From c41ec7a70a27e5e569e274fa6b5782c853c5a7f6 Mon Sep 17 00:00:00 2001 From: Dave Page Date: Tue, 9 Jun 2026 12:01:30 +0100 Subject: [PATCH] Propagate column renames to FK and unique constraints. #9060 In the new-table dialog, the primary key already updated its column references when a column was renamed, but foreign key and unique constraint definitions did not, leaving them pointing at the old name. Mirror the PK rename-propagation in the foreign_key and unique_constraint depChange handlers (and add 'columns' to the unique constraint deps so it fires on column changes). Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/en_US/release_notes_9_16.rst | 2 ++ .../schemas/tables/static/js/table.ui.js | 36 +++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/docs/en_US/release_notes_9_16.rst b/docs/en_US/release_notes_9_16.rst index a7ec92e1bee..4150d8378f1 100644 --- a/docs/en_US/release_notes_9_16.rst +++ b/docs/en_US/release_notes_9_16.rst @@ -25,3 +25,5 @@ Housekeeping Bug fixes ********* + + | `Issue #9060 `_ - Fixed an issue in the Create/Edit Table dialog where renaming a column did not update the column references in foreign key and unique constraint definitions for the new table. diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.ui.js index 8c678ba4b04..da9897abc7a 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.ui.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.ui.js @@ -200,10 +200,25 @@ export class ConstraintsSchema extends BaseUISchema { disabled: this.inCatalog, canAddRow: obj.anyColumnAdded, expandEditOnAdd: true, - depChange: (state)=>{ + depChange: (state, source, topState, actionObj)=>{ if (state.is_partitioned && obj.top.getServerVersion() < 110000 || state.columns?.length <= 0) { return {foreign_key: []}; } + /* If a column is renamed, sync the foreign key local column references. #9060 */ + if(actionObj.type == SCHEMA_STATE_ACTIONS.SET_VALUE && actionObj.path[0] == 'columns' && + actionObj.path[actionObj.path.length-1] == 'name' && state.oid === undefined && + state.foreign_key?.length) { + let oldName = actionObj.oldState.columns[actionObj.path[1]]?.name, + newName = _.get(state, _.slice(actionObj.path, 0, -1))?.name; + if(oldName && newName && oldName !== newName) { + return {foreign_key: state.foreign_key.map((fk)=>({ + ...fk, + columns: fk.columns?.map((c)=>( + c.local_column === oldName ? {...c, local_column: newName} : c + )), + }))}; + } + } } },{ id: 'check_group', type: 'group', label: gettext('Check'), visible: !this.inErd, @@ -223,7 +238,7 @@ export class ConstraintsSchema extends BaseUISchema { schema: this.uniqueConsObj, editable: false, type: 'collection', group: 'unique_group', mode: ['edit', 'create'], - canEdit: true, canDelete: true, deps:['is_partitioned', 'typname'], + canEdit: true, canDelete: true, deps:['is_partitioned', 'typname', 'columns'], columns : ['name', 'columns'], disabled: this.inCatalog, canAdd: function(state) { @@ -231,10 +246,25 @@ export class ConstraintsSchema extends BaseUISchema { }, canAddRow: obj.anyColumnAdded, expandEditOnAdd: true, - depChange: (state)=>{ + depChange: (state, source, topState, actionObj)=>{ if (state.is_partitioned && obj.top.getServerVersion() < 110000 || state.columns?.length <= 0) { return {unique_constraint: []}; } + /* If a column is renamed, sync the unique constraint column references. #9060 */ + if(actionObj.type == SCHEMA_STATE_ACTIONS.SET_VALUE && actionObj.path[0] == 'columns' && + actionObj.path[actionObj.path.length-1] == 'name' && state.oid === undefined && + state.unique_constraint?.length) { + let oldName = actionObj.oldState.columns[actionObj.path[1]]?.name, + newName = _.get(state, _.slice(actionObj.path, 0, -1))?.name; + if(oldName && newName && oldName !== newName) { + return {unique_constraint: state.unique_constraint.map((uc)=>({ + ...uc, + columns: uc.columns?.map((c)=>( + c.column === oldName ? {...c, column: newName} : c + )), + }))}; + } + } } },{ id: 'exclude_group', type: 'group', label: gettext('Exclude'), visible: !this.inErd,