diff --git a/src/backend/distributed/commands/citus_add_local_table_to_metadata.c b/src/backend/distributed/commands/citus_add_local_table_to_metadata.c index 55d8f7479..7e9505feb 100644 --- a/src/backend/distributed/commands/citus_add_local_table_to_metadata.c +++ b/src/backend/distributed/commands/citus_add_local_table_to_metadata.c @@ -46,6 +46,13 @@ #include "utils/syscache.h" +/* + * Global variable for the GUC citus.use_citus_managed_tables. + * This is used after every CREATE TABLE statement in utility_hook.c + * If this variable is set to true, we add all created tables to metadata. + */ +bool AddAllLocalTablesToMetadata = true; + static void citus_add_local_table_to_metadata_internal(Oid relationId, bool cascadeViaForeignKeys); static void ErrorIfAddingPartitionTableToMetadata(Oid relationId); diff --git a/src/backend/distributed/commands/table.c b/src/backend/distributed/commands/table.c index 0f4a3dd7a..9ac8b2091 100644 --- a/src/backend/distributed/commands/table.c +++ b/src/backend/distributed/commands/table.c @@ -2936,6 +2936,7 @@ ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement) case AT_SetNotNull: case AT_ReplicaIdentity: + case AT_ChangeOwner: case AT_ValidateConstraint: case AT_DropConstraint: /* we do the check for invalidation in AlterTableDropsForeignKey */ #if PG_VERSION_NUM >= PG_VERSION_14 diff --git a/src/backend/distributed/commands/utility_hook.c b/src/backend/distributed/commands/utility_hook.c index 66f749ecf..251fd183c 100644 --- a/src/backend/distributed/commands/utility_hook.c +++ b/src/backend/distributed/commands/utility_hook.c @@ -96,6 +96,7 @@ static void PostStandardProcessUtility(Node *parsetree); static void DecrementUtilityHookCountersIfNecessary(Node *parsetree); static bool IsDropSchemaOrDB(Node *parsetree); static bool ShouldCheckUndistributeCitusLocalTables(void); +static bool ShouldAddNewTableToMetadata(Node *parsetree); /* @@ -276,6 +277,28 @@ multi_ProcessUtility(PlannedStmt *pstmt, UndistributeDisconnectedCitusLocalTables(); } ResetConstraintDropped(); + + if (context == PROCESS_UTILITY_TOPLEVEL && + ShouldAddNewTableToMetadata(parsetree)) + { + /* + * Here we need to increment command counter so that next command + * can see the new table. + */ + CommandCounterIncrement(); + CreateStmt *createTableStmt = (CreateStmt *) parsetree; + Oid relationId = RangeVarGetRelid(createTableStmt->relation, + NoLock, false); + + /* + * Here we set autoConverted to false, since the user explicitly + * wants these tables to be added to metadata, by setting the + * GUC use_citus_managed_tables to true. + */ + bool autoConverted = false; + bool cascade = true; + CreateCitusLocalTable(relationId, cascade, autoConverted); + } } UtilityHookLevel--; @@ -843,6 +866,50 @@ ShouldCheckUndistributeCitusLocalTables(void) } +/* + * ShouldAddNewTableToMetadata takes a Node* and returns true if we need to add a + * newly created table to metadata, false otherwise. + * This function checks whether the given Node* is a CREATE TABLE statement. + * For partitions and temporary tables, ShouldAddNewTableToMetadata returns false. + * For other tables created, returns true, if we are on a coordinator that is added + * as worker, and ofcourse, if the GUC use_citus_managed_tables is set to on. + */ +static bool +ShouldAddNewTableToMetadata(Node *parsetree) +{ + if (!IsA(parsetree, CreateStmt)) + { + /* if the command is not CREATE TABLE, we can early return false */ + return false; + } + + CreateStmt *createTableStmt = (CreateStmt *) parsetree; + + if (createTableStmt->relation->relpersistence == RELPERSISTENCE_TEMP || + createTableStmt->partbound != NULL) + { + /* + * Shouldn't add table to metadata if it's a temp table, or a partition. + * Creating partitions of a table that is added to metadata is already handled. + */ + return false; + } + + if (AddAllLocalTablesToMetadata && !IsBinaryUpgrade && + IsCoordinator() && CoordinatorAddedAsWorkerNode()) + { + /* + * We have verified that the GUC is set to true, and we are not upgrading, + * and we are on the coordinator that is added as worker node. + * So return true here, to add this newly created table to metadata. + */ + return true; + } + + return false; +} + + /* * NotifyUtilityHookConstraintDropped sets ConstraintDropped to true to tell us * last command dropped a table constraint. diff --git a/src/backend/distributed/shared_library_init.c b/src/backend/distributed/shared_library_init.c index 2daac9d10..fb195fc2e 100644 --- a/src/backend/distributed/shared_library_init.c +++ b/src/backend/distributed/shared_library_init.c @@ -1671,6 +1671,17 @@ RegisterCitusConfigVariables(void) GUC_STANDARD, WarnIfDeprecatedExecutorUsed, NULL, NULL); + DefineCustomBoolVariable( + "citus.use_citus_managed_tables", + gettext_noop("Allows new local tables to be accessed on workers"), + gettext_noop("Adds all newly created tables to Citus metadata by default, " + "when enabled. Set to false by default."), + &AddAllLocalTablesToMetadata, + false, + PGC_USERSET, + GUC_STANDARD, + NULL, NULL, NULL); + DefineCustomEnumVariable( "citus.use_secondary_nodes", gettext_noop("Sets the policy to use when choosing nodes for SELECT queries."), diff --git a/src/include/distributed/commands.h b/src/include/distributed/commands.h index d57db6f9c..931f1c05a 100644 --- a/src/include/distributed/commands.h +++ b/src/include/distributed/commands.h @@ -21,6 +21,8 @@ #include "tcop/utility.h" +extern bool AddAllLocalTablesToMetadata; + /* controlled via GUC, should be accessed via EnableLocalReferenceForeignKeys() */ extern bool EnableLocalReferenceForeignKeys; diff --git a/src/test/regress/expected/auto_undist_citus_local.out b/src/test/regress/expected/auto_undist_citus_local.out index 71c614c79..73e900a6c 100644 --- a/src/test/regress/expected/auto_undist_citus_local.out +++ b/src/test/regress/expected/auto_undist_citus_local.out @@ -450,22 +450,13 @@ SELECT logicalrelid, partmethod, repmodel FROM pg_dist_partition WHERE logicalre -- verify that citus local tables converted by the user will not be auto-undistributed DROP TABLE IF EXISTS citus_local_table_1, citus_local_table_2, citus_local_table_3; +-- this GUC will add the next three tables to metadata automatically +SET citus.use_citus_managed_tables TO ON; CREATE TABLE citus_local_table_1(a INT UNIQUE); CREATE TABLE citus_local_table_2(a INT UNIQUE); CREATE TABLE citus_local_table_3(a INT UNIQUE); +RESET citus.use_citus_managed_tables; ALTER TABLE citus_local_table_1 ADD CONSTRAINT fkey_cas_test FOREIGN KEY (a) REFERENCES citus_local_table_2 (a); -SELECT citus_add_local_table_to_metadata('citus_local_table_1', cascade_via_foreign_keys=>true); - citus_add_local_table_to_metadata ---------------------------------------------------------------------- - -(1 row) - -SELECT citus_add_local_table_to_metadata('citus_local_table_3'); - citus_add_local_table_to_metadata ---------------------------------------------------------------------- - -(1 row) - ALTER TABLE citus_local_table_3 ADD CONSTRAINT fkey_cas_test_2 FOREIGN KEY (a) REFERENCES citus_local_table_2 (a); ALTER TABLE citus_local_table_3 DROP CONSTRAINT fkey_cas_test_2; SELECT logicalrelid, autoconverted FROM pg_dist_partition diff --git a/src/test/regress/expected/citus_local_tables.out b/src/test/regress/expected/citus_local_tables.out index 9697bea6b..4ad0ade5f 100644 --- a/src/test/regress/expected/citus_local_tables.out +++ b/src/test/regress/expected/citus_local_tables.out @@ -724,20 +724,12 @@ FROM (SELECT tableName FROM pg_catalog.pg_tables WHERE tablename LIKE 'citus_loc -- cannot create a citus local table from a catalog table SELECT citus_add_local_table_to_metadata('pg_class'); ERROR: cannot create a citus table from a catalog table +-- testing foreign key connection between citus local tables, +-- using the GUC use_citus_managed_tables to add tables to metadata +SET citus.use_citus_managed_tables TO ON; CREATE TABLE referencing_table(a int); -SELECT citus_add_local_table_to_metadata('referencing_table'); - citus_add_local_table_to_metadata ---------------------------------------------------------------------- - -(1 row) - CREATE TABLE referenced_table(a int UNIQUE); -SELECT citus_add_local_table_to_metadata('referenced_table'); - citus_add_local_table_to_metadata ---------------------------------------------------------------------- - -(1 row) - +RESET citus.use_citus_managed_tables; ALTER TABLE referencing_table ADD CONSTRAINT fkey_cl_to_cl FOREIGN KEY (a) REFERENCES referenced_table(a); NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (xxxxx, 'citus_local_tables_test_schema', xxxxx, 'citus_local_tables_test_schema', 'ALTER TABLE referencing_table ADD CONSTRAINT fkey_cl_to_cl FOREIGN KEY (a) REFERENCES referenced_table(a);') -- verify creating citus local table with extended statistics diff --git a/src/test/regress/sql/auto_undist_citus_local.sql b/src/test/regress/sql/auto_undist_citus_local.sql index 66ce13ea3..a792b2daa 100644 --- a/src/test/regress/sql/auto_undist_citus_local.sql +++ b/src/test/regress/sql/auto_undist_citus_local.sql @@ -210,12 +210,14 @@ SELECT logicalrelid, partmethod, repmodel FROM pg_dist_partition WHERE logicalre -- verify that citus local tables converted by the user will not be auto-undistributed DROP TABLE IF EXISTS citus_local_table_1, citus_local_table_2, citus_local_table_3; + +-- this GUC will add the next three tables to metadata automatically +SET citus.use_citus_managed_tables TO ON; CREATE TABLE citus_local_table_1(a INT UNIQUE); CREATE TABLE citus_local_table_2(a INT UNIQUE); CREATE TABLE citus_local_table_3(a INT UNIQUE); +RESET citus.use_citus_managed_tables; ALTER TABLE citus_local_table_1 ADD CONSTRAINT fkey_cas_test FOREIGN KEY (a) REFERENCES citus_local_table_2 (a); -SELECT citus_add_local_table_to_metadata('citus_local_table_1', cascade_via_foreign_keys=>true); -SELECT citus_add_local_table_to_metadata('citus_local_table_3'); ALTER TABLE citus_local_table_3 ADD CONSTRAINT fkey_cas_test_2 FOREIGN KEY (a) REFERENCES citus_local_table_2 (a); ALTER TABLE citus_local_table_3 DROP CONSTRAINT fkey_cas_test_2; SELECT logicalrelid, autoconverted FROM pg_dist_partition diff --git a/src/test/regress/sql/citus_local_tables.sql b/src/test/regress/sql/citus_local_tables.sql index 3369bcc72..42c3bea76 100644 --- a/src/test/regress/sql/citus_local_tables.sql +++ b/src/test/regress/sql/citus_local_tables.sql @@ -471,11 +471,12 @@ FROM (SELECT tableName FROM pg_catalog.pg_tables WHERE tablename LIKE 'citus_loc -- cannot create a citus local table from a catalog table SELECT citus_add_local_table_to_metadata('pg_class'); +-- testing foreign key connection between citus local tables, +-- using the GUC use_citus_managed_tables to add tables to metadata +SET citus.use_citus_managed_tables TO ON; CREATE TABLE referencing_table(a int); -SELECT citus_add_local_table_to_metadata('referencing_table'); - CREATE TABLE referenced_table(a int UNIQUE); -SELECT citus_add_local_table_to_metadata('referenced_table'); +RESET citus.use_citus_managed_tables; ALTER TABLE referencing_table ADD CONSTRAINT fkey_cl_to_cl FOREIGN KEY (a) REFERENCES referenced_table(a);