diff --git a/src/backend/distributed/commands/table.c b/src/backend/distributed/commands/table.c index 390a81286..85d09d942 100644 --- a/src/backend/distributed/commands/table.c +++ b/src/backend/distributed/commands/table.c @@ -1028,30 +1028,7 @@ PreprocessAlterTableAddConstraint(AlterTableStmt *alterTableStatement, Oid relationId, Constraint *constraint) { - /* - * We should only preprocess an ADD CONSTRAINT command if we have empty conname - * This only happens when we have to create a constraint name in citus since the client does - * not specify a name. - * indexname should also be NULL to make sure this is not an - * ADD {PRIMARY KEY, UNIQUE} USING INDEX command - * which doesn't need a conname since the indexname will be used - */ - Assert(constraint->conname == NULL && constraint->indexname == NULL); - - Relation rel = RelationIdGetRelation(relationId); - - /* - * Change the alterTableCommand so that the standard utility - * hook runs it with the name we created. - */ - - constraint->conname = GenerateConstraintName(RelationGetRelationName(rel), - RelationGetNamespace(rel), - constraint); - - RelationClose(rel); - - SwitchToSequentialAndLocalExecutionIfConstraintNameTooLong(relationId, constraint); + PrepareAlterTableStmtForConstraint(alterTableStatement, relationId, constraint); char *ddlCommand = DeparseTreeNode((Node *) alterTableStatement); @@ -1067,11 +1044,6 @@ PreprocessAlterTableAddConstraint(AlterTableStmt *alterTableStatement, Oid Oid rightRelationId = RangeVarGetRelid(constraint->pktable, NoLock, false); - if (IsCitusTableType(rightRelationId, REFERENCE_TABLE)) - { - EnsureSequentialModeForAlterTableOperation(); - } - /* * If one of the relations involved in the FOREIGN KEY constraint is not a distributed table, citus errors out eventually. * PreprocessAlterTableStmt function returns an empty tasklist in those cases. @@ -1099,6 +1071,47 @@ PreprocessAlterTableAddConstraint(AlterTableStmt *alterTableStatement, Oid } +/* + * PrepareAlterTableStmtForConstraint assigns a name to the constraint if it + * does not have one and switches to sequential and local execution if the + * constraint name is too long. + */ +void +PrepareAlterTableStmtForConstraint(AlterTableStmt *alterTableStatement, + Oid relationId, + Constraint *constraint) +{ + if (constraint->conname == NULL && constraint->indexname == NULL) + { + Relation rel = RelationIdGetRelation(relationId); + + /* + * Change the alterTableCommand so that the standard utility + * hook runs it with the name we created. + */ + + constraint->conname = GenerateConstraintName(RelationGetRelationName(rel), + RelationGetNamespace(rel), + constraint); + + RelationClose(rel); + } + + SwitchToSequentialAndLocalExecutionIfConstraintNameTooLong(relationId, constraint); + + if (constraint->contype == CONSTR_FOREIGN) + { + Oid rightRelationId = RangeVarGetRelid(constraint->pktable, NoLock, + false); + + if (IsCitusTableType(rightRelationId, REFERENCE_TABLE)) + { + EnsureSequentialModeForAlterTableOperation(); + } + } +} + + /* * PreprocessAlterTableStmt determines whether a given ALTER TABLE statement * involves a distributed table. If so (and if the statement does not use diff --git a/src/include/distributed/commands.h b/src/include/distributed/commands.h index a013f3977..5c2bf2f42 100644 --- a/src/include/distributed/commands.h +++ b/src/include/distributed/commands.h @@ -582,6 +582,8 @@ extern bool ShouldEnableLocalReferenceForeignKeys(void); extern List * PreprocessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement, const char *queryString); extern List * PostprocessAlterTableSchemaStmt(Node *node, const char *queryString); +extern void PrepareAlterTableStmtForConstraint(AlterTableStmt *alterTableStatement, + Oid relationId, Constraint *constraint); extern List * PreprocessAlterTableStmt(Node *node, const char *alterTableCommand, ProcessUtilityContext processUtilityContext); extern List * PreprocessAlterTableMoveAllStmt(Node *node, const char *queryString,