diff --git a/src/backend/distributed/commands/dependencies.c b/src/backend/distributed/commands/dependencies.c index fe6e651fa..bc5724ad0 100644 --- a/src/backend/distributed/commands/dependencies.c +++ b/src/backend/distributed/commands/dependencies.c @@ -31,6 +31,7 @@ typedef bool (*AddressPredicate)(const ObjectAddress *); +static void ErrorIfCircularDependencyExists(const ObjectAddress *objectAddress); static int ObjectAddressComparator(const void *a, const void *b); static List * GetDependencyCreateDDLCommands(const ObjectAddress *dependency); static List * FilterObjectAddressListByPredicate(List *objectAddressList, @@ -56,6 +57,13 @@ EnsureDependenciesExistOnAllNodes(const ObjectAddress *target) List *dependenciesWithCommands = NIL; List *ddlCommands = NULL; + /* + * Having circular dependency between distributed objects prevents Citus from + * adding a new node. So, error out if circular dependency exists for the given + * target object. + */ + ErrorIfCircularDependencyExists(target); + /* collect all dependencies in creation order and get their ddl commands */ List *dependencies = GetDependenciesForObject(target); ObjectAddress *dependency = NULL; @@ -135,6 +143,40 @@ EnsureDependenciesExistOnAllNodes(const ObjectAddress *target) } +/* + * ErrorIfCircularDependencyExists checks whether given object has circular dependency + * with itself via existing objects of pg_dist_object. + */ +static void +ErrorIfCircularDependencyExists(const ObjectAddress *objectAddress) +{ + List *dependencies = GetAllSupportedDependenciesForObject(objectAddress); + + ObjectAddress *dependency = NULL; + foreach_ptr(dependency, dependencies) + { + if (dependency->classId == objectAddress->classId && + dependency->objectId == objectAddress->objectId && + dependency->objectSubId == objectAddress->objectSubId) + { + char *objectDescription = NULL; + + #if PG_VERSION_NUM >= PG_VERSION_14 + objectDescription = getObjectDescription(objectAddress, false); + #else + objectDescription = getObjectDescription(objectAddress); + #endif + + ereport(ERROR, (errmsg("Citus can not handle circular dependencies " + "between distributed objects"), + errdetail("\"%s\" circularly depends itself, resolve " + "circular dependency first", + objectDescription))); + } + } +} + + /* * Copied from PG object_address_comparator function to compare ObjectAddresses. */ diff --git a/src/backend/distributed/commands/utility_hook.c b/src/backend/distributed/commands/utility_hook.c index dfb655fed..91e02a8ff 100644 --- a/src/backend/distributed/commands/utility_hook.c +++ b/src/backend/distributed/commands/utility_hook.c @@ -58,7 +58,6 @@ #include "distributed/metadata_cache.h" #endif #include "distributed/metadata_sync.h" -#include "distributed/metadata/dependency.h" #include "distributed/metadata/distobject.h" #include "distributed/multi_executor.h" #include "distributed/multi_explain.h" @@ -657,36 +656,6 @@ ProcessUtilityInternal(PlannedStmt *pstmt, */ if (EnableDDLPropagation) { - /* - * Having circular dependency between distributed objects prevents Citus from - * adding a new node. So, error out if circular dependency exists for the given - * target object. - * - * We need to check circular dependency here in addition to checking it within - * MarkObjectDistributedLocally since altering already distributed object won't - * call MarkObjectDistributedLocally but will hit the check here. - */ - if (ops && ops->address) - { - ObjectAddress targetObject = GetObjectAddressFromParseTree(parsetree, true); - char *objectDescription = NULL; - - #if PG_VERSION_NUM >= PG_VERSION_14 - objectDescription = getObjectDescription(&targetObject, true); - #else - objectDescription = getObjectDescription(&targetObject); - #endif - - /* - * Having object description as NULL means the target object is either dropped - * or it's name has been changed - */ - if (objectDescription != NULL) - { - ErrorIfCircularDependencyExists(&targetObject); - } - } - if (ops && ops->postprocess) { List *processJobs = ops->postprocess(parsetree, queryString); diff --git a/src/backend/distributed/metadata/dependency.c b/src/backend/distributed/metadata/dependency.c index 0c3fc85c7..5994c5d51 100644 --- a/src/backend/distributed/metadata/dependency.c +++ b/src/backend/distributed/metadata/dependency.c @@ -378,46 +378,6 @@ RecurseObjectDependencies(ObjectAddress target, expandFn expand, followFn follow } -/* - * ErrorIfCircularDependencyExists checks whether given object has circular dependency - * with itself via existing objects of pg_dist_object. - */ -void -ErrorIfCircularDependencyExists(const ObjectAddress *objectAddress) -{ - - /* - * We need to get the see dependencies created in this command. - */ - CommandCounterIncrement(); - - List *dependencies = GetAllSupportedDependenciesForObject(objectAddress); - - ObjectAddress *dependency = NULL; - foreach_ptr(dependency, dependencies) - { - if (dependency->classId == objectAddress->classId && - dependency->objectId == objectAddress->objectId && - dependency->objectSubId == objectAddress->objectSubId) - { - char *objectDescription = NULL; - - #if PG_VERSION_NUM >= PG_VERSION_14 - objectDescription = getObjectDescription(objectAddress, false); - #else - objectDescription = getObjectDescription(objectAddress); - #endif - - ereport(ERROR, (errmsg("Citus can not handle circular dependencies " - "between distributed objects"), - errdetail("\"%s\" circularly depends itself, resolve " - "circular dependency first", - objectDescription))); - } - } -} - - /* * DependencyDefinitionFromPgDepend loads all pg_depend records describing the * dependencies of target. diff --git a/src/backend/distributed/metadata/distobject.c b/src/backend/distributed/metadata/distobject.c index fdd951a13..b345210af 100644 --- a/src/backend/distributed/metadata/distobject.c +++ b/src/backend/distributed/metadata/distobject.c @@ -30,7 +30,6 @@ #include "commands/extension.h" #include "distributed/colocation_utils.h" #include "distributed/commands/utility_hook.h" -#include "distributed/metadata/dependency.h" #include "distributed/metadata/distobject.h" #include "distributed/metadata/pg_dist_object.h" #include "distributed/metadata_cache.h" @@ -199,16 +198,6 @@ MarkObjectDistributedViaSuperUser(const ObjectAddress *distAddress) static void MarkObjectDistributedLocally(const ObjectAddress *distAddress) { - /* - * Having circular dependency between distributed objects prevents Citus from - * adding a new node. So, error out if circular dependency exists for the given - * target object. - * - * Similar check also added to postprocess phase of ProcessUtilityInternal to - * handle altering already distributed objects. - */ - ErrorIfCircularDependencyExists(distAddress); - int paramCount = 3; Oid paramTypes[3] = { OIDOID, diff --git a/src/include/distributed/metadata/dependency.h b/src/include/distributed/metadata/dependency.h index 05462b181..92714f6cb 100644 --- a/src/include/distributed/metadata/dependency.h +++ b/src/include/distributed/metadata/dependency.h @@ -24,7 +24,6 @@ extern List * GetAllDependenciesForObject(const ObjectAddress *target); extern void EnsureRelationDependenciesCanBeDistributed(ObjectAddress *relationAddress); extern ObjectAddress * GetUndistributableDependency(ObjectAddress *target); extern List * OrderObjectAddressListInDependencyOrder(List *objectAddressList); -extern void ErrorIfCircularDependencyExists(const ObjectAddress *objectAddress); extern bool SupportedDependencyByCitus(const ObjectAddress *address); extern List * GetPgDependTuplesForDependingObjects(Oid targetObjectClassId, Oid targetObjectId);