Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1euKVb-0001ag-J2 for pgadmin-hackers@arkaria.postgresql.org; Fri, 09 Mar 2018 16:04:39 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1euKVa-000200-4e for pgadmin-hackers@arkaria.postgresql.org; Fri, 09 Mar 2018 16:04:38 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1euKVZ-0001zp-JR for pgadmin-hackers@lists.postgresql.org; Fri, 09 Mar 2018 16:04:38 +0000 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1euKVV-0007Jd-IW for pgadmin-hackers@postgresql.org; Fri, 09 Mar 2018 16:04:36 +0000 Received: by mail-wm0-x243.google.com with SMTP id t3so4806904wmc.2 for ; Fri, 09 Mar 2018 08:04:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pgadmin-org.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=Vjww1UW5xSTQX6g8VooIm+22jns+UDQri/1u0R/4VMs=; b=1A/ZOUBmSWHEfjkylwmV+5uK+LUS6aFqF4FyaxCGIbIabge3RXoK/RrXR5M9np+aOc kIylYqXnv/LDgPUGyeJmWjjyi/eZ/hJZOJbLoRjYjjy+HToY96qCEHqFXMCgJ8LMKJln UbYC7GwZj6l/ZW1tzausKusFCqJSwlEmvTBdS/1g1xM09XzMigolCGjPckBZkMUq84Wu ewrFQa4L78U1j/Bf8ouITDQa5koQHQOjjaryENKaIX+rNpvaeSkIA9JyHjgRSOzU40iA odSADNboCs/46g0QQKDpHGTLMPzhL3kQqLTKWWhD1fTt7GlwI4VnG4MM7Lc+eAoEnMtd kqVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=Vjww1UW5xSTQX6g8VooIm+22jns+UDQri/1u0R/4VMs=; b=Er3JKlKrReSiOSc52Tc6fHtB6abfuqDtt7tK8CyS91RMV911DkXD1/S0vjxdPrT65G 2DeE/gc5luAeJ8jssh7dlL5KRg7Q96FPGt8iAZQK3CrwlS/5k3LUwZ6s6dfz8s34tpab 3I2T4+Zq3k4Be75l9F/OZorsDVuZdRbGQqoIaUiFEFaeDqspeW7nrPKf2AsTvh2cKquf 8cEgXf65EQ4ftYij/l65/KoRltrPV6xvwEVkm3X+bfeCKPDSx3r1iktDvIkP8zQkZN0E qktUqqJf8BzB4mGR+eoObuAhUUmWOqyUVU16mq+mwefyi6fKHP48rnVCMEEjNpkfvyJ/ /5kQ== X-Gm-Message-State: AElRT7Fwgbk6ge9Dk8zZROzFi4cULAbQpgD6Q36owbEiNG/dGZ0JwTLG ddUI8BM+BDU/Xd55XXHQFxfs/DaEte6ZZC/7RtcuLw== X-Google-Smtp-Source: AG47ELsojwWFxId+9+vmAP/isJ6LdJ5pSuts6N7mDBrUtP5RUYF2kIuMkD7w+CvXPPrcWTXHRhjR1LpdhNEB04DW9uY= X-Received: by 10.28.5.75 with SMTP id 72mr2626300wmf.154.1520611471276; Fri, 09 Mar 2018 08:04:31 -0800 (PST) MIME-Version: 1.0 Received: by 10.28.109.7 with HTTP; Fri, 9 Mar 2018 08:04:30 -0800 (PST) In-Reply-To: References: From: Dave Page Date: Fri, 9 Mar 2018 16:04:30 +0000 Message-ID: Subject: Re: pgAdmin 4 commit: Support EXPLAIN on Greenplum. Fixes #3097 To: Joao De Almeida Pereira Cc: Khushboo Vashi , pgadmin-hackers Content-Type: multipart/alternative; boundary="001a114429c8964f560566fcf2a4" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --001a114429c8964f560566fcf2a4 Content-Type: text/plain; charset="UTF-8" Hi On Fri, Mar 9, 2018 at 3:54 PM, Joao De Almeida Pereira < jdealmeidapereira@pivotal.io> wrote: > Hello, > Definitely running single tests is something that would be great, > specially if you are TDDing something waiting 30-40 seconds to get feedback > is a little cumbersome when the test you are concerned with take less then > a second. > > In the process: > 1. Write a test > 2. Make the test pass > 3. Refactor > Sure, makes sense for development. As I spend 99% of my time reviewing and testing these days, I was just relaying my pain points :-) > > in between each step you run the test more then 1 time, and depending on > the refactoring you might need to run it several times. So imagine waiting > 30 seconds per run to get results. To run a subset of tests is a pain > because you need to be always changing the way you run the tests..... > > I believe we could archive a better granularity and choosing what test to > run if we used a runner like pytest or nose to do it. What was the reason > behind handrolling a test runner script? I am asking this because in a > previous job I decided to handroll a unittest loader script and that was > something that I regretted every time I had to touch it, and eventually was > in the process of changing it to pytest. > Pure newbie-ism. I have no objections to changing to something else, if it reduces our tech debt. > > I looked into pytest to replace the current the current runtest, and the > major problem I found was the testscenarios integration(See Note 1). It can > be done but we would need to change all the test functions to receive the > scenario variables through arguments on the function. Also didn't dug much > into setting all the variables that we need there and all the environment. > The other issue that I do not like very much about pytest is the fact that > you loose the unittest assertion that is not so bad because there are some > neat libraries like: https://github.com/grappa-py/grappa, https:// > github.com/ActivisionGameScience/assertpy, https://github.com/dgilland/ > verify. Personally I really like the syntax of Grapa, but the Veridfy one > is pretty similar to Jasmine too. > > What are your thoughts? > Huh, I also really like the grappa syntax. It's nice and readable. > > > > Note 1: As an example of what our functions would have to look like you > can see: https://github.com/OriMenashe/pytest-scenario/ > blob/master/tests/test_parametrize.py > As a example this class: > Without a diff, it's hard to be sure, but it looks like the only change was BaseTestGenerator to object on the first line? > class ServersWithServiceIDAddTestCase(BaseTestGenerator): > """ This class will add the servers under default server group. """ > > scenarios = [ > # Fetch the default url for server object > ( > 'Default Server Node url', dict( > url='/browser/server/obj/' > ) > ) > ] > > def setUp(self): > pass > > def runTest(self): > """ This function will add the server under default server group.""" > url = "{0}{1}/".format(self.url, utils.SERVER_GROUP) > # Add service name in the config > self.server['service'] = "TestDB" > response = self.tester.post( > url, > data=json.dumps(self.server), > content_type='html/json' > ) > self.assertEquals(response.status_code, 200) > response_data = json.loads(response.data.decode('utf-8')) > self.server_id = response_data['node']['_id'] > > def tearDown(self): > """This function delete the server from SQLite """ > utils.delete_server_with_api(self.tester, self.server_id) > > Would have to look changed to: > > class ServersWithServiceIDAddTestCase(object): > """ This class will add the servers under default server group. """ > > scenarios = [ > # Fetch the default url for server object > ( > 'Default Server Node url', dict( > url='/browser/server/obj/' > ) > ) > ] > > def setUp(self): > pass > > def runTest(self, url): > """ This function will add the server under default server group.""" > url = "{0}{1}/".format(url, utils.SERVER_GROUP) > # Add service name in the config > self.server['service'] = "TestDB" > response = self.tester.post( > url, > data=json.dumps(self.server), > content_type='html/json' > ) > self.assertEquals(response.status_code, 200) > response_data = json.loads(response.data.decode('utf-8')) > self.server_id = response_data['node']['_id'] > > def tearDown(self): > """This function delete the server from SQLite """ > utils.delete_server_with_api(self.tester, self.server_id) > > > > Thanks > Joao > > On Fri, Mar 9, 2018 at 8:31 AM Dave Page wrote: > >> On Thu, Mar 8, 2018 at 2:22 PM, Joao De Almeida Pereira < >> jdealmeidapereira@pivotal.io> wrote: >> >>> Hello Khushboo, >>> Completely forgot about this python "feature"....... >>> Attached is the fix. >>> >> >> Thanks, applied. >> >> >>> >>> Just as a side question, does anyone else feel the pain of wanting to >>> run a single test using a IDE or the command line and not being able to? >>> >> >> Not really - the Python and JS tests are so quick I don't really care >> (and with the Python ones, I can execute for a single module for even more >> speed). >> >> What I would *really* like, is the ability to run individual feature >> tests. That would be very valuable and save me a ton of time. >> >> >> >>> We an HandRolled the loader, and that as some implications. Did anyone >>> try to use a different launcher like pytest or nose instead of the current >>> runner? >>> I understand that testscenarios is one of the problems we have if we >>> want to move away from this way of running tests. >>> Any suggestion? >>> >>> Thanks >>> Joao >>> >>> On Wed, Mar 7, 2018 at 11:41 PM Khushboo Vashi < >>> khushboo.vashi@enterprisedb.com> wrote: >>> >>>> Hi Joao, >>>> >>>> In the test_start_running_query.py, 2 static methods >>>> (is_begin_required_for_sql_query and is_rollback_statement_required) >>>> of StartRunningQuery class were used directly without @patch. Due to >>>> this, in all the cases, the original value of them doesn't restore. >>>> >>>> To fix this, I have sent the patch in another thread, to restore its >>>> original state, but I wonder if we can use these methods with @patch. >>>> >>>> Thanks, >>>> Khushboo >>>> >>>> >>>> On Fri, Feb 9, 2018 at 5:24 PM, Dave Page wrote: >>>> >>>>> Support EXPLAIN on Greenplum. Fixes #3097 >>>>> >>>>> - Extract SQLEditor.execute and SQLEditor._poll into their own files >>>>> and add test around them >>>>> - Extract SQLEditor backend functions that start executing query to >>>>> their own files and add tests around it >>>>> - Move the Explain SQL from the front-end and now pass the Explain >>>>> plan parameters as a JSON object in the start query call. >>>>> - Extract the compile_template_name into a function that can be used >>>>> by the different places that try to select the version of the template and >>>>> the server type >>>>> >>>>> Branch >>>>> ------ >>>>> master >>>>> >>>>> Details >>>>> ------- >>>>> https://git.postgresql.org/gitweb?p=pgadmin4.git;a=commitdiff;h= >>>>> e16a95275336529a734bf0066889e39cc8ef0662 >>>>> Author: Joao Pedro De Almeida Pereira >>>>> >>>>> Modified Files >>>>> -------------- >>>>> .../databases/schemas/tables/tests/test_utils.py | 0 >>>>> web/pgadmin/static/js/sqleditor/execute_query.js | 287 ++++ >>>>> .../js/sqleditor/is_new_transaction_required.js | 14 + >>>>> .../static/js/sqleditor/query_tool_actions.js | 33 +- >>>>> web/pgadmin/tools/sqleditor/__init__.py | 396 +---- >>>>> web/pgadmin/tools/sqleditor/static/js/sqleditor.js | 227 +-- >>>>> .../sqleditor/sql/10_plus/explain_plan.sql | 23 + >>>>> .../sqleditor/sql/9.2_plus/explain_plan.sql | 20 + >>>>> .../sqleditor/sql/default/explain_plan.sql | 17 + >>>>> .../sqleditor/sql/gpdb_5.0_plus/explain_plan.sql | 5 + >>>>> web/pgadmin/tools/sqleditor/tests/__init__.py | 8 + >>>>> .../sqleditor/tests/test_explain_plan_templates.py | 152 ++ >>>>> .../test_extract_sql_from_network_parameters.py | 59 + >>>>> .../tools/sqleditor/tests/test_start_query_tool.py | 38 + >>>>> web/pgadmin/tools/sqleditor/utils/__init__.py | 14 + >>>>> .../sqleditor/utils/apply_explain_plan_wrapper.py | 24 + >>>>> .../tools/sqleditor/utils/constant_definition.py | 32 + >>>>> .../tools/sqleditor/utils/is_begin_required.py | 169 ++ >>>>> .../tools/sqleditor/utils/start_running_query.py | 172 ++ >>>>> .../tools/sqleditor/utils/tests/__init__.py | 8 + >>>>> .../utils/tests/test_apply_explain_plan_wrapper.py | 121 ++ >>>>> .../utils/tests/test_start_running_query.py | 445 +++++ >>>>> .../utils/update_session_grid_transaction.py | 18 + >>>>> web/pgadmin/utils/compile_template_name.py | 17 + >>>>> .../utils/tests/test_compile_template_name.py | 34 + >>>>> web/pgadmin/utils/versioned_template_loader.py | 2 +- >>>>> web/regression/javascript/fake_endpoints.js | 6 +- >>>>> .../javascript/sqleditor/execute_query_spec.js | 1702 >>>>> ++++++++++++++++++++ >>>>> .../sqleditor/is_new_transaction_required_spec.js | 65 + >>>>> .../sqleditor/query_tool_actions_spec.js | 141 +- >>>>> 30 files changed, 3670 insertions(+), 579 deletions(-) >>>>> >>>>> >>>> >> >> >> -- >> Dave Page >> Blog: http://pgsnake.blogspot.com >> Twitter: @pgsnake >> >> EnterpriseDB UK: http://www.enterprisedb.com >> The Enterprise PostgreSQL Company >> > -- Dave Page Blog: http://pgsnake.blogspot.com Twitter: @pgsnake EnterpriseDB UK: http://www.enterprisedb.com The Enterprise PostgreSQL Company --001a114429c8964f560566fcf2a4 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi

On Fri, Mar 9, 2018 at 3:54 PM, Joao De Almeida Pereira <= jdealmeidapereira@pivotal.io> wrote:
Hello,
Definitely running single tests is so= mething that would be great, specially if you are TDDing something waiting = 30-40 seconds to get feedback is a little cumbersome when the test you are = concerned with take less then a second.

In the pro= cess:
1. Write a test
2. Make the test pass
3= . Refactor

Sure, makes sense fo= r development. As I spend 99% of my time reviewing and testing these days, = I was just relaying my pain points :-)
=C2=A0

in between each step = you run the test more then 1 time, and depending on the refactoring you mig= ht need to run it several times. So imagine waiting 30 seconds per run to g= et results. To run a subset of tests is a pain because you need to be alway= s changing the way you run the tests.....

I believ= e we could archive a better granularity and choosing what test to run if we= used a runner like pytest or nose to do it. What was the reason behind han= drolling a test runner script? I am asking this because in a previous job I= decided to handroll a unittest loader script and that was something that I= regretted every time I had to touch it, and eventually was in the process = of changing it to pytest.

Pure = newbie-ism. I have no objections to changing to something else, if it reduc= es our tech debt.
=C2=A0

I looked into pytest to replace the curren= t the current runtest, and the major problem I found was the testscenarios = integration(See Note 1). It can be done but we would need to change all the= test functions to receive the scenario variables through arguments on the = function. Also didn't dug much into setting all the variables that we n= eed there and all the environment.
The other issue that I do not = like very much about pytest is the fact that you loose the unittest asserti= on that is not so bad because there are some neat libraries like:=C2=A0https://githu= b.com/grappa-py/grappa,=C2=A0https://github.com/Act= ivisionGameScience/assertpy,=C2=A0https://github.com/dgilland/verify. Personally I really like the syntax of Grapa, but the Veridfy one is pre= tty similar to Jasmine too.


<= div>
Without a diff, it's hard to be sure, but it looks l= ike the only change was BaseTestGenerator to object on the first line?
=C2=A0
class ServersWithServiceIDAddTestCase(BaseTestGenera= tor):
"&= quot;" This class will add the servers under default server group. &qu= ot;""

= scenarios =3D [
#= Fetch the default url for server object
(
'Default Server Node url', dict( url=3D'/browser/server/obj/'
)
)
= ]

def setUp(self):
pass
=

def ru= nTest(self):
= """ = This function will add the server under default server group.""&q= uot;
= url =3D "{0}{1}/"= .format(self.url, utils.SERVER_GROUP)
# Add service name in the config
self.server['service'] =3D "= ;TestDB"
response =3D self.tester.pos= t(
url,
data=3Djson.dumps(self.server),
content_type=3D'html/json'
= )
self.ass= ertEquals(response.status_code, = 200)
respon= se_data =3D json.loads(response.data.decode('utf-8'))
self.server_id =3D response_data['node'][= '_id']

def = tearDown(self):
"""This function delete the = server from SQLite """
utils.delete_server_with_api(self.tester, self.server_id)
Would have to look changed to:
class ServersWithServiceIDAddTestCase(object):
""" This class will add the s= ervers under default server group. """

scenarios =3D [
# Fetch the default url for server obj= ect
(
= 'Default Server Node ur= l', dict(
url=3D'/= browser/server/obj/'
= )
)
]

def setUp(self):
pass

def runTest
(self, url)= :
"&= quot;" This function will add the server under default server group.&q= uot;""
url =3D "{= 0}{1}/".format(url, utils.SERVER_GROUP)
# A= dd service name in the config
self.server= ['service'] =3D "TestDB"
response =3D self.tester.post(
url,
= data=3Djson.dump= s(self.server),
= content_type=3D= 'html/json'
)
self.assertEquals(response.status_code,
200)
response_data =3D json.loads(response.data.<= wbr>decode('utf-8')) self.server_id =3D r= esponse_data['node'][<= span style=3D"color:rgb(165,194,97)">'_id']

def tearDown(self):=
"&q= uot;"This function delete the server from SQLite """ utils.delete_server_with_api(self.tester, self.server_id)


Thanks
Joao
<= div class=3D"h5">
On Fri, Ma= r 9, 2018 at 8:31 AM Dave Page <dpage@pgadmin.org> wrote:
On Thu, Mar 8, 2018 at 2:22 PM, Joao De Almeida Pereira <jdealmeidapereira@pivotal.io> wrote:
Hello Khushboo,
Completely forgot about = this python "feature".......
Attached is the fix.
=

Thanks, applied.
=
=C2=A0

Just as a side question, does anyone else feel the = pain of wanting to run a single test using a IDE or the command line and no= t being able to?

<= div dir=3D"ltr">
= Not really - the Python and JS tests are so quick I don't really care (= and with the Python ones, I can execute for a single module for even more s= peed).

What I would *really* like, is the ability = to run individual feature tests. That would be very valuable and save me a = ton of time.

=C2=A0
We an HandRolled the loader, and = that as some implications. Did anyone try to use a different launcher like = pytest or nose instead of the current runner?=C2=A0
I understand = that testscenarios is one of the problems we have if we want to move away f= rom this way of running tests.
Any suggestion?

Thanks
Joao

On Wed, Mar 7, 2018 at 11:41 PM Khushboo Vashi <= ;khush= boo.vashi@enterprisedb.com> wrote:
Hi Joao,

In the=C2=A0test_start_running_query.py, 2 static methods (is_begin_required_for_sql_query and is_rollback_statement_required)
of <= /span>StartRunningQuery class were used directly without @p= atch. Due to this, in all the cases, the original va= lue of them doesn't restore.

To fix this, I have sent the patch in another = thread, to restore its original state, but I wonder if we can use these met= hods with @patch.

Thanks,
Khushboo


On Fri, Feb 9, 2018 at 5:24 PM, Dave Page <dpage@pgadmin.org><= /span> wrote:
Support EXPLAIN on Greenplu= m. Fixes #3097

=C2=A0- Extract SQLEditor.execute and SQLEditor._poll into their own files = and add test around them
=C2=A0- Extract SQLEditor backend functions that start executing query to t= heir own files and add tests around it
=C2=A0- Move the Explain SQL from the front-end and now pass the Explain pl= an parameters as a JSON object in the start query call.
=C2=A0- Extract the compile_template_name into a function that can be used = by the different places that try to select the version of the template and = the server type

Branch
------
master

Details
-------
https://git.postgresql.org/gitweb?p=3Dpgadmin4.git;a=3Dcommitdiff;h=3De16a95275336529a734bf0066889e39cc8ef0662
Author: Joao Pedro De Almeida Pereira <jdealmeidapereira@pivotal.io>

Modified Files
--------------
.../databases/schemas/tables/tests/test_utils.py=C2=A0 =C2=A0|=C2=A0 = =C2=A0 0
web/pgadmin/static/js/sqleditor/execute_query.js=C2=A0 =C2=A0|=C2=A0 2= 87 ++++
.../js/sqleditor/is_new_transaction_required.js=C2=A0 =C2=A0 |=C2=A0 = =C2=A014 +
.../static/js/sqleditor/query_tool_actions.js=C2=A0 =C2=A0 =C2=A0 |=C2= =A0 =C2=A033 +-
web/pgadmin/tools/sqleditor/__init__.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 |=C2=A0 396 +----
web/pgadmin/tools/sqleditor/static/js/sqleditor.js |=C2=A0 227 +--
.../sqleditor/sql/10_plus/explain_plan.sql=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0|=C2=A0 =C2=A023 +
.../sqleditor/sql/9.2_plus/explain_plan.sql=C2=A0 =C2=A0 =C2=A0 =C2=A0= |=C2=A0 =C2=A020 +
.../sqleditor/sql/default/explain_plan.sql=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0|=C2=A0 =C2=A017 +
.../sqleditor/sql/gpdb_5.0_plus/explain_plan.sql=C2=A0 =C2=A0|=C2=A0 = =C2=A0 5 +
web/pgadmin/tools/sqleditor/tests/__init__.py=C2=A0 =C2=A0 =C2=A0 |=C2= =A0 =C2=A0 8 +
.../sqleditor/tests/test_explain_plan_templates.py |=C2=A0 152 ++
.../test_extract_sql_from_network_parameters.py=C2=A0 =C2=A0 |=C2=A0 = =C2=A059 +
.../tools/sqleditor/tests/test_start_query_tool.py |=C2=A0 =C2=A038 +<= br> web/pgadmin/tools/sqleditor/utils/__init__.py=C2=A0 =C2=A0 =C2=A0 |=C2= =A0 =C2=A014 +
.../sqleditor/utils/apply_explain_plan_wrapper.py=C2=A0 |=C2=A0 =C2=A0= 24 +
.../tools/sqleditor/utils/constant_definition.py=C2=A0 =C2=A0|=C2=A0 = =C2=A032 +
.../tools/sqleditor/utils/is_begin_required.py=C2=A0 =C2=A0 =C2=A0|=C2= =A0 169 ++
.../tools/sqleditor/utils/start_running_query.py=C2=A0 =C2=A0|=C2=A0 1= 72 ++
.../tools/sqleditor/utils/tests/__init__.py=C2=A0 =C2=A0 =C2=A0 =C2=A0= |=C2=A0 =C2=A0 8 +
.../utils/tests/test_apply_explain_plan_wrapper.py |=C2=A0 121 ++
.../utils/tests/test_start_running_query.py=C2=A0 =C2=A0 =C2=A0 =C2=A0= |=C2=A0 445 +++++
.../utils/update_session_grid_transaction.py=C2=A0 =C2=A0 =C2=A0 =C2= =A0|=C2=A0 =C2=A018 +
web/pgadmin/utils/compile_template_name.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0|=C2=A0 =C2=A017 +
.../utils/tests/test_compile_template_name.py=C2=A0 =C2=A0 =C2=A0 |=C2= =A0 =C2=A034 +
web/pgadmin/utils/versioned_template_loader.py=C2=A0 =C2=A0 =C2=A0|=C2= =A0 =C2=A0 2 +-
web/regression/javascript/fake_endpoints.js=C2=A0 =C2=A0 =C2=A0 =C2=A0= |=C2=A0 =C2=A0 6 +-
.../javascript/sqleditor/execute_query_spec.js=C2=A0 =C2=A0 =C2=A0| 17= 02 ++++++++++++++++++++
.../sqleditor/is_new_transaction_required_spec.js=C2=A0 |=C2=A0 =C2=A0= 65 +
.../sqleditor/query_tool_actions_spec.js=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0|=C2=A0 141 +-
30 files changed, 3670 insertions(+), 579 deletions(-)


=


--
Dave Page
Blog: http://pgsnake.blogspot.com
Twitter: @pgsnake

EnterpriseD= B UK: http://www.= enterprisedb.com
The Enterprise PostgreSQL Company



--
=
Dave Page=
Blog: http://= pgsnake.blogspot.com
Twitter: @pgsnake

EnterpriseDB UK: http://www.enterprised= b.com
The Enterprise PostgreSQL Company
--001a114429c8964f560566fcf2a4--