Merge pull request #6063 from citusdata/list-of-address-api

change address method to return list of addresses
pull/6034/head^2
aykut-bozkurt 2022-07-19 18:22:23 +03:00 committed by GitHub
commit a5af78feb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 850 additions and 543 deletions

View File

@ -1302,7 +1302,7 @@ ErrorIfUnsupportedCascadeObjects(Oid relationId)
* *
* Extension dependency is different than the rest. If an object depends on an extension * Extension dependency is different than the rest. If an object depends on an extension
* dropping the object would drop the extension too. * dropping the object would drop the extension too.
* So we check with IsObjectAddressOwnedByExtension function. * So we check with IsAnyObjectAddressOwnedByExtension function.
*/ */
static bool static bool
DoesCascadeDropUnsupportedObject(Oid classId, Oid objectId, HTAB *nodeMap) DoesCascadeDropUnsupportedObject(Oid classId, Oid objectId, HTAB *nodeMap)
@ -1315,10 +1315,9 @@ DoesCascadeDropUnsupportedObject(Oid classId, Oid objectId, HTAB *nodeMap)
return false; return false;
} }
ObjectAddress objectAddress = { 0 }; ObjectAddress *objectAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(objectAddress, classId, objectId); ObjectAddressSet(*objectAddress, classId, objectId);
if (IsAnyObjectAddressOwnedByExtension(list_make1(objectAddress), NULL))
if (IsObjectAddressOwnedByExtension(&objectAddress, NULL))
{ {
return true; return true;
} }

View File

@ -307,8 +307,8 @@ CreateCitusLocalTable(Oid relationId, bool cascadeViaForeignKeys, bool autoConve
} }
} }
ObjectAddress tableAddress = { 0 }; ObjectAddress *tableAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(tableAddress, RelationRelationId, relationId); ObjectAddressSet(*tableAddress, RelationRelationId, relationId);
/* /*
* Ensure that the sequences used in column defaults of the table * Ensure that the sequences used in column defaults of the table
@ -320,7 +320,7 @@ CreateCitusLocalTable(Oid relationId, bool cascadeViaForeignKeys, bool autoConve
* Ensure dependencies exist as we will create shell table on the other nodes * Ensure dependencies exist as we will create shell table on the other nodes
* in the MX case. * in the MX case.
*/ */
EnsureDependenciesExistOnAllNodes(&tableAddress); EnsureAllObjectDependenciesExistOnAllNodes(list_make1(tableAddress));
/* /*
* Make sure that existing reference tables have been replicated to all * Make sure that existing reference tables have been replicated to all

View File

@ -169,7 +169,7 @@ CreateCollationDDLsIdempotent(Oid collationId)
} }
ObjectAddress List *
AlterCollationOwnerObjectAddress(Node *node, bool missing_ok) AlterCollationOwnerObjectAddress(Node *node, bool missing_ok)
{ {
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
@ -177,8 +177,13 @@ AlterCollationOwnerObjectAddress(Node *node, bool missing_ok)
Assert(stmt->objectType == OBJECT_COLLATION); Assert(stmt->objectType == OBJECT_COLLATION);
return get_object_address(stmt->objectType, stmt->object, &relation, ObjectAddress objectAddress = get_object_address(stmt->objectType, stmt->object,
AccessExclusiveLock, missing_ok); &relation, AccessExclusiveLock,
missing_ok);
ObjectAddress *objectAddressCopy = palloc0(sizeof(ObjectAddress));
*objectAddressCopy = objectAddress;
return list_make1(objectAddressCopy);
} }
@ -186,17 +191,17 @@ AlterCollationOwnerObjectAddress(Node *node, bool missing_ok)
* RenameCollationStmtObjectAddress returns the ObjectAddress of the type that is the object * RenameCollationStmtObjectAddress returns the ObjectAddress of the type that is the object
* of the RenameStmt. Errors if missing_ok is false. * of the RenameStmt. Errors if missing_ok is false.
*/ */
ObjectAddress List *
RenameCollationStmtObjectAddress(Node *node, bool missing_ok) RenameCollationStmtObjectAddress(Node *node, bool missing_ok)
{ {
RenameStmt *stmt = castNode(RenameStmt, node); RenameStmt *stmt = castNode(RenameStmt, node);
Assert(stmt->renameType == OBJECT_COLLATION); Assert(stmt->renameType == OBJECT_COLLATION);
Oid collationOid = get_collation_oid((List *) stmt->object, missing_ok); Oid collationOid = get_collation_oid((List *) stmt->object, missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, CollationRelationId, collationOid); ObjectAddressSet(*address, CollationRelationId, collationOid);
return address; return list_make1(address);
} }
@ -209,7 +214,7 @@ RenameCollationStmtObjectAddress(Node *node, bool missing_ok)
* new schema. Errors if missing_ok is false and the type cannot be found in either of the * new schema. Errors if missing_ok is false and the type cannot be found in either of the
* schemas. * schemas.
*/ */
ObjectAddress List *
AlterCollationSchemaStmtObjectAddress(Node *node, bool missing_ok) AlterCollationSchemaStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
@ -232,9 +237,9 @@ AlterCollationSchemaStmtObjectAddress(Node *node, bool missing_ok)
} }
} }
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, CollationRelationId, collationOid); ObjectAddressSet(*address, CollationRelationId, collationOid);
return address; return list_make1(address);
} }
@ -291,15 +296,15 @@ GenerateBackupNameForCollationCollision(const ObjectAddress *address)
} }
ObjectAddress List *
DefineCollationStmtObjectAddress(Node *node, bool missing_ok) DefineCollationStmtObjectAddress(Node *node, bool missing_ok)
{ {
DefineStmt *stmt = castNode(DefineStmt, node); DefineStmt *stmt = castNode(DefineStmt, node);
Assert(stmt->kind == OBJECT_COLLATION); Assert(stmt->kind == OBJECT_COLLATION);
Oid collOid = get_collation_oid(stmt->defnames, missing_ok); Oid collOid = get_collation_oid(stmt->defnames, missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, CollationRelationId, collOid); ObjectAddressSet(*address, CollationRelationId, collOid);
return address; return list_make1(address);
} }

View File

@ -61,22 +61,26 @@ PostprocessCreateDistributedObjectFromCatalogStmt(Node *stmt, const char *queryS
return NIL; return NIL;
} }
ObjectAddress address = GetObjectAddressFromParseTree(stmt, false); List *addresses = GetObjectAddressListFromParseTree(stmt, false);
/* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
EnsureCoordinator(); EnsureCoordinator();
EnsureSequentialMode(ops->objectType); EnsureSequentialMode(ops->objectType);
/* If the object has any unsupported dependency warn, and only create locally */ /* If the object has any unsupported dependency warn, and only create locally */
DeferredErrorMessage *depError = DeferErrorIfHasUnsupportedDependency(&address); DeferredErrorMessage *depError = DeferErrorIfAnyObjectHasUnsupportedDependency(
addresses);
if (depError != NULL) if (depError != NULL)
{ {
RaiseDeferredError(depError, WARNING); RaiseDeferredError(depError, WARNING);
return NIL; return NIL;
} }
EnsureDependenciesExistOnAllNodes(&address); EnsureAllObjectDependenciesExistOnAllNodes(addresses);
List *commands = GetDependencyCreateDDLCommands(&address); List *commands = GetAllDependencyCreateDDLCommands(addresses);
commands = lcons(DISABLE_DDL_PROPAGATION, commands); commands = lcons(DISABLE_DDL_PROPAGATION, commands);
commands = lappend(commands, ENABLE_DDL_PROPAGATION); commands = lappend(commands, ENABLE_DDL_PROPAGATION);
@ -111,8 +115,12 @@ PreprocessAlterDistributedObjectStmt(Node *stmt, const char *queryString,
const DistributeObjectOps *ops = GetDistributeObjectOps(stmt); const DistributeObjectOps *ops = GetDistributeObjectOps(stmt);
Assert(ops != NULL); Assert(ops != NULL);
ObjectAddress address = GetObjectAddressFromParseTree(stmt, false); List *addresses = GetObjectAddressListFromParseTree(stmt, false);
if (!ShouldPropagateObject(&address))
/* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
if (!ShouldPropagateAnyObject(addresses))
{ {
return NIL; return NIL;
} }
@ -156,8 +164,12 @@ PostprocessAlterDistributedObjectStmt(Node *stmt, const char *queryString)
const DistributeObjectOps *ops = GetDistributeObjectOps(stmt); const DistributeObjectOps *ops = GetDistributeObjectOps(stmt);
Assert(ops != NULL); Assert(ops != NULL);
ObjectAddress address = GetObjectAddressFromParseTree(stmt, false); List *addresses = GetObjectAddressListFromParseTree(stmt, false);
if (!ShouldPropagateObject(&address))
/* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
if (!ShouldPropagateAnyObject(addresses))
{ {
return NIL; return NIL;
} }
@ -168,7 +180,7 @@ PostprocessAlterDistributedObjectStmt(Node *stmt, const char *queryString)
return NIL; return NIL;
} }
EnsureDependenciesExistOnAllNodes(&address); EnsureAllObjectDependenciesExistOnAllNodes(addresses);
return NIL; return NIL;
} }
@ -223,11 +235,10 @@ PreprocessDropDistributedObjectStmt(Node *node, const char *queryString,
Relation rel = NULL; /* not used, but required to pass to get_object_address */ Relation rel = NULL; /* not used, but required to pass to get_object_address */
ObjectAddress address = get_object_address(stmt->removeType, object, &rel, ObjectAddress address = get_object_address(stmt->removeType, object, &rel,
AccessShareLock, stmt->missing_ok); AccessShareLock, stmt->missing_ok);
if (IsObjectDistributed(&address))
{
ObjectAddress *addressPtr = palloc0(sizeof(ObjectAddress)); ObjectAddress *addressPtr = palloc0(sizeof(ObjectAddress));
*addressPtr = address; *addressPtr = address;
if (IsAnyObjectDistributed(list_make1(addressPtr)))
{
distributedObjects = lappend(distributedObjects, object); distributedObjects = lappend(distributedObjects, object);
distributedObjectAddresses = lappend(distributedObjectAddresses, addressPtr); distributedObjectAddresses = lappend(distributedObjectAddresses, addressPtr);
} }

View File

@ -442,10 +442,9 @@ CreateDistributedTable(Oid relationId, char *distributionColumnName,
* via their own connection and committed immediately so they become visible to all * via their own connection and committed immediately so they become visible to all
* sessions creating shards. * sessions creating shards.
*/ */
ObjectAddress tableAddress = { 0 }; ObjectAddress *tableAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(tableAddress, RelationRelationId, relationId); ObjectAddressSet(*tableAddress, RelationRelationId, relationId);
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(tableAddress));
EnsureDependenciesExistOnAllNodes(&tableAddress);
char replicationModel = DecideReplicationModel(distributionMethod, char replicationModel = DecideReplicationModel(distributionMethod,
colocateWithTableName, colocateWithTableName,

View File

@ -40,17 +40,17 @@ bool EnableAlterDatabaseOwner = true;
* AlterDatabaseOwnerObjectAddress returns the ObjectAddress of the database that is the * AlterDatabaseOwnerObjectAddress returns the ObjectAddress of the database that is the
* object of the AlterOwnerStmt. Errors if missing_ok is false. * object of the AlterOwnerStmt. Errors if missing_ok is false.
*/ */
ObjectAddress List *
AlterDatabaseOwnerObjectAddress(Node *node, bool missing_ok) AlterDatabaseOwnerObjectAddress(Node *node, bool missing_ok)
{ {
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
Assert(stmt->objectType == OBJECT_DATABASE); Assert(stmt->objectType == OBJECT_DATABASE);
Oid databaseOid = get_database_oid(strVal((String *) stmt->object), missing_ok); Oid databaseOid = get_database_oid(strVal((String *) stmt->object), missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, DatabaseRelationId, databaseOid); ObjectAddressSet(*address, DatabaseRelationId, databaseOid);
return address; return list_make1(address);
} }

View File

@ -36,6 +36,9 @@ 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 * FilterObjectAddressListByPredicate(List *objectAddressList, static List * FilterObjectAddressListByPredicate(List *objectAddressList,
AddressPredicate predicate); AddressPredicate predicate);
static void EnsureDependenciesExistOnAllNodes(const ObjectAddress *target);
static List * GetDependencyCreateDDLCommands(const ObjectAddress *dependency);
static bool ShouldPropagateObject(const ObjectAddress *address);
/* /*
* EnsureDependenciesExistOnAllNodes finds all the dependencies that we support and makes * EnsureDependenciesExistOnAllNodes finds all the dependencies that we support and makes
@ -51,7 +54,7 @@ static List * FilterObjectAddressListByPredicate(List *objectAddressList,
* This is solved by creating the dependencies in an idempotent manner, either via * This is solved by creating the dependencies in an idempotent manner, either via
* postgres native CREATE IF NOT EXISTS, or citus helper functions. * postgres native CREATE IF NOT EXISTS, or citus helper functions.
*/ */
void static void
EnsureDependenciesExistOnAllNodes(const ObjectAddress *target) EnsureDependenciesExistOnAllNodes(const ObjectAddress *target)
{ {
List *dependenciesWithCommands = NIL; List *dependenciesWithCommands = NIL;
@ -142,6 +145,21 @@ EnsureDependenciesExistOnAllNodes(const ObjectAddress *target)
} }
/*
* EnsureAllObjectDependenciesExistOnAllNodes iteratively calls EnsureDependenciesExistOnAllNodes
* for given targets.
*/
void
EnsureAllObjectDependenciesExistOnAllNodes(const List *targets)
{
ObjectAddress *target = NULL;
foreach_ptr(target, targets)
{
EnsureDependenciesExistOnAllNodes(target);
}
}
/* /*
* EnsureDependenciesCanBeDistributed ensures all dependencies of the given object * EnsureDependenciesCanBeDistributed ensures all dependencies of the given object
* can be distributed. * can be distributed.
@ -153,7 +171,8 @@ EnsureDependenciesCanBeDistributed(const ObjectAddress *objectAddress)
ErrorIfCircularDependencyExists(objectAddress); ErrorIfCircularDependencyExists(objectAddress);
/* If the object has any unsupported dependency, error out */ /* If the object has any unsupported dependency, error out */
DeferredErrorMessage *depError = DeferErrorIfHasUnsupportedDependency(objectAddress); DeferredErrorMessage *depError = DeferErrorIfAnyObjectHasUnsupportedDependency(
list_make1((ObjectAddress *) objectAddress));
if (depError != NULL) if (depError != NULL)
{ {
@ -310,7 +329,7 @@ GetDistributableDependenciesForObject(const ObjectAddress *target)
* GetDependencyCreateDDLCommands returns a list (potentially empty or NIL) of ddl * GetDependencyCreateDDLCommands returns a list (potentially empty or NIL) of ddl
* commands to execute on a worker to create the object. * commands to execute on a worker to create the object.
*/ */
List * static List *
GetDependencyCreateDDLCommands(const ObjectAddress *dependency) GetDependencyCreateDDLCommands(const ObjectAddress *dependency)
{ {
switch (getObjectClass(dependency)) switch (getObjectClass(dependency))
@ -488,6 +507,25 @@ GetDependencyCreateDDLCommands(const ObjectAddress *dependency)
} }
/*
* GetAllDependencyCreateDDLCommands iteratively calls GetDependencyCreateDDLCommands
* for given dependencies.
*/
List *
GetAllDependencyCreateDDLCommands(const List *dependencies)
{
List *commands = NIL;
ObjectAddress *dependency = NULL;
foreach_ptr(dependency, dependencies)
{
commands = list_concat(commands, GetDependencyCreateDDLCommands(dependency));
}
return commands;
}
/* /*
* ReplicateAllObjectsToNodeCommandList returns commands to replicate all * ReplicateAllObjectsToNodeCommandList returns commands to replicate all
* previously marked objects to a worker node. The function also sets * previously marked objects to a worker node. The function also sets
@ -531,7 +569,7 @@ ReplicateAllObjectsToNodeCommandList(const char *nodeName, int nodePort)
ObjectAddress *dependency = NULL; ObjectAddress *dependency = NULL;
foreach_ptr(dependency, dependencies) foreach_ptr(dependency, dependencies)
{ {
if (IsObjectAddressOwnedByExtension(dependency, NULL)) if (IsAnyObjectAddressOwnedByExtension(list_make1(dependency), NULL))
{ {
/* /*
* we expect extension-owned objects to be created as a result * we expect extension-owned objects to be created as a result
@ -663,7 +701,7 @@ ShouldPropagateCreateInCoordinatedTransction()
* ShouldPropagateObject determines if we should be propagating DDLs based * ShouldPropagateObject determines if we should be propagating DDLs based
* on their object address. * on their object address.
*/ */
bool static bool
ShouldPropagateObject(const ObjectAddress *address) ShouldPropagateObject(const ObjectAddress *address)
{ {
if (!ShouldPropagate()) if (!ShouldPropagate())
@ -671,7 +709,7 @@ ShouldPropagateObject(const ObjectAddress *address)
return false; return false;
} }
if (!IsObjectDistributed(address)) if (!IsAnyObjectDistributed(list_make1((ObjectAddress *) address)))
{ {
/* do not propagate for non-distributed types */ /* do not propagate for non-distributed types */
return false; return false;
@ -681,6 +719,26 @@ ShouldPropagateObject(const ObjectAddress *address)
} }
/*
* ShouldPropagateAnyObject determines if we should be propagating DDLs based
* on their object addresses.
*/
bool
ShouldPropagateAnyObject(List *addresses)
{
ObjectAddress *address = NULL;
foreach_ptr(address, addresses)
{
if (ShouldPropagateObject(address))
{
return true;
}
}
return false;
}
/* /*
* FilterObjectAddressListByPredicate takes a list of ObjectAddress *'s and returns a list * FilterObjectAddressListByPredicate takes a list of ObjectAddress *'s and returns a list
* only containing the ObjectAddress *'s for which the predicate returned true. * only containing the ObjectAddress *'s for which the predicate returned true.

View File

@ -37,7 +37,7 @@
static CollateClause * MakeCollateClauseFromOid(Oid collationOid); static CollateClause * MakeCollateClauseFromOid(Oid collationOid);
static ObjectAddress GetDomainAddressByName(TypeName *domainName, bool missing_ok); static List * GetDomainAddressByName(TypeName *domainName, bool missing_ok);
/* /*
* GetDomainAddressByName returns the ObjectAddress of the domain identified by * GetDomainAddressByName returns the ObjectAddress of the domain identified by
@ -45,13 +45,13 @@ static ObjectAddress GetDomainAddressByName(TypeName *domainName, bool missing_o
* InvalidOid. When missing_ok is false this function will raise an error instead when the * InvalidOid. When missing_ok is false this function will raise an error instead when the
* domain can't be found. * domain can't be found.
*/ */
static ObjectAddress static List *
GetDomainAddressByName(TypeName *domainName, bool missing_ok) GetDomainAddressByName(TypeName *domainName, bool missing_ok)
{ {
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
Oid domainOid = LookupTypeNameOid(NULL, domainName, missing_ok); Oid domainOid = LookupTypeNameOid(NULL, domainName, missing_ok);
ObjectAddressSet(address, TypeRelationId, domainOid); ObjectAddressSet(*address, TypeRelationId, domainOid);
return address; return list_make1(address);
} }
@ -229,17 +229,17 @@ MakeCollateClauseFromOid(Oid collationOid)
* created by the statement. When missing_ok is false the function will raise an error if * created by the statement. When missing_ok is false the function will raise an error if
* the domain cannot be found in the local catalog. * the domain cannot be found in the local catalog.
*/ */
ObjectAddress List *
CreateDomainStmtObjectAddress(Node *node, bool missing_ok) CreateDomainStmtObjectAddress(Node *node, bool missing_ok)
{ {
CreateDomainStmt *stmt = castNode(CreateDomainStmt, node); CreateDomainStmt *stmt = castNode(CreateDomainStmt, node);
TypeName *typeName = makeTypeNameFromNameList(stmt->domainname); TypeName *typeName = makeTypeNameFromNameList(stmt->domainname);
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok); Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TypeRelationId, typeOid); ObjectAddressSet(*address, TypeRelationId, typeOid);
return address; return list_make1(address);
} }
@ -248,7 +248,7 @@ CreateDomainStmtObjectAddress(Node *node, bool missing_ok)
* When missing_ok is false this function will raise an error when the domain is not * When missing_ok is false this function will raise an error when the domain is not
* found. * found.
*/ */
ObjectAddress List *
AlterDomainStmtObjectAddress(Node *node, bool missing_ok) AlterDomainStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterDomainStmt *stmt = castNode(AlterDomainStmt, node); AlterDomainStmt *stmt = castNode(AlterDomainStmt, node);
@ -263,7 +263,7 @@ AlterDomainStmtObjectAddress(Node *node, bool missing_ok)
* which the constraint is being renamed. When missing_ok this function will raise an * which the constraint is being renamed. When missing_ok this function will raise an
* error if the domain cannot be found. * error if the domain cannot be found.
*/ */
ObjectAddress List *
DomainRenameConstraintStmtObjectAddress(Node *node, bool missing_ok) DomainRenameConstraintStmtObjectAddress(Node *node, bool missing_ok)
{ {
RenameStmt *stmt = castNode(RenameStmt, node); RenameStmt *stmt = castNode(RenameStmt, node);
@ -278,7 +278,7 @@ DomainRenameConstraintStmtObjectAddress(Node *node, bool missing_ok)
* being changed. When missing_ok is false this function will raise an error if the domain * being changed. When missing_ok is false this function will raise an error if the domain
* cannot be found. * cannot be found.
*/ */
ObjectAddress List *
AlterDomainOwnerStmtObjectAddress(Node *node, bool missing_ok) AlterDomainOwnerStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
@ -294,7 +294,7 @@ AlterDomainOwnerStmtObjectAddress(Node *node, bool missing_ok)
* When missing_ok is false this function will raise an error when the domain cannot be * When missing_ok is false this function will raise an error when the domain cannot be
* found. * found.
*/ */
ObjectAddress List *
RenameDomainStmtObjectAddress(Node *node, bool missing_ok) RenameDomainStmtObjectAddress(Node *node, bool missing_ok)
{ {
RenameStmt *stmt = castNode(RenameStmt, node); RenameStmt *stmt = castNode(RenameStmt, node);

View File

@ -181,9 +181,12 @@ PostprocessCreateExtensionStmt(Node *node, const char *queryString)
(void *) createExtensionStmtSql, (void *) createExtensionStmtSql,
ENABLE_DDL_PROPAGATION); ENABLE_DDL_PROPAGATION);
ObjectAddress extensionAddress = GetObjectAddressFromParseTree(node, false); List *extensionAddresses = GetObjectAddressListFromParseTree(node, false);
EnsureDependenciesExistOnAllNodes(&extensionAddress); /* the code-path only supports a single object */
Assert(list_length(extensionAddresses) == 1);
EnsureAllObjectDependenciesExistOnAllNodes(extensionAddresses);
return NodeDDLTaskList(NON_COORDINATOR_NODES, commands); return NodeDDLTaskList(NON_COORDINATOR_NODES, commands);
} }
@ -319,10 +322,9 @@ FilterDistributedExtensions(List *extensionObjectList)
continue; continue;
} }
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, ExtensionRelationId, extensionOid); ObjectAddressSet(*address, ExtensionRelationId, extensionOid);
if (!IsAnyObjectDistributed(list_make1(address)))
if (!IsObjectDistributed(&address))
{ {
continue; continue;
} }
@ -411,7 +413,10 @@ PreprocessAlterExtensionSchemaStmt(Node *node, const char *queryString,
List * List *
PostprocessAlterExtensionSchemaStmt(Node *node, const char *queryString) PostprocessAlterExtensionSchemaStmt(Node *node, const char *queryString)
{ {
ObjectAddress extensionAddress = GetObjectAddressFromParseTree(node, false); List *extensionAddresses = GetObjectAddressListFromParseTree(node, false);
/* the code-path only supports a single object */
Assert(list_length(extensionAddresses) == 1);
if (!ShouldPropagateExtensionCommand(node)) if (!ShouldPropagateExtensionCommand(node))
{ {
@ -419,7 +424,7 @@ PostprocessAlterExtensionSchemaStmt(Node *node, const char *queryString)
} }
/* dependencies (schema) have changed let's ensure they exist */ /* dependencies (schema) have changed let's ensure they exist */
EnsureDependenciesExistOnAllNodes(&extensionAddress); EnsureAllObjectDependenciesExistOnAllNodes(extensionAddresses);
return NIL; return NIL;
} }
@ -504,7 +509,7 @@ PostprocessAlterExtensionCitusUpdateStmt(Node *node)
* *
* Note that this function is not responsible for ensuring if dependencies exist on * Note that this function is not responsible for ensuring if dependencies exist on
* nodes and satisfying these dependendencies if not exists, which is already done by * nodes and satisfying these dependendencies if not exists, which is already done by
* EnsureDependenciesExistOnAllNodes on demand. Hence, this function is just designed * EnsureAllObjectDependenciesExistOnAllNodes on demand. Hence, this function is just designed
* to be used when "ALTER EXTENSION citus UPDATE" is executed. * to be used when "ALTER EXTENSION citus UPDATE" is executed.
* This is because we want to add existing objects that would have already been in * This is because we want to add existing objects that would have already been in
* pg_dist_object if we had created them in new version of Citus to pg_dist_object. * pg_dist_object if we had created them in new version of Citus to pg_dist_object.
@ -1128,7 +1133,7 @@ GetDependentFDWsToExtension(Oid extensionId)
* AlterExtensionSchemaStmtObjectAddress returns the ObjectAddress of the extension that is * AlterExtensionSchemaStmtObjectAddress returns the ObjectAddress of the extension that is
* the subject of the AlterObjectSchemaStmt. Errors if missing_ok is false. * the subject of the AlterObjectSchemaStmt. Errors if missing_ok is false.
*/ */
ObjectAddress List *
AlterExtensionSchemaStmtObjectAddress(Node *node, bool missing_ok) AlterExtensionSchemaStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
@ -1145,10 +1150,10 @@ AlterExtensionSchemaStmtObjectAddress(Node *node, bool missing_ok)
extensionName))); extensionName)));
} }
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, ExtensionRelationId, extensionOid); ObjectAddressSet(*address, ExtensionRelationId, extensionOid);
return address; return list_make1(address);
} }
@ -1156,7 +1161,7 @@ AlterExtensionSchemaStmtObjectAddress(Node *node, bool missing_ok)
* AlterExtensionUpdateStmtObjectAddress returns the ObjectAddress of the extension that is * AlterExtensionUpdateStmtObjectAddress returns the ObjectAddress of the extension that is
* the subject of the AlterExtensionStmt. Errors if missing_ok is false. * the subject of the AlterExtensionStmt. Errors if missing_ok is false.
*/ */
ObjectAddress List *
AlterExtensionUpdateStmtObjectAddress(Node *node, bool missing_ok) AlterExtensionUpdateStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterExtensionStmt *stmt = castNode(AlterExtensionStmt, node); AlterExtensionStmt *stmt = castNode(AlterExtensionStmt, node);
@ -1171,10 +1176,10 @@ AlterExtensionUpdateStmtObjectAddress(Node *node, bool missing_ok)
extensionName))); extensionName)));
} }
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, ExtensionRelationId, extensionOid); ObjectAddressSet(*address, ExtensionRelationId, extensionOid);
return address; return list_make1(address);
} }

View File

@ -64,6 +64,7 @@ PreprocessGrantOnFDWStmt(Node *node, const char *queryString,
EnsureCoordinator(); EnsureCoordinator();
/* the code-path only supports a single object */
Assert(list_length(stmt->objects) == 1); Assert(list_length(stmt->objects) == 1);
char *sql = DeparseTreeNode((Node *) stmt); char *sql = DeparseTreeNode((Node *) stmt);
@ -87,12 +88,15 @@ NameListHasFDWOwnedByDistributedExtension(List *FDWNames)
foreach_ptr(FDWValue, FDWNames) foreach_ptr(FDWValue, FDWNames)
{ {
/* captures the extension address during lookup */ /* captures the extension address during lookup */
ObjectAddress extensionAddress = { 0 }; ObjectAddress *extensionAddress = palloc0(sizeof(ObjectAddress));
ObjectAddress FDWAddress = GetObjectAddressByFDWName(strVal(FDWValue), false); ObjectAddress FDWAddress = GetObjectAddressByFDWName(strVal(FDWValue), false);
if (IsObjectAddressOwnedByExtension(&FDWAddress, &extensionAddress)) ObjectAddress *copyFDWAddress = palloc0(sizeof(ObjectAddress));
*copyFDWAddress = FDWAddress;
if (IsAnyObjectAddressOwnedByExtension(list_make1(copyFDWAddress),
extensionAddress))
{ {
if (IsObjectDistributed(&extensionAddress)) if (IsAnyObjectDistributed(list_make1(extensionAddress)))
{ {
return true; return true;
} }

View File

@ -16,6 +16,7 @@
#include "distributed/commands.h" #include "distributed/commands.h"
#include "distributed/deparser.h" #include "distributed/deparser.h"
#include "distributed/listutils.h" #include "distributed/listutils.h"
#include "distributed/log_utils.h"
#include "distributed/metadata/distobject.h" #include "distributed/metadata/distobject.h"
#include "distributed/metadata_sync.h" #include "distributed/metadata_sync.h"
#include "distributed/multi_executor.h" #include "distributed/multi_executor.h"
@ -29,7 +30,7 @@
static char * GetForeignServerAlterOwnerCommand(Oid serverId); static char * GetForeignServerAlterOwnerCommand(Oid serverId);
static Node * RecreateForeignServerStmt(Oid serverId); static Node * RecreateForeignServerStmt(Oid serverId);
static bool NameListHasDistributedServer(List *serverNames); static bool NameListHasDistributedServer(List *serverNames);
static ObjectAddress GetObjectAddressByServerName(char *serverName, bool missing_ok); static List * GetObjectAddressByServerName(char *serverName, bool missing_ok);
/* /*
@ -40,7 +41,7 @@ static ObjectAddress GetObjectAddressByServerName(char *serverName, bool missing
* Never returns NULL, but the objid in the address can be invalid if missingOk * Never returns NULL, but the objid in the address can be invalid if missingOk
* was set to true. * was set to true.
*/ */
ObjectAddress List *
CreateForeignServerStmtObjectAddress(Node *node, bool missing_ok) CreateForeignServerStmtObjectAddress(Node *node, bool missing_ok)
{ {
CreateForeignServerStmt *stmt = castNode(CreateForeignServerStmt, node); CreateForeignServerStmt *stmt = castNode(CreateForeignServerStmt, node);
@ -57,7 +58,7 @@ CreateForeignServerStmtObjectAddress(Node *node, bool missing_ok)
* Never returns NULL, but the objid in the address can be invalid if missingOk * Never returns NULL, but the objid in the address can be invalid if missingOk
* was set to true. * was set to true.
*/ */
ObjectAddress List *
AlterForeignServerStmtObjectAddress(Node *node, bool missing_ok) AlterForeignServerStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterForeignServerStmt *stmt = castNode(AlterForeignServerStmt, node); AlterForeignServerStmt *stmt = castNode(AlterForeignServerStmt, node);
@ -101,6 +102,7 @@ PreprocessGrantOnForeignServerStmt(Node *node, const char *queryString,
EnsureCoordinator(); EnsureCoordinator();
/* the code-path only supports a single object */
Assert(list_length(stmt->objects) == 1); Assert(list_length(stmt->objects) == 1);
char *sql = DeparseTreeNode((Node *) stmt); char *sql = DeparseTreeNode((Node *) stmt);
@ -121,7 +123,7 @@ PreprocessGrantOnForeignServerStmt(Node *node, const char *queryString,
* Never returns NULL, but the objid in the address can be invalid if missingOk * Never returns NULL, but the objid in the address can be invalid if missingOk
* was set to true. * was set to true.
*/ */
ObjectAddress List *
RenameForeignServerStmtObjectAddress(Node *node, bool missing_ok) RenameForeignServerStmtObjectAddress(Node *node, bool missing_ok)
{ {
RenameStmt *stmt = castNode(RenameStmt, node); RenameStmt *stmt = castNode(RenameStmt, node);
@ -139,7 +141,7 @@ RenameForeignServerStmtObjectAddress(Node *node, bool missing_ok)
* Never returns NULL, but the objid in the address can be invalid if missingOk * Never returns NULL, but the objid in the address can be invalid if missingOk
* was set to true. * was set to true.
*/ */
ObjectAddress List *
AlterForeignServerOwnerStmtObjectAddress(Node *node, bool missing_ok) AlterForeignServerOwnerStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
@ -245,9 +247,15 @@ NameListHasDistributedServer(List *serverNames)
String *serverValue = NULL; String *serverValue = NULL;
foreach_ptr(serverValue, serverNames) foreach_ptr(serverValue, serverNames)
{ {
ObjectAddress address = GetObjectAddressByServerName(strVal(serverValue), false); List *addresses = GetObjectAddressByServerName(strVal(serverValue), false);
if (IsObjectDistributed(&address)) /* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
/* We have already asserted that we have exactly 1 address in the addresses. */
ObjectAddress *address = linitial(addresses);
if (IsAnyObjectDistributed(list_make1(address)))
{ {
return true; return true;
} }
@ -257,13 +265,13 @@ NameListHasDistributedServer(List *serverNames)
} }
static ObjectAddress static List *
GetObjectAddressByServerName(char *serverName, bool missing_ok) GetObjectAddressByServerName(char *serverName, bool missing_ok)
{ {
ForeignServer *server = GetForeignServerByName(serverName, missing_ok); ForeignServer *server = GetForeignServerByName(serverName, missing_ok);
Oid serverOid = server->serverid; Oid serverOid = server->serverid;
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, ForeignServerRelationId, serverOid); ObjectAddressSet(*address, ForeignServerRelationId, serverOid);
return address; return list_make1(address);
} }

View File

@ -88,7 +88,7 @@ static void EnsureFunctionCanBeColocatedWithTable(Oid functionOid, Oid
static bool ShouldPropagateCreateFunction(CreateFunctionStmt *stmt); static bool ShouldPropagateCreateFunction(CreateFunctionStmt *stmt);
static bool ShouldPropagateAlterFunction(const ObjectAddress *address); static bool ShouldPropagateAlterFunction(const ObjectAddress *address);
static bool ShouldAddFunctionSignature(FunctionParameterMode mode); static bool ShouldAddFunctionSignature(FunctionParameterMode mode);
static ObjectAddress FunctionToObjectAddress(ObjectType objectType, static List * FunctionToObjectAddress(ObjectType objectType,
ObjectWithArgs *objectWithArgs, ObjectWithArgs *objectWithArgs,
bool missing_ok); bool missing_ok);
static void ErrorIfUnsupportedAlterFunctionStmt(AlterFunctionStmt *stmt); static void ErrorIfUnsupportedAlterFunctionStmt(AlterFunctionStmt *stmt);
@ -128,7 +128,7 @@ create_distributed_function(PG_FUNCTION_ARGS)
text *colocateWithText = NULL; /* optional */ text *colocateWithText = NULL; /* optional */
StringInfoData ddlCommand = { 0 }; StringInfoData ddlCommand = { 0 };
ObjectAddress functionAddress = { 0 }; ObjectAddress *functionAddress = palloc0(sizeof(ObjectAddress));
Oid distributionArgumentOid = InvalidOid; Oid distributionArgumentOid = InvalidOid;
bool colocatedWithReferenceTable = false; bool colocatedWithReferenceTable = false;
@ -203,9 +203,9 @@ create_distributed_function(PG_FUNCTION_ARGS)
EnsureCoordinator(); EnsureCoordinator();
EnsureFunctionOwner(funcOid); EnsureFunctionOwner(funcOid);
ObjectAddressSet(functionAddress, ProcedureRelationId, funcOid); ObjectAddressSet(*functionAddress, ProcedureRelationId, funcOid);
if (RecreateSameNonColocatedFunction(functionAddress, if (RecreateSameNonColocatedFunction(*functionAddress,
distributionArgumentName, distributionArgumentName,
colocateWithTableNameDefault, colocateWithTableNameDefault,
forceDelegationAddress)) forceDelegationAddress))
@ -224,9 +224,10 @@ create_distributed_function(PG_FUNCTION_ARGS)
* pg_dist_object, and not propagate the CREATE FUNCTION. Function * pg_dist_object, and not propagate the CREATE FUNCTION. Function
* will be created by the virtue of the extension creation. * will be created by the virtue of the extension creation.
*/ */
if (IsObjectAddressOwnedByExtension(&functionAddress, &extensionAddress)) if (IsAnyObjectAddressOwnedByExtension(list_make1(functionAddress),
&extensionAddress))
{ {
EnsureExtensionFunctionCanBeDistributed(functionAddress, extensionAddress, EnsureExtensionFunctionCanBeDistributed(*functionAddress, extensionAddress,
distributionArgumentName); distributionArgumentName);
} }
else else
@ -237,7 +238,7 @@ create_distributed_function(PG_FUNCTION_ARGS)
*/ */
EnsureSequentialMode(OBJECT_FUNCTION); EnsureSequentialMode(OBJECT_FUNCTION);
EnsureDependenciesExistOnAllNodes(&functionAddress); EnsureAllObjectDependenciesExistOnAllNodes(list_make1(functionAddress));
const char *createFunctionSQL = GetFunctionDDLCommand(funcOid, true); const char *createFunctionSQL = GetFunctionDDLCommand(funcOid, true);
const char *alterFunctionOwnerSQL = GetFunctionAlterOwnerCommand(funcOid); const char *alterFunctionOwnerSQL = GetFunctionAlterOwnerCommand(funcOid);
@ -257,7 +258,7 @@ create_distributed_function(PG_FUNCTION_ARGS)
ddlCommand.data); ddlCommand.data);
} }
MarkObjectDistributed(&functionAddress); MarkObjectDistributed(functionAddress);
if (distributionArgumentName != NULL) if (distributionArgumentName != NULL)
{ {
@ -272,12 +273,12 @@ create_distributed_function(PG_FUNCTION_ARGS)
distributionArgumentOid, distributionArgumentOid,
colocateWithTableName, colocateWithTableName,
forceDelegationAddress, forceDelegationAddress,
&functionAddress); functionAddress);
} }
else if (!colocatedWithReferenceTable) else if (!colocatedWithReferenceTable)
{ {
DistributeFunctionColocatedWithDistributedTable(funcOid, colocateWithTableName, DistributeFunctionColocatedWithDistributedTable(funcOid, colocateWithTableName,
&functionAddress); functionAddress);
} }
else if (colocatedWithReferenceTable) else if (colocatedWithReferenceTable)
{ {
@ -288,7 +289,7 @@ create_distributed_function(PG_FUNCTION_ARGS)
*/ */
ErrorIfAnyNodeDoesNotHaveMetadata(); ErrorIfAnyNodeDoesNotHaveMetadata();
DistributeFunctionColocatedWithReferenceTable(&functionAddress); DistributeFunctionColocatedWithReferenceTable(functionAddress);
} }
PG_RETURN_VOID(); PG_RETURN_VOID();
@ -1308,7 +1309,7 @@ ShouldPropagateAlterFunction(const ObjectAddress *address)
return false; return false;
} }
if (!IsObjectDistributed(address)) if (!IsAnyObjectDistributed(list_make1((ObjectAddress *) address)))
{ {
/* do not propagate alter function for non-distributed functions */ /* do not propagate alter function for non-distributed functions */
return false; return false;
@ -1373,15 +1374,19 @@ PostprocessCreateFunctionStmt(Node *node, const char *queryString)
return NIL; return NIL;
} }
ObjectAddress functionAddress = GetObjectAddressFromParseTree((Node *) stmt, false); List *functionAddresses = GetObjectAddressListFromParseTree((Node *) stmt, false);
if (IsObjectAddressOwnedByExtension(&functionAddress, NULL)) /* the code-path only supports a single object */
Assert(list_length(functionAddresses) == 1);
if (IsAnyObjectAddressOwnedByExtension(functionAddresses, NULL))
{ {
return NIL; return NIL;
} }
/* If the function has any unsupported dependency, create it locally */ /* If the function has any unsupported dependency, create it locally */
DeferredErrorMessage *errMsg = DeferErrorIfHasUnsupportedDependency(&functionAddress); DeferredErrorMessage *errMsg = DeferErrorIfAnyObjectHasUnsupportedDependency(
functionAddresses);
if (errMsg != NULL) if (errMsg != NULL)
{ {
@ -1389,11 +1394,14 @@ PostprocessCreateFunctionStmt(Node *node, const char *queryString)
return NIL; return NIL;
} }
EnsureDependenciesExistOnAllNodes(&functionAddress); EnsureAllObjectDependenciesExistOnAllNodes(functionAddresses);
/* We have already asserted that we have exactly 1 address in the addresses. */
ObjectAddress *functionAddress = linitial(functionAddresses);
List *commands = list_make1(DISABLE_DDL_PROPAGATION); List *commands = list_make1(DISABLE_DDL_PROPAGATION);
commands = list_concat(commands, CreateFunctionDDLCommandsIdempotent( commands = list_concat(commands, CreateFunctionDDLCommandsIdempotent(
&functionAddress)); functionAddress));
commands = list_concat(commands, list_make1(ENABLE_DDL_PROPAGATION)); commands = list_concat(commands, list_make1(ENABLE_DDL_PROPAGATION));
return NodeDDLTaskList(NON_COORDINATOR_NODES, commands); return NodeDDLTaskList(NON_COORDINATOR_NODES, commands);
@ -1405,7 +1413,7 @@ PostprocessCreateFunctionStmt(Node *node, const char *queryString)
* CREATE [OR REPLACE] FUNCTION statement. If missing_ok is false it will error with the * CREATE [OR REPLACE] FUNCTION statement. If missing_ok is false it will error with the
* normal postgres error for unfound functions. * normal postgres error for unfound functions.
*/ */
ObjectAddress List *
CreateFunctionStmtObjectAddress(Node *node, bool missing_ok) CreateFunctionStmtObjectAddress(Node *node, bool missing_ok)
{ {
CreateFunctionStmt *stmt = castNode(CreateFunctionStmt, node); CreateFunctionStmt *stmt = castNode(CreateFunctionStmt, node);
@ -1440,7 +1448,7 @@ CreateFunctionStmtObjectAddress(Node *node, bool missing_ok)
* *
* objectId in the address can be invalid if missing_ok was set to true. * objectId in the address can be invalid if missing_ok was set to true.
*/ */
ObjectAddress List *
DefineAggregateStmtObjectAddress(Node *node, bool missing_ok) DefineAggregateStmtObjectAddress(Node *node, bool missing_ok)
{ {
DefineStmt *stmt = castNode(DefineStmt, node); DefineStmt *stmt = castNode(DefineStmt, node);
@ -1494,8 +1502,15 @@ PreprocessAlterFunctionStmt(Node *node, const char *queryString,
AlterFunctionStmt *stmt = castNode(AlterFunctionStmt, node); AlterFunctionStmt *stmt = castNode(AlterFunctionStmt, node);
AssertObjectTypeIsFunctional(stmt->objtype); AssertObjectTypeIsFunctional(stmt->objtype);
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, false); List *addresses = GetObjectAddressListFromParseTree((Node *) stmt, false);
if (!ShouldPropagateAlterFunction(&address))
/* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
/* We have already asserted that we have exactly 1 address in the addresses. */
ObjectAddress *address = linitial(addresses);
if (!ShouldPropagateAlterFunction(address))
{ {
return NIL; return NIL;
} }
@ -1549,20 +1564,26 @@ PreprocessAlterFunctionDependsStmt(Node *node, const char *queryString,
return NIL; return NIL;
} }
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, true); List *addresses = GetObjectAddressListFromParseTree((Node *) stmt, true);
if (!IsObjectDistributed(&address))
/* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
if (!IsAnyObjectDistributed(addresses))
{ {
return NIL; return NIL;
} }
/* We have already asserted that we have exactly 1 address in the addresses. */
ObjectAddress *address = linitial(addresses);
/* /*
* Distributed objects should not start depending on an extension, this will break * Distributed objects should not start depending on an extension, this will break
* the dependency resolving mechanism we use to replicate distributed objects to new * the dependency resolving mechanism we use to replicate distributed objects to new
* workers * workers
*/ */
const char *functionName = const char *functionName =
getObjectIdentity_compat(&address, /* missingOk: */ false); getObjectIdentity_compat(address, /* missingOk: */ false);
ereport(ERROR, (errmsg("distrtibuted functions are not allowed to depend on an " ereport(ERROR, (errmsg("distrtibuted functions are not allowed to depend on an "
"extension"), "extension"),
errdetail("Function \"%s\" is already distributed. Functions from " errdetail("Function \"%s\" is already distributed. Functions from "
@ -1576,7 +1597,7 @@ PreprocessAlterFunctionDependsStmt(Node *node, const char *queryString,
* is the subject of an ALTER FUNCTION ... DEPENS ON EXTENSION ... statement. If * is the subject of an ALTER FUNCTION ... DEPENS ON EXTENSION ... statement. If
* missing_ok is set to false the lookup will raise an error. * missing_ok is set to false the lookup will raise an error.
*/ */
ObjectAddress List *
AlterFunctionDependsStmtObjectAddress(Node *node, bool missing_ok) AlterFunctionDependsStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterObjectDependsStmt *stmt = castNode(AlterObjectDependsStmt, node); AlterObjectDependsStmt *stmt = castNode(AlterObjectDependsStmt, node);
@ -1592,7 +1613,7 @@ AlterFunctionDependsStmtObjectAddress(Node *node, bool missing_ok)
* AlterFunctionStmt. If missing_ok is set to false an error will be raised if postgres * AlterFunctionStmt. If missing_ok is set to false an error will be raised if postgres
* was unable to find the function/procedure that was the target of the statement. * was unable to find the function/procedure that was the target of the statement.
*/ */
ObjectAddress List *
AlterFunctionStmtObjectAddress(Node *node, bool missing_ok) AlterFunctionStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterFunctionStmt *stmt = castNode(AlterFunctionStmt, node); AlterFunctionStmt *stmt = castNode(AlterFunctionStmt, node);
@ -1604,7 +1625,7 @@ AlterFunctionStmtObjectAddress(Node *node, bool missing_ok)
* RenameFunctionStmtObjectAddress returns the ObjectAddress of the function that is the * RenameFunctionStmtObjectAddress returns the ObjectAddress of the function that is the
* subject of the RenameStmt. Errors if missing_ok is false. * subject of the RenameStmt. Errors if missing_ok is false.
*/ */
ObjectAddress List *
RenameFunctionStmtObjectAddress(Node *node, bool missing_ok) RenameFunctionStmtObjectAddress(Node *node, bool missing_ok)
{ {
RenameStmt *stmt = castNode(RenameStmt, node); RenameStmt *stmt = castNode(RenameStmt, node);
@ -1617,7 +1638,7 @@ RenameFunctionStmtObjectAddress(Node *node, bool missing_ok)
* AlterFunctionOwnerObjectAddress returns the ObjectAddress of the function that is the * AlterFunctionOwnerObjectAddress returns the ObjectAddress of the function that is the
* subject of the AlterOwnerStmt. Errors if missing_ok is false. * subject of the AlterOwnerStmt. Errors if missing_ok is false.
*/ */
ObjectAddress List *
AlterFunctionOwnerObjectAddress(Node *node, bool missing_ok) AlterFunctionOwnerObjectAddress(Node *node, bool missing_ok)
{ {
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
@ -1635,7 +1656,7 @@ AlterFunctionOwnerObjectAddress(Node *node, bool missing_ok)
* the new schema. Errors if missing_ok is false and the type cannot be found in either of * the new schema. Errors if missing_ok is false and the type cannot be found in either of
* the schemas. * the schemas.
*/ */
ObjectAddress List *
AlterFunctionSchemaStmtObjectAddress(Node *node, bool missing_ok) AlterFunctionSchemaStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
@ -1680,10 +1701,10 @@ AlterFunctionSchemaStmtObjectAddress(Node *node, bool missing_ok)
} }
} }
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, ProcedureRelationId, funcOid); ObjectAddressSet(*address, ProcedureRelationId, funcOid);
return address; return list_make1(address);
} }
@ -1827,17 +1848,17 @@ ShouldAddFunctionSignature(FunctionParameterMode mode)
* Function/Procedure/Aggregate. If missing_ok is set to false an error will be * Function/Procedure/Aggregate. If missing_ok is set to false an error will be
* raised by postgres explaining the Function/Procedure could not be found. * raised by postgres explaining the Function/Procedure could not be found.
*/ */
static ObjectAddress static List *
FunctionToObjectAddress(ObjectType objectType, ObjectWithArgs *objectWithArgs, FunctionToObjectAddress(ObjectType objectType, ObjectWithArgs *objectWithArgs,
bool missing_ok) bool missing_ok)
{ {
AssertObjectTypeIsFunctional(objectType); AssertObjectTypeIsFunctional(objectType);
Oid funcOid = LookupFuncWithArgs(objectType, objectWithArgs, missing_ok); Oid funcOid = LookupFuncWithArgs(objectType, objectWithArgs, missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, ProcedureRelationId, funcOid); ObjectAddressSet(*address, ProcedureRelationId, funcOid);
return address; return list_make1(address);
} }
@ -1920,7 +1941,7 @@ EnsureExtensionFunctionCanBeDistributed(const ObjectAddress functionAddress,
/* /*
* Ensure corresponding extension is in pg_dist_object. * Ensure corresponding extension is in pg_dist_object.
* Functions owned by an extension are depending internally on that extension, * Functions owned by an extension are depending internally on that extension,
* hence EnsureDependenciesExistOnAllNodes() creates the extension, which in * hence EnsureAllObjectDependenciesExistOnAllNodes() creates the extension, which in
* turn creates the function, and thus we don't have to create it ourself like * turn creates the function, and thus we don't have to create it ourself like
* we do for non-extension functions. * we do for non-extension functions.
*/ */
@ -1930,7 +1951,9 @@ EnsureExtensionFunctionCanBeDistributed(const ObjectAddress functionAddress,
get_extension_name(extensionAddress.objectId), get_extension_name(extensionAddress.objectId),
get_func_name(functionAddress.objectId)))); get_func_name(functionAddress.objectId))));
EnsureDependenciesExistOnAllNodes(&functionAddress); ObjectAddress *copyFunctionAddress = palloc0(sizeof(ObjectAddress));
*copyFunctionAddress = functionAddress;
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(copyFunctionAddress));
} }
@ -2004,7 +2027,7 @@ PostprocessGrantOnFunctionStmt(Node *node, const char *queryString)
ObjectAddress *functionAddress = NULL; ObjectAddress *functionAddress = NULL;
foreach_ptr(functionAddress, distributedFunctions) foreach_ptr(functionAddress, distributedFunctions)
{ {
EnsureDependenciesExistOnAllNodes(functionAddress); EnsureAllObjectDependenciesExistOnAllNodes(list_make1(functionAddress));
} }
return NIL; return NIL;
} }
@ -2083,7 +2106,7 @@ FilterDistributedFunctions(GrantStmt *grantStmt)
* if this function from GRANT .. ON FUNCTION .. is a distributed * if this function from GRANT .. ON FUNCTION .. is a distributed
* function, add it to the list * function, add it to the list
*/ */
if (IsObjectDistributed(functionAddress)) if (IsAnyObjectDistributed(list_make1(functionAddress)))
{ {
grantFunctionList = lappend(grantFunctionList, functionAddress); grantFunctionList = lappend(grantFunctionList, functionAddress);
} }

View File

@ -238,9 +238,9 @@ CollectGrantTableIdList(GrantStmt *grantStmt)
} }
/* check for distributed sequences included in GRANT ON TABLE statement */ /* check for distributed sequences included in GRANT ON TABLE statement */
ObjectAddress sequenceAddress = { 0 }; ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(sequenceAddress, RelationRelationId, relationId); ObjectAddressSet(*sequenceAddress, RelationRelationId, relationId);
if (IsObjectDistributed(&sequenceAddress)) if (IsAnyObjectDistributed(list_make1(sequenceAddress)))
{ {
grantTableList = lappend_oid(grantTableList, relationId); grantTableList = lappend_oid(grantTableList, relationId);
} }

View File

@ -761,9 +761,9 @@ PostprocessIndexStmt(Node *node, const char *queryString)
Oid indexRelationId = get_relname_relid(indexStmt->idxname, schemaId); Oid indexRelationId = get_relname_relid(indexStmt->idxname, schemaId);
/* ensure dependencies of index exist on all nodes */ /* ensure dependencies of index exist on all nodes */
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, RelationRelationId, indexRelationId); ObjectAddressSet(*address, RelationRelationId, indexRelationId);
EnsureDependenciesExistOnAllNodes(&address); EnsureAllObjectDependenciesExistOnAllNodes(list_make1(address));
/* furtheron we are only processing CONCURRENT index statements */ /* furtheron we are only processing CONCURRENT index statements */
if (!indexStmt->concurrent) if (!indexStmt->concurrent)
@ -772,7 +772,7 @@ PostprocessIndexStmt(Node *node, const char *queryString)
} }
/* /*
* EnsureDependenciesExistOnAllNodes could have distributed objects that are required * EnsureAllObjectDependenciesExistOnAllNodes could have distributed objects that are required
* by this index. During the propagation process an active snapshout might be left as * by this index. During the propagation process an active snapshout might be left as
* a side effect of inserting the local tuples via SPI. To not leak a snapshot like * a side effect of inserting the local tuples via SPI. To not leak a snapshot like
* that we will pop any snapshot if we have any right before we commit. * that we will pop any snapshot if we have any right before we commit.

View File

@ -74,7 +74,7 @@ static Node * makeFloatConst(char *str, int location);
static const char * WrapQueryInAlterRoleIfExistsCall(const char *query, RoleSpec *role); static const char * WrapQueryInAlterRoleIfExistsCall(const char *query, RoleSpec *role);
static VariableSetStmt * MakeVariableSetStmt(const char *config); static VariableSetStmt * MakeVariableSetStmt(const char *config);
static int ConfigGenericNameCompare(const void *lhs, const void *rhs); static int ConfigGenericNameCompare(const void *lhs, const void *rhs);
static ObjectAddress RoleSpecToObjectAddress(RoleSpec *role, bool missing_ok); static List * RoleSpecToObjectAddress(RoleSpec *role, bool missing_ok);
/* controlled via GUC */ /* controlled via GUC */
bool EnableCreateRolePropagation = true; bool EnableCreateRolePropagation = true;
@ -87,7 +87,7 @@ bool EnableAlterRoleSetPropagation = true;
* AlterRoleStmt. If missing_ok is set to false an error will be raised if postgres * AlterRoleStmt. If missing_ok is set to false an error will be raised if postgres
* was unable to find the role that was the target of the statement. * was unable to find the role that was the target of the statement.
*/ */
ObjectAddress List *
AlterRoleStmtObjectAddress(Node *node, bool missing_ok) AlterRoleStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterRoleStmt *stmt = castNode(AlterRoleStmt, node); AlterRoleStmt *stmt = castNode(AlterRoleStmt, node);
@ -100,7 +100,7 @@ AlterRoleStmtObjectAddress(Node *node, bool missing_ok)
* AlterRoleSetStmt. If missing_ok is set to false an error will be raised if postgres * AlterRoleSetStmt. If missing_ok is set to false an error will be raised if postgres
* was unable to find the role that was the target of the statement. * was unable to find the role that was the target of the statement.
*/ */
ObjectAddress List *
AlterRoleSetStmtObjectAddress(Node *node, bool missing_ok) AlterRoleSetStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterRoleSetStmt *stmt = castNode(AlterRoleSetStmt, node); AlterRoleSetStmt *stmt = castNode(AlterRoleSetStmt, node);
@ -113,19 +113,19 @@ AlterRoleSetStmtObjectAddress(Node *node, bool missing_ok)
* RoleSpec. If missing_ok is set to false an error will be raised by postgres * RoleSpec. If missing_ok is set to false an error will be raised by postgres
* explaining the Role could not be found. * explaining the Role could not be found.
*/ */
static ObjectAddress static List *
RoleSpecToObjectAddress(RoleSpec *role, bool missing_ok) RoleSpecToObjectAddress(RoleSpec *role, bool missing_ok)
{ {
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
if (role != NULL) if (role != NULL)
{ {
/* roles can be NULL for statements on ALL roles eg. ALTER ROLE ALL SET ... */ /* roles can be NULL for statements on ALL roles eg. ALTER ROLE ALL SET ... */
Oid roleOid = get_rolespec_oid(role, missing_ok); Oid roleOid = get_rolespec_oid(role, missing_ok);
ObjectAddressSet(address, AuthIdRelationId, roleOid); ObjectAddressSet(*address, AuthIdRelationId, roleOid);
} }
return address; return list_make1(address);
} }
@ -137,8 +137,12 @@ RoleSpecToObjectAddress(RoleSpec *role, bool missing_ok)
List * List *
PostprocessAlterRoleStmt(Node *node, const char *queryString) PostprocessAlterRoleStmt(Node *node, const char *queryString)
{ {
ObjectAddress address = GetObjectAddressFromParseTree(node, false); List *addresses = GetObjectAddressListFromParseTree(node, false);
if (!ShouldPropagateObject(&address))
/* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
if (!ShouldPropagateAnyObject(addresses))
{ {
return NIL; return NIL;
} }
@ -208,14 +212,17 @@ PreprocessAlterRoleSetStmt(Node *node, const char *queryString,
return NIL; return NIL;
} }
ObjectAddress address = GetObjectAddressFromParseTree(node, false); List *addresses = GetObjectAddressListFromParseTree(node, false);
/* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
/* /*
* stmt->role could be NULL when the statement is on 'ALL' roles, we do propagate for * stmt->role could be NULL when the statement is on 'ALL' roles, we do propagate for
* ALL roles. If it is not NULL the role is for a specific role. If that role is not * ALL roles. If it is not NULL the role is for a specific role. If that role is not
* distributed we will not propagate the statement * distributed we will not propagate the statement
*/ */
if (stmt->role != NULL && !IsObjectDistributed(&address)) if (stmt->role != NULL && !IsAnyObjectDistributed(addresses))
{ {
return NIL; return NIL;
} }
@ -1056,7 +1063,6 @@ FilterDistributedRoles(List *roles)
foreach_ptr(roleNode, roles) foreach_ptr(roleNode, roles)
{ {
RoleSpec *role = castNode(RoleSpec, roleNode); RoleSpec *role = castNode(RoleSpec, roleNode);
ObjectAddress roleAddress = { 0 };
Oid roleOid = get_rolespec_oid(role, true); Oid roleOid = get_rolespec_oid(role, true);
if (roleOid == InvalidOid) if (roleOid == InvalidOid)
{ {
@ -1066,8 +1072,9 @@ FilterDistributedRoles(List *roles)
*/ */
continue; continue;
} }
ObjectAddressSet(roleAddress, AuthIdRelationId, roleOid); ObjectAddress *roleAddress = palloc0(sizeof(ObjectAddress));
if (IsObjectDistributed(&roleAddress)) ObjectAddressSet(*roleAddress, AuthIdRelationId, roleOid);
if (IsAnyObjectDistributed(list_make1(roleAddress)))
{ {
distributedRoles = lappend(distributedRoles, role); distributedRoles = lappend(distributedRoles, role);
} }
@ -1137,12 +1144,13 @@ PostprocessGrantRoleStmt(Node *node, const char *queryString)
RoleSpec *role = NULL; RoleSpec *role = NULL;
foreach_ptr(role, stmt->grantee_roles) foreach_ptr(role, stmt->grantee_roles)
{ {
ObjectAddress roleAddress = { 0 };
Oid roleOid = get_rolespec_oid(role, false); Oid roleOid = get_rolespec_oid(role, false);
ObjectAddressSet(roleAddress, AuthIdRelationId, roleOid); ObjectAddress *roleAddress = palloc0(sizeof(ObjectAddress));
if (IsObjectDistributed(&roleAddress)) ObjectAddressSet(*roleAddress, AuthIdRelationId, roleOid);
if (IsAnyObjectDistributed(list_make1(roleAddress)))
{ {
EnsureDependenciesExistOnAllNodes(&roleAddress); EnsureAllObjectDependenciesExistOnAllNodes(list_make1(roleAddress));
} }
} }
return NIL; return NIL;
@ -1179,15 +1187,15 @@ ConfigGenericNameCompare(const void *a, const void *b)
* Never returns NULL, but the objid in the address could be invalid if missing_ok was set * Never returns NULL, but the objid in the address could be invalid if missing_ok was set
* to true. * to true.
*/ */
ObjectAddress List *
CreateRoleStmtObjectAddress(Node *node, bool missing_ok) CreateRoleStmtObjectAddress(Node *node, bool missing_ok)
{ {
CreateRoleStmt *stmt = castNode(CreateRoleStmt, node); CreateRoleStmt *stmt = castNode(CreateRoleStmt, node);
Oid roleOid = get_role_oid(stmt->role, missing_ok); Oid roleOid = get_role_oid(stmt->role, missing_ok);
ObjectAddress roleAddress = { 0 }; ObjectAddress *roleAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(roleAddress, AuthIdRelationId, roleOid); ObjectAddressSet(*roleAddress, AuthIdRelationId, roleOid);
return roleAddress; return list_make1(roleAddress);
} }

View File

@ -40,7 +40,7 @@
#include "utils/relcache.h" #include "utils/relcache.h"
static ObjectAddress GetObjectAddressBySchemaName(char *schemaName, bool missing_ok); static List * GetObjectAddressBySchemaName(char *schemaName, bool missing_ok);
static List * FilterDistributedSchemas(List *schemas); static List * FilterDistributedSchemas(List *schemas);
static bool SchemaHasDistributedTableWithFKey(char *schemaName); static bool SchemaHasDistributedTableWithFKey(char *schemaName);
static bool ShouldPropagateCreateSchemaStmt(void); static bool ShouldPropagateCreateSchemaStmt(void);
@ -183,7 +183,7 @@ PreprocessGrantOnSchemaStmt(Node *node, const char *queryString,
* CreateSchemaStmtObjectAddress returns the ObjectAddress of the schema that is * CreateSchemaStmtObjectAddress returns the ObjectAddress of the schema that is
* the object of the CreateSchemaStmt. Errors if missing_ok is false. * the object of the CreateSchemaStmt. Errors if missing_ok is false.
*/ */
ObjectAddress List *
CreateSchemaStmtObjectAddress(Node *node, bool missing_ok) CreateSchemaStmtObjectAddress(Node *node, bool missing_ok)
{ {
CreateSchemaStmt *stmt = castNode(CreateSchemaStmt, node); CreateSchemaStmt *stmt = castNode(CreateSchemaStmt, node);
@ -213,7 +213,7 @@ CreateSchemaStmtObjectAddress(Node *node, bool missing_ok)
* AlterSchemaRenameStmtObjectAddress returns the ObjectAddress of the schema that is * AlterSchemaRenameStmtObjectAddress returns the ObjectAddress of the schema that is
* the object of the RenameStmt. Errors if missing_ok is false. * the object of the RenameStmt. Errors if missing_ok is false.
*/ */
ObjectAddress List *
AlterSchemaRenameStmtObjectAddress(Node *node, bool missing_ok) AlterSchemaRenameStmtObjectAddress(Node *node, bool missing_ok)
{ {
RenameStmt *stmt = castNode(RenameStmt, node); RenameStmt *stmt = castNode(RenameStmt, node);
@ -227,15 +227,15 @@ AlterSchemaRenameStmtObjectAddress(Node *node, bool missing_ok)
* GetObjectAddressBySchemaName returns the ObjectAddress of the schema with the * GetObjectAddressBySchemaName returns the ObjectAddress of the schema with the
* given name. Errors out if schema is not found and missing_ok is false. * given name. Errors out if schema is not found and missing_ok is false.
*/ */
ObjectAddress List *
GetObjectAddressBySchemaName(char *schemaName, bool missing_ok) GetObjectAddressBySchemaName(char *schemaName, bool missing_ok)
{ {
Oid schemaOid = get_namespace_oid(schemaName, missing_ok); Oid schemaOid = get_namespace_oid(schemaName, missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, NamespaceRelationId, schemaOid); ObjectAddressSet(*address, NamespaceRelationId, schemaOid);
return address; return list_make1(address);
} }
@ -259,10 +259,9 @@ FilterDistributedSchemas(List *schemas)
continue; continue;
} }
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, NamespaceRelationId, schemaOid); ObjectAddressSet(*address, NamespaceRelationId, schemaOid);
if (!IsAnyObjectDistributed(list_make1(address)))
if (!IsObjectDistributed(&address))
{ {
continue; continue;
} }

View File

@ -268,18 +268,16 @@ PreprocessDropSequenceStmt(Node *node, const char *queryString,
Oid seqOid = RangeVarGetRelid(seq, NoLock, stmt->missing_ok); Oid seqOid = RangeVarGetRelid(seq, NoLock, stmt->missing_ok);
ObjectAddress sequenceAddress = { 0 }; ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(sequenceAddress, RelationRelationId, seqOid); ObjectAddressSet(*sequenceAddress, RelationRelationId, seqOid);
if (!IsAnyObjectDistributed(list_make1(sequenceAddress)))
if (!IsObjectDistributed(&sequenceAddress))
{ {
continue; continue;
} }
/* collect information for all distributed sequences */ /* collect information for all distributed sequences */
ObjectAddress *addressp = palloc(sizeof(ObjectAddress)); distributedSequenceAddresses = lappend(distributedSequenceAddresses,
*addressp = sequenceAddress; sequenceAddress);
distributedSequenceAddresses = lappend(distributedSequenceAddresses, addressp);
distributedSequencesList = lappend(distributedSequencesList, objectNameList); distributedSequencesList = lappend(distributedSequencesList, objectNameList);
} }
@ -334,10 +332,13 @@ PreprocessRenameSequenceStmt(Node *node, const char *queryString, ProcessUtility
RenameStmt *stmt = castNode(RenameStmt, node); RenameStmt *stmt = castNode(RenameStmt, node);
Assert(stmt->renameType == OBJECT_SEQUENCE); Assert(stmt->renameType == OBJECT_SEQUENCE);
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, List *addresses = GetObjectAddressListFromParseTree((Node *) stmt,
stmt->missing_ok); stmt->missing_ok);
if (!ShouldPropagateObject(&address)) /* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
if (!ShouldPropagateAnyObject(addresses))
{ {
return NIL; return NIL;
} }
@ -358,7 +359,7 @@ PreprocessRenameSequenceStmt(Node *node, const char *queryString, ProcessUtility
* RenameSequenceStmtObjectAddress returns the ObjectAddress of the sequence that is the * RenameSequenceStmtObjectAddress returns the ObjectAddress of the sequence that is the
* subject of the RenameStmt. * subject of the RenameStmt.
*/ */
ObjectAddress List *
RenameSequenceStmtObjectAddress(Node *node, bool missing_ok) RenameSequenceStmtObjectAddress(Node *node, bool missing_ok)
{ {
RenameStmt *stmt = castNode(RenameStmt, node); RenameStmt *stmt = castNode(RenameStmt, node);
@ -366,10 +367,10 @@ RenameSequenceStmtObjectAddress(Node *node, bool missing_ok)
RangeVar *sequence = stmt->relation; RangeVar *sequence = stmt->relation;
Oid seqOid = RangeVarGetRelid(sequence, NoLock, missing_ok); Oid seqOid = RangeVarGetRelid(sequence, NoLock, missing_ok);
ObjectAddress sequenceAddress = { 0 }; ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(sequenceAddress, RelationRelationId, seqOid); ObjectAddressSet(*sequenceAddress, RelationRelationId, seqOid);
return sequenceAddress; return list_make1(sequenceAddress);
} }
@ -395,21 +396,27 @@ PreprocessAlterSequenceStmt(Node *node, const char *queryString,
{ {
AlterSeqStmt *stmt = castNode(AlterSeqStmt, node); AlterSeqStmt *stmt = castNode(AlterSeqStmt, node);
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, List *addresses = GetObjectAddressListFromParseTree((Node *) stmt,
stmt->missing_ok); stmt->missing_ok);
/* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
/* error out if the sequence is distributed */ /* error out if the sequence is distributed */
if (IsObjectDistributed(&address)) if (IsAnyObjectDistributed(addresses))
{ {
ereport(ERROR, (errmsg( ereport(ERROR, (errmsg(
"Altering a distributed sequence is currently not supported."))); "Altering a distributed sequence is currently not supported.")));
} }
/* We have already asserted that we have exactly 1 address in the addresses. */
ObjectAddress *address = linitial(addresses);
/* /*
* error out if the sequence is used in a distributed table * error out if the sequence is used in a distributed table
* and this is an ALTER SEQUENCE .. AS .. statement * and this is an ALTER SEQUENCE .. AS .. statement
*/ */
Oid citusTableId = SequenceUsedInDistributedTable(&address); Oid citusTableId = SequenceUsedInDistributedTable(address);
if (citusTableId != InvalidOid) if (citusTableId != InvalidOid)
{ {
List *options = stmt->options; List *options = stmt->options;
@ -463,6 +470,7 @@ SequenceUsedInDistributedTable(const ObjectAddress *sequenceAddress)
} }
} }
} }
return InvalidOid; return InvalidOid;
} }
@ -471,17 +479,17 @@ SequenceUsedInDistributedTable(const ObjectAddress *sequenceAddress)
* AlterSequenceStmtObjectAddress returns the ObjectAddress of the sequence that is the * AlterSequenceStmtObjectAddress returns the ObjectAddress of the sequence that is the
* subject of the AlterSeqStmt. * subject of the AlterSeqStmt.
*/ */
ObjectAddress List *
AlterSequenceStmtObjectAddress(Node *node, bool missing_ok) AlterSequenceStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterSeqStmt *stmt = castNode(AlterSeqStmt, node); AlterSeqStmt *stmt = castNode(AlterSeqStmt, node);
RangeVar *sequence = stmt->sequence; RangeVar *sequence = stmt->sequence;
Oid seqOid = RangeVarGetRelid(sequence, NoLock, stmt->missing_ok); Oid seqOid = RangeVarGetRelid(sequence, NoLock, stmt->missing_ok);
ObjectAddress sequenceAddress = { 0 }; ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(sequenceAddress, RelationRelationId, seqOid); ObjectAddressSet(*sequenceAddress, RelationRelationId, seqOid);
return sequenceAddress; return list_make1(sequenceAddress);
} }
@ -498,9 +506,13 @@ PreprocessAlterSequenceSchemaStmt(Node *node, const char *queryString,
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
Assert(stmt->objectType == OBJECT_SEQUENCE); Assert(stmt->objectType == OBJECT_SEQUENCE);
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, List *addresses = GetObjectAddressListFromParseTree((Node *) stmt,
stmt->missing_ok); stmt->missing_ok);
if (!ShouldPropagateObject(&address))
/* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
if (!ShouldPropagateAnyObject(addresses))
{ {
return NIL; return NIL;
} }
@ -521,7 +533,7 @@ PreprocessAlterSequenceSchemaStmt(Node *node, const char *queryString,
* AlterSequenceSchemaStmtObjectAddress returns the ObjectAddress of the sequence that is * AlterSequenceSchemaStmtObjectAddress returns the ObjectAddress of the sequence that is
* the subject of the AlterObjectSchemaStmt. * the subject of the AlterObjectSchemaStmt.
*/ */
ObjectAddress List *
AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok) AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
@ -555,10 +567,10 @@ AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok)
} }
} }
ObjectAddress sequenceAddress = { 0 }; ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(sequenceAddress, RelationRelationId, seqOid); ObjectAddressSet(*sequenceAddress, RelationRelationId, seqOid);
return sequenceAddress; return list_make1(sequenceAddress);
} }
@ -572,16 +584,19 @@ PostprocessAlterSequenceSchemaStmt(Node *node, const char *queryString)
{ {
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
Assert(stmt->objectType == OBJECT_SEQUENCE); Assert(stmt->objectType == OBJECT_SEQUENCE);
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, List *addresses = GetObjectAddressListFromParseTree((Node *) stmt,
stmt->missing_ok); stmt->missing_ok);
if (!ShouldPropagateObject(&address)) /* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
if (!ShouldPropagateAnyObject(addresses))
{ {
return NIL; return NIL;
} }
/* dependencies have changed (schema) let's ensure they exist */ /* dependencies have changed (schema) let's ensure they exist */
EnsureDependenciesExistOnAllNodes(&address); EnsureAllObjectDependenciesExistOnAllNodes(addresses);
return NIL; return NIL;
} }
@ -601,8 +616,12 @@ PreprocessAlterSequenceOwnerStmt(Node *node, const char *queryString,
AlterTableStmt *stmt = castNode(AlterTableStmt, node); AlterTableStmt *stmt = castNode(AlterTableStmt, node);
Assert(AlterTableStmtObjType_compat(stmt) == OBJECT_SEQUENCE); Assert(AlterTableStmtObjType_compat(stmt) == OBJECT_SEQUENCE);
ObjectAddress sequenceAddress = GetObjectAddressFromParseTree((Node *) stmt, false); List *sequenceAddresses = GetObjectAddressListFromParseTree((Node *) stmt, false);
if (!ShouldPropagateObject(&sequenceAddress))
/* the code-path only supports a single object */
Assert(list_length(sequenceAddresses) == 1);
if (!ShouldPropagateAnyObject(sequenceAddresses))
{ {
return NIL; return NIL;
} }
@ -623,7 +642,7 @@ PreprocessAlterSequenceOwnerStmt(Node *node, const char *queryString,
* AlterSequenceOwnerStmtObjectAddress returns the ObjectAddress of the sequence that is the * AlterSequenceOwnerStmtObjectAddress returns the ObjectAddress of the sequence that is the
* subject of the AlterOwnerStmt. * subject of the AlterOwnerStmt.
*/ */
ObjectAddress List *
AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok) AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterTableStmt *stmt = castNode(AlterTableStmt, node); AlterTableStmt *stmt = castNode(AlterTableStmt, node);
@ -631,10 +650,10 @@ AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok)
RangeVar *sequence = stmt->relation; RangeVar *sequence = stmt->relation;
Oid seqOid = RangeVarGetRelid(sequence, NoLock, missing_ok); Oid seqOid = RangeVarGetRelid(sequence, NoLock, missing_ok);
ObjectAddress sequenceAddress = { 0 }; ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(sequenceAddress, RelationRelationId, seqOid); ObjectAddressSet(*sequenceAddress, RelationRelationId, seqOid);
return sequenceAddress; return list_make1(sequenceAddress);
} }
@ -649,14 +668,18 @@ PostprocessAlterSequenceOwnerStmt(Node *node, const char *queryString)
AlterTableStmt *stmt = castNode(AlterTableStmt, node); AlterTableStmt *stmt = castNode(AlterTableStmt, node);
Assert(AlterTableStmtObjType_compat(stmt) == OBJECT_SEQUENCE); Assert(AlterTableStmtObjType_compat(stmt) == OBJECT_SEQUENCE);
ObjectAddress sequenceAddress = GetObjectAddressFromParseTree((Node *) stmt, false); List *sequenceAddresses = GetObjectAddressListFromParseTree((Node *) stmt, false);
if (!ShouldPropagateObject(&sequenceAddress))
/* the code-path only supports a single object */
Assert(list_length(sequenceAddresses) == 1);
if (!ShouldPropagateAnyObject(sequenceAddresses))
{ {
return NIL; return NIL;
} }
/* dependencies have changed (owner) let's ensure they exist */ /* dependencies have changed (owner) let's ensure they exist */
EnsureDependenciesExistOnAllNodes(&sequenceAddress); EnsureAllObjectDependenciesExistOnAllNodes(sequenceAddresses);
return NIL; return NIL;
} }
@ -744,10 +767,10 @@ PostprocessGrantOnSequenceStmt(Node *node, const char *queryString)
RangeVar *sequence = NULL; RangeVar *sequence = NULL;
foreach_ptr(sequence, distributedSequences) foreach_ptr(sequence, distributedSequences)
{ {
ObjectAddress sequenceAddress = { 0 }; ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
Oid sequenceOid = RangeVarGetRelid(sequence, NoLock, false); Oid sequenceOid = RangeVarGetRelid(sequence, NoLock, false);
ObjectAddressSet(sequenceAddress, RelationRelationId, sequenceOid); ObjectAddressSet(*sequenceAddress, RelationRelationId, sequenceOid);
EnsureDependenciesExistOnAllNodes(&sequenceAddress); EnsureAllObjectDependenciesExistOnAllNodes(list_make1(sequenceAddress));
} }
return NIL; return NIL;
} }
@ -866,15 +889,15 @@ FilterDistributedSequences(GrantStmt *stmt)
RangeVar *sequenceRangeVar = NULL; RangeVar *sequenceRangeVar = NULL;
foreach_ptr(sequenceRangeVar, stmt->objects) foreach_ptr(sequenceRangeVar, stmt->objects)
{ {
ObjectAddress sequenceAddress = { 0 };
Oid sequenceOid = RangeVarGetRelid(sequenceRangeVar, NoLock, missing_ok); Oid sequenceOid = RangeVarGetRelid(sequenceRangeVar, NoLock, missing_ok);
ObjectAddressSet(sequenceAddress, RelationRelationId, sequenceOid); ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*sequenceAddress, RelationRelationId, sequenceOid);
/* /*
* if this sequence from GRANT .. ON SEQUENCE .. is a distributed * if this sequence from GRANT .. ON SEQUENCE .. is a distributed
* sequence, add it to the list * sequence, add it to the list
*/ */
if (IsObjectDistributed(&sequenceAddress)) if (IsAnyObjectDistributed(list_make1(sequenceAddress)))
{ {
grantSequenceList = lappend(grantSequenceList, sequenceRangeVar); grantSequenceList = lappend(grantSequenceList, sequenceRangeVar);
} }

View File

@ -122,9 +122,12 @@ PostprocessCreateStatisticsStmt(Node *node, const char *queryString)
} }
bool missingOk = false; bool missingOk = false;
ObjectAddress objectAddress = GetObjectAddressFromParseTree((Node *) stmt, missingOk); List *objectAddresses = GetObjectAddressListFromParseTree((Node *) stmt, missingOk);
EnsureDependenciesExistOnAllNodes(&objectAddress); /* the code-path only supports a single object */
Assert(list_length(objectAddresses) == 1);
EnsureAllObjectDependenciesExistOnAllNodes(objectAddresses);
return NIL; return NIL;
} }
@ -138,16 +141,16 @@ PostprocessCreateStatisticsStmt(Node *node, const char *queryString)
* Never returns NULL, but the objid in the address can be invalid if missingOk * Never returns NULL, but the objid in the address can be invalid if missingOk
* was set to true. * was set to true.
*/ */
ObjectAddress List *
CreateStatisticsStmtObjectAddress(Node *node, bool missingOk) CreateStatisticsStmtObjectAddress(Node *node, bool missingOk)
{ {
CreateStatsStmt *stmt = castNode(CreateStatsStmt, node); CreateStatsStmt *stmt = castNode(CreateStatsStmt, node);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
Oid statsOid = get_statistics_object_oid(stmt->defnames, missingOk); Oid statsOid = get_statistics_object_oid(stmt->defnames, missingOk);
ObjectAddressSet(address, StatisticExtRelationId, statsOid); ObjectAddressSet(*address, StatisticExtRelationId, statsOid);
return address; return list_make1(address);
} }
@ -306,9 +309,12 @@ PostprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString)
} }
bool missingOk = false; bool missingOk = false;
ObjectAddress objectAddress = GetObjectAddressFromParseTree((Node *) stmt, missingOk); List *objectAddresses = GetObjectAddressListFromParseTree((Node *) stmt, missingOk);
EnsureDependenciesExistOnAllNodes(&objectAddress); /* the code-path only supports a single object */
Assert(list_length(objectAddresses) == 1);
EnsureAllObjectDependenciesExistOnAllNodes(objectAddresses);
return NIL; return NIL;
} }
@ -322,18 +328,18 @@ PostprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString)
* Never returns NULL, but the objid in the address can be invalid if missingOk * Never returns NULL, but the objid in the address can be invalid if missingOk
* was set to true. * was set to true.
*/ */
ObjectAddress List *
AlterStatisticsSchemaStmtObjectAddress(Node *node, bool missingOk) AlterStatisticsSchemaStmtObjectAddress(Node *node, bool missingOk)
{ {
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
String *statName = llast((List *) stmt->object); String *statName = llast((List *) stmt->object);
Oid statsOid = get_statistics_object_oid(list_make2(makeString(stmt->newschema), Oid statsOid = get_statistics_object_oid(list_make2(makeString(stmt->newschema),
statName), missingOk); statName), missingOk);
ObjectAddressSet(address, StatisticExtRelationId, statsOid); ObjectAddressSet(*address, StatisticExtRelationId, statsOid);
return address; return list_make1(address);
} }
@ -449,10 +455,9 @@ PostprocessAlterStatisticsOwnerStmt(Node *node, const char *queryString)
return NIL; return NIL;
} }
ObjectAddress statisticsAddress = { 0 }; ObjectAddress *statisticsAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(statisticsAddress, StatisticExtRelationId, statsOid); ObjectAddressSet(*statisticsAddress, StatisticExtRelationId, statsOid);
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(statisticsAddress));
EnsureDependenciesExistOnAllNodes(&statisticsAddress);
return NIL; return NIL;
} }

View File

@ -649,13 +649,19 @@ PostprocessAlterTableSchemaStmt(Node *node, const char *queryString)
/* /*
* We will let Postgres deal with missing_ok * We will let Postgres deal with missing_ok
*/ */
ObjectAddress tableAddress = GetObjectAddressFromParseTree((Node *) stmt, true); List *tableAddresses = GetObjectAddressListFromParseTree((Node *) stmt, true);
/* the code-path only supports a single object */
Assert(list_length(tableAddress) == 1);
/* We have already asserted that we have exactly 1 address in the addresses. */
ObjectAddress *tableAddress = linitial(tableAddresses);
/* /*
* Check whether we are dealing with a sequence or view here and route queries * Check whether we are dealing with a sequence or view here and route queries
* accordingly to the right processor function. * accordingly to the right processor function.
*/ */
char relKind = get_rel_relkind(tableAddress.objectId); char relKind = get_rel_relkind(tableAddress->objectId);
if (relKind == RELKIND_SEQUENCE) if (relKind == RELKIND_SEQUENCE)
{ {
stmt->objectType = OBJECT_SEQUENCE; stmt->objectType = OBJECT_SEQUENCE;
@ -667,12 +673,12 @@ PostprocessAlterTableSchemaStmt(Node *node, const char *queryString)
return PostprocessAlterViewSchemaStmt((Node *) stmt, queryString); return PostprocessAlterViewSchemaStmt((Node *) stmt, queryString);
} }
if (!ShouldPropagate() || !IsCitusTable(tableAddress.objectId)) if (!ShouldPropagate() || !IsCitusTable(tableAddress->objectId))
{ {
return NIL; return NIL;
} }
EnsureDependenciesExistOnAllNodes(&tableAddress); EnsureAllObjectDependenciesExistOnAllNodes(tableAddresses);
return NIL; return NIL;
} }
@ -1776,9 +1782,15 @@ PreprocessAlterTableSchemaStmt(Node *node, const char *queryString,
return NIL; return NIL;
} }
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, List *addresses = GetObjectAddressListFromParseTree((Node *) stmt,
stmt->missing_ok); stmt->missing_ok);
Oid relationId = address.objectId;
/* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
/* We have already asserted that we have exactly 1 address in the addresses. */
ObjectAddress *address = linitial(addresses);
Oid relationId = address->objectId;
/* /*
* Check whether we are dealing with a sequence or view here and route queries * Check whether we are dealing with a sequence or view here and route queries
@ -1990,9 +2002,9 @@ PostprocessAlterTableStmt(AlterTableStmt *alterTableStatement)
EnsureRelationHasCompatibleSequenceTypes(relationId); EnsureRelationHasCompatibleSequenceTypes(relationId);
/* changing a relation could introduce new dependencies */ /* changing a relation could introduce new dependencies */
ObjectAddress tableAddress = { 0 }; ObjectAddress *tableAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(tableAddress, RelationRelationId, relationId); ObjectAddressSet(*tableAddress, RelationRelationId, relationId);
EnsureDependenciesExistOnAllNodes(&tableAddress); EnsureAllObjectDependenciesExistOnAllNodes(list_make1(tableAddress));
} }
/* for the new sequences coming with this ALTER TABLE statement */ /* for the new sequences coming with this ALTER TABLE statement */
@ -3353,7 +3365,7 @@ ErrorIfUnsupportedAlterAddConstraintStmt(AlterTableStmt *alterTableStatement)
* will look in the new schema. Errors if missing_ok is false and the table cannot * will look in the new schema. Errors if missing_ok is false and the table cannot
* be found in either of the schemas. * be found in either of the schemas.
*/ */
ObjectAddress List *
AlterTableSchemaStmtObjectAddress(Node *node, bool missing_ok) AlterTableSchemaStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
@ -3389,10 +3401,10 @@ AlterTableSchemaStmtObjectAddress(Node *node, bool missing_ok)
} }
} }
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, RelationRelationId, tableOid); ObjectAddressSet(*address, RelationRelationId, tableOid);
return address; return list_make1(address);
} }

View File

@ -569,7 +569,7 @@ get_ts_parser_namelist(Oid tsparserOid)
* being created. If missing_pk is false the function will error, explaining to the user * being created. If missing_pk is false the function will error, explaining to the user
* the text search configuration described in the statement doesn't exist. * the text search configuration described in the statement doesn't exist.
*/ */
ObjectAddress List *
CreateTextSearchConfigurationObjectAddress(Node *node, bool missing_ok) CreateTextSearchConfigurationObjectAddress(Node *node, bool missing_ok)
{ {
DefineStmt *stmt = castNode(DefineStmt, node); DefineStmt *stmt = castNode(DefineStmt, node);
@ -577,9 +577,9 @@ CreateTextSearchConfigurationObjectAddress(Node *node, bool missing_ok)
Oid objid = get_ts_config_oid(stmt->defnames, missing_ok); Oid objid = get_ts_config_oid(stmt->defnames, missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TSConfigRelationId, objid); ObjectAddressSet(*address, TSConfigRelationId, objid);
return address; return list_make1(address);
} }
@ -588,7 +588,7 @@ CreateTextSearchConfigurationObjectAddress(Node *node, bool missing_ok)
* being created. If missing_pk is false the function will error, explaining to the user * being created. If missing_pk is false the function will error, explaining to the user
* the text search dictionary described in the statement doesn't exist. * the text search dictionary described in the statement doesn't exist.
*/ */
ObjectAddress List *
CreateTextSearchDictObjectAddress(Node *node, bool missing_ok) CreateTextSearchDictObjectAddress(Node *node, bool missing_ok)
{ {
DefineStmt *stmt = castNode(DefineStmt, node); DefineStmt *stmt = castNode(DefineStmt, node);
@ -596,9 +596,9 @@ CreateTextSearchDictObjectAddress(Node *node, bool missing_ok)
Oid objid = get_ts_dict_oid(stmt->defnames, missing_ok); Oid objid = get_ts_dict_oid(stmt->defnames, missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TSDictionaryRelationId, objid); ObjectAddressSet(*address, TSDictionaryRelationId, objid);
return address; return list_make1(address);
} }
@ -607,7 +607,7 @@ CreateTextSearchDictObjectAddress(Node *node, bool missing_ok)
* SEARCH CONFIGURATION being renamed. Optionally errors if the configuration does not * SEARCH CONFIGURATION being renamed. Optionally errors if the configuration does not
* exist based on the missing_ok flag passed in by the caller. * exist based on the missing_ok flag passed in by the caller.
*/ */
ObjectAddress List *
RenameTextSearchConfigurationStmtObjectAddress(Node *node, bool missing_ok) RenameTextSearchConfigurationStmtObjectAddress(Node *node, bool missing_ok)
{ {
RenameStmt *stmt = castNode(RenameStmt, node); RenameStmt *stmt = castNode(RenameStmt, node);
@ -615,9 +615,9 @@ RenameTextSearchConfigurationStmtObjectAddress(Node *node, bool missing_ok)
Oid objid = get_ts_config_oid(castNode(List, stmt->object), missing_ok); Oid objid = get_ts_config_oid(castNode(List, stmt->object), missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TSConfigRelationId, objid); ObjectAddressSet(*address, TSConfigRelationId, objid);
return address; return list_make1(address);
} }
@ -626,7 +626,7 @@ RenameTextSearchConfigurationStmtObjectAddress(Node *node, bool missing_ok)
* SEARCH DICTIONARY being renamed. Optionally errors if the dictionary does not * SEARCH DICTIONARY being renamed. Optionally errors if the dictionary does not
* exist based on the missing_ok flag passed in by the caller. * exist based on the missing_ok flag passed in by the caller.
*/ */
ObjectAddress List *
RenameTextSearchDictionaryStmtObjectAddress(Node *node, bool missing_ok) RenameTextSearchDictionaryStmtObjectAddress(Node *node, bool missing_ok)
{ {
RenameStmt *stmt = castNode(RenameStmt, node); RenameStmt *stmt = castNode(RenameStmt, node);
@ -634,9 +634,9 @@ RenameTextSearchDictionaryStmtObjectAddress(Node *node, bool missing_ok)
Oid objid = get_ts_dict_oid(castNode(List, stmt->object), missing_ok); Oid objid = get_ts_dict_oid(castNode(List, stmt->object), missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TSDictionaryRelationId, objid); ObjectAddressSet(*address, TSDictionaryRelationId, objid);
return address; return list_make1(address);
} }
@ -645,16 +645,16 @@ RenameTextSearchDictionaryStmtObjectAddress(Node *node, bool missing_ok)
* SEARCH CONFIGURATION being altered. Optionally errors if the configuration does not * SEARCH CONFIGURATION being altered. Optionally errors if the configuration does not
* exist based on the missing_ok flag passed in by the caller. * exist based on the missing_ok flag passed in by the caller.
*/ */
ObjectAddress List *
AlterTextSearchConfigurationStmtObjectAddress(Node *node, bool missing_ok) AlterTextSearchConfigurationStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterTSConfigurationStmt *stmt = castNode(AlterTSConfigurationStmt, node); AlterTSConfigurationStmt *stmt = castNode(AlterTSConfigurationStmt, node);
Oid objid = get_ts_config_oid(stmt->cfgname, missing_ok); Oid objid = get_ts_config_oid(stmt->cfgname, missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TSConfigRelationId, objid); ObjectAddressSet(*address, TSConfigRelationId, objid);
return address; return list_make1(address);
} }
@ -663,16 +663,16 @@ AlterTextSearchConfigurationStmtObjectAddress(Node *node, bool missing_ok)
* SEARCH CONFIGURATION being altered. Optionally errors if the configuration does not * SEARCH CONFIGURATION being altered. Optionally errors if the configuration does not
* exist based on the missing_ok flag passed in by the caller. * exist based on the missing_ok flag passed in by the caller.
*/ */
ObjectAddress List *
AlterTextSearchDictionaryStmtObjectAddress(Node *node, bool missing_ok) AlterTextSearchDictionaryStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterTSDictionaryStmt *stmt = castNode(AlterTSDictionaryStmt, node); AlterTSDictionaryStmt *stmt = castNode(AlterTSDictionaryStmt, node);
Oid objid = get_ts_dict_oid(stmt->dictname, missing_ok); Oid objid = get_ts_dict_oid(stmt->dictname, missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TSDictionaryRelationId, objid); ObjectAddressSet(*address, TSDictionaryRelationId, objid);
return address; return list_make1(address);
} }
@ -685,7 +685,7 @@ AlterTextSearchDictionaryStmtObjectAddress(Node *node, bool missing_ok)
* the triple checking before the error might be thrown. Errors for non-existing schema's * the triple checking before the error might be thrown. Errors for non-existing schema's
* in edgecases will be raised by postgres while executing the move. * in edgecases will be raised by postgres while executing the move.
*/ */
ObjectAddress List *
AlterTextSearchConfigurationSchemaStmtObjectAddress(Node *node, bool missing_ok) AlterTextSearchConfigurationSchemaStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
@ -723,9 +723,9 @@ AlterTextSearchConfigurationSchemaStmtObjectAddress(Node *node, bool missing_ok)
} }
} }
ObjectAddress sequenceAddress = { 0 }; ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(sequenceAddress, TSConfigRelationId, objid); ObjectAddressSet(*sequenceAddress, TSConfigRelationId, objid);
return sequenceAddress; return list_make1(sequenceAddress);
} }
@ -738,7 +738,7 @@ AlterTextSearchConfigurationSchemaStmtObjectAddress(Node *node, bool missing_ok)
* the triple checking before the error might be thrown. Errors for non-existing schema's * the triple checking before the error might be thrown. Errors for non-existing schema's
* in edgecases will be raised by postgres while executing the move. * in edgecases will be raised by postgres while executing the move.
*/ */
ObjectAddress List *
AlterTextSearchDictionarySchemaStmtObjectAddress(Node *node, bool missing_ok) AlterTextSearchDictionarySchemaStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
@ -776,9 +776,9 @@ AlterTextSearchDictionarySchemaStmtObjectAddress(Node *node, bool missing_ok)
} }
} }
ObjectAddress sequenceAddress = { 0 }; ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(sequenceAddress, TSDictionaryRelationId, objid); ObjectAddressSet(*sequenceAddress, TSDictionaryRelationId, objid);
return sequenceAddress; return list_make1(sequenceAddress);
} }
@ -787,7 +787,7 @@ AlterTextSearchDictionarySchemaStmtObjectAddress(Node *node, bool missing_ok)
* SEARCH CONFIGURATION on which the comment is placed. Optionally errors if the * SEARCH CONFIGURATION on which the comment is placed. Optionally errors if the
* configuration does not exist based on the missing_ok flag passed in by the caller. * configuration does not exist based on the missing_ok flag passed in by the caller.
*/ */
ObjectAddress List *
TextSearchConfigurationCommentObjectAddress(Node *node, bool missing_ok) TextSearchConfigurationCommentObjectAddress(Node *node, bool missing_ok)
{ {
CommentStmt *stmt = castNode(CommentStmt, node); CommentStmt *stmt = castNode(CommentStmt, node);
@ -795,9 +795,9 @@ TextSearchConfigurationCommentObjectAddress(Node *node, bool missing_ok)
Oid objid = get_ts_config_oid(castNode(List, stmt->object), missing_ok); Oid objid = get_ts_config_oid(castNode(List, stmt->object), missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TSConfigRelationId, objid); ObjectAddressSet(*address, TSConfigRelationId, objid);
return address; return list_make1(address);
} }
@ -806,7 +806,7 @@ TextSearchConfigurationCommentObjectAddress(Node *node, bool missing_ok)
* DICTIONARY on which the comment is placed. Optionally errors if the dictionary does not * DICTIONARY on which the comment is placed. Optionally errors if the dictionary does not
* exist based on the missing_ok flag passed in by the caller. * exist based on the missing_ok flag passed in by the caller.
*/ */
ObjectAddress List *
TextSearchDictCommentObjectAddress(Node *node, bool missing_ok) TextSearchDictCommentObjectAddress(Node *node, bool missing_ok)
{ {
CommentStmt *stmt = castNode(CommentStmt, node); CommentStmt *stmt = castNode(CommentStmt, node);
@ -814,9 +814,9 @@ TextSearchDictCommentObjectAddress(Node *node, bool missing_ok)
Oid objid = get_ts_dict_oid(castNode(List, stmt->object), missing_ok); Oid objid = get_ts_dict_oid(castNode(List, stmt->object), missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TSDictionaryRelationId, objid); ObjectAddressSet(*address, TSDictionaryRelationId, objid);
return address; return list_make1(address);
} }
@ -825,7 +825,7 @@ TextSearchDictCommentObjectAddress(Node *node, bool missing_ok)
* SEARCH CONFIGURATION for which the owner is changed. Optionally errors if the * SEARCH CONFIGURATION for which the owner is changed. Optionally errors if the
* configuration does not exist based on the missing_ok flag passed in by the caller. * configuration does not exist based on the missing_ok flag passed in by the caller.
*/ */
ObjectAddress List *
AlterTextSearchConfigurationOwnerObjectAddress(Node *node, bool missing_ok) AlterTextSearchConfigurationOwnerObjectAddress(Node *node, bool missing_ok)
{ {
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
@ -833,8 +833,14 @@ AlterTextSearchConfigurationOwnerObjectAddress(Node *node, bool missing_ok)
Assert(stmt->objectType == OBJECT_TSCONFIGURATION); Assert(stmt->objectType == OBJECT_TSCONFIGURATION);
return get_object_address(stmt->objectType, stmt->object, &relation, AccessShareLock, ObjectAddress objectAddress = get_object_address(stmt->objectType, stmt->object,
&relation, AccessShareLock,
missing_ok); missing_ok);
ObjectAddress *objectAddressCopy = palloc0(sizeof(ObjectAddress));
*objectAddressCopy = objectAddress;
return list_make1(objectAddressCopy);
} }
@ -843,16 +849,20 @@ AlterTextSearchConfigurationOwnerObjectAddress(Node *node, bool missing_ok)
* SEARCH DICTIONARY for which the owner is changed. Optionally errors if the * SEARCH DICTIONARY for which the owner is changed. Optionally errors if the
* configuration does not exist based on the missing_ok flag passed in by the caller. * configuration does not exist based on the missing_ok flag passed in by the caller.
*/ */
ObjectAddress List *
AlterTextSearchDictOwnerObjectAddress(Node *node, bool missing_ok) AlterTextSearchDictOwnerObjectAddress(Node *node, bool missing_ok)
{ {
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
Relation relation = NULL; Relation relation = NULL;
Assert(stmt->objectType == OBJECT_TSDICTIONARY); Assert(stmt->objectType == OBJECT_TSDICTIONARY);
ObjectAddress objectAddress = get_object_address(stmt->objectType, stmt->object,
return get_object_address(stmt->objectType, stmt->object, &relation, AccessShareLock, &relation, AccessShareLock,
missing_ok); missing_ok);
ObjectAddress *objectAddressCopy = palloc0(sizeof(ObjectAddress));
*objectAddressCopy = objectAddress;
return list_make1(objectAddressCopy);
} }

View File

@ -224,8 +224,12 @@ PostprocessCreateTriggerStmt(Node *node, const char *queryString)
EnsureCoordinator(); EnsureCoordinator();
ErrorOutForTriggerIfNotSupported(relationId); ErrorOutForTriggerIfNotSupported(relationId);
ObjectAddress objectAddress = GetObjectAddressFromParseTree(node, missingOk); List *objectAddresses = GetObjectAddressListFromParseTree(node, missingOk);
EnsureDependenciesExistOnAllNodes(&objectAddress);
/* the code-path only supports a single object */
Assert(list_length(objectAddresses) == 1);
EnsureAllObjectDependenciesExistOnAllNodes(objectAddresses);
char *triggerName = createTriggerStmt->trigname; char *triggerName = createTriggerStmt->trigname;
return CitusCreateTriggerCommandDDLJob(relationId, triggerName, return CitusCreateTriggerCommandDDLJob(relationId, triggerName,
@ -241,7 +245,7 @@ PostprocessCreateTriggerStmt(Node *node, const char *queryString)
* Never returns NULL, but the objid in the address can be invalid if missingOk * Never returns NULL, but the objid in the address can be invalid if missingOk
* was set to true. * was set to true.
*/ */
ObjectAddress List *
CreateTriggerStmtObjectAddress(Node *node, bool missingOk) CreateTriggerStmtObjectAddress(Node *node, bool missingOk)
{ {
CreateTrigStmt *createTriggerStmt = castNode(CreateTrigStmt, node); CreateTrigStmt *createTriggerStmt = castNode(CreateTrigStmt, node);
@ -260,9 +264,9 @@ CreateTriggerStmtObjectAddress(Node *node, bool missingOk)
triggerName, relationName))); triggerName, relationName)));
} }
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TriggerRelationId, triggerId); ObjectAddressSet(*address, TriggerRelationId, triggerId);
return address; return list_make1(address);
} }

View File

@ -117,8 +117,12 @@ PreprocessRenameTypeAttributeStmt(Node *node, const char *queryString,
Assert(stmt->renameType == OBJECT_ATTRIBUTE); Assert(stmt->renameType == OBJECT_ATTRIBUTE);
Assert(stmt->relationType == OBJECT_TYPE); Assert(stmt->relationType == OBJECT_TYPE);
ObjectAddress typeAddress = GetObjectAddressFromParseTree((Node *) stmt, false); List *typeAddresses = GetObjectAddressListFromParseTree((Node *) stmt, false);
if (!ShouldPropagateObject(&typeAddress))
/* the code-path only supports a single object */
Assert(list_length(objectAddresses) == 1);
if (!ShouldPropagateAnyObject(typeAddresses))
{ {
return NIL; return NIL;
} }
@ -300,16 +304,16 @@ EnumValsList(Oid typeOid)
* Never returns NULL, but the objid in the address could be invalid if missing_ok was set * Never returns NULL, but the objid in the address could be invalid if missing_ok was set
* to true. * to true.
*/ */
ObjectAddress List *
CompositeTypeStmtObjectAddress(Node *node, bool missing_ok) CompositeTypeStmtObjectAddress(Node *node, bool missing_ok)
{ {
CompositeTypeStmt *stmt = castNode(CompositeTypeStmt, node); CompositeTypeStmt *stmt = castNode(CompositeTypeStmt, node);
TypeName *typeName = MakeTypeNameFromRangeVar(stmt->typevar); TypeName *typeName = MakeTypeNameFromRangeVar(stmt->typevar);
Oid typeOid = LookupNonAssociatedArrayTypeNameOid(NULL, typeName, missing_ok); Oid typeOid = LookupNonAssociatedArrayTypeNameOid(NULL, typeName, missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TypeRelationId, typeOid); ObjectAddressSet(*address, TypeRelationId, typeOid);
return address; return list_make1(address);
} }
@ -321,16 +325,16 @@ CompositeTypeStmtObjectAddress(Node *node, bool missing_ok)
* Never returns NULL, but the objid in the address could be invalid if missing_ok was set * Never returns NULL, but the objid in the address could be invalid if missing_ok was set
* to true. * to true.
*/ */
ObjectAddress List *
CreateEnumStmtObjectAddress(Node *node, bool missing_ok) CreateEnumStmtObjectAddress(Node *node, bool missing_ok)
{ {
CreateEnumStmt *stmt = castNode(CreateEnumStmt, node); CreateEnumStmt *stmt = castNode(CreateEnumStmt, node);
TypeName *typeName = makeTypeNameFromNameList(stmt->typeName); TypeName *typeName = makeTypeNameFromNameList(stmt->typeName);
Oid typeOid = LookupNonAssociatedArrayTypeNameOid(NULL, typeName, missing_ok); Oid typeOid = LookupNonAssociatedArrayTypeNameOid(NULL, typeName, missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TypeRelationId, typeOid); ObjectAddressSet(*address, TypeRelationId, typeOid);
return address; return list_make1(address);
} }
@ -342,7 +346,7 @@ CreateEnumStmtObjectAddress(Node *node, bool missing_ok)
* Never returns NULL, but the objid in the address could be invalid if missing_ok was set * Never returns NULL, but the objid in the address could be invalid if missing_ok was set
* to true. * to true.
*/ */
ObjectAddress List *
AlterTypeStmtObjectAddress(Node *node, bool missing_ok) AlterTypeStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterTableStmt *stmt = castNode(AlterTableStmt, node); AlterTableStmt *stmt = castNode(AlterTableStmt, node);
@ -350,10 +354,10 @@ AlterTypeStmtObjectAddress(Node *node, bool missing_ok)
TypeName *typeName = MakeTypeNameFromRangeVar(stmt->relation); TypeName *typeName = MakeTypeNameFromRangeVar(stmt->relation);
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok); Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TypeRelationId, typeOid); ObjectAddressSet(*address, TypeRelationId, typeOid);
return address; return list_make1(address);
} }
@ -361,16 +365,16 @@ AlterTypeStmtObjectAddress(Node *node, bool missing_ok)
* AlterEnumStmtObjectAddress return the ObjectAddress of the enum type that is the * AlterEnumStmtObjectAddress return the ObjectAddress of the enum type that is the
* object of the AlterEnumStmt. Errors is missing_ok is false. * object of the AlterEnumStmt. Errors is missing_ok is false.
*/ */
ObjectAddress List *
AlterEnumStmtObjectAddress(Node *node, bool missing_ok) AlterEnumStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterEnumStmt *stmt = castNode(AlterEnumStmt, node); AlterEnumStmt *stmt = castNode(AlterEnumStmt, node);
TypeName *typeName = makeTypeNameFromNameList(stmt->typeName); TypeName *typeName = makeTypeNameFromNameList(stmt->typeName);
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok); Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TypeRelationId, typeOid); ObjectAddressSet(*address, TypeRelationId, typeOid);
return address; return list_make1(address);
} }
@ -378,7 +382,7 @@ AlterEnumStmtObjectAddress(Node *node, bool missing_ok)
* RenameTypeStmtObjectAddress returns the ObjectAddress of the type that is the object * RenameTypeStmtObjectAddress returns the ObjectAddress of the type that is the object
* of the RenameStmt. Errors if missing_ok is false. * of the RenameStmt. Errors if missing_ok is false.
*/ */
ObjectAddress List *
RenameTypeStmtObjectAddress(Node *node, bool missing_ok) RenameTypeStmtObjectAddress(Node *node, bool missing_ok)
{ {
RenameStmt *stmt = castNode(RenameStmt, node); RenameStmt *stmt = castNode(RenameStmt, node);
@ -386,10 +390,10 @@ RenameTypeStmtObjectAddress(Node *node, bool missing_ok)
TypeName *typeName = makeTypeNameFromNameList((List *) stmt->object); TypeName *typeName = makeTypeNameFromNameList((List *) stmt->object);
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok); Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TypeRelationId, typeOid); ObjectAddressSet(*address, TypeRelationId, typeOid);
return address; return list_make1(address);
} }
@ -402,7 +406,7 @@ RenameTypeStmtObjectAddress(Node *node, bool missing_ok)
* new schema. Errors if missing_ok is false and the type cannot be found in either of the * new schema. Errors if missing_ok is false and the type cannot be found in either of the
* schemas. * schemas.
*/ */
ObjectAddress List *
AlterTypeSchemaStmtObjectAddress(Node *node, bool missing_ok) AlterTypeSchemaStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
@ -447,10 +451,10 @@ AlterTypeSchemaStmtObjectAddress(Node *node, bool missing_ok)
} }
} }
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TypeRelationId, typeOid); ObjectAddressSet(*address, TypeRelationId, typeOid);
return address; return list_make1(address);
} }
@ -462,7 +466,7 @@ AlterTypeSchemaStmtObjectAddress(Node *node, bool missing_ok)
* changed as Attributes are not distributed on their own but as a side effect of the * changed as Attributes are not distributed on their own but as a side effect of the
* whole type distribution. * whole type distribution.
*/ */
ObjectAddress List *
RenameTypeAttributeStmtObjectAddress(Node *node, bool missing_ok) RenameTypeAttributeStmtObjectAddress(Node *node, bool missing_ok)
{ {
RenameStmt *stmt = castNode(RenameStmt, node); RenameStmt *stmt = castNode(RenameStmt, node);
@ -471,10 +475,10 @@ RenameTypeAttributeStmtObjectAddress(Node *node, bool missing_ok)
TypeName *typeName = MakeTypeNameFromRangeVar(stmt->relation); TypeName *typeName = MakeTypeNameFromRangeVar(stmt->relation);
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok); Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TypeRelationId, typeOid); ObjectAddressSet(*address, TypeRelationId, typeOid);
return address; return list_make1(address);
} }
@ -482,7 +486,7 @@ RenameTypeAttributeStmtObjectAddress(Node *node, bool missing_ok)
* AlterTypeOwnerObjectAddress returns the ObjectAddress of the type that is the object * AlterTypeOwnerObjectAddress returns the ObjectAddress of the type that is the object
* of the AlterOwnerStmt. Errors if missing_ok is false. * of the AlterOwnerStmt. Errors if missing_ok is false.
*/ */
ObjectAddress List *
AlterTypeOwnerObjectAddress(Node *node, bool missing_ok) AlterTypeOwnerObjectAddress(Node *node, bool missing_ok)
{ {
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
@ -490,10 +494,10 @@ AlterTypeOwnerObjectAddress(Node *node, bool missing_ok)
TypeName *typeName = makeTypeNameFromNameList((List *) stmt->object); TypeName *typeName = makeTypeNameFromNameList((List *) stmt->object);
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok); Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(address, TypeRelationId, typeOid); ObjectAddressSet(*address, TypeRelationId, typeOid);
return address; return list_make1(address);
} }

View File

@ -853,8 +853,12 @@ ProcessUtilityInternal(PlannedStmt *pstmt,
*/ */
if (ops && ops->markDistributed) if (ops && ops->markDistributed)
{ {
ObjectAddress address = GetObjectAddressFromParseTree(parsetree, false); List *addresses = GetObjectAddressListFromParseTree(parsetree, false);
MarkObjectDistributed(&address); ObjectAddress *address = NULL;
foreach_ptr(address, addresses)
{
MarkObjectDistributed(address);
}
} }
} }

View File

@ -94,22 +94,27 @@ PostprocessViewStmt(Node *node, const char *queryString)
return NIL; return NIL;
} }
ObjectAddress viewAddress = GetObjectAddressFromParseTree((Node *) stmt, false); List *viewAddresses = GetObjectAddressListFromParseTree((Node *) stmt, false);
if (IsObjectAddressOwnedByExtension(&viewAddress, NULL)) /* the code-path only supports a single object */
Assert(list_length(viewAddresses) == 1);
if (IsAnyObjectAddressOwnedByExtension(viewAddresses, NULL))
{ {
return NIL; return NIL;
} }
/* If the view has any unsupported dependency, create it locally */ /* If the view has any unsupported dependency, create it locally */
if (ErrorOrWarnIfObjectHasUnsupportedDependency(&viewAddress)) if (ErrorOrWarnIfAnyObjectHasUnsupportedDependency(viewAddresses))
{ {
return NIL; return NIL;
} }
EnsureDependenciesExistOnAllNodes(&viewAddress); EnsureAllObjectDependenciesExistOnAllNodes(viewAddresses);
char *command = CreateViewDDLCommand(viewAddress.objectId); /* We have already asserted that we have exactly 1 address in the addresses. */
ObjectAddress *viewAddress = linitial(viewAddresses);
char *command = CreateViewDDLCommand(viewAddress->objectId);
/* /*
* We'd typically use NodeDDLTaskList() for generating node-level DDL commands, * We'd typically use NodeDDLTaskList() for generating node-level DDL commands,
@ -140,7 +145,7 @@ PostprocessViewStmt(Node *node, const char *queryString)
* *
*/ */
DDLJob *ddlJob = palloc0(sizeof(DDLJob)); DDLJob *ddlJob = palloc0(sizeof(DDLJob));
ddlJob->targetObjectAddress = viewAddress; ddlJob->targetObjectAddress = *viewAddress;
ddlJob->metadataSyncCommand = command; ddlJob->metadataSyncCommand = command;
ddlJob->taskList = NIL; ddlJob->taskList = NIL;
@ -152,17 +157,17 @@ PostprocessViewStmt(Node *node, const char *queryString)
* ViewStmtObjectAddress returns the ObjectAddress for the subject of the * ViewStmtObjectAddress returns the ObjectAddress for the subject of the
* CREATE [OR REPLACE] VIEW statement. * CREATE [OR REPLACE] VIEW statement.
*/ */
ObjectAddress List *
ViewStmtObjectAddress(Node *node, bool missing_ok) ViewStmtObjectAddress(Node *node, bool missing_ok)
{ {
ViewStmt *stmt = castNode(ViewStmt, node); ViewStmt *stmt = castNode(ViewStmt, node);
Oid viewOid = RangeVarGetRelid(stmt->view, NoLock, missing_ok); Oid viewOid = RangeVarGetRelid(stmt->view, NoLock, missing_ok);
ObjectAddress viewAddress = { 0 }; ObjectAddress *viewAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(viewAddress, RelationRelationId, viewOid); ObjectAddressSet(*viewAddress, RelationRelationId, viewOid);
return viewAddress; return list_make1(viewAddress);
} }
@ -442,10 +447,9 @@ IsViewDistributed(Oid viewOid)
Assert(get_rel_relkind(viewOid) == RELKIND_VIEW || Assert(get_rel_relkind(viewOid) == RELKIND_VIEW ||
get_rel_relkind(viewOid) == RELKIND_MATVIEW); get_rel_relkind(viewOid) == RELKIND_MATVIEW);
ObjectAddress viewAddress = { 0 }; ObjectAddress *viewAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(viewAddress, RelationRelationId, viewOid); ObjectAddressSet(*viewAddress, RelationRelationId, viewOid);
return IsAnyObjectDistributed(list_make1(viewAddress));
return IsObjectDistributed(&viewAddress);
} }
@ -458,8 +462,12 @@ PreprocessAlterViewStmt(Node *node, const char *queryString, ProcessUtilityConte
{ {
AlterTableStmt *stmt = castNode(AlterTableStmt, node); AlterTableStmt *stmt = castNode(AlterTableStmt, node);
ObjectAddress viewAddress = GetObjectAddressFromParseTree((Node *) stmt, true); List *viewAddresses = GetObjectAddressListFromParseTree((Node *) stmt, true);
if (!ShouldPropagateObject(&viewAddress))
/* the code-path only supports a single object */
Assert(list_length(viewAddresses) == 1);
if (!ShouldPropagateAnyObject(viewAddresses))
{ {
return NIL; return NIL;
} }
@ -471,12 +479,15 @@ PreprocessAlterViewStmt(Node *node, const char *queryString, ProcessUtilityConte
/* reconstruct alter statement in a portable fashion */ /* reconstruct alter statement in a portable fashion */
const char *alterViewStmtSql = DeparseTreeNode((Node *) stmt); const char *alterViewStmtSql = DeparseTreeNode((Node *) stmt);
/* We have already asserted that we have exactly 1 address in the addresses. */
ObjectAddress *viewAddress = linitial(viewAddresses);
/* /*
* To avoid sequential mode, we are using metadata connection. For the * To avoid sequential mode, we are using metadata connection. For the
* detailed explanation, please check the comment on PostprocessViewStmt. * detailed explanation, please check the comment on PostprocessViewStmt.
*/ */
DDLJob *ddlJob = palloc0(sizeof(DDLJob)); DDLJob *ddlJob = palloc0(sizeof(DDLJob));
ddlJob->targetObjectAddress = viewAddress; ddlJob->targetObjectAddress = *viewAddress;
ddlJob->metadataSyncCommand = alterViewStmtSql; ddlJob->metadataSyncCommand = alterViewStmtSql;
ddlJob->taskList = NIL; ddlJob->taskList = NIL;
@ -493,24 +504,28 @@ PostprocessAlterViewStmt(Node *node, const char *queryString)
AlterTableStmt *stmt = castNode(AlterTableStmt, node); AlterTableStmt *stmt = castNode(AlterTableStmt, node);
Assert(AlterTableStmtObjType_compat(stmt) == OBJECT_VIEW); Assert(AlterTableStmtObjType_compat(stmt) == OBJECT_VIEW);
ObjectAddress viewAddress = GetObjectAddressFromParseTree((Node *) stmt, true); List *viewAddresses = GetObjectAddressListFromParseTree((Node *) stmt, true);
if (!ShouldPropagateObject(&viewAddress))
/* the code-path only supports a single object */
Assert(list_length(viewAddresses) == 1);
if (!ShouldPropagateAnyObject(viewAddresses))
{ {
return NIL; return NIL;
} }
if (IsObjectAddressOwnedByExtension(&viewAddress, NULL)) if (IsAnyObjectAddressOwnedByExtension(viewAddresses, NULL))
{ {
return NIL; return NIL;
} }
/* If the view has any unsupported dependency, create it locally */ /* If the view has any unsupported dependency, create it locally */
if (ErrorOrWarnIfObjectHasUnsupportedDependency(&viewAddress)) if (ErrorOrWarnIfAnyObjectHasUnsupportedDependency(viewAddresses))
{ {
return NIL; return NIL;
} }
EnsureDependenciesExistOnAllNodes(&viewAddress); EnsureAllObjectDependenciesExistOnAllNodes(viewAddresses);
return NIL; return NIL;
} }
@ -520,16 +535,16 @@ PostprocessAlterViewStmt(Node *node, const char *queryString)
* AlterViewStmtObjectAddress returns the ObjectAddress for the subject of the * AlterViewStmtObjectAddress returns the ObjectAddress for the subject of the
* ALTER VIEW statement. * ALTER VIEW statement.
*/ */
ObjectAddress List *
AlterViewStmtObjectAddress(Node *node, bool missing_ok) AlterViewStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterTableStmt *stmt = castNode(AlterTableStmt, node); AlterTableStmt *stmt = castNode(AlterTableStmt, node);
Oid viewOid = RangeVarGetRelid(stmt->relation, NoLock, missing_ok); Oid viewOid = RangeVarGetRelid(stmt->relation, NoLock, missing_ok);
ObjectAddress viewAddress = { 0 }; ObjectAddress *viewAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(viewAddress, RelationRelationId, viewOid); ObjectAddressSet(*viewAddress, RelationRelationId, viewOid);
return viewAddress; return list_make1(viewAddress);
} }
@ -541,8 +556,12 @@ List *
PreprocessRenameViewStmt(Node *node, const char *queryString, PreprocessRenameViewStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext) ProcessUtilityContext processUtilityContext)
{ {
ObjectAddress viewAddress = GetObjectAddressFromParseTree(node, true); List *viewAddresses = GetObjectAddressListFromParseTree(node, true);
if (!ShouldPropagateObject(&viewAddress))
/* the code-path only supports a single object */
Assert(list_length(viewAddresses) == 1);
if (!ShouldPropagateAnyObject(viewAddresses))
{ {
return NIL; return NIL;
} }
@ -555,12 +574,15 @@ PreprocessRenameViewStmt(Node *node, const char *queryString,
/* deparse sql*/ /* deparse sql*/
const char *renameStmtSql = DeparseTreeNode(node); const char *renameStmtSql = DeparseTreeNode(node);
/* We have already asserted that we have exactly 1 address in the addresses. */
ObjectAddress *viewAddress = linitial(viewAddresses);
/* /*
* To avoid sequential mode, we are using metadata connection. For the * To avoid sequential mode, we are using metadata connection. For the
* detailed explanation, please check the comment on PostprocessViewStmt. * detailed explanation, please check the comment on PostprocessViewStmt.
*/ */
DDLJob *ddlJob = palloc0(sizeof(DDLJob)); DDLJob *ddlJob = palloc0(sizeof(DDLJob));
ddlJob->targetObjectAddress = viewAddress; ddlJob->targetObjectAddress = *viewAddress;
ddlJob->metadataSyncCommand = renameStmtSql; ddlJob->metadataSyncCommand = renameStmtSql;
ddlJob->taskList = NIL; ddlJob->taskList = NIL;
@ -572,17 +594,17 @@ PreprocessRenameViewStmt(Node *node, const char *queryString,
* RenameViewStmtObjectAddress returns the ObjectAddress of the view that is the object * RenameViewStmtObjectAddress returns the ObjectAddress of the view that is the object
* of the RenameStmt. Errors if missing_ok is false. * of the RenameStmt. Errors if missing_ok is false.
*/ */
ObjectAddress List *
RenameViewStmtObjectAddress(Node *node, bool missing_ok) RenameViewStmtObjectAddress(Node *node, bool missing_ok)
{ {
RenameStmt *stmt = castNode(RenameStmt, node); RenameStmt *stmt = castNode(RenameStmt, node);
Oid viewOid = RangeVarGetRelid(stmt->relation, NoLock, missing_ok); Oid viewOid = RangeVarGetRelid(stmt->relation, NoLock, missing_ok);
ObjectAddress viewAddress = { 0 }; ObjectAddress *viewAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(viewAddress, RelationRelationId, viewOid); ObjectAddressSet(*viewAddress, RelationRelationId, viewOid);
return viewAddress; return list_make1(viewAddress);
} }
@ -596,8 +618,12 @@ PreprocessAlterViewSchemaStmt(Node *node, const char *queryString,
{ {
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
ObjectAddress viewAddress = GetObjectAddressFromParseTree((Node *) stmt, true); List *viewAddresses = GetObjectAddressListFromParseTree((Node *) stmt, true);
if (!ShouldPropagateObject(&viewAddress))
/* the code-path only supports a single object */
Assert(list_length(viewAddresses) == 1);
if (!ShouldPropagateAnyObject(viewAddresses))
{ {
return NIL; return NIL;
} }
@ -608,12 +634,15 @@ PreprocessAlterViewSchemaStmt(Node *node, const char *queryString,
const char *sql = DeparseTreeNode((Node *) stmt); const char *sql = DeparseTreeNode((Node *) stmt);
/* We have already asserted that we have exactly 1 address in the addresses. */
ObjectAddress *viewAddress = linitial(viewAddresses);
/* /*
* To avoid sequential mode, we are using metadata connection. For the * To avoid sequential mode, we are using metadata connection. For the
* detailed explanation, please check the comment on PostprocessViewStmt. * detailed explanation, please check the comment on PostprocessViewStmt.
*/ */
DDLJob *ddlJob = palloc0(sizeof(DDLJob)); DDLJob *ddlJob = palloc0(sizeof(DDLJob));
ddlJob->targetObjectAddress = viewAddress; ddlJob->targetObjectAddress = *viewAddress;
ddlJob->metadataSyncCommand = sql; ddlJob->metadataSyncCommand = sql;
ddlJob->taskList = NIL; ddlJob->taskList = NIL;
@ -631,14 +660,18 @@ PostprocessAlterViewSchemaStmt(Node *node, const char *queryString)
{ {
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
ObjectAddress viewAddress = GetObjectAddressFromParseTree((Node *) stmt, true); List *viewAddresses = GetObjectAddressListFromParseTree((Node *) stmt, true);
if (!ShouldPropagateObject(&viewAddress))
/* the code-path only supports a single object */
Assert(list_length(viewAddresses) == 1);
if (!ShouldPropagateAnyObject(viewAddresses))
{ {
return NIL; return NIL;
} }
/* dependencies have changed (schema) let's ensure they exist */ /* dependencies have changed (schema) let's ensure they exist */
EnsureDependenciesExistOnAllNodes(&viewAddress); EnsureAllObjectDependenciesExistOnAllNodes(viewAddresses);
return NIL; return NIL;
} }
@ -648,7 +681,7 @@ PostprocessAlterViewSchemaStmt(Node *node, const char *queryString)
* AlterViewSchemaStmtObjectAddress returns the ObjectAddress of the view that is the object * AlterViewSchemaStmtObjectAddress returns the ObjectAddress of the view that is the object
* of the alter schema statement. * of the alter schema statement.
*/ */
ObjectAddress List *
AlterViewSchemaStmtObjectAddress(Node *node, bool missing_ok) AlterViewSchemaStmtObjectAddress(Node *node, bool missing_ok)
{ {
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
@ -676,10 +709,10 @@ AlterViewSchemaStmtObjectAddress(Node *node, bool missing_ok)
} }
} }
ObjectAddress viewAddress = { 0 }; ObjectAddress *viewAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(viewAddress, RelationRelationId, viewOid); ObjectAddressSet(*viewAddress, RelationRelationId, viewOid);
return viewAddress; return list_make1(viewAddress);
} }

View File

@ -20,11 +20,11 @@
/* /*
* GetObjectAddressFromParseTree returns the ObjectAddress of the main target of the parse * GetObjectAddressListFromParseTree returns the list of ObjectAddress of the main target of the parse
* tree. * tree.
*/ */
ObjectAddress List *
GetObjectAddressFromParseTree(Node *parseTree, bool missing_ok) GetObjectAddressListFromParseTree(Node *parseTree, bool missing_ok)
{ {
const DistributeObjectOps *ops = GetDistributeObjectOps(parseTree); const DistributeObjectOps *ops = GetDistributeObjectOps(parseTree);
@ -37,7 +37,7 @@ GetObjectAddressFromParseTree(Node *parseTree, bool missing_ok)
} }
ObjectAddress List *
RenameAttributeStmtObjectAddress(Node *node, bool missing_ok) RenameAttributeStmtObjectAddress(Node *node, bool missing_ok)
{ {
RenameStmt *stmt = castNode(RenameStmt, node); RenameStmt *stmt = castNode(RenameStmt, node);
@ -67,11 +67,11 @@ RenameAttributeStmtObjectAddress(Node *node, bool missing_ok)
* Never returns NULL, but the objid in the address could be invalid if missing_ok was set * Never returns NULL, but the objid in the address could be invalid if missing_ok was set
* to true. * to true.
*/ */
ObjectAddress List *
CreateExtensionStmtObjectAddress(Node *node, bool missing_ok) CreateExtensionStmtObjectAddress(Node *node, bool missing_ok)
{ {
CreateExtensionStmt *stmt = castNode(CreateExtensionStmt, node); CreateExtensionStmt *stmt = castNode(CreateExtensionStmt, node);
ObjectAddress address = { 0 }; ObjectAddress *address = palloc0(sizeof(ObjectAddress));
const char *extensionName = stmt->extname; const char *extensionName = stmt->extname;
@ -85,7 +85,7 @@ CreateExtensionStmtObjectAddress(Node *node, bool missing_ok)
extensionName))); extensionName)));
} }
ObjectAddressSet(address, ExtensionRelationId, extensionoid); ObjectAddressSet(*address, ExtensionRelationId, extensionoid);
return address; return list_make1(address);
} }

View File

@ -137,6 +137,8 @@ static DependencyDefinition * CreateObjectAddressDependencyDef(Oid classId, Oid
static List * GetTypeConstraintDependencyDefinition(Oid typeId); static List * GetTypeConstraintDependencyDefinition(Oid typeId);
static List * CreateObjectAddressDependencyDefList(Oid classId, List *objectIdList); static List * CreateObjectAddressDependencyDefList(Oid classId, List *objectIdList);
static ObjectAddress DependencyDefinitionObjectAddress(DependencyDefinition *definition); static ObjectAddress DependencyDefinitionObjectAddress(DependencyDefinition *definition);
static DeferredErrorMessage * DeferErrorIfHasUnsupportedDependency(const ObjectAddress *
objectAddress);
/* forward declarations for functions to interact with the ObjectAddressCollector */ /* forward declarations for functions to interact with the ObjectAddressCollector */
static void InitObjectAddressCollector(ObjectAddressCollector *collector); static void InitObjectAddressCollector(ObjectAddressCollector *collector);
@ -176,7 +178,10 @@ static List * ExpandCitusSupportedTypes(ObjectAddressCollector *collector,
static List * GetDependentRoleIdsFDW(Oid FDWOid); static List * GetDependentRoleIdsFDW(Oid FDWOid);
static List * ExpandRolesToGroups(Oid roleid); static List * ExpandRolesToGroups(Oid roleid);
static ViewDependencyNode * BuildViewDependencyGraph(Oid relationId, HTAB *nodeMap); static ViewDependencyNode * BuildViewDependencyGraph(Oid relationId, HTAB *nodeMap);
static bool IsObjectAddressOwnedByExtension(const ObjectAddress *target,
ObjectAddress *extensionAddress);
static bool ErrorOrWarnIfObjectHasUnsupportedDependency(const
ObjectAddress *objectAddress);
/* /*
* GetUniqueDependenciesList takes a list of object addresses and returns a new list * GetUniqueDependenciesList takes a list of object addresses and returns a new list
@ -774,8 +779,8 @@ SupportedDependencyByCitus(const ObjectAddress *address)
* object doesn't have any unsupported dependency, else throws a message with proper level * object doesn't have any unsupported dependency, else throws a message with proper level
* (except the cluster doesn't have any node) and return true. * (except the cluster doesn't have any node) and return true.
*/ */
bool static bool
ErrorOrWarnIfObjectHasUnsupportedDependency(ObjectAddress *objectAddress) ErrorOrWarnIfObjectHasUnsupportedDependency(const ObjectAddress *objectAddress)
{ {
DeferredErrorMessage *errMsg = DeferErrorIfHasUnsupportedDependency(objectAddress); DeferredErrorMessage *errMsg = DeferErrorIfHasUnsupportedDependency(objectAddress);
if (errMsg != NULL) if (errMsg != NULL)
@ -805,7 +810,7 @@ ErrorOrWarnIfObjectHasUnsupportedDependency(ObjectAddress *objectAddress)
* is not distributed yet, we can create it locally to not affect user's local * is not distributed yet, we can create it locally to not affect user's local
* usage experience. * usage experience.
*/ */
else if (IsObjectDistributed(objectAddress)) else if (IsAnyObjectDistributed(list_make1((ObjectAddress *) objectAddress)))
{ {
RaiseDeferredError(errMsg, ERROR); RaiseDeferredError(errMsg, ERROR);
} }
@ -821,11 +826,31 @@ ErrorOrWarnIfObjectHasUnsupportedDependency(ObjectAddress *objectAddress)
} }
/*
* ErrorOrWarnIfAnyObjectHasUnsupportedDependency iteratively calls
* ErrorOrWarnIfObjectHasUnsupportedDependency for given addresses.
*/
bool
ErrorOrWarnIfAnyObjectHasUnsupportedDependency(List *objectAddresses)
{
ObjectAddress *objectAddress = NULL;
foreach_ptr(objectAddress, objectAddresses)
{
if (ErrorOrWarnIfObjectHasUnsupportedDependency(objectAddress))
{
return true;
}
}
return false;
}
/* /*
* DeferErrorIfHasUnsupportedDependency returns deferred error message if the given * DeferErrorIfHasUnsupportedDependency returns deferred error message if the given
* object has any undistributable dependency. * object has any undistributable dependency.
*/ */
DeferredErrorMessage * static DeferredErrorMessage *
DeferErrorIfHasUnsupportedDependency(const ObjectAddress *objectAddress) DeferErrorIfHasUnsupportedDependency(const ObjectAddress *objectAddress)
{ {
ObjectAddress *undistributableDependency = GetUndistributableDependency( ObjectAddress *undistributableDependency = GetUndistributableDependency(
@ -858,7 +883,7 @@ DeferErrorIfHasUnsupportedDependency(const ObjectAddress *objectAddress)
* Otherwise, callers are expected to throw the error returned from this * Otherwise, callers are expected to throw the error returned from this
* function as a hard one by ignoring the detail part. * function as a hard one by ignoring the detail part.
*/ */
if (!IsObjectDistributed(objectAddress)) if (!IsAnyObjectDistributed(list_make1((ObjectAddress *) objectAddress)))
{ {
appendStringInfo(detailInfo, "\"%s\" will be created only locally", appendStringInfo(detailInfo, "\"%s\" will be created only locally",
objectDescription); objectDescription);
@ -873,7 +898,7 @@ DeferErrorIfHasUnsupportedDependency(const ObjectAddress *objectAddress)
objectDescription, objectDescription,
dependencyDescription); dependencyDescription);
if (IsObjectDistributed(objectAddress)) if (IsAnyObjectDistributed(list_make1((ObjectAddress *) objectAddress)))
{ {
appendStringInfo(hintInfo, appendStringInfo(hintInfo,
"Distribute \"%s\" first to modify \"%s\" on worker nodes", "Distribute \"%s\" first to modify \"%s\" on worker nodes",
@ -900,6 +925,28 @@ DeferErrorIfHasUnsupportedDependency(const ObjectAddress *objectAddress)
} }
/*
* DeferErrorIfAnyObjectHasUnsupportedDependency iteratively calls
* DeferErrorIfHasUnsupportedDependency for given addresses.
*/
DeferredErrorMessage *
DeferErrorIfAnyObjectHasUnsupportedDependency(const List *objectAddresses)
{
DeferredErrorMessage *deferredErrorMessage = NULL;
ObjectAddress *objectAddress = NULL;
foreach_ptr(objectAddress, objectAddresses)
{
deferredErrorMessage = DeferErrorIfHasUnsupportedDependency(objectAddress);
if (deferredErrorMessage)
{
return deferredErrorMessage;
}
}
return NULL;
}
/* /*
* GetUndistributableDependency checks whether object has any non-distributable * GetUndistributableDependency checks whether object has any non-distributable
* dependency. If any one found, it will be returned. * dependency. If any one found, it will be returned.
@ -936,7 +983,7 @@ GetUndistributableDependency(const ObjectAddress *objectAddress)
/* /*
* If object is distributed already, ignore it. * If object is distributed already, ignore it.
*/ */
if (IsObjectDistributed(dependency)) if (IsAnyObjectDistributed(list_make1(dependency)))
{ {
continue; continue;
} }
@ -1015,7 +1062,7 @@ IsTableOwnedByExtension(Oid relationId)
* If extensionAddress is not set to a NULL pointer the function will write the extension * If extensionAddress is not set to a NULL pointer the function will write the extension
* address this function depends on into this location. * address this function depends on into this location.
*/ */
bool static bool
IsObjectAddressOwnedByExtension(const ObjectAddress *target, IsObjectAddressOwnedByExtension(const ObjectAddress *target,
ObjectAddress *extensionAddress) ObjectAddress *extensionAddress)
{ {
@ -1055,6 +1102,27 @@ IsObjectAddressOwnedByExtension(const ObjectAddress *target,
} }
/*
* IsAnyObjectAddressOwnedByExtension iteratively calls IsObjectAddressOwnedByExtension
* for given addresses to determine if any address is owned by an extension.
*/
bool
IsAnyObjectAddressOwnedByExtension(const List *targets,
ObjectAddress *extensionAddress)
{
ObjectAddress *target = NULL;
foreach_ptr(target, targets)
{
if (IsObjectAddressOwnedByExtension(target, extensionAddress))
{
return true;
}
}
return false;
}
/* /*
* FollowNewSupportedDependencies applies filters on pg_depend entries to follow all * FollowNewSupportedDependencies applies filters on pg_depend entries to follow all
* objects which should be distributed before the root object can safely be created. * objects which should be distributed before the root object can safely be created.
@ -1097,7 +1165,9 @@ FollowNewSupportedDependencies(ObjectAddressCollector *collector,
* If the object is already distributed it is not a `new` object that needs to be * If the object is already distributed it is not a `new` object that needs to be
* distributed before we create a dependent object * distributed before we create a dependent object
*/ */
if (IsObjectDistributed(&address)) ObjectAddress *copyAddress = palloc0(sizeof(ObjectAddress));
*copyAddress = address;
if (IsAnyObjectDistributed(list_make1(copyAddress)))
{ {
return false; return false;
} }

View File

@ -53,6 +53,7 @@
static char * CreatePgDistObjectEntryCommand(const ObjectAddress *objectAddress); static char * CreatePgDistObjectEntryCommand(const ObjectAddress *objectAddress);
static int ExecuteCommandAsSuperuser(char *query, int paramCount, Oid *paramTypes, static int ExecuteCommandAsSuperuser(char *query, int paramCount, Oid *paramTypes,
Datum *paramValues); Datum *paramValues);
static bool IsObjectDistributed(const ObjectAddress *address);
PG_FUNCTION_INFO_V1(citus_unmark_object_distributed); PG_FUNCTION_INFO_V1(citus_unmark_object_distributed);
PG_FUNCTION_INFO_V1(master_unmark_object_distributed); PG_FUNCTION_INFO_V1(master_unmark_object_distributed);
@ -240,17 +241,18 @@ ShouldMarkRelationDistributed(Oid relationId)
return false; return false;
} }
ObjectAddress relationAddress = { 0 }; ObjectAddress *relationAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(relationAddress, RelationRelationId, relationId); ObjectAddressSet(*relationAddress, RelationRelationId, relationId);
bool pgObject = (relationId < FirstNormalObjectId); bool pgObject = (relationId < FirstNormalObjectId);
bool isObjectSupported = SupportedDependencyByCitus(&relationAddress); bool isObjectSupported = SupportedDependencyByCitus(relationAddress);
bool ownedByExtension = IsTableOwnedByExtension(relationId); bool ownedByExtension = IsTableOwnedByExtension(relationId);
bool alreadyDistributed = IsObjectDistributed(&relationAddress); bool alreadyDistributed = IsObjectDistributed(relationAddress);
bool hasUnsupportedDependency = bool hasUnsupportedDependency =
DeferErrorIfHasUnsupportedDependency(&relationAddress) != NULL; DeferErrorIfAnyObjectHasUnsupportedDependency(list_make1(relationAddress)) !=
NULL;
bool hasCircularDependency = bool hasCircularDependency =
DeferErrorIfCircularDependencyExists(&relationAddress) != NULL; DeferErrorIfCircularDependencyExists(relationAddress) != NULL;
/* /*
* pgObject: Citus never marks pg objects as distributed * pgObject: Citus never marks pg objects as distributed
@ -390,7 +392,7 @@ UnmarkObjectDistributed(const ObjectAddress *address)
* IsObjectDistributed returns if the object addressed is already distributed in the * IsObjectDistributed returns if the object addressed is already distributed in the
* cluster. This performs a local indexed lookup in pg_dist_object. * cluster. This performs a local indexed lookup in pg_dist_object.
*/ */
bool static bool
IsObjectDistributed(const ObjectAddress *address) IsObjectDistributed(const ObjectAddress *address)
{ {
ScanKeyData key[3]; ScanKeyData key[3];
@ -422,6 +424,26 @@ IsObjectDistributed(const ObjectAddress *address)
} }
/*
* IsAnyObjectDistributed iteratively calls IsObjectDistributed for given addresses to
* determine if any object is distributed.
*/
bool
IsAnyObjectDistributed(const List *addresses)
{
ObjectAddress *address = NULL;
foreach_ptr(address, addresses)
{
if (IsObjectDistributed(address))
{
return true;
}
}
return false;
}
/* /*
* GetDistributedObjectAddressList returns a list of ObjectAddresses that contains all * GetDistributedObjectAddressList returns a list of ObjectAddresses that contains all
* distributed objects as marked in pg_dist_object * distributed objects as marked in pg_dist_object

View File

@ -356,10 +356,9 @@ CreateDependingViewsOnWorkers(Oid relationId)
continue; continue;
} }
ObjectAddress viewAddress = { 0 }; ObjectAddress *viewAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(viewAddress, RelationRelationId, viewOid); ObjectAddressSet(*viewAddress, RelationRelationId, viewOid);
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(viewAddress));
EnsureDependenciesExistOnAllNodes(&viewAddress);
char *createViewCommand = CreateViewDDLCommand(viewOid); char *createViewCommand = CreateViewDDLCommand(viewOid);
char *alterViewOwnerCommand = AlterViewOwnerCommand(viewOid); char *alterViewOwnerCommand = AlterViewOwnerCommand(viewOid);
@ -367,7 +366,7 @@ CreateDependingViewsOnWorkers(Oid relationId)
SendCommandToWorkersWithMetadata(createViewCommand); SendCommandToWorkersWithMetadata(createViewCommand);
SendCommandToWorkersWithMetadata(alterViewOwnerCommand); SendCommandToWorkersWithMetadata(alterViewOwnerCommand);
MarkObjectDistributed(&viewAddress); MarkObjectDistributed(viewAddress);
} }
SendCommandToWorkersWithMetadata(ENABLE_DDL_PROPAGATION); SendCommandToWorkersWithMetadata(ENABLE_DDL_PROPAGATION);
@ -603,10 +602,10 @@ ShouldSyncSequenceMetadata(Oid relationId)
return false; return false;
} }
ObjectAddress sequenceAddress = { 0 }; ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(sequenceAddress, RelationRelationId, relationId); ObjectAddressSet(*sequenceAddress, RelationRelationId, relationId);
return IsObjectDistributed(&sequenceAddress); return IsAnyObjectDistributed(list_make1(sequenceAddress));
} }

View File

@ -70,7 +70,6 @@ master_create_worker_shards(PG_FUNCTION_ARGS)
text *tableNameText = PG_GETARG_TEXT_P(0); text *tableNameText = PG_GETARG_TEXT_P(0);
int32 shardCount = PG_GETARG_INT32(1); int32 shardCount = PG_GETARG_INT32(1);
int32 replicationFactor = PG_GETARG_INT32(2); int32 replicationFactor = PG_GETARG_INT32(2);
ObjectAddress tableAddress = { 0 };
Oid distributedTableId = ResolveRelationId(tableNameText, false); Oid distributedTableId = ResolveRelationId(tableNameText, false);
@ -83,8 +82,9 @@ master_create_worker_shards(PG_FUNCTION_ARGS)
* via their own connection and committed immediately so they become visible to all * via their own connection and committed immediately so they become visible to all
* sessions creating shards. * sessions creating shards.
*/ */
ObjectAddressSet(tableAddress, RelationRelationId, distributedTableId); ObjectAddress *tableAddress = palloc0(sizeof(ObjectAddress));
EnsureDependenciesExistOnAllNodes(&tableAddress); ObjectAddressSet(*tableAddress, RelationRelationId, distributedTableId);
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(tableAddress));
EnsureReferenceTablesExistOnAllNodes(); EnsureReferenceTablesExistOnAllNodes();

View File

@ -96,7 +96,7 @@ master_create_empty_shard(PG_FUNCTION_ARGS)
text *relationNameText = PG_GETARG_TEXT_P(0); text *relationNameText = PG_GETARG_TEXT_P(0);
char *relationName = text_to_cstring(relationNameText); char *relationName = text_to_cstring(relationNameText);
uint32 attemptableNodeCount = 0; uint32 attemptableNodeCount = 0;
ObjectAddress tableAddress = { 0 }; ObjectAddress *tableAddress = palloc0(sizeof(ObjectAddress));
uint32 candidateNodeIndex = 0; uint32 candidateNodeIndex = 0;
List *candidateNodeList = NIL; List *candidateNodeList = NIL;
@ -115,8 +115,8 @@ master_create_empty_shard(PG_FUNCTION_ARGS)
* via their own connection and committed immediately so they become visible to all * via their own connection and committed immediately so they become visible to all
* sessions creating shards. * sessions creating shards.
*/ */
ObjectAddressSet(tableAddress, RelationRelationId, relationId); ObjectAddressSet(*tableAddress, RelationRelationId, relationId);
EnsureDependenciesExistOnAllNodes(&tableAddress); EnsureAllObjectDependenciesExistOnAllNodes(list_make1(tableAddress));
EnsureReferenceTablesExistOnAllNodes(); EnsureReferenceTablesExistOnAllNodes();
/* don't allow the table to be dropped */ /* don't allow the table to be dropped */

View File

@ -181,8 +181,13 @@ WorkerCreateOrReplaceObject(List *sqlStatements)
* same subject. * same subject.
*/ */
Node *parseTree = ParseTreeNode(linitial(sqlStatements)); Node *parseTree = ParseTreeNode(linitial(sqlStatements));
ObjectAddress address = GetObjectAddressFromParseTree(parseTree, true); List *addresses = GetObjectAddressListFromParseTree(parseTree, true);
if (ObjectExists(&address)) Assert(list_length(viewAddresses) == 1);
/* We have already asserted that we have exactly 1 address in the addresses. */
ObjectAddress *address = linitial(addresses);
if (ObjectExists(address))
{ {
/* /*
* Object with name from statement is already found locally, check if states are * Object with name from statement is already found locally, check if states are
@ -195,7 +200,7 @@ WorkerCreateOrReplaceObject(List *sqlStatements)
* recreate our version of the object. This we can compare to what the coordinator * recreate our version of the object. This we can compare to what the coordinator
* sent us. If they match we don't do anything. * sent us. If they match we don't do anything.
*/ */
List *localSqlStatements = CreateStmtListByObjectAddress(&address); List *localSqlStatements = CreateStmtListByObjectAddress(address);
if (CompareStringList(sqlStatements, localSqlStatements)) if (CompareStringList(sqlStatements, localSqlStatements))
{ {
/* /*
@ -208,9 +213,9 @@ WorkerCreateOrReplaceObject(List *sqlStatements)
return false; return false;
} }
char *newName = GenerateBackupNameForCollision(&address); char *newName = GenerateBackupNameForCollision(address);
RenameStmt *renameStmt = CreateRenameStatement(&address, newName); RenameStmt *renameStmt = CreateRenameStatement(address, newName);
const char *sqlRenameStmt = DeparseTreeNode((Node *) renameStmt); const char *sqlRenameStmt = DeparseTreeNode((Node *) renameStmt);
ProcessUtilityParseTree((Node *) renameStmt, sqlRenameStmt, ProcessUtilityParseTree((Node *) renameStmt, sqlRenameStmt,
PROCESS_UTILITY_QUERY, PROCESS_UTILITY_QUERY,

View File

@ -127,7 +127,8 @@ WorkerDropDistributedTable(Oid relationId)
relation_close(distributedRelation, AccessShareLock); relation_close(distributedRelation, AccessShareLock);
/* prepare distributedTableObject for dropping the table */ /* prepare distributedTableObject for dropping the table */
ObjectAddress distributedTableObject = { RelationRelationId, relationId, 0 }; ObjectAddress *distributedTableObject = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*distributedTableObject, RelationRelationId, relationId);
/* Drop dependent sequences from pg_dist_object */ /* Drop dependent sequences from pg_dist_object */
#if PG_VERSION_NUM >= PG_VERSION_13 #if PG_VERSION_NUM >= PG_VERSION_13
@ -144,7 +145,7 @@ WorkerDropDistributedTable(Oid relationId)
UnmarkObjectDistributed(&ownedSequenceAddress); UnmarkObjectDistributed(&ownedSequenceAddress);
} }
UnmarkObjectDistributed(&distributedTableObject); UnmarkObjectDistributed(distributedTableObject);
/* /*
* Remove metadata before object's itself to make functions no-op within * Remove metadata before object's itself to make functions no-op within
@ -177,7 +178,7 @@ WorkerDropDistributedTable(Oid relationId)
* until the user runs DROP EXTENSION. Therefore, we skip dropping the * until the user runs DROP EXTENSION. Therefore, we skip dropping the
* table. * table.
*/ */
if (!IsObjectAddressOwnedByExtension(&distributedTableObject, NULL)) if (!IsAnyObjectAddressOwnedByExtension(list_make1(distributedTableObject), NULL))
{ {
char *relName = get_rel_name(relationId); char *relName = get_rel_name(relationId);
Oid schemaId = get_rel_namespace(relationId); Oid schemaId = get_rel_namespace(relationId);
@ -238,12 +239,9 @@ worker_drop_shell_table(PG_FUNCTION_ARGS)
relation_close(distributedRelation, AccessShareLock); relation_close(distributedRelation, AccessShareLock);
/* prepare distributedTableObject for dropping the table */ /* prepare distributedTableObject for dropping the table */
ObjectAddress distributedTableObject = { InvalidOid, InvalidOid, 0 }; ObjectAddress *distributedTableObject = palloc0(sizeof(ObjectAddress));
distributedTableObject.classId = RelationRelationId; ObjectAddressSet(*distributedTableObject, RelationRelationId, relationId);
distributedTableObject.objectId = relationId; if (IsAnyObjectAddressOwnedByExtension(list_make1(distributedTableObject), NULL))
distributedTableObject.objectSubId = 0;
if (IsObjectAddressOwnedByExtension(&distributedTableObject, NULL))
{ {
PG_RETURN_VOID(); PG_RETURN_VOID();
} }
@ -270,7 +268,7 @@ worker_drop_shell_table(PG_FUNCTION_ARGS)
* *
* We drop the table with cascade since other tables may be referring to it. * We drop the table with cascade since other tables may be referring to it.
*/ */
performDeletion(&distributedTableObject, DROP_CASCADE, performDeletion(distributedTableObject, DROP_CASCADE,
PERFORM_DELETION_INTERNAL); PERFORM_DELETION_INTERNAL);
PG_RETURN_VOID(); PG_RETURN_VOID();

View File

@ -63,7 +63,7 @@ typedef struct DistributeObjectOps
void (*qualify)(Node *); void (*qualify)(Node *);
List * (*preprocess)(Node *, const char *, ProcessUtilityContext); List * (*preprocess)(Node *, const char *, ProcessUtilityContext);
List * (*postprocess)(Node *, const char *); List * (*postprocess)(Node *, const char *);
ObjectAddress (*address)(Node *, bool); List * (*address)(Node *, bool);
bool markDistributed; bool markDistributed;
/* fields used by common implementations, omitted for specialized implementations */ /* fields used by common implementations, omitted for specialized implementations */
@ -159,24 +159,24 @@ extern bool CallDistributedProcedureRemotely(CallStmt *callStmt, DestReceiver *d
/* collation.c - forward declarations */ /* collation.c - forward declarations */
extern char * CreateCollationDDL(Oid collationId); extern char * CreateCollationDDL(Oid collationId);
extern List * CreateCollationDDLsIdempotent(Oid collationId); extern List * CreateCollationDDLsIdempotent(Oid collationId);
extern ObjectAddress AlterCollationOwnerObjectAddress(Node *stmt, bool missing_ok); extern List * AlterCollationOwnerObjectAddress(Node *stmt, bool missing_ok);
extern ObjectAddress RenameCollationStmtObjectAddress(Node *stmt, bool missing_ok); extern List * RenameCollationStmtObjectAddress(Node *stmt, bool missing_ok);
extern ObjectAddress AlterCollationSchemaStmtObjectAddress(Node *stmt, extern List * AlterCollationSchemaStmtObjectAddress(Node *stmt,
bool missing_ok); bool missing_ok);
extern char * GenerateBackupNameForCollationCollision(const ObjectAddress *address); extern char * GenerateBackupNameForCollationCollision(const ObjectAddress *address);
extern ObjectAddress DefineCollationStmtObjectAddress(Node *stmt, bool missing_ok); extern List * DefineCollationStmtObjectAddress(Node *stmt, bool missing_ok);
/* database.c - forward declarations */ /* database.c - forward declarations */
extern ObjectAddress AlterDatabaseOwnerObjectAddress(Node *node, bool missing_ok); extern List * AlterDatabaseOwnerObjectAddress(Node *node, bool missing_ok);
extern List * DatabaseOwnerDDLCommands(const ObjectAddress *address); extern List * DatabaseOwnerDDLCommands(const ObjectAddress *address);
/* domain.c - forward declarations */ /* domain.c - forward declarations */
extern ObjectAddress CreateDomainStmtObjectAddress(Node *node, bool missing_ok); extern List * CreateDomainStmtObjectAddress(Node *node, bool missing_ok);
extern ObjectAddress AlterDomainStmtObjectAddress(Node *node, bool missing_ok); extern List * AlterDomainStmtObjectAddress(Node *node, bool missing_ok);
extern ObjectAddress DomainRenameConstraintStmtObjectAddress(Node *node, extern List * DomainRenameConstraintStmtObjectAddress(Node *node,
bool missing_ok); bool missing_ok);
extern ObjectAddress AlterDomainOwnerStmtObjectAddress(Node *node, bool missing_ok); extern List * AlterDomainOwnerStmtObjectAddress(Node *node, bool missing_ok);
extern ObjectAddress RenameDomainStmtObjectAddress(Node *node, bool missing_ok); extern List * RenameDomainStmtObjectAddress(Node *node, bool missing_ok);
extern CreateDomainStmt * RecreateDomainStmt(Oid domainOid); extern CreateDomainStmt * RecreateDomainStmt(Oid domainOid);
extern Oid get_constraint_typid(Oid conoid); extern Oid get_constraint_typid(Oid conoid);
@ -208,9 +208,9 @@ extern List * PreprocessAlterExtensionContentsStmt(Node *node,
ProcessUtilityContext ProcessUtilityContext
processUtilityContext); processUtilityContext);
extern List * CreateExtensionDDLCommand(const ObjectAddress *extensionAddress); extern List * CreateExtensionDDLCommand(const ObjectAddress *extensionAddress);
extern ObjectAddress AlterExtensionSchemaStmtObjectAddress(Node *stmt, extern List * AlterExtensionSchemaStmtObjectAddress(Node *stmt,
bool missing_ok); bool missing_ok);
extern ObjectAddress AlterExtensionUpdateStmtObjectAddress(Node *stmt, extern List * AlterExtensionUpdateStmtObjectAddress(Node *stmt,
bool missing_ok); bool missing_ok);
extern void CreateExtensionWithVersion(char *extname, char *extVersion); extern void CreateExtensionWithVersion(char *extname, char *extVersion);
extern void AlterExtensionUpdateStmt(char *extname, char *extVersion); extern void AlterExtensionUpdateStmt(char *extname, char *extVersion);
@ -263,10 +263,10 @@ extern Acl * GetPrivilegesForFDW(Oid FDWOid);
extern List * PreprocessGrantOnForeignServerStmt(Node *node, const char *queryString, extern List * PreprocessGrantOnForeignServerStmt(Node *node, const char *queryString,
ProcessUtilityContext ProcessUtilityContext
processUtilityContext); processUtilityContext);
extern ObjectAddress CreateForeignServerStmtObjectAddress(Node *node, bool missing_ok); extern List * CreateForeignServerStmtObjectAddress(Node *node, bool missing_ok);
extern ObjectAddress AlterForeignServerStmtObjectAddress(Node *node, bool missing_ok); extern List * AlterForeignServerStmtObjectAddress(Node *node, bool missing_ok);
extern ObjectAddress RenameForeignServerStmtObjectAddress(Node *node, bool missing_ok); extern List * RenameForeignServerStmtObjectAddress(Node *node, bool missing_ok);
extern ObjectAddress AlterForeignServerOwnerStmtObjectAddress(Node *node, bool extern List * AlterForeignServerOwnerStmtObjectAddress(Node *node, bool
missing_ok); missing_ok);
extern List * GetForeignServerCreateDDLCommand(Oid serverId); extern List * GetForeignServerCreateDDLCommand(Oid serverId);
@ -282,25 +282,25 @@ extern List * PreprocessCreateFunctionStmt(Node *stmt, const char *queryString,
ProcessUtilityContext processUtilityContext); ProcessUtilityContext processUtilityContext);
extern List * PostprocessCreateFunctionStmt(Node *stmt, extern List * PostprocessCreateFunctionStmt(Node *stmt,
const char *queryString); const char *queryString);
extern ObjectAddress CreateFunctionStmtObjectAddress(Node *stmt, extern List * CreateFunctionStmtObjectAddress(Node *stmt,
bool missing_ok); bool missing_ok);
extern ObjectAddress DefineAggregateStmtObjectAddress(Node *stmt, extern List * DefineAggregateStmtObjectAddress(Node *stmt,
bool missing_ok); bool missing_ok);
extern List * PreprocessAlterFunctionStmt(Node *stmt, const char *queryString, extern List * PreprocessAlterFunctionStmt(Node *stmt, const char *queryString,
ProcessUtilityContext processUtilityContext); ProcessUtilityContext processUtilityContext);
extern ObjectAddress AlterFunctionStmtObjectAddress(Node *stmt, extern List * AlterFunctionStmtObjectAddress(Node *stmt,
bool missing_ok); bool missing_ok);
extern ObjectAddress RenameFunctionStmtObjectAddress(Node *stmt, extern List * RenameFunctionStmtObjectAddress(Node *stmt,
bool missing_ok); bool missing_ok);
extern ObjectAddress AlterFunctionOwnerObjectAddress(Node *stmt, extern List * AlterFunctionOwnerObjectAddress(Node *stmt,
bool missing_ok); bool missing_ok);
extern ObjectAddress AlterFunctionSchemaStmtObjectAddress(Node *stmt, extern List * AlterFunctionSchemaStmtObjectAddress(Node *stmt,
bool missing_ok); bool missing_ok);
extern List * PreprocessAlterFunctionDependsStmt(Node *stmt, extern List * PreprocessAlterFunctionDependsStmt(Node *stmt,
const char *queryString, const char *queryString,
ProcessUtilityContext ProcessUtilityContext
processUtilityContext); processUtilityContext);
extern ObjectAddress AlterFunctionDependsStmtObjectAddress(Node *stmt, extern List * AlterFunctionDependsStmtObjectAddress(Node *stmt,
bool missing_ok); bool missing_ok);
extern List * PreprocessGrantOnFunctionStmt(Node *node, const char *queryString, extern List * PreprocessGrantOnFunctionStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext); ProcessUtilityContext processUtilityContext);
@ -340,7 +340,7 @@ extern List * ExecuteFunctionOnEachTableIndex(Oid relationId, PGIndexProcessor
extern bool IsReindexWithParam_compat(ReindexStmt *stmt, char *paramName); extern bool IsReindexWithParam_compat(ReindexStmt *stmt, char *paramName);
/* objectaddress.c - forward declarations */ /* objectaddress.c - forward declarations */
extern ObjectAddress CreateExtensionStmtObjectAddress(Node *stmt, bool missing_ok); extern List * CreateExtensionStmtObjectAddress(Node *stmt, bool missing_ok);
/* policy.c - forward declarations */ /* policy.c - forward declarations */
@ -376,9 +376,9 @@ extern List * PostprocessAlterRoleStmt(Node *stmt, const char *queryString);
extern List * PreprocessAlterRoleSetStmt(Node *stmt, const char *queryString, extern List * PreprocessAlterRoleSetStmt(Node *stmt, const char *queryString,
ProcessUtilityContext processUtilityContext); ProcessUtilityContext processUtilityContext);
extern List * GenerateAlterRoleSetCommandForRole(Oid roleid); extern List * GenerateAlterRoleSetCommandForRole(Oid roleid);
extern ObjectAddress AlterRoleStmtObjectAddress(Node *node, extern List * AlterRoleStmtObjectAddress(Node *node,
bool missing_ok); bool missing_ok);
extern ObjectAddress AlterRoleSetStmtObjectAddress(Node *node, extern List * AlterRoleSetStmtObjectAddress(Node *node,
bool missing_ok); bool missing_ok);
extern List * PreprocessCreateRoleStmt(Node *stmt, const char *queryString, extern List * PreprocessCreateRoleStmt(Node *stmt, const char *queryString,
ProcessUtilityContext processUtilityContext); ProcessUtilityContext processUtilityContext);
@ -388,7 +388,7 @@ extern List * PreprocessGrantRoleStmt(Node *stmt, const char *queryString,
ProcessUtilityContext processUtilityContext); ProcessUtilityContext processUtilityContext);
extern List * PostprocessGrantRoleStmt(Node *stmt, const char *queryString); extern List * PostprocessGrantRoleStmt(Node *stmt, const char *queryString);
extern List * GenerateCreateOrAlterRoleCommand(Oid roleOid); extern List * GenerateCreateOrAlterRoleCommand(Oid roleOid);
ObjectAddress CreateRoleStmtObjectAddress(Node *stmt, bool missing_ok); extern List * CreateRoleStmtObjectAddress(Node *stmt, bool missing_ok);
extern void UnmarkRolesDistributed(List *roles); extern void UnmarkRolesDistributed(List *roles);
extern List * FilterDistributedRoles(List *roles); extern List * FilterDistributedRoles(List *roles);
@ -402,8 +402,8 @@ extern List * PreprocessAlterObjectSchemaStmt(Node *alterObjectSchemaStmt,
const char *alterObjectSchemaCommand); const char *alterObjectSchemaCommand);
extern List * PreprocessGrantOnSchemaStmt(Node *node, const char *queryString, extern List * PreprocessGrantOnSchemaStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext); ProcessUtilityContext processUtilityContext);
extern ObjectAddress CreateSchemaStmtObjectAddress(Node *node, bool missing_ok); extern List * CreateSchemaStmtObjectAddress(Node *node, bool missing_ok);
extern ObjectAddress AlterSchemaRenameStmtObjectAddress(Node *node, bool missing_ok); extern List * AlterSchemaRenameStmtObjectAddress(Node *node, bool missing_ok);
/* sequence.c - forward declarations */ /* sequence.c - forward declarations */
extern List * PreprocessAlterSequenceStmt(Node *node, const char *queryString, extern List * PreprocessAlterSequenceStmt(Node *node, const char *queryString,
@ -422,10 +422,10 @@ extern List * PreprocessRenameSequenceStmt(Node *node, const char *queryString,
extern List * PreprocessGrantOnSequenceStmt(Node *node, const char *queryString, extern List * PreprocessGrantOnSequenceStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext); ProcessUtilityContext processUtilityContext);
extern List * PostprocessGrantOnSequenceStmt(Node *node, const char *queryString); extern List * PostprocessGrantOnSequenceStmt(Node *node, const char *queryString);
extern ObjectAddress AlterSequenceStmtObjectAddress(Node *node, bool missing_ok); extern List * AlterSequenceStmtObjectAddress(Node *node, bool missing_ok);
extern ObjectAddress AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok); extern List * AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok);
extern ObjectAddress AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok); extern List * AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok);
extern ObjectAddress RenameSequenceStmtObjectAddress(Node *node, bool missing_ok); extern List * RenameSequenceStmtObjectAddress(Node *node, bool missing_ok);
extern void ErrorIfUnsupportedSeqStmt(CreateSeqStmt *createSeqStmt); extern void ErrorIfUnsupportedSeqStmt(CreateSeqStmt *createSeqStmt);
extern void ErrorIfDistributedAlterSeqOwnedBy(AlterSeqStmt *alterSeqStmt); extern void ErrorIfDistributedAlterSeqOwnedBy(AlterSeqStmt *alterSeqStmt);
extern char * GenerateBackupNameForSequenceCollision(const ObjectAddress *address); extern char * GenerateBackupNameForSequenceCollision(const ObjectAddress *address);
@ -436,7 +436,7 @@ extern void RenameExistingSequenceWithDifferentTypeIfExists(RangeVar *sequence,
extern List * PreprocessCreateStatisticsStmt(Node *node, const char *queryString, extern List * PreprocessCreateStatisticsStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext); ProcessUtilityContext processUtilityContext);
extern List * PostprocessCreateStatisticsStmt(Node *node, const char *queryString); extern List * PostprocessCreateStatisticsStmt(Node *node, const char *queryString);
extern ObjectAddress CreateStatisticsStmtObjectAddress(Node *node, bool missingOk); extern List * CreateStatisticsStmtObjectAddress(Node *node, bool missingOk);
extern List * PreprocessDropStatisticsStmt(Node *node, const char *queryString, extern List * PreprocessDropStatisticsStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext); ProcessUtilityContext processUtilityContext);
extern List * PreprocessAlterStatisticsRenameStmt(Node *node, const char *queryString, extern List * PreprocessAlterStatisticsRenameStmt(Node *node, const char *queryString,
@ -446,7 +446,7 @@ extern List * PreprocessAlterStatisticsSchemaStmt(Node *node, const char *queryS
ProcessUtilityContext ProcessUtilityContext
processUtilityContext); processUtilityContext);
extern List * PostprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString); extern List * PostprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString);
extern ObjectAddress AlterStatisticsSchemaStmtObjectAddress(Node *node, bool missingOk); extern List * AlterStatisticsSchemaStmtObjectAddress(Node *node, bool missingOk);
extern List * PreprocessAlterStatisticsStmt(Node *node, const char *queryString, extern List * PreprocessAlterStatisticsStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext); ProcessUtilityContext processUtilityContext);
extern List * PreprocessAlterStatisticsOwnerStmt(Node *node, const char *queryString, extern List * PreprocessAlterStatisticsOwnerStmt(Node *node, const char *queryString,
@ -487,7 +487,7 @@ extern void ErrorUnsupportedAlterTableAddColumn(Oid relationId, AlterTableCmd *c
extern void ErrorIfUnsupportedConstraint(Relation relation, char distributionMethod, extern void ErrorIfUnsupportedConstraint(Relation relation, char distributionMethod,
char referencingReplicationModel, char referencingReplicationModel,
Var *distributionColumn, uint32 colocationId); Var *distributionColumn, uint32 colocationId);
extern ObjectAddress AlterTableSchemaStmtObjectAddress(Node *stmt, extern List * AlterTableSchemaStmtObjectAddress(Node *stmt,
bool missing_ok); bool missing_ok);
extern List * MakeNameListFromRangeVar(const RangeVar *rel); extern List * MakeNameListFromRangeVar(const RangeVar *rel);
extern Oid GetSequenceOid(Oid relationId, AttrNumber attnum); extern Oid GetSequenceOid(Oid relationId, AttrNumber attnum);
@ -499,29 +499,29 @@ extern List * GetCreateTextSearchConfigStatements(const ObjectAddress *address);
extern List * GetCreateTextSearchDictionaryStatements(const ObjectAddress *address); extern List * GetCreateTextSearchDictionaryStatements(const ObjectAddress *address);
extern List * CreateTextSearchConfigDDLCommandsIdempotent(const ObjectAddress *address); extern List * CreateTextSearchConfigDDLCommandsIdempotent(const ObjectAddress *address);
extern List * CreateTextSearchDictDDLCommandsIdempotent(const ObjectAddress *address); extern List * CreateTextSearchDictDDLCommandsIdempotent(const ObjectAddress *address);
extern ObjectAddress CreateTextSearchConfigurationObjectAddress(Node *node, extern List * CreateTextSearchConfigurationObjectAddress(Node *node,
bool missing_ok); bool missing_ok);
extern ObjectAddress CreateTextSearchDictObjectAddress(Node *node, extern List * CreateTextSearchDictObjectAddress(Node *node,
bool missing_ok); bool missing_ok);
extern ObjectAddress RenameTextSearchConfigurationStmtObjectAddress(Node *node, extern List * RenameTextSearchConfigurationStmtObjectAddress(Node *node,
bool missing_ok); bool missing_ok);
extern ObjectAddress RenameTextSearchDictionaryStmtObjectAddress(Node *node, extern List * RenameTextSearchDictionaryStmtObjectAddress(Node *node,
bool missing_ok); bool missing_ok);
extern ObjectAddress AlterTextSearchConfigurationStmtObjectAddress(Node *node, extern List * AlterTextSearchConfigurationStmtObjectAddress(Node *node,
bool missing_ok); bool missing_ok);
extern ObjectAddress AlterTextSearchDictionaryStmtObjectAddress(Node *node, extern List * AlterTextSearchDictionaryStmtObjectAddress(Node *node,
bool missing_ok); bool missing_ok);
extern ObjectAddress AlterTextSearchConfigurationSchemaStmtObjectAddress(Node *node, extern List * AlterTextSearchConfigurationSchemaStmtObjectAddress(Node *node,
bool missing_ok); bool missing_ok);
extern ObjectAddress AlterTextSearchDictionarySchemaStmtObjectAddress(Node *node, extern List * AlterTextSearchDictionarySchemaStmtObjectAddress(Node *node,
bool missing_ok); bool missing_ok);
extern ObjectAddress TextSearchConfigurationCommentObjectAddress(Node *node, extern List * TextSearchConfigurationCommentObjectAddress(Node *node,
bool missing_ok); bool missing_ok);
extern ObjectAddress TextSearchDictCommentObjectAddress(Node *node, extern List * TextSearchDictCommentObjectAddress(Node *node,
bool missing_ok); bool missing_ok);
extern ObjectAddress AlterTextSearchConfigurationOwnerObjectAddress(Node *node, extern List * AlterTextSearchConfigurationOwnerObjectAddress(Node *node,
bool missing_ok); bool missing_ok);
extern ObjectAddress AlterTextSearchDictOwnerObjectAddress(Node *node, extern List * AlterTextSearchDictOwnerObjectAddress(Node *node,
bool missing_ok); bool missing_ok);
extern char * GenerateBackupNameForTextSearchConfiguration(const ObjectAddress *address); extern char * GenerateBackupNameForTextSearchConfiguration(const ObjectAddress *address);
extern char * GenerateBackupNameForTextSearchDict(const ObjectAddress *address); extern char * GenerateBackupNameForTextSearchDict(const ObjectAddress *address);
@ -535,16 +535,16 @@ extern List * PreprocessRenameTypeAttributeStmt(Node *stmt, const char *queryStr
ProcessUtilityContext ProcessUtilityContext
processUtilityContext); processUtilityContext);
extern Node * CreateTypeStmtByObjectAddress(const ObjectAddress *address); extern Node * CreateTypeStmtByObjectAddress(const ObjectAddress *address);
extern ObjectAddress CompositeTypeStmtObjectAddress(Node *stmt, bool missing_ok); extern List * CompositeTypeStmtObjectAddress(Node *stmt, bool missing_ok);
extern ObjectAddress CreateEnumStmtObjectAddress(Node *stmt, bool missing_ok); extern List * CreateEnumStmtObjectAddress(Node *stmt, bool missing_ok);
extern ObjectAddress AlterTypeStmtObjectAddress(Node *stmt, bool missing_ok); extern List * AlterTypeStmtObjectAddress(Node *stmt, bool missing_ok);
extern ObjectAddress AlterEnumStmtObjectAddress(Node *stmt, bool missing_ok); extern List * AlterEnumStmtObjectAddress(Node *stmt, bool missing_ok);
extern ObjectAddress RenameTypeStmtObjectAddress(Node *stmt, bool missing_ok); extern List * RenameTypeStmtObjectAddress(Node *stmt, bool missing_ok);
extern ObjectAddress AlterTypeSchemaStmtObjectAddress(Node *stmt, extern List * AlterTypeSchemaStmtObjectAddress(Node *stmt,
bool missing_ok); bool missing_ok);
extern ObjectAddress RenameTypeAttributeStmtObjectAddress(Node *stmt, extern List * RenameTypeAttributeStmtObjectAddress(Node *stmt,
bool missing_ok); bool missing_ok);
extern ObjectAddress AlterTypeOwnerObjectAddress(Node *stmt, bool missing_ok); extern List * AlterTypeOwnerObjectAddress(Node *stmt, bool missing_ok);
extern List * CreateTypeDDLCommandsIdempotent(const ObjectAddress *typeAddress); extern List * CreateTypeDDLCommandsIdempotent(const ObjectAddress *typeAddress);
extern char * GenerateBackupNameForTypeCollision(const ObjectAddress *address); extern char * GenerateBackupNameForTypeCollision(const ObjectAddress *address);
@ -565,8 +565,8 @@ extern List * PostprocessVacuumStmt(Node *node, const char *vacuumCommand);
extern List * PreprocessViewStmt(Node *node, const char *queryString, extern List * PreprocessViewStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext); ProcessUtilityContext processUtilityContext);
extern List * PostprocessViewStmt(Node *node, const char *queryString); extern List * PostprocessViewStmt(Node *node, const char *queryString);
extern ObjectAddress ViewStmtObjectAddress(Node *node, bool missing_ok); extern List * ViewStmtObjectAddress(Node *node, bool missing_ok);
extern ObjectAddress AlterViewStmtObjectAddress(Node *node, bool missing_ok); extern List * AlterViewStmtObjectAddress(Node *node, bool missing_ok);
extern List * PreprocessDropViewStmt(Node *node, const char *queryString, extern List * PreprocessDropViewStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext); ProcessUtilityContext processUtilityContext);
extern char * CreateViewDDLCommand(Oid viewOid); extern char * CreateViewDDLCommand(Oid viewOid);
@ -582,11 +582,11 @@ extern List * PreprocessAlterViewStmt(Node *node, const char *queryString,
extern List * PostprocessAlterViewStmt(Node *node, const char *queryString); extern List * PostprocessAlterViewStmt(Node *node, const char *queryString);
extern List * PreprocessRenameViewStmt(Node *node, const char *queryString, extern List * PreprocessRenameViewStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext); ProcessUtilityContext processUtilityContext);
extern ObjectAddress RenameViewStmtObjectAddress(Node *node, bool missing_ok); extern List * RenameViewStmtObjectAddress(Node *node, bool missing_ok);
extern List * PreprocessAlterViewSchemaStmt(Node *node, const char *queryString, extern List * PreprocessAlterViewSchemaStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext); ProcessUtilityContext processUtilityContext);
extern List * PostprocessAlterViewSchemaStmt(Node *node, const char *queryString); extern List * PostprocessAlterViewSchemaStmt(Node *node, const char *queryString);
extern ObjectAddress AlterViewSchemaStmtObjectAddress(Node *node, bool missing_ok); extern List * AlterViewSchemaStmtObjectAddress(Node *node, bool missing_ok);
extern bool IsViewRenameStmt(RenameStmt *renameStmt); extern bool IsViewRenameStmt(RenameStmt *renameStmt);
/* trigger.c - forward declarations */ /* trigger.c - forward declarations */
@ -594,7 +594,7 @@ extern List * GetExplicitTriggerCommandList(Oid relationId);
extern HeapTuple GetTriggerTupleById(Oid triggerId, bool missingOk); extern HeapTuple GetTriggerTupleById(Oid triggerId, bool missingOk);
extern List * GetExplicitTriggerIdList(Oid relationId); extern List * GetExplicitTriggerIdList(Oid relationId);
extern List * PostprocessCreateTriggerStmt(Node *node, const char *queryString); extern List * PostprocessCreateTriggerStmt(Node *node, const char *queryString);
extern ObjectAddress CreateTriggerStmtObjectAddress(Node *node, bool missingOk); extern List * CreateTriggerStmtObjectAddress(Node *node, bool missingOk);
extern void CreateTriggerEventExtendNames(CreateTrigStmt *createTriggerStmt, extern void CreateTriggerEventExtendNames(CreateTrigStmt *createTriggerStmt,
char *schemaName, uint64 shardId); char *schemaName, uint64 shardId);
extern List * PostprocessAlterTriggerRenameStmt(Node *node, const char *queryString); extern List * PostprocessAlterTriggerRenameStmt(Node *node, const char *queryString);

View File

@ -148,8 +148,8 @@ extern void QualifyAlterTypeOwnerStmt(Node *stmt);
extern char * GetTypeNamespaceNameByNameList(List *names); extern char * GetTypeNamespaceNameByNameList(List *names);
extern Oid TypeOidGetNamespaceOid(Oid typeOid); extern Oid TypeOidGetNamespaceOid(Oid typeOid);
extern ObjectAddress GetObjectAddressFromParseTree(Node *parseTree, bool missing_ok); extern List * GetObjectAddressListFromParseTree(Node *parseTree, bool missing_ok);
extern ObjectAddress RenameAttributeStmtObjectAddress(Node *stmt, bool missing_ok); extern List * RenameAttributeStmtObjectAddress(Node *stmt, bool missing_ok);
/* forward declarations for deparse_view_stmts.c */ /* forward declarations for deparse_view_stmts.c */
extern void QualifyDropViewStmt(Node *node); extern void QualifyDropViewStmt(Node *node);

View File

@ -23,10 +23,9 @@ extern List * GetUniqueDependenciesList(List *objectAddressesList);
extern List * GetDependenciesForObject(const ObjectAddress *target); extern List * GetDependenciesForObject(const ObjectAddress *target);
extern List * GetAllSupportedDependenciesForObject(const ObjectAddress *target); extern List * GetAllSupportedDependenciesForObject(const ObjectAddress *target);
extern List * GetAllDependenciesForObject(const ObjectAddress *target); extern List * GetAllDependenciesForObject(const ObjectAddress *target);
extern bool ErrorOrWarnIfObjectHasUnsupportedDependency(ObjectAddress *objectAddress); extern bool ErrorOrWarnIfAnyObjectHasUnsupportedDependency(List *objectAddresses);
extern DeferredErrorMessage * DeferErrorIfHasUnsupportedDependency(const extern DeferredErrorMessage * DeferErrorIfAnyObjectHasUnsupportedDependency(const List *
ObjectAddress * objectAddresses);
objectAddress);
extern List * OrderObjectAddressListInDependencyOrder(List *objectAddressList); extern List * OrderObjectAddressListInDependencyOrder(List *objectAddressList);
extern bool SupportedDependencyByCitus(const ObjectAddress *address); extern bool SupportedDependencyByCitus(const ObjectAddress *address);
extern List * GetPgDependTuplesForDependingObjects(Oid targetObjectClassId, extern List * GetPgDependTuplesForDependingObjects(Oid targetObjectClassId,

View File

@ -20,14 +20,14 @@
extern bool ObjectExists(const ObjectAddress *address); extern bool ObjectExists(const ObjectAddress *address);
extern bool CitusExtensionObject(const ObjectAddress *objectAddress); extern bool CitusExtensionObject(const ObjectAddress *objectAddress);
extern bool IsObjectDistributed(const ObjectAddress *address); extern bool IsAnyObjectDistributed(const List *addresses);
extern bool ClusterHasDistributedFunctionWithDistArgument(void); extern bool ClusterHasDistributedFunctionWithDistArgument(void);
extern void MarkObjectDistributed(const ObjectAddress *distAddress); extern void MarkObjectDistributed(const ObjectAddress *distAddress);
extern void MarkObjectDistributedViaSuperUser(const ObjectAddress *distAddress); extern void MarkObjectDistributedViaSuperUser(const ObjectAddress *distAddress);
extern void MarkObjectDistributedLocally(const ObjectAddress *distAddress); extern void MarkObjectDistributedLocally(const ObjectAddress *distAddress);
extern void UnmarkObjectDistributed(const ObjectAddress *address); extern void UnmarkObjectDistributed(const ObjectAddress *address);
extern bool IsTableOwnedByExtension(Oid relationId); extern bool IsTableOwnedByExtension(Oid relationId);
extern bool IsObjectAddressOwnedByExtension(const ObjectAddress *target, extern bool IsAnyObjectAddressOwnedByExtension(const List *targets,
ObjectAddress *extensionAddress); ObjectAddress *extensionAddress);
extern ObjectAddress PgGetObjectAddress(char *ttype, ArrayType *namearr, extern ObjectAddress PgGetObjectAddress(char *ttype, ArrayType *namearr,
ArrayType *argsarr); ArrayType *argsarr);

View File

@ -258,15 +258,15 @@ extern void CreateDistributedTable(Oid relationId, char *distributionColumnName,
extern void CreateTruncateTrigger(Oid relationId); extern void CreateTruncateTrigger(Oid relationId);
extern TableConversionReturn * UndistributeTable(TableConversionParameters *params); extern TableConversionReturn * UndistributeTable(TableConversionParameters *params);
extern void EnsureDependenciesExistOnAllNodes(const ObjectAddress *target); extern void EnsureAllObjectDependenciesExistOnAllNodes(const List *targets);
extern DeferredErrorMessage * DeferErrorIfCircularDependencyExists(const extern DeferredErrorMessage * DeferErrorIfCircularDependencyExists(const
ObjectAddress * ObjectAddress *
objectAddress); objectAddress);
extern List * GetDistributableDependenciesForObject(const ObjectAddress *target); extern List * GetDistributableDependenciesForObject(const ObjectAddress *target);
extern List * GetDependencyCreateDDLCommands(const ObjectAddress *dependency); extern List * GetAllDependencyCreateDDLCommands(const List *dependencies);
extern bool ShouldPropagate(void); extern bool ShouldPropagate(void);
extern bool ShouldPropagateCreateInCoordinatedTransction(void); extern bool ShouldPropagateCreateInCoordinatedTransction(void);
extern bool ShouldPropagateObject(const ObjectAddress *address); extern bool ShouldPropagateAnyObject(List *addresses);
extern List * ReplicateAllObjectsToNodeCommandList(const char *nodeName, int nodePort); extern List * ReplicateAllObjectsToNodeCommandList(const char *nodeName, int nodePort);
/* Remaining metadata utility functions */ /* Remaining metadata utility functions */