diff --git a/src/backend/distributed/commands/cluster.c b/src/backend/distributed/commands/cluster.c index a7def3c48..d1dd313fe 100644 --- a/src/backend/distributed/commands/cluster.c +++ b/src/backend/distributed/commands/cluster.c @@ -15,10 +15,11 @@ #include "distributed/metadata_cache.h" -/* placeholder for PlanClusterStmt */ +/* placeholder for PreprocessClusterStmt */ List * -PlanClusterStmt(ClusterStmt *clusterStmt, const char *clusterCommand) +PreprocessClusterStmt(Node *node, const char *clusterCommand) { + ClusterStmt *clusterStmt = castNode(ClusterStmt, node); bool showPropagationWarning = false; /* CLUSTER all */ diff --git a/src/backend/distributed/commands/collation.c b/src/backend/distributed/commands/collation.c index 615d5f90e..af0eb6bcf 100644 --- a/src/backend/distributed/commands/collation.c +++ b/src/backend/distributed/commands/collation.c @@ -16,6 +16,7 @@ #include "distributed/commands/utility_hook.h" #include "distributed/commands.h" #include "distributed/deparser.h" +#include "distributed/listutils.h" #include "distributed/master_metadata_utility.h" #include "distributed/metadata/distobject.h" #include "distributed/metadata_sync.h" @@ -163,14 +164,15 @@ CreateCollationDDLsIdempotent(Oid collationId) ObjectAddress -AlterCollationOwnerObjectAddress(AlterOwnerStmt *stmt) +AlterCollationOwnerObjectAddress(Node *node, bool missing_ok) { + AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); Relation relation; Assert(stmt->objectType == OBJECT_COLLATION); return get_object_address(stmt->objectType, stmt->object, &relation, - AccessExclusiveLock, false); + AccessExclusiveLock, missing_ok); } @@ -217,13 +219,14 @@ FilterNameListForDistributedCollations(List *objects, bool missing_ok, List * -PlanDropCollationStmt(DropStmt *stmt) +PreprocessDropCollationStmt(Node *node, const char *queryString) { + DropStmt *stmt = castNode(DropStmt, node); + /* * We swap the list of objects to remove during deparse so we need a reference back to * the old list to put back */ - ListCell *addressCell = NULL; List *distributedTypeAddresses = NIL; if (!ShouldPropagate()) @@ -253,10 +256,10 @@ PlanDropCollationStmt(DropStmt *stmt) /* * remove the entries for the distributed objects on dropping */ - foreach(addressCell, distributedTypeAddresses) + ObjectAddress *addressItem = NULL; + foreach_ptr(addressItem, distributedTypeAddresses) { - ObjectAddress *address = (ObjectAddress *) lfirst(addressCell); - UnmarkObjectDistributed(address); + UnmarkObjectDistributed(addressItem); } /* @@ -279,19 +282,20 @@ PlanDropCollationStmt(DropStmt *stmt) /* - * PlanAlterCollationOwnerStmt is called for change of ownership of collations + * PreprocessAlterCollationOwnerStmt is called for change of ownership of collations * before the ownership is changed on the local instance. * * If the type for which the owner is changed is distributed we execute the change on all * the workers to keep the type in sync across the cluster. */ List * -PlanAlterCollationOwnerStmt(AlterOwnerStmt *stmt, const char *queryString) +PreprocessAlterCollationOwnerStmt(Node *node, const char *queryString) { + AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); Assert(stmt->objectType == OBJECT_COLLATION); - ObjectAddress *collationAddress = GetObjectAddressFromParseTree((Node *) stmt, false); - if (!ShouldPropagateObject(collationAddress)) + ObjectAddress collationAddress = GetObjectAddressFromParseTree((Node *) stmt, false); + if (!ShouldPropagateObject(&collationAddress)) { return NIL; } @@ -311,7 +315,7 @@ PlanAlterCollationOwnerStmt(AlterOwnerStmt *stmt, const char *queryString) /* - * PlanRenameCollationStmt is called when the user is renaming the collation. The invocation happens + * PreprocessRenameCollationStmt is called when the user is renaming the collation. The invocation happens * before the statement is applied locally. * * As the collation already exists we have access to the ObjectAddress for the collation, this is @@ -319,10 +323,11 @@ PlanAlterCollationOwnerStmt(AlterOwnerStmt *stmt, const char *queryString) * executed on all the workers to keep the collation in sync across the cluster. */ List * -PlanRenameCollationStmt(RenameStmt *stmt, const char *queryString) +PreprocessRenameCollationStmt(Node *node, const char *queryString) { - ObjectAddress *collationAddress = GetObjectAddressFromParseTree((Node *) stmt, false); - if (!ShouldPropagateObject(collationAddress)) + RenameStmt *stmt = castNode(RenameStmt, node); + ObjectAddress collationAddress = GetObjectAddressFromParseTree((Node *) stmt, false); + if (!ShouldPropagateObject(&collationAddress)) { return NIL; } @@ -345,18 +350,19 @@ PlanRenameCollationStmt(RenameStmt *stmt, const char *queryString) /* - * PlanAlterCollationSchemaStmt is executed before the statement is applied to the local + * PreprocessAlterCollationSchemaStmt is executed before the statement is applied to the local * postgres instance. * * In this stage we can prepare the commands that need to be run on all workers. */ List * -PlanAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString) +PreprocessAlterCollationSchemaStmt(Node *node, const char *queryString) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); Assert(stmt->objectType == OBJECT_COLLATION); - ObjectAddress *collationAddress = GetObjectAddressFromParseTree((Node *) stmt, false); - if (!ShouldPropagateObject(collationAddress)) + ObjectAddress collationAddress = GetObjectAddressFromParseTree((Node *) stmt, false); + if (!ShouldPropagateObject(&collationAddress)) { return NIL; } @@ -377,23 +383,26 @@ PlanAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryStrin /* - * ProcessAlterCollationSchemaStmt is executed after the change has been applied locally, we + * PostprocessAlterCollationSchemaStmt is executed after the change has been applied locally, we * can now use the new dependencies of the type to ensure all its dependencies exist on * the workers before we apply the commands remotely. */ -void -ProcessAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString) +List * +PostprocessAlterCollationSchemaStmt(Node *node, const char *queryString) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); Assert(stmt->objectType == OBJECT_COLLATION); - ObjectAddress *collationAddress = GetObjectAddressFromParseTree((Node *) stmt, false); - if (!ShouldPropagateObject(collationAddress)) + ObjectAddress collationAddress = GetObjectAddressFromParseTree((Node *) stmt, false); + if (!ShouldPropagateObject(&collationAddress)) { - return; + return NIL; } /* dependencies have changed (schema) let's ensure they exist */ - EnsureDependenciesExistsOnAllNodes(collationAddress); + EnsureDependenciesExistOnAllNodes(&collationAddress); + + return NIL; } @@ -401,15 +410,16 @@ ProcessAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt, const char *querySt * RenameCollationStmtObjectAddress returns the ObjectAddress of the type that is the object * of the RenameStmt. Errors if missing_ok is false. */ -ObjectAddress * -RenameCollationStmtObjectAddress(RenameStmt *stmt, bool missing_ok) +ObjectAddress +RenameCollationStmtObjectAddress(Node *node, bool missing_ok) { + RenameStmt *stmt = castNode(RenameStmt, node); Assert(stmt->renameType == OBJECT_COLLATION); - ObjectAddress *address = palloc0(sizeof(ObjectAddress)); Oid collationOid = get_collation_oid((List *) stmt->object, missing_ok); + ObjectAddress address = { 0 }; + ObjectAddressSet(address, CollationRelationId, collationOid); - ObjectAddressSet(*address, CollationRelationId, collationOid); return address; } @@ -423,9 +433,10 @@ RenameCollationStmtObjectAddress(RenameStmt *stmt, bool missing_ok) * new schema. Errors if missing_ok is false and the type cannot be found in either of the * schemas. */ -ObjectAddress * -AlterCollationSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, bool missing_ok) +ObjectAddress +AlterCollationSchemaStmtObjectAddress(Node *node, bool missing_ok) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); Assert(stmt->objectType == OBJECT_COLLATION); List *name = (List *) stmt->object; @@ -445,8 +456,8 @@ AlterCollationSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, bool missing_ } } - ObjectAddress *address = palloc0(sizeof(ObjectAddress)); - ObjectAddressSet(*address, CollationRelationId, collationOid); + ObjectAddress address = { 0 }; + ObjectAddressSet(address, CollationRelationId, collationOid); return address; } @@ -544,31 +555,31 @@ GenerateBackupNameForCollationCollision(const ObjectAddress *address) } -ObjectAddress * -DefineCollationStmtObjectAddress(DefineStmt *stmt, bool missing_ok) +ObjectAddress +DefineCollationStmtObjectAddress(Node *node, bool missing_ok) { + DefineStmt *stmt = castNode(DefineStmt, node); Assert(stmt->kind == OBJECT_COLLATION); Oid collOid = get_collation_oid(stmt->defnames, missing_ok); - ObjectAddress *address = palloc0(sizeof(ObjectAddress)); - - ObjectAddressSet(*address, CollationRelationId, collOid); + ObjectAddress address = { 0 }; + ObjectAddressSet(address, CollationRelationId, collOid); return address; } /* - * ProcessCollationDefineStmt executed after the extension has been + * PostprocessDefineCollationStmt executed after the collation has been * created locally and before we create it on the worker nodes. - * As we now have access to ObjectAddress of the extension that is just + * As we now have access to ObjectAddress of the collation that is just * created, we can mark it as distributed to make sure that its * dependencies exist on all nodes. */ List * -ProcessCollationDefineStmt(DefineStmt *stmt, const char *queryString) +PostprocessDefineCollationStmt(Node *node, const char *queryString) { - Assert(stmt->kind == OBJECT_COLLATION); + Assert(castNode(DefineStmt, node)->kind == OBJECT_COLLATION); if (!ShouldPropagate()) { @@ -584,18 +595,13 @@ ProcessCollationDefineStmt(DefineStmt *stmt, const char *queryString) return NIL; } - ObjectAddress *collationAddress = - DefineCollationStmtObjectAddress(stmt, false); + ObjectAddress collationAddress = + DefineCollationStmtObjectAddress(node, false); - if (collationAddress->objectId == InvalidOid) - { - return NIL; - } + EnsureDependenciesExistOnAllNodes(&collationAddress); - EnsureDependenciesExistsOnAllNodes(collationAddress); - - MarkObjectDistributed(collationAddress); + MarkObjectDistributed(&collationAddress); return NodeDDLTaskList(ALL_WORKERS, CreateCollationDDLsIdempotent( - collationAddress->objectId)); + collationAddress.objectId)); } diff --git a/src/backend/distributed/commands/create_distributed_table.c b/src/backend/distributed/commands/create_distributed_table.c index adbf2e68f..9f0ad7e6f 100644 --- a/src/backend/distributed/commands/create_distributed_table.c +++ b/src/backend/distributed/commands/create_distributed_table.c @@ -141,7 +141,7 @@ master_create_distributed_table(PG_FUNCTION_ARGS) * sessions creating shards. */ ObjectAddressSet(tableAddress, RelationRelationId, relationId); - EnsureDependenciesExistsOnAllNodes(&tableAddress); + EnsureDependenciesExistOnAllNodes(&tableAddress); /* * Lock target relation with an exclusive lock - there's no way to make @@ -207,7 +207,7 @@ create_distributed_table(PG_FUNCTION_ARGS) * sessions creating shards. */ ObjectAddressSet(tableAddress, RelationRelationId, relationId); - EnsureDependenciesExistsOnAllNodes(&tableAddress); + EnsureDependenciesExistOnAllNodes(&tableAddress); /* * Lock target relation with an exclusive lock - there's no way to make @@ -272,7 +272,7 @@ create_reference_table(PG_FUNCTION_ARGS) * sessions creating shards. */ ObjectAddressSet(tableAddress, RelationRelationId, relationId); - EnsureDependenciesExistsOnAllNodes(&tableAddress); + EnsureDependenciesExistOnAllNodes(&tableAddress); /* * Lock target relation with an exclusive lock - there's no way to make diff --git a/src/backend/distributed/commands/dependencies.c b/src/backend/distributed/commands/dependencies.c index 669e70e94..b0aab9ae4 100644 --- a/src/backend/distributed/commands/dependencies.c +++ b/src/backend/distributed/commands/dependencies.c @@ -24,16 +24,17 @@ #include "storage/lmgr.h" #include "utils/lsyscache.h" +typedef bool (*AddressPredicate)(const ObjectAddress *); + static List * GetDependencyCreateDDLCommands(const ObjectAddress *dependency); static List * FilterObjectAddressListByPredicate(List *objectAddressList, - bool (*predicate)(const - ObjectAddress *)); + AddressPredicate predicate); bool EnableDependencyCreation = true; /* - * EnsureDependenciesExists finds all the dependencies that we support and makes sure - * these are available on all workers. If not available they will be created on the + * EnsureDependenciesExistOnAllNodes finds all the dependencies that we support and makes + * sure these are available on all workers. If not available they will be created on the * workers via a separate session that will be committed directly so that the objects are * visible to potentially multiple sessions creating the shards. * @@ -47,7 +48,7 @@ bool EnableDependencyCreation = true; * postgres native CREATE IF NOT EXISTS, or citus helper functions. */ void -EnsureDependenciesExistsOnAllNodes(const ObjectAddress *target) +EnsureDependenciesExistOnAllNodes(const ObjectAddress *target) { /* local variables to work with dependencies */ List *dependenciesWithCommands = NIL; @@ -324,8 +325,7 @@ ShouldPropagateObject(const ObjectAddress *address) * only containing the ObjectAddress *'s for which the predicate returned true. */ static List * -FilterObjectAddressListByPredicate(List *objectAddressList, - bool (*predicate)(const ObjectAddress *)) +FilterObjectAddressListByPredicate(List *objectAddressList, AddressPredicate predicate) { List *result = NIL; ListCell *objectAddressListCell = NULL; diff --git a/src/backend/distributed/commands/distribute_object_ops.c b/src/backend/distributed/commands/distribute_object_ops.c new file mode 100644 index 000000000..432604860 --- /dev/null +++ b/src/backend/distributed/commands/distribute_object_ops.c @@ -0,0 +1,752 @@ +/*------------------------------------------------------------------------- + * + * distribute_object_ops.c + * + * Contains declarations for DistributeObjectOps, along with their + * lookup function, GetDistributeObjectOps. + * + * Copyright (c) Citus Data, Inc. + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "distributed/commands.h" +#include "distributed/deparser.h" + +static DistributeObjectOps NoDistributeOps = { + .deparse = NULL, + .qualify = NULL, + .preprocess = NULL, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Aggregate_AlterObjectSchema = { + .deparse = DeparseAlterFunctionSchemaStmt, + .qualify = QualifyAlterFunctionSchemaStmt, + .preprocess = PreprocessAlterFunctionSchemaStmt, + .postprocess = PostprocessAlterFunctionSchemaStmt, + .address = AlterFunctionSchemaStmtObjectAddress, +}; +static DistributeObjectOps Aggregate_AlterOwner = { + .deparse = DeparseAlterFunctionOwnerStmt, + .qualify = QualifyAlterFunctionOwnerStmt, + .preprocess = PreprocessAlterFunctionOwnerStmt, + .postprocess = NULL, + .address = AlterFunctionOwnerObjectAddress, +}; +static DistributeObjectOps Aggregate_Define = { + .deparse = NULL, + .qualify = NULL, + .preprocess = NULL, + .postprocess = NULL, + .address = DefineAggregateStmtObjectAddress, +}; +static DistributeObjectOps Aggregate_Drop = { + .deparse = DeparseDropFunctionStmt, + .qualify = NULL, + .preprocess = PreprocessDropFunctionStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Aggregate_Rename = { + .deparse = DeparseRenameFunctionStmt, + .qualify = QualifyRenameFunctionStmt, + .preprocess = PreprocessRenameFunctionStmt, + .postprocess = NULL, + .address = RenameFunctionStmtObjectAddress, +}; +static DistributeObjectOps Any_AlterEnum = { + .deparse = DeparseAlterEnumStmt, + .qualify = QualifyAlterEnumStmt, + .preprocess = PreprocessAlterEnumStmt, + .postprocess = PostprocessAlterEnumStmt, + .address = AlterEnumStmtObjectAddress, +}; +static DistributeObjectOps Any_AlterExtension = { + .deparse = DeparseAlterExtensionStmt, + .qualify = NULL, + .preprocess = PreprocessAlterExtensionUpdateStmt, + .postprocess = NULL, + .address = AlterExtensionUpdateStmtObjectAddress, +}; +static DistributeObjectOps Any_AlterExtensionContents = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessAlterExtensionContentsStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Any_AlterFunction = { + .deparse = DeparseAlterFunctionStmt, + .qualify = QualifyAlterFunctionStmt, + .preprocess = PreprocessAlterFunctionStmt, + .postprocess = NULL, + .address = AlterFunctionStmtObjectAddress, +}; +static DistributeObjectOps Any_AlterObjectSchema = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessAlterTableSchemaStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Any_AlterPolicy = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessAlterPolicyStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Any_AlterRole = { + .deparse = DeparseAlterRoleStmt, + .qualify = NULL, + .preprocess = NULL, + .postprocess = PostprocessAlterRoleStmt, + .address = NULL, +}; +static DistributeObjectOps Any_AlterTableMoveAll = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessAlterTableMoveAllStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Any_Cluster = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessClusterStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Any_CompositeType = { + .deparse = DeparseCompositeTypeStmt, + .qualify = QualifyCompositeTypeStmt, + .preprocess = PreprocessCompositeTypeStmt, + .postprocess = PostprocessCompositeTypeStmt, + .address = CompositeTypeStmtObjectAddress, +}; +static DistributeObjectOps Any_CreateEnum = { + .deparse = DeparseCreateEnumStmt, + .qualify = QualifyCreateEnumStmt, + .preprocess = PreprocessCreateEnumStmt, + .postprocess = PostprocessCreateEnumStmt, + .address = CreateEnumStmtObjectAddress, +}; +static DistributeObjectOps Any_CreateExtension = { + .deparse = DeparseCreateExtensionStmt, + .qualify = NULL, + .preprocess = NULL, + .postprocess = PostprocessCreateExtensionStmt, + .address = CreateExtensionStmtObjectAddress, +}; +static DistributeObjectOps Any_CreateFunction = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessCreateFunctionStmt, + .postprocess = PostprocessCreateFunctionStmt, + .address = CreateFunctionStmtObjectAddress, +}; +static DistributeObjectOps Any_CreatePolicy = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessCreatePolicyStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Any_Grant = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessGrantStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Any_Index = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessIndexStmt, + .postprocess = PostprocessIndexStmt, + .address = NULL, +}; +static DistributeObjectOps Any_Reindex = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessReindexStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Any_Rename = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessRenameStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Attribute_Rename = { + .deparse = DeparseRenameAttributeStmt, + .qualify = QualifyRenameAttributeStmt, + .preprocess = PreprocessRenameAttributeStmt, + .postprocess = NULL, + .address = RenameAttributeStmtObjectAddress, +}; +static DistributeObjectOps Collation_AlterObjectSchema = { + .deparse = DeparseAlterCollationSchemaStmt, + .qualify = QualifyAlterCollationSchemaStmt, + .preprocess = PreprocessAlterCollationSchemaStmt, + .postprocess = PostprocessAlterCollationSchemaStmt, + .address = AlterCollationSchemaStmtObjectAddress, +}; +static DistributeObjectOps Collation_AlterOwner = { + .deparse = DeparseAlterCollationOwnerStmt, + .qualify = QualifyAlterCollationOwnerStmt, + .preprocess = PreprocessAlterCollationOwnerStmt, + .postprocess = NULL, + .address = AlterCollationOwnerObjectAddress, +}; +static DistributeObjectOps Collation_Define = { + .deparse = NULL, + .qualify = NULL, + .preprocess = NULL, + .postprocess = PostprocessDefineCollationStmt, + .address = DefineCollationStmtObjectAddress, +}; +static DistributeObjectOps Collation_Drop = { + .deparse = DeparseDropCollationStmt, + .qualify = QualifyDropCollationStmt, + .preprocess = PreprocessDropCollationStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Collation_Rename = { + .deparse = DeparseRenameCollationStmt, + .qualify = QualifyRenameCollationStmt, + .preprocess = PreprocessRenameCollationStmt, + .postprocess = NULL, + .address = RenameCollationStmtObjectAddress, +}; +static DistributeObjectOps Extension_AlterObjectSchema = { + .deparse = DeparseAlterExtensionSchemaStmt, + .qualify = NULL, + .preprocess = PreprocessAlterExtensionSchemaStmt, + .postprocess = PostprocessAlterExtensionSchemaStmt, + .address = AlterExtensionSchemaStmtObjectAddress, +}; +static DistributeObjectOps Extension_Drop = { + .deparse = DeparseDropExtensionStmt, + .qualify = NULL, + .preprocess = PreprocessDropExtensionStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps ForeignTable_AlterTable = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessAlterTableStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Function_AlterObjectDepends = { + .deparse = DeparseAlterFunctionDependsStmt, + .qualify = QualifyAlterFunctionDependsStmt, + .preprocess = PreprocessAlterFunctionDependsStmt, + .postprocess = NULL, + .address = AlterFunctionDependsStmtObjectAddress, +}; +static DistributeObjectOps Function_AlterObjectSchema = { + .deparse = DeparseAlterFunctionSchemaStmt, + .qualify = QualifyAlterFunctionSchemaStmt, + .preprocess = PreprocessAlterFunctionSchemaStmt, + .postprocess = PostprocessAlterFunctionSchemaStmt, + .address = AlterFunctionSchemaStmtObjectAddress, +}; +static DistributeObjectOps Function_AlterOwner = { + .deparse = DeparseAlterFunctionOwnerStmt, + .qualify = QualifyAlterFunctionOwnerStmt, + .preprocess = PreprocessAlterFunctionOwnerStmt, + .postprocess = NULL, + .address = AlterFunctionOwnerObjectAddress, +}; +static DistributeObjectOps Function_Drop = { + .deparse = DeparseDropFunctionStmt, + .qualify = NULL, + .preprocess = PreprocessDropFunctionStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Function_Rename = { + .deparse = DeparseRenameFunctionStmt, + .qualify = QualifyRenameFunctionStmt, + .preprocess = PreprocessRenameFunctionStmt, + .postprocess = NULL, + .address = RenameFunctionStmtObjectAddress, +}; +static DistributeObjectOps Index_AlterTable = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessAlterTableStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Index_Drop = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessDropIndexStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Policy_Drop = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessDropPolicyStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Procedure_AlterObjectDepends = { + .deparse = DeparseAlterFunctionDependsStmt, + .qualify = QualifyAlterFunctionDependsStmt, + .preprocess = PreprocessAlterFunctionDependsStmt, + .postprocess = NULL, + .address = AlterFunctionDependsStmtObjectAddress, +}; +static DistributeObjectOps Procedure_AlterObjectSchema = { + .deparse = DeparseAlterFunctionSchemaStmt, + .qualify = QualifyAlterFunctionSchemaStmt, + .preprocess = PreprocessAlterFunctionSchemaStmt, + .postprocess = PostprocessAlterFunctionSchemaStmt, + .address = AlterFunctionSchemaStmtObjectAddress, +}; +static DistributeObjectOps Procedure_AlterOwner = { + .deparse = DeparseAlterFunctionOwnerStmt, + .qualify = QualifyAlterFunctionOwnerStmt, + .preprocess = PreprocessAlterFunctionOwnerStmt, + .postprocess = NULL, + .address = AlterFunctionOwnerObjectAddress, +}; +static DistributeObjectOps Procedure_Drop = { + .deparse = DeparseDropFunctionStmt, + .qualify = NULL, + .preprocess = PreprocessDropFunctionStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Procedure_Rename = { + .deparse = DeparseRenameFunctionStmt, + .qualify = QualifyRenameFunctionStmt, + .preprocess = PreprocessRenameFunctionStmt, + .postprocess = NULL, + .address = RenameFunctionStmtObjectAddress, +}; +static DistributeObjectOps Schema_Drop = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessDropSchemaStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Table_AlterTable = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessAlterTableStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Table_Drop = { + .deparse = NULL, + .qualify = NULL, + .preprocess = PreprocessDropTableStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Type_AlterObjectSchema = { + .deparse = DeparseAlterTypeSchemaStmt, + .qualify = QualifyAlterTypeSchemaStmt, + .preprocess = PreprocessAlterTypeSchemaStmt, + .postprocess = PostprocessAlterTypeSchemaStmt, + .address = AlterTypeSchemaStmtObjectAddress, +}; +static DistributeObjectOps Type_AlterOwner = { + .deparse = DeparseAlterTypeOwnerStmt, + .qualify = QualifyAlterTypeOwnerStmt, + .preprocess = PreprocessAlterTypeOwnerStmt, + .postprocess = NULL, + .address = AlterTypeOwnerObjectAddress, +}; +static DistributeObjectOps Type_AlterTable = { + .deparse = DeparseAlterTypeStmt, + .qualify = QualifyAlterTypeStmt, + .preprocess = PreprocessAlterTypeStmt, + .postprocess = NULL, + .address = AlterTypeStmtObjectAddress, +}; +static DistributeObjectOps Type_Drop = { + .deparse = DeparseDropTypeStmt, + .qualify = NULL, + .preprocess = PreprocessDropTypeStmt, + .postprocess = NULL, + .address = NULL, +}; +static DistributeObjectOps Type_Rename = { + .deparse = DeparseRenameTypeStmt, + .qualify = QualifyRenameTypeStmt, + .preprocess = PreprocessRenameTypeStmt, + .postprocess = NULL, + .address = RenameTypeStmtObjectAddress, +}; + + +/* + * GetDistributeObjectOps looks up the DistributeObjectOps which handles the node. + * + * Never returns NULL. + */ +const DistributeObjectOps * +GetDistributeObjectOps(Node *node) +{ + switch (nodeTag(node)) + { + case T_AlterEnumStmt: + { + return &Any_AlterEnum; + } + + case T_AlterExtensionStmt: + { + return &Any_AlterExtension; + } + + case T_AlterExtensionContentsStmt: + { + return &Any_AlterExtensionContents; + } + + case T_AlterFunctionStmt: + { + return &Any_AlterFunction; + } + + case T_AlterObjectDependsStmt: + { + AlterObjectDependsStmt *stmt = castNode(AlterObjectDependsStmt, node); + switch (stmt->objectType) + { + case OBJECT_FUNCTION: + { + return &Function_AlterObjectDepends; + } + + case OBJECT_PROCEDURE: + { + return &Procedure_AlterObjectDepends; + } + + default: + { + return &NoDistributeOps; + } + } + } + + case T_AlterObjectSchemaStmt: + { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); + switch (stmt->objectType) + { + case OBJECT_AGGREGATE: + { + return &Aggregate_AlterObjectSchema; + } + + case OBJECT_COLLATION: + { + return &Collation_AlterObjectSchema; + } + + case OBJECT_EXTENSION: + { + return &Extension_AlterObjectSchema; + } + + case OBJECT_FUNCTION: + { + return &Function_AlterObjectSchema; + } + + case OBJECT_PROCEDURE: + { + return &Procedure_AlterObjectSchema; + } + + case OBJECT_TYPE: + { + return &Type_AlterObjectSchema; + } + + default: + { + return &Any_AlterObjectSchema; + } + } + } + + case T_AlterOwnerStmt: + { + AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); + switch (stmt->objectType) + { + case OBJECT_AGGREGATE: + { + return &Aggregate_AlterOwner; + } + + case OBJECT_COLLATION: + { + return &Collation_AlterOwner; + } + + case OBJECT_FUNCTION: + { + return &Function_AlterOwner; + } + + case OBJECT_PROCEDURE: + { + return &Procedure_AlterOwner; + } + + case OBJECT_TYPE: + { + return &Type_AlterOwner; + } + + default: + { + return &NoDistributeOps; + } + } + } + + case T_AlterPolicyStmt: + { + return &Any_AlterPolicy; + } + + case T_AlterRoleStmt: + { + return &Any_AlterRole; + } + + case T_AlterTableStmt: + { + AlterTableStmt *stmt = castNode(AlterTableStmt, node); + switch (stmt->relkind) + { + case OBJECT_TYPE: + { + return &Type_AlterTable; + } + + case OBJECT_TABLE: + { + return &Table_AlterTable; + } + + case OBJECT_FOREIGN_TABLE: + { + return &ForeignTable_AlterTable; + } + + case OBJECT_INDEX: + { + return &Index_AlterTable; + } + + default: + { + return &NoDistributeOps; + } + } + } + + case T_AlterTableMoveAllStmt: + { + return &Any_AlterTableMoveAll; + } + + case T_ClusterStmt: + { + return &Any_Cluster; + } + + case T_CompositeTypeStmt: + { + return &Any_CompositeType; + } + + case T_CreateEnumStmt: + { + return &Any_CreateEnum; + } + + case T_CreateExtensionStmt: + { + return &Any_CreateExtension; + } + + case T_CreateFunctionStmt: + { + return &Any_CreateFunction; + } + + case T_CreatePolicyStmt: + { + return &Any_CreatePolicy; + } + + case T_DefineStmt: + { + DefineStmt *stmt = castNode(DefineStmt, node); + switch (stmt->kind) + { + case OBJECT_AGGREGATE: + { + return &Aggregate_Define; + } + + case OBJECT_COLLATION: + { + return &Collation_Define; + } + + default: + { + return &NoDistributeOps; + } + } + } + + case T_DropStmt: + { + DropStmt *stmt = castNode(DropStmt, node); + switch (stmt->removeType) + { + case OBJECT_AGGREGATE: + { + return &Aggregate_Drop; + } + + case OBJECT_COLLATION: + { + return &Collation_Drop; + } + + case OBJECT_EXTENSION: + { + return &Extension_Drop; + } + + case OBJECT_FUNCTION: + { + return &Function_Drop; + } + + case OBJECT_INDEX: + { + return &Index_Drop; + } + + case OBJECT_POLICY: + { + return &Policy_Drop; + } + + case OBJECT_PROCEDURE: + { + return &Procedure_Drop; + } + + case OBJECT_SCHEMA: + { + return &Schema_Drop; + } + + case OBJECT_TABLE: + { + return &Table_Drop; + } + + case OBJECT_TYPE: + { + return &Type_Drop; + } + + default: + { + return &NoDistributeOps; + } + } + } + + case T_GrantStmt: + { + return &Any_Grant; + } + + case T_IndexStmt: + { + return &Any_Index; + } + + case T_ReindexStmt: + { + return &Any_Reindex; + } + + case T_RenameStmt: + { + RenameStmt *stmt = castNode(RenameStmt, node); + switch (stmt->renameType) + { + case OBJECT_AGGREGATE: + { + return &Aggregate_Rename; + } + + case OBJECT_ATTRIBUTE: + { + return &Attribute_Rename; + } + + case OBJECT_COLLATION: + { + return &Collation_Rename; + } + + case OBJECT_FUNCTION: + { + return &Function_Rename; + } + + case OBJECT_PROCEDURE: + { + return &Procedure_Rename; + } + + case OBJECT_TYPE: + { + return &Type_Rename; + } + + default: + { + return &Any_Rename; + } + } + } + + default: + { + return &NoDistributeOps; + } + } +} diff --git a/src/backend/distributed/commands/extension.c b/src/backend/distributed/commands/extension.c index 60139a42c..5add3f147 100644 --- a/src/backend/distributed/commands/extension.c +++ b/src/backend/distributed/commands/extension.c @@ -115,16 +115,21 @@ ExtractNewExtensionVersion(Node *parseTree) /* - * PlanCreateExtensionStmt is called during the creation of an extension. - * It is executed before the statement is applied locally. + * PostprocessCreateExtensionStmt is called after the creation of an extension. * We decide if the extension needs to be replicated to the worker, and * if that is the case return a list of DDLJob's that describe how and * where the extension needs to be created. + * + * As we now have access to ObjectAddress of the extension that is just + * created, we can mark it as distributed to make sure that its + * dependencies exist on all nodes. */ List * -PlanCreateExtensionStmt(CreateExtensionStmt *createExtensionStmt, const char *queryString) +PostprocessCreateExtensionStmt(Node *node, const char *queryString) { - if (!ShouldPropagateExtensionCommand((Node *) createExtensionStmt)) + CreateExtensionStmt *stmt = castNode(CreateExtensionStmt, node); + + if (!ShouldPropagateExtensionCommand(node)) { return NIL; } @@ -161,9 +166,9 @@ PlanCreateExtensionStmt(CreateExtensionStmt *createExtensionStmt, const char *qu * Here we append "schema" field to the "options" list (if not specified) * to satisfy the schema consistency between worker nodes and the coordinator. */ - AddSchemaFieldIfMissing(createExtensionStmt); + AddSchemaFieldIfMissing(stmt); - const char *createExtensionStmtSql = DeparseTreeNode((Node *) createExtensionStmt); + const char *createExtensionStmtSql = DeparseTreeNode(node); /* * To prevent recursive propagation in mx architecture, we disable ddl @@ -173,6 +178,12 @@ PlanCreateExtensionStmt(CreateExtensionStmt *createExtensionStmt, const char *qu (void *) createExtensionStmtSql, ENABLE_DDL_PROPAGATION); + ObjectAddress extensionAddress = GetObjectAddressFromParseTree(node, false); + + EnsureDependenciesExistOnAllNodes(&extensionAddress); + + MarkObjectDistributed(&extensionAddress); + return NodeDDLTaskList(ALL_WORKERS, commands); } @@ -214,42 +225,7 @@ AddSchemaFieldIfMissing(CreateExtensionStmt *createExtensionStmt) /* - * ProcessCreateExtensionStmt is executed after the extension has been - * created locally and before we create it on the worker nodes. - * As we now have access to ObjectAddress of the extension that is just - * created, we can mark it as distributed to make sure that its - * dependencies exist on all nodes. - */ -void -ProcessCreateExtensionStmt(CreateExtensionStmt *createExtensionStmt, const - char *queryString) -{ - if (!ShouldPropagateExtensionCommand((Node *) createExtensionStmt)) - { - return; - } - - - /* - * If the extension command is a part of a bigger multi-statement transaction, - * do not propagate it - */ - if (IsMultiStatementTransaction()) - { - return; - } - - const ObjectAddress *extensionAddress = GetObjectAddressFromParseTree( - (Node *) createExtensionStmt, false); - - EnsureDependenciesExistsOnAllNodes(extensionAddress); - - MarkObjectDistributed(extensionAddress); -} - - -/* - * PlanDropExtensionStmt is called to drop extension(s) in coordinator and + * PreprocessDropExtensionStmt is called to drop extension(s) in coordinator and * in worker nodes if distributed before. * We first ensure that we keep only the distributed ones before propagating * the statement to worker nodes. @@ -257,19 +233,18 @@ ProcessCreateExtensionStmt(CreateExtensionStmt *createExtensionStmt, const * be made to the workers. */ List * -PlanDropExtensionStmt(DropStmt *dropStmt, const char *queryString) +PreprocessDropExtensionStmt(Node *node, const char *queryString) { - List *allDroppedExtensions = dropStmt->objects; - - + DropStmt *stmt = castNode(DropStmt, node); ListCell *addressCell = NULL; - if (!ShouldPropagateExtensionCommand((Node *) dropStmt)) + if (!ShouldPropagateExtensionCommand(node)) { return NIL; } /* get distributed extensions to be dropped in worker nodes as well */ + List *allDroppedExtensions = stmt->objects; List *distributedExtensions = FilterDistributedExtensions(allDroppedExtensions); if (list_length(distributedExtensions) <= 0) @@ -311,13 +286,13 @@ PlanDropExtensionStmt(DropStmt *dropStmt, const char *queryString) * Temporary swap the lists of objects to delete with the distributed * objects and deparse to an sql statement for the workers. * Then switch back to allDroppedExtensions to drop all specified - * extensions in coordinator after PlanDropExtensionStmt completes + * extensions in coordinator after PreprocessDropExtensionStmt completes * its execution. */ - dropStmt->objects = distributedExtensions; - const char *deparsedStmt = DeparseTreeNode((Node *) dropStmt); + stmt->objects = distributedExtensions; + const char *deparsedStmt = DeparseTreeNode((Node *) stmt); - dropStmt->objects = allDroppedExtensions; + stmt->objects = allDroppedExtensions; /* * To prevent recursive propagation in mx architecture, we disable ddl @@ -348,8 +323,6 @@ FilterDistributedExtensions(List *extensionObjectList) { char *extensionName = strVal(lfirst(objectCell)); - ObjectAddress *address = palloc0(sizeof(ObjectAddress)); - Oid extensionOid = get_extension_oid(extensionName, missingOk); if (!OidIsValid(extensionOid)) @@ -357,9 +330,10 @@ FilterDistributedExtensions(List *extensionObjectList) continue; } - ObjectAddressSet(*address, ExtensionRelationId, extensionOid); + ObjectAddress address = { 0 }; + ObjectAddressSet(address, ExtensionRelationId, extensionOid); - if (!IsObjectDistributed(address)) + if (!IsObjectDistributed(&address)) { continue; } @@ -408,13 +382,12 @@ ExtensionNameListToObjectAddressList(List *extensionObjectList) /* - * PlanAlterExtensionSchemaStmt is invoked for alter extension set schema statements. + * PreprocessAlterExtensionSchemaStmt is invoked for alter extension set schema statements. */ List * -PlanAlterExtensionSchemaStmt(AlterObjectSchemaStmt *alterExtensionStmt, const - char *queryString) +PreprocessAlterExtensionSchemaStmt(Node *node, const char *queryString) { - if (!ShouldPropagateExtensionCommand((Node *) alterExtensionStmt)) + if (!ShouldPropagateExtensionCommand(node)) { return NIL; } @@ -437,7 +410,7 @@ PlanAlterExtensionSchemaStmt(AlterObjectSchemaStmt *alterExtensionStmt, const */ EnsureSequentialModeForExtensionDDL(); - const char *alterExtensionStmtSql = DeparseTreeNode((Node *) alterExtensionStmt); + const char *alterExtensionStmtSql = DeparseTreeNode(node); /* * To prevent recursive propagation in mx architecture, we disable ddl @@ -452,34 +425,34 @@ PlanAlterExtensionSchemaStmt(AlterObjectSchemaStmt *alterExtensionStmt, const /* - * ProcessAlterExtensionSchemaStmt is executed after the change has been applied + * PostprocessAlterExtensionSchemaStmt is executed after the change has been applied * locally, we can now use the new dependencies (schema) of the extension to ensure * all its dependencies exist on the workers before we apply the commands remotely. */ -void -ProcessAlterExtensionSchemaStmt(AlterObjectSchemaStmt *alterExtensionStmt, const - char *queryString) +List * +PostprocessAlterExtensionSchemaStmt(Node *node, const char *queryString) { - const ObjectAddress *extensionAddress = GetObjectAddressFromParseTree( - (Node *) alterExtensionStmt, false); + ObjectAddress extensionAddress = GetObjectAddressFromParseTree(node, false); - if (!ShouldPropagateExtensionCommand((Node *) alterExtensionStmt)) + if (!ShouldPropagateExtensionCommand(node)) { - return; + return NIL; } /* dependencies (schema) have changed let's ensure they exist */ - EnsureDependenciesExistsOnAllNodes(extensionAddress); + EnsureDependenciesExistOnAllNodes(&extensionAddress); + + return NIL; } /* - * PlanAlterExtensionUpdateStmt is invoked for alter extension update statements. + * PreprocessAlterExtensionUpdateStmt is invoked for alter extension update statements. */ List * -PlanAlterExtensionUpdateStmt(AlterExtensionStmt *alterExtensionStmt, const - char *queryString) +PreprocessAlterExtensionUpdateStmt(Node *node, const char *queryString) { + AlterExtensionStmt *alterExtensionStmt = castNode(AlterExtensionStmt, node); if (!ShouldPropagateExtensionCommand((Node *) alterExtensionStmt)) { return NIL; @@ -518,6 +491,21 @@ PlanAlterExtensionUpdateStmt(AlterExtensionStmt *alterExtensionStmt, const } +/* + * PreprocessAlterExtensionContentsStmt issues a notice. It does not propagate. + */ +List * +PreprocessAlterExtensionContentsStmt(Node *node, const char *queryString) +{ + ereport(NOTICE, (errmsg( + "Citus does not propagate adding/dropping member objects"), + errhint( + "You can add/drop the member objects on the workers as well."))); + + return NIL; +} + + /* * EnsureSequentialModeForExtensionDDL makes sure that the current transaction is already in * sequential mode, or can still safely be put in sequential mode, it errors if that is @@ -753,13 +741,13 @@ RecreateExtensionStmt(Oid extensionOid) * AlterExtensionSchemaStmtObjectAddress returns the ObjectAddress of the extension that is * the subject of the AlterObjectSchemaStmt. Errors if missing_ok is false. */ -ObjectAddress * -AlterExtensionSchemaStmtObjectAddress(AlterObjectSchemaStmt *alterExtensionSchemaStmt, - bool missing_ok) +ObjectAddress +AlterExtensionSchemaStmtObjectAddress(Node *node, bool missing_ok) { - Assert(alterExtensionSchemaStmt->objectType == OBJECT_EXTENSION); + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); + Assert(stmt->objectType == OBJECT_EXTENSION); - const char *extensionName = strVal(alterExtensionSchemaStmt->object); + const char *extensionName = strVal(stmt->object); Oid extensionOid = get_extension_oid(extensionName, missing_ok); @@ -770,10 +758,10 @@ AlterExtensionSchemaStmtObjectAddress(AlterObjectSchemaStmt *alterExtensionSchem extensionName))); } - ObjectAddress *extensionAddress = palloc0(sizeof(ObjectAddress)); - ObjectAddressSet(*extensionAddress, ExtensionRelationId, extensionOid); + ObjectAddress address = { 0 }; + ObjectAddressSet(address, ExtensionRelationId, extensionOid); - return extensionAddress; + return address; } @@ -781,11 +769,11 @@ AlterExtensionSchemaStmtObjectAddress(AlterObjectSchemaStmt *alterExtensionSchem * AlterExtensionUpdateStmtObjectAddress returns the ObjectAddress of the extension that is * the subject of the AlterExtensionStmt. Errors if missing_ok is false. */ -ObjectAddress * -AlterExtensionUpdateStmtObjectAddress(AlterExtensionStmt *alterExtensionStmt, - bool missing_ok) +ObjectAddress +AlterExtensionUpdateStmtObjectAddress(Node *node, bool missing_ok) { - const char *extensionName = alterExtensionStmt->extname; + AlterExtensionStmt *stmt = castNode(AlterExtensionStmt, node); + const char *extensionName = stmt->extname; Oid extensionOid = get_extension_oid(extensionName, missing_ok); @@ -796,8 +784,8 @@ AlterExtensionUpdateStmtObjectAddress(AlterExtensionStmt *alterExtensionStmt, extensionName))); } - ObjectAddress *extensionAddress = palloc0(sizeof(ObjectAddress)); - ObjectAddressSet(*extensionAddress, ExtensionRelationId, extensionOid); + ObjectAddress address = { 0 }; + ObjectAddressSet(address, ExtensionRelationId, extensionOid); - return extensionAddress; + return address; } diff --git a/src/backend/distributed/commands/function.c b/src/backend/distributed/commands/function.c index 2672d0bd3..94aa05a5c 100644 --- a/src/backend/distributed/commands/function.c +++ b/src/backend/distributed/commands/function.c @@ -75,9 +75,9 @@ static void EnsureSequentialModeForFunctionDDL(void); static void TriggerSyncMetadataToPrimaryNodes(void); static bool ShouldPropagateCreateFunction(CreateFunctionStmt *stmt); static bool ShouldPropagateAlterFunction(const ObjectAddress *address); -static ObjectAddress * FunctionToObjectAddress(ObjectType objectType, - ObjectWithArgs *objectWithArgs, - bool missing_ok); +static ObjectAddress FunctionToObjectAddress(ObjectType objectType, + ObjectWithArgs *objectWithArgs, + bool missing_ok); static void ErrorIfUnsupportedAlterFunctionStmt(AlterFunctionStmt *stmt); static void ErrorIfFunctionDependsOnExtension(const ObjectAddress *functionAddress); static char * quote_qualified_func_name(Oid funcOid); @@ -155,7 +155,7 @@ create_distributed_function(PG_FUNCTION_ARGS) */ EnsureSequentialModeForFunctionDDL(); - EnsureDependenciesExistsOnAllNodes(&functionAddress); + EnsureDependenciesExistOnAllNodes(&functionAddress); const char *createFunctionSQL = GetFunctionDDLCommand(funcOid, true); const char *alterFunctionOwnerSQL = GetFunctionAlterOwnerCommand(funcOid); @@ -1098,8 +1098,8 @@ ShouldPropagateCreateFunction(CreateFunctionStmt *stmt) * Even though its a replace we should accept an non-existing function, it will just * not be distributed */ - const ObjectAddress *address = GetObjectAddressFromParseTree((Node *) stmt, true); - if (!IsObjectDistributed(address)) + ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, true); + if (!IsObjectDistributed(&address)) { /* do not propagate alter function for non-distributed functions */ return false; @@ -1144,7 +1144,7 @@ ShouldPropagateAlterFunction(const ObjectAddress *address) /* - * PlanCreateFunctionStmt is called during the planning phase for CREATE [OR REPLACE] + * PreprocessCreateFunctionStmt is called during the planning phase for CREATE [OR REPLACE] * FUNCTION. We primarily care for the replace variant of this statement to keep * distributed functions in sync. We bail via a check on ShouldPropagateCreateFunction * which checks for the OR REPLACE modifier. @@ -1156,8 +1156,10 @@ ShouldPropagateAlterFunction(const ObjectAddress *address) * can propagate the function in sequential mode. */ List * -PlanCreateFunctionStmt(CreateFunctionStmt *stmt, const char *queryString) +PreprocessCreateFunctionStmt(Node *node, const char *queryString) { + CreateFunctionStmt *stmt = castNode(CreateFunctionStmt, node); + if (!ShouldPropagateCreateFunction(stmt)) { return NIL; @@ -1176,26 +1178,28 @@ PlanCreateFunctionStmt(CreateFunctionStmt *stmt, const char *queryString) /* - * ProcessCreateFunctionStmt actually creates the plan we need to execute for function + * PostprocessCreateFunctionStmt actually creates the plan we need to execute for function * propagation. This is the downside of using pg_get_functiondef to get the sql statement. * * Besides creating the plan we also make sure all (new) dependencies of the function are * created on all nodes. */ List * -ProcessCreateFunctionStmt(CreateFunctionStmt *stmt, const char *queryString) +PostprocessCreateFunctionStmt(Node *node, const char *queryString) { + CreateFunctionStmt *stmt = castNode(CreateFunctionStmt, node); + if (!ShouldPropagateCreateFunction(stmt)) { return NIL; } - const ObjectAddress *address = GetObjectAddressFromParseTree((Node *) stmt, false); - EnsureDependenciesExistsOnAllNodes(address); + ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, false); + EnsureDependenciesExistOnAllNodes(&address); List *commands = list_make4(DISABLE_DDL_PROPAGATION, - GetFunctionDDLCommand(address->objectId, true), - GetFunctionAlterOwnerCommand(address->objectId), + GetFunctionDDLCommand(address.objectId, true), + GetFunctionAlterOwnerCommand(address.objectId), ENABLE_DDL_PROPAGATION); return NodeDDLTaskList(ALL_WORKERS, commands); @@ -1207,9 +1211,10 @@ ProcessCreateFunctionStmt(CreateFunctionStmt *stmt, const char *queryString) * CREATE [OR REPLACE] FUNCTION statement. If missing_ok is false it will error with the * normal postgres error for unfound functions. */ -ObjectAddress * -CreateFunctionStmtObjectAddress(CreateFunctionStmt *stmt, bool missing_ok) +ObjectAddress +CreateFunctionStmtObjectAddress(Node *node, bool missing_ok) { + CreateFunctionStmt *stmt = castNode(CreateFunctionStmt, node); ObjectType objectType = OBJECT_FUNCTION; ListCell *parameterCell = NULL; @@ -1236,12 +1241,12 @@ CreateFunctionStmtObjectAddress(CreateFunctionStmt *stmt, bool missing_ok) * by the DefineStmtObjectAddress. If missing_ok is false this function throws an error if the * aggregate does not exist. * - * Never returns NULL, but the objid in the address could be invalid if missing_ok was set - * to true. + * objectId in the address can be invalid if missing_ok was set to true. */ -ObjectAddress * -DefineAggregateStmtObjectAddress(DefineStmt *stmt, bool missing_ok) +ObjectAddress +DefineAggregateStmtObjectAddress(Node *node, bool missing_ok) { + DefineStmt *stmt = castNode(DefineStmt, node); ListCell *parameterCell = NULL; Assert(stmt->kind == OBJECT_AGGREGATE); @@ -1260,17 +1265,18 @@ DefineAggregateStmtObjectAddress(DefineStmt *stmt, bool missing_ok) /* - * PlanAlterFunctionStmt is invoked for alter function statements with actions. Here we + * PreprocessAlterFunctionStmt is invoked for alter function statements with actions. Here we * plan the jobs to be executed on the workers for functions that have been distributed in * the cluster. */ List * -PlanAlterFunctionStmt(AlterFunctionStmt *stmt, const char *queryString) +PreprocessAlterFunctionStmt(Node *node, const char *queryString) { + AlterFunctionStmt *stmt = castNode(AlterFunctionStmt, node); AssertObjectTypeIsFunctional(stmt->objtype); - const ObjectAddress *address = GetObjectAddressFromParseTree((Node *) stmt, false); - if (!ShouldPropagateAlterFunction(address)) + ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, false); + if (!ShouldPropagateAlterFunction(&address)) { return NIL; } @@ -1290,7 +1296,7 @@ PlanAlterFunctionStmt(AlterFunctionStmt *stmt, const char *queryString) /* - * PlanRenameFunctionStmt is called when the user is renaming a function. The invocation + * PreprocessRenameFunctionStmt is called when the user is renaming a function. The invocation * happens before the statement is applied locally. * * As the function already exists we have access to the ObjectAddress, this is used to @@ -1298,12 +1304,13 @@ PlanAlterFunctionStmt(AlterFunctionStmt *stmt, const char *queryString) * types in sync across the cluster. */ List * -PlanRenameFunctionStmt(RenameStmt *stmt, const char *queryString) +PreprocessRenameFunctionStmt(Node *node, const char *queryString) { + RenameStmt *stmt = castNode(RenameStmt, node); AssertObjectTypeIsFunctional(stmt->renameType); - const ObjectAddress *address = GetObjectAddressFromParseTree((Node *) stmt, false); - if (!ShouldPropagateAlterFunction(address)) + ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, false); + if (!ShouldPropagateAlterFunction(&address)) { return NIL; } @@ -1322,18 +1329,19 @@ PlanRenameFunctionStmt(RenameStmt *stmt, const char *queryString) /* - * PlanAlterFunctionSchemaStmt is executed before the statement is applied to the local + * PreprocessAlterFunctionSchemaStmt is executed before the statement is applied to the local * postgres instance. * * In this stage we can prepare the commands that need to be run on all workers. */ List * -PlanAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString) +PreprocessAlterFunctionSchemaStmt(Node *node, const char *queryString) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AssertObjectTypeIsFunctional(stmt->objectType); - const ObjectAddress *address = GetObjectAddressFromParseTree((Node *) stmt, false); - if (!ShouldPropagateAlterFunction(address)) + ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, false); + if (!ShouldPropagateAlterFunction(&address)) { return NIL; } @@ -1352,19 +1360,20 @@ PlanAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString /* - * PlanAlterTypeOwnerStmt is called for change of owner ship of functions before the owner + * PreprocessAlterTypeOwnerStmt is called for change of owner ship of functions before the owner * ship is changed on the local instance. * * If the function for which the owner is changed is distributed we execute the change on * all the workers to keep the type in sync across the cluster. */ List * -PlanAlterFunctionOwnerStmt(AlterOwnerStmt *stmt, const char *queryString) +PreprocessAlterFunctionOwnerStmt(Node *node, const char *queryString) { + AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); AssertObjectTypeIsFunctional(stmt->objectType); - const ObjectAddress *address = GetObjectAddressFromParseTree((Node *) stmt, false); - if (!ShouldPropagateAlterFunction(address)) + ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, false); + if (!ShouldPropagateAlterFunction(&address)) { return NIL; } @@ -1383,7 +1392,7 @@ PlanAlterFunctionOwnerStmt(AlterOwnerStmt *stmt, const char *queryString) /* - * PlanDropFunctionStmt gets called during the planning phase of a DROP FUNCTION statement + * PreprocessDropFunctionStmt gets called during the planning phase of a DROP FUNCTION statement * and returns a list of DDLJob's that will drop any distributed functions from the * workers. * @@ -1392,8 +1401,9 @@ PlanAlterFunctionOwnerStmt(AlterOwnerStmt *stmt, const char *queryString) * functions will still be dropped locally but not on the workers. */ List * -PlanDropFunctionStmt(DropStmt *stmt, const char *queryString) +PreprocessDropFunctionStmt(Node *node, const char *queryString) { + DropStmt *stmt = castNode(DropStmt, node); List *deletingObjectWithArgsList = stmt->objects; List *distributedObjectWithArgsList = NIL; List *distributedFunctionAddresses = NIL; @@ -1433,16 +1443,18 @@ PlanDropFunctionStmt(DropStmt *stmt, const char *queryString) foreach(objectWithArgsListCell, deletingObjectWithArgsList) { ObjectWithArgs *func = castNode(ObjectWithArgs, lfirst(objectWithArgsListCell)); - ObjectAddress *address = FunctionToObjectAddress(stmt->removeType, func, - stmt->missing_ok); + ObjectAddress address = FunctionToObjectAddress(stmt->removeType, func, + stmt->missing_ok); - if (!IsObjectDistributed(address)) + if (!IsObjectDistributed(&address)) { continue; } /* collect information for all distributed functions */ - distributedFunctionAddresses = lappend(distributedFunctionAddresses, address); + ObjectAddress *addressp = palloc(sizeof(ObjectAddress)); + *addressp = address; + distributedFunctionAddresses = lappend(distributedFunctionAddresses, addressp); distributedObjectWithArgsList = lappend(distributedObjectWithArgsList, func); } @@ -1484,7 +1496,7 @@ PlanDropFunctionStmt(DropStmt *stmt, const char *queryString) /* - * PlanAlterFunctionDependsStmt is called during the planning phase of an + * PreprocessAlterFunctionDependsStmt is called during the planning phase of an * ALTER FUNCION ... DEPENDS ON EXTENSION ... statement. Since functions depending on * extensions are assumed to be Owned by an extension we assume the extension to keep the * function in sync. @@ -1495,8 +1507,9 @@ PlanDropFunctionStmt(DropStmt *stmt, const char *queryString) * don't allow this dependency to be created. */ List * -PlanAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt, const char *queryString) +PreprocessAlterFunctionDependsStmt(Node *node, const char *queryString) { + AlterObjectDependsStmt *stmt = castNode(AlterObjectDependsStmt, node); AssertObjectTypeIsFunctional(stmt->objectType); if (creating_extension) @@ -1516,8 +1529,8 @@ PlanAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt, const char *queryStri return NIL; } - const ObjectAddress *address = GetObjectAddressFromParseTree((Node *) stmt, true); - if (!IsObjectDistributed(address)) + ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, true); + if (!IsObjectDistributed(&address)) { return NIL; } @@ -1528,7 +1541,7 @@ PlanAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt, const char *queryStri * workers */ - const char *functionName = getObjectIdentity(address); + const char *functionName = getObjectIdentity(&address); ereport(ERROR, (errmsg("distrtibuted functions are not allowed to depend on an " "extension"), errdetail("Function \"%s\" is already distributed. Functions from " @@ -1542,9 +1555,10 @@ PlanAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt, const char *queryStri * is the subject of an ALTER FUNCTION ... DEPENS ON EXTENSION ... statement. If * missing_ok is set to false the lookup will raise an error. */ -ObjectAddress * -AlterFunctionDependsStmtObjectAddress(AlterObjectDependsStmt *stmt, bool missing_ok) +ObjectAddress +AlterFunctionDependsStmtObjectAddress(Node *node, bool missing_ok) { + AlterObjectDependsStmt *stmt = castNode(AlterObjectDependsStmt, node); AssertObjectTypeIsFunctional(stmt->objectType); return FunctionToObjectAddress(stmt->objectType, @@ -1553,23 +1567,26 @@ AlterFunctionDependsStmtObjectAddress(AlterObjectDependsStmt *stmt, bool missing /* - * ProcessAlterFunctionSchemaStmt is executed after the change has been applied locally, + * PostprocessAlterFunctionSchemaStmt is executed after the change has been applied locally, * we can now use the new dependencies of the function to ensure all its dependencies * exist on the workers before we apply the commands remotely. */ -void -ProcessAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString) +List * +PostprocessAlterFunctionSchemaStmt(Node *node, const char *queryString) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AssertObjectTypeIsFunctional(stmt->objectType); - const ObjectAddress *address = GetObjectAddressFromParseTree((Node *) stmt, false); - if (!ShouldPropagateAlterFunction(address)) + ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, false); + if (!ShouldPropagateAlterFunction(&address)) { - return; + return NIL; } /* dependencies have changed (schema) let's ensure they exist */ - EnsureDependenciesExistsOnAllNodes(address); + EnsureDependenciesExistOnAllNodes(&address); + + return NIL; } @@ -1578,9 +1595,10 @@ ProcessAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryStr * 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. */ -ObjectAddress * -AlterFunctionStmtObjectAddress(AlterFunctionStmt *stmt, bool missing_ok) +ObjectAddress +AlterFunctionStmtObjectAddress(Node *node, bool missing_ok) { + AlterFunctionStmt *stmt = castNode(AlterFunctionStmt, node); return FunctionToObjectAddress(stmt->objtype, stmt->func, missing_ok); } @@ -1589,9 +1607,10 @@ AlterFunctionStmtObjectAddress(AlterFunctionStmt *stmt, bool missing_ok) * RenameFunctionStmtObjectAddress returns the ObjectAddress of the function that is the * subject of the RenameStmt. Errors if missing_ok is false. */ -ObjectAddress * -RenameFunctionStmtObjectAddress(RenameStmt *stmt, bool missing_ok) +ObjectAddress +RenameFunctionStmtObjectAddress(Node *node, bool missing_ok) { + RenameStmt *stmt = castNode(RenameStmt, node); return FunctionToObjectAddress(stmt->renameType, castNode(ObjectWithArgs, stmt->object), missing_ok); } @@ -1601,9 +1620,10 @@ RenameFunctionStmtObjectAddress(RenameStmt *stmt, bool missing_ok) * AlterFunctionOwnerObjectAddress returns the ObjectAddress of the function that is the * subject of the AlterOwnerStmt. Errors if missing_ok is false. */ -ObjectAddress * -AlterFunctionOwnerObjectAddress(AlterOwnerStmt *stmt, bool missing_ok) +ObjectAddress +AlterFunctionOwnerObjectAddress(Node *node, bool missing_ok) { + AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); return FunctionToObjectAddress(stmt->objectType, castNode(ObjectWithArgs, stmt->object), missing_ok); } @@ -1618,9 +1638,10 @@ AlterFunctionOwnerObjectAddress(AlterOwnerStmt *stmt, bool missing_ok) * the new schema. Errors if missing_ok is false and the type cannot be found in either of * the schemas. */ -ObjectAddress * -AlterFunctionSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, bool missing_ok) +ObjectAddress +AlterFunctionSchemaStmtObjectAddress(Node *node, bool missing_ok) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AssertObjectTypeIsFunctional(stmt->objectType); ObjectWithArgs *objectWithArgs = castNode(ObjectWithArgs, stmt->object); @@ -1662,8 +1683,8 @@ AlterFunctionSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, bool missing_o } } - ObjectAddress *address = palloc0(sizeof(ObjectAddress)); - ObjectAddressSet(*address, ProcedureRelationId, funcOid); + ObjectAddress address = { 0 }; + ObjectAddressSet(address, ProcedureRelationId, funcOid); return address; } @@ -1780,15 +1801,15 @@ ObjectWithArgsFromOid(Oid funcOid) * false an error will be raised by postgres explaining the Function/Procedure could not * be found. */ -static ObjectAddress * +static ObjectAddress FunctionToObjectAddress(ObjectType objectType, ObjectWithArgs *objectWithArgs, bool missing_ok) { AssertObjectTypeIsFunctional(objectType); Oid funcOid = LookupFuncWithArgs(objectType, objectWithArgs, missing_ok); - ObjectAddress *address = palloc0(sizeof(ObjectAddress)); - ObjectAddressSet(*address, ProcedureRelationId, funcOid); + ObjectAddress address = { 0 }; + ObjectAddressSet(address, ProcedureRelationId, funcOid); return address; } diff --git a/src/backend/distributed/commands/grant.c b/src/backend/distributed/commands/grant.c index 3917ab909..4bfef449c 100644 --- a/src/backend/distributed/commands/grant.c +++ b/src/backend/distributed/commands/grant.c @@ -11,9 +11,9 @@ #include "distributed/commands.h" -/* placeholder for PlanGrantStmt */ +/* placeholder for PreprocessGrantStmt */ List * -PlanGrantStmt(GrantStmt *grantStmt) +PreprocessGrantStmt(Node *node, const char *queryString) { return NIL; } diff --git a/src/backend/distributed/commands/index.c b/src/backend/distributed/commands/index.c index 024336205..b2386b734 100644 --- a/src/backend/distributed/commands/index.c +++ b/src/backend/distributed/commands/index.c @@ -96,7 +96,7 @@ IsIndexRenameStmt(RenameStmt *renameStmt) /* - * PlanIndexStmt determines whether a given CREATE INDEX statement involves + * PreprocessIndexStmt determines whether a given CREATE INDEX statement involves * a distributed table. If so (and if the statement does not use unsupported * options), it modifies the input statement to ensure proper execution against * the master node table and creates a DDLJob to encapsulate information needed @@ -104,8 +104,9 @@ IsIndexRenameStmt(RenameStmt *renameStmt) * in a List. If no distributed table is involved, this function returns NIL. */ List * -PlanIndexStmt(IndexStmt *createIndexStatement, const char *createIndexCommand) +PreprocessIndexStmt(Node *node, const char *createIndexCommand) { + IndexStmt *createIndexStatement = castNode(IndexStmt, node); List *ddlJobs = NIL; /* @@ -187,7 +188,7 @@ PlanIndexStmt(IndexStmt *createIndexStatement, const char *createIndexCommand) /* - * PlanReindexStmt determines whether a given REINDEX statement involves + * PreprocessReindexStmt determines whether a given REINDEX statement involves * a distributed table. If so (and if the statement does not use unsupported * options), it modifies the input statement to ensure proper execution against * the master node table and creates a DDLJob to encapsulate information needed @@ -195,8 +196,9 @@ PlanIndexStmt(IndexStmt *createIndexStatement, const char *createIndexCommand) * in a List. If no distributed table is involved, this function returns NIL. */ List * -PlanReindexStmt(ReindexStmt *reindexStatement, const char *reindexCommand) +PreprocessReindexStmt(Node *node, const char *reindexCommand) { + ReindexStmt *reindexStatement = castNode(ReindexStmt, node); List *ddlJobs = NIL; /* @@ -294,7 +296,7 @@ PlanReindexStmt(ReindexStmt *reindexStatement, const char *reindexCommand) /* - * PlanDropIndexStmt determines whether a given DROP INDEX statement involves + * PreprocessDropIndexStmt determines whether a given DROP INDEX statement involves * a distributed table. If so (and if the statement does not use unsupported * options), it modifies the input statement to ensure proper execution against * the master node table and creates a DDLJob to encapsulate information needed @@ -302,8 +304,9 @@ PlanReindexStmt(ReindexStmt *reindexStatement, const char *reindexCommand) * in a List. If no distributed table is involved, this function returns NIL. */ List * -PlanDropIndexStmt(DropStmt *dropIndexStatement, const char *dropIndexCommand) +PreprocessDropIndexStmt(Node *node, const char *dropIndexCommand) { + DropStmt *dropIndexStatement = castNode(DropStmt, node); List *ddlJobs = NIL; ListCell *dropObjectCell = NULL; Oid distributedIndexId = InvalidOid; @@ -384,24 +387,26 @@ PlanDropIndexStmt(DropStmt *dropIndexStatement, const char *dropIndexCommand) /* - * PostProcessIndexStmt marks new indexes invalid if they were created using the + * PostprocessIndexStmt marks new indexes invalid if they were created using the * CONCURRENTLY flag. This (non-transactional) change provides the fallback * state if an error is raised, otherwise a sub-sequent change to valid will be * committed. */ -void -PostProcessIndexStmt(IndexStmt *indexStmt) +List * +PostprocessIndexStmt(Node *node, const char *queryString) { + IndexStmt *indexStmt = castNode(IndexStmt, node); + /* we are only processing CONCURRENT index statements */ if (!indexStmt->concurrent) { - return; + return NIL; } /* this logic only applies to the coordinator */ if (!IsCoordinator()) { - return; + return NIL; } /* commit the current transaction and start anew */ @@ -441,6 +446,8 @@ PostProcessIndexStmt(IndexStmt *indexStmt) /* clean up; index now marked valid, but ROLLBACK will mark invalid */ heap_freetuple(indexTuple); heap_close(pg_index, RowExclusiveLock); + + return NIL; } diff --git a/src/backend/distributed/commands/policy.c b/src/backend/distributed/commands/policy.c index 252660cc2..c51bac841 100644 --- a/src/backend/distributed/commands/policy.c +++ b/src/backend/distributed/commands/policy.c @@ -26,10 +26,11 @@ CreatePolicyCommands(Oid relationId) } -/* placeholder for PlanCreatePolicyStmt */ +/* placeholder for PreprocessCreatePolicyStmt */ List * -PlanCreatePolicyStmt(CreatePolicyStmt *stmt) +PreprocessCreatePolicyStmt(Node *node, const char *queryString) { + CreatePolicyStmt *stmt = castNode(CreatePolicyStmt, node); Oid relationId = RangeVarGetRelid(stmt->table, AccessExclusiveLock, false); @@ -45,9 +46,9 @@ PlanCreatePolicyStmt(CreatePolicyStmt *stmt) } -/* placeholder for PlanAlterPolicyStmt */ +/* placeholder for PreprocessAlterPolicyStmt */ List * -PlanAlterPolicyStmt(AlterPolicyStmt *stmt) +PreprocessAlterPolicyStmt(Node *node, const char *queryString) { /* placeholder for future implementation */ return NIL; @@ -76,9 +77,9 @@ ErrorIfUnsupportedPolicyExpr(Node *expr) } -/* placeholder for PlanDropPolicyStmt */ +/* placeholder for PreprocessDropPolicyStmt */ List * -PlanDropPolicyStmt(DropStmt *stmt, const char *queryString) +PreprocessDropPolicyStmt(Node *node, const char *queryString) { /* placeholder for future implementation */ return NIL; diff --git a/src/backend/distributed/commands/rename.c b/src/backend/distributed/commands/rename.c index 93dfcbff9..fbd354cf2 100644 --- a/src/backend/distributed/commands/rename.c +++ b/src/backend/distributed/commands/rename.c @@ -19,15 +19,16 @@ /* - * PlanRenameStmt first determines whether a given rename statement involves + * PreprocessRenameStmt first determines whether a given rename statement involves * a distributed table. If so (and if it is supported, i.e. renames a column), * it creates a DDLJob to encapsulate information needed during the worker node * portion of DDL execution before returning that DDLJob in a List. If no dis- * tributed table is involved, this function returns NIL. */ List * -PlanRenameStmt(RenameStmt *renameStmt, const char *renameCommand) +PreprocessRenameStmt(Node *node, const char *renameCommand) { + RenameStmt *renameStmt = castNode(RenameStmt, node); Oid objectRelationId = InvalidOid; /* SQL Object OID */ Oid tableRelationId = InvalidOid; /* Relation OID, maybe not the same. */ @@ -136,3 +137,30 @@ ErrorIfUnsupportedRenameStmt(RenameStmt *renameStmt) "currently unsupported"))); } } + + +/* + * PreprocessRenameAttributeStmt called for RenameStmt's that are targetting an attribute eg. + * type attributes. Based on the relation type the attribute gets renamed it dispatches to + * a specialized implementation if present, otherwise return an empty list for its DDLJobs + */ +List * +PreprocessRenameAttributeStmt(Node *node, const char *queryString) +{ + RenameStmt *stmt = castNode(RenameStmt, node); + Assert(stmt->renameType == OBJECT_ATTRIBUTE); + + switch (stmt->relationType) + { + case OBJECT_TYPE: + { + return PreprocessRenameTypeAttributeStmt(node, queryString); + } + + default: + { + /* unsupported relation for attribute rename, do nothing */ + return NIL; + } + } +} diff --git a/src/backend/distributed/commands/role.c b/src/backend/distributed/commands/role.c index f690a1346..127e92528 100644 --- a/src/backend/distributed/commands/role.c +++ b/src/backend/distributed/commands/role.c @@ -38,13 +38,14 @@ static DefElem * makeDefElemInt(char *name, int value); bool EnableAlterRolePropagation = false; /* - * ProcessAlterRoleStmt actually creates the plan we need to execute for alter + * PostprocessAlterRoleStmt actually creates the plan we need to execute for alter * role statement. We need to do it this way because we need to use the encrypted * password, which is, in some cases, created at standardProcessUtility. */ List * -ProcessAlterRoleStmt(AlterRoleStmt *stmt, const char *queryString) +PostprocessAlterRoleStmt(Node *node, const char *queryString) { + AlterRoleStmt *stmt = castNode(AlterRoleStmt, node); ListCell *optionCell = NULL; if (!EnableAlterRolePropagation || !IsCoordinator()) diff --git a/src/backend/distributed/commands/schema.c b/src/backend/distributed/commands/schema.c index dcfcc8b7b..c5cd89c0c 100644 --- a/src/backend/distributed/commands/schema.c +++ b/src/backend/distributed/commands/schema.c @@ -31,12 +31,13 @@ /* - * ProcessDropSchemaStmt invalidates the foreign key cache if any table created + * PreprocessDropSchemaStmt invalidates the foreign key cache if any table created * under dropped schema involved in any foreign key relationship. */ -void -ProcessDropSchemaStmt(DropStmt *dropStatement) +List * +PreprocessDropSchemaStmt(Node *node, const char *queryString) { + DropStmt *dropStatement = castNode(DropStmt, node); Relation pgClass = NULL; HeapTuple heapTuple = NULL; SysScanDesc scanDescriptor = NULL; @@ -48,7 +49,7 @@ ProcessDropSchemaStmt(DropStmt *dropStatement) if (dropStatement->behavior != DROP_CASCADE) { - return; + return NIL; } foreach(dropSchemaCell, dropStatement->objects) @@ -91,7 +92,7 @@ ProcessDropSchemaStmt(DropStmt *dropStatement) systable_endscan(scanDescriptor); heap_close(pgClass, NoLock); - return; + return NIL; } heapTuple = systable_getnext(scanDescriptor); @@ -100,69 +101,21 @@ ProcessDropSchemaStmt(DropStmt *dropStatement) systable_endscan(scanDescriptor); heap_close(pgClass, NoLock); } + + return NIL; } /* - * PlanAlterObjectSchemaStmt is called by citus' utility hook for AlterObjectSchemaStmt - * parsetrees. It dispatches the statement based on the object type for which the schema - * is being altered. - * - * A (potentially empty) list of DDLJobs is being returned with the jobs on how to - * distribute the change into the cluster. - */ -List * -PlanAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString) -{ - switch (stmt->objectType) - { - case OBJECT_TYPE: - { - return PlanAlterTypeSchemaStmt(stmt, queryString); - } - - case OBJECT_COLLATION: - { - return PlanAlterCollationSchemaStmt(stmt, queryString); - } - - case OBJECT_PROCEDURE: - case OBJECT_AGGREGATE: - case OBJECT_FUNCTION: - { - return PlanAlterFunctionSchemaStmt(stmt, queryString); - } - - case OBJECT_EXTENSION: - { - return PlanAlterExtensionSchemaStmt(stmt, queryString); - } - - default: - { - /* do nothing for unsupported objects */ - break; - } - } - - /* - * old behaviour, needs to be reconciled to the above switch statement for all - * objectType's relating to tables. Maybe it is as easy to support - * ALTER TABLE ... SET SCHEMA - */ - return PlanAlterTableSchemaStmt(stmt, queryString); -} - - -/* - * PlanAlterTableSchemaStmt determines whether a given ALTER ... SET SCHEMA + * PreprocessAlterTableSchemaStmt determines whether a given ALTER ... SET SCHEMA * statement involves a distributed table and issues a warning if so. Because * we do not support distributed ALTER ... SET SCHEMA, this function always * returns NIL. */ List * -PlanAlterTableSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString) +PreprocessAlterTableSchemaStmt(Node *node, const char *queryString) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); if (stmt->relation == NULL) { return NIL; @@ -186,49 +139,3 @@ PlanAlterTableSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString) return NIL; } - - -/* - * ProcessAlterObjectSchemaStmt is called by multi_ProcessUtility _after_ the command has - * been applied to the local postgres. It is useful to create potentially new dependencies - * of this object (the new schema) on the workers before the command gets applied to the - * remote objects. - */ -void -ProcessAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString) -{ - switch (stmt->objectType) - { - case OBJECT_TYPE: - { - ProcessAlterTypeSchemaStmt(stmt, queryString); - return; - } - - case OBJECT_COLLATION: - { - ProcessAlterCollationSchemaStmt(stmt, queryString); - return; - } - - case OBJECT_PROCEDURE: - case OBJECT_AGGREGATE: - case OBJECT_FUNCTION: - { - ProcessAlterFunctionSchemaStmt(stmt, queryString); - return; - } - - case OBJECT_EXTENSION: - { - ProcessAlterExtensionSchemaStmt(stmt, queryString); - return; - } - - default: - { - /* do nothing for unsupported objects */ - return; - } - } -} diff --git a/src/backend/distributed/commands/table.c b/src/backend/distributed/commands/table.c index 79b861cf6..637fa01c0 100644 --- a/src/backend/distributed/commands/table.c +++ b/src/backend/distributed/commands/table.c @@ -52,7 +52,7 @@ static void ErrorIfUnsupportedAlterAddConstraintStmt(AlterTableStmt *alterTableS static bool SetupExecutionModeForAlterTable(Oid relationId, AlterTableCmd *command); /* - * ProcessDropTableStmt processes DROP TABLE commands for partitioned tables. + * PreprocessDropTableStmt processes DROP TABLE commands for partitioned tables. * If we are trying to DROP partitioned tables, we first need to go to MX nodes * and DETACH partitions from their parents. Otherwise, we process DROP command * multiple times in MX workers. For shards, we send DROP commands with IF EXISTS @@ -61,9 +61,10 @@ static bool SetupExecutionModeForAlterTable(Oid relationId, AlterTableCmd *comma * Postgres catalogs via performDeletion function, thus we need to be cautious * about not processing same DROP command twice. */ -void -ProcessDropTableStmt(DropStmt *dropTableStatement) +List * +PreprocessDropTableStmt(Node *node, const char *queryString) { + DropStmt *dropTableStatement = castNode(DropStmt, node); ListCell *dropTableCell = NULL; Assert(dropTableStatement->removeType == OBJECT_TABLE); @@ -114,11 +115,13 @@ ProcessDropTableStmt(DropStmt *dropTableStatement) SendCommandToWorkersWithMetadata(detachPartitionCommand); } } + + return NIL; } /* - * ProcessCreateTableStmtPartitionOf takes CreateStmt object as a parameter but + * PostprocessCreateTableStmtPartitionOf takes CreateStmt object as a parameter but * it only processes CREATE TABLE ... PARTITION OF statements and it checks if * user creates the table as a partition of a distributed table. In that case, * it distributes partition as well. Since the table itself is a partition, @@ -128,8 +131,9 @@ ProcessDropTableStmt(DropStmt *dropTableStatement) * This function does nothing if the provided CreateStmt is not a CREATE TABLE ... * PARTITION OF command. */ -void -ProcessCreateTableStmtPartitionOf(CreateStmt *createStatement) +List * +PostprocessCreateTableStmtPartitionOf(CreateStmt *createStatement, const + char *queryString) { if (createStatement->inhRelations != NIL && createStatement->partbound != NULL) { @@ -162,11 +166,13 @@ ProcessCreateTableStmtPartitionOf(CreateStmt *createStatement) viaDeprecatedAPI); } } + + return NIL; } /* - * ProcessAlterTableStmtAttachPartition takes AlterTableStmt object as parameter + * PostprocessAlterTableStmtAttachPartition takes AlterTableStmt object as parameter * but it only processes into ALTER TABLE ... ATTACH PARTITION commands and * distributes the partition if necessary. There are four cases to consider; * @@ -191,8 +197,9 @@ ProcessCreateTableStmtPartitionOf(CreateStmt *createStatement) * This function does nothing if the provided CreateStmt is not an ALTER TABLE ... * ATTACH PARTITION OF command. */ -void -ProcessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement) +List * +PostprocessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement, + const char *queryString) { List *commandList = alterTableStatement->cmds; ListCell *commandCell = NULL; @@ -239,11 +246,13 @@ ProcessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement) } } } + + return NIL; } /* - * PlanAlterTableStmt determines whether a given ALTER TABLE statement involves + * PreprocessAlterTableStmt determines whether a given ALTER TABLE statement involves * a distributed table. If so (and if the statement does not use unsupported * options), it modifies the input statement to ensure proper execution against * the master node table and creates a DDLJob to encapsulate information needed @@ -251,8 +260,9 @@ ProcessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement) * in a List. If no distributed table is involved, this function returns NIL. */ List * -PlanAlterTableStmt(AlterTableStmt *alterTableStatement, const char *alterTableCommand) +PreprocessAlterTableStmt(Node *node, const char *alterTableCommand) { + AlterTableStmt *alterTableStatement = castNode(AlterTableStmt, node); Oid rightRelationId = InvalidOid; ListCell *commandCell = NULL; bool executeSequentially = false; @@ -448,6 +458,24 @@ PlanAlterTableStmt(AlterTableStmt *alterTableStatement, const char *alterTableCo } +/* + * PreprocessAlterTableStmt issues a warning. + * ALTER TABLE ALL IN TABLESPACE statements have their node type as + * AlterTableMoveAllStmt. At the moment we do not support this functionality in + * the distributed environment. We warn out here. + */ +List * +PreprocessAlterTableMoveAllStmt(Node *node, const char *queryString) +{ + ereport(WARNING, (errmsg("not propagating ALTER TABLE ALL IN TABLESPACE " + "commands to worker nodes"), + errhint("Connect to worker nodes directly to manually " + "move all tables."))); + + return NIL; +} + + /* * WorkerProcessAlterTableStmt checks and processes the alter table statement to be * worked on the distributed table of the worker node. Currently, it only processes @@ -587,14 +615,14 @@ ErrorIfAlterDropsPartitionColumn(AlterTableStmt *alterTableStatement) /* - * PostProcessAlterTableStmt runs after the ALTER TABLE command has already run on the + * PostprocessAlterTableStmt runs after the ALTER TABLE command has already run on the * master, so we are checking constraints over the table with constraints already defined * (to make the constraint check process same for ALTER TABLE and CREATE TABLE). If * constraints do not fulfill the rules we defined, they will be removed and the table * will return back to the state before the ALTER TABLE command. */ void -PostProcessAlterTableStmt(AlterTableStmt *alterTableStatement) +PostprocessAlterTableStmt(AlterTableStmt *alterTableStatement) { List *commandList = alterTableStatement->cmds; ListCell *commandCell = NULL; @@ -607,7 +635,7 @@ PostProcessAlterTableStmt(AlterTableStmt *alterTableStatement) /* changing a relation could introduce new dependencies */ ObjectAddress tableAddress = { 0 }; ObjectAddressSet(tableAddress, RelationRelationId, relationId); - EnsureDependenciesExistsOnAllNodes(&tableAddress); + EnsureDependenciesExistOnAllNodes(&tableAddress); } foreach(commandCell, commandList) diff --git a/src/backend/distributed/commands/truncate.c b/src/backend/distributed/commands/truncate.c index e5fbe938f..2bd177815 100644 --- a/src/backend/distributed/commands/truncate.c +++ b/src/backend/distributed/commands/truncate.c @@ -42,12 +42,12 @@ static void AcquireDistributedLockOnRelations(List *relationIdList, LOCKMODE loc /* - * ProcessTruncateStatement handles few things that should be + * PostprocessTruncateStatement handles few things that should be * done before standard process utility is called for truncate * command. */ void -ProcessTruncateStatement(TruncateStmt *truncateStatement) +PostprocessTruncateStatement(TruncateStmt *truncateStatement) { ErrorIfUnsupportedTruncateStmt(truncateStatement); EnsurePartitionTableNotReplicatedForTruncate(truncateStatement); diff --git a/src/backend/distributed/commands/type.c b/src/backend/distributed/commands/type.c index 620a0e7d0..e7a54dff0 100644 --- a/src/backend/distributed/commands/type.c +++ b/src/backend/distributed/commands/type.c @@ -101,7 +101,7 @@ static bool ShouldPropagateTypeCreate(void); /* - * PlanCompositeTypeStmt is called during the creation of a composite type. It is executed + * PreprocessCompositeTypeStmt is called during the creation of a composite type. It is executed * before the statement is applied locally. * * We decide if the compisite type needs to be replicated to the worker, and if that is @@ -112,7 +112,7 @@ static bool ShouldPropagateTypeCreate(void); * access to the ObjectAddress of the new type. */ List * -PlanCompositeTypeStmt(CompositeTypeStmt *stmt, const char *queryString) +PreprocessCompositeTypeStmt(Node *node, const char *queryString) { if (!ShouldPropagateTypeCreate()) { @@ -136,7 +136,7 @@ PlanCompositeTypeStmt(CompositeTypeStmt *stmt, const char *queryString) LockRelationOid(DistNodeRelationId(), RowShareLock); /* fully qualify before lookup and later deparsing */ - QualifyTreeNode((Node *) stmt); + QualifyTreeNode(node); /* * reconstruct creation statement in a portable fashion. The create_or_replace helper @@ -146,7 +146,7 @@ PlanCompositeTypeStmt(CompositeTypeStmt *stmt, const char *queryString) * type previously has been attempted to be created in a transaction which did not * commit on the coordinator. */ - const char *compositeTypeStmtSql = DeparseCompositeTypeStmt(stmt); + const char *compositeTypeStmtSql = DeparseCompositeTypeStmt(node); compositeTypeStmtSql = WrapCreateOrReplace(compositeTypeStmtSql); /* @@ -164,45 +164,46 @@ PlanCompositeTypeStmt(CompositeTypeStmt *stmt, const char *queryString) /* - * ProcessCompositeTypeStmt is executed after the type has been created locally and before + * PostprocessCompositeTypeStmt is executed after the type has been created locally and before * we create it on the remote servers. Here we have access to the ObjectAddress of the new * type which we use to make sure the type's dependencies are on all nodes. */ -void -ProcessCompositeTypeStmt(CompositeTypeStmt *stmt, const char *queryString) +List * +PostprocessCompositeTypeStmt(Node *node, const char *queryString) { /* same check we perform during planning of the statement */ if (!ShouldPropagateTypeCreate()) { - return; + return NIL; } /* * find object address of the just created object, because the type has been created * locally it can't be missing */ - const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt, - false); - EnsureDependenciesExistsOnAllNodes(typeAddress); + ObjectAddress typeAddress = GetObjectAddressFromParseTree(node, false); + EnsureDependenciesExistOnAllNodes(&typeAddress); - MarkObjectDistributed(typeAddress); + MarkObjectDistributed(&typeAddress); + + return NIL; } /* - * PlanAlterTypeStmt is invoked for alter type statements for composite types. + * PreprocessAlterTypeStmt is invoked for alter type statements for composite types. * * Normally we would have a process step as well to re-ensure dependencies exists, however * this is already implemented by the post processing for adding columns to tables. */ List * -PlanAlterTypeStmt(AlterTableStmt *stmt, const char *queryString) +PreprocessAlterTypeStmt(Node *node, const char *queryString) { + AlterTableStmt *stmt = castNode(AlterTableStmt, node); Assert(stmt->relkind == OBJECT_TYPE); - const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt, - false); - if (!ShouldPropagateObject(typeAddress)) + ObjectAddress typeAddress = GetObjectAddressFromParseTree((Node *) stmt, false); + if (!ShouldPropagateObject(&typeAddress)) { return NIL; } @@ -229,7 +230,7 @@ PlanAlterTypeStmt(AlterTableStmt *stmt, const char *queryString) /* - * PlanCreateEnumStmt is called before the statement gets applied locally. + * PreprocessCreateEnumStmt is called before the statement gets applied locally. * * It decides if the create statement will be applied to the workers and if that is the * case returns a list of DDLJobs that will be executed _after_ the statement has been @@ -239,24 +240,21 @@ PlanAlterTypeStmt(AlterTableStmt *stmt, const char *queryString) * ObjectAddress for the new type just yet. */ List * -PlanCreateEnumStmt(CreateEnumStmt *stmt, const char *queryString) +PreprocessCreateEnumStmt(Node *node, const char *queryString) { if (!ShouldPropagateTypeCreate()) { return NIL; } - /* - * managing types can only be done on the coordinator if ddl propagation is on. when - * it is off we will never get here - */ + /* managing types can only be done on the coordinator */ EnsureCoordinator(); /* enforce fully qualified typeName for correct deparsing and lookup */ - QualifyTreeNode((Node *) stmt); + QualifyTreeNode(node); /* reconstruct creation statement in a portable fashion */ - const char *createEnumStmtSql = DeparseCreateEnumStmt(stmt); + const char *createEnumStmtSql = DeparseCreateEnumStmt(node); createEnumStmtSql = WrapCreateOrReplace(createEnumStmtSql); /* @@ -275,37 +273,38 @@ PlanCreateEnumStmt(CreateEnumStmt *stmt, const char *queryString) /* - * ProcessCreateEnumStmt is called after the statement has been applied locally, but + * PostprocessCreateEnumStmt is called after the statement has been applied locally, but * before the plan on how to create the types on the workers has been executed. * * We apply the same checks to verify if the type should be distributed, if that is the * case we resolve the ObjectAddress for the just created object, distribute its * dependencies to all the nodes, and mark the object as distributed. */ -void -ProcessCreateEnumStmt(CreateEnumStmt *stmt, const char *queryString) +List * +PostprocessCreateEnumStmt(Node *node, const char *queryString) { if (!ShouldPropagateTypeCreate()) { - return; + return NIL; } /* lookup type address of just created type */ - const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt, - false); - EnsureDependenciesExistsOnAllNodes(typeAddress); + ObjectAddress typeAddress = GetObjectAddressFromParseTree(node, false); + EnsureDependenciesExistOnAllNodes(&typeAddress); /* * now that the object has been created and distributed to the workers we mark them as * distributed so we know to keep them up to date and recreate on a new node in the * future */ - MarkObjectDistributed(typeAddress); + MarkObjectDistributed(&typeAddress); + + return NIL; } /* - * PlanAlterEnumStmt handles ALTER TYPE ... ADD VALUE for enum based types. Planning + * PreprocessAlterEnumStmt handles ALTER TYPE ... ADD VALUE for enum based types. Planning * happens before the statement has been applied locally. * * Since it is an alter of an existing type we actually have the ObjectAddress. This is @@ -313,13 +312,12 @@ ProcessCreateEnumStmt(CreateEnumStmt *stmt, const char *queryString) * workers directly to keep the types in sync accross the cluster. */ List * -PlanAlterEnumStmt(AlterEnumStmt *stmt, const char *queryString) +PreprocessAlterEnumStmt(Node *node, const char *queryString) { List *commands = NIL; - const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt, - false); - if (!ShouldPropagateObject(typeAddress)) + ObjectAddress typeAddress = GetObjectAddressFromParseTree(node, false); + if (!ShouldPropagateObject(&typeAddress)) { return NIL; } @@ -338,8 +336,8 @@ PlanAlterEnumStmt(AlterEnumStmt *stmt, const char *queryString) */ EnsureCoordinator(); - QualifyTreeNode((Node *) stmt); - const char *alterEnumStmtSql = DeparseTreeNode((Node *) stmt); + QualifyTreeNode(node); + const char *alterEnumStmtSql = DeparseTreeNode(node); /* * Before pg12 ALTER ENUM ... ADD VALUE could not be within a xact block. Instead of @@ -347,7 +345,7 @@ PlanAlterEnumStmt(AlterEnumStmt *stmt, const char *queryString) * we directly connect to workers and execute the commands remotely. */ #if PG_VERSION_NUM < 120000 - if (AlterEnumIsAddValue(stmt)) + if (AlterEnumIsAddValue(castNode(AlterEnumStmt, node))) { /* * a plan cannot be made as it will be committed via 2PC when ran through the @@ -366,7 +364,7 @@ PlanAlterEnumStmt(AlterEnumStmt *stmt, const char *queryString) /* - * ProcessAlterEnumStmt is called after the AlterEnumStmt has been applied locally. + * PostprocessAlterEnumStmt is called after the AlterEnumStmt has been applied locally. * * This function is used for ALTER ENUM ... ADD VALUE for postgres versions lower than 12 * to distribute the call. Before pg12 these statements could not be called in a @@ -381,16 +379,9 @@ PlanAlterEnumStmt(AlterEnumStmt *stmt, const char *queryString) * For pg12 the statements can be called in a transaction but will only become visible * when the transaction commits. This is behaviour that is ok to perform in a 2PC. */ -void -ProcessAlterEnumStmt(AlterEnumStmt *stmt, const char *queryString) +List * +PostprocessAlterEnumStmt(Node *node, const char *queryString) { - const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt, - false); - if (!ShouldPropagateObject(typeAddress)) - { - return; - } - /* * Before pg12 ALTER ENUM ... ADD VALUE could not be within a xact block. Normally we * would propagate the statements in a xact block to perform 2pc on changes via ddl. @@ -400,6 +391,13 @@ ProcessAlterEnumStmt(AlterEnumStmt *stmt, const char *queryString) * planning. */ #if PG_VERSION_NUM < 120000 + AlterEnumStmt *stmt = castNode(AlterEnumStmt, node); + ObjectAddress typeAddress = GetObjectAddressFromParseTree((Node *) stmt, false); + if (!ShouldPropagateObject(&typeAddress)) + { + return NIL; + } + if (AlterEnumIsAddValue(stmt)) { /* @@ -433,17 +431,21 @@ ProcessAlterEnumStmt(AlterEnumStmt *stmt, const char *queryString) } } #endif + + return NIL; } /* - * PlanDropTypeStmt is called for all DROP TYPE statements. For all types in the list that + * PreprocessDropTypeStmt is called for all DROP TYPE statements. For all types in the list that * citus has distributed to the workers it will drop the type on the workers as well. If * no types in the drop list are distributed no calls will be made to the workers. */ List * -PlanDropTypeStmt(DropStmt *stmt, const char *queryString) +PreprocessDropTypeStmt(Node *node, const char *queryString) { + DropStmt *stmt = castNode(DropStmt, node); + /* * We swap the list of objects to remove during deparse so we need a reference back to * the old list to put back @@ -501,7 +503,7 @@ PlanDropTypeStmt(DropStmt *stmt, const char *queryString) /* - * PlanRenameTypeStmt is called when the user is renaming the type. The invocation happens + * PreprocessRenameTypeStmt is called when the user is renaming the type. The invocation happens * before the statement is applied locally. * * As the type already exists we have access to the ObjectAddress for the type, this is @@ -509,20 +511,19 @@ PlanDropTypeStmt(DropStmt *stmt, const char *queryString) * executed on all the workers to keep the types in sync across the cluster. */ List * -PlanRenameTypeStmt(RenameStmt *stmt, const char *queryString) +PreprocessRenameTypeStmt(Node *node, const char *queryString) { - const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt, - false); - if (!ShouldPropagateObject(typeAddress)) + ObjectAddress typeAddress = GetObjectAddressFromParseTree(node, false); + if (!ShouldPropagateObject(&typeAddress)) { return NIL; } /* fully qualify */ - QualifyTreeNode((Node *) stmt); + QualifyTreeNode(node); /* deparse sql*/ - const char *renameStmtSql = DeparseTreeNode((Node *) stmt); + const char *renameStmtSql = DeparseTreeNode(node); EnsureSequentialModeForTypeDDL(); @@ -536,21 +537,21 @@ PlanRenameTypeStmt(RenameStmt *stmt, const char *queryString) /* - * PlanRenameTypeAttributeStmt is called for changes of attribute names for composite + * PreprocessRenameTypeAttributeStmt is called for changes of attribute names for composite * types. Planning is called before the statement is applied locally. * * For distributed types we apply the attribute renames directly on all the workers to * keep the type in sync across the cluster. */ List * -PlanRenameTypeAttributeStmt(RenameStmt *stmt, const char *queryString) +PreprocessRenameTypeAttributeStmt(Node *node, const char *queryString) { + RenameStmt *stmt = castNode(RenameStmt, node); Assert(stmt->renameType == OBJECT_ATTRIBUTE); Assert(stmt->relationType == OBJECT_TYPE); - const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt, - false); - if (!ShouldPropagateObject(typeAddress)) + ObjectAddress typeAddress = GetObjectAddressFromParseTree((Node *) stmt, false); + if (!ShouldPropagateObject(&typeAddress)) { return NIL; } @@ -569,19 +570,19 @@ PlanRenameTypeAttributeStmt(RenameStmt *stmt, const char *queryString) /* - * PlanAlterTypeSchemaStmt is executed before the statement is applied to the local + * PreprocessAlterTypeSchemaStmt is executed before the statement is applied to the local * postgres instance. * * In this stage we can prepare the commands that need to be run on all workers. */ List * -PlanAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString) +PreprocessAlterTypeSchemaStmt(Node *node, const char *queryString) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); Assert(stmt->objectType == OBJECT_TYPE); - const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt, - false); - if (!ShouldPropagateObject(typeAddress)) + ObjectAddress typeAddress = GetObjectAddressFromParseTree((Node *) stmt, false); + if (!ShouldPropagateObject(&typeAddress)) { return NIL; } @@ -602,42 +603,44 @@ PlanAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString) /* - * ProcessAlterTypeSchemaStmt is executed after the change has been applied locally, we + * PostprocessAlterTypeSchemaStmt is executed after the change has been applied locally, we * can now use the new dependencies of the type to ensure all its dependencies exist on * the workers before we apply the commands remotely. */ -void -ProcessAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString) +List * +PostprocessAlterTypeSchemaStmt(Node *node, const char *queryString) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); Assert(stmt->objectType == OBJECT_TYPE); - const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt, - false); - if (!ShouldPropagateObject(typeAddress)) + ObjectAddress typeAddress = GetObjectAddressFromParseTree((Node *) stmt, false); + if (!ShouldPropagateObject(&typeAddress)) { - return; + return NIL; } /* dependencies have changed (schema) let's ensure they exist */ - EnsureDependenciesExistsOnAllNodes(typeAddress); + EnsureDependenciesExistOnAllNodes(&typeAddress); + + return NIL; } /* - * PlanAlterTypeOwnerStmt is called for change of ownership of types before the + * PreprocessAlterTypeOwnerStmt is called for change of ownership of types before the * ownership is changed on the local instance. * * If the type for which the owner is changed is distributed we execute the change on all * the workers to keep the type in sync across the cluster. */ List * -PlanAlterTypeOwnerStmt(AlterOwnerStmt *stmt, const char *queryString) +PreprocessAlterTypeOwnerStmt(Node *node, const char *queryString) { + AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); Assert(stmt->objectType == OBJECT_TYPE); - const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt, - false); - if (!ShouldPropagateObject(typeAddress)) + ObjectAddress typeAddress = GetObjectAddressFromParseTree((Node *) stmt, false); + if (!ShouldPropagateObject(&typeAddress)) { return NIL; } @@ -815,13 +818,14 @@ EnumValsList(Oid typeOid) * Never returns NULL, but the objid in the address could be invalid if missing_ok was set * to true. */ -ObjectAddress * -CompositeTypeStmtObjectAddress(CompositeTypeStmt *stmt, bool missing_ok) +ObjectAddress +CompositeTypeStmtObjectAddress(Node *node, bool missing_ok) { + CompositeTypeStmt *stmt = castNode(CompositeTypeStmt, node); TypeName *typeName = MakeTypeNameFromRangeVar(stmt->typevar); Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok); - ObjectAddress *address = palloc0(sizeof(ObjectAddress)); - ObjectAddressSet(*address, TypeRelationId, typeOid); + ObjectAddress address = { 0 }; + ObjectAddressSet(address, TypeRelationId, typeOid); return address; } @@ -835,13 +839,14 @@ CompositeTypeStmtObjectAddress(CompositeTypeStmt *stmt, bool missing_ok) * Never returns NULL, but the objid in the address could be invalid if missing_ok was set * to true. */ -ObjectAddress * -CreateEnumStmtObjectAddress(CreateEnumStmt *stmt, bool missing_ok) +ObjectAddress +CreateEnumStmtObjectAddress(Node *node, bool missing_ok) { + CreateEnumStmt *stmt = castNode(CreateEnumStmt, node); TypeName *typeName = makeTypeNameFromNameList(stmt->typeName); Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok); - ObjectAddress *address = palloc0(sizeof(ObjectAddress)); - ObjectAddressSet(*address, TypeRelationId, typeOid); + ObjectAddress address = { 0 }; + ObjectAddressSet(address, TypeRelationId, typeOid); return address; } @@ -855,15 +860,16 @@ CreateEnumStmtObjectAddress(CreateEnumStmt *stmt, bool missing_ok) * Never returns NULL, but the objid in the address could be invalid if missing_ok was set * to true. */ -ObjectAddress * -AlterTypeStmtObjectAddress(AlterTableStmt *stmt, bool missing_ok) +ObjectAddress +AlterTypeStmtObjectAddress(Node *node, bool missing_ok) { + AlterTableStmt *stmt = castNode(AlterTableStmt, node); Assert(stmt->relkind == OBJECT_TYPE); TypeName *typeName = MakeTypeNameFromRangeVar(stmt->relation); Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok); - ObjectAddress *address = palloc0(sizeof(ObjectAddress)); - ObjectAddressSet(*address, TypeRelationId, typeOid); + ObjectAddress address = { 0 }; + ObjectAddressSet(address, TypeRelationId, typeOid); return address; } @@ -873,13 +879,14 @@ AlterTypeStmtObjectAddress(AlterTableStmt *stmt, bool missing_ok) * AlterEnumStmtObjectAddress return the ObjectAddress of the enum type that is the * object of the AlterEnumStmt. Errors is missing_ok is false. */ -ObjectAddress * -AlterEnumStmtObjectAddress(AlterEnumStmt *stmt, bool missing_ok) +ObjectAddress +AlterEnumStmtObjectAddress(Node *node, bool missing_ok) { + AlterEnumStmt *stmt = castNode(AlterEnumStmt, node); TypeName *typeName = makeTypeNameFromNameList(stmt->typeName); Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok); - ObjectAddress *address = palloc0(sizeof(ObjectAddress)); - ObjectAddressSet(*address, TypeRelationId, typeOid); + ObjectAddress address = { 0 }; + ObjectAddressSet(address, TypeRelationId, typeOid); return address; } @@ -889,15 +896,16 @@ AlterEnumStmtObjectAddress(AlterEnumStmt *stmt, bool missing_ok) * RenameTypeStmtObjectAddress returns the ObjectAddress of the type that is the object * of the RenameStmt. Errors if missing_ok is false. */ -ObjectAddress * -RenameTypeStmtObjectAddress(RenameStmt *stmt, bool missing_ok) +ObjectAddress +RenameTypeStmtObjectAddress(Node *node, bool missing_ok) { + RenameStmt *stmt = castNode(RenameStmt, node); Assert(stmt->renameType == OBJECT_TYPE); TypeName *typeName = makeTypeNameFromNameList((List *) stmt->object); Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok); - ObjectAddress *address = palloc0(sizeof(ObjectAddress)); - ObjectAddressSet(*address, TypeRelationId, typeOid); + ObjectAddress address = { 0 }; + ObjectAddressSet(address, TypeRelationId, typeOid); return address; } @@ -912,9 +920,10 @@ RenameTypeStmtObjectAddress(RenameStmt *stmt, bool missing_ok) * new schema. Errors if missing_ok is false and the type cannot be found in either of the * schemas. */ -ObjectAddress * -AlterTypeSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, bool missing_ok) +ObjectAddress +AlterTypeSchemaStmtObjectAddress(Node *node, bool missing_ok) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); Assert(stmt->objectType == OBJECT_TYPE); List *names = (List *) stmt->object; @@ -956,8 +965,8 @@ AlterTypeSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, bool missing_ok) } } - ObjectAddress *address = palloc0(sizeof(ObjectAddress)); - ObjectAddressSet(*address, TypeRelationId, typeOid); + ObjectAddress address = { 0 }; + ObjectAddressSet(address, TypeRelationId, typeOid); return address; } @@ -971,16 +980,17 @@ AlterTypeSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, bool missing_ok) * changed as Attributes are not distributed on their own but as a side effect of the * whole type distribution. */ -ObjectAddress * -RenameTypeAttributeStmtObjectAddress(RenameStmt *stmt, bool missing_ok) +ObjectAddress +RenameTypeAttributeStmtObjectAddress(Node *node, bool missing_ok) { + RenameStmt *stmt = castNode(RenameStmt, node); Assert(stmt->renameType == OBJECT_ATTRIBUTE); Assert(stmt->relationType == OBJECT_TYPE); TypeName *typeName = MakeTypeNameFromRangeVar(stmt->relation); Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok); - ObjectAddress *address = palloc0(sizeof(ObjectAddress)); - ObjectAddressSet(*address, TypeRelationId, typeOid); + ObjectAddress address = { 0 }; + ObjectAddressSet(address, TypeRelationId, typeOid); return address; } @@ -990,15 +1000,16 @@ RenameTypeAttributeStmtObjectAddress(RenameStmt *stmt, bool missing_ok) * AlterTypeOwnerObjectAddress returns the ObjectAddress of the type that is the object * of the AlterOwnerStmt. Errors if missing_ok is false. */ -ObjectAddress * -AlterTypeOwnerObjectAddress(AlterOwnerStmt *stmt, bool missing_ok) +ObjectAddress +AlterTypeOwnerObjectAddress(Node *node, bool missing_ok) { + AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); Assert(stmt->objectType == OBJECT_TYPE); TypeName *typeName = makeTypeNameFromNameList((List *) stmt->object); Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok); - ObjectAddress *address = palloc0(sizeof(ObjectAddress)); - ObjectAddressSet(*address, TypeRelationId, typeOid); + ObjectAddress address = { 0 }; + ObjectAddressSet(address, TypeRelationId, typeOid); return address; } diff --git a/src/backend/distributed/commands/utility_hook.c b/src/backend/distributed/commands/utility_hook.c index 87eb0becf..540bc6f95 100644 --- a/src/backend/distributed/commands/utility_hook.c +++ b/src/backend/distributed/commands/utility_hook.c @@ -4,7 +4,7 @@ * * The utility hook is called by PostgreSQL when processing any command * that is not SELECT, UPDATE, DELETE, INSERT, in place of the regular - * ProcessUtility function. We use this primarily to implement (or in + * PostprocessUtility function. We use this primarily to implement (or in * some cases prevent) DDL commands and COPY on distributed tables. * * For DDL commands that affect distributed tables, we check whether @@ -18,7 +18,7 @@ * on their distribution column value instead of writing it to the local * table on the coordinator. For COPY from a distributed table, we * replace the table with a SELECT * FROM table and pass it back to - * ProcessUtility, which will plan the query via the distributed planner + * PostprocessUtility, which will plan the query via the distributed planner * hook. * * Copyright (c) Citus Data, Inc. @@ -41,6 +41,7 @@ #include "distributed/commands.h" #include "distributed/commands/multi_copy.h" #include "distributed/commands/utility_hook.h" /* IWYU pragma: keep */ +#include "distributed/deparser.h" #include "distributed/listutils.h" #include "distributed/local_executor.h" #include "distributed/maintenanced.h" @@ -72,11 +73,6 @@ static int activeDropSchemaOrDBs = 0; static void ExecuteDistributedDDLJob(DDLJob *ddlJob); static char * SetSearchPathToCurrentSearchPathCommand(void); static char * CurrentSearchPath(void); -static void PostProcessUtility(Node *parsetree); -static List * PlanRenameAttributeStmt(RenameStmt *stmt, const char *queryString); -static List * PlanAlterOwnerStmt(AlterOwnerStmt *stmt, const char *queryString); -static List * PlanAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, - const char *queryString); static bool IsDropSchemaOrDB(Node *parsetree); @@ -289,7 +285,7 @@ multi_ProcessUtility(PlannedStmt *pstmt, if (IsMultiStatementTransaction() && ShouldPropagateSetCommand(setStmt)) { - ProcessVariableSetStmt(setStmt, queryString); + PostprocessVariableSetStmt(setStmt, queryString); } } @@ -368,245 +364,21 @@ multi_ProcessUtility(PlannedStmt *pstmt, if (IsA(parsetree, TruncateStmt)) { - ProcessTruncateStatement((TruncateStmt *) parsetree); + PostprocessTruncateStatement((TruncateStmt *) parsetree); } /* only generate worker DDLJobs if propagation is enabled */ + const DistributeObjectOps *ops = NULL; if (EnableDDLPropagation) { /* copy planned statement since we might scribble on it or its utilityStmt */ pstmt = copyObject(pstmt); parsetree = pstmt->utilityStmt; + ops = GetDistributeObjectOps(parsetree); - if (IsA(parsetree, IndexStmt)) + if (ops && ops->preprocess) { - ddlJobs = PlanIndexStmt((IndexStmt *) parsetree, queryString); - } - - if (IsA(parsetree, ReindexStmt)) - { - ddlJobs = PlanReindexStmt((ReindexStmt *) parsetree, queryString); - } - - if (IsA(parsetree, DropStmt)) - { - DropStmt *dropStatement = (DropStmt *) parsetree; - switch (dropStatement->removeType) - { - case OBJECT_COLLATION: - { - ddlJobs = PlanDropCollationStmt(dropStatement); - break; - } - - case OBJECT_INDEX: - { - ddlJobs = PlanDropIndexStmt(dropStatement, queryString); - break; - } - - case OBJECT_TABLE: - { - ProcessDropTableStmt(dropStatement); - break; - } - - case OBJECT_SCHEMA: - { - ProcessDropSchemaStmt(dropStatement); - break; - } - - case OBJECT_POLICY: - { - ddlJobs = PlanDropPolicyStmt(dropStatement, queryString); - break; - } - - case OBJECT_TYPE: - { - ddlJobs = PlanDropTypeStmt(dropStatement, queryString); - break; - } - - case OBJECT_PROCEDURE: - case OBJECT_AGGREGATE: - case OBJECT_FUNCTION: - { - ddlJobs = PlanDropFunctionStmt(dropStatement, queryString); - break; - } - - case OBJECT_EXTENSION: - { - ddlJobs = PlanDropExtensionStmt(dropStatement, queryString); - break; - } - - default: - { - /* unsupported type, skipping*/ - } - } - } - - if (IsA(parsetree, AlterEnumStmt)) - { - ddlJobs = PlanAlterEnumStmt(castNode(AlterEnumStmt, parsetree), queryString); - } - - if (IsA(parsetree, AlterTableStmt)) - { - AlterTableStmt *alterTableStmt = (AlterTableStmt *) parsetree; - if (alterTableStmt->relkind == OBJECT_TABLE || - alterTableStmt->relkind == OBJECT_FOREIGN_TABLE || - alterTableStmt->relkind == OBJECT_INDEX) - { - ddlJobs = PlanAlterTableStmt(alterTableStmt, queryString); - } - - if (alterTableStmt->relkind == OBJECT_TYPE) - { - ddlJobs = PlanAlterTypeStmt(alterTableStmt, queryString); - } - } - - /* - * ALTER ... RENAME statements have their node type as RenameStmt. - * So intercept RenameStmt to tackle these commands. - */ - if (IsA(parsetree, RenameStmt)) - { - RenameStmt *renameStmt = (RenameStmt *) parsetree; - - switch (renameStmt->renameType) - { - case OBJECT_COLLATION: - { - ddlJobs = PlanRenameCollationStmt(renameStmt, queryString); - break; - } - - case OBJECT_TYPE: - { - ddlJobs = PlanRenameTypeStmt(renameStmt, queryString); - break; - } - - case OBJECT_ATTRIBUTE: - { - ddlJobs = PlanRenameAttributeStmt(renameStmt, queryString); - break; - } - - case OBJECT_PROCEDURE: - case OBJECT_AGGREGATE: - case OBJECT_FUNCTION: - { - ddlJobs = PlanRenameFunctionStmt(renameStmt, queryString); - break; - } - - default: - { - ddlJobs = PlanRenameStmt(renameStmt, queryString); - break; - } - } - } - - /* handle distributed CLUSTER statements */ - if (IsA(parsetree, ClusterStmt)) - { - ddlJobs = PlanClusterStmt((ClusterStmt *) parsetree, queryString); - } - - /* - * ALTER ... SET SCHEMA statements have their node type as AlterObjectSchemaStmt. - * So, we intercept AlterObjectSchemaStmt to tackle these commands. - */ - if (IsA(parsetree, AlterObjectSchemaStmt)) - { - ddlJobs = PlanAlterObjectSchemaStmt( - castNode(AlterObjectSchemaStmt, parsetree), queryString); - } - - if (IsA(parsetree, GrantStmt)) - { - ddlJobs = PlanGrantStmt((GrantStmt *) parsetree); - } - - if (IsA(parsetree, AlterOwnerStmt)) - { - ddlJobs = PlanAlterOwnerStmt(castNode(AlterOwnerStmt, parsetree), - queryString); - } - - if (IsA(parsetree, CreatePolicyStmt)) - { - ddlJobs = PlanCreatePolicyStmt((CreatePolicyStmt *) parsetree); - } - - if (IsA(parsetree, AlterPolicyStmt)) - { - ddlJobs = PlanAlterPolicyStmt((AlterPolicyStmt *) parsetree); - } - - if (IsA(parsetree, CompositeTypeStmt)) - { - ddlJobs = PlanCompositeTypeStmt(castNode(CompositeTypeStmt, parsetree), - queryString); - } - - if (IsA(parsetree, CreateEnumStmt)) - { - ddlJobs = PlanCreateEnumStmt(castNode(CreateEnumStmt, parsetree), - queryString); - } - - if (IsA(parsetree, AlterFunctionStmt)) - { - ddlJobs = PlanAlterFunctionStmt(castNode(AlterFunctionStmt, parsetree), - queryString); - } - - if (IsA(parsetree, CreateFunctionStmt)) - { - ddlJobs = PlanCreateFunctionStmt(castNode(CreateFunctionStmt, parsetree), - queryString); - } - - if (IsA(parsetree, AlterObjectDependsStmt)) - { - ddlJobs = PlanAlterObjectDependsStmt( - castNode(AlterObjectDependsStmt, parsetree), queryString); - } - - if (IsA(parsetree, AlterExtensionStmt)) - { - ddlJobs = PlanAlterExtensionUpdateStmt(castNode(AlterExtensionStmt, - parsetree), queryString); - } - - if (IsA(parsetree, AlterExtensionContentsStmt)) - { - ereport(NOTICE, (errmsg( - "Citus does not propagate adding/dropping member objects"), - errhint( - "You can add/drop the member objects on the workers as well."))); - } - - /* - * ALTER TABLE ALL IN TABLESPACE statements have their node type as - * AlterTableMoveAllStmt. At the moment we do not support this functionality in - * the distributed environment. We warn out here. - */ - if (IsA(parsetree, AlterTableMoveAllStmt)) - { - ereport(WARNING, (errmsg("not propagating ALTER TABLE ALL IN TABLESPACE " - "commands to worker nodes"), - errhint("Connect to worker nodes directly to manually " - "move all tables."))); + ddlJobs = ops->preprocess(parsetree, queryString); } } else @@ -635,9 +407,8 @@ multi_ProcessUtility(PlannedStmt *pstmt, * the validation step should be skipped on the distributed table. * Therefore, we check whether the given ALTER TABLE statement is a * FOREIGN KEY constraint and if so disable the validation step. - * Note that validation is done on the shard level when DDL - * propagation is enabled. Unlike the preceeding Plan* calls, the - * following eagerly executes some tasks on workers. + * Note validation is done on the shard level when DDL propagation + * is enabled. The following eagerly executes some tasks on workers. */ parsetree = WorkerProcessAlterTableStmt(alterTableStmt, queryString); } @@ -743,51 +514,17 @@ multi_ProcessUtility(PlannedStmt *pstmt, */ if (EnableDDLPropagation) { - if (IsA(parsetree, CompositeTypeStmt)) + if (ops && ops->postprocess) { - ProcessCompositeTypeStmt(castNode(CompositeTypeStmt, parsetree), queryString); - } + List *processJobs = ops->postprocess(parsetree, queryString); - if (IsA(parsetree, CreateEnumStmt)) - { - ProcessCreateEnumStmt(castNode(CreateEnumStmt, parsetree), queryString); - } - - if (IsA(parsetree, DefineStmt)) - { - DefineStmt *defineStmt = castNode(DefineStmt, parsetree); - - if (defineStmt->kind == OBJECT_COLLATION) + if (processJobs) { - ddlJobs = ProcessCollationDefineStmt(defineStmt, queryString); + Assert(ddlJobs == NIL); /* jobs should not have been set before */ + ddlJobs = processJobs; } } - if (IsA(parsetree, AlterObjectSchemaStmt)) - { - ProcessAlterObjectSchemaStmt(castNode(AlterObjectSchemaStmt, parsetree), - queryString); - } - - if (IsA(parsetree, AlterEnumStmt)) - { - ProcessAlterEnumStmt(castNode(AlterEnumStmt, parsetree), queryString); - } - - if (IsA(parsetree, CreateFunctionStmt)) - { - Assert(ddlJobs == NIL); /* jobs should not have been set before */ - ddlJobs = ProcessCreateFunctionStmt(castNode(CreateFunctionStmt, parsetree), - queryString); - } - - if (IsA(parsetree, AlterRoleStmt)) - { - Assert(ddlJobs == NIL); /* jobs should not have been set before */ - ddlJobs = ProcessAlterRoleStmt(castNode(AlterRoleStmt, parsetree), - queryString); - } - if (IsA(parsetree, AlterRoleSetStmt) && EnableAlterRolePropagation) { ereport(NOTICE, (errmsg("Citus partially supports ALTER ROLE for " @@ -822,7 +559,7 @@ multi_ProcessUtility(PlannedStmt *pstmt, { CreateStmt *createStatement = (CreateStmt *) parsetree; - ProcessCreateTableStmtPartitionOf(createStatement); + PostprocessCreateTableStmtPartitionOf(createStatement, queryString); } /* @@ -833,27 +570,7 @@ multi_ProcessUtility(PlannedStmt *pstmt, { AlterTableStmt *alterTableStatement = (AlterTableStmt *) parsetree; - ProcessAlterTableStmtAttachPartition(alterTableStatement); - } - - /* - * We call PlanCreateExtensionStmt and ProcessCreateExtensionStmt after standard_ProcessUtility - * does its work to learn the schema that the extension belongs to (if statement does not include - * WITH SCHEMA clause) - */ - if (EnableDDLPropagation && IsA(parsetree, CreateExtensionStmt)) - { - CreateExtensionStmt *createExtensionStmt = castNode(CreateExtensionStmt, - parsetree); - - ddlJobs = PlanCreateExtensionStmt(createExtensionStmt, queryString); - ProcessCreateExtensionStmt(createExtensionStmt, queryString); - } - - /* don't run post-process code for local commands */ - if (ddlJobs != NIL) - { - PostProcessUtility(parsetree); + PostprocessAlterTableStmtAttachPartition(alterTableStatement, queryString); } /* @@ -869,17 +586,14 @@ multi_ProcessUtility(PlannedStmt *pstmt, /* after local command has completed, finish by executing worker DDLJobs, if any */ if (ddlJobs != NIL) { - ListCell *ddlJobCell = NULL; - if (IsA(parsetree, AlterTableStmt)) { - PostProcessAlterTableStmt(castNode(AlterTableStmt, parsetree)); + PostprocessAlterTableStmt(castNode(AlterTableStmt, parsetree)); } - foreach(ddlJobCell, ddlJobs) + DDLJob *ddlJob = NULL; + foreach_ptr(ddlJob, ddlJobs) { - DDLJob *ddlJob = (DDLJob *) lfirst(ddlJobCell); - ExecuteDistributedDDLJob(ddlJob); } } @@ -889,7 +603,7 @@ multi_ProcessUtility(PlannedStmt *pstmt, { VacuumStmt *vacuumStmt = (VacuumStmt *) parsetree; - ProcessVacuumStmt(vacuumStmt, queryString); + PostprocessVacuumStmt(vacuumStmt, queryString); } /* @@ -918,94 +632,6 @@ IsDropSchemaOrDB(Node *parsetree) } -/* - * PlanRenameAttributeStmt called for RenameStmt's that are targetting an attribute eg. - * type attributes. Based on the relation type the attribute gets renamed it dispatches to - * a specialized implementation if present, otherwise return an empty list for its DDLJobs - */ -static List * -PlanRenameAttributeStmt(RenameStmt *stmt, const char *queryString) -{ - Assert(stmt->renameType == OBJECT_ATTRIBUTE); - - switch (stmt->relationType) - { - case OBJECT_TYPE: - { - return PlanRenameTypeAttributeStmt(stmt, queryString); - } - - default: - { - /* unsupported relation for attribute rename, do nothing */ - return NIL; - } - } -} - - -/* - * PlanAlterOwnerStmt gets called for statements that change the ownership of an object. - * Based on the type of object the ownership gets changed for it dispatches to a - * specialized implementation or returns an empty list of DDLJobs for objects that do not - * have an implementation provided. - */ -static List * -PlanAlterOwnerStmt(AlterOwnerStmt *stmt, const char *queryString) -{ - switch (stmt->objectType) - { - case OBJECT_COLLATION: - { - return PlanAlterCollationOwnerStmt(stmt, queryString); - } - - case OBJECT_TYPE: - { - return PlanAlterTypeOwnerStmt(stmt, queryString); - } - - case OBJECT_PROCEDURE: - case OBJECT_AGGREGATE: - case OBJECT_FUNCTION: - { - return PlanAlterFunctionOwnerStmt(stmt, queryString); - } - - default: - { - /* do nothing for unsupported alter owner statements */ - return NIL; - } - } -} - - -/* - * PlanAlterObjectDependsStmt gets called during the planning phase for - * ALTER ... DEPENDS ON EXTENSION ... statements. Based on the object type we call out to - * a specialized implementation. If no implementation is available we do nothing, eg. we - * allow the local node to execute. - */ -static List * -PlanAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, const char *queryString) -{ - switch (stmt->objectType) - { - case OBJECT_PROCEDURE: - case OBJECT_FUNCTION: - { - return PlanAlterFunctionDependsStmt(stmt, queryString); - } - - default: - { - return NIL; - } - } -} - - /* * ExecuteDistributedDDLJob simply executes a provided DDLJob in a distributed trans- * action, including metadata sync if needed. If the multi shard commit protocol is @@ -1174,20 +800,6 @@ CurrentSearchPath(void) } -/* - * PostProcessUtility performs additional tasks after a utility's local portion - * has been completed. - */ -static void -PostProcessUtility(Node *parsetree) -{ - if (IsA(parsetree, IndexStmt)) - { - PostProcessIndexStmt(castNode(IndexStmt, parsetree)); - } -} - - /* * MarkInvalidateForeignKeyGraph marks whether the foreign key graph should be * invalidated due to a DDL. diff --git a/src/backend/distributed/commands/vacuum.c b/src/backend/distributed/commands/vacuum.c index 031b9d566..c9ecc6e38 100644 --- a/src/backend/distributed/commands/vacuum.c +++ b/src/backend/distributed/commands/vacuum.c @@ -49,7 +49,7 @@ static List * ExtractVacuumTargetRels(VacuumStmt *vacuumStmt); static CitusVacuumParams VacuumStmtParams(VacuumStmt *vacstmt); /* - * ProcessVacuumStmt processes vacuum statements that may need propagation to + * PostprocessVacuumStmt processes vacuum statements that may need propagation to * distributed tables. If a VACUUM or ANALYZE command references a distributed * table, it is propagated to all involved nodes; otherwise, this function will * immediately exit after some error checking. @@ -59,7 +59,7 @@ static CitusVacuumParams VacuumStmtParams(VacuumStmt *vacstmt); * ANALYZE has already been processed. */ void -ProcessVacuumStmt(VacuumStmt *vacuumStmt, const char *vacuumCommand) +PostprocessVacuumStmt(VacuumStmt *vacuumStmt, const char *vacuumCommand) { int relationIndex = 0; List *vacuumRelationList = ExtractVacuumTargetRels(vacuumStmt); diff --git a/src/backend/distributed/commands/variableset.c b/src/backend/distributed/commands/variableset.c index b5767530b..b0fc125c9 100644 --- a/src/backend/distributed/commands/variableset.c +++ b/src/backend/distributed/commands/variableset.c @@ -110,12 +110,12 @@ IsSettingSafeToPropagate(char *name) /* - * ProcessVariableSetStmt actually does the work of propagating a provided SET stmt + * PostprocessVariableSetStmt actually does the work of propagating a provided SET stmt * to currently-participating worker nodes and adding the SET command test to a string * keeping track of all propagated SET commands since (sub-)xact start. */ void -ProcessVariableSetStmt(VariableSetStmt *setStmt, const char *setStmtString) +PostprocessVariableSetStmt(VariableSetStmt *setStmt, const char *setStmtString) { dlist_iter iter; const bool raiseInterrupts = true; diff --git a/src/backend/distributed/connection/connection_management.c b/src/backend/distributed/connection/connection_management.c index b4965047b..e0fca3533 100644 --- a/src/backend/distributed/connection/connection_management.c +++ b/src/backend/distributed/connection/connection_management.c @@ -197,8 +197,8 @@ StartNodeConnection(uint32 flags, const char *hostname, int32 port) * See StartNodeUserDatabaseConnection for details. */ MultiConnection * -GetNodeUserDatabaseConnection(uint32 flags, const char *hostname, int32 port, const - char *user, const char *database) +GetNodeUserDatabaseConnection(uint32 flags, const char *hostname, int32 port, + const char *user, const char *database) { MultiConnection *connection = StartNodeUserDatabaseConnection(flags, hostname, port, user, database); @@ -250,8 +250,8 @@ StartWorkerListConnections(List *workerNodeList, uint32 flags, const char *user, * that's not desired use the Get* variant. */ MultiConnection * -StartNodeUserDatabaseConnection(uint32 flags, const char *hostname, int32 port, const - char *user, const char *database) +StartNodeUserDatabaseConnection(uint32 flags, const char *hostname, int32 port, + const char *user, const char *database) { ConnectionHashKey key; MultiConnection *connection; diff --git a/src/backend/distributed/deparser/deparse.c b/src/backend/distributed/deparser/deparse.c index b87de69bb..cff1d0b16 100644 --- a/src/backend/distributed/deparser/deparse.c +++ b/src/backend/distributed/deparser/deparse.c @@ -15,344 +15,23 @@ #include "postgres.h" +#include "distributed/commands.h" #include "distributed/deparser.h" -static char * DeparseDropStmt(DropStmt *stmt); -static char * DeparseAlterTableStmt(AlterTableStmt *stmt); -static char * DeparseRenameStmt(RenameStmt *stmt); -static char * DeparseRenameAttributeStmt(RenameStmt *stmt); -static char * DeparseAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt); -static char * DeparseAlterOwnerStmt(AlterOwnerStmt *stmt); -static char * DeparseAlterObjectDependsStmt(AlterObjectDependsStmt *stmt); - /* * DeparseTreeNode aims to be the inverse of postgres' ParseTreeNode. Currently with * limited support. Check support before using, and add support for new statements as * required. - * - * Currently supported: - * - CREATE TYPE, ALTER TYPE, DROP TYPE - * - ALTER FUNCTION, ALTER PROCEDURE, ALTER AGGREGATE - * - DROP FUNCTION, DROP PROCEDURE, DROP AGGREGATE - * - CREATE EXTENSION, ALTER EXTENSION, DROP EXTENSION - * - ALTER COLLATION, DROP COLLATION */ char * DeparseTreeNode(Node *stmt) { - switch (nodeTag(stmt)) + const DistributeObjectOps *ops = GetDistributeObjectOps(stmt); + + if (!ops->deparse) { - case T_DropStmt: - { - return DeparseDropStmt(castNode(DropStmt, stmt)); - } - - case T_CompositeTypeStmt: - { - return DeparseCompositeTypeStmt(castNode(CompositeTypeStmt, stmt)); - } - - case T_CreateEnumStmt: - { - return DeparseCreateEnumStmt(castNode(CreateEnumStmt, stmt)); - } - - case T_AlterTableStmt: - { - return DeparseAlterTableStmt(castNode(AlterTableStmt, stmt)); - } - - case T_AlterEnumStmt: - { - return DeparseAlterEnumStmt(castNode(AlterEnumStmt, stmt)); - } - - case T_AlterFunctionStmt: - { - return DeparseAlterFunctionStmt(castNode(AlterFunctionStmt, stmt)); - } - - case T_RenameStmt: - { - return DeparseRenameStmt(castNode(RenameStmt, stmt)); - } - - case T_AlterObjectSchemaStmt: - { - return DeparseAlterObjectSchemaStmt(castNode(AlterObjectSchemaStmt, stmt)); - } - - case T_AlterOwnerStmt: - { - return DeparseAlterOwnerStmt(castNode(AlterOwnerStmt, stmt)); - } - - case T_AlterObjectDependsStmt: - { - return DeparseAlterObjectDependsStmt(castNode(AlterObjectDependsStmt, stmt)); - } - - case T_AlterRoleStmt: - { - return DeparseAlterRoleStmt(castNode(AlterRoleStmt, stmt)); - } - - case T_CreateExtensionStmt: - { - return DeparseCreateExtensionStmt(castNode(CreateExtensionStmt, stmt)); - } - - case T_AlterExtensionStmt: - { - return DeparseAlterExtensionStmt(castNode(AlterExtensionStmt, stmt)); - } - - default: - { - ereport(ERROR, (errmsg("unsupported statement for deparsing"))); - } - } -} - - -/* - * DeparseDropStmt aims to deparse DROP statements. - * - * Currently with limited support. Check support before using, and add support for new - * statements as required. - */ -static char * -DeparseDropStmt(DropStmt *stmt) -{ - switch (stmt->removeType) - { - case OBJECT_TYPE: - { - return DeparseDropTypeStmt(stmt); - } - - case OBJECT_COLLATION: - { - return DeparseDropCollationStmt(stmt); - } - - case OBJECT_PROCEDURE: - case OBJECT_AGGREGATE: - case OBJECT_FUNCTION: - { - return DeparseDropFunctionStmt(stmt); - } - - case OBJECT_EXTENSION: - { - return DeparseDropExtensionStmt(stmt); - } - - default: - { - ereport(ERROR, (errmsg("unsupported drop statement for deparsing"))); - } - } -} - - -/* - * DeparseAlterTableStmt deparses an AlterTableStmt to its SQL command. - * Contrary to its name these statements are covering not only ALTER TABLE ... - * statements but are used for almost all relation-esque objects in postgres, - * including but not limited to, Tables, Types, ... - * - * Currently with limited support. Check support before using, and add support for new - * statements as required. - */ -static char * -DeparseAlterTableStmt(AlterTableStmt *stmt) -{ - switch (stmt->relkind) - { - case OBJECT_TYPE: - { - return DeparseAlterTypeStmt(stmt); - } - - default: - { - ereport(ERROR, (errmsg("unsupported alter statement for deparsing"))); - } - } -} - - -/* - * DeparseRenameStmt deparses an RenameStmt to its SQL command. - * Contrary to its name these statements are not covering all ALTER .. RENAME - * statements. - * - * e.g. ALTER TYPE name RENAME VALUE old TO new is an AlterEnumStmt - * - * Currently with limited support. Check support before using, and add support for new - * statements as required. - */ -static char * -DeparseRenameStmt(RenameStmt *stmt) -{ - switch (stmt->renameType) - { - case OBJECT_TYPE: - { - return DeparseRenameTypeStmt(stmt); - } - - case OBJECT_ATTRIBUTE: - { - return DeparseRenameAttributeStmt(stmt); - } - - case OBJECT_COLLATION: - { - return DeparseRenameCollationStmt(stmt); - } - - case OBJECT_PROCEDURE: - case OBJECT_AGGREGATE: - case OBJECT_FUNCTION: - { - return DeparseRenameFunctionStmt(stmt); - } - - default: - { - ereport(ERROR, (errmsg("unsupported rename statement for deparsing"))); - } - } -} - - -static char * -DeparseRenameAttributeStmt(RenameStmt *stmt) -{ - Assert(stmt->renameType == OBJECT_ATTRIBUTE); - - switch (stmt->relationType) - { - case OBJECT_TYPE: - { - return DeparseRenameTypeAttributeStmt(stmt); - } - - default: - { - ereport(ERROR, (errmsg("unsupported rename attribute statement for" - " deparsing"))); - } - } -} - - -/* - * DeparseAlterObjectSchemaStmt aims to deparse - * ALTER .. SET SCHEMA .. - * statements. - * - * Currently with limited support. Check support before using, and add support for new - * statements as required. - */ -static char * -DeparseAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt) -{ - switch (stmt->objectType) - { - case OBJECT_TYPE: - { - return DeparseAlterTypeSchemaStmt(stmt); - } - - case OBJECT_COLLATION: - { - return DeparseAlterCollationSchemaStmt(stmt); - } - - case OBJECT_PROCEDURE: - case OBJECT_AGGREGATE: - case OBJECT_FUNCTION: - { - return DeparseAlterFunctionSchemaStmt(stmt); - } - - case OBJECT_EXTENSION: - { - return DeparseAlterExtensionSchemaStmt(stmt); - } - - default: - { - ereport(ERROR, (errmsg("unsupported rename statement for deparsing"))); - } - } -} - - -/* - * DeparseAlterOwnerStmt aims to deparse - * ALTER .. OWNER TO .. - * statements. - * - * Currently with limited support. Check support before using, and add support for new - * statements as required. - */ -static char * -DeparseAlterOwnerStmt(AlterOwnerStmt *stmt) -{ - switch (stmt->objectType) - { - case OBJECT_TYPE: - { - return DeparseAlterTypeOwnerStmt(stmt); - } - - case OBJECT_COLLATION: - { - return DeparseAlterCollationOwnerStmt(stmt); - } - - case OBJECT_PROCEDURE: - case OBJECT_AGGREGATE: - case OBJECT_FUNCTION: - { - return DeparseAlterFunctionOwnerStmt(stmt); - } - - default: - { - ereport(ERROR, (errmsg("unsupported alter owner statement for deparsing"))); - } - } -} - - -/* - * DeparseAlterObjectDependsStmt aims to deparse - * ALTER .. DEPENDS ON EXTENSION .. - * statements. - * - * Currently with limited support. Check support before using, and add support for new - * statements as required. - */ -static char * -DeparseAlterObjectDependsStmt(AlterObjectDependsStmt *stmt) -{ - switch (stmt->objectType) - { - case OBJECT_PROCEDURE: - case OBJECT_AGGREGATE: - case OBJECT_FUNCTION: - { - return DeparseAlterFunctionDependsStmt(stmt); - } - - default: - { - ereport(ERROR, (errmsg("unsupported alter depends statement for deparsing"))); - } + ereport(ERROR, (errmsg("unsupported statement for deparsing"))); } + + return ops->deparse(stmt); } diff --git a/src/backend/distributed/deparser/deparse_attribute_stmts.c b/src/backend/distributed/deparser/deparse_attribute_stmts.c new file mode 100644 index 000000000..4b79450d2 --- /dev/null +++ b/src/backend/distributed/deparser/deparse_attribute_stmts.c @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * deparse_attribute_stmts.c + * All routines to deparse attribute statements. + * + * Copyright (c) Citus Data, Inc. + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "distributed/deparser.h" + +char * +DeparseRenameAttributeStmt(Node *node) +{ + RenameStmt *stmt = castNode(RenameStmt, node); + Assert(stmt->renameType == OBJECT_ATTRIBUTE); + + switch (stmt->relationType) + { + case OBJECT_TYPE: + { + return DeparseRenameTypeAttributeStmt(node); + } + + default: + { + ereport(ERROR, (errmsg("unsupported rename attribute statement for" + " deparsing"))); + } + } +} diff --git a/src/backend/distributed/deparser/deparse_collation_stmts.c b/src/backend/distributed/deparser/deparse_collation_stmts.c index 35578de12..44f7f9098 100644 --- a/src/backend/distributed/deparser/deparse_collation_stmts.c +++ b/src/backend/distributed/deparser/deparse_collation_stmts.c @@ -31,8 +31,9 @@ static void AppendNameList(StringInfo buf, List *objects); * DeparseDropCollationStmt builds and returns a string representing the DropStmt */ char * -DeparseDropCollationStmt(DropStmt *stmt) +DeparseDropCollationStmt(Node *node) { + DropStmt *stmt = castNode(DropStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); @@ -67,8 +68,9 @@ AppendDropCollationStmt(StringInfo buf, DropStmt *stmt) * DeparseRenameCollationStmt builds and returns a string representing the RenameStmt */ char * -DeparseRenameCollationStmt(RenameStmt *stmt) +DeparseRenameCollationStmt(Node *node) { + RenameStmt *stmt = castNode(RenameStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); @@ -88,8 +90,8 @@ AppendRenameCollationStmt(StringInfo buf, RenameStmt *stmt) { List *names = (List *) stmt->object; - appendStringInfo(buf, "ALTER COLLATION %s RENAME TO %s;", NameListToQuotedString( - names), + appendStringInfo(buf, "ALTER COLLATION %s RENAME TO %s;", + NameListToQuotedString(names), quote_identifier(stmt->newname)); } @@ -98,8 +100,9 @@ AppendRenameCollationStmt(StringInfo buf, RenameStmt *stmt) * DeparseAlterCollationSchemaStmt builds and returns a string representing the AlterObjectSchemaStmt */ char * -DeparseAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt) +DeparseAlterCollationSchemaStmt(Node *node) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); @@ -130,8 +133,9 @@ AppendAlterCollationSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt) * DeparseAlterCollationOwnerStmt builds and returns a string representing the AlterOwnerStmt */ char * -DeparseAlterCollationOwnerStmt(AlterOwnerStmt *stmt) +DeparseAlterCollationOwnerStmt(Node *node) { + AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); diff --git a/src/backend/distributed/deparser/deparse_extension_stmts.c b/src/backend/distributed/deparser/deparse_extension_stmts.c index c25b6395e..7b393c90e 100644 --- a/src/backend/distributed/deparser/deparse_extension_stmts.c +++ b/src/backend/distributed/deparser/deparse_extension_stmts.c @@ -68,12 +68,13 @@ GetExtensionOption(List *extensionOptions, const char *defname) * CreateExtensionStmt to be sent to worker nodes. */ char * -DeparseCreateExtensionStmt(CreateExtensionStmt *createExtensionStmt) +DeparseCreateExtensionStmt(Node *node) { + CreateExtensionStmt *stmt = castNode(CreateExtensionStmt, node); StringInfoData sql = { 0 }; initStringInfo(&sql); - AppendCreateExtensionStmt(&sql, createExtensionStmt); + AppendCreateExtensionStmt(&sql, stmt); return sql.data; } @@ -141,12 +142,13 @@ AppendCreateExtensionStmt(StringInfo buf, CreateExtensionStmt *createExtensionSt * AlterExtensionStmt to be sent to worker nodes. */ char * -DeparseAlterExtensionStmt(AlterExtensionStmt *alterExtensionStmt) +DeparseAlterExtensionStmt(Node *node) { + AlterExtensionStmt *stmt = castNode(AlterExtensionStmt, node); StringInfoData sql = { 0 }; initStringInfo(&sql); - AppendAlterExtensionStmt(&sql, alterExtensionStmt); + AppendAlterExtensionStmt(&sql, stmt); return sql.data; } @@ -184,12 +186,13 @@ AppendAlterExtensionStmt(StringInfo buf, AlterExtensionStmt *alterExtensionStmt) * DeparseDropExtensionStmt builds and returns a string representing the DropStmt */ char * -DeparseDropExtensionStmt(DropStmt *dropStmt) +DeparseDropExtensionStmt(Node *node) { + DropStmt *stmt = castNode(DropStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); - AppendDropExtensionStmt(&str, dropStmt); + AppendDropExtensionStmt(&str, stmt); return str.data; } @@ -252,14 +255,15 @@ AppendExtensionNameList(StringInfo str, List *objects) * AlterObjectSchemaStmt (ALTER EXTENSION SET SCHEMA). */ char * -DeparseAlterExtensionSchemaStmt(AlterObjectSchemaStmt *alterExtensionSchemaStmt) +DeparseAlterExtensionSchemaStmt(Node *node) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); - Assert(alterExtensionSchemaStmt->objectType == OBJECT_EXTENSION); + Assert(stmt->objectType == OBJECT_EXTENSION); - AppendAlterExtensionSchemaStmt(&str, alterExtensionSchemaStmt); + AppendAlterExtensionSchemaStmt(&str, stmt); return str.data; } diff --git a/src/backend/distributed/deparser/deparse_function_stmts.c b/src/backend/distributed/deparser/deparse_function_stmts.c index fd547d14e..95f23b949 100644 --- a/src/backend/distributed/deparser/deparse_function_stmts.c +++ b/src/backend/distributed/deparser/deparse_function_stmts.c @@ -71,8 +71,9 @@ static char * CopyAndConvertToUpperCase(const char *str); * DeparseAlterFunctionStmt builds and returns a string representing the AlterFunctionStmt */ char * -DeparseAlterFunctionStmt(AlterFunctionStmt *stmt) +DeparseAlterFunctionStmt(Node *node) { + AlterFunctionStmt *stmt = castNode(AlterFunctionStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); @@ -427,8 +428,9 @@ AppendVarSetValue(StringInfo buf, VariableSetStmt *setStmt) * DeparseRenameFunctionStmt builds and returns a string representing the RenameStmt */ char * -DeparseRenameFunctionStmt(RenameStmt *stmt) +DeparseRenameFunctionStmt(Node *node) { + RenameStmt *stmt = castNode(RenameStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); @@ -458,8 +460,9 @@ AppendRenameFunctionStmt(StringInfo buf, RenameStmt *stmt) * DeparseAlterFunctionSchemaStmt builds and returns a string representing the AlterObjectSchemaStmt */ char * -DeparseAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt) +DeparseAlterFunctionSchemaStmt(Node *node) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); @@ -489,8 +492,9 @@ AppendAlterFunctionSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt) * DeparseAlterFunctionOwnerStmt builds and returns a string representing the AlterOwnerStmt */ char * -DeparseAlterFunctionOwnerStmt(AlterOwnerStmt *stmt) +DeparseAlterFunctionOwnerStmt(Node *node) { + AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); @@ -520,8 +524,9 @@ AppendAlterFunctionOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt) * DeparseAlterFunctionDependsStmt builds and returns a string representing the AlterObjectDependsStmt */ char * -DeparseAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt) +DeparseAlterFunctionDependsStmt(Node *node) { + AlterObjectDependsStmt *stmt = castNode(AlterObjectDependsStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); @@ -551,8 +556,9 @@ AppendAlterFunctionDependsStmt(StringInfo buf, AlterObjectDependsStmt *stmt) * DeparseDropFunctionStmt builds and returns a string representing the DropStmt */ char * -DeparseDropFunctionStmt(DropStmt *stmt) +DeparseDropFunctionStmt(Node *node) { + DropStmt *stmt = castNode(DropStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); diff --git a/src/backend/distributed/deparser/deparse_role_stmts.c b/src/backend/distributed/deparser/deparse_role_stmts.c index 30bb131e1..c63c57fd3 100644 --- a/src/backend/distributed/deparser/deparse_role_stmts.c +++ b/src/backend/distributed/deparser/deparse_role_stmts.c @@ -27,8 +27,9 @@ static void AppendAlterRoleStmt(StringInfo buf, AlterRoleStmt *stmt); * AlterRoleStmt for application on a remote server. */ char * -DeparseAlterRoleStmt(AlterRoleStmt *stmt) +DeparseAlterRoleStmt(Node *node) { + AlterRoleStmt *stmt = castNode(AlterRoleStmt, node); StringInfoData buf = { 0 }; initStringInfo(&buf); diff --git a/src/backend/distributed/deparser/deparse_type_stmts.c b/src/backend/distributed/deparser/deparse_type_stmts.c index 47bd75470..16a69f147 100644 --- a/src/backend/distributed/deparser/deparse_type_stmts.c +++ b/src/backend/distributed/deparser/deparse_type_stmts.c @@ -62,8 +62,9 @@ static void AppendAlterTypeOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt); * CompositeTypeStmt for application on a remote server. */ char * -DeparseCompositeTypeStmt(CompositeTypeStmt *stmt) +DeparseCompositeTypeStmt(Node *node) { + CompositeTypeStmt *stmt = castNode(CompositeTypeStmt, node); StringInfoData sql = { 0 }; initStringInfo(&sql); @@ -74,8 +75,9 @@ DeparseCompositeTypeStmt(CompositeTypeStmt *stmt) char * -DeparseCreateEnumStmt(CreateEnumStmt *stmt) +DeparseCreateEnumStmt(Node *node) { + CreateEnumStmt *stmt = castNode(CreateEnumStmt, node); StringInfoData sql = { 0 }; initStringInfo(&sql); @@ -86,8 +88,9 @@ DeparseCreateEnumStmt(CreateEnumStmt *stmt) char * -DeparseAlterEnumStmt(AlterEnumStmt *stmt) +DeparseAlterEnumStmt(Node *node) { + AlterEnumStmt *stmt = castNode(AlterEnumStmt, node); StringInfoData sql = { 0 }; initStringInfo(&sql); @@ -98,8 +101,9 @@ DeparseAlterEnumStmt(AlterEnumStmt *stmt) char * -DeparseDropTypeStmt(DropStmt *stmt) +DeparseDropTypeStmt(Node *node) { + DropStmt *stmt = castNode(DropStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); @@ -112,8 +116,9 @@ DeparseDropTypeStmt(DropStmt *stmt) char * -DeparseAlterTypeStmt(AlterTableStmt *stmt) +DeparseAlterTypeStmt(Node *node) { + AlterTableStmt *stmt = castNode(AlterTableStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); @@ -395,8 +400,9 @@ AppendColumnDef(StringInfo str, ColumnDef *columnDef) char * -DeparseRenameTypeStmt(RenameStmt *stmt) +DeparseRenameTypeStmt(Node *node) { + RenameStmt *stmt = castNode(RenameStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); @@ -419,8 +425,9 @@ AppendRenameTypeStmt(StringInfo buf, RenameStmt *stmt) char * -DeparseRenameTypeAttributeStmt(RenameStmt *stmt) +DeparseRenameTypeAttributeStmt(Node *node) { + RenameStmt *stmt = castNode(RenameStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); @@ -452,8 +459,9 @@ AppendRenameTypeAttributeStmt(StringInfo buf, RenameStmt *stmt) char * -DeparseAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt) +DeparseAlterTypeSchemaStmt(Node *node) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); @@ -477,8 +485,9 @@ AppendAlterTypeSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt) char * -DeparseAlterTypeOwnerStmt(AlterOwnerStmt *stmt) +DeparseAlterTypeOwnerStmt(Node *node) { + AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); StringInfoData str = { 0 }; initStringInfo(&str); diff --git a/src/backend/distributed/deparser/objectaddress.c b/src/backend/distributed/deparser/objectaddress.c index 88c8b2c9e..a1ef82b0b 100644 --- a/src/backend/distributed/deparser/objectaddress.c +++ b/src/backend/distributed/deparser/objectaddress.c @@ -18,241 +18,36 @@ #include "catalog/objectaddress.h" #include "catalog/pg_extension_d.h" -static ObjectAddress * AlterTableStmtObjectAddress(AlterTableStmt *stmt, bool missing_ok); -static ObjectAddress * RenameStmtObjectAddress(RenameStmt *stmt, bool missing_ok); -static ObjectAddress * AlterObjectSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, - bool missing_ok); -static ObjectAddress * RenameAttributeStmtObjectAddress(RenameStmt *stmt, bool - missing_ok); -static ObjectAddress * AlterOwnerStmtObjectAddress(AlterOwnerStmt *stmt, bool missing_ok); -static ObjectAddress * AlterObjectDependsStmtObjectAddress(AlterObjectDependsStmt *stmt, - bool missing_ok); -static ObjectAddress * CreateExtensionStmtObjectAddress(CreateExtensionStmt *stmt, bool - missing_ok); -static ObjectAddress * AlterExtensionStmtObjectAddress( - AlterExtensionStmt *alterExtensionStmt, bool missing_ok); /* * GetObjectAddressFromParseTree returns the ObjectAddress of the main target of the parse * tree. */ -ObjectAddress * +ObjectAddress GetObjectAddressFromParseTree(Node *parseTree, bool missing_ok) { - switch (parseTree->type) + const DistributeObjectOps *ops = GetDistributeObjectOps(parseTree); + + if (!ops->address) { - case T_CompositeTypeStmt: - { - return CompositeTypeStmtObjectAddress(castNode(CompositeTypeStmt, parseTree), - missing_ok); - } - - case T_AlterTableStmt: - { - return AlterTableStmtObjectAddress(castNode(AlterTableStmt, parseTree), - missing_ok); - } - - case T_CreateEnumStmt: - { - return CreateEnumStmtObjectAddress(castNode(CreateEnumStmt, parseTree), - missing_ok); - } - - case T_AlterEnumStmt: - { - return AlterEnumStmtObjectAddress(castNode(AlterEnumStmt, parseTree), - missing_ok); - } - - case T_RenameStmt: - { - return RenameStmtObjectAddress(castNode(RenameStmt, parseTree), missing_ok); - } - - case T_AlterObjectSchemaStmt: - { - return AlterObjectSchemaStmtObjectAddress(castNode(AlterObjectSchemaStmt, - parseTree), missing_ok); - } - - case T_AlterOwnerStmt: - { - return AlterOwnerStmtObjectAddress(castNode(AlterOwnerStmt, parseTree), - missing_ok); - } - - case T_AlterFunctionStmt: - { - return AlterFunctionStmtObjectAddress(castNode(AlterFunctionStmt, parseTree), - missing_ok); - } - - case T_CreateFunctionStmt: - { - return CreateFunctionStmtObjectAddress( - castNode(CreateFunctionStmt, parseTree), missing_ok); - } - - case T_AlterObjectDependsStmt: - { - return AlterObjectDependsStmtObjectAddress( - castNode(AlterObjectDependsStmt, parseTree), missing_ok); - } - - case T_DefineStmt: - { - DefineStmt *stmt = castNode(DefineStmt, parseTree); - - switch (stmt->kind) - { - case OBJECT_AGGREGATE: - { - return DefineAggregateStmtObjectAddress(stmt, missing_ok); - } - - case OBJECT_COLLATION: - { - return DefineCollationStmtObjectAddress(stmt, missing_ok); - } - - default: - { - break; - } - } - - ereport(ERROR, (errmsg( - "unsupported object type to get object address for DefineStmt"))); - return NULL; - } - - case T_CreateExtensionStmt: - { - return CreateExtensionStmtObjectAddress(castNode(CreateExtensionStmt, - parseTree), missing_ok); - } - - case T_AlterExtensionStmt: - { - return AlterExtensionStmtObjectAddress(castNode(AlterExtensionStmt, - parseTree), missing_ok); - } - - default: - { - /* - * should not be reached, indicates the coordinator is sending unsupported - * statements - */ - ereport(ERROR, (errmsg("unsupported statement to get object address for"))); - return NULL; - } + ereport(ERROR, (errmsg("unsupported statement to get object address for"))); } + + return ops->address(parseTree, missing_ok); } -static ObjectAddress * -AlterTableStmtObjectAddress(AlterTableStmt *stmt, bool missing_ok) -{ - switch (stmt->relkind) - { - case OBJECT_TYPE: - { - return AlterTypeStmtObjectAddress(stmt, missing_ok); - } - - default: - { - ereport(ERROR, (errmsg("unsupported alter statement to get object address for" - ))); - } - } -} - - -static ObjectAddress * -RenameStmtObjectAddress(RenameStmt *stmt, bool missing_ok) -{ - switch (stmt->renameType) - { - case OBJECT_TYPE: - { - return RenameTypeStmtObjectAddress(stmt, missing_ok); - } - - case OBJECT_ATTRIBUTE: - { - return RenameAttributeStmtObjectAddress(stmt, missing_ok); - } - - case OBJECT_COLLATION: - { - return RenameCollationStmtObjectAddress(stmt, missing_ok); - } - - case OBJECT_PROCEDURE: - case OBJECT_AGGREGATE: - case OBJECT_FUNCTION: - { - return RenameFunctionStmtObjectAddress(stmt, missing_ok); - } - - default: - { - ereport(ERROR, (errmsg("unsupported rename statement to get object address " - "for"))); - } - } -} - - -static ObjectAddress * -AlterObjectSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, bool missing_ok) -{ - switch (stmt->objectType) - { - case OBJECT_TYPE: - { - return AlterTypeSchemaStmtObjectAddress(stmt, missing_ok); - } - - case OBJECT_COLLATION: - { - return AlterCollationSchemaStmtObjectAddress(stmt, missing_ok); - } - - case OBJECT_PROCEDURE: - case OBJECT_AGGREGATE: - case OBJECT_FUNCTION: - { - return AlterFunctionSchemaStmtObjectAddress(stmt, missing_ok); - } - - case OBJECT_EXTENSION: - { - return AlterExtensionSchemaStmtObjectAddress(stmt, missing_ok); - } - - default: - { - ereport(ERROR, (errmsg("unsupported alter schema statement to get object " - "address for"))); - } - } -} - - -static ObjectAddress * -RenameAttributeStmtObjectAddress(RenameStmt *stmt, bool missing_ok) +ObjectAddress +RenameAttributeStmtObjectAddress(Node *node, bool missing_ok) { + RenameStmt *stmt = castNode(RenameStmt, node); Assert(stmt->renameType == OBJECT_ATTRIBUTE); switch (stmt->relationType) { case OBJECT_TYPE: { - return RenameTypeAttributeStmtObjectAddress(stmt, missing_ok); + return RenameTypeAttributeStmtObjectAddress(node, missing_ok); } default: @@ -264,69 +59,6 @@ RenameAttributeStmtObjectAddress(RenameStmt *stmt, bool missing_ok) } -static ObjectAddress * -AlterOwnerStmtObjectAddress(AlterOwnerStmt *stmt, bool missing_ok) -{ - switch (stmt->objectType) - { - case OBJECT_COLLATION: - { - ObjectAddress *address = palloc(sizeof(ObjectAddress)); - *address = AlterCollationOwnerObjectAddress(stmt); - return address; - } - - case OBJECT_TYPE: - { - return AlterTypeOwnerObjectAddress(stmt, missing_ok); - } - - case OBJECT_PROCEDURE: - case OBJECT_AGGREGATE: - case OBJECT_FUNCTION: - { - return AlterFunctionOwnerObjectAddress(stmt, missing_ok); - } - - default: - { - ereport(ERROR, (errmsg("unsupported alter owner statement to get object " - "address for"))); - } - } -} - - -/* - * AlterObjectDependsStmtObjectAddress resolves the ObjectAddress for the object targeted - * by the AlterObjectDependStmt. This is done by dispatching the call to the object - * specific implementation based on the ObjectType captured in the original statement. If - * a specific implementation is not present an error will be raised. This is a developer - * error since this function should only be reachable by calls of supported types. - * - * If missing_ok is set to fails the object specific implementation is supposed to raise - * an error explaining the user the object is not existing. - */ -static ObjectAddress * -AlterObjectDependsStmtObjectAddress(AlterObjectDependsStmt *stmt, bool missing_ok) -{ - switch (stmt->objectType) - { - case OBJECT_PROCEDURE: - case OBJECT_FUNCTION: - { - return AlterFunctionDependsStmtObjectAddress(stmt, missing_ok); - } - - default: - { - ereport(ERROR, (errmsg("unsupported alter depends on extension statement to " - "get object address for"))); - } - } -} - - /* * CreateExtensionStmtObjectAddress finds the ObjectAddress for the extension described * by the CreateExtensionStmt. If missing_ok is false, then this function throws an @@ -335,13 +67,13 @@ AlterObjectDependsStmtObjectAddress(AlterObjectDependsStmt *stmt, bool missing_o * Never returns NULL, but the objid in the address could be invalid if missing_ok was set * to true. */ -static ObjectAddress * -CreateExtensionStmtObjectAddress(CreateExtensionStmt *createExtensionStmt, bool - missing_ok) +ObjectAddress +CreateExtensionStmtObjectAddress(Node *node, bool missing_ok) { - ObjectAddress *address = palloc0(sizeof(ObjectAddress)); + CreateExtensionStmt *stmt = castNode(CreateExtensionStmt, node); + ObjectAddress address = { 0 }; - const char *extensionName = createExtensionStmt->extname; + const char *extensionName = stmt->extname; Oid extensionoid = get_extension_oid(extensionName, missing_ok); @@ -353,7 +85,7 @@ CreateExtensionStmtObjectAddress(CreateExtensionStmt *createExtensionStmt, bool extensionName))); } - ObjectAddressSet(*address, ExtensionRelationId, extensionoid); + ObjectAddressSet(address, ExtensionRelationId, extensionoid); return address; } @@ -367,13 +99,13 @@ CreateExtensionStmtObjectAddress(CreateExtensionStmt *createExtensionStmt, bool * Never returns NULL, but the objid in the address could be invalid if missing_ok was set * to true. */ -static ObjectAddress * -AlterExtensionStmtObjectAddress(AlterExtensionStmt *alterExtensionStmt, bool - missing_ok) +ObjectAddress +AlterExtensionStmtObjectAddress(Node *node, bool missing_ok) { - ObjectAddress *address = palloc0(sizeof(ObjectAddress)); + AlterExtensionStmt *stmt = castNode(AlterExtensionStmt, node); + ObjectAddress address = { 0 }; - const char *extensionName = alterExtensionStmt->extname; + const char *extensionName = stmt->extname; Oid extensionoid = get_extension_oid(extensionName, missing_ok); @@ -385,7 +117,7 @@ AlterExtensionStmtObjectAddress(AlterExtensionStmt *alterExtensionStmt, bool extensionName))); } - ObjectAddressSet(*address, ExtensionRelationId, extensionoid); + ObjectAddressSet(address, ExtensionRelationId, extensionoid); return address; } diff --git a/src/backend/distributed/deparser/qualify.c b/src/backend/distributed/deparser/qualify.c index e6f25677d..262a6a50a 100644 --- a/src/backend/distributed/deparser/qualify.c +++ b/src/backend/distributed/deparser/qualify.c @@ -21,17 +21,10 @@ #include "postgres.h" +#include "distributed/commands.h" #include "distributed/deparser.h" -static void QualifyRenameStmt(RenameStmt *stmt); -static void QualifyRenameAttributeStmt(RenameStmt *stmt); -static void QualifyAlterTableStmt(AlterTableStmt *stmt); -static void QualifyAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt); -static void QualifyAlterOwnerStmt(AlterOwnerStmt *stmt); -static void QualifyAlterObjectDependsStmt(AlterObjectDependsStmt *stmt); -static void QualifyDropObjectStmt(DropStmt *stmt); - /* * QualifyTreeNode transforms the statement in place and makes all (supported) statements * fully qualified. Fully qualified statements allow for application on a remote postgres @@ -40,117 +33,11 @@ static void QualifyDropObjectStmt(DropStmt *stmt); void QualifyTreeNode(Node *stmt) { - switch (nodeTag(stmt)) + const DistributeObjectOps *ops = GetDistributeObjectOps(stmt); + + if (ops && ops->qualify) { - case T_RenameStmt: - { - QualifyRenameStmt(castNode(RenameStmt, stmt)); - return; - } - - case T_AlterEnumStmt: - { - QualifyAlterEnumStmt(castNode(AlterEnumStmt, stmt)); - return; - } - - case T_AlterTableStmt: - { - QualifyAlterTableStmt(castNode(AlterTableStmt, stmt)); - return; - } - - case T_CompositeTypeStmt: - { - QualifyCompositeTypeStmt(castNode(CompositeTypeStmt, stmt)); - return; - } - - case T_CreateEnumStmt: - { - QualifyCreateEnumStmt(castNode(CreateEnumStmt, stmt)); - return; - } - - case T_AlterObjectSchemaStmt: - { - QualifyAlterObjectSchemaStmt(castNode(AlterObjectSchemaStmt, stmt)); - return; - } - - case T_AlterOwnerStmt: - { - QualifyAlterOwnerStmt(castNode(AlterOwnerStmt, stmt)); - return; - } - - case T_AlterFunctionStmt: - { - QualifyAlterFunctionStmt(castNode(AlterFunctionStmt, stmt)); - return; - } - - case T_AlterObjectDependsStmt: - { - QualifyAlterObjectDependsStmt(castNode(AlterObjectDependsStmt, stmt)); - return; - } - - case T_DropStmt: - { - QualifyDropObjectStmt(castNode(DropStmt, stmt)); - break; - } - - default: - { - /* skip unsupported statements */ - break; - } - } -} - - -/* - * QualifyRenameStmt transforms a RENAME statement in place and makes all (supported) - * statements fully qualified. - */ -static void -QualifyRenameStmt(RenameStmt *stmt) -{ - switch (stmt->renameType) - { - case OBJECT_TYPE: - { - QualifyRenameTypeStmt(stmt); - return; - } - - case OBJECT_ATTRIBUTE: - { - QualifyRenameAttributeStmt(stmt); - return; - } - - case OBJECT_COLLATION: - { - QualifyRenameCollationStmt(stmt); - return; - } - - case OBJECT_AGGREGATE: - case OBJECT_FUNCTION: - case OBJECT_PROCEDURE: - { - QualifyRenameFunctionStmt(stmt); - return; - } - - default: - { - /* skip unsupported statements */ - break; - } + ops->qualify(stmt); } } @@ -159,142 +46,17 @@ QualifyRenameStmt(RenameStmt *stmt) * QualifyRenameAttributeStmt transforms a RENAME ATTRIBUTE statement in place and makes all (supported) * statements fully qualified. */ -static void -QualifyRenameAttributeStmt(RenameStmt *stmt) +void +QualifyRenameAttributeStmt(Node *node) { + RenameStmt *stmt = castNode(RenameStmt, node); Assert(stmt->renameType == OBJECT_ATTRIBUTE); switch (stmt->relationType) { case OBJECT_TYPE: { - QualifyRenameTypeAttributeStmt(stmt); - return; - } - - default: - { - return; - } - } -} - - -static void -QualifyAlterTableStmt(AlterTableStmt *stmt) -{ - switch (stmt->relkind) - { - case OBJECT_TYPE: - { - QualifyAlterTypeStmt(stmt); - return; - } - - default: - { - /* skip unsupported statements */ - break; - } - } -} - - -static void -QualifyAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt) -{ - switch (stmt->objectType) - { - case OBJECT_TYPE: - { - QualifyAlterTypeSchemaStmt(stmt); - return; - } - - case OBJECT_COLLATION: - { - QualifyAlterCollationSchemaStmt(stmt); - return; - } - - case OBJECT_AGGREGATE: - case OBJECT_FUNCTION: - case OBJECT_PROCEDURE: - { - QualifyAlterFunctionSchemaStmt(stmt); - return; - } - - default: - { - /* skip unsupported statements */ - break; - } - } -} - - -static void -QualifyAlterOwnerStmt(AlterOwnerStmt *stmt) -{ - switch (stmt->objectType) - { - case OBJECT_TYPE: - { - QualifyAlterTypeOwnerStmt(stmt); - return; - } - - case OBJECT_COLLATION: - { - QualifyAlterCollationOwnerStmt(stmt); - return; - } - - case OBJECT_AGGREGATE: - case OBJECT_FUNCTION: - case OBJECT_PROCEDURE: - { - QualifyAlterFunctionOwnerStmt(stmt); - return; - } - - default: - { - return; - } - } -} - - -static void -QualifyAlterObjectDependsStmt(AlterObjectDependsStmt *stmt) -{ - switch (stmt->objectType) - { - case OBJECT_FUNCTION: - case OBJECT_PROCEDURE: - { - QualifyAlterFunctionDependsStmt(stmt); - return; - } - - default: - { - return; - } - } -} - - -static void -QualifyDropObjectStmt(DropStmt *stmt) -{ - switch (stmt->removeType) - { - case OBJECT_COLLATION: - { - QualifyDropCollationStmt(stmt); + QualifyRenameTypeAttributeStmt(node); return; } diff --git a/src/backend/distributed/deparser/qualify_collation_stmt.c b/src/backend/distributed/deparser/qualify_collation_stmt.c index 84785aa11..e1fcc2b50 100644 --- a/src/backend/distributed/deparser/qualify_collation_stmt.c +++ b/src/backend/distributed/deparser/qualify_collation_stmt.c @@ -32,8 +32,9 @@ static Node * QualifyCollationName(List *func); * statement in place and makes the collation name fully qualified. */ void -QualifyRenameCollationStmt(RenameStmt *stmt) +QualifyRenameCollationStmt(Node *node) { + RenameStmt *stmt = castNode(RenameStmt, node); Assert(stmt->renameType == OBJECT_COLLATION); stmt->object = QualifyCollationName(castNode(List, stmt->object)); @@ -46,8 +47,9 @@ QualifyRenameCollationStmt(RenameStmt *stmt) * statement in place and makes the collation name fully qualified. */ void -QualifyAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt) +QualifyAlterCollationSchemaStmt(Node *node) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); Assert(stmt->objectType == OBJECT_COLLATION); stmt->object = QualifyCollationName(castNode(List, stmt->object)); @@ -60,8 +62,9 @@ QualifyAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt) * statement in place and makes the collation name fully qualified. */ void -QualifyAlterCollationOwnerStmt(AlterOwnerStmt *stmt) +QualifyAlterCollationOwnerStmt(Node *node) { + AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); Assert(stmt->objectType == OBJECT_COLLATION); stmt->object = QualifyCollationName(castNode(List, stmt->object)); @@ -74,8 +77,9 @@ QualifyAlterCollationOwnerStmt(AlterOwnerStmt *stmt) * statement in place and makes the collation name fully qualified. */ void -QualifyDropCollationStmt(DropStmt *stmt) +QualifyDropCollationStmt(Node *node) { + DropStmt *stmt = castNode(DropStmt, node); List *names = NIL; List *name = NIL; diff --git a/src/backend/distributed/deparser/qualify_function_stmt.c b/src/backend/distributed/deparser/qualify_function_stmt.c index d6095f3fa..168ef0095 100644 --- a/src/backend/distributed/deparser/qualify_function_stmt.c +++ b/src/backend/distributed/deparser/qualify_function_stmt.c @@ -51,8 +51,9 @@ AssertObjectTypeIsFunctional(ObjectType type) * (e.g. ALTER FUNCTION .. RENAME .. queries are RenameStmt ) */ void -QualifyAlterFunctionStmt(AlterFunctionStmt *stmt) +QualifyAlterFunctionStmt(Node *node) { + AlterFunctionStmt *stmt = castNode(AlterFunctionStmt, node); AssertObjectTypeIsFunctional(stmt->objtype); QualifyFunction(stmt->func, stmt->objtype); @@ -65,8 +66,9 @@ QualifyAlterFunctionStmt(AlterFunctionStmt *stmt) * statement in place and makes the function name fully qualified. */ void -QualifyRenameFunctionStmt(RenameStmt *stmt) +QualifyRenameFunctionStmt(Node *node) { + RenameStmt *stmt = castNode(RenameStmt, node); AssertObjectTypeIsFunctional(stmt->renameType); QualifyFunction(castNode(ObjectWithArgs, stmt->object), stmt->renameType); @@ -79,8 +81,9 @@ QualifyRenameFunctionStmt(RenameStmt *stmt) * statement in place and makes the function name fully qualified. */ void -QualifyAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt) +QualifyAlterFunctionSchemaStmt(Node *node) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); AssertObjectTypeIsFunctional(stmt->objectType); QualifyFunction(castNode(ObjectWithArgs, stmt->object), stmt->objectType); @@ -93,8 +96,9 @@ QualifyAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt) * statement in place and makes the function name fully qualified. */ void -QualifyAlterFunctionOwnerStmt(AlterOwnerStmt *stmt) +QualifyAlterFunctionOwnerStmt(Node *node) { + AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); AssertObjectTypeIsFunctional(stmt->objectType); QualifyFunction(castNode(ObjectWithArgs, stmt->object), stmt->objectType); @@ -107,8 +111,9 @@ QualifyAlterFunctionOwnerStmt(AlterOwnerStmt *stmt) * statement in place and makes the function name fully qualified. */ void -QualifyAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt) +QualifyAlterFunctionDependsStmt(Node *node) { + AlterObjectDependsStmt *stmt = castNode(AlterObjectDependsStmt, node); AssertObjectTypeIsFunctional(stmt->objectType); QualifyFunction(castNode(ObjectWithArgs, stmt->object), stmt->objectType); diff --git a/src/backend/distributed/deparser/qualify_type_stmt.c b/src/backend/distributed/deparser/qualify_type_stmt.c index d5928cd91..e4ff94fd0 100644 --- a/src/backend/distributed/deparser/qualify_type_stmt.c +++ b/src/backend/distributed/deparser/qualify_type_stmt.c @@ -70,8 +70,9 @@ TypeOidGetNamespaceOid(Oid typeOid) void -QualifyRenameTypeStmt(RenameStmt *stmt) +QualifyRenameTypeStmt(Node *node) { + RenameStmt *stmt = castNode(RenameStmt, node); List *names = (List *) stmt->object; Assert(stmt->renameType == OBJECT_TYPE); @@ -88,8 +89,9 @@ QualifyRenameTypeStmt(RenameStmt *stmt) void -QualifyRenameTypeAttributeStmt(RenameStmt *stmt) +QualifyRenameTypeAttributeStmt(Node *node) { + RenameStmt *stmt = castNode(RenameStmt, node); Assert(stmt->renameType == OBJECT_ATTRIBUTE); Assert(stmt->relationType == OBJECT_TYPE); @@ -103,8 +105,9 @@ QualifyRenameTypeAttributeStmt(RenameStmt *stmt) void -QualifyAlterEnumStmt(AlterEnumStmt *stmt) +QualifyAlterEnumStmt(Node *node) { + AlterEnumStmt *stmt = castNode(AlterEnumStmt, node); List *names = stmt->typeName; if (list_length(names) == 1) @@ -119,8 +122,9 @@ QualifyAlterEnumStmt(AlterEnumStmt *stmt) void -QualifyAlterTypeStmt(AlterTableStmt *stmt) +QualifyAlterTypeStmt(Node *node) { + AlterTableStmt *stmt = castNode(AlterTableStmt, node); Assert(stmt->relkind == OBJECT_TYPE); if (stmt->relation->schemaname == NULL) @@ -133,8 +137,10 @@ QualifyAlterTypeStmt(AlterTableStmt *stmt) void -QualifyCompositeTypeStmt(CompositeTypeStmt *stmt) +QualifyCompositeTypeStmt(Node *node) { + CompositeTypeStmt *stmt = castNode(CompositeTypeStmt, node); + if (stmt->typevar->schemaname == NULL) { Oid creationSchema = RangeVarGetCreationNamespace(stmt->typevar); @@ -144,8 +150,10 @@ QualifyCompositeTypeStmt(CompositeTypeStmt *stmt) void -QualifyCreateEnumStmt(CreateEnumStmt *stmt) +QualifyCreateEnumStmt(Node *node) { + CreateEnumStmt *stmt = castNode(CreateEnumStmt, node); + if (list_length(stmt->typeName) == 1) { char *objname = NULL; @@ -157,8 +165,9 @@ QualifyCreateEnumStmt(CreateEnumStmt *stmt) void -QualifyAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt) +QualifyAlterTypeSchemaStmt(Node *node) { + AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node); Assert(stmt->objectType == OBJECT_TYPE); List *names = (List *) stmt->object; @@ -173,8 +182,9 @@ QualifyAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt) void -QualifyAlterTypeOwnerStmt(AlterOwnerStmt *stmt) +QualifyAlterTypeOwnerStmt(Node *node) { + AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); Assert(stmt->objectType == OBJECT_TYPE); List *names = (List *) stmt->object; diff --git a/src/backend/distributed/master/master_create_shards.c b/src/backend/distributed/master/master_create_shards.c index 05c7d654c..f97deb33b 100644 --- a/src/backend/distributed/master/master_create_shards.c +++ b/src/backend/distributed/master/master_create_shards.c @@ -84,7 +84,7 @@ master_create_worker_shards(PG_FUNCTION_ARGS) * sessions creating shards. */ ObjectAddressSet(tableAddress, RelationRelationId, distributedTableId); - EnsureDependenciesExistsOnAllNodes(&tableAddress); + EnsureDependenciesExistOnAllNodes(&tableAddress); CreateShardsWithRoundRobinPolicy(distributedTableId, shardCount, replicationFactor, useExclusiveConnections); diff --git a/src/backend/distributed/master/master_stage_protocol.c b/src/backend/distributed/master/master_stage_protocol.c index 3f02d9e74..439a44188 100644 --- a/src/backend/distributed/master/master_stage_protocol.c +++ b/src/backend/distributed/master/master_stage_protocol.c @@ -105,7 +105,7 @@ master_create_empty_shard(PG_FUNCTION_ARGS) * sessions creating shards. */ ObjectAddressSet(tableAddress, RelationRelationId, relationId); - EnsureDependenciesExistsOnAllNodes(&tableAddress); + EnsureDependenciesExistOnAllNodes(&tableAddress); /* don't allow the table to be dropped */ LockRelationOid(relationId, AccessShareLock); diff --git a/src/backend/distributed/metadata/dependency.c b/src/backend/distributed/metadata/dependency.c index d427ad3ce..e4e0167df 100644 --- a/src/backend/distributed/metadata/dependency.c +++ b/src/backend/distributed/metadata/dependency.c @@ -46,8 +46,8 @@ typedef struct ObjectAddressCollector /* forward declarations for functions to interact with the ObjectAddressCollector */ static void InitObjectAddressCollector(ObjectAddressCollector *collector); -static void CollectObjectAddress(ObjectAddressCollector *collector, const - ObjectAddress *address); +static void CollectObjectAddress(ObjectAddressCollector *collector, + const ObjectAddress *address); static bool IsObjectAddressCollected(const ObjectAddress *findAddress, ObjectAddressCollector *collector); static void MarkObjectVisited(ObjectAddressCollector *collector, diff --git a/src/backend/distributed/metadata/metadata_sync.c b/src/backend/distributed/metadata/metadata_sync.c index 1c6ef8b20..4908cd430 100644 --- a/src/backend/distributed/metadata/metadata_sync.c +++ b/src/backend/distributed/metadata/metadata_sync.c @@ -394,7 +394,7 @@ MetadataCreateCommands(void) * visible to all sessions creating shards. */ ObjectAddressSet(tableAddress, RelationRelationId, relationId); - EnsureDependenciesExistsOnAllNodes(&tableAddress); + EnsureDependenciesExistOnAllNodes(&tableAddress); metadataSnapshotCommandList = list_concat(metadataSnapshotCommandList, workerSequenceDDLCommands); diff --git a/src/backend/distributed/transaction/worker_transaction.c b/src/backend/distributed/transaction/worker_transaction.c index b9db46014..37aca6898 100644 --- a/src/backend/distributed/transaction/worker_transaction.c +++ b/src/backend/distributed/transaction/worker_transaction.c @@ -35,12 +35,12 @@ static void SendCommandToMetadataWorkersParams(const char *command, const char *user, int parameterCount, - const Oid *parameterTypes, const - char *const *parameterValues); + const Oid *parameterTypes, + const char *const *parameterValues); static void SendCommandToWorkersParamsInternal(TargetWorkerSet targetWorkerSet, const char *command, const char *user, - int parameterCount, const - Oid *parameterTypes, + int parameterCount, + const Oid *parameterTypes, const char *const *parameterValues); static void ErrorIfAnyMetadataNodeOutOfSync(List *metadataNodeList); static void SendCommandListToAllWorkersInternal(List *commandList, bool failOnError, @@ -316,8 +316,8 @@ SendBareOptionalCommandListToAllWorkersAsUser(List *commandList, const char *use static void SendCommandToMetadataWorkersParams(const char *command, const char *user, int parameterCount, - const Oid *parameterTypes, const - char *const *parameterValues) + const Oid *parameterTypes, + const char *const *parameterValues) { List *workerNodeList = TargetWorkerSetNodeList(WORKERS_WITH_METADATA, ShareLock); @@ -340,8 +340,8 @@ SendCommandToMetadataWorkersParams(const char *command, static void SendCommandToWorkersParamsInternal(TargetWorkerSet targetWorkerSet, const char *command, const char *user, int parameterCount, - const Oid *parameterTypes, const - char *const *parameterValues) + const Oid *parameterTypes, + const char *const *parameterValues) { List *connectionList = NIL; ListCell *connectionCell = NULL; diff --git a/src/backend/distributed/utils/foreign_key_relationship.c b/src/backend/distributed/utils/foreign_key_relationship.c index 12bf25d89..9ecb5d643 100644 --- a/src/backend/distributed/utils/foreign_key_relationship.c +++ b/src/backend/distributed/utils/foreign_key_relationship.c @@ -75,8 +75,8 @@ static ForeignConstraintRelationshipGraph *fConstraintRelationshipGraph = NULL; static void CreateForeignConstraintRelationshipGraph(void); static void PopulateAdjacencyLists(void); -static int CompareForeignConstraintRelationshipEdges(const void *leftElement, const - void *rightElement); +static int CompareForeignConstraintRelationshipEdges(const void *leftElement, + const void *rightElement); static void AddForeignConstraintRelationshipEdge(Oid referencingOid, Oid referencedOid); static ForeignConstraintRelationshipNode * CreateOrFindNode(HTAB *adjacencyLists, Oid relid); @@ -360,15 +360,13 @@ PopulateAdjacencyLists(void) * ForeignConstraintRelationshipEdge using referencing and referenced ids respectively. */ static int -CompareForeignConstraintRelationshipEdges(const void *leftElement, const - void *rightElement) +CompareForeignConstraintRelationshipEdges(const void *leftElement, + const void *rightElement) { - const ForeignConstraintRelationshipEdge *leftEdge = *((const - ForeignConstraintRelationshipEdge - **) leftElement); - const ForeignConstraintRelationshipEdge *rightEdge = *((const - ForeignConstraintRelationshipEdge - **) rightElement); + const ForeignConstraintRelationshipEdge *leftEdge = + *((const ForeignConstraintRelationshipEdge **) leftElement); + const ForeignConstraintRelationshipEdge *rightEdge = + *((const ForeignConstraintRelationshipEdge **) rightElement); int referencingDiff = leftEdge->referencingRelationOID - rightEdge->referencingRelationOID; diff --git a/src/backend/distributed/worker/worker_create_or_replace.c b/src/backend/distributed/worker/worker_create_or_replace.c index e32d63b72..d6a5a1540 100644 --- a/src/backend/distributed/worker/worker_create_or_replace.c +++ b/src/backend/distributed/worker/worker_create_or_replace.c @@ -83,10 +83,10 @@ worker_create_or_replace_object(PG_FUNCTION_ARGS) * if the type actually exists instead of adding the IF EXISTS keyword to the * statement. */ - const ObjectAddress *address = GetObjectAddressFromParseTree(parseTree, true); - if (ObjectExists(address)) + ObjectAddress address = GetObjectAddressFromParseTree(parseTree, true); + if (ObjectExists(&address)) { - const char *localSqlStatement = CreateStmtByObjectAddress(address); + const char *localSqlStatement = CreateStmtByObjectAddress(&address); if (strcmp(sqlStatement, localSqlStatement) == 0) { @@ -106,9 +106,9 @@ worker_create_or_replace_object(PG_FUNCTION_ARGS) PG_RETURN_BOOL(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); CitusProcessUtility((Node *) renameStmt, sqlRenameStmt, PROCESS_UTILITY_TOPLEVEL, diff --git a/src/backend/distributed/worker/worker_partition_protocol.c b/src/backend/distributed/worker/worker_partition_protocol.c index f643fac6e..90612b8ce 100644 --- a/src/backend/distributed/worker/worker_partition_protocol.c +++ b/src/backend/distributed/worker/worker_partition_protocol.c @@ -57,6 +57,8 @@ static uint32 FileBufferSizeInBytes = 0; /* file buffer size to init later */ /* Local functions forward declarations */ +typedef uint32 (*PartitionIdFunction)(Datum, Oid, const void *); + static ShardInterval ** SyntheticShardIntervalArrayForShardMinValues( Datum *shardMinValues, int shardCount); @@ -69,8 +71,7 @@ static void FileOutputStreamWrite(FileOutputStream *file, StringInfo dataToWrite static void FileOutputStreamFlush(FileOutputStream *file); static void FilterAndPartitionTable(const char *filterQuery, const char *columnName, Oid columnType, - uint32 (*PartitionIdFunction)(Datum, Oid, const - void *), + PartitionIdFunction partitionIdFunction, const void *partitionIdContext, FileOutputStream *partitionFileArray, uint32 fileCount); @@ -79,10 +80,10 @@ static CopyOutState InitRowOutputState(void); static void ClearRowOutputState(CopyOutState copyState); static void OutputBinaryHeaders(FileOutputStream *partitionFileArray, uint32 fileCount); static void OutputBinaryFooters(FileOutputStream *partitionFileArray, uint32 fileCount); -static uint32 RangePartitionId(Datum partitionValue, Oid partitionCollation, const - void *context); -static uint32 HashPartitionId(Datum partitionValue, Oid partitionCollation, const - void *context); +static uint32 RangePartitionId(Datum partitionValue, Oid partitionCollation, + const void *context); +static uint32 HashPartitionId(Datum partitionValue, Oid partitionCollation, + const void *context); static StringInfo UserPartitionFilename(StringInfo directoryName, uint32 partitionId); static bool FileIsLink(char *filename, struct stat filestat); @@ -854,7 +855,7 @@ FileOutputStreamFlush(FileOutputStream *file) static void FilterAndPartitionTable(const char *filterQuery, const char *partitionColumnName, Oid partitionColumnType, - uint32 (*PartitionIdFunction)(Datum, Oid, const void *), + PartitionIdFunction partitionIdFunction, const void *partitionIdContext, FileOutputStream *partitionFileArray, uint32 fileCount) @@ -941,7 +942,7 @@ FilterAndPartitionTable(const char *filterQuery, */ if (!partitionKeyNull) { - partitionId = (*PartitionIdFunction)(partitionKey, + partitionId = (*partitionIdFunction)(partitionKey, partitionColumnCollation, partitionIdContext); if (partitionId == INVALID_SHARD_INDEX) diff --git a/src/include/distributed/commands.h b/src/include/distributed/commands.h index 3667985ea..7b94c5c23 100644 --- a/src/include/distributed/commands.h +++ b/src/include/distributed/commands.h @@ -19,62 +19,84 @@ #include "nodes/parsenodes.h" #include "tcop/dest.h" +/* + * DistributeObjectOps specifies handlers for node/object type pairs. + * Instances of this type should all be declared in deparse.c. + * Handlers expect to receive the same Node passed to GetDistributeObjectOps. + * Handlers may be NULL. + * + * Handlers: + * deparse: return a string representation of the node. + * qualify: replace names in tree with qualified names. + * preprocess: executed before standard_ProcessUtility. + * postprocess: executed after standard_ProcessUtility. + * address: return an ObjectAddress for the subject of the statement. + * 2nd parameter is missing_ok. + * + * preprocess/postprocess return a List of DDLJobs. + */ +typedef struct DistributeObjectOps +{ + char * (*deparse)(Node *); + void (*qualify)(Node *); + List * (*preprocess)(Node *, const char *); + List * (*postprocess)(Node *, const char *); + ObjectAddress (*address)(Node *, bool); +} DistributeObjectOps; + +const DistributeObjectOps * GetDistributeObjectOps(Node *node); /* cluster.c - forward declarations */ -extern List * PlanClusterStmt(ClusterStmt *clusterStmt, const char *clusterCommand); +extern List * PreprocessClusterStmt(Node *node, const char *clusterCommand); /* call.c */ extern bool CallDistributedProcedureRemotely(CallStmt *callStmt, DestReceiver *dest); + /* collation.c - forward declarations */ extern char * CreateCollationDDL(Oid collationId); extern List * CreateCollationDDLsIdempotent(Oid collationId); -extern ObjectAddress AlterCollationOwnerObjectAddress(AlterOwnerStmt *stmt); -extern List * PlanDropCollationStmt(DropStmt *stmt); -extern List * PlanAlterCollationOwnerStmt(AlterOwnerStmt *stmt, const char *queryString); -extern List * PlanAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt, - const char *queryString); -extern List * PlanRenameCollationStmt(RenameStmt *stmt, const char *queryString); -extern ObjectAddress * RenameCollationStmtObjectAddress(RenameStmt *stmt, - bool missing_ok); -extern ObjectAddress * AlterCollationSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, - bool missing_ok); -extern void ProcessAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt, - const char *queryString); +extern ObjectAddress AlterCollationOwnerObjectAddress(Node *stmt, bool missing_ok); +extern List * PreprocessDropCollationStmt(Node *stmt, const char *queryString); +extern List * PreprocessAlterCollationOwnerStmt(Node *stmt, const char *queryString); +extern List * PreprocessAlterCollationSchemaStmt(Node *stmt, const char *queryString); +extern List * PreprocessRenameCollationStmt(Node *stmt, const char *queryString); +extern ObjectAddress RenameCollationStmtObjectAddress(Node *stmt, bool missing_ok); +extern ObjectAddress AlterCollationSchemaStmtObjectAddress(Node *stmt, + bool missing_ok); +extern List * PostprocessAlterCollationSchemaStmt(Node *stmt, const char *queryString); extern char * GenerateBackupNameForCollationCollision(const ObjectAddress *address); -extern ObjectAddress * DefineCollationStmtObjectAddress(DefineStmt *stmt, bool - missing_ok); -extern List * ProcessCollationDefineStmt(DefineStmt *stmt, const char *queryString); +extern ObjectAddress DefineCollationStmtObjectAddress(Node *stmt, bool missing_ok); +extern List * PostprocessDefineCollationStmt(Node *stmt, const char *queryString); /* extension.c - forward declarations */ extern bool IsCreateAlterExtensionUpdateCitusStmt(Node *parsetree); extern void ErrorIfUnstableCreateOrAlterExtensionStmt(Node *parsetree); -extern List * PlanCreateExtensionStmt(CreateExtensionStmt *stmt, const char *queryString); -extern void ProcessCreateExtensionStmt(CreateExtensionStmt *stmt, const - char *queryString); -extern List * PlanDropExtensionStmt(DropStmt *stmt, const char *queryString); -extern List * PlanAlterExtensionSchemaStmt(AlterObjectSchemaStmt *alterExtensionStmt, - const char *queryString); -extern void ProcessAlterExtensionSchemaStmt(AlterObjectSchemaStmt *alterExtensionStmt, - const char *queryString); -extern List * PlanAlterExtensionUpdateStmt(AlterExtensionStmt *alterExtensionStmt, const - char *queryString); +extern List * PostprocessCreateExtensionStmt(Node *stmt, const char *queryString); +extern List * PreprocessDropExtensionStmt(Node *stmt, const char *queryString); +extern List * PreprocessAlterExtensionSchemaStmt(Node *stmt, + const char *queryString); +extern List * PostprocessAlterExtensionSchemaStmt(Node *stmt, + const char *queryString); +extern List * PreprocessAlterExtensionUpdateStmt(Node *stmt, + const char *queryString); +extern List * PreprocessAlterExtensionContentsStmt(Node *node, + const char *queryString); extern List * CreateExtensionDDLCommand(const ObjectAddress *extensionAddress); -extern ObjectAddress * AlterExtensionSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, - bool missing_ok); -extern ObjectAddress * AlterExtensionUpdateStmtObjectAddress( - AlterExtensionStmt *alterExtensionStmt, - bool missing_ok); +extern ObjectAddress AlterExtensionSchemaStmtObjectAddress(Node *stmt, + bool missing_ok); +extern ObjectAddress AlterExtensionUpdateStmtObjectAddress(Node *stmt, + bool missing_ok); /* foreign_constraint.c - forward declarations */ extern bool ConstraintIsAForeignKeyToReferenceTable(char *constraintName, Oid leftRelationId); -extern void ErrorIfUnsupportedForeignConstraintExists(Relation relation, char - distributionMethod, - Var *distributionColumn, uint32 - colocationId); +extern void ErrorIfUnsupportedForeignConstraintExists(Relation relation, + char distributionMethod, + Var *distributionColumn, + uint32 colocationId); extern bool ColumnAppearsInForeignKeyToReferenceTable(char *columnName, Oid relationId); extern List * GetTableForeignConstraintCommands(Oid relationId); @@ -85,58 +107,62 @@ extern bool ConstraintIsAForeignKey(char *constraintName, Oid relationId); /* function.c - forward declarations */ -extern List * PlanCreateFunctionStmt(CreateFunctionStmt *stmt, const char *queryString); -extern List * ProcessCreateFunctionStmt(CreateFunctionStmt *stmt, const - char *queryString); -extern ObjectAddress * CreateFunctionStmtObjectAddress(CreateFunctionStmt *stmt, - bool missing_ok); -extern ObjectAddress * DefineAggregateStmtObjectAddress(DefineStmt *stmt, bool - missing_ok); -extern List * PlanAlterFunctionStmt(AlterFunctionStmt *stmt, const char *queryString); -extern ObjectAddress * AlterFunctionStmtObjectAddress(AlterFunctionStmt *stmt, +extern List * PreprocessCreateFunctionStmt(Node *stmt, const char *queryString); +extern List * PostprocessCreateFunctionStmt(Node *stmt, + const char *queryString); +extern ObjectAddress CreateFunctionStmtObjectAddress(Node *stmt, + bool missing_ok); +extern ObjectAddress DefineAggregateStmtObjectAddress(Node *stmt, bool missing_ok); -extern List * PlanRenameFunctionStmt(RenameStmt *stmt, const char *queryString); -extern ObjectAddress * RenameFunctionStmtObjectAddress(RenameStmt *stmt, - bool missing_ok); -extern List * PlanAlterFunctionOwnerStmt(AlterOwnerStmt *stmt, const char *queryString); -extern ObjectAddress * AlterFunctionOwnerObjectAddress(AlterOwnerStmt *stmt, - bool missing_ok); -extern List * PlanAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt, - const char *queryString); -extern ObjectAddress * AlterFunctionSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, - bool missing_ok); -extern void ProcessAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt, - const char *queryString); -extern List * PlanDropFunctionStmt(DropStmt *stmt, const char *queryString); -extern List * PlanAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt, - const char *queryString); -extern ObjectAddress * AlterFunctionDependsStmtObjectAddress(AlterObjectDependsStmt *stmt, - bool missing_ok); +extern List * PreprocessAlterFunctionStmt(Node *stmt, const char *queryString); +extern ObjectAddress AlterFunctionStmtObjectAddress(Node *stmt, + bool missing_ok); +extern List * PreprocessRenameFunctionStmt(Node *stmt, const char *queryString); +extern ObjectAddress RenameFunctionStmtObjectAddress(Node *stmt, + bool missing_ok); +extern List * PreprocessAlterFunctionOwnerStmt(Node *stmt, const char *queryString); +extern ObjectAddress AlterFunctionOwnerObjectAddress(Node *stmt, + bool missing_ok); +extern List * PreprocessAlterFunctionSchemaStmt(Node *stmt, const char *queryString); +extern ObjectAddress AlterFunctionSchemaStmtObjectAddress(Node *stmt, + bool missing_ok); +extern List * PostprocessAlterFunctionSchemaStmt(Node *stmt, + const char *queryString); +extern List * PreprocessDropFunctionStmt(Node *stmt, const char *queryString); +extern List * PreprocessAlterFunctionDependsStmt(Node *stmt, + const char *queryString); +extern ObjectAddress AlterFunctionDependsStmtObjectAddress(Node *stmt, + bool missing_ok); /* grant.c - forward declarations */ -extern List * PlanGrantStmt(GrantStmt *grantStmt); +extern List * PreprocessGrantStmt(Node *node, const char *queryString); /* index.c - forward declarations */ extern bool IsIndexRenameStmt(RenameStmt *renameStmt); -extern List * PlanIndexStmt(IndexStmt *createIndexStatement, - const char *createIndexCommand); -extern List * PlanReindexStmt(ReindexStmt *ReindexStatement, - const char *ReindexCommand); -extern List * PlanDropIndexStmt(DropStmt *dropIndexStatement, - const char *dropIndexCommand); -extern void PostProcessIndexStmt(IndexStmt *indexStmt); +extern List * PreprocessIndexStmt(Node *createIndexStatement, + const char *createIndexCommand); +extern List * PreprocessReindexStmt(Node *ReindexStatement, + const char *ReindexCommand); +extern List * PreprocessDropIndexStmt(Node *dropIndexStatement, + const char *dropIndexCommand); +extern List * PostprocessIndexStmt(Node *node, + const char *queryString); extern void ErrorIfUnsupportedAlterIndexStmt(AlterTableStmt *alterTableStatement); +/* objectaddress.c - forward declarations */ +extern ObjectAddress CreateExtensionStmtObjectAddress(Node *stmt, bool missing_ok); +extern ObjectAddress AlterExtensionStmtObjectAddress(Node *stmt, bool missing_ok); + /* policy.c - forward declarations */ extern List * CreatePolicyCommands(Oid relationId); extern void ErrorIfUnsupportedPolicy(Relation relation); extern void ErrorIfUnsupportedPolicyExpr(Node *expr); -extern List * PlanCreatePolicyStmt(CreatePolicyStmt *stmt); -extern List * PlanAlterPolicyStmt(AlterPolicyStmt *stmt); -extern List * PlanDropPolicyStmt(DropStmt *stmt, const char *queryString); +extern List * PreprocessCreatePolicyStmt(Node *node, const char *queryString); +extern List * PreprocessAlterPolicyStmt(Node *node, const char *queryString); +extern List * PreprocessDropPolicyStmt(Node *stmt, const char *queryString); extern bool IsPolicyRenameStmt(RenameStmt *stmt); extern void CreatePolicyEventExtendNames(CreatePolicyStmt *stmt, const char *schemaName, uint64 shardId); @@ -149,24 +175,23 @@ extern void DropPolicyEventExtendNames(DropStmt *stmt, const char *schemaName, u /* rename.c - forward declarations*/ -extern List * PlanRenameStmt(RenameStmt *renameStmt, const char *renameCommand); +extern List * PreprocessRenameStmt(Node *renameStmt, const char *renameCommand); extern void ErrorIfUnsupportedRenameStmt(RenameStmt *renameStmt); +extern List * PreprocessRenameAttributeStmt(Node *stmt, const char *queryString); /* role.c - forward declarations*/ -extern List * ProcessAlterRoleStmt(AlterRoleStmt *stmt, const char *queryString); +extern List * PostprocessAlterRoleStmt(Node *stmt, const char *queryString); extern List * GenerateAlterRoleIfExistsCommandAllRoles(void); /* schema.c - forward declarations */ -extern void ProcessDropSchemaStmt(DropStmt *dropSchemaStatement); -extern List * PlanAlterTableSchemaStmt(AlterObjectSchemaStmt *stmt, +extern List * PreprocessDropSchemaStmt(Node *dropSchemaStatement, const char *queryString); -extern List * PlanAlterObjectSchemaStmt(AlterObjectSchemaStmt *alterObjectSchemaStmt, - const char *alterObjectSchemaCommand); - -extern void ProcessAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt, - const char *queryString); +extern List * PreprocessAlterTableSchemaStmt(Node *stmt, + const char *queryString); +extern List * PreprocessAlterObjectSchemaStmt(Node *alterObjectSchemaStmt, + const char *alterObjectSchemaCommand); /* sequence.c - forward declarations */ @@ -179,16 +204,19 @@ extern Node * ProcessCreateSubscriptionStmt(CreateSubscriptionStmt *createSubStm /* table.c - forward declarations */ -extern void ProcessDropTableStmt(DropStmt *dropTableStatement); -extern void ProcessCreateTableStmtPartitionOf(CreateStmt *createStatement); -extern void ProcessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement); -extern List * PlanAlterTableStmt(AlterTableStmt *alterTableStatement, - const char *alterTableCommand); +extern List * PreprocessDropTableStmt(Node *stmt, const char *queryString); +extern List * PostprocessCreateTableStmtPartitionOf(CreateStmt *createStatement, + const char *queryString); +extern List * PostprocessAlterTableStmtAttachPartition( + AlterTableStmt *alterTableStatement, + const char *queryString); +extern List * PreprocessAlterTableStmt(Node *node, const char *alterTableCommand); +extern List * PreprocessAlterTableMoveAllStmt(Node *node, const char *queryString); extern Node * WorkerProcessAlterTableStmt(AlterTableStmt *alterTableStatement, const char *alterTableCommand); extern bool IsAlterTableRenameStmt(RenameStmt *renameStmt); extern void ErrorIfAlterDropsPartitionColumn(AlterTableStmt *alterTableStatement); -extern void PostProcessAlterTableStmt(AlterTableStmt *pStmt); +extern void PostprocessAlterTableStmt(AlterTableStmt *pStmt); extern void ErrorUnsupportedAlterTableAddColumn(Oid relationId, AlterTableCmd *command, Constraint *constraint); extern void ErrorIfUnsupportedConstraint(Relation relation, char distributionMethod, @@ -196,36 +224,33 @@ extern void ErrorIfUnsupportedConstraint(Relation relation, char distributionMet /* truncate.c - forward declarations */ -extern void ProcessTruncateStatement(TruncateStmt *truncateStatement); +extern void PostprocessTruncateStatement(TruncateStmt *truncateStatement); /* type.c - forward declarations */ -extern List * PlanCompositeTypeStmt(CompositeTypeStmt *stmt, const char *queryString); -extern void ProcessCompositeTypeStmt(CompositeTypeStmt *stmt, const char *queryString); -extern List * PlanAlterTypeStmt(AlterTableStmt *stmt, const char *queryString); -extern List * PlanCreateEnumStmt(CreateEnumStmt *createEnumStmt, const char *queryString); -extern void ProcessCreateEnumStmt(CreateEnumStmt *stmt, const char *queryString); -extern List * PlanAlterEnumStmt(AlterEnumStmt *stmt, const char *queryString); -extern void ProcessAlterEnumStmt(AlterEnumStmt *stmt, const char *queryString); -extern List * PlanDropTypeStmt(DropStmt *stmt, const char *queryString); -extern List * PlanRenameTypeStmt(RenameStmt *stmt, const char *queryString); -extern List * PlanRenameTypeAttributeStmt(RenameStmt *stmt, const char *queryString); -extern List * PlanAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt, - const char *queryString); -extern List * PlanAlterTypeOwnerStmt(AlterOwnerStmt *stmt, const char *queryString); -extern void ProcessAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt, - const char *queryString); +extern List * PreprocessCompositeTypeStmt(Node *stmt, const char *queryString); +extern List * PostprocessCompositeTypeStmt(Node *stmt, const char *queryString); +extern List * PreprocessAlterTypeStmt(Node *stmt, const char *queryString); +extern List * PreprocessCreateEnumStmt(Node *stmt, const char *queryString); +extern List * PostprocessCreateEnumStmt(Node *stmt, const char *queryString); +extern List * PreprocessAlterEnumStmt(Node *stmt, const char *queryString); +extern List * PostprocessAlterEnumStmt(Node *stmt, const char *queryString); +extern List * PreprocessDropTypeStmt(Node *stmt, const char *queryString); +extern List * PreprocessRenameTypeStmt(Node *stmt, const char *queryString); +extern List * PreprocessRenameTypeAttributeStmt(Node *stmt, const char *queryString); +extern List * PreprocessAlterTypeSchemaStmt(Node *stmt, const char *queryString); +extern List * PreprocessAlterTypeOwnerStmt(Node *stmt, const char *queryString); +extern List * PostprocessAlterTypeSchemaStmt(Node *stmt, const char *queryString); extern Node * CreateTypeStmtByObjectAddress(const ObjectAddress *address); -extern ObjectAddress * CompositeTypeStmtObjectAddress(CompositeTypeStmt *stmt, bool - missing_ok); -extern ObjectAddress * CreateEnumStmtObjectAddress(CreateEnumStmt *stmt, bool missing_ok); -extern ObjectAddress * AlterTypeStmtObjectAddress(AlterTableStmt *stmt, bool missing_ok); -extern ObjectAddress * AlterEnumStmtObjectAddress(AlterEnumStmt *stmt, bool missing_ok); -extern ObjectAddress * RenameTypeStmtObjectAddress(RenameStmt *stmt, bool missing_ok); -extern ObjectAddress * AlterTypeSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, - bool missing_ok); -extern ObjectAddress * RenameTypeAttributeStmtObjectAddress(RenameStmt *stmt, bool - missing_ok); -extern ObjectAddress * AlterTypeOwnerObjectAddress(AlterOwnerStmt *stmt, bool missing_ok); +extern ObjectAddress CompositeTypeStmtObjectAddress(Node *stmt, bool missing_ok); +extern ObjectAddress CreateEnumStmtObjectAddress(Node *stmt, bool missing_ok); +extern ObjectAddress AlterTypeStmtObjectAddress(Node *stmt, bool missing_ok); +extern ObjectAddress AlterEnumStmtObjectAddress(Node *stmt, bool missing_ok); +extern ObjectAddress RenameTypeStmtObjectAddress(Node *stmt, bool missing_ok); +extern ObjectAddress AlterTypeSchemaStmtObjectAddress(Node *stmt, + bool missing_ok); +extern ObjectAddress RenameTypeAttributeStmtObjectAddress(Node *stmt, + bool missing_ok); +extern ObjectAddress AlterTypeOwnerObjectAddress(Node *stmt, bool missing_ok); extern List * CreateTypeDDLCommandsIdempotent(const ObjectAddress *typeAddress); extern char * GenerateBackupNameForTypeCollision(const ObjectAddress *address); @@ -236,9 +261,9 @@ extern char * GenerateBackupNameForProcCollision(const ObjectAddress *address); extern ObjectWithArgs * ObjectWithArgsFromOid(Oid funcOid); /* vacuum.c - froward declarations */ -extern void ProcessVacuumStmt(VacuumStmt *vacuumStmt, const char *vacuumCommand); +extern void PostprocessVacuumStmt(VacuumStmt *vacuumStmt, const char *vacuumCommand); extern bool ShouldPropagateSetCommand(VariableSetStmt *setStmt); -extern void ProcessVariableSetStmt(VariableSetStmt *setStmt, const char *setCommand); +extern void PostprocessVariableSetStmt(VariableSetStmt *setStmt, const char *setCommand); #endif /*CITUS_COMMANDS_H */ diff --git a/src/include/distributed/connection_management.h b/src/include/distributed/connection_management.h index 17ff36d12..2424dfd13 100644 --- a/src/include/distributed/connection_management.h +++ b/src/include/distributed/connection_management.h @@ -209,8 +209,8 @@ extern MultiConnection * GetNodeConnection(uint32 flags, const char *hostname, extern MultiConnection * StartNodeConnection(uint32 flags, const char *hostname, int32 port); extern MultiConnection * GetNodeUserDatabaseConnection(uint32 flags, const char *hostname, - int32 port, const char *user, const - char *database); + int32 port, const char *user, + const char *database); extern List * StartWorkerListConnections(List *workerList, uint32 flags, const char *user, const char *database); extern MultiConnection * StartNodeUserDatabaseConnection(uint32 flags, diff --git a/src/include/distributed/deparser.h b/src/include/distributed/deparser.h index 165575151..236280631 100644 --- a/src/include/distributed/deparser.h +++ b/src/include/distributed/deparser.h @@ -32,64 +32,68 @@ extern void AssertObjectTypeIsFunctional(ObjectType type); extern void QualifyTreeNode(Node *stmt); extern char * DeparseTreeNode(Node *stmt); -/* forward declarations for deparse_collation_stmts.c */ -extern char * DeparseDropCollationStmt(DropStmt *stmt); -extern char * DeparseRenameCollationStmt(RenameStmt *stmt); -extern char * DeparseAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt); -extern char * DeparseAlterCollationOwnerStmt(AlterOwnerStmt *stmt); +/* forward declarations for deparse_attribute_stmts.c */ +extern char * DeparseRenameAttributeStmt(Node *); -extern void QualifyDropCollationStmt(DropStmt *stmt); -extern void QualifyRenameCollationStmt(RenameStmt *stmt); -extern void QualifyAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt); -extern void QualifyAlterCollationOwnerStmt(AlterOwnerStmt *stmt); +/* forward declarations for deparse_collation_stmts.c */ +extern char * DeparseDropCollationStmt(Node *stmt); +extern char * DeparseRenameCollationStmt(Node *stmt); +extern char * DeparseAlterCollationSchemaStmt(Node *stmt); +extern char * DeparseAlterCollationOwnerStmt(Node *stmt); + +extern void QualifyDropCollationStmt(Node *stmt); +extern void QualifyRenameCollationStmt(Node *stmt); +extern void QualifyAlterCollationSchemaStmt(Node *stmt); +extern void QualifyAlterCollationOwnerStmt(Node *stmt); /* forward declarations for deparse_type_stmts.c */ -extern char * DeparseCompositeTypeStmt(CompositeTypeStmt *stmt); -extern char * DeparseCreateEnumStmt(CreateEnumStmt *stmt); -extern char * DeparseDropTypeStmt(DropStmt *stmt); -extern char * DeparseAlterEnumStmt(AlterEnumStmt *stmt); -extern char * DeparseAlterTypeStmt(AlterTableStmt *stmt); -extern char * DeparseRenameTypeStmt(RenameStmt *stmt); -extern char * DeparseRenameTypeAttributeStmt(RenameStmt *stmt); -extern char * DeparseAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt); -extern char * DeparseAlterTypeOwnerStmt(AlterOwnerStmt *stmt); +extern char * DeparseCompositeTypeStmt(Node *stmt); +extern char * DeparseCreateEnumStmt(Node *stmt); +extern char * DeparseDropTypeStmt(Node *stmt); +extern char * DeparseAlterEnumStmt(Node *stmt); +extern char * DeparseAlterTypeStmt(Node *stmt); +extern char * DeparseRenameTypeStmt(Node *stmt); +extern char * DeparseRenameTypeAttributeStmt(Node *stmt); +extern char * DeparseAlterTypeSchemaStmt(Node *stmt); +extern char * DeparseAlterTypeOwnerStmt(Node *stmt); -extern void QualifyRenameTypeStmt(RenameStmt *stmt); -extern void QualifyRenameTypeAttributeStmt(RenameStmt *stmt); -extern void QualifyAlterEnumStmt(AlterEnumStmt *stmt); -extern void QualifyAlterTypeStmt(AlterTableStmt *stmt); -extern void QualifyCompositeTypeStmt(CompositeTypeStmt *stmt); -extern void QualifyCreateEnumStmt(CreateEnumStmt *stmt); -extern void QualifyAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt); -extern void QualifyAlterTypeOwnerStmt(AlterOwnerStmt *stmt); +extern void QualifyRenameAttributeStmt(Node *stmt); +extern void QualifyRenameTypeStmt(Node *stmt); +extern void QualifyRenameTypeAttributeStmt(Node *stmt); +extern void QualifyAlterEnumStmt(Node *stmt); +extern void QualifyAlterTypeStmt(Node *stmt); +extern void QualifyCompositeTypeStmt(Node *stmt); +extern void QualifyCreateEnumStmt(Node *stmt); +extern void QualifyAlterTypeSchemaStmt(Node *stmt); +extern void QualifyAlterTypeOwnerStmt(Node *stmt); -extern ObjectAddress * GetObjectAddressFromParseTree(Node *parseTree, bool missing_ok); +extern ObjectAddress GetObjectAddressFromParseTree(Node *parseTree, bool missing_ok); +extern ObjectAddress RenameAttributeStmtObjectAddress(Node *stmt, bool missing_ok); /* forward declarations for deparse_function_stmts.c */ -extern char * DeparseDropFunctionStmt(DropStmt *stmt); -extern char * DeparseAlterFunctionStmt(AlterFunctionStmt *stmt); +extern char * DeparseDropFunctionStmt(Node *stmt); +extern char * DeparseAlterFunctionStmt(Node *stmt); -extern char * DeparseRenameFunctionStmt(RenameStmt *stmt); -extern char * DeparseAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt); -extern char * DeparseAlterFunctionOwnerStmt(AlterOwnerStmt *stmt); -extern char * DeparseAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt); +extern char * DeparseRenameFunctionStmt(Node *stmt); +extern char * DeparseAlterFunctionSchemaStmt(Node *stmt); +extern char * DeparseAlterFunctionOwnerStmt(Node *stmt); +extern char * DeparseAlterFunctionDependsStmt(Node *stmt); -extern void QualifyAlterFunctionStmt(AlterFunctionStmt *stmt); -extern void QualifyRenameFunctionStmt(RenameStmt *stmt); -extern void QualifyAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt); -extern void QualifyAlterFunctionOwnerStmt(AlterOwnerStmt *stmt); -extern void QualifyAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt); +extern void QualifyAlterFunctionStmt(Node *stmt); +extern void QualifyRenameFunctionStmt(Node *stmt); +extern void QualifyAlterFunctionSchemaStmt(Node *stmt); +extern void QualifyAlterFunctionOwnerStmt(Node *stmt); +extern void QualifyAlterFunctionDependsStmt(Node *stmt); /* forward declarations for deparse_role_stmts.c */ -extern char * DeparseAlterRoleStmt(AlterRoleStmt *stmt); +extern char * DeparseAlterRoleStmt(Node *stmt); /* forward declarations for deparse_extension_stmts.c */ -extern Value * GetExtensionOption(List *extensionOptions, const - char *defname); -extern char * DeparseCreateExtensionStmt(CreateExtensionStmt *stmt); -extern char * DeparseDropExtensionStmt(DropStmt *stmt); -extern char * DeparseAlterExtensionSchemaStmt( - AlterObjectSchemaStmt *alterExtensionSchemaStmt); -extern char * DeparseAlterExtensionStmt(AlterExtensionStmt *alterExtensionStmt); +extern Value * GetExtensionOption(List *extensionOptions, + const char *defname); +extern char * DeparseCreateExtensionStmt(Node *stmt); +extern char * DeparseDropExtensionStmt(Node *stmt); +extern char * DeparseAlterExtensionSchemaStmt(Node *stmt); +extern char * DeparseAlterExtensionStmt(Node *stmt); #endif /* CITUS_DEPARSER_H */ diff --git a/src/include/distributed/errormessage.h b/src/include/distributed/errormessage.h index 87992deb1..7d2d37fee 100644 --- a/src/include/distributed/errormessage.h +++ b/src/include/distributed/errormessage.h @@ -38,8 +38,8 @@ typedef struct DeferredErrorMessage DeferredErrorInternal(code, message, detail, hint, __FILE__, __LINE__, \ PG_FUNCNAME_MACRO) -DeferredErrorMessage * DeferredErrorInternal(int code, const char *message, const - char *detail, const char *hint, +DeferredErrorMessage * DeferredErrorInternal(int code, const char *message, + const char *detail, const char *hint, const char *filename, int linenumber, const char *functionname); diff --git a/src/include/distributed/master_metadata_utility.h b/src/include/distributed/master_metadata_utility.h index 12e3811f9..17e12ca42 100644 --- a/src/include/distributed/master_metadata_utility.h +++ b/src/include/distributed/master_metadata_utility.h @@ -137,7 +137,7 @@ extern void CreateDistributedTable(Oid relationId, Var *distributionColumn, bool viaDeprecatedAPI); extern void CreateTruncateTrigger(Oid relationId); -extern void EnsureDependenciesExistsOnAllNodes(const ObjectAddress *target); +extern void EnsureDependenciesExistOnAllNodes(const ObjectAddress *target); extern bool ShouldPropagate(void); extern bool ShouldPropagateObject(const ObjectAddress *address); extern void ReplicateAllDependenciesToNode(const char *nodeName, int nodePort); diff --git a/src/include/distributed/shardinterval_utils.h b/src/include/distributed/shardinterval_utils.h index 1400c5358..88cb9065f 100644 --- a/src/include/distributed/shardinterval_utils.h +++ b/src/include/distributed/shardinterval_utils.h @@ -42,8 +42,8 @@ extern ShardInterval * LowestShardIntervalById(List *shardIntervalList); extern int CompareShardIntervals(const void *leftElement, const void *rightElement, SortShardIntervalContext *sortContext); extern int CompareShardIntervalsById(const void *leftElement, const void *rightElement); -extern int CompareShardPlacementsByShardId(const void *leftElement, const - void *rightElement); +extern int CompareShardPlacementsByShardId(const void *leftElement, + const void *rightElement); extern int CompareRelationShards(const void *leftElement, const void *rightElement); extern int ShardIndex(ShardInterval *shardInterval); diff --git a/src/include/distributed/worker_transaction.h b/src/include/distributed/worker_transaction.h index 00cff4758..91774822a 100644 --- a/src/include/distributed/worker_transaction.h +++ b/src/include/distributed/worker_transaction.h @@ -32,9 +32,8 @@ typedef enum TargetWorkerSet extern List * GetWorkerTransactions(void); extern List * TargetWorkerSetNodeList(TargetWorkerSet targetWorkerSet, LOCKMODE lockMode); extern void SendCommandToWorker(char *nodeName, int32 nodePort, const char *command); -extern void SendCommandToWorkersAsUser(TargetWorkerSet targetWorkerSet, const - char *nodeUser, - const char *command); +extern void SendCommandToWorkersAsUser(TargetWorkerSet targetWorkerSet, + const char *nodeUser, const char *command); extern void SendCommandToWorkerAsUser(char *nodeName, int32 nodePort, const char *nodeUser, const char *command); extern void SendCommandToWorkersWithMetadata(const char *command);