1) Fix an error while retrieving json data from the table. Fixes #4427

2) Fix an issue where Explain and Explain Analyze are not working, it's regression of #1760. Fixes #4484
3) Fix an issue where Filter toolbar button is not working in view/edit data, it's regression of keyboard navigation. Fixes #4485
This commit is contained in:
Khushboo Vashi 2019-07-22 18:42:48 +05:30 committed by Akshay Joshi
parent 6e49c9c36f
commit c019778a47
7 changed files with 144 additions and 20 deletions

View File

@ -40,6 +40,7 @@ Bug fixes
| `Issue #4389 <https://redmine.postgresql.org/issues/4389>`_ - Fix an error that could be seen when editing column privileges.
| `Issue #4393 <https://redmine.postgresql.org/issues/4393>`_ - Ensure parameter values are quoted when needed when editing roles.
| `Issue #4395 <https://redmine.postgresql.org/issues/4395>`_ - EXPLAIN options should be Query Tool instance-specific.
| `Issue #4427 <https://redmine.postgresql.org/issues/4427>`_ - Fix an error while retrieving json data from the table.
| `Issue #4428 <https://redmine.postgresql.org/issues/4428>`_ - Fix 'malformed array literal' error when updating a pgAgent job.
| `Issue #4429 <https://redmine.postgresql.org/issues/4429>`_ - Ensure drag/drop from the treeview works as expected on Firefox.
| `Issue #4437 <https://redmine.postgresql.org/issues/4437>`_ - Fix table icon issue when updating any existing field.
@ -48,4 +49,6 @@ Bug fixes
| `Issue #4448 <https://redmine.postgresql.org/issues/4448>`_ - Fix an error seen when updating a connection string in a pgAgent job step.
| `Issue #4450 <https://redmine.postgresql.org/issues/4450>`_ - Fix reverse engineered sql for Foreign Data Wrapper created on EPAS server in redwood mode.
| `Issue #4462 <https://redmine.postgresql.org/issues/4462>`_ - Fix some minor UI issues on IE11.
| `Issue #4470 <https://redmine.postgresql.org/issues/4470>`_ - Fix sequence reverse engineered SQL generation with quoted names on PG/EPAS 10+.
| `Issue #4470 <https://redmine.postgresql.org/issues/4470>`_ - Fix sequence reverse engineered SQL generation with quoted names on PG/EPAS 10+.
| `Issue #4484 <https://redmine.postgresql.org/issues/4484>`_ - Fix an issue where Explain and Explain Analyze are not working, it's regression of #1760.
| `Issue #4485 <https://redmine.postgresql.org/issues/4485>`_ - Fix an issue where Filter toolbar button is not working in view/edit data, it's regression of keyboard navigation.

View File

@ -1271,12 +1271,19 @@ define([
var $dialog = gridBody.append(subNodeGrid);
let preferences = pgBrowser.get_preferences_for_module('browser');
let addBtn = $dialog.find('.add');
// Add title to the buttons
$(addBtn)
.attr('title',
keyboardShortcuts.shortcut_title(gettext('Add new row'),preferences.add_grid_row));
let tmp_browser = pgBrowser;
if (pgBrowser.preferences_cache.length == 0)
tmp_browser = window.opener ? window.opener.pgAdmin.Browser : window.top.pgAdmin.Browser;
let preferences = tmp_browser.get_preferences_for_module('browser');
if (preferences) {
let addBtn = $dialog.find('.add');
// Add title to the buttons
$(addBtn)
.attr('title',
keyboardShortcuts.shortcut_title(gettext('Add new row'),preferences.add_grid_row));
}
// Add button callback
if (!(data.disabled || data.canAdd == false)) {
@ -1563,12 +1570,19 @@ define([
var $dialog = gridBody.append(subNodeGrid);
let preferences = pgBrowser.get_preferences_for_module('browser');
let addBtn = $dialog.find('.add');
// Add title to the buttons
$(addBtn)
.attr('title',
keyboardShortcuts.shortcut_title(gettext('Add new row'),preferences.add_grid_row));
let tmp_browser = pgBrowser;
if (pgBrowser.preferences_cache.length == 0)
tmp_browser = window.opener ? window.opener.pgAdmin.Browser : window.top.pgAdmin.Browser;
let preferences = tmp_browser.get_preferences_for_module('browser');
if (preferences) {
let addBtn = $dialog.find('.add');
// Add title to the buttons
$(addBtn)
.attr('title',
keyboardShortcuts.shortcut_title(gettext('Add new row'),preferences.add_grid_row));
}
// Add button callback

View File

@ -36,7 +36,10 @@ export function callRenderAfterPoll(sqlEditor, alertify, res) {
sqlEditor.query_end_time);
const msg = sprintf(
gettext('Query returned successfully in %s.'), sqlEditor.total_time);
res.result += '\n\n' + msg;
if (res.result)
res.result += '\n\n' + msg;
else
res.result = msg;
sqlEditor.update_msg_history(true, res.result, true);
sqlEditor.reset_data_store();
if (isNotificationEnabled(sqlEditor)) {

View File

@ -407,6 +407,8 @@ def poll(trans_id):
if (result != 'SELECT 1' or result != 'SELECT 0') and \
result is not None and additional_messages:
result = additional_messages + result
else:
result = None
if st:
if 'primary_keys' in session_obj:

View File

@ -705,7 +705,7 @@ define('tools.querytool', [
*/
// This function is responsible to create and render the SlickGrid.
render_grid: function(collection, columns, is_editable, client_primary_key, rows_affected) {
render_grid: function(collection, columns, is_editable, client_primary_key, rows_affected, is_explain_plan) {
var self = this;
self.handler.numberOfModifiedCells = 0;
@ -824,7 +824,7 @@ define('tools.querytool', [
}
var grid_options = {
editable: is_editable,
editable: is_editable || is_explain_plan,
enableAddRow: is_editable,
enableCellNavigation: true,
enableColumnReorder: false,
@ -2379,7 +2379,7 @@ define('tools.querytool', [
*/
_render: function(data) {
var self = this;
self.colinfo = data.col_info;
self.colinfo = data.colinfo;
self.primary_keys = (_.isEmpty(data.primary_keys) && data.has_oids) ? data.oids : data.primary_keys;
self.client_primary_key = data.client_primary_key;
self.cell_selected = false;
@ -2388,6 +2388,7 @@ define('tools.querytool', [
self.has_oids = data.has_oids;
self.oids = data.oids;
$('.sql-editor-explain').empty();
self.explain_plan = false;
/* If object don't have primary keys then set the
* can_edit flag to false.
@ -2463,9 +2464,12 @@ define('tools.querytool', [
var explain_data_array = [],
explain_data_json = null;
if(data.types[0] && data.types[0].typname === 'json') {
if(self.colinfo[0].name == 'QUERY PLAN' && data.result
&& data.types[0] && data.types[0].typname === 'json') {
/* json is sent as text, parse it */
explain_data_json = JSON.parse(data.result[0][0]);
self.is_explain_plan = true;
}
if (explain_data_json && explain_data_json[0] &&
@ -2481,7 +2485,7 @@ define('tools.querytool', [
function() {
self.gridView.render_grid(
explain_data_array, self.columns, self.can_edit,
self.client_primary_key
self.client_primary_key, 0, self.is_explain_plan
);
// Make sure - the 'Explain' panel is visible, before - we
// start rendering the grid.

View File

@ -251,7 +251,7 @@ class TestSaveChangedData(BaseTestGenerator):
},
save_status=True,
check_sql='SELECT * FROM %s WHERE pk_col = 2',
check_result='SELECT 0'
check_result=None
)),
]

View File

@ -0,0 +1,98 @@
##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2019, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
##########################################################################
import uuid
import json
import random
from pgadmin.utils.route import BaseTestGenerator
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
database_utils
from regression import parent_node_dict
from regression.python_test_utils import test_utils
from pgadmin.utils import server_utils, IS_PY2
class TestViewData(BaseTestGenerator):
"""
This class checks the view data result for a table with JSON datatype
"""
skip_on_database = ['gpdb']
scenarios = [
(
'Table with JSON datatype',
dict(
table_sql="""Create Table <TABLE_NAME>(
id integer Not Null,
json_val json Not Null,
Constraint table_pk Primary Key(id)
);""",
result_data=None,
rows_fetched_to=0
)
)
]
def setUp(self):
self.server_id = self.server_information['server_id']
self.database_info = parent_node_dict["database"][-1]
self.db_name = self.database_info["db_name"]
self.db_id = self.database_info["db_id"]
self.connection = test_utils.get_db_connection(
self.db_name,
self.server['username'],
self.server['db_password'],
self.server['host'],
self.server['port']
)
def runTest(self):
self.table = "test_table_%s" % (str(uuid.uuid4())[1:8])
self.table_sql = self.table_sql.replace('<TABLE_NAME>', self.table)
# Create table
test_utils.create_table_with_query(self.server,
self.db_name,
self.table_sql)
# Fetch Table OID
pg_cursor = self.connection.cursor()
pg_cursor.execute("""Select oid FROM pg_class WHERE
relname = '%s' AND relkind IN ('r','s','t')""" % self.table)
result = pg_cursor.fetchall()
table_id = result[0][0]
# Initialize query tool
url = '/datagrid/initialize/datagrid/3/table/{0}/{1}/{2}/{3}'.format(
test_utils.SERVER_GROUP, self.server_id, self.db_id, table_id)
response = self.tester.post(url)
self.assertEquals(response.status_code, 200)
response_data = json.loads(response.data.decode('utf-8'))
self.trans_id = response_data['data']['gridTransId']
url = "/sqleditor/view_data/start/{0}".format(self.trans_id)
response = self.tester.get(url)
self.assertEquals(response.status_code, 200)
# Check the query result
url = '/sqleditor/poll/{0}'.format(self.trans_id)
response = self.tester.get(url)
self.assertEquals(response.status_code, 200)
response_data = json.loads(response.data.decode('utf-8'))
self.assertEquals(response_data['data']['result'], self.result_data)
self.assertEquals(response_data['data']['rows_fetched_to'],
self.rows_fetched_to)
def tearDown(self):
database_utils.disconnect_database(self, self.server_id,
self.db_id)