diff options
author | Peter Eisentraut <peter@eisentraut.org> | 2019-03-13 14:15:37 +0100 |
---|---|---|
committer | Peter Eisentraut <peter@eisentraut.org> | 2019-03-13 14:25:42 +0100 |
commit | f177660ab01e53dd5597b195dcc8526baa5cfcbd (patch) | |
tree | 73fbb45bb8f7b721cb16dc8780e45b19b406f0c8 /src/backend/commands/tablecmds.c | |
parent | bbb96c3704c041d139181c6601e5bc770e045d26 (diff) | |
download | postgresql-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.c | 42 |
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. |