public inbox for [email protected]
help / color / mirror / Atom feed[pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
19+ messages / 6 participants
[nested] [flat]
* [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-02-02 22:50 Joao De Almeida Pereira <[email protected]>
0 siblings, 2 replies; 19+ messages in thread
From: Joao De Almeida Pereira @ 2018-02-02 22:50 UTC (permalink / raw)
To: pgadmin-hackers
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
Attachments:
[application/octet-stream] explain-plan-greenplum.diff (182.4K, 3-explain-plan-greenplum.diff)
download | inline diff:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/tests/test_utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/tests/test_utils.py
new file mode 100644
index 00000000..e69de29b
diff --git a/web/pgadmin/static/js/sqleditor/execute_query.js b/web/pgadmin/static/js/sqleditor/execute_query.js
new file mode 100644
index 00000000..e91c9e85
--- /dev/null
+++ b/web/pgadmin/static/js/sqleditor/execute_query.js
@@ -0,0 +1,287 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2018, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////////////////
+
+import gettext from '../gettext';
+import $ from 'jquery';
+import url_for from '../url_for';
+import axios from 'axios';
+import * as transaction from './is_new_transaction_required';
+
+class LoadingScreen {
+ constructor(sqlEditor) {
+ this.sqlEditor = sqlEditor;
+ }
+
+ setMessage(message) {
+ this.sqlEditor.trigger(
+ 'pgadmin-sqleditor:loading-icon:message',
+ gettext(message)
+ );
+ }
+
+ show(withMessage) {
+ this.sqlEditor.trigger(
+ 'pgadmin-sqleditor:loading-icon:show',
+ withMessage
+ );
+ }
+
+ hide() {
+ this.sqlEditor.trigger('pgadmin-sqleditor:loading-icon:hide');
+ }
+}
+
+class ExecuteQuery {
+ constructor(sqlEditor, userManagement) {
+ this.sqlServerObject = sqlEditor;
+ this.loadingScreen = new LoadingScreen(sqlEditor);
+ this.userManagement = userManagement;
+ }
+
+ delayedPoll() {
+ const self = this;
+ setTimeout(
+ () => {
+ self.poll();
+ }, self.sqlServerObject.POLL_FALLBACK_TIME());
+ }
+
+ execute(sqlStatement, explainPlan) {
+ // If it is an empty query, do nothing.
+ if (sqlStatement.length <= 0) return;
+
+ const self = this;
+ let service = axios.create({});
+ self.explainPlan = explainPlan;
+
+ const sqlStatementWithAnalyze = ExecuteQuery.prepareAnalyzeSql(sqlStatement, explainPlan);
+
+ self.initializeExecutionOnSqlEditor(sqlStatementWithAnalyze);
+
+ service.post(
+ url_for('sqleditor.query_tool_start', {
+ 'trans_id': self.sqlServerObject.transId,
+ }),
+ JSON.stringify(sqlStatementWithAnalyze),
+ {headers: {'Content-Type': 'application/json'}})
+ .then(function (result) {
+ let httpMessageData = result.data;
+ self.removeGridViewMarker();
+
+ if (ExecuteQuery.isSqlCorrect(httpMessageData)) {
+ self.loadingScreen.setMessage('Waiting for the query execution to complete...');
+
+ self.updateSqlEditorStateWithInformationFromServer(httpMessageData.data);
+
+ // If status is True then poll the result.
+ self.delayedPoll();
+ } else {
+ self.loadingScreen.hide();
+ self.enableSQLEditorButtons();
+ self.sqlServerObject.update_msg_history(false, httpMessageData.data.result);
+
+ // Highlight the error in the sql panel
+ self.sqlServerObject._highlight_error(httpMessageData.data.result);
+ }
+ }).catch(function (error) {
+ self.onExecuteHTTPError(error.response.data);
+ }
+ );
+ }
+
+ poll() {
+ const self = this;
+ let service = axios.create({});
+ service.get(
+ url_for('sqleditor.poll', {
+ 'trans_id': self.sqlServerObject.transId,
+ })
+ ).then(
+ (httpMessage) => {
+ if (ExecuteQuery.isQueryFinished(httpMessage)) {
+ self.loadingScreen.setMessage('Loading data from the database server and rendering...');
+
+ self.sqlServerObject.call_render_after_poll(httpMessage.data.data);
+ } else if (ExecuteQuery.isQueryStillRunning(httpMessage)) {
+ // If status is Busy then poll the result by recursive call to the poll function
+ this.delayedPoll();
+ self.sqlServerObject.setIsQueryRunning(true);
+ if (httpMessage.data.data.result) {
+ self.sqlServerObject.update_msg_history(httpMessage.data.data.status, httpMessage.data.data.result, false);
+ }
+ } else if (ExecuteQuery.isConnectionToServerLostWhilePolling(httpMessage)) {
+ self.loadingScreen.hide();
+ // Enable/Disable query tool button only if is_query_tool is true.
+ if (self.sqlServerObject.is_query_tool) {
+ self.enableSQLEditorButtons();
+ }
+ self.sqlServerObject.update_msg_history(false, httpMessage.data.data.result, true);
+ } else if (ExecuteQuery.isQueryCancelled(httpMessage)) {
+ self.loadingScreen.hide();
+ self.sqlServerObject.update_msg_history(false, 'Execution Cancelled!', true);
+ }
+ }
+ ).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)) {
+ self.handleConnectionToServerLost();
+ return;
+ }
+ if (self.userManagement.is_pga_login_required(errorData)) {
+ return self.userManagement.pga_login();
+ }
+
+ let msg = ExecuteQuery.extractErrorMessage(errorData);
+
+ self.sqlServerObject.update_msg_history(false, msg);
+ // Highlight the error in the sql panel
+ self.sqlServerObject._highlight_error(msg);
+ });
+ }
+
+ initializeExecutionOnSqlEditor(sqlStatement) {
+ this.loadingScreen.show('Initializing query execution...');
+
+ $('#btn-flash').prop('disabled', true);
+
+ this.sqlServerObject.query_start_time = new Date();
+ if(typeof sqlStatement === 'object') {
+ this.sqlServerObject.query = sqlStatement['sql'];
+ } else {
+ this.sqlServerObject.query = sqlStatement;
+ }
+
+ this.sqlServerObject.rows_affected = 0;
+ this.sqlServerObject._init_polling_flags();
+ this.disableSQLEditorButtons();
+ }
+
+ static prepareAnalyzeSql(sqlStatement, analyzeSql) {
+ let sqlStatementWithAnalyze = {
+ sql: sqlStatement,
+ explain_plan: analyzeSql,
+ };
+ return sqlStatementWithAnalyze;
+ }
+
+ onExecuteHTTPError(httpMessage) {
+ this.loadingScreen.hide();
+ this.enableSQLEditorButtons();
+
+ if (ExecuteQuery.wasConnectionLostToServer(httpMessage)) {
+ this.handleConnectionToServerLost();
+ return;
+ }
+
+ if (this.userManagement.is_pga_login_required(httpMessage)) {
+ this.sqlServerObject.save_state('execute', [this.explainPlan]);
+ this.userManagement.pga_login();
+ }
+
+ if (transaction.is_new_transaction_required(httpMessage)) {
+ 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);
+ });
+ }
+ }
+
+ this.sqlServerObject.update_msg_history(false, msg);
+ }
+
+ removeGridViewMarker() {
+ if (this.sqlServerObject.gridView.marker) {
+ this.sqlServerObject.gridView.marker.clear();
+ delete this.sqlServerObject.gridView.marker;
+ this.sqlServerObject.gridView.marker = null;
+
+ // Remove already existing marker
+ this.sqlServerObject.gridView.query_tool_obj.removeLineClass(this.sqlServerObject.marked_line_no, 'wrap', 'CodeMirror-activeline-background');
+ }
+ }
+
+ enableSQLEditorButtons() {
+ this.sqlServerObject.disable_tool_buttons(false);
+ $('#btn-cancel-query').prop('disabled', true);
+ }
+
+ disableSQLEditorButtons() {
+ this.sqlServerObject.disable_tool_buttons(true);
+ $('#btn-cancel-query').prop('disabled', false);
+ }
+
+ static wasConnectionLostToServer(errorMessage) {
+ return errorMessage.readyState === 0;
+ }
+
+ handleConnectionToServerLost() {
+ this.sqlServerObject.update_msg_history(false,
+ gettext('Not connected to the server or the connection to the server has been closed.')
+ );
+ }
+
+ updateSqlEditorStateWithInformationFromServer(messageData) {
+ this.sqlServerObject.can_edit = messageData.can_edit;
+ this.sqlServerObject.can_filter = messageData.can_filter;
+ this.sqlServerObject.info_notifier_timeout = messageData.info_notifier_timeout;
+ }
+
+ static isSqlCorrect(httpMessageData) {
+ return httpMessageData.data.status;
+ }
+
+ static extractErrorMessage(httpMessage) {
+ let msg = httpMessage.errormsg;
+ if (httpMessage.responseJSON !== undefined &&
+ httpMessage.responseJSON.errormsg !== undefined)
+ msg = httpMessage.responseJSON.errormsg;
+
+ return msg;
+ }
+
+ static isQueryFinished(httpMessage) {
+ return httpMessage.data.data.status === 'Success';
+ }
+
+ static isQueryStillRunning(httpMessage) {
+ return httpMessage.data.data.status === 'Busy';
+ }
+
+ static isQueryCancelled(httpMessage) {
+ return httpMessage.data.data.status === 'Cancel';
+ }
+
+ static isConnectionToServerLostWhilePolling(httpMessage) {
+ return httpMessage.data.data.status === 'NotConnected';
+ }
+}
+
+module.exports = {
+ ExecuteQuery: ExecuteQuery,
+};
diff --git a/web/pgadmin/static/js/sqleditor/is_new_transaction_required.js b/web/pgadmin/static/js/sqleditor/is_new_transaction_required.js
new file mode 100644
index 00000000..9d83c926
--- /dev/null
+++ b/web/pgadmin/static/js/sqleditor/is_new_transaction_required.js
@@ -0,0 +1,14 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2018, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////////////////
+
+export function is_new_transaction_required(xhr) {
+ return xhr.status === 404 && xhr.responseJSON &&
+ xhr.responseJSON.info &&
+ xhr.responseJSON.info === 'DATAGRID_TRANSACTION_REQUIRED';
+}
diff --git a/web/pgadmin/static/js/sqleditor/query_tool_actions.js b/web/pgadmin/static/js/sqleditor/query_tool_actions.js
index 44a674b8..01d19215 100644
--- a/web/pgadmin/static/js/sqleditor/query_tool_actions.js
+++ b/web/pgadmin/static/js/sqleditor/query_tool_actions.js
@@ -2,19 +2,19 @@ import $ from 'jquery';
let queryToolActions = {
_verbose: function () {
- return $('.explain-verbose').hasClass('visibility-hidden') ? 'OFF' : 'ON';
+ return !$('.explain-verbose').hasClass('visibility-hidden');
},
_costsEnabled: function () {
- return $('.explain-costs').hasClass('visibility-hidden') ? 'OFF' : 'ON';
+ return !$('.explain-costs').hasClass('visibility-hidden');
},
_buffers: function () {
- return $('.explain-buffers').hasClass('visibility-hidden') ? 'OFF' : 'ON';
+ return !$('.explain-buffers').hasClass('visibility-hidden');
},
_timing: function () {
- return $('.explain-timing').hasClass('visibility-hidden') ? 'OFF' : 'ON';
+ return !$('.explain-timing').hasClass('visibility-hidden');
},
_clearMessageTab: function () {
@@ -35,18 +35,35 @@ let queryToolActions = {
let verbose = this._verbose();
let buffers = this._buffers();
let timing = this._timing();
- let explainAnalyzeQuery = `EXPLAIN (FORMAT JSON, ANALYZE ON, VERBOSE ${verbose}, COSTS ${costEnabled}, BUFFERS ${buffers}, TIMING ${timing}) `;
+ const explainObject = {
+ format: 'json',
+ analyze: true,
+ verbose: verbose,
+ costs: costEnabled,
+ buffers: buffers,
+ timing: timing,
+ summary: false,
+ };
this._clearMessageTab();
- sqlEditorController.execute(explainAnalyzeQuery);
+ sqlEditorController.execute(explainObject);
},
explain: function (sqlEditorController) {
let costEnabled = this._costsEnabled();
let verbose = this._verbose();
- let explainQuery = `EXPLAIN (FORMAT JSON, ANALYZE OFF, VERBOSE ${verbose}, COSTS ${costEnabled}, BUFFERS OFF, TIMING OFF) `;
+ // let explainQuery = `EXPLAIN (FORMAT JSON, ANALYZE OFF, VERBOSE ${verbose}, COSTS ${costEnabled}, BUFFERS OFF, TIMING OFF) `;
+ const explainObject = {
+ format: 'json',
+ analyze: false,
+ verbose: verbose,
+ costs: costEnabled,
+ buffers: false,
+ timing: false,
+ summary: false,
+ };
this._clearMessageTab();
- sqlEditorController.execute(explainQuery);
+ sqlEditorController.execute(explainObject);
},
download: function (sqlEditorController) {
diff --git a/web/pgadmin/tools/sqleditor/__init__.py b/web/pgadmin/tools/sqleditor/__init__.py
index b1ca3b87..f8870036 100644
--- a/web/pgadmin/tools/sqleditor/__init__.py
+++ b/web/pgadmin/tools/sqleditor/__init__.py
@@ -8,28 +8,32 @@
##########################################################################
"""A blueprint module implementing the sqleditor frame."""
-import simplejson as json
+import codecs
import os
import pickle
import random
-import codecs
-from flask import Response, url_for, render_template, session, request,\
+import simplejson as json
+from flask import Response, url_for, render_template, session, request, \
current_app
from flask_babel import gettext
from flask_security import login_required
+
+from config import PG_DEFAULT_DRIVER, ON_DEMAND_RECORD_COUNT
+from pgadmin.misc.file_manager import Filemanager
from pgadmin.tools.sqleditor.command import QueryToolCommand
+from pgadmin.tools.sqleditor.utils.constant_definition import ASYNC_OK, ASYNC_EXECUTION_ABORTED, \
+ CONNECTION_STATUS_MESSAGE_MAPPING, TX_STATUS_INERROR
+from pgadmin.tools.sqleditor.utils.start_running_query import StartRunningQuery
+from pgadmin.tools.sqleditor.utils.update_session_grid_transaction import update_session_grid_transaction
from pgadmin.utils import PgAdminModule
from pgadmin.utils import get_storage_directory
from pgadmin.utils.ajax import make_json_response, bad_request, \
success_return, internal_server_error, unauthorized
from pgadmin.utils.driver import get_driver
-from pgadmin.utils.sqlautocomplete.autocomplete import SQLAutoComplete
-from pgadmin.misc.file_manager import Filemanager
from pgadmin.utils.menu import MenuItem
from pgadmin.utils.exception import ConnectionLost
-
-from config import PG_DEFAULT_DRIVER, ON_DEMAND_RECORD_COUNT
+from pgadmin.utils.sqlautocomplete.autocomplete import SQLAutoComplete
MODULE_NAME = 'sqleditor'
@@ -39,28 +43,6 @@ try:
except ImportError:
from urllib.parse import unquote
-# Async Constants
-ASYNC_OK = 1
-ASYNC_READ_TIMEOUT = 2
-ASYNC_WRITE_TIMEOUT = 3
-ASYNC_NOT_CONNECTED = 4
-ASYNC_EXECUTION_ABORTED = 5
-
-# Transaction status constants
-TX_STATUS_IDLE = 0
-TX_STATUS__ACTIVE = 1
-TX_STATUS_INTRANS = 2
-TX_STATUS_INERROR = 3
-
-# Connection status codes mapping
-CONNECTION_STATUS_MESSAGE_MAPPING = dict([
- (0, 'The session is idle and there is no current transaction.'),
- (1, 'A command is currently in progress.'),
- (2, 'The session is idle in a valid transaction block.'),
- (3, 'The session is idle in a failed transaction block.'),
- (4, 'The connection with the server is bad.')
-])
-
class SqlEditorModule(PgAdminModule):
"""
@@ -376,13 +358,6 @@ def index():
)
-def update_session_grid_transaction(trans_id, data):
- if 'gridData' in session:
- grid_data = session['gridData']
- grid_data[str(trans_id)] = data
- session['gridData'] = grid_data
-
-
def check_transaction_status(trans_id):
"""
This function is used to check the transaction id
@@ -458,7 +433,7 @@ def start_view_data(trans_id):
check_transaction_status(trans_id)
if error_msg == gettext(
- 'Transaction ID not found in the session.'):
+ 'Transaction ID not found in the session.'):
return make_json_response(success=0, errormsg=error_msg,
info='DATAGRID_TRANSACTION_REQUIRED',
status=404)
@@ -486,7 +461,7 @@ def start_view_data(trans_id):
)
if status and conn is not None \
- and trans_obj is not None and session_obj is not None:
+ and trans_obj is not None and session_obj is not None:
# set fetched row count to 0 as we are executing query again.
trans_obj.update_fetched_row_cnt(0)
session_obj['command_obj'] = pickle.dumps(trans_obj, -1)
@@ -554,107 +529,19 @@ def start_query_tool(trans_id):
trans_id: unique transaction id
"""
- if request.data:
- sql = json.loads(request.data, encoding='utf-8')
- else:
- sql = request.args or request.form
-
- connect = True if 'connect' in request.args and \
- request.args['connect'] == '1' else False
-
- if 'gridData' not in session:
- return make_json_response(
- success=0,
- errormsg=gettext('Transaction ID not found in the session.'),
- info='DATAGRID_TRANSACTION_REQUIRED', status=404)
-
- grid_data = session['gridData']
-
- # Return from the function if transaction id not found
- if str(trans_id) not in grid_data:
- return make_json_response(
- success=0,
- errormsg=gettext('Transaction ID not found in the session.'),
- info='DATAGRID_TRANSACTION_REQUIRED',
- status=404)
-
- # Fetch the object for the specified transaction id.
- # Use pickle.loads function to get the command object
- session_obj = grid_data[str(trans_id)]
- trans_obj = pickle.loads(session_obj['command_obj'])
- # set fetched row count to 0 as we are executing query again.
- trans_obj.update_fetched_row_cnt(0)
-
- can_edit = False
- can_filter = False
+ sql = extract_sql_from_network_parameters(request.data, request.args, request.form)
- if trans_obj is not None and session_obj is not None:
- conn_id = trans_obj.conn_id
- try:
- manager = get_driver(
- PG_DEFAULT_DRIVER).connection_manager(trans_obj.sid)
- conn = manager.connection(did=trans_obj.did, conn_id=conn_id,
- auto_reconnect=False,
- use_binary_placeholder=True,
- array_to_string=True)
- except ConnectionLost as e:
- raise
- except Exception as e:
- current_app.logger.error(e)
- return internal_server_error(errormsg=str(e))
+ return StartRunningQuery(blueprint, current_app).execute(sql, trans_id, session)
- # Connect to the Server if not connected.
- if connect and not conn.connected():
- status, msg = conn.connect()
- if not status:
- current_app.logger.error(msg)
- return internal_server_error(errormsg=str(msg))
-
- # on successful connection set the connection id to the
- # transaction object
- trans_obj.set_connection_id(conn_id)
-
- # As we changed the transaction object we need to
- # restore it and update the session variable.
- session_obj['command_obj'] = pickle.dumps(trans_obj, -1)
- update_session_grid_transaction(trans_id, session_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 not trans_obj.auto_commit \
- and conn.transaction_status() == TX_STATUS_IDLE \
- and is_begin_required(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 as e:
- raise
- # If the transaction aborted for some reason and
- # Auto RollBack is True then issue a rollback to cleanup.
- trans_status = conn.transaction_status()
- if trans_status == TX_STATUS_INERROR and trans_obj.auto_rollback:
- conn.execute_void("ROLLBACK;")
-
- can_edit = trans_obj.can_edit()
- can_filter = trans_obj.can_filter()
+def extract_sql_from_network_parameters(request_data, request_arguments, request_form_data):
+ if request_data:
+ sql_parameters = json.loads(request_data, encoding='utf-8')
+ if type(sql_parameters) is str:
+ return dict(sql=sql_parameters, explain_plan=None)
+ return sql_parameters
else:
- status = False
- result = gettext(
- 'Either transaction object or session object not found.')
-
- return make_json_response(
- data={
- 'status': status, 'result': result,
- 'can_edit': can_edit, 'can_filter': can_filter,
- 'info_notifier_timeout': blueprint.info_notifier_timeout.get()
- }
- )
+ return request_arguments or request_form_data
@blueprint.route(
@@ -675,13 +562,13 @@ def preferences(trans_id):
check_transaction_status(trans_id)
if error_msg == gettext(
- 'Transaction ID not found in the session.'):
+ 'Transaction ID not found in the session.'):
return make_json_response(success=0, errormsg=error_msg,
info='DATAGRID_TRANSACTION_REQUIRED',
status=404)
if status and conn is not None \
- and trans_obj is not None and session_obj is not None:
+ and trans_obj is not None and session_obj is not None:
# Call the set_auto_commit and set_auto_rollback method of
# transaction object
trans_obj.set_auto_commit(blueprint.auto_commit.get())
@@ -751,7 +638,7 @@ def poll(trans_id):
check_transaction_status(trans_id)
if error_msg == gettext(
- 'Transaction ID not found in the session.'):
+ 'Transaction ID not found in the session.'):
return make_json_response(success=0, errormsg=error_msg,
info='DATAGRID_TRANSACTION_REQUIRED',
status=404)
@@ -779,7 +666,7 @@ def poll(trans_id):
if isinstance(trans_obj, QueryToolCommand):
trans_status = conn.transaction_status()
if (trans_status == TX_STATUS_INERROR and
- trans_obj.auto_rollback):
+ trans_obj.auto_rollback):
conn.execute_void("ROLLBACK;")
st, result = conn.async_fetchmany_2darray(ON_DEMAND_RECORD_COUNT)
@@ -854,15 +741,15 @@ def poll(trans_id):
typname == 'character varying'
):
typname = typname + '(' + \
- str(col_info['internal_size']) + \
- ')'
+ str(col_info['internal_size']) + \
+ ')'
elif (
typname == 'character[]' or
typname == 'character varying[]'
):
typname = typname[:-2] + '(' + \
- str(col_info['internal_size']) + \
- ')[]'
+ str(col_info['internal_size']) + \
+ ')[]'
col_info['type_name'] = typname
@@ -913,7 +800,7 @@ def poll(trans_id):
if status == 'Success' and result is None:
result = conn.status_message()
if (result != 'SELECT 1' or result != 'SELECT 0') \
- and result is not None and additional_messages:
+ and result is not None and additional_messages:
result = additional_messages + result
return make_json_response(
@@ -954,7 +841,7 @@ def fetch(trans_id, fetch_all=None):
check_transaction_status(trans_id)
if error_msg == gettext(
- 'Transaction ID not found in the session.'):
+ 'Transaction ID not found in the session.'):
return make_json_response(success=0, errormsg=error_msg,
info='DATAGRID_TRANSACTION_REQUIRED',
status=404)
@@ -1018,7 +905,7 @@ def fetch_pg_types(columns_info, trans_obj):
if oids:
status, res = default_conn.execute_dict(
- u"SELECT oid, format_type(oid,null) as typname FROM pg_type "
+ u"SELECT oid, format_type(oid,NULL) AS typname FROM pg_type "
u"WHERE oid IN %s ORDER BY oid;", [tuple(oids)]
)
@@ -1077,17 +964,17 @@ def save(trans_id):
check_transaction_status(trans_id)
if error_msg == gettext(
- 'Transaction ID not found in the session.'):
+ 'Transaction ID not found in the session.'):
return make_json_response(success=0, errormsg=error_msg,
info='DATAGRID_TRANSACTION_REQUIRED',
status=404)
if status and conn is not None \
- and trans_obj is not None and session_obj is not None:
+ and trans_obj is not None and session_obj is not None:
# If there is no primary key found then return from the function.
if (len(session_obj['primary_keys']) <= 0 or len(changed_data) <= 0) \
- and 'has_oids' not in session_obj:
+ and 'has_oids' not in session_obj:
return make_json_response(
data={
'status': False,
@@ -1146,12 +1033,12 @@ def get_filter(trans_id):
check_transaction_status(trans_id)
if error_msg == gettext(
- 'Transaction ID not found in the session.'):
+ 'Transaction ID not found in the session.'):
return make_json_response(success=0, errormsg=error_msg,
info='DATAGRID_TRANSACTION_REQUIRED',
status=404)
if status and conn is not None \
- and trans_obj is not None and session_obj is not None:
+ and trans_obj is not None and session_obj is not None:
res = trans_obj.get_filter()
else:
@@ -1183,13 +1070,13 @@ def apply_filter(trans_id):
check_transaction_status(trans_id)
if error_msg == gettext(
- 'Transaction ID not found in the session.'):
+ 'Transaction ID not found in the session.'):
return make_json_response(success=0, errormsg=error_msg,
info='DATAGRID_TRANSACTION_REQUIRED',
status=404)
if status and conn is not None \
- and trans_obj is not None and session_obj is not None:
+ and trans_obj is not None and session_obj is not None:
status, res = trans_obj.set_filter(filter_sql)
@@ -1226,13 +1113,13 @@ def append_filter_inclusive(trans_id):
check_transaction_status(trans_id)
if error_msg == gettext(
- 'Transaction ID not found in the session.'):
+ 'Transaction ID not found in the session.'):
return make_json_response(success=0, errormsg=error_msg,
info='DATAGRID_TRANSACTION_REQUIRED',
status=404)
if status and conn is not None \
- and trans_obj is not None and session_obj is not None:
+ and trans_obj is not None and session_obj is not None:
res = None
filter_sql = ''
@@ -1282,12 +1169,12 @@ def append_filter_exclusive(trans_id):
check_transaction_status(trans_id)
if error_msg == gettext(
- 'Transaction ID not found in the session.'):
+ 'Transaction ID not found in the session.'):
return make_json_response(success=0, errormsg=error_msg,
info='DATAGRID_TRANSACTION_REQUIRED',
status=404)
if status and conn is not None \
- and trans_obj is not None and session_obj is not None:
+ and trans_obj is not None and session_obj is not None:
res = None
filter_sql = ''
@@ -1335,13 +1222,13 @@ def remove_filter(trans_id):
check_transaction_status(trans_id)
if error_msg == gettext(
- 'Transaction ID not found in the session.'):
+ 'Transaction ID not found in the session.'):
return make_json_response(success=0, errormsg=error_msg,
info='DATAGRID_TRANSACTION_REQUIRED',
status=404)
if status and conn is not None \
- and trans_obj is not None and session_obj is not None:
+ and trans_obj is not None and session_obj is not None:
res = None
@@ -1380,13 +1267,13 @@ def set_limit(trans_id):
check_transaction_status(trans_id)
if error_msg == gettext(
- 'Transaction ID not found in the session.'):
+ 'Transaction ID not found in the session.'):
return make_json_response(success=0, errormsg=error_msg,
info='DATAGRID_TRANSACTION_REQUIRED',
status=404)
if status and conn is not None \
- and trans_obj is not None and session_obj is not None:
+ and trans_obj is not None and session_obj is not None:
res = None
@@ -1501,13 +1388,13 @@ def get_object_name(trans_id):
check_transaction_status(trans_id)
if error_msg == gettext(
- 'Transaction ID not found in the session.'):
+ 'Transaction ID not found in the session.'):
return make_json_response(success=0, errormsg=error_msg,
info='DATAGRID_TRANSACTION_REQUIRED',
status=404)
if status and conn is not None \
- and trans_obj is not None and session_obj is not None:
+ and trans_obj is not None and session_obj is not None:
res = trans_obj.object_name
else:
status = False
@@ -1538,13 +1425,13 @@ def set_auto_commit(trans_id):
check_transaction_status(trans_id)
if error_msg == gettext(
- 'Transaction ID not found in the session.'):
+ 'Transaction ID not found in the session.'):
return make_json_response(success=0, errormsg=error_msg,
info='DATAGRID_TRANSACTION_REQUIRED',
status=404)
if status and conn is not None \
- and trans_obj is not None and session_obj is not None:
+ and trans_obj is not None and session_obj is not None:
res = None
@@ -1587,13 +1474,13 @@ def set_auto_rollback(trans_id):
check_transaction_status(trans_id)
if error_msg == gettext(
- 'Transaction ID not found in the session.'):
+ 'Transaction ID not found in the session.'):
return make_json_response(success=0, errormsg=error_msg,
info='DATAGRID_TRANSACTION_REQUIRED',
status=404)
if status and conn is not None \
- and trans_obj is not None and session_obj is not None:
+ and trans_obj is not None and session_obj is not None:
res = None
@@ -1643,13 +1530,13 @@ def auto_complete(trans_id):
check_transaction_status(trans_id)
if error_msg == gettext(
- 'Transaction ID not found in the session.'):
+ 'Transaction ID not found in the session.'):
return make_json_response(success=0, errormsg=error_msg,
info='DATAGRID_TRANSACTION_REQUIRED',
status=404)
if status and conn is not None \
- and trans_obj is not None and session_obj is not None:
+ and trans_obj is not None and session_obj is not None:
# Create object of SQLAutoComplete class and pass connection object
auto_complete_obj = SQLAutoComplete(
@@ -1680,165 +1567,6 @@ def script():
)
-def is_begin_required(query):
- word_len = 0
- query = query.strip()
- query_len = len(query)
-
- # Check word length (since "beginx" is not "begin").
- while (word_len < query_len) and query[word_len].isalpha():
- word_len += 1
-
- # Transaction control commands. These should include every keyword that
- # gives rise to a TransactionStmt in the backend grammar, except for the
- # savepoint-related commands.
- #
- # (We assume that START must be START TRANSACTION, since there is
- # presently no other "START foo" command.)
-
- keyword = query[0:word_len]
-
- if word_len == 5 and keyword.lower() == "abort":
- return False
- if word_len == 5 and keyword.lower() == "begin":
- return False
- if word_len == 5 and keyword.lower() == "start":
- return False
- if word_len == 6:
- # SELECT is protected from dirty reads hence don't require transaction
- if keyword.lower() in ["select", "commit"]:
- return False
- if word_len == 3 and keyword.lower() == "end":
- return False
- if word_len == 8 and keyword.lower() == "rollback":
- return False
- if word_len == 7 and keyword.lower() == "prepare":
- # PREPARE TRANSACTION is a TC command, PREPARE foo is not
- query = query[word_len:query_len]
- query = query.strip()
- query_len = len(query)
- word_len = 0
-
- while (word_len < query_len) and query[word_len].isalpha():
- word_len += 1
-
- keyword = query[0:word_len]
- if word_len == 11 and keyword.lower() == "transaction":
- return False
- return True
-
- # Commands not allowed within transactions. The statements checked for
- # here should be exactly those that call PreventTransactionChain() in the
- # backend.
- if word_len == 6 and keyword.lower() == "vacuum":
- return False
-
- if word_len == 7 and keyword.lower() == "cluster":
- # CLUSTER with any arguments is allowed in transactions
- query = query[word_len:query_len]
- query = query.strip()
-
- if query[0].isalpha():
- return True # has additional words
- return False # it's CLUSTER without arguments
-
- if word_len == 6 and keyword.lower() == "create":
- query = query[word_len:query_len]
- query = query.strip()
- query_len = len(query)
- word_len = 0
-
- while (word_len < query_len) and query[word_len].isalpha():
- word_len += 1
-
- keyword = query[0:word_len]
- if word_len == 8 and keyword.lower() == "database":
- return False
- if word_len == 10 and keyword.lower() == "tablespace":
- return False
-
- # CREATE [UNIQUE] INDEX CONCURRENTLY isn't allowed in xacts
- if word_len == 7 and keyword.lower() == "cluster":
- query = query[word_len:query_len]
- query = query.strip()
- query_len = len(query)
- word_len = 0
-
- while (word_len < query_len) and query[word_len].isalpha():
- word_len += 1
-
- keyword = query[0:word_len]
-
- if word_len == 5 and keyword.lower() == "index":
- query = query[word_len:query_len]
- query = query.strip()
- query_len = len(query)
- word_len = 0
-
- while (word_len < query_len) and query[word_len].isalpha():
- word_len += 1
-
- keyword = query[0:word_len]
- if word_len == 12 and keyword.lower() == "concurrently":
- return False
- return True
-
- if word_len == 5 and keyword.lower() == "alter":
- query = query[word_len:query_len]
- query = query.strip()
- query_len = len(query)
- word_len = 0
-
- while (word_len < query_len) and query[word_len].isalpha():
- word_len += 1
-
- keyword = query[0:word_len]
-
- # ALTER SYSTEM isn't allowed in xacts
- if word_len == 6 and keyword.lower() == "system":
- return False
- return True
-
- # Note: these tests will match DROP SYSTEM and REINDEX TABLESPACE, which
- # aren't really valid commands so we don't care much. The other four
- # possible matches are correct.
- if word_len == 4 and keyword.lower() == "drop" \
- or word_len == 7 and keyword.lower() == "reindex":
- query = query[word_len:query_len]
- query = query.strip()
- query_len = len(query)
- word_len = 0
-
- while (word_len < query_len) and query[word_len].isalpha():
- word_len += 1
-
- keyword = query[0:word_len]
- if word_len == 8 and keyword.lower() == "database":
- return False
- if word_len == 6 and keyword.lower() == "system":
- return False
- if word_len == 10 and keyword.lower() == "tablespace":
- return False
- return True
-
- # DISCARD ALL isn't allowed in xacts, but other variants are allowed.
- if word_len == 7 and keyword.lower() == "discard":
- query = query[word_len:query_len]
- query = query.strip()
- query_len = len(query)
- word_len = 0
-
- while (word_len < query_len) and query[word_len].isalpha():
- word_len += 1
-
- keyword = query[0:word_len]
- if word_len == 3 and keyword.lower() == "all":
- return False
- return True
-
- return True
-
-
@blueprint.route('/load_file/', methods=["PUT", "POST"], endpoint='load_file')
@login_required
def load_file():
@@ -1865,9 +1593,9 @@ def load_file():
)
status, err_msg, is_binary, \
- is_startswith_bom, enc = Filemanager.check_file_for_bom_and_binary(
- file_path
- )
+ is_startswith_bom, enc = Filemanager.check_file_for_bom_and_binary(
+ file_path
+ )
if not status:
return internal_server_error(
@@ -1960,10 +1688,10 @@ def save_file():
def start_query_download_tool(trans_id):
sync_conn = None
status, error_msg, conn, trans_obj, \
- session_obj = check_transaction_status(trans_id)
+ session_obj = check_transaction_status(trans_id)
if status and conn is not None \
- and trans_obj is not None and session_obj is not None:
+ and trans_obj is not None and session_obj is not None:
data = request.args if request.args else None
try:
@@ -2063,7 +1791,7 @@ def query_tool_status(trans_id):
TRANSACTION_STATUS_UNKNOWN = 4
"""
status, error_msg, conn, trans_obj, \
- session_obj = check_transaction_status(trans_id)
+ session_obj = check_transaction_status(trans_id)
if not status and error_msg and type(error_msg) == str:
return internal_server_error(
diff --git a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
index 52109ecd..349c9a00 100644
--- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
+++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
@@ -12,6 +12,8 @@ define('tools.querytool', [
'sources/selection/xcell_selection_model',
'sources/selection/set_staged_rows',
'sources/sqleditor_utils',
+ 'sources/sqleditor/execute_query',
+ 'sources/sqleditor/is_new_transaction_required',
'sources/history/index.js',
'sources/../jsx/history/query_history',
'react', 'react-dom',
@@ -28,7 +30,8 @@ define('tools.querytool', [
], function(
babelPollyfill, gettext, url_for, $, _, S, alertify, pgAdmin, Backbone, codemirror,
pgExplain, GridSelector, ActiveCellCapture, clipboard, copyData, RangeSelectionHelper, handleQueryOutputKeyboardEvent,
- XCellSelectionModel, setStagedRows, SqlEditorUtils, HistoryBundle, queryHistory, React, ReactDOM,
+ XCellSelectionModel, setStagedRows, SqlEditorUtils, ExecuteQuery, transaction,
+ HistoryBundle, queryHistory, React, ReactDOM,
keyboardShortcuts, queryToolActions, Datagrid) {
/* Return back, this has been called more than once */
if (pgAdmin.SqlEditor)
@@ -43,12 +46,6 @@ define('tools.querytool', [
var is_query_running = false;
- var is_new_transaction_required = function(xhr) {
- return xhr.status == 404 && xhr.responseJSON &&
- xhr.responseJSON.info &&
- xhr.responseJSON.info == 'DATAGRID_TRANSACTION_REQUIRED';
- };
-
// Defining Backbone view for the sql grid.
var SQLEditorView = Backbone.View.extend({
initialize: function(opts) {
@@ -485,7 +482,7 @@ define('tools.querytool', [
if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
return pgAdmin.Browser.UserManagement.pga_login();
}
- if(is_new_transaction_required(e)) {
+ if(transaction.is_new_transaction_required(e)) {
return self.init_transaction();
}
},
@@ -2188,7 +2185,7 @@ define('tools.querytool', [
pgAdmin.Browser.UserManagement.pga_login();
}
- if(is_new_transaction_required(e)) {
+ if(transaction.is_new_transaction_required(e)) {
self.save_state('_run_query', []);
self.init_transaction();
}
@@ -2256,74 +2253,8 @@ define('tools.querytool', [
* 'Success' then call the render method to render the data.
*/
_poll: function() {
- var self = this;
-
- setTimeout(
- function() {
- $.ajax({
- url: url_for('sqleditor.poll', {
- 'trans_id': self.transId,
- }),
- method: 'GET',
- success: function(res) {
- if (res.data.status === 'Success') {
- self.trigger(
- 'pgadmin-sqleditor:loading-icon:message',
- gettext('Loading data from the database server and rendering...')
- );
-
- self.call_render_after_poll(res.data);
- } else if (res.data.status === 'Busy') {
- // If status is Busy then poll the result by recursive call to the poll function
- self._poll();
- is_query_running = true;
- if (res.data.result) {
- self.update_msg_history(res.data.status, res.data.result, false);
- }
- } else if (res.data.status === 'NotConnected') {
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- // Enable/Disable query tool button only if is_query_tool is true.
- if (self.is_query_tool) {
- self.disable_tool_buttons(false);
- $('#btn-cancel-query').prop('disabled', true);
- }
- self.update_msg_history(false, res.data.result, true);
- } else if (res.data.status === 'Cancel') {
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- self.update_msg_history(false, 'Execution Cancelled!', true);
- }
- },
- error: function(e) {
- // Enable/Disable query tool button only if is_query_tool is true.
- self.resetQueryHistoryObject(self);
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- if (self.is_query_tool) {
- self.disable_tool_buttons(false);
- $('#btn-cancel-query').prop('disabled', true);
- }
-
- if (e.readyState == 0) {
- self.update_msg_history(false,
- gettext('Not connected to the server or the connection to the server has been closed.')
- );
- return;
- }
-
- if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
- return pgAdmin.Browser.UserManagement.pga_login();
- }
-
- var msg = e.responseText;
- if (e.responseJSON != undefined &&
- e.responseJSON.errormsg != undefined)
- msg = e.responseJSON.errormsg;
-
- self.update_msg_history(false, msg);
- // Highlight the error in the sql panel
- self._highlight_error(msg);
- },
- });
- }, self.POLL_FALLBACK_TIME());
+ const executeQuery = new ExecuteQuery.ExecuteQuery(this, pgAdmin.Browser.UserManagement);
+ executeQuery.delayedPoll(this);
},
/* This function is used to create the backgrid columns,
@@ -2941,7 +2872,7 @@ define('tools.querytool', [
pgAdmin.Browser.UserManagement.pga_login();
}
- if(is_new_transaction_required(e)) {
+ if(transaction.is_new_transaction_required(e)) {
self.save_state('_save', [view, controller, save_as]);
self.init_transaction();
}
@@ -3267,7 +3198,7 @@ define('tools.querytool', [
return pgAdmin.Browser.UserManagement.pga_login();
}
- if(is_new_transaction_required(e)) {
+ if(transaction.is_new_transaction_required(e)) {
self.save_state('_show_filter', []);
return self.init_transaction();
}
@@ -3356,7 +3287,7 @@ define('tools.querytool', [
return pgAdmin.Browser.UserManagement.pga_login();
}
- if(is_new_transaction_required(e)) {
+ if(transaction.is_new_transaction_required(e)) {
self.save_state('_include_filter', []);
return self.init_transaction();
}
@@ -3447,7 +3378,7 @@ define('tools.querytool', [
return pgAdmin.Browser.UserManagement.pga_login();
}
- if(is_new_transaction_required(e)) {
+ if(transaction.is_new_transaction_required(e)) {
self.save_state('_exclude_filter', []);
return self.init_transaction();
}
@@ -3517,7 +3448,7 @@ define('tools.querytool', [
return pgAdmin.Browser.UserManagement.pga_login();
}
- if(is_new_transaction_required(e)) {
+ if(transaction.is_new_transaction_required(e)) {
self.save_state('_remove_filter', []);
return self.init_transaction();
}
@@ -3592,7 +3523,7 @@ define('tools.querytool', [
return pgAdmin.Browser.UserManagement.pga_login();
}
- if(is_new_transaction_required(e)) {
+ if(transaction.is_new_transaction_required(e)) {
self.save_state('_apply_filter', []);
return self.init_transaction();
}
@@ -3747,7 +3678,7 @@ define('tools.querytool', [
return pgAdmin.Browser.UserManagement.pga_login();
}
- if(is_new_transaction_required(e)) {
+ if(transaction.is_new_transaction_required(e)) {
self.save_state('_set_limit', []);
return self.init_transaction();
}
@@ -3795,10 +3726,7 @@ define('tools.querytool', [
// and execute the query.
execute: function(explain_prefix) {
var self = this,
- sql = '',
- url = url_for('sqleditor.query_tool_start', {
- 'trans_id': self.transId,
- });
+ sql = '';
self.has_more_rows = false;
self.fetching_rows = false;
@@ -3812,109 +3740,8 @@ define('tools.querytool', [
else
sql = self.gridView.query_tool_obj.getValue();
- // If it is an empty query, do nothing.
- if (sql.length <= 0) return;
-
- self.trigger(
- 'pgadmin-sqleditor:loading-icon:show',
- gettext('Initializing query execution...')
- );
-
- $('#btn-flash').prop('disabled', true);
-
- if (explain_prefix != undefined &&
- !S.startsWith(sql.trim().toUpperCase(), 'EXPLAIN')) {
- sql = explain_prefix + ' ' + sql;
- }
-
- self.query_start_time = new Date();
- self.query = sql;
- self.rows_affected = 0;
- self._init_polling_flags();
- self.disable_tool_buttons(true);
- $('#btn-cancel-query').prop('disabled', false);
-
- if (arguments.length > 0 &&
- arguments[arguments.length - 1] == 'connect') {
- url += '?connect=1';
- }
-
- $.ajax({
- url: url,
- method: 'POST',
- contentType: 'application/json',
- data: JSON.stringify(sql),
- success: function(res) {
- // Remove marker
- if (self.gridView.marker) {
- self.gridView.marker.clear();
- delete self.gridView.marker;
- self.gridView.marker = null;
-
- // Remove already existing marker
- self.gridView.query_tool_obj.removeLineClass(self.marked_line_no, 'wrap', 'CodeMirror-activeline-background');
- }
-
- if (res.data.status) {
- self.trigger(
- 'pgadmin-sqleditor:loading-icon:message',
- gettext('Waiting for the query execution to complete...')
- );
-
- self.can_edit = res.data.can_edit;
- self.can_filter = res.data.can_filter;
- self.info_notifier_timeout = res.data.info_notifier_timeout;
-
- // If status is True then poll the result.
- self._poll();
- } else {
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- self.disable_tool_buttons(false);
- $('#btn-cancel-query').prop('disabled', true);
- self.update_msg_history(false, res.data.result);
-
- // Highlight the error in the sql panel
- self._highlight_error(res.data.result);
- }
- },
- error: function(e) {
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- self.disable_tool_buttons(false);
- $('#btn-cancel-query').prop('disabled', true);
-
- if (e.readyState == 0) {
- self.update_msg_history(false,
- gettext('Not connected to the server or the connection to the server has been closed.')
- );
- return;
- }
-
- if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
- self.save_state('execute', [explain_prefix]);
- pgAdmin.Browser.UserManagement.pga_login();
- }
-
- if(is_new_transaction_required(e)) {
- self.save_state('execute', [explain_prefix]);
- self.init_transaction();
- }
- var msg = e.responseText;
- if (e.responseJSON != undefined) {
- if(e.responseJSON.errormsg != undefined) {
- msg = e.responseJSON.errormsg;
- }
-
- if(e.status == 503 && e.responseJSON.info != undefined &&
- e.responseJSON.info == 'CONNECTION_LOST') {
- setTimeout(function() {
- self.save_state('execute', [explain_prefix]);
- self.handle_connection_lost(false, e);
- });
- }
- }
- self.update_msg_history(false, msg);
- },
- });
+ const executeQuery = new ExecuteQuery.ExecuteQuery(this, pgAdmin.Browser.UserManagement);
+ executeQuery.execute(sql, explain_prefix);
},
/* This function is used to highlight the error line and
@@ -4078,7 +3905,7 @@ define('tools.querytool', [
return pgAdmin.Browser.UserManagement.pga_login();
}
- if(is_new_transaction_required(e)) {
+ if(transaction.is_new_transaction_required(e)) {
self.save_state('_auto_rollback', []);
self.init_transaction();
}
@@ -4139,7 +3966,7 @@ define('tools.querytool', [
return pgAdmin.Browser.UserManagement.pga_login();
}
- if(is_new_transaction_required(e)) {
+ if(transaction.is_new_transaction_required(e)) {
self.save_state('_auto_commit', []);
return self.init_transaction();
}
@@ -4201,7 +4028,7 @@ define('tools.querytool', [
return pgAdmin.Browser.UserManagement.pga_login();
}
- if(is_new_transaction_required(e)) {
+ if(transaction.is_new_transaction_required(e)) {
self.save_state('_explain_verbose', []);
return self.init_transaction();
}
@@ -4250,7 +4077,7 @@ define('tools.querytool', [
return pgAdmin.Browser.UserManagement.pga_login();
}
- if(is_new_transaction_required(e)) {
+ if(transaction.is_new_transaction_required(e)) {
self.save_state('_explain_costs', []);
return self.init_transaction();
}
@@ -4298,7 +4125,7 @@ define('tools.querytool', [
return pgAdmin.Browser.UserManagement.pga_login();
}
- if(is_new_transaction_required(e)) {
+ if(transaction.is_new_transaction_required(e)) {
self.save_state('_explain_buffers', []);
return self.init_transaction();
}
@@ -4345,7 +4172,7 @@ define('tools.querytool', [
return pgAdmin.Browser.UserManagement.pga_login();
}
- if(is_new_transaction_required(e)) {
+ if(transaction.is_new_transaction_required(e)) {
self.save_state('_explain_timing', []);
return self.init_transaction();
}
@@ -4379,6 +4206,10 @@ define('tools.querytool', [
return is_query_running;
},
+ setIsQueryRunning: function(value) {
+ is_query_running = value;
+ },
+
/*
* This function get explain options and auto rollback/auto commit
* values from preferences
@@ -4455,7 +4286,7 @@ define('tools.querytool', [
return pgAdmin.Browser.UserManagement.pga_login();
}
- if(is_new_transaction_required(e)) {
+ if(transaction.is_new_transaction_required(e)) {
self.save_state('get_preferences', []);
return self.init_transaction();
}
diff --git a/web/pgadmin/tools/sqleditor/templates/sqleditor/sql/10_plus/explain_plan.sql b/web/pgadmin/tools/sqleditor/templates/sqleditor/sql/10_plus/explain_plan.sql
new file mode 100644
index 00000000..fc4a8d2d
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/templates/sqleditor/sql/10_plus/explain_plan.sql
@@ -0,0 +1,23 @@
+EXPLAIN (
+{% if format %}
+ FORMAT {{ format.upper() }},
+{% endif %}
+{% if analyze is defined %}
+ ANALYZE {{ analyze }},
+{% endif %}
+{% if verbose is defined %}
+ VERBOSE {{ verbose }},
+{% endif %}
+{% if costs is defined %}
+ COSTS {{ costs }},
+{% endif %}
+{% if timing is defined %}
+ TIMING {{ timing }},
+{% endif %}
+{% if summary is defined %}
+ SUMMARY {{ summary }},
+{% endif %}
+{% if buffers is defined %}
+ BUFFERS {{ buffers }}
+{% endif %}
+) {{ sql }}
diff --git a/web/pgadmin/tools/sqleditor/templates/sqleditor/sql/9.2_plus/explain_plan.sql b/web/pgadmin/tools/sqleditor/templates/sqleditor/sql/9.2_plus/explain_plan.sql
new file mode 100644
index 00000000..315174a6
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/templates/sqleditor/sql/9.2_plus/explain_plan.sql
@@ -0,0 +1,20 @@
+EXPLAIN (
+{% if format %}
+ FORMAT {{ format.upper() }},
+{% endif %}
+{% if analyze is defined %}
+ ANALYZE {{ analyze }},
+{% endif %}
+{% if verbose is defined %}
+ VERBOSE {{ verbose }},
+{% endif %}
+{% if costs is defined %}
+ COSTS {{ costs }},
+{% endif %}
+{% if timing is defined %}
+ TIMING {{ timing }},
+{% endif %}
+{% if buffers is defined %}
+ BUFFERS {{ buffers }}
+{% endif %}
+) {{ sql }}
diff --git a/web/pgadmin/tools/sqleditor/templates/sqleditor/sql/default/explain_plan.sql b/web/pgadmin/tools/sqleditor/templates/sqleditor/sql/default/explain_plan.sql
new file mode 100644
index 00000000..72b20c95
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/templates/sqleditor/sql/default/explain_plan.sql
@@ -0,0 +1,17 @@
+EXPLAIN (
+{% if format %}
+ FORMAT {{ format.upper() }},
+{% endif %}
+{% if analyze is defined %}
+ ANALYZE {{ analyze }},
+{% endif %}
+{% if verbose is defined %}
+ VERBOSE {{ verbose }},
+{% endif %}
+{% if costs is defined %}
+ COSTS {{ costs }},
+{% endif %}
+{% if buffers is defined %}
+ BUFFERS {{ buffers }}
+{% endif %}
+) {{ sql }}
diff --git a/web/pgadmin/tools/sqleditor/templates/sqleditor/sql/gpdb_5.0_plus/explain_plan.sql b/web/pgadmin/tools/sqleditor/templates/sqleditor/sql/gpdb_5.0_plus/explain_plan.sql
new file mode 100644
index 00000000..aacabe45
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/templates/sqleditor/sql/gpdb_5.0_plus/explain_plan.sql
@@ -0,0 +1,5 @@
+EXPLAIN
+{% if analyze %}
+ ANALYZE
+{% endif %}
+ {{ sql }}
diff --git a/web/pgadmin/tools/sqleditor/tests/__init__.py b/web/pgadmin/tools/sqleditor/tests/__init__.py
new file mode 100644
index 00000000..590026ad
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/tests/__init__.py
@@ -0,0 +1,8 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
diff --git a/web/pgadmin/tools/sqleditor/tests/test_explain_plan_templates.py b/web/pgadmin/tools/sqleditor/tests/test_explain_plan_templates.py
new file mode 100644
index 00000000..ab018788
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/tests/test_explain_plan_templates.py
@@ -0,0 +1,152 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import os
+
+from flask import Flask, render_template
+from jinja2 import FileSystemLoader
+
+from pgadmin import VersionedTemplateLoader
+from pgadmin.utils.route import BaseTestGenerator
+
+
+class TestExplainPlanTemplates(BaseTestGenerator):
+ scenarios = [
+ (
+ 'When rendering Postgres 9.0 template, '
+ 'when passing all parameters,'
+ 'it returns the explain plan with all parameters',
+ dict(
+ template_path=os.path.join('sqleditor', 'sql', 'default', 'explain_plan.sql'),
+ input_parameters=dict(
+ sql='select * from places',
+ format='xml',
+ analyze=True,
+ verbose=True,
+ costs=False,
+ buffers=True
+ ),
+ sql_statement='select * from places',
+ expected_return_value='EXPLAIN '
+ '( FORMAT XML, ANALYZE True, VERBOSE True, '
+ 'COSTS False, BUFFERS True) select * from places'
+ )
+ ),
+ (
+ 'When rendering Postgres 9.0 template, '
+ 'when not all parameters are present,'
+ 'it returns the explain plan with the present parameters',
+ dict(
+ template_path=os.path.join('sqleditor', 'sql', 'default', 'explain_plan.sql'),
+ input_parameters=dict(
+ sql='select * from places',
+ format='json',
+ buffers=True
+ ),
+ sql_statement='select * from places',
+ expected_return_value='EXPLAIN '
+ '( FORMAT JSON, BUFFERS True) select * from places'
+ )
+ ),
+ (
+ 'When rendering Postgres 9.2 template, '
+ 'when timing is present,'
+ 'it returns the explain plan with timing',
+ dict(
+ template_path=os.path.join('sqleditor', 'sql', '9.2_plus', 'explain_plan.sql'),
+ input_parameters=dict(
+ sql='select * from places',
+ format='json',
+ buffers=True,
+ timing=False
+ ),
+ sql_statement='select * from places',
+ expected_return_value='EXPLAIN '
+ '( FORMAT JSON, TIMING False, BUFFERS True) select * from places'
+ )
+ ),
+ (
+ 'When rendering Postgres 10 template, '
+ 'when summary is present,'
+ 'it returns the explain plan with summary',
+ dict(
+ template_path=os.path.join('sqleditor', 'sql', '10_plus', 'explain_plan.sql'),
+ input_parameters=dict(
+ sql='select * from places',
+ format='yaml',
+ buffers=True,
+ timing=False,
+ summary=True
+ ),
+ sql_statement='select * from places',
+ expected_return_value='EXPLAIN '
+ '( FORMAT YAML, TIMING False, SUMMARY True, BUFFERS True) select * from places'
+ )
+ ),
+ (
+ 'When rendering GreenPlum 5.3 template, '
+ 'when all parameters are present,'
+ 'it returns the explain without parameters',
+ dict(
+ template_path=os.path.join('sqleditor', 'sql', 'gpdb_5.0_plus', 'explain_plan.sql'),
+ input_parameters=dict(
+ sql='select * from places',
+ format='json',
+ buffers=True
+ ),
+ sql_statement='select * from places',
+ expected_return_value='EXPLAIN select * from places'
+ )
+ ),
+ (
+ 'When rendering GreenPlum 5.3 template, '
+ 'when analyze is true,'
+ 'it returns the explain analyze',
+ dict(
+ template_path=os.path.join('sqleditor', 'sql', 'gpdb_5.0_plus', 'explain_plan.sql'),
+ input_parameters=dict(
+ sql='select * from places',
+ analyze=True
+ ),
+ sql_statement='select * from places',
+ expected_return_value='EXPLAIN ANALYZE select * from places'
+ )
+ ),
+ (
+ 'When rendering GreenPlum 5.3 template, '
+ 'when analyze is false,'
+ 'it returns the only explain',
+ dict(
+ template_path=os.path.join('sqleditor', 'sql', 'gpdb_5.0_plus', 'explain_plan.sql'),
+ input_parameters=dict(
+ sql='select * from places',
+ analyze=False
+ ),
+ sql_statement='select * from places',
+ expected_return_value='EXPLAIN select * from places'
+ )
+ ),
+ ]
+
+ def setUp(self):
+ self.loader = VersionedTemplateLoader(FakeApp())
+
+ def runTest(self):
+ with FakeApp().app_context():
+ result = render_template(self.template_path, **self.input_parameters)
+ self.assertEqual(
+ str(result).replace("\n", ""), self.expected_return_value)
+
+
+class FakeApp(Flask):
+ def __init__(self):
+ super(FakeApp, self).__init__("")
+ self.jinja_loader = FileSystemLoader(
+ os.path.dirname(os.path.realpath(__file__)) + "/../templates"
+ )
diff --git a/web/pgadmin/tools/sqleditor/tests/test_extract_sql_from_network_parameters.py b/web/pgadmin/tools/sqleditor/tests/test_extract_sql_from_network_parameters.py
new file mode 100644
index 00000000..c4e002cc
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/tests/test_extract_sql_from_network_parameters.py
@@ -0,0 +1,59 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from werkzeug.datastructures import ImmutableMultiDict
+
+from pgadmin.tools.sqleditor import extract_sql_from_network_parameters
+from pgadmin.utils.route import BaseTestGenerator
+
+
+class ExtractSQLFromNetworkParametersTest(BaseTestGenerator):
+ """
+ This class validates the change password functionality
+ by defining change password scenarios; where dict of
+ parameters describes the scenario appended by test name.
+ """
+
+ scenarios = [
+ ('Single string in the payload', dict(
+ request_strigified_data='"some sql"',
+ request_arguments=ImmutableMultiDict(),
+ request_form_data=ImmutableMultiDict(),
+
+ expected_result=dict(sql='some sql', explain_plan=None)
+ )),
+ ('Payload that requests explain plan using json', dict(
+ request_strigified_data='{"sql": "some sql", "explain_plan": {"format": "json", "analyze": false, "verbose": false, "costs": false, "buffers": false, "timing": false}}',
+ request_arguments=ImmutableMultiDict(),
+ request_form_data=ImmutableMultiDict(),
+
+ expected_result=dict(
+ sql='some sql',
+ explain_plan=dict(
+ format='json',
+ analyze=False,
+ verbose=False,
+ buffers=False,
+ costs=False,
+ timing=False
+ )
+ )
+ ))
+ ]
+
+ def runTest(self):
+ """Check correct function is called to handle to run query."""
+
+ result = extract_sql_from_network_parameters(
+ self.request_strigified_data,
+ self.request_arguments,
+ self.request_form_data
+ )
+
+ self.assertEquals(result, self.expected_result)
diff --git a/web/pgadmin/tools/sqleditor/tests/test_start_query_tool.py b/web/pgadmin/tools/sqleditor/tests/test_start_query_tool.py
new file mode 100644
index 00000000..5e2752ae
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/tests/test_start_query_tool.py
@@ -0,0 +1,38 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from pgadmin.utils.route import BaseTestGenerator
+from pgadmin.tools.sqleditor import StartRunningQuery
+
+if sys.version_info < (3, 3):
+ from mock import patch, ANY
+else:
+ from unittest.mock import patch, ANY
+
+
+class StartQueryTool(BaseTestGenerator):
+ """
+ Ensures that the call to the backend to start running a query
+ calls the needed functions
+ """
+
+ @patch('pgadmin.tools.sqleditor.extract_sql_from_network_parameters')
+ def runTest(self, extract_sql_from_network_parameters_mock):
+ """Check correct function is called to handle to run query."""
+
+ extract_sql_from_network_parameters_mock.return_value = 'transformed sql'
+
+ with patch.object(StartRunningQuery, 'execute', return_value='some result') as StartRunningQuery_execute_mock:
+ response = self.tester.post('/sqleditor/query_tool/start/1234', data='"some sql statement"')
+
+ self.assertEquals(response.status, '200 OK')
+ self.assertEquals(response.data, 'some result')
+ StartRunningQuery_execute_mock.assert_called_with('transformed sql', 1234, ANY)
+ extract_sql_from_network_parameters_mock.assert_called_with('"some sql statement"', ANY, ANY)
diff --git a/web/pgadmin/tools/sqleditor/utils/__init__.py b/web/pgadmin/tools/sqleditor/utils/__init__.py
new file mode 100644
index 00000000..3626b658
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/utils/__init__.py
@@ -0,0 +1,14 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from .constant_definition import *
+from .is_begin_required import is_begin_required
+from .update_session_grid_transaction import update_session_grid_transaction
+from .start_running_query import *
+from .apply_explain_plan_wrapper import *
diff --git a/web/pgadmin/tools/sqleditor/utils/apply_explain_plan_wrapper.py b/web/pgadmin/tools/sqleditor/utils/apply_explain_plan_wrapper.py
new file mode 100644
index 00000000..84e478de
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/utils/apply_explain_plan_wrapper.py
@@ -0,0 +1,24 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+"""Apply Explain plan wrapper to sql object."""
+from flask import render_template
+
+from pgadmin.utils.compile_template_name import compile_template_name
+
+
+def apply_explain_plan_wrapper_if_needed(manager, sql):
+ if 'explain_plan' in sql and sql['explain_plan']:
+ explain_plan = sql['explain_plan']
+ ver = manager.version
+ server_type = manager.server_type
+ template_path = compile_template_name('sqleditor/sql', 'explain_plan.sql', server_type, ver)
+ return render_template(template_path, sql=sql['sql'], **explain_plan)
+ else:
+ return sql['sql']
diff --git a/web/pgadmin/tools/sqleditor/utils/constant_definition.py b/web/pgadmin/tools/sqleditor/utils/constant_definition.py
new file mode 100644
index 00000000..44c7ecb7
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/utils/constant_definition.py
@@ -0,0 +1,32 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+"""Definition of constants for SQLEditor."""
+
+# Async Constants
+ASYNC_OK = 1
+ASYNC_READ_TIMEOUT = 2
+ASYNC_WRITE_TIMEOUT = 3
+ASYNC_NOT_CONNECTED = 4
+ASYNC_EXECUTION_ABORTED = 5
+
+# Transaction status constants
+TX_STATUS_IDLE = 0
+TX_STATUS__ACTIVE = 1
+TX_STATUS_INTRANS = 2
+TX_STATUS_INERROR = 3
+
+# Connection status codes mapping
+CONNECTION_STATUS_MESSAGE_MAPPING = dict({
+ 0: 'The session is idle and there is no current transaction.',
+ 1: 'A command is currently in progress.',
+ 2: 'The session is idle in a valid transaction block.',
+ 3: 'The session is idle in a failed transaction block.',
+ 4: 'The connection with the server is bad.'
+})
diff --git a/web/pgadmin/tools/sqleditor/utils/is_begin_required.py b/web/pgadmin/tools/sqleditor/utils/is_begin_required.py
new file mode 100644
index 00000000..8db7b954
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/utils/is_begin_required.py
@@ -0,0 +1,169 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+"""Check if requires BEGIN in the current query."""
+
+
+def is_begin_required(query):
+ word_len = 0
+ query = query.strip()
+ query_len = len(query)
+
+ # Check word length (since "beginx" is not "begin").
+ while (word_len < query_len) and query[word_len].isalpha():
+ word_len += 1
+
+ # Transaction control commands. These should include every keyword that
+ # gives rise to a TransactionStmt in the backend grammar, except for the
+ # savepoint-related commands.
+ #
+ # (We assume that START must be START TRANSACTION, since there is
+ # presently no other "START foo" command.)
+
+ keyword = query[0:word_len]
+
+ if word_len == 5 and keyword.lower() == "abort":
+ return False
+ if word_len == 5 and keyword.lower() == "begin":
+ return False
+ if word_len == 5 and keyword.lower() == "start":
+ return False
+ if word_len == 6:
+ # SELECT is protected from dirty reads hence don't require transaction
+ if keyword.lower() in ["select", "commit"]:
+ return False
+ if word_len == 3 and keyword.lower() == "end":
+ return False
+ if word_len == 8 and keyword.lower() == "rollback":
+ return False
+ if word_len == 7 and keyword.lower() == "prepare":
+ # PREPARE TRANSACTION is a TC command, PREPARE foo is not
+ query = query[word_len:query_len]
+ query = query.strip()
+ query_len = len(query)
+ word_len = 0
+
+ while (word_len < query_len) and query[word_len].isalpha():
+ word_len += 1
+
+ keyword = query[0:word_len]
+ if word_len == 11 and keyword.lower() == "transaction":
+ return False
+ return True
+
+ # Commands not allowed within transactions. The statements checked for
+ # here should be exactly those that call PreventTransactionChain() in the
+ # backend.
+ if word_len == 6 and keyword.lower() == "vacuum":
+ return False
+
+ if word_len == 7 and keyword.lower() == "cluster":
+ # CLUSTER with any arguments is allowed in transactions
+ query = query[word_len:query_len]
+ query = query.strip()
+
+ if query[0].isalpha():
+ return True # has additional words
+ return False # it's CLUSTER without arguments
+
+ if word_len == 6 and keyword.lower() == "create":
+ query = query[word_len:query_len]
+ query = query.strip()
+ query_len = len(query)
+ word_len = 0
+
+ while (word_len < query_len) and query[word_len].isalpha():
+ word_len += 1
+
+ keyword = query[0:word_len]
+ if word_len == 8 and keyword.lower() == "database":
+ return False
+ if word_len == 10 and keyword.lower() == "tablespace":
+ return False
+
+ # CREATE [UNIQUE] INDEX CONCURRENTLY isn't allowed in xacts
+ if word_len == 7 and keyword.lower() == "cluster":
+ query = query[word_len:query_len]
+ query = query.strip()
+ query_len = len(query)
+ word_len = 0
+
+ while (word_len < query_len) and query[word_len].isalpha():
+ word_len += 1
+
+ keyword = query[0:word_len]
+
+ if word_len == 5 and keyword.lower() == "index":
+ query = query[word_len:query_len]
+ query = query.strip()
+ query_len = len(query)
+ word_len = 0
+
+ while (word_len < query_len) and query[word_len].isalpha():
+ word_len += 1
+
+ keyword = query[0:word_len]
+ if word_len == 12 and keyword.lower() == "concurrently":
+ return False
+ return True
+
+ if word_len == 5 and keyword.lower() == "alter":
+ query = query[word_len:query_len]
+ query = query.strip()
+ query_len = len(query)
+ word_len = 0
+
+ while (word_len < query_len) and query[word_len].isalpha():
+ word_len += 1
+
+ keyword = query[0:word_len]
+
+ # ALTER SYSTEM isn't allowed in xacts
+ if word_len == 6 and keyword.lower() == "system":
+ return False
+ return True
+
+ # Note: these tests will match DROP SYSTEM and REINDEX TABLESPACE, which
+ # aren't really valid commands so we don't care much. The other four
+ # possible matches are correct.
+ if word_len == 4 and keyword.lower() == "drop" \
+ or word_len == 7 and keyword.lower() == "reindex":
+ query = query[word_len:query_len]
+ query = query.strip()
+ query_len = len(query)
+ word_len = 0
+
+ while (word_len < query_len) and query[word_len].isalpha():
+ word_len += 1
+
+ keyword = query[0:word_len]
+ if word_len == 8 and keyword.lower() == "database":
+ return False
+ if word_len == 6 and keyword.lower() == "system":
+ return False
+ if word_len == 10 and keyword.lower() == "tablespace":
+ return False
+ return True
+
+ # DISCARD ALL isn't allowed in xacts, but other variants are allowed.
+ if word_len == 7 and keyword.lower() == "discard":
+ query = query[word_len:query_len]
+ query = query.strip()
+ query_len = len(query)
+ word_len = 0
+
+ while (word_len < query_len) and query[word_len].isalpha():
+ word_len += 1
+
+ keyword = query[0:word_len]
+ if word_len == 3 and keyword.lower() == "all":
+ return False
+ return True
+
+ return True
diff --git a/web/pgadmin/tools/sqleditor/utils/start_running_query.py b/web/pgadmin/tools/sqleditor/utils/start_running_query.py
new file mode 100644
index 00000000..f5e1feae
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/utils/start_running_query.py
@@ -0,0 +1,172 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+"""Start executing the query in async mode."""
+
+import pickle
+import random
+
+from flask import Response
+from flask_babel import gettext
+
+from config import PG_DEFAULT_DRIVER
+from pgadmin.tools.sqleditor.utils.apply_explain_plan_wrapper import apply_explain_plan_wrapper_if_needed
+from pgadmin.tools.sqleditor.utils.update_session_grid_transaction import update_session_grid_transaction
+from pgadmin.tools.sqleditor.utils.is_begin_required import is_begin_required
+from pgadmin.tools.sqleditor.utils.constant_definition import TX_STATUS_IDLE, TX_STATUS_INERROR
+
+from pgadmin.utils.ajax import make_json_response, internal_server_error
+from pgadmin.utils.driver import get_driver
+from pgadmin.utils.exception import ConnectionLost
+
+
+class StartRunningQuery:
+
+ def __init__(self, blueprint_object, logger):
+ self.http_session = None
+ self.blueprint_object = blueprint_object
+ self.connection_id = str(random.randint(1, 9999999))
+ self.logger = logger
+
+ def execute(self, sql, trans_id, http_session):
+ session_obj = StartRunningQuery.retrieve_session_information(http_session, trans_id)
+ if type(session_obj) is Response:
+ return session_obj
+
+ transaction_object = pickle.loads(session_obj['command_obj'])
+ can_edit = False
+ can_filter = False
+ if transaction_object is not None and session_obj is not None:
+ # set fetched row count to 0 as we are executing query again.
+ transaction_object.update_fetched_row_cnt(0)
+ self.__retrieve_connection_id(transaction_object)
+
+ try:
+ manager = get_driver(
+ PG_DEFAULT_DRIVER).connection_manager(transaction_object.sid)
+ conn = manager.connection(did=transaction_object.did, conn_id=self.connection_id,
+ auto_reconnect=False,
+ use_binary_placeholder=True,
+ array_to_string=True)
+ except ConnectionLost:
+ raise
+ except Exception as e:
+ self.logger.error(e)
+ return internal_server_error(errormsg=str(e))
+
+ # Connect to the Server if not connected.
+ if not conn.connected():
+ status, msg = conn.connect()
+ if not status:
+ self.logger.error(msg)
+ return internal_server_error(errormsg=str(msg))
+
+ effective_sql_statement = apply_explain_plan_wrapper_if_needed(manager, sql)
+
+ result, status = self.__execute_query(
+ conn,
+ session_obj,
+ effective_sql_statement,
+ trans_id,
+ transaction_object
+ )
+
+ can_edit = transaction_object.can_edit()
+ can_filter = transaction_object.can_filter()
+
+ else:
+ status = False
+ result = gettext(
+ 'Either transaction object or session object not found.')
+ return make_json_response(
+ data={
+ 'status': status, 'result': result,
+ 'can_edit': can_edit, 'can_filter': can_filter,
+ 'info_notifier_timeout': self.blueprint_object.info_notifier_timeout.get()
+ }
+ )
+
+ def __retrieve_connection_id(self, trans_obj):
+ conn_id = trans_obj.conn_id
+ # if conn_id is None then we will have to create a new connection
+ if conn_id is not None:
+ 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)
+
+ 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
+ def is_begin_required_for_sql_query(trans_obj, conn, sql):
+ return not trans_obj.auto_commit \
+ and conn.transaction_status() == TX_STATUS_IDLE \
+ and is_begin_required(sql)
+
+ @staticmethod
+ def is_rollback_statement_required(trans_obj, conn):
+ return conn.transaction_status() == TX_STATUS_INERROR and trans_obj.auto_rollback
+
+ @staticmethod
+ def save_transaction_in_session(session, transaction_id, transaction):
+ # As we changed the transaction object we need to
+ # restore it and update the session variable.
+ session['command_obj'] = pickle.dumps(transaction, -1)
+ update_session_grid_transaction(transaction_id, session)
+
+ @staticmethod
+ def retrieve_session_information(http_session, transaction_id):
+ if 'gridData' not in http_session:
+ return make_json_response(
+ success=0,
+ errormsg=gettext('Transaction ID not found in the session.'),
+ info='DATAGRID_TRANSACTION_REQUIRED', status=404
+ )
+ grid_data = http_session['gridData']
+ # Return from the function if transaction id not found
+ if str(transaction_id) not in grid_data:
+ return make_json_response(
+ success=0,
+ errormsg=gettext('Transaction ID not found in the session.'),
+ info='DATAGRID_TRANSACTION_REQUIRED',
+ status=404
+ )
+ # Fetch the object for the specified transaction id.
+ # Use pickle.loads function to get the command object
+ return grid_data[str(transaction_id)]
+
+
diff --git a/web/pgadmin/tools/sqleditor/utils/tests/__init__.py b/web/pgadmin/tools/sqleditor/utils/tests/__init__.py
new file mode 100644
index 00000000..590026ad
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/utils/tests/__init__.py
@@ -0,0 +1,8 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
diff --git a/web/pgadmin/tools/sqleditor/utils/tests/test_apply_explain_plan_wrapper.py b/web/pgadmin/tools/sqleditor/utils/tests/test_apply_explain_plan_wrapper.py
new file mode 100644
index 00000000..6cf320eb
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/utils/tests/test_apply_explain_plan_wrapper.py
@@ -0,0 +1,121 @@
+#######################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+"""Apply Explain plan wrapper to sql object."""
+import sys
+
+from pgadmin.tools.sqleditor.utils import apply_explain_plan_wrapper_if_needed
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+ from mock import patch, MagicMock
+else:
+ from unittest.mock import patch, MagicMock
+
+
+class StartRunningQueryTest(BaseTestGenerator):
+ """
+ Check that the apply_explain_plan_weapper_if_needed method works as intended
+ """
+ scenarios = [
+ ('When explain_plan is none, it should return unaltered SQL', dict(
+ function_input_parameters={
+ 'manager': MagicMock(),
+ 'sql': {
+ 'sql': 'some sql',
+ 'explain_plan': None
+ }
+ },
+
+ expect_render_template_mock_parameters=None,
+
+ expected_return_value='some sql'
+ )),
+ ('When explain_plan is not present, it should return unaltered SQL', dict(
+ function_input_parameters={
+ 'manager': MagicMock(),
+ 'sql': {
+ 'sql': 'some sql'
+ }
+ },
+
+ expect_render_template_mock_parameters=None,
+
+ expected_return_value='some sql'
+ )),
+ ('When explain_plan is present for a Postgres server version 10, it should return SQL with explain plan', dict(
+ function_input_parameters={
+ 'manager': MagicMock(version=10, server_type='pg'),
+ 'sql': {
+ 'sql': 'some sql',
+ 'explain_plan': {
+ 'format': 'json',
+ 'analyze': False,
+ 'verbose': True,
+ 'buffers': False,
+ 'timing': True
+ }
+ }
+ },
+
+ expect_render_template_mock_parameters=dict(
+ template_name_or_list='sqleditor/sql/#10#/explain_plan.sql',
+ named_parameters=dict(
+ format='json',
+ analyze=False,
+ verbose=True,
+ buffers=False,
+ timing=True
+ )),
+
+ expected_return_value='EXPLAIN (FORMAT JSON, ANALYZE FALSE, VERBOSE TRUE, COSTS FALSE, BUFFERS FALSE, '
+ 'TIMING TRUE) some sql'
+ )),
+ ('When explain_plan is present for a GreenPlum server version 5, it should return SQL with explain plan', dict(
+ function_input_parameters={
+ 'manager': MagicMock(version=80323, server_type='gpdb'),
+ 'sql': {
+ 'sql': 'some sql',
+ 'explain_plan': {
+ 'format': 'json',
+ 'analyze': False,
+ 'verbose': True,
+ 'buffers': False,
+ 'timing': True
+ }
+ }
+ },
+
+ expect_render_template_mock_parameters=dict(
+ template_name_or_list='sqleditor/sql/#gpdb#80323#/explain_plan.sql',
+ named_parameters=dict(
+ format='json',
+ analyze=False,
+ verbose=True,
+ buffers=False,
+ timing=True
+ )),
+
+ expected_return_value='EXPLAIN some sql'
+ ))
+ ]
+
+ def runTest(self):
+ with patch('pgadmin.tools.sqleditor.utils.apply_explain_plan_wrapper.render_template') as render_template_mock:
+ render_template_mock.return_value = self.expected_return_value
+ result = apply_explain_plan_wrapper_if_needed(**self.function_input_parameters)
+ self.assertEquals(result, self.expected_return_value)
+ if self.expect_render_template_mock_parameters:
+ render_template_mock.assert_called_with(
+ self.expect_render_template_mock_parameters['template_name_or_list'],
+ sql=self.function_input_parameters['sql']['sql'],
+ **self.expect_render_template_mock_parameters['named_parameters']
+ )
+ else:
+ render_template_mock.assert_not_called()
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
new file mode 100644
index 00000000..d53c0248
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/utils/tests/test_start_running_query.py
@@ -0,0 +1,445 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import sys
+
+from flask import Response
+import simplejson as json
+
+from pgadmin.tools.sqleditor.utils.start_running_query import StartRunningQuery
+from pgadmin.utils.exception import ConnectionLost
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+ from mock import patch, MagicMock
+else:
+ from unittest.mock import patch, MagicMock
+
+get_driver_exception = Exception('get_driver exception')
+
+
+class StartRunningQueryTest(BaseTestGenerator):
+ """
+ Check that the start_running_query method works as intended
+ """
+
+ scenarios = [
+ ('When gridData is not present in the session, it returns an error', dict(
+ function_parameters=dict(
+ sql=dict(sql='some sql', explain_plan=None),
+ trans_id=123,
+ http_session=dict()
+ ),
+ pickle_load_return=None,
+ get_driver_exception=False,
+ manager_connection_exception=None,
+
+ is_connected_to_server=False,
+ connection_connect_return=None,
+ execute_async_return_value=None,
+ is_begin_required=False,
+ is_rollback_required=False,
+ apply_explain_plan_wrapper_if_needed_return_value='some sql',
+
+ expect_make_json_response_to_have_been_called_with=dict(
+ success=0,
+ errormsg='Transaction ID not found in the session.',
+ info='DATAGRID_TRANSACTION_REQUIRED',
+ status=404,
+ ),
+ expect_internal_server_error_to_have_been_called_with=None,
+ expected_logger_error=None,
+ expect_execute_void_called_with='some sql',
+ )),
+ ('When transactionId is not present in the gridData, it returns an error', dict(
+ function_parameters=dict(
+ sql=dict(sql='some sql', explain_plan=None),
+ trans_id=123,
+ http_session=dict(gridData=dict())
+ ),
+ pickle_load_return=None,
+ get_driver_exception=False,
+ manager_connection_exception=None,
+
+ is_connected_to_server=False,
+ connection_connect_return=None,
+ execute_async_return_value=None,
+ is_begin_required=False,
+ is_rollback_required=False,
+ apply_explain_plan_wrapper_if_needed_return_value='some sql',
+
+ expect_make_json_response_to_have_been_called_with=dict(
+ success=0,
+ errormsg='Transaction ID not found in the session.',
+ info='DATAGRID_TRANSACTION_REQUIRED',
+ status=404,
+ ),
+ expect_internal_server_error_to_have_been_called_with=None,
+ expected_logger_error=None,
+ expect_execute_void_called_with='some sql',
+ )),
+ ('When the command information for the transaction cannot be retrieved, it returns an error', dict(
+ function_parameters=dict(
+ sql=dict(sql='some sql', explain_plan=None),
+ trans_id=123,
+ http_session=dict(gridData={'123': dict(command_obj='')})
+ ),
+ pickle_load_return=None,
+ get_driver_exception=False,
+ manager_connection_exception=None,
+
+ is_connected_to_server=False,
+ connection_connect_return=None,
+ execute_async_return_value=None,
+ is_begin_required=False,
+ is_rollback_required=False,
+ apply_explain_plan_wrapper_if_needed_return_value='some sql',
+
+ expect_make_json_response_to_have_been_called_with=dict(
+ data=dict(
+ status=False,
+ result='Either transaction object or session object not found.',
+ can_edit=False,
+ can_filter=False,
+ info_notifier_timeout=5
+ )
+ ),
+ expect_internal_server_error_to_have_been_called_with=None,
+ expected_logger_error=None,
+ expect_execute_void_called_with='some sql',
+ )),
+ ('When exception happens while retrieving the database driver, it returns an error', dict(
+ function_parameters=dict(
+ sql=dict(sql='some sql', explain_plan=None),
+ trans_id=123,
+ http_session=dict(gridData={'123': dict(command_obj='')})
+ ),
+ pickle_load_return=MagicMock(conn_id=1, update_fetched_row_cnt=MagicMock()),
+ get_driver_exception=True,
+ manager_connection_exception=None,
+
+ is_connected_to_server=False,
+ connection_connect_return=None,
+ execute_async_return_value=None,
+ is_begin_required=False,
+ is_rollback_required=False,
+ apply_explain_plan_wrapper_if_needed_return_value='some sql',
+
+ expect_make_json_response_to_have_been_called_with=None,
+ expect_internal_server_error_to_have_been_called_with=dict(
+ errormsg='get_driver exception'
+ ),
+ expected_logger_error=get_driver_exception,
+ expect_execute_void_called_with='some sql',
+ )),
+ ('When ConnectionLost happens while retrieving the database connection, it returns an error', dict(
+ function_parameters=dict(
+ sql=dict(sql='some sql', explain_plan=None),
+ trans_id=123,
+ http_session=dict(gridData={'123': dict(command_obj='')})
+ ),
+ pickle_load_return=MagicMock(conn_id=1, update_fetched_row_cnt=MagicMock()),
+ get_driver_exception=False,
+ manager_connection_exception=ConnectionLost('1', '2', '3'),
+
+ is_connected_to_server=False,
+ connection_connect_return=None,
+ execute_async_return_value=None,
+ is_begin_required=False,
+ is_rollback_required=False,
+ apply_explain_plan_wrapper_if_needed_return_value='some sql',
+
+ expect_make_json_response_to_have_been_called_with=None,
+ expect_internal_server_error_to_have_been_called_with=None,
+ expected_logger_error=None,
+ expect_execute_void_called_with='some sql',
+ )),
+ ('When is not connected to the server and fails to connect, it returns an error', dict(
+ function_parameters=dict(
+ sql=dict(sql='some sql', explain_plan=None),
+ trans_id=123,
+ http_session=dict(gridData={'123': dict(command_obj='')})
+ ),
+ pickle_load_return=MagicMock(conn_id=1, update_fetched_row_cnt=MagicMock()),
+ get_driver_exception=False,
+ manager_connection_exception=None,
+
+ is_connected_to_server=False,
+ connection_connect_return=[False, 'Unable to connect to server'],
+ execute_async_return_value=None,
+ is_begin_required=False,
+ is_rollback_required=False,
+ apply_explain_plan_wrapper_if_needed_return_value='some sql',
+
+ expect_make_json_response_to_have_been_called_with=None,
+ expect_internal_server_error_to_have_been_called_with=dict(
+ errormsg='Unable to connect to server'
+ ),
+ expected_logger_error='Unable to connect to server',
+ expect_execute_void_called_with='some sql',
+ )),
+ ('When server is connected and start query async request, it returns an success message', dict(
+ function_parameters=dict(
+ sql=dict(sql='some sql', explain_plan=None),
+ trans_id=123,
+ http_session=dict(gridData={'123': dict(command_obj='')})
+ ),
+ pickle_load_return=MagicMock(
+ conn_id=1,
+ update_fetched_row_cnt=MagicMock(),
+ set_connection_id=MagicMock(),
+ auto_commit=True,
+ auto_rollback=False,
+ can_edit=lambda: True,
+ can_filter=lambda: True
+ ),
+ get_driver_exception=False,
+ manager_connection_exception=None,
+
+ is_connected_to_server=True,
+ connection_connect_return=None,
+ execute_async_return_value=[True, 'async function result output'],
+ is_begin_required=False,
+ is_rollback_required=False,
+ apply_explain_plan_wrapper_if_needed_return_value='some sql',
+
+ expect_make_json_response_to_have_been_called_with=dict(
+ data=dict(
+ status=True,
+ result='async function result output',
+ can_edit=True,
+ can_filter=True,
+ info_notifier_timeout=5
+ )
+ ),
+ expect_internal_server_error_to_have_been_called_with=None,
+ expected_logger_error=None,
+ expect_execute_void_called_with='some sql',
+ )),
+ ('When server is connected and start query async request and begin is required, '
+ 'it returns an success message', dict(
+ function_parameters=dict(
+ sql=dict(sql='some sql', explain_plan=None),
+ trans_id=123,
+ http_session=dict(gridData={'123': dict(command_obj='')})
+ ),
+ pickle_load_return=MagicMock(
+ conn_id=1,
+ update_fetched_row_cnt=MagicMock(),
+ set_connection_id=MagicMock(),
+ auto_commit=True,
+ auto_rollback=False,
+ can_edit=lambda: True,
+ can_filter=lambda: True
+ ),
+ get_driver_exception=False,
+ manager_connection_exception=None,
+
+ is_connected_to_server=True,
+ connection_connect_return=None,
+ execute_async_return_value=[True, 'async function result output'],
+ is_begin_required=True,
+ is_rollback_required=False,
+ apply_explain_plan_wrapper_if_needed_return_value='some sql',
+
+ expect_make_json_response_to_have_been_called_with=dict(
+ data=dict(
+ status=True,
+ result='async function result output',
+ can_edit=True,
+ can_filter=True,
+ info_notifier_timeout=5
+ )
+ ),
+ expect_internal_server_error_to_have_been_called_with=None,
+ expected_logger_error=None,
+ expect_execute_void_called_with='some sql',
+ )),
+ ('When server is connected and start query async request and rollback is required, '
+ 'it returns an success message', dict(
+ function_parameters=dict(
+ sql=dict(sql='some sql', explain_plan=None),
+ trans_id=123,
+ http_session=dict(gridData={'123': dict(command_obj='')})
+ ),
+ pickle_load_return=MagicMock(
+ conn_id=1,
+ update_fetched_row_cnt=MagicMock(),
+ set_connection_id=MagicMock(),
+ auto_commit=True,
+ auto_rollback=False,
+ can_edit=lambda: True,
+ can_filter=lambda: True
+ ),
+ get_driver_exception=False,
+ manager_connection_exception=None,
+
+ is_connected_to_server=True,
+ connection_connect_return=None,
+ execute_async_return_value=[True, 'async function result output'],
+ is_begin_required=False,
+ is_rollback_required=True,
+ apply_explain_plan_wrapper_if_needed_return_value='some sql',
+
+ expect_make_json_response_to_have_been_called_with=dict(
+ data=dict(
+ status=True,
+ result='async function result output',
+ can_edit=True,
+ can_filter=True,
+ info_notifier_timeout=5
+ )
+ ),
+ expect_internal_server_error_to_have_been_called_with=None,
+ expected_logger_error=None,
+ expect_execute_void_called_with='some sql',
+ )),
+ ('When server is connected and start query async request with explain plan wrapper, '
+ 'it returns an success message', dict(
+ function_parameters=dict(
+ sql=dict(sql='some sql', explain_plan=None),
+ trans_id=123,
+ http_session=dict(gridData={'123': dict(command_obj='')})
+ ),
+ pickle_load_return=MagicMock(
+ conn_id=1,
+ update_fetched_row_cnt=MagicMock(),
+ set_connection_id=MagicMock(),
+ auto_commit=True,
+ auto_rollback=False,
+ can_edit=lambda: True,
+ can_filter=lambda: True
+ ),
+ get_driver_exception=False,
+ manager_connection_exception=None,
+
+ is_connected_to_server=True,
+ connection_connect_return=None,
+ execute_async_return_value=[True, 'async function result output'],
+ is_begin_required=False,
+ is_rollback_required=True,
+ apply_explain_plan_wrapper_if_needed_return_value='EXPLAIN PLAN some sql',
+
+ expect_make_json_response_to_have_been_called_with=dict(
+ data=dict(
+ status=True,
+ result='async function result output',
+ can_edit=True,
+ can_filter=True,
+ info_notifier_timeout=5
+ )
+ ),
+ expect_internal_server_error_to_have_been_called_with=None,
+ expected_logger_error=None,
+ expect_execute_void_called_with='EXPLAIN PLAN some sql',
+ )),
+ ]
+
+ @patch('pgadmin.tools.sqleditor.utils.start_running_query.apply_explain_plan_wrapper_if_needed')
+ @patch('pgadmin.tools.sqleditor.utils.start_running_query.make_json_response')
+ @patch('pgadmin.tools.sqleditor.utils.start_running_query.pickle')
+ @patch('pgadmin.tools.sqleditor.utils.start_running_query.get_driver')
+ @patch('pgadmin.tools.sqleditor.utils.start_running_query.internal_server_error')
+ @patch('pgadmin.tools.sqleditor.utils.start_running_query.update_session_grid_transaction')
+ def runTest(self, update_session_grid_transaction_mock,
+ internal_server_error_mock, get_driver_mock, pickle_mock,
+ make_json_response_mock, apply_explain_plan_wrapper_if_needed_mock):
+ """Check correct function is called to handle to run query."""
+ self.connection = None
+
+ self.loggerMock = MagicMock(error=MagicMock())
+ expected_response = Response(response=json.dumps({'errormsg': 'some value'}))
+ make_json_response_mock.return_value = expected_response
+ if self.expect_internal_server_error_to_have_been_called_with is not None:
+ internal_server_error_mock.return_value = expected_response
+ pickle_mock.loads.return_value = self.pickle_load_return
+ blueprint_mock = MagicMock(info_notifier_timeout=MagicMock(get=lambda: 5))
+
+ if self.is_begin_required:
+ StartRunningQuery.is_begin_required_for_sql_query = MagicMock(return_value=True)
+ else:
+ StartRunningQuery.is_begin_required_for_sql_query = MagicMock(return_value=False)
+ if self.is_rollback_required:
+ StartRunningQuery.is_rollback_statement_required = MagicMock(return_value=True)
+ else:
+ StartRunningQuery.is_rollback_statement_required = MagicMock(return_value=False)
+
+ apply_explain_plan_wrapper_if_needed_mock.return_value = self.apply_explain_plan_wrapper_if_needed_return_value
+
+ manager = self.__create_manager()
+ if self.get_driver_exception:
+ get_driver_mock.side_effect = get_driver_exception
+ else:
+ get_driver_mock.return_value = MagicMock(connection_manager=lambda session_id: manager)
+
+ try:
+ result = StartRunningQuery(
+ blueprint_mock,
+ self.loggerMock
+ ).execute(
+ **self.function_parameters
+ )
+ if self.manager_connection_exception is not None:
+ self.fail('Exception: "' + str(self.manager_connection_exception) + '" excepted but not raised')
+
+ self.assertEquals(result, expected_response)
+
+ except AssertionError:
+ raise
+ except Exception as exception:
+ self.assertEquals(self.manager_connection_exception, exception)
+
+ self.__mock_assertions(internal_server_error_mock, make_json_response_mock)
+ if self.is_connected_to_server:
+ apply_explain_plan_wrapper_if_needed_mock.assert_called_with(manager, self.function_parameters['sql'])
+
+ def __create_manager(self):
+ self.connection = MagicMock(
+ connected=lambda: self.is_connected_to_server,
+ connect=MagicMock(),
+ execute_async=MagicMock(),
+ execute_void=MagicMock(),
+ )
+ self.connection.connect.return_value = self.connection_connect_return
+ self.connection.execute_async.return_value = self.execute_async_return_value
+ if self.manager_connection_exception is None:
+ manager = MagicMock(
+ connection=lambda did, conn_id, use_binary_placeholder, array_to_string, auto_reconnect: self.connection
+ )
+ else:
+ manager = MagicMock()
+ manager.connection.side_effect = self.manager_connection_exception
+ return manager
+
+ def __mock_assertions(self, internal_server_error_mock, make_json_response_mock):
+ if self.expect_make_json_response_to_have_been_called_with is not None:
+ make_json_response_mock.assert_called_with(**self.expect_make_json_response_to_have_been_called_with)
+ else:
+ make_json_response_mock.assert_not_called()
+ if self.expect_internal_server_error_to_have_been_called_with is not None:
+ internal_server_error_mock.assert_called_with(**self.expect_internal_server_error_to_have_been_called_with)
+ else:
+ internal_server_error_mock.assert_not_called()
+ if self.execute_async_return_value is not None:
+ self.connection.execute_async.assert_called_with(self.expect_execute_void_called_with)
+ else:
+ self.connection.execute_async.assert_not_called()
+
+ if self.expected_logger_error is not None:
+ self.loggerMock.error.assert_called_with(self.expected_logger_error)
+ else:
+ self.loggerMock.error.assert_not_called()
+
+ if self.is_begin_required:
+ self.connection.execute_void.assert_called_with('BEGIN;')
+ elif not self.is_rollback_required:
+ self.connection.execute_void.assert_not_called()
+ if self.is_rollback_required:
+ self.connection.execute_void.assert_called_with('ROLLBACK;')
+ elif not self.is_begin_required:
+ self.connection.execute_void.assert_not_called()
diff --git a/web/pgadmin/tools/sqleditor/utils/update_session_grid_transaction.py b/web/pgadmin/tools/sqleditor/utils/update_session_grid_transaction.py
new file mode 100644
index 00000000..aef78f23
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/utils/update_session_grid_transaction.py
@@ -0,0 +1,18 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+"""Update session with gridData."""
+from flask import session
+
+
+def update_session_grid_transaction(trans_id, data):
+ if 'gridData' in session:
+ grid_data = session['gridData']
+ grid_data[str(trans_id)] = data
+ session['gridData'] = grid_data
diff --git a/web/pgadmin/utils/compile_template_name.py b/web/pgadmin/utils/compile_template_name.py
new file mode 100644
index 00000000..6eb2431f
--- /dev/null
+++ b/web/pgadmin/utils/compile_template_name.py
@@ -0,0 +1,17 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+import os
+
+
+def compile_template_name(template_prefix, template_file_name, server_type, version):
+ if server_type == 'gpdb':
+ version_path = '#{0}#{1}#'.format(server_type, version)
+ else:
+ version_path = '#{0}#'.format(version)
+ return os.path.join(template_prefix, version_path, template_file_name)
diff --git a/web/pgadmin/utils/tests/test_compile_template_name.py b/web/pgadmin/utils/tests/test_compile_template_name.py
new file mode 100644
index 00000000..97f1b05c
--- /dev/null
+++ b/web/pgadmin/utils/tests/test_compile_template_name.py
@@ -0,0 +1,34 @@
+#######################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+from pgadmin.utils.compile_template_name import compile_template_name
+from pgadmin.utils.route import BaseTestGenerator
+
+
+class StartRunningQueryTest(BaseTestGenerator):
+ """
+ Check that the apply_explain_plan_weapper_if_needed method works as intended
+ """
+ scenarios = [
+ ('When server is Postgres and version is 10, it returns the path to the postgres template', dict(
+ server_type='pg',
+ version=100000,
+
+ expected_return_value='some/prefix/#100000#/some_file.sql'
+ )),
+ ('When server is GreenPlum and version is 5, it returns the path to the GreenPlum template', dict(
+ server_type='gpdb',
+ version=80323,
+
+ expected_return_value='some/prefix/#gpdb#80323#/some_file.sql'
+ )),
+ ]
+
+ def runTest(self):
+ result = compile_template_name('some/prefix', 'some_file.sql', self.server_type, self.version)
+ self.assertEquals(result, self.expected_return_value)
diff --git a/web/pgadmin/utils/versioned_template_loader.py b/web/pgadmin/utils/versioned_template_loader.py
index 19693012..8e8259fe 100644
--- a/web/pgadmin/utils/versioned_template_loader.py
+++ b/web/pgadmin/utils/versioned_template_loader.py
@@ -6,7 +6,6 @@
# This software is released under the PostgreSQL Licence
#
##########################################################################
-
from flask.templating import DispatchingJinjaLoader
from jinja2 import TemplateNotFound
@@ -54,6 +53,7 @@ class VersionedTemplateLoader(DispatchingJinjaLoader):
template_path = path_start + '/' + \
server_version['name'] + '/' + file_name
+
try:
return super(VersionedTemplateLoader, self).get_source(
environment, template_path
diff --git a/web/regression/javascript/fake_endpoints.js b/web/regression/javascript/fake_endpoints.js
index 0250a0df..63ab05dc 100644
--- a/web/regression/javascript/fake_endpoints.js
+++ b/web/regression/javascript/fake_endpoints.js
@@ -8,5 +8,9 @@
//////////////////////////////////////////////////////////////////////////
define(function () {
- return {'static': '/base/pgadmin/static/<path:filename>'};
+ return {
+ 'static': '/base/pgadmin/static/<path:filename>',
+ 'sqleditor.poll': '/sqleditor/query_tool/poll/<path:trans_id>',
+ 'sqleditor.query_tool_start': '/sqleditor/query_tool/start/<path:trans_id>'
+ };
});
diff --git a/web/regression/javascript/sqleditor/execute_query_spec.js b/web/regression/javascript/sqleditor/execute_query_spec.js
new file mode 100644
index 00000000..98faed7d
--- /dev/null
+++ b/web/regression/javascript/sqleditor/execute_query_spec.js
@@ -0,0 +1,1702 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2018, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////////////////
+
+import * as subject from 'sources/sqleditor/execute_query';
+import * as transaction from 'sources/sqleditor/is_new_transaction_required';
+import axios from 'axios';
+import MockAdapter from 'axios-mock-adapter';
+import $ from 'jquery';
+
+const context = describe;
+
+describe('ExecuteQuery', () => {
+ let sqlEditorMock;
+ let networkMock;
+ let executeQuery;
+ let userManagementMock;
+ let isNewTransactionRequiredMock;
+
+ const startTime = new Date(2018, 1, 29, 12, 15, 52);
+ beforeEach(() => {
+ networkMock = new MockAdapter(axios);
+ jasmine.addMatchers({jQuerytoHaveBeenCalledWith: jQuerytoHaveBeenCalledWith});
+ userManagementMock = jasmine.createSpyObj('UserManagement', [
+ 'is_pga_login_required',
+ 'pga_login',
+ ]);
+
+ sqlEditorMock = jasmine.createSpyObj('SqlEditor', [
+ 'call_render_after_poll',
+ 'disable_tool_buttons',
+ 'resetQueryHistoryObject',
+ 'setIsQueryRunning',
+ 'trigger',
+ 'update_msg_history',
+ '_highlight_error',
+ '_init_polling_flags',
+ 'save_state',
+ 'init_transaction',
+ ]);
+ sqlEditorMock.transId = 123;
+ sqlEditorMock.rows_affected = 1000;
+ executeQuery = new subject.ExecuteQuery(sqlEditorMock, userManagementMock);
+ isNewTransactionRequiredMock = spyOn(transaction, 'is_new_transaction_required');
+ });
+
+ describe('#poll', () => {
+ let cancelButtonSpy;
+ let response;
+
+ beforeEach(() => {
+ sqlEditorMock.POLL_FALLBACK_TIME = () => {
+ return 0;
+ };
+
+ cancelButtonSpy = spyOn($.fn, 'prop');
+ executeQuery.delayedPoll = jasmine.createSpy('ExecuteQuery.delayedPoll');
+ });
+
+ afterEach(() => {
+ });
+
+ context('when SQLEditor is the query tool', () => {
+ beforeEach(() => {
+ sqlEditorMock.is_query_tool = true;
+ });
+
+ describe('when server answer with success', () => {
+ describe('when query was successful', () => {
+ beforeEach(() => {
+ response = {
+ data: {status: 'Success'},
+ };
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
+
+ executeQuery.poll();
+ });
+
+ it('should update the loading icon message', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith(
+ 'pgadmin-sqleditor:loading-icon:message',
+ 'Loading data from the database server and rendering...'
+ );
+ done();
+ }, 0);
+ });
+
+ it('should render the results', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.call_render_after_poll)
+ .toHaveBeenCalledWith({status: 'Success'});
+ done();
+ }, 0);
+ });
+ });
+
+ describe('when query is still running', () => {
+ context('when no additional information is returned', () => {
+ beforeEach(() => {
+ response = {
+ data: {status: 'Busy'},
+ };
+
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
+ executeQuery.poll();
+ });
+
+ it('should set the flag to inform SQLEditor a query is running', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.setIsQueryRunning)
+ .toHaveBeenCalledWith(true);
+ done();
+ }, 0);
+ });
+
+ it('should does not update history', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.update_msg_history).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should recursively call polling', (done) => {
+ setTimeout(() => {
+ expect(executeQuery.delayedPoll)
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+ });
+
+ context('when additional information is returned', () => {
+ beforeEach(() => {
+ response = {
+ data: {
+ status: 'Busy',
+ result: 'Some important result',
+ },
+ };
+
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
+ executeQuery.poll();
+ });
+
+ it('should set the flag to inform SQLEditor a query is running', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.setIsQueryRunning)
+ .toHaveBeenCalledWith(true);
+ done();
+ }, 0);
+ });
+
+ it('should update history message', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith('Busy', 'Some important result', false);
+ done();
+ }, 0);
+ });
+
+ it('should recursively call polling', (done) => {
+ setTimeout(() => {
+ expect(executeQuery.delayedPoll)
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+ });
+ });
+
+ describe('when the application lost connection with the database', () => {
+ beforeEach(() => {
+ response = {
+ data: {
+ status: 'NotConnected',
+ result: 'Some interesting result',
+ },
+ };
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
+
+ executeQuery.poll();
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should add new entry to history and update the Messages tab and clear the result grid', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith(
+ false,
+ 'Some interesting result',
+ true
+ );
+ done();
+ }, 0);
+ });
+
+ it('should enable the tool buttons', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.disable_tool_buttons)
+ .toHaveBeenCalledWith(false);
+ done();
+ }, 0);
+ });
+
+ it('should disable the cancel button', (done) => {
+ setTimeout(
+ () => {
+ expect(cancelButtonSpy)
+ .toHaveBeenCalledWith('disabled', true);
+ done();
+ }, 0);
+ });
+ });
+
+ describe('when query was cancelled', () => {
+ beforeEach(() => {
+ response = {
+ data: {status: 'Cancel'},
+ };
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
+
+ executeQuery.poll();
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should add new entry to history, add cancellation message to Messages tab and clear the result grid', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith(
+ false,
+ 'Execution Cancelled!',
+ true
+ );
+ done();
+ }, 0);
+ });
+ });
+ });
+
+ describe('when an error occur', () => {
+ let errorMessageJson = {
+ errormsg: 'Some error in JSON',
+ };
+ let errorMessageText = 'Some plain text error';
+
+ describe('when the connection to the server was lost', () => {
+ describe('when JSON response is available', () => {
+ describe('when login is not required', () => {
+ beforeEach(() => {
+ userManagementMock.is_pga_login_required.and.returnValue(false);
+ response = {responseJSON: errorMessageJson};
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, response);
+
+ executeQuery.poll();
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should reset last query information', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.resetQueryHistoryObject)
+ .toHaveBeenCalledWith(sqlEditorMock);
+ done();
+ }, 0);
+ });
+
+ it('should highlight the error in the SQL panel', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock._highlight_error)
+ .toHaveBeenCalledWith('Some error in JSON');
+ done();
+ }, 0);
+ });
+
+ it('should add new entry to history and update the Messages tab', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith(false, 'Some error in JSON');
+ done();
+ }, 0);
+ });
+
+ it('should enable the tool buttons', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.disable_tool_buttons)
+ .toHaveBeenCalledWith(false);
+ done();
+ }, 0);
+ });
+
+ it('should disable the cancel button', (done) => {
+ setTimeout(
+ () => {
+ expect(cancelButtonSpy)
+ .toHaveBeenCalledWith('disabled', true);
+ done();
+ }, 0);
+ });
+
+ it('should not login is displayed', (done) => {
+ setTimeout(
+ () => {
+ expect(userManagementMock.pga_login).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+ });
+
+ describe('when login is required', () => {
+ beforeEach(() => {
+ userManagementMock.is_pga_login_required.and.returnValue(true);
+ response = {responseJSON: errorMessageJson};
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, response);
+
+ executeQuery.poll();
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should reset last query information', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.resetQueryHistoryObject)
+ .toHaveBeenCalledWith(sqlEditorMock);
+ done();
+ }, 0);
+ });
+
+ it('should not highlight the error in the SQL panel', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock._highlight_error).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should not add new entry to history and update the Messages tab', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.update_msg_history).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should enable the tool buttons', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.disable_tool_buttons)
+ .toHaveBeenCalledWith(false);
+ done();
+ }, 0);
+ });
+
+ it('should disable the cancel button', (done) => {
+ setTimeout(
+ () => {
+ expect(cancelButtonSpy)
+ .toHaveBeenCalledWith('disabled', true);
+ done();
+ }, 0);
+ });
+
+ it('should login is displayed', (done) => {
+ setTimeout(
+ () => {
+ expect(userManagementMock.pga_login)
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+ });
+ });
+
+ describe('when no JSON response is available', () => {
+ describe('when login is not required', () => {
+ beforeEach(() => {
+ userManagementMock.is_pga_login_required.and.returnValue(false);
+ response = {
+ errormsg: errorMessageText,
+ };
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, response);
+
+ executeQuery.poll();
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should reset last query information', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.resetQueryHistoryObject)
+ .toHaveBeenCalledWith(sqlEditorMock);
+ done();
+ }, 0);
+ });
+
+ it('should highlight the error in the SQL panel', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock._highlight_error)
+ .toHaveBeenCalledWith('Some plain text error');
+ done();
+ }, 0);
+ });
+
+ it('should add new entry to history and update the Messages tab', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith(false, 'Some plain text error');
+ done();
+ }, 0);
+ });
+
+ it('should enable the tool buttons', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.disable_tool_buttons)
+ .toHaveBeenCalledWith(false);
+ done();
+ }, 0);
+ });
+
+ it('should disable the cancel button', (done) => {
+ setTimeout(
+ () => {
+ expect(cancelButtonSpy)
+ .toHaveBeenCalledWith('disabled', true);
+ done();
+ }, 0);
+ });
+
+ it('should login is not displayed', (done) => {
+ setTimeout(
+ () => {
+ expect(userManagementMock.pga_login).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+ });
+
+ describe('when login is required', () => {
+ beforeEach(() => {
+ userManagementMock.is_pga_login_required.and.returnValue(true);
+ response = {
+ errormsg: errorMessageText,
+ };
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, response);
+
+ executeQuery.poll();
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should reset last query information', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.resetQueryHistoryObject)
+ .toHaveBeenCalledWith(sqlEditorMock);
+ done();
+ }, 0);
+ });
+
+ it('should not highlight the error in the SQL panel', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock._highlight_error).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should not add new entry to history and update the Messages tab', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.update_msg_history).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should enable the tool buttons', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.disable_tool_buttons)
+ .toHaveBeenCalledWith(false);
+ done();
+ }, 0);
+ });
+
+ it('should disable the cancel button', (done) => {
+ setTimeout(
+ () => {
+ expect(cancelButtonSpy)
+ .toHaveBeenCalledWith('disabled', true);
+ done();
+ }, 0);
+ });
+
+ it('should login is displayed', (done) => {
+ setTimeout(
+ () => {
+ expect(userManagementMock.pga_login)
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+ });
+ });
+
+ describe('when cannot reach the Python Server', () => {
+ beforeEach(() => {
+ response = {readyState: 0};
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, response);
+
+ executeQuery.poll();
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should reset last query information', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.resetQueryHistoryObject)
+ .toHaveBeenCalledWith(sqlEditorMock);
+ done();
+ }, 0);
+ });
+
+ it('should not highlight the error in the SQL panel', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock._highlight_error).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should add new entry to history and update the Messages tab', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith(false, 'Not connected to the server or the connection to the server has been closed.');
+ done();
+ }, 0);
+ });
+
+ it('should enable the tool buttons', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.disable_tool_buttons)
+ .toHaveBeenCalledWith(false);
+ done();
+ }, 0);
+ });
+
+ it('should disable the cancel button', (done) => {
+ setTimeout(
+ () => {
+ expect(cancelButtonSpy)
+ .toHaveBeenCalledWith('disabled', true);
+ done();
+ }, 0);
+ });
+
+ it('should login is not displayed', (done) => {
+ setTimeout(
+ () => {
+ expect(userManagementMock.pga_login).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+ });
+ });
+ });
+ });
+
+ context('when SQLEditor is NOT the query tool', () => {
+ beforeEach(() => {
+ sqlEditorMock.is_query_tool = false;
+ });
+
+ describe('when server answer with success', () => {
+ describe('when query was successful', () => {
+ beforeEach(() => {
+ response = {
+ data: {status: 'Success'},
+ };
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
+
+ executeQuery.poll();
+ });
+
+ it('should update the loading icon message', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith(
+ 'pgadmin-sqleditor:loading-icon:message',
+ 'Loading data from the database server and rendering...'
+ );
+ done();
+ }, 0);
+ });
+
+ it('should render the results', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.call_render_after_poll)
+ .toHaveBeenCalledWith({status: 'Success'});
+ done();
+ }, 0);
+ });
+ });
+
+ describe('when query is still running', () => {
+ context('when no additional information is returned', () => {
+ beforeEach(() => {
+ response = {
+ data: {status: 'Busy'},
+ };
+
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
+ executeQuery.poll();
+ });
+
+ it('should set the flag to inform SQLEditor a query is running', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.setIsQueryRunning)
+ .toHaveBeenCalledWith(true);
+ done();
+ }, 0);
+ });
+
+ it('should does not update history', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.update_msg_history).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should recursively call polling', (done) => {
+ setTimeout(() => {
+ expect(executeQuery.delayedPoll)
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+ });
+
+ context('when additional information is returned', () => {
+ beforeEach(() => {
+ response = {
+ data: {
+ status: 'Busy',
+ result: 'Some important result',
+ },
+ };
+
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
+ executeQuery.poll();
+ });
+
+ it('should set the flag to inform SQLEditor a query is running', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.setIsQueryRunning)
+ .toHaveBeenCalledWith(true);
+ done();
+ }, 0);
+ });
+
+ it('should update history message', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith('Busy', 'Some important result', false);
+ done();
+ }, 0);
+ });
+
+ it('should recursively call polling', (done) => {
+ setTimeout(() => {
+ expect(executeQuery.delayedPoll)
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+ });
+ });
+
+ describe('when the application lost connection with the database', () => {
+ beforeEach(() => {
+ response = {
+ data: {
+ status: 'NotConnected',
+ result: 'Some interesting result',
+ },
+ };
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
+
+ executeQuery.poll();
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should add new entry to history and update the Messages tab and clear the result grid', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith(
+ false,
+ 'Some interesting result',
+ true
+ );
+ done();
+ }, 0);
+ });
+
+ it('should NOT enable the tool buttons', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.disable_tool_buttons).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should NOT disable the cancel button', (done) => {
+ setTimeout(
+ () => {
+ expect(cancelButtonSpy).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+ });
+
+ describe('when query was cancelled', () => {
+ beforeEach(() => {
+ response = {
+ data: {status: 'Cancel'},
+ };
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
+
+ executeQuery.poll();
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should add new entry to history, add cancellation message to Messages tab and clear the result grid', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith(
+ false,
+ 'Execution Cancelled!',
+ true
+ );
+ done();
+ }, 0);
+ });
+ });
+ });
+
+ describe('when an error occur', () => {
+ let errorMessageJson = {
+ errormsg: 'Some error in JSON',
+ };
+ let errorMessageText = 'Some plain text error';
+ let response;
+
+ describe('when the connection to the server was lost', () => {
+ describe('when JSON response is available', () => {
+ beforeEach(() => {
+ response = {responseJSON: errorMessageJson};
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, response);
+
+ executeQuery.poll();
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should reset last query information', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.resetQueryHistoryObject)
+ .toHaveBeenCalledWith(sqlEditorMock);
+ done();
+ }, 0);
+ });
+
+ it('should highlight the error in the SQL panel', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock._highlight_error)
+ .toHaveBeenCalledWith('Some error in JSON');
+ done();
+ }, 0);
+ });
+
+ it('should add new entry to history and update the Messages tab', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith(false, 'Some error in JSON');
+ done();
+ }, 0);
+ });
+
+ it('should enable the tool buttons', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.disable_tool_buttons).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should disable the cancel button', (done) => {
+ setTimeout(
+ () => {
+ expect(cancelButtonSpy).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+ });
+ describe('when no JSON response is available', () => {
+ beforeEach(() => {
+ response = {errormsg: errorMessageText};
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, response);
+
+ executeQuery.poll();
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should reset last query information', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.resetQueryHistoryObject)
+ .toHaveBeenCalledWith(sqlEditorMock);
+ done();
+ }, 0);
+ });
+
+ it('should highlight the error in the SQL panel', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock._highlight_error)
+ .toHaveBeenCalledWith('Some plain text error');
+ done();
+ }, 0);
+ });
+
+ it('should add new entry to history and update the Messages tab', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith(false, 'Some plain text error');
+ done();
+ }, 0);
+ });
+
+ it('should not enable the tool buttons', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.disable_tool_buttons).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should not disable the cancel button', (done) => {
+ setTimeout(
+ () => {
+ expect(cancelButtonSpy).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+ });
+
+ describe('when cannot reach the Python Server', () => {
+ beforeEach(() => {
+ response = {readyState: 0};
+ networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, response);
+
+ executeQuery.poll();
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should reset last query information', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.resetQueryHistoryObject)
+ .toHaveBeenCalledWith(sqlEditorMock);
+ done();
+ }, 0);
+ });
+
+ it('should not highlight the error in the SQL panel', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock._highlight_error).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should add new entry to history and update the Messages tab', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith(false, 'Not connected to the server or the connection to the server has been closed.');
+ done();
+ }, 0);
+ });
+
+ it('should enable the tool buttons', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.disable_tool_buttons).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should disable the cancel button', (done) => {
+ setTimeout(
+ () => {
+ expect(cancelButtonSpy).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+ });
+ });
+ });
+ });
+ });
+
+ describe('#execute', () => {
+ let response;
+
+ beforeEach(() => {
+ response = {
+ 'info': '',
+ 'errormsg': '',
+ 'data': {
+ 'status': true,
+ 'can_edit': false,
+ 'info_notifier_timeout': 5,
+ 'result': '2',
+ 'can_filter': false,
+ },
+ 'result': null,
+ 'success': 1,
+ };
+ });
+
+ context('when the SQL statement is empty', () => {
+ it('should return without executing', (done) => {
+ let wasNetworkCalled = false;
+ networkMock.onAny('/sqleditor/query_tool/start/123').reply(() => {
+ wasNetworkCalled = true;
+ });
+
+ executeQuery.execute('', {});
+
+ setTimeout(() => {
+ expect(wasNetworkCalled).toBe(false);
+ done();
+ }, 0);
+ });
+ });
+
+ context('when the SQL statement is not empty', () => {
+ let pollSpy;
+ let jqueryPropSpy;
+
+ beforeEach(() => {
+ jqueryPropSpy = spyOn($.fn, 'prop');
+ sqlEditorMock.gridView = {};
+ sqlEditorMock.gridView.query_tool_obj = jasmine.createSpyObj(
+ 'QueryToolObject',
+ ['removeLineClass']
+ );
+ });
+
+ describe('before the backend request', () => {
+ beforeEach(() => {
+ jasmine.clock().install();
+ jasmine.clock().mockDate(startTime);
+ jasmine.clock().tick(50);
+ networkMock.onAny('/sqleditor/query_tool/start/123').reply(200, response);
+ pollSpy = spyOn(executeQuery, 'poll');
+ executeQuery.execute('some sql query', '');
+ });
+
+ afterEach(function () {
+ jasmine.clock().uninstall();
+ });
+
+ it('should update loading text to "Initializing query execution"', () => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith(
+ 'pgadmin-sqleditor:loading-icon:show',
+ 'Initializing query execution...'
+ );
+ });
+
+ it('disables the run query button', () => {
+ const callToProp = findJQueryCallWithSelector(jqueryPropSpy, '#btn-flash');
+
+ expect(callToProp).jQuerytoHaveBeenCalledWith('disabled', true);
+ });
+
+ it('enable the cancel query button', () => {
+ const callToProp = findJQueryCallWithSelector(jqueryPropSpy, '#btn-cancel-query');
+
+ expect(callToProp).jQuerytoHaveBeenCalledWith('disabled', false);
+ });
+
+ it('disable the query tool buttons', () => {
+ expect(sqlEditorMock.disable_tool_buttons).toHaveBeenCalledWith(true);
+ });
+
+ it('initializes the polling flags', () => {
+ expect(sqlEditorMock._init_polling_flags).toHaveBeenCalled();
+ });
+
+ it('save the query', () => {
+ expect(sqlEditorMock.query).toEqual('some sql query');
+ });
+
+ it('reset the number of rows that were affected', () => {
+ expect(sqlEditorMock.rows_affected).toBe(0);
+ });
+
+ it('reset query start time', () => {
+ expect(sqlEditorMock.query_start_time.getTime()).toEqual(startTime.getTime() + 50);
+ });
+ });
+
+ describe('when HTTP return 200', () => {
+ describe('when backend informs that query started successfully', () => {
+ beforeEach(() => {
+ networkMock.onAny('/sqleditor/query_tool/start/123').reply(200, response);
+ pollSpy = spyOn(executeQuery, 'delayedPoll');
+ executeQuery.execute('some sql query', '');
+ });
+
+ it('should changes the loading message to "Waiting for the query execution to complete"', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.trigger).toHaveBeenCalledWith(
+ 'pgadmin-sqleditor:loading-icon:message',
+ 'Waiting for the query execution to complete...'
+ );
+ done();
+ }, 0);
+ });
+
+ it('should update the can edit flag', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.can_edit).toBe(false);
+ done();
+ }, 0);
+ });
+
+ it('should update the can filter flag', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.can_filter).toBe(false);
+ done();
+ }, 0);
+ });
+
+ it('should update information notifier timeout', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.info_notifier_timeout).toBe(5);
+ done();
+ }, 0);
+ });
+
+ it('should start polling', (done) => {
+ setTimeout(() => {
+ expect(pollSpy).toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+ });
+
+ describe('when explain plan is not empty', () => {
+ it('should send the explain plan informatioon through the wire', (done) => {
+ networkMock.onAny('/sqleditor/query_tool/start/123').reply((config) => {
+ setTimeout(() => {
+ expect(config.data).toEqual(JSON.stringify({
+ sql: 'some sql query',
+ explain_plan: {
+ buffers: true,
+ analyze: false,
+ timing: true,
+ summary: false,
+ },
+ }));
+
+ done();
+ }, 0);
+ return [200, ''];
+ });
+ pollSpy = spyOn(executeQuery, 'delayedPoll');
+ executeQuery.execute('some sql query', {
+ buffers: true,
+ analyze: false,
+ timing: true,
+ summary: false,
+ });
+ });
+
+
+ });
+
+ describe('when backend informs that there was a problem with the query', () => {
+ beforeEach(() => {
+ response.data.status = false;
+ response.data.result = 'something went wrong';
+ networkMock.onAny('/sqleditor/query_tool/start/123').reply(200, response);
+ pollSpy = spyOn(executeQuery, 'poll');
+ executeQuery.execute('some sql query', '');
+ });
+
+ it('hide the loading screen', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.trigger).toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('disable the cancel query button', (done) => {
+ setTimeout(() => {
+ const callToProp = findJQueryCallWithSelector(jqueryPropSpy, '#btn-cancel-query');
+
+ expect(callToProp).jQuerytoHaveBeenCalledWith('disabled', true);
+ done();
+ }, 0);
+ });
+
+ it('enable the query tool buttons', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.disable_tool_buttons).toHaveBeenCalledWith(false);
+ done();
+ }, 0);
+ });
+
+ it('update the history tab with the result message', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.update_msg_history).toHaveBeenCalledWith(false, 'something went wrong');
+ done();
+ }, 0);
+ });
+
+ it('highlight the error in the editor', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock._highlight_error).toHaveBeenCalledWith('something went wrong');
+ done();
+ }, 0);
+ });
+
+ it('should not start polling', (done) => {
+ setTimeout(() => {
+ expect(pollSpy).not.toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+ });
+
+ describe('when there is a marker set in the grid', () => {
+ let markerClearSpy;
+ beforeEach(() => {
+ sqlEditorMock.gridView.marker = jasmine.createSpyObj(
+ 'GridViewMarker',
+ ['clear']
+ );
+ markerClearSpy = sqlEditorMock.gridView.marker.clear;
+ networkMock.onAny('/sqleditor/query_tool/start/123').reply(200, response);
+ pollSpy = spyOn(executeQuery, 'poll');
+ executeQuery.execute('some sql query', '');
+ });
+
+ it('should call clear function on marker', (done) => {
+ setTimeout(() => {
+ expect(markerClearSpy).toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should removes the marker', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.gridView.marker).toEqual(null);
+ done();
+ }, 0);
+ });
+
+ it('should remove CSS classes from the editor', (done) => {
+ setTimeout(() => {
+ expect(sqlEditorMock.gridView.query_tool_obj.removeLineClass)
+ .toHaveBeenCalledWith(sqlEditorMock.marked_line_no, 'wrap', 'CodeMirror-activeline-background');
+ done();
+ }, 0);
+ });
+ });
+ });
+
+ describe('when cannot reach the Python Server', () => {
+ beforeEach(() => {
+ response = {
+ readyState: 0,
+ };
+ networkMock.onAny('/sqleditor/query_tool/start/123').reply(500, response);
+
+
+ executeQuery.execute('some sql query', '');
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should not highlight the error in the SQL panel', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock._highlight_error).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should add new entry to history and update the Messages tab', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith(false, 'Not connected to the server or the connection to the server has been closed.');
+ done();
+ }, 0);
+ });
+
+ it('should enable the tool buttons', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.disable_tool_buttons)
+ .toHaveBeenCalledWith(false);
+ done();
+ }, 0);
+ });
+
+ it('should disable the cancel button', (done) => {
+ setTimeout(
+ () => {
+ const callToProp = findJQueryCallWithSelector(jqueryPropSpy, '#btn-cancel-query');
+
+ expect(callToProp).jQuerytoHaveBeenCalledWith('disabled', true);
+ done();
+ }, 0);
+ });
+ });
+
+ describe('when error is returned by the server', () => {
+ describe('when login is not required', () => {
+ beforeEach(() => {
+ userManagementMock.is_pga_login_required.and.returnValue(false);
+ response.errormsg = 'some error message';
+ networkMock.onAny('/sqleditor/query_tool/start/123').reply(500, response);
+
+
+ executeQuery.execute('some sql query', '');
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should not highlight the error in the SQL panel', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock._highlight_error).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should add new entry to history and update the Messages tab', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith(false, 'some error message');
+ done();
+ }, 0);
+ });
+
+ it('should enable the tool buttons', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.disable_tool_buttons)
+ .toHaveBeenCalledWith(false);
+ done();
+ }, 0);
+ });
+
+ it('should disable the cancel button', (done) => {
+ setTimeout(
+ () => {
+ const callToProp = findJQueryCallWithSelector(jqueryPropSpy, '#btn-cancel-query');
+
+ expect(callToProp).jQuerytoHaveBeenCalledWith('disabled', true);
+ done();
+ }, 0);
+ });
+
+ it('should not save the state', () => {
+ setTimeout(() => {
+ expect(sqlEditorMock.save_state).not.toHaveBeenCalled();
+ }, 0);
+ });
+
+ it('should not display pga login', () => {
+ setTimeout(() => {
+ expect(userManagementMock.pga_login).not.toHaveBeenCalled();
+ }, 0);
+ });
+ });
+ describe('when login is required', () => {
+ beforeEach(() => {
+ userManagementMock.is_pga_login_required.and.returnValue(true);
+ response.errormsg = 'some error message';
+ networkMock.onAny('/sqleditor/query_tool/start/123').reply(500, response);
+
+
+ executeQuery.execute('some sql query', '');
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should not highlight the error in the SQL panel', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock._highlight_error).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should add new entry to history and update the Messages tab', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith(false, 'some error message');
+ done();
+ }, 0);
+ });
+
+ it('should enable the tool buttons', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.disable_tool_buttons)
+ .toHaveBeenCalledWith(false);
+ done();
+ }, 0);
+ });
+
+ it('should disable the cancel button', (done) => {
+ setTimeout(
+ () => {
+ const callToProp = findJQueryCallWithSelector(jqueryPropSpy, '#btn-cancel-query');
+
+ expect(callToProp).jQuerytoHaveBeenCalledWith('disabled', true);
+ done();
+ }, 0);
+ });
+
+ it('should save the state', () => {
+ setTimeout(() => {
+ expect(sqlEditorMock.save_state).toHaveBeenCalledWith(
+ 'execute',
+ ['']
+ );
+ }, 0);
+ });
+
+ it('should display pga login', () => {
+ setTimeout(() => {
+ expect(userManagementMock.pga_login).toHaveBeenCalled();
+ }, 0);
+ });
+ });
+ describe('when a new transaction is not required', () => {
+ beforeEach(() => {
+ isNewTransactionRequiredMock.and.returnValue(false);
+ response.errormsg = 'some error message';
+ networkMock.onAny('/sqleditor/query_tool/start/123').reply(500, response);
+
+
+ executeQuery.execute('some sql query', '');
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should not highlight the error in the SQL panel', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock._highlight_error).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should add new entry to history and update the Messages tab', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith(false, 'some error message');
+ done();
+ }, 0);
+ });
+
+ it('should enable the tool buttons', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.disable_tool_buttons)
+ .toHaveBeenCalledWith(false);
+ done();
+ }, 0);
+ });
+
+ it('should disable the cancel button', (done) => {
+ setTimeout(
+ () => {
+ const callToProp = findJQueryCallWithSelector(jqueryPropSpy, '#btn-cancel-query');
+
+ expect(callToProp).jQuerytoHaveBeenCalledWith('disabled', true);
+ done();
+ }, 0);
+ });
+
+ it('should not save the state', () => {
+ setTimeout(() => {
+ expect(sqlEditorMock.save_state).not.toHaveBeenCalled();
+ }, 0);
+ });
+
+ it('should not display pga login', () => {
+ setTimeout(() => {
+ expect(userManagementMock.pga_login).not.toHaveBeenCalled();
+ }, 0);
+ });
+
+ it('should not initialize a new transaction', () => {
+ setTimeout(() => {
+ expect(sqlEditorMock.init_transaction).not.toHaveBeenCalled();
+ }, 0);
+ });
+ });
+
+ describe('when a new transaction is required', () => {
+ beforeEach(() => {
+ isNewTransactionRequiredMock.and.returnValue(true);
+ response.errormsg = 'some error message';
+ networkMock.onAny('/sqleditor/query_tool/start/123').reply(500, response);
+
+ executeQuery.execute('some sql query', '');
+ });
+
+ it('should hide the loading icon', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.trigger)
+ .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
+ done();
+ }, 0);
+ });
+
+ it('should not highlight the error in the SQL panel', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock._highlight_error).not
+ .toHaveBeenCalled();
+ done();
+ }, 0);
+ });
+
+ it('should add new entry to history and update the Messages tab', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.update_msg_history)
+ .toHaveBeenCalledWith(false, 'some error message');
+ done();
+ }, 0);
+ });
+
+ it('should enable the tool buttons', (done) => {
+ setTimeout(
+ () => {
+ expect(sqlEditorMock.disable_tool_buttons)
+ .toHaveBeenCalledWith(false);
+ done();
+ }, 0);
+ });
+
+ it('should disable the cancel button', (done) => {
+ setTimeout(
+ () => {
+ const callToProp = findJQueryCallWithSelector(jqueryPropSpy, '#btn-cancel-query');
+
+ expect(callToProp).jQuerytoHaveBeenCalledWith('disabled', true);
+ done();
+ }, 0);
+ });
+
+ it('should save the state', () => {
+ setTimeout(() => {
+ expect(sqlEditorMock.save_state).toHaveBeenCalledWith(
+ 'execute',
+ ['']
+ );
+ }, 0);
+ });
+
+ it('should not display pga login', () => {
+ setTimeout(() => {
+ expect(userManagementMock.pga_login).not.toHaveBeenCalled();
+ }, 0);
+ });
+
+ it('should initialize a new transaction', () => {
+ setTimeout(() => {
+ expect(sqlEditorMock.init_transaction).toHaveBeenCalled();
+ }, 0);
+ });
+ });
+ });
+ });
+ });
+
+ let findJQueryCallWithSelector = (jquerySpy, selector) => {
+ let result = undefined;
+
+ jquerySpy.calls.all().forEach((call) => {
+ if (call.object.selector === selector) {
+ result = call;
+ }
+ });
+ return result;
+ };
+});
+
+const jQuerytoHaveBeenCalledWith = function (util) {
+ return {
+ compare: function (actual) {
+ let result = {};
+ let expectedArgs = jasmine.util.argsToArray(arguments).slice(1);
+ if (actual.object === undefined || actual.object.selector === undefined) {
+ throw new Error('Expected a JQuery object, but got ' + jasmine.pp(actual) + '.');
+ }
+
+ result.pass = util.equals(actual.args, expectedArgs, '');
+ if (result.pass) {
+ result.message = 'larifo';
+ } else {
+ result.message =
+ 'Expected jquery with selector "' +
+ actual.object.selector +
+ '" to have been called with ' +
+ jasmine.pp(expectedArgs) +
+ ' but was called with ' +
+ jasmine.pp(actual.args);
+ }
+
+ return result;
+ },
+ };
+};
+
diff --git a/web/regression/javascript/sqleditor/is_new_transaction_required_spec.js b/web/regression/javascript/sqleditor/is_new_transaction_required_spec.js
new file mode 100644
index 00000000..d323700d
--- /dev/null
+++ b/web/regression/javascript/sqleditor/is_new_transaction_required_spec.js
@@ -0,0 +1,65 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2018, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////////////////
+
+import {is_new_transaction_required} from '../../../pgadmin/static/js/sqleditor/is_new_transaction_required';
+
+describe('#is_new_transaction_required', () => {
+ describe('when status is not 404', () => {
+ it('should return false', () => {
+ expect(is_new_transaction_required({
+ status: 300,
+ })).toBe(false);
+ });
+ });
+
+ describe('when status is 404', () => {
+ describe('when responseJSON is not present', () => {
+ it('should return false', () => {
+ expect(is_new_transaction_required({
+ status: 404,
+ })).toBeFalsy();
+ });
+ });
+
+ describe('when responseJSON is present', () => {
+ describe('when info is not present inside responseJSON', () => {
+ it('should return false', () => {
+ expect(is_new_transaction_required({
+ status: 404,
+ responseJSON: {},
+ })).toBeFalsy();
+ });
+ });
+
+ describe('when info is present inside responseJSON', () => {
+ describe('when info value is not "DATAGRID_TRANSACTION_REQUIRED"', () => {
+ it('should return false', () => {
+ expect(is_new_transaction_required({
+ status: 404,
+ responseJSON: {
+ info: 'some information',
+ },
+ })).toBe(false);
+ });
+ });
+
+ describe('when info value is "DATAGRID_TRANSACTION_REQUIRED"', () => {
+ it('should return false', () => {
+ expect(is_new_transaction_required({
+ status: 404,
+ responseJSON: {
+ info: 'DATAGRID_TRANSACTION_REQUIRED',
+ },
+ })).toBe(true);
+ });
+ });
+ });
+ });
+ });
+});
diff --git a/web/regression/javascript/sqleditor/query_tool_actions_spec.js b/web/regression/javascript/sqleditor/query_tool_actions_spec.js
index c46b4a24..f3ac7815 100644
--- a/web/regression/javascript/sqleditor/query_tool_actions_spec.js
+++ b/web/regression/javascript/sqleditor/query_tool_actions_spec.js
@@ -43,7 +43,6 @@ describe('queryToolActions', () => {
expect(sqlEditorController.execute_data_query).toHaveBeenCalled();
});
-
});
});
@@ -51,60 +50,100 @@ describe('queryToolActions', () => {
describe('when verbose and costs are not selected and buffers and timing are not selected', () => {
beforeEach(() => {
setUpSpies('', '');
- spyOn(queryToolActions, '_verbose').and.returnValue('OFF');
- spyOn(queryToolActions, '_costsEnabled').and.returnValue('OFF');
- spyOn(queryToolActions, '_buffers').and.returnValue('OFF');
- spyOn(queryToolActions, '_timing').and.returnValue('OFF');
+ spyOn(queryToolActions, '_verbose').and.returnValue(false);
+ spyOn(queryToolActions, '_costsEnabled').and.returnValue(false);
+ spyOn(queryToolActions, '_buffers').and.returnValue(false);
+ spyOn(queryToolActions, '_timing').and.returnValue(false);
});
+
it('calls the execute function', () => {
queryToolActions.explainAnalyze(sqlEditorController);
- let explainAnalyzeQuery = 'EXPLAIN (FORMAT JSON, ANALYZE ON, VERBOSE OFF, COSTS OFF, BUFFERS OFF, TIMING OFF) ';
- expect(sqlEditorController.execute).toHaveBeenCalledWith(explainAnalyzeQuery);
+
+ // let explainAnalyzeQuery = 'EXPLAIN (FORMAT JSON, ANALYZE ON, VERBOSE OFF, COSTS OFF, BUFFERS OFF, TIMING OFF) ';
+ const explainObject = {
+ format: 'json',
+ analyze: true,
+ verbose: false,
+ costs: false,
+ buffers: false,
+ timing: false,
+ summary: false,
+ };
+
+ expect(sqlEditorController.execute).toHaveBeenCalledWith(explainObject);
});
});
describe('when verbose and costs and buffers and timing are all selected', () => {
beforeEach(() => {
setUpSpies('', '');
- spyOn(queryToolActions, '_verbose').and.returnValue('ON');
- spyOn(queryToolActions, '_costsEnabled').and.returnValue('ON');
- spyOn(queryToolActions, '_buffers').and.returnValue('ON');
- spyOn(queryToolActions, '_timing').and.returnValue('ON');
+ spyOn(queryToolActions, '_verbose').and.returnValue(true);
+ spyOn(queryToolActions, '_costsEnabled').and.returnValue(true);
+ spyOn(queryToolActions, '_buffers').and.returnValue(true);
+ spyOn(queryToolActions, '_timing').and.returnValue(true);
});
it('calls the execute function', () => {
queryToolActions.explainAnalyze(sqlEditorController);
- let explainAnalyzeQuery = 'EXPLAIN (FORMAT JSON, ANALYZE ON, VERBOSE ON, COSTS ON, BUFFERS ON, TIMING ON) ';
- expect(sqlEditorController.execute).toHaveBeenCalledWith(explainAnalyzeQuery);
+ const explainObject = {
+ format: 'json',
+ analyze: true,
+ verbose: true,
+ costs: true,
+ buffers: true,
+ timing: true,
+ summary: false,
+ };
+ expect(sqlEditorController.execute).toHaveBeenCalledWith(explainObject);
});
});
describe('when verbose is selected and costs is not selected and buffer is selected and timing is not selected', () => {
beforeEach(() => {
setUpSpies('', '');
- spyOn(queryToolActions, '_verbose').and.returnValue('ON');
- spyOn(queryToolActions, '_costsEnabled').and.returnValue('OFF');
- spyOn(queryToolActions, '_buffers').and.returnValue('ON');
- spyOn(queryToolActions, '_timing').and.returnValue('OFF');
+ spyOn(queryToolActions, '_verbose').and.returnValue(true);
+ spyOn(queryToolActions, '_costsEnabled').and.returnValue(false);
+ spyOn(queryToolActions, '_buffers').and.returnValue(true);
+ spyOn(queryToolActions, '_timing').and.returnValue(false);
});
it('calls the execute function', () => {
queryToolActions.explainAnalyze(sqlEditorController);
- let explainAnalyzeQuery = 'EXPLAIN (FORMAT JSON, ANALYZE ON, VERBOSE ON, COSTS OFF, BUFFERS ON, TIMING OFF) ';
- expect(sqlEditorController.execute).toHaveBeenCalledWith(explainAnalyzeQuery);
+
+ const explainObject = {
+ format: 'json',
+ analyze: true,
+ verbose: true,
+ costs: false,
+ buffers: true,
+ timing: false,
+ summary: false,
+ };
+
+ expect(sqlEditorController.execute).toHaveBeenCalledWith(explainObject);
});
});
describe('when verbose is not selected and costs is selected and buffer is not selected and timing is selected', () => {
beforeEach(() => {
setUpSpies('', '');
- spyOn(queryToolActions, '_verbose').and.returnValue('OFF');
- spyOn(queryToolActions, '_costsEnabled').and.returnValue('ON');
- spyOn(queryToolActions, '_buffers').and.returnValue('OFF');
- spyOn(queryToolActions, '_timing').and.returnValue('ON');
+ spyOn(queryToolActions, '_verbose').and.returnValue(false);
+ spyOn(queryToolActions, '_costsEnabled').and.returnValue(true);
+ spyOn(queryToolActions, '_buffers').and.returnValue(false);
+ spyOn(queryToolActions, '_timing').and.returnValue(true);
});
it('calls the execute function', () => {
queryToolActions.explainAnalyze(sqlEditorController);
- let explainAnalyzeQuery = 'EXPLAIN (FORMAT JSON, ANALYZE ON, VERBOSE OFF, COSTS ON, BUFFERS OFF, TIMING ON) ';
- expect(sqlEditorController.execute).toHaveBeenCalledWith(explainAnalyzeQuery);
+
+ const explainObject = {
+ format: 'json',
+ analyze: true,
+ verbose: false,
+ costs: true,
+ buffers: false,
+ timing: true,
+ summary: false,
+ };
+
+ expect(sqlEditorController.execute).toHaveBeenCalledWith(explainObject);
});
});
});
@@ -113,39 +152,67 @@ describe('queryToolActions', () => {
describe('when verbose and costs are selected', () => {
beforeEach(() => {
setUpSpies('', '');
- spyOn(queryToolActions, '_verbose').and.returnValue('ON');
- spyOn(queryToolActions, '_costsEnabled').and.returnValue('ON');
+ spyOn(queryToolActions, '_verbose').and.returnValue(true);
+ spyOn(queryToolActions, '_costsEnabled').and.returnValue(true);
});
+
it('calls the execute function', () => {
queryToolActions.explain(sqlEditorController);
- let explainQuery = 'EXPLAIN (FORMAT JSON, ANALYZE OFF, VERBOSE ON, COSTS ON, BUFFERS OFF, TIMING OFF) ';
- expect(sqlEditorController.execute).toHaveBeenCalledWith(explainQuery);
+ const explainObject = {
+ format: 'json',
+ analyze: false,
+ verbose: true,
+ costs: true,
+ buffers: false,
+ timing: false,
+ summary: false,
+ };
+ expect(sqlEditorController.execute).toHaveBeenCalledWith(explainObject);
});
});
describe('when verbose and costs are not selected', () => {
beforeEach(() => {
setUpSpies('', '');
- spyOn(queryToolActions, '_verbose').and.returnValue('OFF');
- spyOn(queryToolActions, '_costsEnabled').and.returnValue('OFF');
+ spyOn(queryToolActions, '_verbose').and.returnValue(false);
+ spyOn(queryToolActions, '_costsEnabled').and.returnValue(false);
});
+
it('calls the execute function', () => {
queryToolActions.explain(sqlEditorController);
- let explainQuery = 'EXPLAIN (FORMAT JSON, ANALYZE OFF, VERBOSE OFF, COSTS OFF, BUFFERS OFF, TIMING OFF) ';
- expect(sqlEditorController.execute).toHaveBeenCalledWith(explainQuery);
+ const explainObject = {
+ format: 'json',
+ analyze: false,
+ verbose: false,
+ costs: false,
+ buffers: false,
+ timing: false,
+ summary: false,
+ };
+
+ expect(sqlEditorController.execute).toHaveBeenCalledWith(explainObject);
});
});
describe('when verbose is selected and costs is not selected', () => {
beforeEach(() => {
setUpSpies('', '');
- spyOn(queryToolActions, '_verbose').and.returnValue('ON');
- spyOn(queryToolActions, '_costsEnabled').and.returnValue('OFF');
+ spyOn(queryToolActions, '_verbose').and.returnValue(true);
+ spyOn(queryToolActions, '_costsEnabled').and.returnValue(false);
});
+
it('calls the execute function', () => {
queryToolActions.explain(sqlEditorController);
- let explainQuery = 'EXPLAIN (FORMAT JSON, ANALYZE OFF, VERBOSE ON, COSTS OFF, BUFFERS OFF, TIMING OFF) ';
- expect(sqlEditorController.execute).toHaveBeenCalledWith(explainQuery);
+ const explainObject = {
+ format: 'json',
+ analyze: false,
+ verbose: true,
+ costs: false,
+ buffers: false,
+ timing: false,
+ summary: false,
+ };
+ expect(sqlEditorController.execute).toHaveBeenCalledWith(explainObject);
});
});
});
[application/octet-stream] update-javascript-packages.diff (13.0K, 4-update-javascript-packages.diff)
download | inline diff:
diff --git a/web/karma.conf.js b/web/karma.conf.js
index e9b0e062..9f04cb48 100644
--- a/web/karma.conf.js
+++ b/web/karma.conf.js
@@ -1,6 +1,6 @@
// Karma configuration
-// Generated on Wed Mar 01 2017 14:19:28 GMT-0500 (EST)
const webpackConfig = require('./webpack.test.config.js');
+const isDocker = require('is-docker')();
module.exports = function (config) {
config.set({
@@ -8,7 +8,7 @@ module.exports = function (config) {
reporters: ['progress', 'kjhtml'],
plugins: [
'karma-webpack',
- 'karma-phantomjs-launcher',
+ 'karma-chrome-launcher',
'karma-jasmine',
'karma-jasmine-html-reporter',
],
@@ -56,7 +56,15 @@ module.exports = function (config) {
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
- browsers: ['PhantomJS'],
+ customLaunchers: {
+ ChromeCustom: {
+ base: 'ChromeHeadless',
+ // We must disable the Chrome sandbox when running Chrome inside Docker (Chrome's sandbox needs
+ // more permissions than Docker allows by default)
+ flags: isDocker ? ['--no-sandbox'] : []
+ }
+ },
+ browsers: ['ChromeCustom'],
// Continuous Integration mode
diff --git a/web/package.json b/web/package.json
index 01a55ec4..a6c9659b 100644
--- a/web/package.json
+++ b/web/package.json
@@ -1,8 +1,9 @@
{
"license": "PostgreSQL",
"devDependencies": {
+ "axios-mock-adapter": "^1.11.0",
"babel-core": "~6.24.0",
- "babel-loader": "~6.4.1",
+ "babel-loader": "~7.1.2",
"babel-preset-es2015": "~6.24.0",
"babel-preset-react": "~6.23.0",
"cross-env": "^5.0.1",
@@ -11,14 +12,16 @@
"enzyme-matchers": "^3.1.0",
"eslint": "3.19.0",
"eslint-plugin-react": "^6.10.3",
- "extract-text-webpack-plugin": "^2.1.2",
+ "extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^0.11.2",
"image-webpack-loader": "^3.3.1",
- "jasmine-core": "~2.5.2",
- "jasmine-enzyme": "^3.1.0",
+ "is-docker": "^1.1.0",
+ "jasmine-core": "~2.9.0",
+ "jasmine-enzyme": "~4.0.0",
"karma": "~1.5.0",
"karma-babel-preprocessor": "^6.0.1",
"karma-browserify": "~5.1.1",
+ "karma-chrome-launcher": "^2.2.0",
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"karma-phantomjs-launcher": "~1.0.2",
@@ -69,7 +72,7 @@
"jquery": "1.11.2",
"jquery-contextmenu": "^2.5.0",
"jquery-ui": "^1.12.1",
- "moment": "^2.18.1",
+ "moment": "^2.20.1",
"mousetrap": "^1.6.1",
"prop-types": "^15.5.10",
"react": "file:../web/pgadmin/static/vendor/react",
diff --git a/web/yarn.lock b/web/yarn.lock
index b57a80ca..4464b140 100644
--- a/web/yarn.lock
+++ b/web/yarn.lock
@@ -283,6 +283,12 @@ async@^2.1.2, async@^2.1.5:
dependencies:
lodash "^4.14.0"
+async@^2.4.1:
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4"
+ dependencies:
+ lodash "^4.14.0"
+
async@~0.9.0:
version "0.9.2"
resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d"
@@ -314,6 +320,12 @@ aws4@^1.2.1, aws4@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
+axios-mock-adapter@^1.11.0:
+ version "1.11.0"
+ resolved "https://registry.yarnpkg.com/axios-mock-adapter/-/axios-mock-adapter-1.11.0.tgz#96e4bb2702cf6900f2ae5f9bdbef6e5dc86669e2"
+ dependencies:
+ deep-equal "^1.0.1"
+
axios@^0.16.1:
version "0.16.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.16.2.tgz#ba4f92f17167dfbab40983785454b9ac149c3c6d"
@@ -473,14 +485,13 @@ babel-helpers@^6.24.1:
babel-runtime "^6.22.0"
babel-template "^6.24.1"
-babel-loader@~6.4.1:
- version "6.4.1"
- resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-6.4.1.tgz#0b34112d5b0748a8dcdbf51acf6f9bd42d50b8ca"
+babel-loader@~7.1.2:
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.2.tgz#f6cbe122710f1aa2af4d881c6d5b54358ca24126"
dependencies:
- find-cache-dir "^0.1.1"
- loader-utils "^0.2.16"
+ find-cache-dir "^1.0.0"
+ loader-utils "^1.0.2"
mkdirp "^0.5.1"
- object-assign "^4.0.1"
babel-messages@^6.23.0:
version "6.23.0"
@@ -1445,6 +1456,10 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
inherits "^2.0.1"
safe-buffer "^5.0.1"
+circular-json-es6@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/circular-json-es6/-/circular-json-es6-2.0.2.tgz#e4f4a093e49fb4b6aba1157365746112a78bd344"
+
circular-json@^0.3.1:
version "0.3.3"
resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
@@ -2017,6 +2032,10 @@ deep-equal-ident@^1.1.1:
dependencies:
lodash.isequal "^3.0"
+deep-equal@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
+
deep-extend@~0.4.0:
version "0.4.2"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
@@ -2363,12 +2382,19 @@ entities@^1.1.1, entities@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
-enzyme-matchers@^3.1.0, enzyme-matchers@^3.8.3:
+enzyme-matchers@^3.1.0:
version "3.8.3"
resolved "https://registry.yarnpkg.com/enzyme-matchers/-/enzyme-matchers-3.8.3.tgz#6269d47b0d81d5222745da503f27ac003ba208d2"
dependencies:
deep-equal-ident "^1.1.1"
+enzyme-matchers@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/enzyme-matchers/-/enzyme-matchers-4.0.2.tgz#3f4457d0d0da3e268af4bee9f222439dfca26214"
+ dependencies:
+ circular-json-es6 "^2.0.1"
+ deep-equal-ident "^1.1.1"
+
enzyme@~2.8.2:
version "2.8.2"
resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-2.8.2.tgz#6c8bcb05012abc4aa4bc3213fb23780b9b5b1714"
@@ -2701,12 +2727,12 @@ extglob@^0.3.1:
dependencies:
is-extglob "^1.0.0"
-extract-text-webpack-plugin@^2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-2.1.2.tgz#756ef4efa8155c3681833fbc34da53b941746d6c"
+extract-text-webpack-plugin@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz#5f043eaa02f9750a9258b78c0a6e0dc1408fb2f7"
dependencies:
- async "^2.1.2"
- loader-utils "^1.0.2"
+ async "^2.4.1"
+ loader-utils "^1.1.0"
schema-utils "^0.3.0"
webpack-sources "^1.0.1"
@@ -2834,13 +2860,13 @@ [email protected]:
statuses "~1.3.1"
unpipe "~1.0.0"
-find-cache-dir@^0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9"
+find-cache-dir@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f"
dependencies:
commondir "^1.0.1"
- mkdirp "^0.5.1"
- pkg-dir "^1.0.0"
+ make-dir "^1.0.0"
+ pkg-dir "^2.0.0"
find-up@^1.0.0:
version "1.1.2"
@@ -2849,7 +2875,7 @@ find-up@^1.0.0:
path-exists "^2.0.0"
pinkie-promise "^2.0.0"
-find-up@^2.0.0:
+find-up@^2.0.0, find-up@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
dependencies:
@@ -2943,6 +2969,12 @@ form-data@~2.3.1:
combined-stream "^1.0.5"
mime-types "^2.1.12"
+fs-access@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/fs-access/-/fs-access-1.0.1.tgz#d6a87f262271cefebec30c553407fb995da8777a"
+ dependencies:
+ null-check "^1.0.0"
+
fs-extra@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950"
@@ -2984,11 +3016,11 @@ function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
function.prototype.name@^1.0.0:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.0.3.tgz#0099ae5572e9dd6f03c97d023fd92bcc5e639eac"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.0.tgz#8bd763cc0af860a859cc5d49384d74b932cd2327"
dependencies:
define-properties "^1.1.2"
- function-bind "^1.1.0"
+ function-bind "^1.1.1"
is-callable "^1.1.3"
gauge@~2.7.3:
@@ -3778,6 +3810,10 @@ is-date-object@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
+is-docker@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-1.1.0.tgz#f04374d4eee5310e9a8e113bf1495411e46176a1"
+
is-dotfile@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1"
@@ -4033,15 +4069,15 @@ isurl@^1.0.0-alpha5:
has-to-string-tag-x "^1.2.0"
is-object "^1.0.1"
-jasmine-core@~2.5.2:
- version "2.5.2"
- resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.5.2.tgz#6f61bd79061e27f43e6f9355e44b3c6cab6ff297"
+jasmine-core@~2.9.0:
+ version "2.9.1"
+ resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.9.1.tgz#b6bbc1d8e65250d56f5888461705ebeeeb88f22f"
-jasmine-enzyme@^3.1.0:
- version "3.8.3"
- resolved "https://registry.yarnpkg.com/jasmine-enzyme/-/jasmine-enzyme-3.8.3.tgz#c9c04f82e7a47d2aead6d2f09c84722fc408ee20"
+jasmine-enzyme@~4.0.0:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/jasmine-enzyme/-/jasmine-enzyme-4.0.2.tgz#d5d3453164d9fe982144eb621147edaba85914be"
dependencies:
- enzyme-matchers "^3.8.3"
+ enzyme-matchers "^4.0.2"
[email protected]:
version "1.6.7"
@@ -4191,6 +4227,13 @@ karma-browserify@~5.1.1:
minimatch "^3.0.0"
os-shim "^0.1.3"
+karma-chrome-launcher@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz#cf1b9d07136cc18fe239327d24654c3dbc368acf"
+ dependencies:
+ fs-access "^1.0.0"
+ which "^1.2.1"
+
karma-jasmine-html-reporter@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-0.2.2.tgz#48a8e5ef18807617ee2b5e33c1194c35b439524c"
@@ -4417,7 +4460,7 @@ loader-runner@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2"
-loader-utils@^0.2.16, loader-utils@^0.2.5, loader-utils@~0.2.2:
+loader-utils@^0.2.5, loader-utils@~0.2.2:
version "0.2.17"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348"
dependencies:
@@ -4891,10 +4934,14 @@ moment-timezone@^0.4.0:
dependencies:
moment ">= 2.6.0"
-"moment@>= 2.6.0", moment@^2.10, moment@^2.18.1:
+"moment@>= 2.6.0", moment@^2.10:
version "2.18.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f"
+moment@^2.20.1:
+ version "2.20.1"
+ resolved "https://registry.yarnpkg.com/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd"
+
mousetrap@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/mousetrap/-/mousetrap-1.6.1.tgz#2a085f5c751294c75e7e81f6ec2545b29cbf42d9"
@@ -5123,6 +5170,10 @@ nth-check@~1.0.1:
dependencies:
boolbase "~1.0.0"
+null-check@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd"
+
num2fraction@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
@@ -5506,11 +5557,11 @@ pinkie@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
-pkg-dir@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4"
+pkg-dir@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
dependencies:
- find-up "^1.0.0"
+ find-up "^2.1.0"
pluralize@^1.2.1:
version "1.2.1"
@@ -7405,7 +7456,7 @@ which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
-which@1, which@^1.2.9:
+which@1, which@^1.2.1, which@^1.2.9:
version "1.3.0"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
dependencies:
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-02-06 14:33 Joao De Almeida Pereira <[email protected]>
parent: Joao De Almeida Pereira <[email protected]>
1 sibling, 1 reply; 19+ messages in thread
From: Joao De Almeida Pereira @ 2018-02-06 14:33 UTC (permalink / raw)
To: pgadmin-hackers
Hello,
Any feedback on this Patch?
Thanks
Joao
On Fri, Feb 2, 2018 at 5:50 PM Joao De Almeida Pereira <
[email protected]> 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
>
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-02-07 22:32 Joao De Almeida Pereira <[email protected]>
parent: Joao De Almeida Pereira <[email protected]>
0 siblings, 1 reply; 19+ messages in thread
From: Joao De Almeida Pereira @ 2018-02-07 22:32 UTC (permalink / raw)
To: pgadmin-hackers
Hello,
Any Feedback on this Patch?
We have other changes that we already developed that depend on this change.
Thanks
On Tue, Feb 6, 2018 at 9:33 AM Joao De Almeida Pereira <
[email protected]> wrote:
> Hello,
> Any feedback on this Patch?
>
> Thanks
> Joao
>
> On Fri, Feb 2, 2018 at 5:50 PM Joao De Almeida Pereira <
> [email protected]> 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
>>
>
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-02-08 07:55 Dave Page <[email protected]>
parent: Joao De Almeida Pereira <[email protected]>
0 siblings, 0 replies; 19+ messages in thread
From: Dave Page @ 2018-02-08 07:55 UTC (permalink / raw)
To: Joao De Almeida Pereira <[email protected]>; +Cc: pgadmin-hackers
It’s in my queue, but I’ve been traveling. I hope to get to it later today or tomorrow.
--
Dave Page
Blog: http://pgsnake.blogspot.com
Twitter: @pgsnake
EnterpriseDB UK:http://www.enterprisedb.com
The Enterprise PostgreSQL Company
> On 7 Feb 2018, at 22:32, Joao De Almeida Pereira <[email protected]> wrote:
>
> Hello,
> Any Feedback on this Patch?
> We have other changes that we already developed that depend on this change.
>
> Thanks
>
>> On Tue, Feb 6, 2018 at 9:33 AM Joao De Almeida Pereira <[email protected]> wrote:
>> Hello,
>> Any feedback on this Patch?
>>
>> Thanks
>> Joao
>>
>>> On Fri, Feb 2, 2018 at 5:50 PM Joao De Almeida Pereira <[email protected]> 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
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-02-09 11:54 Dave Page <[email protected]>
parent: Joao De Almeida Pereira <[email protected]>
1 sibling, 1 reply; 19+ messages in thread
From: Dave Page @ 2018-02-09 11:54 UTC (permalink / raw)
To: Joao De Almeida Pereira <[email protected]>; +Cc: pgadmin-hackers
Thanks, patches applied.
On Fri, Feb 2, 2018 at 10:50 PM, Joao De Almeida Pereira <
[email protected]> 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
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-02-09 12:29 Dave Page <[email protected]>
parent: Dave Page <[email protected]>
0 siblings, 1 reply; 19+ messages in thread
From: Dave Page @ 2018-02-09 12:29 UTC (permalink / raw)
To: Joao De Almeida Pereira <[email protected]>; +Cc: pgadmin-hackers
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 <[email protected]> wrote:
> Thanks, patches applied.
>
> On Fri, Feb 2, 2018 at 10:50 PM, Joao De Almeida Pereira <
> [email protected]> 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
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-02-09 14:35 Joao De Almeida Pereira <[email protected]>
parent: Dave Page <[email protected]>
0 siblings, 1 reply; 19+ messages in thread
From: Joao De Almeida Pereira @ 2018-02-09 14:35 UTC (permalink / raw)
To: Dave Page <[email protected]>; +Cc: pgadmin-hackers
Hello,
Attached you can find the fix for the current pronlem
On Fri, Feb 9, 2018 at 7:29 AM Dave Page <[email protected]> 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 <[email protected]> wrote:
>
>> Thanks, patches applied.
>>
>> On Fri, Feb 2, 2018 at 10:50 PM, Joao De Almeida Pereira <
>> [email protected]> 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
>
Attachments:
[application/octet-stream] correct-tests0in-python-3.6 (951B, 3-correct-tests0in-python-3.6)
download
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-02-09 14:47 Dave Page <[email protected]>
parent: Joao De Almeida Pereira <[email protected]>
0 siblings, 1 reply; 19+ messages in thread
From: Dave Page @ 2018-02-09 14:47 UTC (permalink / raw)
To: Joao De Almeida Pereira <[email protected]>; +Cc: pgadmin-hackers
Thanks, applied.
On Fri, Feb 9, 2018 at 2:35 PM, Joao De Almeida Pereira <
[email protected]> wrote:
> Hello,
> Attached you can find the fix for the current pronlem
>
>
> On Fri, Feb 9, 2018 at 7:29 AM Dave Page <[email protected]> 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 <[email protected]> wrote:
>>
>>> Thanks, patches applied.
>>>
>>> On Fri, Feb 2, 2018 at 10:50 PM, Joao De Almeida Pereira <
>>> [email protected]> 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
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-03-20 07:51 Akshay Joshi <[email protected]>
parent: Dave Page <[email protected]>
0 siblings, 1 reply; 19+ messages in thread
From: Akshay Joshi @ 2018-03-20 07:51 UTC (permalink / raw)
To: Joao Pedro De Almeida Pereira <[email protected]>; +Cc: pgadmin-hackers; Dave Page <[email protected]>
--94eb2c12522415dba50567d35659
Content-Type: text/plain; charset="UTF-8"
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".
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-03-20 09:36 Dave Page <[email protected]>
parent: Akshay Joshi <[email protected]>
0 siblings, 1 reply; 19+ messages in thread
From: Dave Page @ 2018-03-20 09:36 UTC (permalink / raw)
To: Akshay Joshi <[email protected]>; +Cc: Joao Pedro De Almeida Pereira <[email protected]>; pgadmin-hackers
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?
On Tue, Mar 20, 2018 at 7:51 AM, Akshay Joshi <[email protected]
> 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 <[email protected]> wrote:
>
>> Thanks, applied.
>>
>> On Fri, Feb 9, 2018 at 2:35 PM, Joao De Almeida Pereira <
>> [email protected]> wrote:
>>
>>> Hello,
>>> Attached you can find the fix for the current pronlem
>>>
>>>
>>> On Fri, Feb 9, 2018 at 7:29 AM Dave Page <[email protected]> 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 <[email protected]> wrote:
>>>>
>>>>> Thanks, patches applied.
>>>>>
>>>>> On Fri, Feb 2, 2018 at 10:50 PM, Joao De Almeida Pereira <
>>>>> [email protected]> 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
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-03-20 09:48 Akshay Joshi <[email protected]>
parent: Dave Page <[email protected]>
0 siblings, 1 reply; 19+ messages in thread
From: Akshay Joshi @ 2018-03-20 09:48 UTC (permalink / raw)
To: Dave Page <[email protected]>; +Cc: Joao Pedro De Almeida Pereira <[email protected]>; pgadmin-hackers
On Tue, Mar 20, 2018 at 3:06 PM, Dave Page <[email protected]>
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.
>
> On Tue, Mar 20, 2018 at 7:51 AM, Akshay Joshi <
> [email protected]> 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 <[email protected]> wrote:
>>
>>> Thanks, applied.
>>>
>>> On Fri, Feb 9, 2018 at 2:35 PM, Joao De Almeida Pereira <
>>> [email protected]> wrote:
>>>
>>>> Hello,
>>>> Attached you can find the fix for the current pronlem
>>>>
>>>>
>>>> On Fri, Feb 9, 2018 at 7:29 AM Dave Page <[email protected]> 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 <[email protected]> wrote:
>>>>>
>>>>>> Thanks, patches applied.
>>>>>>
>>>>>> On Fri, Feb 2, 2018 at 10:50 PM, Joao De Almeida Pereira <
>>>>>> [email protected]> 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-9517Mobile: +91 976-788-8246*
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-03-20 09:54 Dave Page <[email protected]>
parent: Akshay Joshi <[email protected]>
0 siblings, 1 reply; 19+ messages in thread
From: Dave Page @ 2018-03-20 09:54 UTC (permalink / raw)
To: Akshay Joshi <[email protected]>; +Cc: Joao Pedro De Almeida Pereira <[email protected]>; pgadmin-hackers
On Tue, Mar 20, 2018 at 9:48 AM, Akshay Joshi <[email protected]
> wrote:
>
>
> On Tue, Mar 20, 2018 at 3:06 PM, Dave Page <[email protected]>
> 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 <
>> [email protected]> 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 <[email protected]> wrote:
>>>
>>>> Thanks, applied.
>>>>
>>>> On Fri, Feb 9, 2018 at 2:35 PM, Joao De Almeida Pereira <
>>>> [email protected]> wrote:
>>>>
>>>>> Hello,
>>>>> Attached you can find the fix for the current pronlem
>>>>>
>>>>>
>>>>> On Fri, Feb 9, 2018 at 7:29 AM Dave Page <[email protected]> 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 <[email protected]> wrote:
>>>>>>
>>>>>>> Thanks, patches applied.
>>>>>>>
>>>>>>> On Fri, Feb 2, 2018 at 10:50 PM, Joao De Almeida Pereira <
>>>>>>> [email protected]> 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
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-03-20 13:12 Akshay Joshi <[email protected]>
parent: Dave Page <[email protected]>
0 siblings, 2 replies; 19+ messages in thread
From: Akshay Joshi @ 2018-03-20 13:12 UTC (permalink / raw)
To: Dave Page <[email protected]>; +Cc: Joao Pedro De Almeida Pereira <[email protected]>; pgadmin-hackers
Hi Hackers
Attached is the patch file to fix the RM #2815.
On Tue, Mar 20, 2018 at 3:24 PM, Dave Page <[email protected]>
wrote:
>
>
> On Tue, Mar 20, 2018 at 9:48 AM, Akshay Joshi <
> [email protected]> wrote:
>
>>
>>
>> On Tue, Mar 20, 2018 at 3:06 PM, Dave Page <[email protected]>
>> 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 <
>>> [email protected]> 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 <[email protected]> wrote:
>>>>
>>>>> Thanks, applied.
>>>>>
>>>>> On Fri, Feb 9, 2018 at 2:35 PM, Joao De Almeida Pereira <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Hello,
>>>>>> Attached you can find the fix for the current pronlem
>>>>>>
>>>>>>
>>>>>> On Fri, Feb 9, 2018 at 7:29 AM Dave Page <[email protected]> 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 <[email protected]>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> Thanks, patches applied.
>>>>>>>>
>>>>>>>> On Fri, Feb 2, 2018 at 10:50 PM, Joao De Almeida Pereira <
>>>>>>>> [email protected]> 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-9517Mobile: +91 976-788-8246*
Attachments:
[application/octet-stream] RM_2815.patch (21.7K, 3-RM_2815.patch)
download | inline diff:
diff --git a/web/pgadmin/dashboard/static/js/dashboard.js b/web/pgadmin/dashboard/static/js/dashboard.js
index dd6ecf9..4d817ad 100644
--- a/web/pgadmin/dashboard/static/js/dashboard.js
+++ b/web/pgadmin/dashboard/static/js/dashboard.js
@@ -444,18 +444,28 @@ 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,
+ var err = '',
+ msg = '',
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.');
- }
+
+ if (xhr.readyState == 0) {
+ msg = gettext('Not connected to the server or the connection to the server has been closed.');
cls = 'info';
- } else {
- msg = gettext('An error occurred whilst rendering the graph.');
- cls = 'danger';
+ } else
+ {
+ err = $.parseJSON(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.');
+ }
+ cls = 'info';
+ } else {
+ msg = gettext('An error occurred whilst rendering the graph.');
+ cls = 'danger';
+ }
}
$(container).addClass('graph-error');
@@ -576,18 +586,27 @@ define('pgadmin.dashboard', [
filter.search();
},
error: function(model, xhr) {
- var err = $.parseJSON(xhr.responseText),
- msg = err.errormsg,
+ var err = '',
+ msg = '',
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.');
- }
+
+ if (xhr.readyState == 0) {
+ msg = gettext('Not connected to the server or the connection to the server has been closed.');
cls = 'info';
} else {
- msg = gettext('An error occurred whilst rendering the table.');
- cls = 'danger';
+ err = $.parseJSON(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.');
+ }
+ cls = 'info';
+ } 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 e91c9e8..0feb1e6 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;
@@ -64,10 +64,20 @@ class ExecuteQuery {
self.initializeExecutionOnSqlEditor(sqlStatementWithAnalyze);
+ let url = url_for('sqleditor.query_tool_start', {
+ 'trans_id': self.sqlServerObject.transId,
+ });
+
+ /* If connect parameter is true, then send this parameter
+ * as a part of requested url to connect to the server if not
+ * already connected.
+ */
+ if (connect) {
+ url += '?connect=1';
+ }
+
service.post(
- url_for('sqleditor.query_tool_start', {
- 'trans_id': self.sqlServerObject.transId,
- }),
+ url,
JSON.stringify(sqlStatementWithAnalyze),
{headers: {'Content-Type': 'application/json'}})
.then(function (result) {
@@ -90,7 +100,12 @@ class ExecuteQuery {
self.sqlServerObject._highlight_error(httpMessageData.data.result);
}
}).catch(function (error) {
- self.onExecuteHTTPError(error.response.data);
+ // If response is undefined then connection to the server has been lost.
+ if (error.response != undefined && error.response.data != undefined) {
+ self.onExecuteHTTPError(error);
+ } else {
+ self.handleConnectionToServerLost();
+ }
}
);
}
@@ -129,6 +144,12 @@ class ExecuteQuery {
}
).catch(
error => {
+ // If response is undefined then connection to the server has been lost.
+ if (error.response == undefined || error.response.data == undefined) {
+ self.handleConnectionToServerLost();
+ return;
+ }
+
const errorData = error.response.data;
// Enable/Disable query tool button only if is_query_tool is true.
self.sqlServerObject.resetQueryHistoryObject(self.sqlServerObject);
@@ -137,7 +158,7 @@ class ExecuteQuery {
self.enableSQLEditorButtons();
}
- if (ExecuteQuery.wasConnectionLostToServer(errorData)) {
+ if (ExecuteQuery.wasConnectionLostToServer(error.request)) {
self.handleConnectionToServerLost();
return;
}
@@ -179,40 +200,40 @@ class ExecuteQuery {
}
onExecuteHTTPError(httpMessage) {
- this.loadingScreen.hide();
- this.enableSQLEditorButtons();
+ const self = this;
- if (ExecuteQuery.wasConnectionLostToServer(httpMessage)) {
- this.handleConnectionToServerLost();
+ self.loadingScreen.hide();
+ self.enableSQLEditorButtons();
+
+ if (ExecuteQuery.wasConnectionLostToServer(httpMessage.request) ||
+ httpMessage.response == undefined ||
+ httpMessage.response.data == undefined)
+ {
+ self.handleConnectionToServerLost();
return;
}
- if (this.userManagement.is_pga_login_required(httpMessage)) {
- this.sqlServerObject.save_state('execute', [this.explainPlan]);
- this.userManagement.pga_login();
+ if (self.userManagement.is_pga_login_required(httpMessage.response)) {
+ self.sqlServerObject.save_state('execute', [self.explainPlan]);
+ self.userManagement.pga_login();
}
- if (transaction.is_new_transaction_required(httpMessage)) {
- this.sqlServerObject.save_state('execute', [this.explainPlan]);
- this.sqlServerObject.init_transaction();
+ if (transaction.is_new_transaction_required(httpMessage.response)) {
+ self.sqlServerObject.save_state('execute', [self.explainPlan]);
+ self.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);
- });
- }
+ let msg = httpMessage.response.data.errormsg;
+ if (httpMessage.response.status === 503 &&
+ httpMessage.response.data.info !== undefined &&
+ httpMessage.response.data.info === 'CONNECTION_LOST') {
+ setTimeout(function () {
+ self.sqlServerObject.save_state('execute', [self.explainPlan]);
+ self.sqlServerObject.handle_connection_lost(false, httpMessage);
+ });
}
- this.sqlServerObject.update_msg_history(false, msg);
+ self.sqlServerObject.update_msg_history(false, msg);
}
removeGridViewMarker() {
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 9d83c92..8197ba1 100644
--- a/web/pgadmin/static/js/sqleditor/is_new_transaction_required.js
+++ b/web/pgadmin/static/js/sqleditor/is_new_transaction_required.js
@@ -8,6 +8,15 @@
//////////////////////////////////////////////////////////////////////////
export function is_new_transaction_required(xhr) {
+ /* If responseJSON is undefined then it could be object of
+ * axois(Promise HTTP) response, so we should check accordingly.
+ */
+ if (xhr.responseJSON == undefined && xhr.data != undefined) {
+ return xhr.status === 404 && xhr.data &&
+ xhr.data.info &&
+ xhr.data.info === 'DATAGRID_TRANSACTION_REQUIRED';
+ }
+
return xhr.status === 404 && xhr.responseJSON &&
xhr.responseJSON.info &&
xhr.responseJSON.info === 'DATAGRID_TRANSACTION_REQUIRED';
diff --git a/web/pgadmin/tools/sqleditor/__init__.py b/web/pgadmin/tools/sqleditor/__init__.py
index cc0aa4c..ea9a973 100644
--- a/web/pgadmin/tools/sqleditor/__init__.py
+++ b/web/pgadmin/tools/sqleditor/__init__.py
@@ -298,8 +298,11 @@ def start_query_tool(trans_id):
request.data, request.args, request.form
)
+ connect = True if 'connect' in request.args and \
+ request.args['connect'] == '1' else False
+
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 ff5138d..0e07a14 100644
--- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
+++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
@@ -1848,7 +1848,17 @@ 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
+ * axois(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.
+ self.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);
@@ -3747,7 +3757,13 @@ define('tools.querytool', [
sql = self.gridView.query_tool_obj.getValue();
const executeQuery = new ExecuteQuery.ExecuteQuery(this, pgAdmin.Browser.UserManagement);
- executeQuery.execute(sql, explain_prefix);
+
+ if (arguments.length > 0 &&
+ arguments[arguments.length - 1] == 'connect') {
+ executeQuery.execute(sql, explain_prefix, true);
+ } else {
+ executeQuery.execute(sql, explain_prefix);
+ }
},
/* 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 2a50259..c2ff21c 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 11b946b..3b3c502 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 23a5c7f..4ad0891 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 2a3b2f0..3352c15 100644
--- a/web/pgadmin/tools/user_management/static/js/user_management.js
+++ b/web/pgadmin/tools/user_management/static/js/user_management.js
@@ -130,6 +130,15 @@ define([
},
is_pga_login_required(xhr) {
+ /* If responseJSON is undefined then it could be object of
+ * axois(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';
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-03-20 13:27 Robert Eckhardt <[email protected]>
parent: Akshay Joshi <[email protected]>
1 sibling, 0 replies; 19+ messages in thread
From: Robert Eckhardt @ 2018-03-20 13:27 UTC (permalink / raw)
To: Akshay Joshi <[email protected]>; +Cc: Dave Page <[email protected]>; Joao Pedro De Almeida Pereira <[email protected]>; pgadmin-hackers
Thanks for doing this, sorry about the breakage.
We're taking a look at this to make sure it is still working with
Greenplum.
-- Rob
On Tue, Mar 20, 2018 at 9:12 AM, Akshay Joshi <[email protected]
> wrote:
> Hi Hackers
>
> Attached is the patch file to fix the RM #2815.
>
> On Tue, Mar 20, 2018 at 3:24 PM, Dave Page <[email protected]>
> wrote:
>
>>
>>
>> On Tue, Mar 20, 2018 at 9:48 AM, Akshay Joshi <
>> [email protected]> wrote:
>>
>>>
>>>
>>> On Tue, Mar 20, 2018 at 3:06 PM, Dave Page <[email protected]>
>>> 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 <
>>>> [email protected]> 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 <[email protected]> wrote:
>>>>>
>>>>>> Thanks, applied.
>>>>>>
>>>>>> On Fri, Feb 9, 2018 at 2:35 PM, Joao De Almeida Pereira <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> Hello,
>>>>>>> Attached you can find the fix for the current pronlem
>>>>>>>
>>>>>>>
>>>>>>> On Fri, Feb 9, 2018 at 7:29 AM Dave Page <[email protected]> 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 <[email protected]>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> Thanks, patches applied.
>>>>>>>>>
>>>>>>>>> On Fri, Feb 2, 2018 at 10:50 PM, Joao De Almeida Pereira <
>>>>>>>>> [email protected]> 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>*
>
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-03-20 14:05 Dave Page <[email protected]>
parent: Akshay Joshi <[email protected]>
1 sibling, 1 reply; 19+ messages in thread
From: Dave Page @ 2018-03-20 14:05 UTC (permalink / raw)
To: Akshay Joshi <[email protected]>; +Cc: Joao Pedro De Almeida Pereira <[email protected]>; pgadmin-hackers
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 <[email protected]
> wrote:
> Hi Hackers
>
> Attached is the patch file to fix the RM #2815.
>
> On Tue, Mar 20, 2018 at 3:24 PM, Dave Page <[email protected]>
> wrote:
>
>>
>>
>> On Tue, Mar 20, 2018 at 9:48 AM, Akshay Joshi <
>> [email protected]> wrote:
>>
>>>
>>>
>>> On Tue, Mar 20, 2018 at 3:06 PM, Dave Page <[email protected]>
>>> 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 <
>>>> [email protected]> 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 <[email protected]> wrote:
>>>>>
>>>>>> Thanks, applied.
>>>>>>
>>>>>> On Fri, Feb 9, 2018 at 2:35 PM, Joao De Almeida Pereira <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> Hello,
>>>>>>> Attached you can find the fix for the current pronlem
>>>>>>>
>>>>>>>
>>>>>>> On Fri, Feb 9, 2018 at 7:29 AM Dave Page <[email protected]> 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 <[email protected]>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> Thanks, patches applied.
>>>>>>>>>
>>>>>>>>> On Fri, Feb 2, 2018 at 10:50 PM, Joao De Almeida Pereira <
>>>>>>>>> [email protected]> 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
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-03-20 20:39 Victoria Henry <[email protected]>
parent: Dave Page <[email protected]>
0 siblings, 1 reply; 19+ messages in thread
From: Victoria Henry @ 2018-03-20 20:39 UTC (permalink / raw)
To: Dave Page <[email protected]>; +Cc: Akshay Joshi <[email protected]>; Joao Pedro De Almeida Pereira <[email protected]>; pgadmin-hackers
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 <[email protected]>
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 <
> [email protected]> wrote:
>
>> Hi Hackers
>>
>> Attached is the patch file to fix the RM #2815.
>>
>> On Tue, Mar 20, 2018 at 3:24 PM, Dave Page <[email protected]>
>> wrote:
>>
>>>
>>>
>>> On Tue, Mar 20, 2018 at 9:48 AM, Akshay Joshi <
>>> [email protected]> wrote:
>>>
>>>>
>>>>
>>>> On Tue, Mar 20, 2018 at 3:06 PM, Dave Page <[email protected]>
>>>> 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 <
>>>>> [email protected]> 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 <[email protected]> wrote:
>>>>>>
>>>>>>> Thanks, applied.
>>>>>>>
>>>>>>> On Fri, Feb 9, 2018 at 2:35 PM, Joao De Almeida Pereira <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> Hello,
>>>>>>>> Attached you can find the fix for the current pronlem
>>>>>>>>
>>>>>>>>
>>>>>>>> On Fri, Feb 9, 2018 at 7:29 AM Dave Page <[email protected]> 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 <[email protected]>
>>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>> Thanks, patches applied.
>>>>>>>>>>
>>>>>>>>>> On Fri, Feb 2, 2018 at 10:50 PM, Joao De Almeida Pereira <
>>>>>>>>>> [email protected]> 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
>
Attachments:
[text/x-patch] rm_2815_v1.patch (28.2K, 3-rm_2815_v1.patch)
download | inline diff:
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);
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-03-21 07:27 Akshay Joshi <[email protected]>
parent: Victoria Henry <[email protected]>
0 siblings, 1 reply; 19+ messages in thread
From: Akshay Joshi @ 2018-03-21 07:27 UTC (permalink / raw)
To: Victoria Henry <[email protected]>; +Cc: Dave Page <[email protected]>; Joao Pedro De Almeida Pereira <[email protected]>; pgadmin-hackers
Hi Victoria,
In "is_new_transaction_required.js" file I have modified the code and
handled both "responseJSON" and "axios" responses, but in your patch you
have removed "responseJSON" part which is required because "i
*s_new_transaction_required*()" function is also called from sqleditor.js
with normal javascript response.
I have re-added that code and also found one issue where "from
pgadmin.utils.exception
import ConnectionLost" statement is missing from "web/pgadmin/utils
/driver/psycopg2/server_manager.py" file, so I added that too.
Attached is the modified patch.
On Wed, Mar 21, 2018 at 2:09 AM, Victoria Henry <[email protected]> wrote:
> 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 <[email protected]>
> 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 <
>> [email protected]> wrote:
>>
>>> Hi Hackers
>>>
>>> Attached is the patch file to fix the RM #2815.
>>>
>>> On Tue, Mar 20, 2018 at 3:24 PM, Dave Page <[email protected]>
>>> wrote:
>>>
>>>>
>>>>
>>>> On Tue, Mar 20, 2018 at 9:48 AM, Akshay Joshi <
>>>> [email protected]> wrote:
>>>>
>>>>>
>>>>>
>>>>> On Tue, Mar 20, 2018 at 3:06 PM, Dave Page <[email protected]
>>>>> > 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 <
>>>>>> [email protected]> 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 <[email protected]> wrote:
>>>>>>>
>>>>>>>> Thanks, applied.
>>>>>>>>
>>>>>>>> On Fri, Feb 9, 2018 at 2:35 PM, Joao De Almeida Pereira <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> Hello,
>>>>>>>>> Attached you can find the fix for the current pronlem
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Fri, Feb 9, 2018 at 7:29 AM Dave Page <[email protected]>
>>>>>>>>> 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 <[email protected]>
>>>>>>>>>> wrote:
>>>>>>>>>>
>>>>>>>>>>> Thanks, patches applied.
>>>>>>>>>>>
>>>>>>>>>>> On Fri, Feb 2, 2018 at 10:50 PM, Joao De Almeida Pereira <
>>>>>>>>>>> [email protected]> 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
>>
>
>
--
*Akshay Joshi*
*Sr. Software Architect *
*Phone: +91 20-3058-9517Mobile: +91 976-788-8246*
Attachments:
[application/octet-stream] RM_2815_v2.patch (28.9K, 3-RM_2815_v2.patch)
download | inline diff:
diff --git a/web/pgadmin/dashboard/static/js/dashboard.js b/web/pgadmin/dashboard/static/js/dashboard.js
index dd6ecf9..e4f0dd5 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 e91c9e8..9c36f28 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 9d83c92..e009611 100644
--- a/web/pgadmin/static/js/sqleditor/is_new_transaction_required.js
+++ b/web/pgadmin/static/js/sqleditor/is_new_transaction_required.js
@@ -8,6 +8,15 @@
//////////////////////////////////////////////////////////////////////////
export function is_new_transaction_required(xhr) {
+ /* 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 === 404 && xhr.data &&
+ xhr.data.info &&
+ xhr.data.info === 'DATAGRID_TRANSACTION_REQUIRED';
+ }
+
return xhr.status === 404 && xhr.responseJSON &&
xhr.responseJSON.info &&
xhr.responseJSON.info === 'DATAGRID_TRANSACTION_REQUIRED';
diff --git a/web/pgadmin/tools/sqleditor/__init__.py b/web/pgadmin/tools/sqleditor/__init__.py
index cc0aa4c..6f5d5b7 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 ff5138d..923ccea 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 2a50259..c2ff21c 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 11b946b..3b3c502 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 23a5c7f..4ad0891 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 2a3b2f0..2627328 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/pgadmin/utils/driver/psycopg2/server_manager.py b/web/pgadmin/utils/driver/psycopg2/server_manager.py
index 2299e28..f288a94 100644
--- a/web/pgadmin/utils/driver/psycopg2/server_manager.py
+++ b/web/pgadmin/utils/driver/psycopg2/server_manager.py
@@ -19,6 +19,7 @@ from flask_babel import gettext
from pgadmin.utils.crypto import decrypt
from .connection import Connection
from pgadmin.model import Server
+from pgadmin.utils.exception import ConnectionLost
class ServerManager(object):
diff --git a/web/regression/javascript/sqleditor/execute_query_spec.js b/web/regression/javascript/sqleditor/execute_query_spec.js
index 98faed7..5f92dc5 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 d323700..97d1bc5 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);
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-03-21 08:39 Dave Page <[email protected]>
parent: Akshay Joshi <[email protected]>
0 siblings, 1 reply; 19+ messages in thread
From: Dave Page @ 2018-03-21 08:39 UTC (permalink / raw)
To: Akshay Joshi <[email protected]>; +Cc: Victoria Henry <[email protected]>; Joao Pedro De Almeida Pereira <[email protected]>; pgadmin-hackers
Thanks, applied. All tests pass on my machine, now waiting for Jenkins to
run. Assuming all is good, I'll build the release packages.
On Wed, Mar 21, 2018 at 7:27 AM, Akshay Joshi <[email protected]
> wrote:
> Hi Victoria,
>
> In "is_new_transaction_required.js" file I have modified the code and
> handled both "responseJSON" and "axios" responses, but in your patch you
> have removed "responseJSON" part which is required because "i
> *s_new_transaction_required*()" function is also called from sqleditor.js
> with normal javascript response.
>
> I have re-added that code and also found one issue where "from pgadmin.
> utils.exception import ConnectionLost" statement is missing from "web/
> pgadmin/utils/driver/psycopg2/server_manager.py" file, so I added that
> too.
>
> Attached is the modified patch.
>
> On Wed, Mar 21, 2018 at 2:09 AM, Victoria Henry <[email protected]> wrote:
>
>> 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 <[email protected]>
>> 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 <
>>> [email protected]> wrote:
>>>
>>>> Hi Hackers
>>>>
>>>> Attached is the patch file to fix the RM #2815.
>>>>
>>>> On Tue, Mar 20, 2018 at 3:24 PM, Dave Page <[email protected]>
>>>> wrote:
>>>>
>>>>>
>>>>>
>>>>> On Tue, Mar 20, 2018 at 9:48 AM, Akshay Joshi <
>>>>> [email protected]> wrote:
>>>>>
>>>>>>
>>>>>>
>>>>>> On Tue, Mar 20, 2018 at 3:06 PM, Dave Page <dave.page@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 <
>>>>>>> [email protected]> 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 <[email protected]>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> Thanks, applied.
>>>>>>>>>
>>>>>>>>> On Fri, Feb 9, 2018 at 2:35 PM, Joao De Almeida Pereira <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>> Hello,
>>>>>>>>>> Attached you can find the fix for the current pronlem
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Fri, Feb 9, 2018 at 7:29 AM Dave Page <[email protected]>
>>>>>>>>>> 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 <[email protected]>
>>>>>>>>>>> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Thanks, patches applied.
>>>>>>>>>>>>
>>>>>>>>>>>> On Fri, Feb 2, 2018 at 10:50 PM, Joao De Almeida Pereira <
>>>>>>>>>>>> [email protected]> 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
>>>
>>
>>
>
>
> --
> *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
^ permalink raw reply [nested|flat] 19+ messages in thread
* Re: [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed
@ 2018-03-21 14:00 Joao De Almeida Pereira <[email protected]>
parent: Dave Page <[email protected]>
0 siblings, 0 replies; 19+ messages in thread
From: Joao De Almeida Pereira @ 2018-03-21 14:00 UTC (permalink / raw)
To: Dave Page <[email protected]>; +Cc: Akshay Joshi <[email protected]>; Victoria Henry <[email protected]>; pgadmin-hackers
Hello Akshay,
Thanks for double checking the patch, clearly the things that we missing
are asking for some tests to ensure that mistakes like this do not happen
again. Specially in scenarios where the we have strange behaviors, like
loosing connection to the python server and so on.
Thanks
Joao
On Wed, Mar 21, 2018 at 4:39 AM Dave Page <[email protected]>
wrote:
> Thanks, applied. All tests pass on my machine, now waiting for Jenkins to
> run. Assuming all is good, I'll build the release packages.
>
>
>
> On Wed, Mar 21, 2018 at 7:27 AM, Akshay Joshi <
> [email protected]> wrote:
>
>> Hi Victoria,
>>
>> In "is_new_transaction_required.js" file I have modified the code and
>> handled both "responseJSON" and "axios" responses, but in your patch you
>> have removed "responseJSON" part which is required because "i
>> *s_new_transaction_required*()" function is also called from sqleditor.js
>> with normal javascript response.
>>
>> I have re-added that code and also found one issue where "from pgadmin.
>> utils.exception import ConnectionLost" statement is missing from "web/
>> pgadmin/utils/driver/psycopg2/server_manager.py" file, so I added that
>> too.
>>
>> Attached is the modified patch.
>>
>> On Wed, Mar 21, 2018 at 2:09 AM, Victoria Henry <[email protected]>
>> wrote:
>>
>>> 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 <[email protected]>
>>> 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 <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi Hackers
>>>>>
>>>>> Attached is the patch file to fix the RM #2815.
>>>>>
>>>>> On Tue, Mar 20, 2018 at 3:24 PM, Dave Page <[email protected]
>>>>> > wrote:
>>>>>
>>>>>>
>>>>>>
>>>>>> On Tue, Mar 20, 2018 at 9:48 AM, Akshay Joshi <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Tue, Mar 20, 2018 at 3:06 PM, Dave Page <dave.page@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 <
>>>>>>>> [email protected]> 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 <[email protected]>
>>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>> Thanks, applied.
>>>>>>>>>>
>>>>>>>>>> On Fri, Feb 9, 2018 at 2:35 PM, Joao De Almeida Pereira <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>> Hello,
>>>>>>>>>>> Attached you can find the fix for the current pronlem
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Fri, Feb 9, 2018 at 7:29 AM Dave Page <[email protected]>
>>>>>>>>>>> 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 <[email protected]>
>>>>>>>>>>>> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> Thanks, patches applied.
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Fri, Feb 2, 2018 at 10:50 PM, Joao De Almeida Pereira <
>>>>>>>>>>>>> [email protected]> 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
>>>>
>>>
>>>
>>
>>
>> --
>> *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
>
^ permalink raw reply [nested|flat] 19+ messages in thread
end of thread, other threads:[~2018-03-21 14:00 UTC | newest]
Thread overview: 19+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2018-02-02 22:50 [pgadmin][patch] [GreenPlum] When user press Explain Plan and Explain analyze plan an error is displayed Joao De Almeida Pereira <[email protected]>
2018-02-06 14:33 ` Joao De Almeida Pereira <[email protected]>
2018-02-07 22:32 ` Joao De Almeida Pereira <[email protected]>
2018-02-08 07:55 ` Dave Page <[email protected]>
2018-02-09 11:54 ` Dave Page <[email protected]>
2018-02-09 12:29 ` Dave Page <[email protected]>
2018-02-09 14:35 ` Joao De Almeida Pereira <[email protected]>
2018-02-09 14:47 ` Dave Page <[email protected]>
2018-03-20 07:51 ` Akshay Joshi <[email protected]>
2018-03-20 09:36 ` Dave Page <[email protected]>
2018-03-20 09:48 ` Akshay Joshi <[email protected]>
2018-03-20 09:54 ` Dave Page <[email protected]>
2018-03-20 13:12 ` Akshay Joshi <[email protected]>
2018-03-20 13:27 ` Robert Eckhardt <[email protected]>
2018-03-20 14:05 ` Dave Page <[email protected]>
2018-03-20 20:39 ` Victoria Henry <[email protected]>
2018-03-21 07:27 ` Akshay Joshi <[email protected]>
2018-03-21 08:39 ` Dave Page <[email protected]>
2018-03-21 14:00 ` Joao De Almeida Pereira <[email protected]>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox