Ensure that constraints, indexes, rules, triggers, and compound triggers should be created on partitions. Fixes #4842.

This commit is contained in:
Aditya Toshniwal 2020-01-01 12:59:48 +05:30 committed by Akshay Joshi
parent 737f8375fb
commit febbd729ec
15 changed files with 39 additions and 12 deletions

View File

@ -24,6 +24,7 @@ Bug fixes
*********
| `Issue #4506 <https://redmine.postgresql.org/issues/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 <https://redmine.postgresql.org/issues/4842>`_ - Ensure that constraints, indexes, rules, triggers, and compound triggers should be created on partitions.
| `Issue #4943 <https://redmine.postgresql.org/issues/4943>`_ - Added more information to the 'Database connected/disconnected' message.
| `Issue #4999 <https://redmine.postgresql.org/issues/4999>`_ - Rename some internal environment variables that could conflict with Kubernetes.
| `Issue #5004 <https://redmine.postgresql.org/issues/5004>`_ - Fix vulnerability issues reported by 'yarn audit'. Replace the deprecated uglifyjs-webpack-plugin with a terser-webpack-plugin.

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -71,6 +71,7 @@ define('pgadmin.node.rule', [
return true;
}
},
url_jump_after_node: 'schema',
Init: function() {
/* Avoid mulitple registration of menus */

View File

@ -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',

View File

@ -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

View File

@ -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');

View File

@ -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