From febbd729ec766ff75348924e70a492a697d644fe Mon Sep 17 00:00:00 2001 From: Aditya Toshniwal Date: Wed, 1 Jan 2020 12:59:48 +0530 Subject: [PATCH] Ensure that constraints, indexes, rules, triggers, and compound triggers should be created on partitions. Fixes #4842. --- docs/en_US/release_notes_4_17.rst | 1 + .../tables/compound_triggers/__init__.py | 2 +- .../static/js/compound_trigger.js | 1 + .../static/js/check_constraint.js | 1 + .../static/js/exclusion_constraint.js | 1 + .../foreign_key/static/js/foreign_key.js | 6 ++++-- .../index_constraint/static/js/primary_key.js | 1 + .../static/js/unique_constraint.js | 1 + .../constraints/static/js/constraints.js | 1 + .../schemas/tables/indexes/static/js/index.js | 4 ++++ .../schemas/tables/rules/static/js/rule.js | 1 + .../tables/triggers/static/js/trigger.js | 3 ++- web/pgadmin/browser/static/js/node.js | 18 ++++++++++++++---- web/pgadmin/browser/static/js/node.ui.js | 8 +++++--- web/pgadmin/static/js/backform.pgadmin.js | 2 +- 15 files changed, 39 insertions(+), 12 deletions(-) diff --git a/docs/en_US/release_notes_4_17.rst b/docs/en_US/release_notes_4_17.rst index d02c34daa..fcf12cf25 100644 --- a/docs/en_US/release_notes_4_17.rst +++ b/docs/en_US/release_notes_4_17.rst @@ -24,6 +24,7 @@ Bug fixes ********* | `Issue #4506 `_ - Fix an issue where clicking on an empty textbox like fill factor or comments, considers it as change and enabled the save button. +| `Issue #4842 `_ - Ensure that constraints, indexes, rules, triggers, and compound triggers should be created on partitions. | `Issue #4943 `_ - Added more information to the 'Database connected/disconnected' message. | `Issue #4999 `_ - Rename some internal environment variables that could conflict with Kubernetes. | `Issue #5004 `_ - Fix vulnerability issues reported by 'yarn audit'. Replace the deprecated uglifyjs-webpack-plugin with a terser-webpack-plugin. diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/__init__.py index 6119ff138..565d00fed 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/__init__.py @@ -726,7 +726,7 @@ class CompoundTriggerView(PGChildNodeView): self.conn, self.schema, self.table, tid, trid, self.datlastsysoid) except Exception as e: - return internal_server_error(errormsg=SQL) + return internal_server_error(errormsg=str(e)) return ajax_response(response=SQL) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js index 0f74895cf..1d7efeb45 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js @@ -42,6 +42,7 @@ define('pgadmin.node.compound_trigger', [ sqlAlterHelp: 'sql-altertcompoundtrigger.html', sqlCreateHelp: 'sql-createcompoundtrigger.html', dialogHelp: url_for('help.static', {'filename': 'compound_trigger_dialog.html'}), + url_jump_after_node: 'schema', Init: function() { /* Avoid mulitple registration of menus */ if (this.initialized) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/static/js/check_constraint.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/static/js/check_constraint.js index 65a002e1f..fed717ac2 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/static/js/check_constraint.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/static/js/check_constraint.js @@ -26,6 +26,7 @@ define('pgadmin.node.check_constraint', [ hasSQL: true, hasDepends: true, parent_type: ['table','partition'], + url_jump_after_node: 'schema', Init: function() { // Avoid mulitple registration of menus if (this.initialized) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/static/js/exclusion_constraint.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/static/js/exclusion_constraint.js index 647b63525..db1286f88 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/static/js/exclusion_constraint.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/static/js/exclusion_constraint.js @@ -629,6 +629,7 @@ define('pgadmin.node.exclusion_constraint', [ hasDepends: true, hasStatistics: true, statsPrettifyFields: [gettext('Index size')], + url_jump_after_node: 'schema', Init: function() { /* Avoid multiple registration of menus */ if (this.initialized) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/static/js/foreign_key.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/static/js/foreign_key.js index 96713ff08..12a940e34 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/static/js/foreign_key.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/static/js/foreign_key.js @@ -545,7 +545,8 @@ define('pgadmin.node.foreign_key', [ url = 'get_coveringindex', m = self.model, cols = [], - coveringindex = null; + coveringindex = null, + url_jump_after_node = 'schema'; self.collection.each(function(m){ cols.push(m.get('local_column')); @@ -557,7 +558,7 @@ define('pgadmin.node.foreign_key', [ full_url = node.generate_url.apply( node, [ null, url, this.field.get('node_data'), - this.field.get('url_with_id') || false, node_info, + this.field.get('url_with_id') || false, node_info, url_jump_after_node, ]); if (this.field.get('version_compatible')) { @@ -622,6 +623,7 @@ define('pgadmin.node.foreign_key', [ canDrop: true, canDropCascade: true, hasDepends: true, + url_jump_after_node: 'schema', Init: function() { /* Avoid multiple registration of menus */ if (this.initialized) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.js index 8ecd1dae0..ee0206d99 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.js @@ -29,6 +29,7 @@ define('pgadmin.node.primary_key', [ parent_type: ['table','partition'], canDrop: true, canDropCascade: true, + url_jump_after_node: 'schema', Init: function() { /* Avoid multiple registration of menus */ if (this.initialized) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/unique_constraint.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/unique_constraint.js index 9dac22028..fbec7b8fc 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/unique_constraint.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/unique_constraint.js @@ -29,6 +29,7 @@ define('pgadmin.node.unique_constraint', [ parent_type: ['table','partition'], canDrop: true, canDropCascade: true, + url_jump_after_node: 'schema', Init: function() { /* Avoid multiple registration of menus */ if (this.initialized) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/static/js/constraints.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/static/js/constraints.js index 60c2b3e98..7634f7a92 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/static/js/constraints.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/static/js/constraints.js @@ -33,6 +33,7 @@ define('pgadmin.node.constraints', [ label: gettext('Constraints'), collection_type: 'coll-constraints', parent_type: ['table','partition'], + url_jump_after_node: 'schema', Init: function() { /* Avoid mulitple registration of menus */ if (this.initialized) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js index 1f211b527..df2a7184a 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js @@ -92,6 +92,7 @@ define('pgadmin.node.index', [ return !(m.inSchemaWithModelCheck.apply(this, arguments)); }, control: 'node-ajax-options', url: 'get_collations', node: 'index', + url_jump_after_node: 'schema', },{ id: 'op_class', label: gettext('Operator class'), cell: NodeAjaxOptionsDepsCell, tags: true, @@ -106,6 +107,7 @@ define('pgadmin.node.index', [ return !(m.checkAccessMethod.apply(this, arguments)); }, control: 'node-ajax-options', url: 'get_op_class', node: 'index', + url_jump_after_node: 'schema', deps: ['amname'], transform: function(data, control) { /* We need to extract data from collection according * to access method selected by user if not selected @@ -232,6 +234,7 @@ define('pgadmin.node.index', [ hasStatistics: true, width: pgBrowser.stdW.md + 'px', statsPrettifyFields: [gettext('Size'), gettext('Index size')], + url_jump_after_node: 'schema', Init: function() { /* Avoid mulitple registration of menus */ if (this.initialized) @@ -308,6 +311,7 @@ define('pgadmin.node.index', [ id: 'amname', label: gettext('Access Method'), cell: 'string', type: 'text', mode: ['properties', 'create', 'edit'], disabled: 'inSchemaWithModelCheck', url: 'get_access_methods', + url_jump_after_node: 'schema', group: gettext('Definition'), select2: {'allowClear': true}, control: Backform.NodeAjaxOptionsControl.extend({ // When access method changes we need to clear columns collection diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.js index 7d66d9116..624b98806 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.js @@ -71,6 +71,7 @@ define('pgadmin.node.rule', [ return true; } }, + url_jump_after_node: 'schema', Init: function() { /* Avoid mulitple registration of menus */ diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js index 3ab6072c3..c390a8350 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js @@ -42,6 +42,7 @@ define('pgadmin.node.trigger', [ sqlAlterHelp: 'sql-altertrigger.html', sqlCreateHelp: 'sql-createtrigger.html', dialogHelp: url_for('help.static', {'filename': 'trigger_dialog.html'}), + url_jump_after_node: 'schema', Init: function() { /* Avoid mulitple registration of menus */ if (this.initialized) @@ -315,7 +316,7 @@ define('pgadmin.node.trigger', [ id: 'tfunction', label: gettext('Trigger function'), type: 'text', disabled: 'inSchemaWithModelCheck', mode: ['create','edit', 'properties'], group: gettext('Definition'), - control: 'node-ajax-options', url: 'get_triggerfunctions', + control: 'node-ajax-options', url: 'get_triggerfunctions', url_jump_after_node: 'schema', cache_node: 'trigger_function', },{ id: 'tgargs', label: gettext('Arguments'), cell: 'string', diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js index 1792037c6..b29c98ad3 100644 --- a/web/pgadmin/browser/static/js/node.js +++ b/web/pgadmin/browser/static/js/node.js @@ -281,7 +281,7 @@ define('pgadmin.browser.node', [ if (this.model) { // This will be the URL, used for object manipulation. // i.e. Create, Update in these cases - var urlBase = this.generate_url(item, type, node, false); + var urlBase = this.generate_url(item, type, node, false, null, that.url_jump_after_node); if (!urlBase) // Ashamed of myself, I don't know how to manipulate this @@ -1698,11 +1698,14 @@ define('pgadmin.browser.node', [ * type: Create/drop/edit/properties/sql/depends/statistics * d: Provide the ItemData for the current item node * with_id: Required id information at the end? - * + * jump_after_node: This will skip all the value between jump_after_node + * to the last node, excluding jump_after_node and the last node. This is particularly + * helpful in partition table where we need to skip parent table OID of a partitioned + * table in URL formation. Partitioned table itself is a "table" and can be multilevel * Supports url generation for create, drop, edit, properties, sql, * depends, statistics */ - generate_url: function(item, type, d, with_id, info) { + generate_url: function(item, type, d, with_id, info, jump_after_node) { var opURL = { 'create': 'obj', 'drop': 'obj', @@ -1735,9 +1738,16 @@ define('pgadmin.browser.node', [ }); } } + + let jump_after_priority = priority; + if(jump_after_node && treeInfo[jump_after_node]) { + jump_after_priority = treeInfo[jump_after_node].priority; + } + var nodePickFunction = function(treeInfoValue) { - return (treeInfoValue.priority <= priority); + return (treeInfoValue.priority <= jump_after_priority || treeInfoValue.priority == priority); }; + return generateUrl.generate_url(pgBrowser.URL, treeInfo, actionType, self.type, nodePickFunction, itemID); }, // Base class for Node Data Collection diff --git a/web/pgadmin/browser/static/js/node.ui.js b/web/pgadmin/browser/static/js/node.ui.js index 836d83d1f..6e5060791 100644 --- a/web/pgadmin/browser/static/js/node.ui.js +++ b/web/pgadmin/browser/static/js/node.ui.js @@ -179,7 +179,8 @@ define([ */ var self = this, url = self.field.get('url') || self.defaults.url, - m = self.model.top || self.model; + m = self.model.top || self.model, + url_jump_after_node = self.field.get('url_jump_after_node') || null; // Hmm - we found the url option. // That means - we needs to fetch the options from that node. @@ -189,7 +190,7 @@ define([ with_id = this.field.get('url_with_id') || false, full_url = node.generate_url.apply( node, [ - null, url, this.field.get('node_data'), with_id, node_info, + null, url, this.field.get('node_data'), with_id, node_info, url_jump_after_node, ]), cache_level, cache_node = this.field.get('cache_node'); @@ -450,9 +451,10 @@ define([ node = column.get('schema_node'), node_info = column.get('node_info'), with_id = column.get('url_with_id') || false, + url_jump_after_node = this.column.get('url_jump_after_node') || null, full_url = node.generate_url.apply( node, [ - null, url, column.get('node_data'), with_id, node_info, + null, url, column.get('node_data'), with_id, node_info, url_jump_after_node, ]), cache_level, cache_node = column.get('cache_node'); diff --git a/web/pgadmin/static/js/backform.pgadmin.js b/web/pgadmin/static/js/backform.pgadmin.js index 51fb5d763..c53be832c 100644 --- a/web/pgadmin/static/js/backform.pgadmin.js +++ b/web/pgadmin/static/js/backform.pgadmin.js @@ -1811,7 +1811,7 @@ define([ msql_url = node.generate_url.apply( node, [ null, 'msql', this.field.get('node_data'), !self.model.isNew(), - this.field.get('node_info'), + this.field.get('node_info'), node.url_jump_after_node, ]); // Fetching the modified SQL