mirror of https://github.com/citusdata/citus.git
Error out if adding a new object causes a circular dependency
parent
341c3ee90a
commit
3668492e14
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
typedef bool (*AddressPredicate)(const ObjectAddress *);
|
typedef bool (*AddressPredicate)(const ObjectAddress *);
|
||||||
|
|
||||||
|
static void ErrorIfCircularDependencyExists(const ObjectAddress *objectAddress);
|
||||||
static int ObjectAddressComparator(const void *a, const void *b);
|
static int ObjectAddressComparator(const void *a, const void *b);
|
||||||
static List * GetDependencyCreateDDLCommands(const ObjectAddress *dependency);
|
static List * GetDependencyCreateDDLCommands(const ObjectAddress *dependency);
|
||||||
static List * FilterObjectAddressListByPredicate(List *objectAddressList,
|
static List * FilterObjectAddressListByPredicate(List *objectAddressList,
|
||||||
|
@ -56,6 +57,13 @@ EnsureDependenciesExistOnAllNodes(const ObjectAddress *target)
|
||||||
List *dependenciesWithCommands = NIL;
|
List *dependenciesWithCommands = NIL;
|
||||||
List *ddlCommands = NULL;
|
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 */
|
/* collect all dependencies in creation order and get their ddl commands */
|
||||||
List *dependencies = GetDependenciesForObject(target);
|
List *dependencies = GetDependenciesForObject(target);
|
||||||
ObjectAddress *dependency = NULL;
|
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.
|
* Copied from PG object_address_comparator function to compare ObjectAddresses.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue