aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 11fcb51a165..4397123398e 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -557,8 +557,8 @@ static ObjectAddress ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *
Relation rel, Constraint *fkconstraint,
bool recurse, bool recursing,
LOCKMODE lockmode);
-static void validateFkOnDeleteSetColumns(int numfks, const int16 *fkattnums,
- int numfksetcols, const int16 *fksetcolsattnums,
+static int validateFkOnDeleteSetColumns(int numfks, const int16 *fkattnums,
+ int numfksetcols, int16 *fksetcolsattnums,
List *fksetcols);
static ObjectAddress addFkConstraint(addFkConstraintSides fkside,
char *constraintname,
@@ -10037,9 +10037,10 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
numfkdelsetcols = transformColumnNameList(RelationGetRelid(rel),
fkconstraint->fk_del_set_cols,
fkdelsetcols, NULL, NULL);
- validateFkOnDeleteSetColumns(numfks, fkattnum,
- numfkdelsetcols, fkdelsetcols,
- fkconstraint->fk_del_set_cols);
+ numfkdelsetcols = validateFkOnDeleteSetColumns(numfks, fkattnum,
+ numfkdelsetcols,
+ fkdelsetcols,
+ fkconstraint->fk_del_set_cols);
/*
* If the attribute list for the referenced table was omitted, lookup the
@@ -10499,17 +10500,23 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
* validateFkOnDeleteSetColumns
* Verifies that columns used in ON DELETE SET NULL/DEFAULT (...)
* column lists are valid.
+ *
+ * If there are duplicates in the fksetcolsattnums[] array, this silently
+ * removes the dups. The new count of numfksetcols is returned.
*/
-void
+static int
validateFkOnDeleteSetColumns(int numfks, const int16 *fkattnums,
- int numfksetcols, const int16 *fksetcolsattnums,
+ int numfksetcols, int16 *fksetcolsattnums,
List *fksetcols)
{
+ int numcolsout = 0;
+
for (int i = 0; i < numfksetcols; i++)
{
int16 setcol_attnum = fksetcolsattnums[i];
bool seen = false;
+ /* Make sure it's in fkattnums[] */
for (int j = 0; j < numfks; j++)
{
if (fkattnums[j] == setcol_attnum)
@@ -10527,7 +10534,21 @@ validateFkOnDeleteSetColumns(int numfks, const int16 *fkattnums,
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
errmsg("column \"%s\" referenced in ON DELETE SET action must be part of foreign key", col)));
}
+
+ /* Now check for dups */
+ seen = false;
+ for (int j = 0; j < numcolsout; j++)
+ {
+ if (fksetcolsattnums[j] == setcol_attnum)
+ {
+ seen = true;
+ break;
+ }
+ }
+ if (!seen)
+ fksetcolsattnums[numcolsout++] = setcol_attnum;
}
+ return numcolsout;
}
/*