diff --git a/src/backend/distributed/executor/multi_utility.c b/src/backend/distributed/executor/multi_utility.c index 80f844059..84c7fb01f 100644 --- a/src/backend/distributed/executor/multi_utility.c +++ b/src/backend/distributed/executor/multi_utility.c @@ -170,7 +170,6 @@ multi_ProcessUtility(Node *parsetree, DestReceiver *dest, char *completionTag) { - bool isCoordinator = IsCoordinator(); bool commandMustRunAsOwner = false; Oid savedUserId = InvalidOid; int savedSecurityContext = 0; @@ -296,19 +295,30 @@ multi_ProcessUtility(Node *parsetree, "move all tables."))); } } - else if (!isCoordinator) + else { + /* + * citus.enable_ddl_propagation is disabled, which means that PostgreSQL + * should handle the DDL command on a distributed table directly, without + * Citus intervening. Advanced Citus users use this to implement their own + * DDL propagation. We also use it to avoid re-propagating DDL commands + * when changing MX tables on workers. Below, we also make sure that DDL + * commands don't run queries that might get intercepted by Citus and error + * out, specifically we skip validation in foreign keys. + */ + if (IsA(parsetree, AlterTableStmt)) { AlterTableStmt *alterTableStmt = (AlterTableStmt *) parsetree; if (alterTableStmt->relkind == OBJECT_TABLE) { /* - * When the coordinator issues an ALTER TABLE ... ADD FOREIGN KEY - * command, the validation step should be skipped on the distributed - * table of the worker. Therefore, we check whether the given ALTER - * TABLE statement is a FOREIGN KEY constraint and if so disable the - * validation step. Note that validation is done on the shard level. + * When issuing an ALTER TABLE ... ADD FOREIGN KEY command, the + * the validation step should be skipped on the distributed table. + * Therefore, we check whether the given ALTER TABLE statement is a + * FOREIGN KEY constraint and if so disable the validation step. + * Note that validation is done on the shard level when DDL + * propagation is enabled. */ parsetree = WorkerProcessAlterTableStmt(alterTableStmt, queryString); } diff --git a/src/test/regress/expected/multi_foreign_key.out b/src/test/regress/expected/multi_foreign_key.out index 20058b869..10cf4d6b2 100644 --- a/src/test/regress/expected/multi_foreign_key.out +++ b/src/test/regress/expected/multi_foreign_key.out @@ -407,6 +407,13 @@ SELECT master_create_worker_shards('referencing_table', 4, 1); (1 row) +-- verify that we skip foreign key validation when propagation is turned off +-- not skipping validation would result in a distributed query, which emits debug messages +BEGIN; +SET LOCAL citus.enable_ddl_propagation TO off; +SET LOCAL client_min_messages TO DEBUG2; +ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY (ref_id) REFERENCES referenced_table (id); +ABORT; -- test foreign constraint creation -- test foreign constraint creation with not supported parameters ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON DELETE SET NULL; diff --git a/src/test/regress/sql/multi_foreign_key.sql b/src/test/regress/sql/multi_foreign_key.sql index f7258521d..5d4d51d4e 100644 --- a/src/test/regress/sql/multi_foreign_key.sql +++ b/src/test/regress/sql/multi_foreign_key.sql @@ -220,6 +220,13 @@ CREATE TABLE referencing_table(id int, ref_id int); SELECT master_create_distributed_table('referencing_table', 'ref_id', 'hash'); SELECT master_create_worker_shards('referencing_table', 4, 1); +-- verify that we skip foreign key validation when propagation is turned off +-- not skipping validation would result in a distributed query, which emits debug messages +BEGIN; +SET LOCAL citus.enable_ddl_propagation TO off; +SET LOCAL client_min_messages TO DEBUG2; +ALTER TABLE referencing_table ADD CONSTRAINT test_constraint FOREIGN KEY (ref_id) REFERENCES referenced_table (id); +ABORT; -- test foreign constraint creation -- test foreign constraint creation with not supported parameters