aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter@eisentraut.org>2019-03-13 14:15:37 +0100
committerPeter Eisentraut <peter@eisentraut.org>2019-03-13 14:25:42 +0100
commitf177660ab01e53dd5597b195dcc8526baa5cfcbd (patch)
tree73fbb45bb8f7b721cb16dc8780e45b19b406f0c8 /src/backend/commands/tablecmds.c
parentbbb96c3704c041d139181c6601e5bc770e045d26 (diff)
downloadpostgresql-f177660ab01e53dd5597b195dcc8526baa5cfcbd.tar.gz
postgresql-f177660ab01e53dd5597b195dcc8526baa5cfcbd.zip
Include all columns in default names for foreign key constraints
When creating a name for a foreign key constraint when none is specified, use all column names instead of only the first one, similar to how it is already done for index names. Author: Paul Martinez <hellopfm@gmail.com> Reviewed-by: Peter Eisentraut <peter.eisentraut@2ndquadrant.com> Discussion: https://www.postgresql.org/message-id/flat/CAF+2_SFjky6XRfLNRXpkG97W6PRbOO_mjAxqXzAAimU=c7w7_A@mail.gmail.com
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 754b59581b8..515c29072c8 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -402,6 +402,7 @@ static ObjectAddress ATExecAddConstraint(List **wqueue,
AlteredTableInfo *tab, Relation rel,
Constraint *newConstraint, bool recurse, bool is_readd,
LOCKMODE lockmode);
+static char *ChooseForeignKeyConstraintNameAddition(List *colnames);
static ObjectAddress ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel,
IndexStmt *stmt, LOCKMODE lockmode);
static ObjectAddress ATAddCheckConstraint(List **wqueue,
@@ -7191,7 +7192,7 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
else
newConstraint->conname =
ChooseConstraintName(RelationGetRelationName(rel),
- strVal(linitial(newConstraint->fk_attrs)),
+ ChooseForeignKeyConstraintNameAddition(newConstraint->fk_attrs),
"fkey",
RelationGetNamespace(rel),
NIL);
@@ -7211,6 +7212,45 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
}
/*
+ * Generate the column-name portion of the constraint name for a new foreign
+ * key given the list of column names that reference the referenced
+ * table. This will be passed to ChooseConstraintName along with the parent
+ * table name and the "fkey" suffix.
+ *
+ * We know that less than NAMEDATALEN characters will actually be used, so we
+ * can truncate the result once we've generated that many.
+ *
+ * XXX see also ChooseExtendedStatisticNameAddition and
+ * ChooseIndexNameAddition.
+ */
+static char *
+ChooseForeignKeyConstraintNameAddition(List *colnames)
+{
+ char buf[NAMEDATALEN * 2];
+ int buflen = 0;
+ ListCell *lc;
+
+ buf[0] = '\0';
+ foreach(lc, colnames)
+ {
+ const char *name = strVal(lfirst(lc));
+
+ if (buflen > 0)
+ buf[buflen++] = '_'; /* insert _ between names */
+
+ /*
+ * At this point we have buflen <= NAMEDATALEN. name should be less
+ * than NAMEDATALEN already, but use strlcpy for paranoia.
+ */
+ strlcpy(buf + buflen, name, NAMEDATALEN);
+ buflen += strlen(buf + buflen);
+ if (buflen >= NAMEDATALEN)
+ break;
+ }
+ return pstrdup(buf);
+}
+
+/*
* Add a check constraint to a single table and its children. Returns the
* address of the constraint added to the parent relation, if one gets added,
* or InvalidObjectAddress otherwise.