Hi Hackers,

We fixed the tests and refactored some of the code.  All tests pass now.
Attached is the reviewed patch.

Sincerely,

Joao and Victoria

On Tue, Mar 20, 2018 at 10:05 AM, Dave Page <dave.p...@enterprisedb.com>
wrote:

> Hi
>
> This doesn't pass the Javascript tests for me. Please investigate ASAP:
>
> webpack: Compiled successfully.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 152 of 486 SUCCESS (0
> secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 153 of 486 SUCCESS (0
> secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 154 of 486 SUCCESS (0
> secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 155 of 486 SUCCESS (0
> secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 156 of 486 SUCCESS (0
> secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 157 of 486 SUCCESS (0
> secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 158 of 486 SUCCESS (0
> secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is the query tool when an error occur when the connection to the server was
> lost when JSON response is available when login is not required should
> highlight the error in the SQL panel FAILED
> Expected spy SqlEditor._highlight_error to have been called with [ 'Some
> error in JSON' ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:11753:58
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 285 of 486 (1 FAILED) (0
> secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is the query tool when an error occur when the connection to the server was
> lost when JSON response is available when login is not required should
> highlight the error in the SQL panel FAILED
> Expected spy SqlEditor._highlight_error to have been called with [ 'Some
> error in JSON' ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is the query tool when an error occur when the connection to the server was
> lost when JSON response is available when login is not required should add
> new entry to history and update the Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'Some error in JSON' ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:11760:60
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 286 of 486 (2 FAILED) (0
> secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is the query tool when an error occur when the connection to the server was
> lost when JSON response is available when login is not required should add
> new entry to history and update the Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'Some error in JSON' ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is the query tool when an error occur when the connection to the server was
> lost when JSON response is available when login is required should login is
> displayed FAILED
> Expected spy UserManagement.pga_login to have been called.
>     at regression/javascript/sqleditor/execute_query_spec.js:11840:56
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 296 of 486 (3 FAILED) (0
> secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is the query tool when an error occur when the connection to the server was
> lost when JSON response is available when login is required should login is
> displayed FAILED
> Expected spy UserManagement.pga_login to have been called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is the query tool when an error occur when the connection to the server was
> lost when no JSON response is available when login is not required should
> highlight the error in the SQL panel FAILED
> Expected spy SqlEditor._highlight_error to have been called with [ 'Some
> plain text error' ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:11875:58
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 299 of 486 (4 FAILED) (0
> secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is the query tool when an error occur when the connection to the server was
> lost when no JSON response is available when login is not required should
> highlight the error in the SQL panel FAILED
> Expected spy SqlEditor._highlight_error to have been called with [ 'Some
> plain text error' ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is the query tool when an error occur when the connection to the server was
> lost when no JSON response is available when login is not required should
> add new entry to history and update the Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'Some plain text error' ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:11882:60
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 300 of 486 (5 FAILED) (0
> secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is the query tool when an error occur when the connection to the server was
> lost when no JSON response is available when login is not required should
> add new entry to history and update the Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'Some plain text error' ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is the query tool when an error occur when the connection to the server was
> lost when no JSON response is available when login is required should login
> is displayed FAILED
> Expected spy UserManagement.pga_login to have been called.
>     at regression/javascript/sqleditor/execute_query_spec.js:11964:56
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 310 of 486 (6 FAILED) (0
> secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is the query tool when an error occur when the connection to the server was
> lost when no JSON response is available when login is required should login
> is displayed FAILED
> Expected spy UserManagement.pga_login to have been called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is the query tool when an error occur when the connection to the server was
> lost when cannot reach the Python Server should add new entry to history
> and update the Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'Not connected to the server or the connection to the server has
> been closed.' ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:12002:58
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 314 of 486 (7 FAILED) (0
> secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is the query tool when an error occur when the connection to the server was
> lost when cannot reach the Python Server should add new entry to history
> and update the Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'Not connected to the server or the connection to the server has
> been closed.' ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is NOT the query tool when an error occur when the connection to the server
> was lost when JSON response is available should highlight the error in the
> SQL panel FAILED
> Expected spy SqlEditor._highlight_error to have been called with [ 'Some
> error in JSON' ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:12232:56
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 334 of 486 (8 FAILED) (0
> secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is NOT the query tool when an error occur when the connection to the server
> was lost when JSON response is available should highlight the error in the
> SQL panel FAILED
> Expected spy SqlEditor._highlight_error to have been called with [ 'Some
> error in JSON' ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is NOT the query tool when an error occur when the connection to the server
> was lost when JSON response is available should add new entry to history
> and update the Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'Some error in JSON' ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:12239:58
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 335 of 486 (9 FAILED) (0
> secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is NOT the query tool when an error occur when the connection to the server
> was lost when JSON response is available should add new entry to history
> and update the Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'Some error in JSON' ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is NOT the query tool when an error occur when the connection to the server
> was lost when no JSON response is available should highlight the error in
> the SQL panel FAILED
> Expected spy SqlEditor._highlight_error to have been called with [ 'Some
> plain text error' ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:12282:56
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 340 of 486 (10 FAILED)
> (0 secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is NOT the query tool when an error occur when the connection to the server
> was lost when no JSON response is available should highlight the error in
> the SQL panel FAILED
> Expected spy SqlEditor._highlight_error to have been called with [ 'Some
> plain text error' ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is NOT the query tool when an error occur when the connection to the server
> was lost when no JSON response is available should add new entry to history
> and update the Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'Some plain text error' ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:12289:58
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 341 of 486 (11 FAILED)
> (0 secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is NOT the query tool when an error occur when the connection to the server
> was lost when no JSON response is available should add new entry to history
> and update the Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'Some plain text error' ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is NOT the query tool when an error occur when the connection to the server
> was lost when cannot reach the Python Server should add new entry to
> history and update the Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'Not connected to the server or the connection to the server has
> been closed.' ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:12340:58
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 347 of 486 (12 FAILED)
> (0 secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #poll when SQLEditor
> is NOT the query tool when an error occur when the connection to the server
> was lost when cannot reach the Python Server should add new entry to
> history and update the Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'Not connected to the server or the connection to the server has
> been closed.' ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when cannot reach the Python Server should add new
> entry to history and update the Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'Not connected to the server or the connection to the server has
> been closed.' ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:12645:54
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 376 of 486 (13 FAILED)
> (0 secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when cannot reach the Python Server should add new
> entry to history and update the Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'Not connected to the server or the connection to the server has
> been closed.' ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when error is returned by the server when login is
> not required should add new entry to history and update the Messages tab
> FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'some error message' ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:12693:56
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 381 of 486 (14 FAILED)
> (0 secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when error is returned by the server when login is
> not required should add new entry to history and update the Messages tab
> FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'some error message' ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when error is returned by the server when login is
> required should add new entry to history and update the Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'some error message' ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:12751:56
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 388 of 486 (15 FAILED)
> (0 secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when error is returned by the server when login is
> required should add new entry to history and update the Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'some error message' ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when error is returned by the server when login is
> required should save the state FAILED
> Expected spy SqlEditor.save_state to have been called with [ 'execute', [
> '' ] ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:12774:48
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 391 of 486 (16 FAILED)
> (0 secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when error is returned by the server when login is
> required should save the state FAILED
> Expected spy SqlEditor.save_state to have been called with [ 'execute', [
> '' ] ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when error is returned by the server when login is
> required should display pga login FAILED
> Expected spy UserManagement.pga_login to have been called.
>     at regression/javascript/sqleditor/execute_query_spec.js:12780:52
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 392 of 486 (17 FAILED)
> (0 secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when error is returned by the server when login is
> required should display pga login FAILED
> Expected spy UserManagement.pga_login to have been called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when error is returned by the server when a new
> transaction is not required should add new entry to history and update the
> Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'some error message' ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:12809:56
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 395 of 486 (18 FAILED)
> (0 secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when error is returned by the server when a new
> transaction is not required should add new entry to history and update the
> Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'some error message' ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when error is returned by the server when a new
> transaction is required should add new entry to history and update the
> Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'some error message' ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:12874:56
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 403 of 486 (19 FAILED)
> (0 secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when error is returned by the server when a new
> transaction is required should add new entry to history and update the
> Messages tab FAILED
> Expected spy SqlEditor.update_msg_history to have been called with [
> false, 'some error message' ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when error is returned by the server when a new
> transaction is required should save the state FAILED
> Expected spy SqlEditor.save_state to have been called with [ 'execute', [
> '' ] ] but it was never called.
>     at regression/javascript/sqleditor/execute_query_spec.js:12897:48
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 406 of 486 (20 FAILED)
> (0 secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when error is returned by the server when a new
> transaction is required should save the state FAILED
> Expected spy SqlEditor.save_state to have been called with [ 'execute', [
> '' ] ] but it was never called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when error is returned by the server when a new
> transaction is required should initialize a new transaction FAILED
> Expected spy SqlEditor.init_transaction to have been called.
>     at regression/javascript/sqleditor/execute_query_spec.js:12909:54
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 408 of 486 (21 FAILED)
> (0 secs / 0 secs)
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6) ExecuteQuery #execute when the SQL
> statement is not empty when error is returned by the server when a new
> transaction is required should initialize a new transaction FAILED
> Expected spy SqlEditor.init_transaction to have been called.
> HeadlessChrome 0.0.0 (Mac OS X 10.12.6): Executed 486 of 486 (21 FAILED)
> (7.05 secs / 0 secs)
> error Command failed with exit code 1.
> info Visit https://yarnpkg.com/en/docs/cli/run for documentation about
> this command.
> make: *** [check-js] Error 1
>
>
> On Tue, Mar 20, 2018 at 1:12 PM, Akshay Joshi <
> akshay.jo...@enterprisedb.com> wrote:
>
>> Hi Hackers
>>
>> Attached is the patch file to fix the RM #2815.
>>
>> On Tue, Mar 20, 2018 at 3:24 PM, Dave Page <dave.p...@enterprisedb.com>
>> wrote:
>>
>>>
>>>
>>> On Tue, Mar 20, 2018 at 9:48 AM, Akshay Joshi <
>>> akshay.jo...@enterprisedb.com> wrote:
>>>
>>>>
>>>>
>>>> On Tue, Mar 20, 2018 at 3:06 PM, Dave Page <dave.p...@enterprisedb.com>
>>>> wrote:
>>>>
>>>>> I'm a little concerned that noone mentioned this earlier; I'm supposed
>>>>> to be building the release this afternoon, and I expect this change to at
>>>>> the very least be complex to fully test and verify. What's the ETA on the
>>>>> patch? What steps are being taken to ensure it's correct and doesn't cause
>>>>> regressions?
>>>>>
>>>>
>>>>     Harshal has already mentioned in the RM. Currently I am changing
>>>> the logic, but it may take time to complete, fully test and verify. I'll
>>>> try my best to do it asap.
>>>>
>>>
>>> Sure, but how many of us are watching every comment on every RM? I know
>>> I'm not (I currently average ~400 emails/day).
>>>
>>>
>>>>
>>>>> On Tue, Mar 20, 2018 at 7:51 AM, Akshay Joshi <
>>>>> akshay.jo...@enterprisedb.com> wrote:
>>>>>
>>>>>> Hi Joao
>>>>>>
>>>>>> It seems that this fix broke the functionality of RM #2815. It is
>>>>>> mentioned in the RM what needs to be fixed now and I am currently working
>>>>>> on it.
>>>>>> While fixing the issue following problem that I found
>>>>>>
>>>>>>    - In "start_running_query.py" file, we need to remove check "if
>>>>>>    conn.connected()" from "__execute_query" function as we required
>>>>>>    exception to be thrown while executing the query to identify the
>>>>>>    ConnectionLost.
>>>>>>    - In "execute_query.js" we have used *axios* to execute the query
>>>>>>    and in case of exception, object is different then normal javascript
>>>>>>    response object.
>>>>>>    - We call following functions when exception or error comes and
>>>>>>    send the "*<object>.response.data*" as parameter
>>>>>>       - wasConnectionLostToServer(): Check for the readyState
>>>>>>       parameter, which is not the part of "<object>.response.data".
>>>>>>       - extractErrorMessage(): Check for the "responseJSON" and "
>>>>>>       responseJSON.info", which is not the part of
>>>>>>       "<object>.response.data".
>>>>>>       - is_pga_login_required(): Check for the "responseJSON" and "
>>>>>>       responseJSON.info", which is not the part of
>>>>>>       "<object>.response.data".
>>>>>>       - is_new_transaction_required(): Check for the "responseJSON"
>>>>>>       and "responseJSON.info", which is not the part of
>>>>>>       "<object>.response.data".
>>>>>>
>>>>>> From the above list, some of the function calls are generic where
>>>>>> they need "responseJSON" and "responseJSON.info", so we can't change
>>>>>> that. Possible solution could be pass one extra flag as parameter to
>>>>>> identify the object is a axios response or javascript response to
>>>>>> above functions and change the logic accordingly.
>>>>>>
>>>>>> Please let me know your thoughts or any other suggestion.
>>>>>>
>>>>>>
>>>>>> On Fri, Feb 9, 2018 at 8:17 PM, Dave Page <dp...@pgadmin.org> wrote:
>>>>>>
>>>>>>> Thanks, applied.
>>>>>>>
>>>>>>> On Fri, Feb 9, 2018 at 2:35 PM, Joao De Almeida Pereira <
>>>>>>> jdealmeidapere...@pivotal.io> wrote:
>>>>>>>
>>>>>>>> Hello,
>>>>>>>> Attached you can find the fix for the current pronlem
>>>>>>>>
>>>>>>>>
>>>>>>>> On Fri, Feb 9, 2018 at 7:29 AM Dave Page <dp...@pgadmin.org> wrote:
>>>>>>>>
>>>>>>>>> Hi Joao,
>>>>>>>>>
>>>>>>>>> It looks like Jenkins has taken umbrage to this change, at least
>>>>>>>>> with Python 3.x. Can you take a look please?
>>>>>>>>>
>>>>>>>>> https://jenkins.pgadmin.org/
>>>>>>>>>
>>>>>>>>> Thanks.
>>>>>>>>>
>>>>>>>>> On Fri, Feb 9, 2018 at 11:54 AM, Dave Page <dp...@pgadmin.org>
>>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>> Thanks, patches applied.
>>>>>>>>>>
>>>>>>>>>> On Fri, Feb 2, 2018 at 10:50 PM, Joao De Almeida Pereira <
>>>>>>>>>> jdealmeidapere...@pivotal.io> wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi Hackers,
>>>>>>>>>>> This is quite a big patch in order to solve the problem with the
>>>>>>>>>>> Explain Plan.
>>>>>>>>>>>
>>>>>>>>>>> We sent 2 patches that have the following:
>>>>>>>>>>> *- update-javascript-packages.diff *
>>>>>>>>>>>     Add package:
>>>>>>>>>>>      is-docker to select a specific setting when running the
>>>>>>>>>>> Chrome tests in
>>>>>>>>>>>      Docker
>>>>>>>>>>>
>>>>>>>>>>>     Upgrade the version of:
>>>>>>>>>>>     - babel-loader
>>>>>>>>>>>     - extract-text-webpack-plugin
>>>>>>>>>>>     - jasmine-core
>>>>>>>>>>>     - jasmine-enzyme
>>>>>>>>>>>     - moment
>>>>>>>>>>> *- explain-plan-greenplum.diff*
>>>>>>>>>>>   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
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Thanks
>>>>>>>>>>> Joao
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> 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
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Dave Page
>>>>>>> Blog: http://pgsnake.blogspot.com
>>>>>>> Twitter: @pgsnake
>>>>>>>
>>>>>>> EnterpriseDB UK: http://www.enterprisedb.com
>>>>>>> The Enterprise PostgreSQL Company
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> *Akshay Joshi*
>>>>>>
>>>>>> *Sr. Software Architect *
>>>>>>
>>>>>>
>>>>>>
>>>>>> *Phone: +91 20-3058-9517 <+91%2020%203058%209517>Mobile: +91
>>>>>> 976-788-8246 <+91%2097678%2088246>*
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Dave Page
>>>>> VP, Chief Architect, Tools & Installers
>>>>> EnterpriseDB: http://www.enterprisedb.com
>>>>> The Enterprise PostgreSQL Company
>>>>>
>>>>> Blog: http://pgsnake.blogspot.com
>>>>> Twitter: @pgsnake
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> *Akshay Joshi*
>>>>
>>>> *Sr. Software Architect *
>>>>
>>>>
>>>>
>>>> *Phone: +91 20-3058-9517 <+91%2020%203058%209517>Mobile: +91
>>>> 976-788-8246 <+91%2097678%2088246>*
>>>>
>>>
>>>
>>>
>>> --
>>> Dave Page
>>> VP, Chief Architect, Tools & Installers
>>> EnterpriseDB: http://www.enterprisedb.com
>>> The Enterprise PostgreSQL Company
>>>
>>> Blog: http://pgsnake.blogspot.com
>>> Twitter: @pgsnake
>>>
>>
>>
>>
>> --
>> *Akshay Joshi*
>>
>> *Sr. Software Architect *
>>
>>
>>
>> *Phone: +91 20-3058-9517 <+91%2020%203058%209517>Mobile: +91 976-788-8246
>> <+91%2097678%2088246>*
>>
>
>
>
> --
> Dave Page
> VP, Chief Architect, Tools & Installers
> EnterpriseDB: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>
> Blog: http://pgsnake.blogspot.com
> Twitter: @pgsnake
>
diff --git a/web/pgadmin/dashboard/static/js/dashboard.js b/web/pgadmin/dashboard/static/js/dashboard.js
index dd6ecf96..e4f0dd54 100644
--- a/web/pgadmin/dashboard/static/js/dashboard.js
+++ b/web/pgadmin/dashboard/static/js/dashboard.js
@@ -444,18 +444,25 @@ define('pgadmin.dashboard', [
             pgAdmin.Dashboard.render_chart(container, data, dataset, sid, did, url, options, counter, refresh);
           },
           error: function(xhr) {
-            var err = $.parseJSON(xhr.responseText),
-              msg = err.errormsg,
-              cls;
-            // If we get a 428, it means the server isn't connected
-            if (xhr.status == 428) {
-              if (_.isUndefined(msg) || _.isNull(msg)) {
-                msg = gettext('Please connect to the selected server to view the graph.');
-              }
-              cls = 'info';
+            let err = '';
+            let msg = '';
+            let cls = 'info';
+
+            if (xhr.readyState === 0) {
+              msg = gettext('Not connected to the server or the connection to the server has been closed.');
             } else {
-              msg = gettext('An error occurred whilst rendering the graph.');
-              cls = 'danger';
+              err = JSON.parse(xhr.responseText);
+              msg = err.errormsg;
+
+              // If we get a 428, it means the server isn't connected
+              if (xhr.status === 428) {
+                if (_.isUndefined(msg) || _.isNull(msg)) {
+                  msg = gettext('Please connect to the selected server to view the graph.');
+                }
+              } else {
+                msg = gettext('An error occurred whilst rendering the graph.');
+                cls = 'danger';
+              }
             }
 
             $(container).addClass('graph-error');
@@ -576,18 +583,25 @@ define('pgadmin.dashboard', [
           filter.search();
         },
         error: function(model, xhr) {
-          var err = $.parseJSON(xhr.responseText),
-            msg = err.errormsg,
-            cls;
-          // If we get a 428, it means the server isn't connected
-          if (xhr.status == 428) {
-            if (_.isUndefined(msg) || _.isNull(msg)) {
-              msg = gettext('Please connect to the selected server to view the table.');
-            }
-            cls = 'info';
+          let err = '';
+          let msg = '';
+          let cls = 'info';
+
+          if (xhr.readyState === 0) {
+            msg = gettext('Not connected to the server or the connection to the server has been closed.');
           } else {
-            msg = gettext('An error occurred whilst rendering the table.');
-            cls = 'danger';
+            err = JSON.parse(xhr.responseText);
+            msg = err.errormsg;
+
+            // If we get a 428, it means the server isn't connected
+            if (xhr.status === 428) {
+              if (_.isUndefined(msg) || _.isNull(msg)) {
+                msg = gettext('Please connect to the selected server to view the table.');
+              }
+            } else {
+              msg = gettext('An error occurred whilst rendering the table.');
+              cls = 'danger';
+            }
           }
 
           // Replace the content with the error, if not already present. Always update the message
diff --git a/web/pgadmin/static/js/sqleditor/execute_query.js b/web/pgadmin/static/js/sqleditor/execute_query.js
index e91c9e85..9c36f28c 100644
--- a/web/pgadmin/static/js/sqleditor/execute_query.js
+++ b/web/pgadmin/static/js/sqleditor/execute_query.js
@@ -52,7 +52,7 @@ class ExecuteQuery {
       }, self.sqlServerObject.POLL_FALLBACK_TIME());
   }
 
-  execute(sqlStatement, explainPlan) {
+  execute(sqlStatement, explainPlan, connect) {
     // If it is an empty query, do nothing.
     if (sqlStatement.length <= 0) return;
 
@@ -63,11 +63,8 @@ class ExecuteQuery {
     const sqlStatementWithAnalyze = ExecuteQuery.prepareAnalyzeSql(sqlStatement, explainPlan);
 
     self.initializeExecutionOnSqlEditor(sqlStatementWithAnalyze);
-
     service.post(
-      url_for('sqleditor.query_tool_start', {
-        'trans_id': self.sqlServerObject.transId,
-      }),
+      this.generateURLReconnectionFlag(connect),
       JSON.stringify(sqlStatementWithAnalyze),
       {headers: {'Content-Type': 'application/json'}})
       .then(function (result) {
@@ -90,11 +87,22 @@ class ExecuteQuery {
           self.sqlServerObject._highlight_error(httpMessageData.data.result);
         }
       }).catch(function (error) {
-        self.onExecuteHTTPError(error.response.data);
+        self.onExecuteHTTPError(error);
       }
     );
   }
 
+  generateURLReconnectionFlag(shouldReconnect) {
+    let url = url_for('sqleditor.query_tool_start', {
+      'trans_id': this.sqlServerObject.transId,
+    });
+
+    if (shouldReconnect) {
+      url += '?connect=1';
+    }
+    return url;
+  }
+
   poll() {
     const self = this;
     let service = axios.create({});
@@ -129,18 +137,21 @@ class ExecuteQuery {
       }
     ).catch(
       error => {
-        const errorData = error.response.data;
         // Enable/Disable query tool button only if is_query_tool is true.
         self.sqlServerObject.resetQueryHistoryObject(self.sqlServerObject);
+
         self.loadingScreen.hide();
         if (self.sqlServerObject.is_query_tool) {
           self.enableSQLEditorButtons();
         }
 
-        if (ExecuteQuery.wasConnectionLostToServer(errorData)) {
+        if (ExecuteQuery.wasConnectionLostToPythonServer(error.response)) {
           self.handleConnectionToServerLost();
           return;
         }
+
+        const errorData = error.response.data;
+
         if (self.userManagement.is_pga_login_required(errorData)) {
           return self.userManagement.pga_login();
         }
@@ -159,7 +170,7 @@ class ExecuteQuery {
     $('#btn-flash').prop('disabled', true);
 
     this.sqlServerObject.query_start_time = new Date();
-    if(typeof sqlStatement === 'object') {
+    if (typeof sqlStatement === 'object') {
       this.sqlServerObject.query = sqlStatement['sql'];
     } else {
       this.sqlServerObject.query = sqlStatement;
@@ -182,39 +193,36 @@ class ExecuteQuery {
     this.loadingScreen.hide();
     this.enableSQLEditorButtons();
 
-    if (ExecuteQuery.wasConnectionLostToServer(httpMessage)) {
+    if (ExecuteQuery.wasConnectionLostToPythonServer(httpMessage.response)) {
       this.handleConnectionToServerLost();
       return;
     }
 
-    if (this.userManagement.is_pga_login_required(httpMessage)) {
+    if (this.userManagement.is_pga_login_required(httpMessage.response)) {
       this.sqlServerObject.save_state('execute', [this.explainPlan]);
       this.userManagement.pga_login();
     }
 
-    if (transaction.is_new_transaction_required(httpMessage)) {
+    if (transaction.is_new_transaction_required(httpMessage.response)) {
       this.sqlServerObject.save_state('execute', [this.explainPlan]);
       this.sqlServerObject.init_transaction();
     }
 
-    let msg = httpMessage.errormsg;
-    if (httpMessage.responseJSON !== undefined) {
-      if (httpMessage.responseJSON.errormsg !== undefined) {
-        msg = httpMessage.responseJSON.errormsg;
-      }
-
-      if (httpMessage.status === 503 && httpMessage.responseJSON.info !== undefined &&
-        httpMessage.responseJSON.info === 'CONNECTION_LOST') {
-        setTimeout(function () {
-          this.sqlServerObject.save_state('execute', [this.explainPlan]);
-          this.sqlServerObject.handle_connection_lost(false, httpMessage);
-        });
-      }
+    if (this.wasDatabaseConnectionLost(httpMessage)) {
+      this.sqlServerObject.save_state('execute', [this.explainPlan]);
+      this.sqlServerObject.handle_connection_lost(false, httpMessage);
     }
 
+    let msg = httpMessage.response.data.errormsg;
     this.sqlServerObject.update_msg_history(false, msg);
   }
 
+  wasDatabaseConnectionLost(httpMessage) {
+    return httpMessage.response.status === 503 &&
+      httpMessage.response.data.info !== undefined &&
+      httpMessage.response.data.info === 'CONNECTION_LOST';
+  }
+
   removeGridViewMarker() {
     if (this.sqlServerObject.gridView.marker) {
       this.sqlServerObject.gridView.marker.clear();
@@ -236,8 +244,8 @@ class ExecuteQuery {
     $('#btn-cancel-query').prop('disabled', false);
   }
 
-  static wasConnectionLostToServer(errorMessage) {
-    return errorMessage.readyState === 0;
+  static wasConnectionLostToPythonServer(httpResponse) {
+    return _.isUndefined(httpResponse) || _.isUndefined(httpResponse.data);
   }
 
   handleConnectionToServerLost() {
diff --git a/web/pgadmin/static/js/sqleditor/is_new_transaction_required.js b/web/pgadmin/static/js/sqleditor/is_new_transaction_required.js
index 9d83c926..5b25c19d 100644
--- a/web/pgadmin/static/js/sqleditor/is_new_transaction_required.js
+++ b/web/pgadmin/static/js/sqleditor/is_new_transaction_required.js
@@ -8,7 +8,7 @@
 //////////////////////////////////////////////////////////////////////////
 
 export function is_new_transaction_required(xhr) {
-  return xhr.status === 404 && xhr.responseJSON &&
-    xhr.responseJSON.info &&
-    xhr.responseJSON.info === 'DATAGRID_TRANSACTION_REQUIRED';
+  return xhr.status === 404 && xhr.data &&
+    xhr.data.info &&
+    xhr.data.info === 'DATAGRID_TRANSACTION_REQUIRED';
 }
diff --git a/web/pgadmin/tools/sqleditor/__init__.py b/web/pgadmin/tools/sqleditor/__init__.py
index cc0aa4cf..6f5d5b78 100644
--- a/web/pgadmin/tools/sqleditor/__init__.py
+++ b/web/pgadmin/tools/sqleditor/__init__.py
@@ -298,8 +298,10 @@ def start_query_tool(trans_id):
         request.data, request.args, request.form
     )
 
+    connect = 'connect' in request.args and request.args['connect'] == '1'
+
     return StartRunningQuery(blueprint, current_app).execute(
-        sql, trans_id, session
+        sql, trans_id, session, connect
     )
 
 
diff --git a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
index ff5138d9..923ccead 100644
--- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
+++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
@@ -1847,13 +1847,21 @@ define('tools.querytool', [
       },
 
       handle_connection_lost: function(create_transaction, xhr) {
-        var self= this;
-        if (xhr.responseJSON.data && !xhr.responseJSON.data.conn_id) {
+        /* If responseJSON is undefined then it could be object of
+         * axios(Promise HTTP) response, so we should check accordingly.
+         */
+        if (xhr.responseJSON !== undefined &&
+            xhr.responseJSON.data && !xhr.responseJSON.data.conn_id) {
+          // if conn_id is null then this is maintenance db.
+          // so attempt connection connect without prompt.
+          this.init_connection(create_transaction);
+        } else if (xhr.data !== undefined &&
+          xhr.data.data && !xhr.data.data.conn_id) {
           // if conn_id is null then this is maintenance db.
           // so attempt connection connect without prompt.
-          self.init_connection(create_transaction);
+          this.init_connection(create_transaction);
         } else {
-          self.warn_before_continue();
+          this.warn_before_continue();
         }
       },
       warn_before_continue: function() {
@@ -3730,7 +3738,7 @@ define('tools.querytool', [
 
       // This function will fetch the sql query from the text box
       // and execute the query.
-      execute: function(explain_prefix) {
+      execute: function(explain_prefix, shouldReconnect=false) {
         var self = this,
           sql = '';
 
@@ -3747,7 +3755,7 @@ define('tools.querytool', [
           sql = self.gridView.query_tool_obj.getValue();
 
         const executeQuery = new ExecuteQuery.ExecuteQuery(this, pgAdmin.Browser.UserManagement);
-        executeQuery.execute(sql, explain_prefix);
+        executeQuery.execute(sql, explain_prefix, shouldReconnect);
       },
 
       /* This function is used to highlight the error line and
diff --git a/web/pgadmin/tools/sqleditor/tests/test_start_query_tool.py b/web/pgadmin/tools/sqleditor/tests/test_start_query_tool.py
index 2a50259a..c2ff21c5 100644
--- a/web/pgadmin/tools/sqleditor/tests/test_start_query_tool.py
+++ b/web/pgadmin/tools/sqleditor/tests/test_start_query_tool.py
@@ -42,6 +42,6 @@ class StartQueryTool(BaseTestGenerator):
             self.assertEquals(response.status, '200 OK')
             self.assertEquals(response.data, b'some result')
             StartRunningQuery_execute_mock \
-                .assert_called_with('transformed sql', 1234, ANY)
+                .assert_called_with('transformed sql', 1234, ANY, False)
             extract_sql_from_network_parameters_mock \
                 .assert_called_with(b'"some sql statement"', ANY, ANY)
diff --git a/web/pgadmin/tools/sqleditor/utils/start_running_query.py b/web/pgadmin/tools/sqleditor/utils/start_running_query.py
index 11b946b5..3b3c5020 100644
--- a/web/pgadmin/tools/sqleditor/utils/start_running_query.py
+++ b/web/pgadmin/tools/sqleditor/utils/start_running_query.py
@@ -36,7 +36,7 @@ class StartRunningQuery:
         self.connection_id = str(random.randint(1, 9999999))
         self.logger = logger
 
-    def execute(self, sql, trans_id, http_session):
+    def execute(self, sql, trans_id, http_session, connect=False):
         session_obj = StartRunningQuery.retrieve_session_information(
             http_session,
             trans_id
@@ -68,7 +68,7 @@ class StartRunningQuery:
                 return internal_server_error(errormsg=str(e))
 
             # Connect to the Server if not connected.
-            if not conn.connected():
+            if connect and not conn.connected():
                 status, msg = conn.connect()
                 if not status:
                     self.logger.error(msg)
@@ -108,39 +108,34 @@ class StartRunningQuery:
             self.connection_id = conn_id
 
     def __execute_query(self, conn, session_obj, sql, trans_id, trans_obj):
-        if conn.connected():
-            # on successful connection set the connection id to the
-            # transaction object
-            trans_obj.set_connection_id(self.connection_id)
+        # on successful connection set the connection id to the
+        # transaction object
+        trans_obj.set_connection_id(self.connection_id)
+
+        StartRunningQuery.save_transaction_in_session(session_obj,
+                                                      trans_id, trans_obj)
+
+        # If auto commit is False and transaction status is Idle
+        # then call is_begin_not_required() function to check BEGIN
+        # is required or not.
+
+        if StartRunningQuery.is_begin_required_for_sql_query(trans_obj,
+                                                             conn, sql):
+            conn.execute_void("BEGIN;")
+
+        # Execute sql asynchronously with params is None
+        # and formatted_error is True.
+        try:
+            status, result = conn.execute_async(sql)
+        except ConnectionLost:
+            raise
+
+        # If the transaction aborted for some reason and
+        # Auto RollBack is True then issue a rollback to cleanup.
+        if StartRunningQuery.is_rollback_statement_required(trans_obj,
+                                                            conn):
+            conn.execute_void("ROLLBACK;")
 
-            StartRunningQuery.save_transaction_in_session(session_obj,
-                                                          trans_id, trans_obj)
-
-            # If auto commit is False and transaction status is Idle
-            # then call is_begin_not_required() function to check BEGIN
-            # is required or not.
-
-            if StartRunningQuery.is_begin_required_for_sql_query(trans_obj,
-                                                                 conn, sql):
-                conn.execute_void("BEGIN;")
-
-            # Execute sql asynchronously with params is None
-            # and formatted_error is True.
-            try:
-                status, result = conn.execute_async(sql)
-            except ConnectionLost:
-                raise
-
-            # If the transaction aborted for some reason and
-            # Auto RollBack is True then issue a rollback to cleanup.
-            if StartRunningQuery.is_rollback_statement_required(trans_obj,
-                                                                conn):
-                conn.execute_void("ROLLBACK;")
-        else:
-            status = False
-            result = gettext(
-                'Not connected to server or connection with the server has '
-                'been closed.')
         return result, status
 
     @staticmethod
diff --git a/web/pgadmin/tools/sqleditor/utils/tests/test_start_running_query.py b/web/pgadmin/tools/sqleditor/utils/tests/test_start_running_query.py
index 23a5c7fc..4ad0891a 100644
--- a/web/pgadmin/tools/sqleditor/utils/tests/test_start_running_query.py
+++ b/web/pgadmin/tools/sqleditor/utils/tests/test_start_running_query.py
@@ -21,6 +21,7 @@ else:
     from unittest.mock import patch, MagicMock
 
 get_driver_exception = Exception('get_driver exception')
+get_connection_lost_exception = Exception('Unable to connect to server')
 
 
 class StartRunningQueryTest(BaseTestGenerator):
@@ -38,6 +39,7 @@ class StartRunningQueryTest(BaseTestGenerator):
              ),
              pickle_load_return=None,
              get_driver_exception=False,
+             get_connection_lost_exception=False,
              manager_connection_exception=None,
 
              is_connected_to_server=False,
@@ -67,6 +69,7 @@ class StartRunningQueryTest(BaseTestGenerator):
              ),
              pickle_load_return=None,
              get_driver_exception=False,
+             get_connection_lost_exception=False,
              manager_connection_exception=None,
 
              is_connected_to_server=False,
@@ -97,6 +100,7 @@ class StartRunningQueryTest(BaseTestGenerator):
              ),
              pickle_load_return=None,
              get_driver_exception=False,
+             get_connection_lost_exception=False,
              manager_connection_exception=None,
 
              is_connected_to_server=False,
@@ -131,6 +135,7 @@ class StartRunningQueryTest(BaseTestGenerator):
              pickle_load_return=MagicMock(conn_id=1,
                                           update_fetched_row_cnt=MagicMock()),
              get_driver_exception=True,
+             get_connection_lost_exception=False,
              manager_connection_exception=None,
 
              is_connected_to_server=False,
@@ -161,6 +166,7 @@ class StartRunningQueryTest(BaseTestGenerator):
                  update_fetched_row_cnt=MagicMock()
              ),
              get_driver_exception=False,
+             get_connection_lost_exception=False,
              manager_connection_exception=ConnectionLost('1', '2', '3'),
 
              is_connected_to_server=False,
@@ -188,6 +194,7 @@ class StartRunningQueryTest(BaseTestGenerator):
                  update_fetched_row_cnt=MagicMock()
              ),
              get_driver_exception=False,
+             get_connection_lost_exception=True,
              manager_connection_exception=None,
 
              is_connected_to_server=False,
@@ -202,7 +209,7 @@ class StartRunningQueryTest(BaseTestGenerator):
              expect_internal_server_error_called_with=dict(
                  errormsg='Unable to connect to server'
              ),
-             expected_logger_error='Unable to connect to server',
+             expected_logger_error=get_connection_lost_exception,
              expect_execute_void_called_with='some sql',
          )),
         ('When server is connected and start query async request, '
@@ -223,6 +230,7 @@ class StartRunningQueryTest(BaseTestGenerator):
                  can_filter=lambda: True
              ),
              get_driver_exception=False,
+             get_connection_lost_exception=False,
              manager_connection_exception=None,
 
              is_connected_to_server=True,
@@ -265,6 +273,7 @@ class StartRunningQueryTest(BaseTestGenerator):
                  can_filter=lambda: True
              ),
              get_driver_exception=False,
+             get_connection_lost_exception=False,
              manager_connection_exception=None,
 
              is_connected_to_server=True,
@@ -307,6 +316,7 @@ class StartRunningQueryTest(BaseTestGenerator):
                  can_filter=lambda: True
              ),
              get_driver_exception=False,
+             get_connection_lost_exception=False,
              manager_connection_exception=None,
 
              is_connected_to_server=True,
@@ -349,6 +359,7 @@ class StartRunningQueryTest(BaseTestGenerator):
                  can_filter=lambda: True
              ),
              get_driver_exception=False,
+             get_connection_lost_exception=False,
              manager_connection_exception=None,
 
              is_connected_to_server=True,
@@ -431,6 +442,8 @@ class StartRunningQueryTest(BaseTestGenerator):
         manager = self.__create_manager()
         if self.get_driver_exception:
             get_driver_mock.side_effect = get_driver_exception
+        elif self.get_connection_lost_exception:
+            get_driver_mock.side_effect = get_connection_lost_exception
         else:
             get_driver_mock.return_value = MagicMock(
                 connection_manager=lambda session_id: manager)
diff --git a/web/pgadmin/tools/user_management/static/js/user_management.js b/web/pgadmin/tools/user_management/static/js/user_management.js
index 2a3b2f07..26273280 100644
--- a/web/pgadmin/tools/user_management/static/js/user_management.js
+++ b/web/pgadmin/tools/user_management/static/js/user_management.js
@@ -130,9 +130,18 @@ define([
     },
 
     is_pga_login_required(xhr) {
-      return xhr.status == 401 && xhr.responseJSON &&
+      /* If responseJSON is undefined then it could be object of
+       * axios(Promise HTTP) response, so we should check accordingly.
+       */
+      if (xhr.responseJSON === undefined && xhr.data !== undefined) {
+        return xhr.status === 401 && xhr.data &&
+                  xhr.data.info &&
+                  xhr.data.info === 'PGADMIN_LOGIN_REQUIRED';
+      }
+
+      return xhr.status === 401 && xhr.responseJSON &&
                 xhr.responseJSON.info &&
-                xhr.responseJSON.info == 'PGADMIN_LOGIN_REQUIRED';
+                xhr.responseJSON.info === 'PGADMIN_LOGIN_REQUIRED';
     },
 
     // Callback to draw pgAdmin4 login dialog.
diff --git a/web/regression/javascript/sqleditor/execute_query_spec.js b/web/regression/javascript/sqleditor/execute_query_spec.js
index 98faed7d..5f92dc50 100644
--- a/web/regression/javascript/sqleditor/execute_query_spec.js
+++ b/web/regression/javascript/sqleditor/execute_query_spec.js
@@ -42,6 +42,7 @@ describe('ExecuteQuery', () => {
       '_init_polling_flags',
       'save_state',
       'init_transaction',
+      'handle_connection_lost',
     ]);
     sqlEditorMock.transId = 123;
     sqlEditorMock.rows_affected = 1000;
@@ -49,6 +50,10 @@ describe('ExecuteQuery', () => {
     isNewTransactionRequiredMock = spyOn(transaction, 'is_new_transaction_required');
   });
 
+  afterEach(() => {
+    networkMock.restore();
+  });
+
   describe('#poll', () => {
     let cancelButtonSpy;
     let response;
@@ -62,9 +67,6 @@ describe('ExecuteQuery', () => {
       executeQuery.delayedPoll = jasmine.createSpy('ExecuteQuery.delayedPoll');
     });
 
-    afterEach(() => {
-    });
-
     context('when SQLEditor is the query tool', () => {
       beforeEach(() => {
         sqlEditorMock.is_query_tool = true;
@@ -569,8 +571,7 @@ describe('ExecuteQuery', () => {
 
           describe('when cannot reach the Python Server', () => {
             beforeEach(() => {
-              response = {readyState: 0};
-              networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, response);
+              networkMock.onGet('/sqleditor/query_tool/poll/123').reply(404, undefined);
 
               executeQuery.poll();
             });
@@ -972,8 +973,7 @@ describe('ExecuteQuery', () => {
 
           describe('when cannot reach the Python Server', () => {
             beforeEach(() => {
-              response = {readyState: 0};
-              networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, response);
+              networkMock.onGet('/sqleditor/query_tool/poll/123').reply(404, undefined);
 
               executeQuery.poll();
             });
@@ -1143,9 +1143,9 @@ describe('ExecuteQuery', () => {
       describe('when HTTP return 200', () => {
         describe('when backend informs that query started successfully', () => {
           beforeEach(() => {
-            networkMock.onAny('/sqleditor/query_tool/start/123').reply(200, response);
+            networkMock.onPost('/sqleditor/query_tool/start/123?connect=1').reply(200, response);
             pollSpy = spyOn(executeQuery, 'delayedPoll');
-            executeQuery.execute('some sql query', '');
+            executeQuery.execute('some sql query', '', true);
           });
 
           it('should changes the loading message to "Waiting for the query execution to complete"', (done) => {
@@ -1310,10 +1310,7 @@ describe('ExecuteQuery', () => {
 
       describe('when cannot reach the Python Server', () => {
         beforeEach(() => {
-          response = {
-            readyState: 0,
-          };
-          networkMock.onAny('/sqleditor/query_tool/start/123').reply(500, response);
+          networkMock.onAny('/sqleditor/query_tool/start/123').reply(500, undefined);
 
 
           executeQuery.execute('some sql query', '');
@@ -1657,7 +1654,32 @@ describe('ExecuteQuery', () => {
             }, 0);
           });
         });
+        describe('when connection to database is lost', () => {
+          beforeEach(() => {
+            isNewTransactionRequiredMock.and.returnValue(false);
+            response.info = 'CONNECTION_LOST';
+            networkMock.onAny('/sqleditor/query_tool/start/123').reply(503, response);
+
+            executeQuery.execute('some sql query', '');
+          });
+
+          it('saves state', () => {
+            setTimeout(() => {
+              expect(sqlEditorMock.save_state).toHaveBeenCalledWith(
+                'execute',
+                ['']
+              );
+            }, 0);
+          });
+
+          it('calls handle_connection_lost', () => {
+            setTimeout(() => {
+              expect(sqlEditorMock.handle_connection_lost).toHaveBeenCalled();
+            }, 0);
+          });
+        });
       });
+
     });
   });
 
diff --git a/web/regression/javascript/sqleditor/is_new_transaction_required_spec.js b/web/regression/javascript/sqleditor/is_new_transaction_required_spec.js
index d323700d..97d1bc52 100644
--- a/web/regression/javascript/sqleditor/is_new_transaction_required_spec.js
+++ b/web/regression/javascript/sqleditor/is_new_transaction_required_spec.js
@@ -19,7 +19,7 @@ describe('#is_new_transaction_required', () => {
   });
 
   describe('when status is 404', () => {
-    describe('when responseJSON is not present', () => {
+    describe('when data is not present', () => {
       it('should return false', () => {
         expect(is_new_transaction_required({
           status: 404,
@@ -27,22 +27,22 @@ describe('#is_new_transaction_required', () => {
       });
     });
 
-    describe('when responseJSON is present', () => {
-      describe('when info is not present inside responseJSON', () => {
+    describe('when data is present', () => {
+      describe('when info is not present inside data', () => {
         it('should return false', () => {
           expect(is_new_transaction_required({
             status: 404,
-            responseJSON: {},
+            data: {},
           })).toBeFalsy();
         });
       });
 
-      describe('when info is present inside responseJSON', () => {
+      describe('when info is present inside data', () => {
         describe('when info value is not "DATAGRID_TRANSACTION_REQUIRED"', () => {
           it('should return false', () => {
             expect(is_new_transaction_required({
               status: 404,
-              responseJSON: {
+              data: {
                 info: 'some information',
               },
             })).toBe(false);
@@ -53,7 +53,7 @@ describe('#is_new_transaction_required', () => {
           it('should return false', () => {
             expect(is_new_transaction_required({
               status: 404,
-              responseJSON: {
+              data: {
                 info: 'DATAGRID_TRANSACTION_REQUIRED',
               },
             })).toBe(true);

Reply via email to