Introduce GetDistributeObjectOps to organize dispatch of logic dependent on node/object type

pull/3364/head
Philip Dubé 2020-01-03 02:40:42 +00:00
parent 22cc5b1240
commit 73c06fae3b
47 changed files with 1658 additions and 2019 deletions

View File

@ -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 */

View File

@ -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));
}

View File

@ -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

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -75,7 +75,7 @@ static void EnsureSequentialModeForFunctionDDL(void);
static void TriggerSyncMetadataToPrimaryNodes(void);
static bool ShouldPropagateCreateFunction(CreateFunctionStmt *stmt);
static bool ShouldPropagateAlterFunction(const ObjectAddress *address);
static ObjectAddress * FunctionToObjectAddress(ObjectType objectType,
static ObjectAddress FunctionToObjectAddress(ObjectType objectType,
ObjectWithArgs *objectWithArgs,
bool missing_ok);
static void ErrorIfUnsupportedAlterFunctionStmt(AlterFunctionStmt *stmt);
@ -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,
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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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())

View File

@ -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;
}
}
}

View File

@ -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)

View File

@ -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);

View File

@ -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;
}

View File

@ -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,49 +514,15 @@ 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)
{
ddlJobs = ProcessCollationDefineStmt(defineStmt, queryString);
}
}
if (IsA(parsetree, AlterObjectSchemaStmt))
{
ProcessAlterObjectSchemaStmt(castNode(AlterObjectSchemaStmt, parsetree),
queryString);
}
if (IsA(parsetree, AlterEnumStmt))
{
ProcessAlterEnumStmt(castNode(AlterEnumStmt, parsetree), queryString);
}
if (IsA(parsetree, CreateFunctionStmt))
if (processJobs)
{
Assert(ddlJobs == NIL); /* jobs should not have been set before */
ddlJobs = ProcessCreateFunctionStmt(castNode(CreateFunctionStmt, parsetree),
queryString);
ddlJobs = processJobs;
}
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)
@ -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.

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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))
{
case T_DropStmt:
{
return DeparseDropStmt(castNode(DropStmt, stmt));
}
const DistributeObjectOps *ops = GetDistributeObjectOps(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:
if (!ops->deparse)
{
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")));
}
}
return ops->deparse(stmt);
}

View File

@ -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")));
}
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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)
{
case T_CompositeTypeStmt:
{
return CompositeTypeStmtObjectAddress(castNode(CompositeTypeStmt, parseTree),
missing_ok);
}
const DistributeObjectOps *ops = GetDistributeObjectOps(parseTree);
case T_AlterTableStmt:
if (!ops->address)
{
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;
}
}
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;
}

View File

@ -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))
{
case T_RenameStmt:
{
QualifyRenameStmt(castNode(RenameStmt, stmt));
return;
}
const DistributeObjectOps *ops = GetDistributeObjectOps(stmt);
case T_AlterEnumStmt:
if (ops && ops->qualify)
{
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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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)

View File

@ -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,
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 ObjectAddress * AlterCollationSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt,
bool missing_ok);
extern void ProcessAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt,
const char *queryString);
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,
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 void ProcessAlterExtensionSchemaStmt(AlterObjectSchemaStmt *alterExtensionStmt,
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 * PlanAlterExtensionUpdateStmt(AlterExtensionStmt *alterExtensionStmt, const
char *queryString);
extern List * CreateExtensionDDLCommand(const ObjectAddress *extensionAddress);
extern ObjectAddress * AlterExtensionSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt,
extern ObjectAddress AlterExtensionSchemaStmtObjectAddress(Node *stmt,
bool missing_ok);
extern ObjectAddress * AlterExtensionUpdateStmtObjectAddress(
AlterExtensionStmt *alterExtensionStmt,
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,
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,
extern List * PreprocessCreateFunctionStmt(Node *stmt, const char *queryString);
extern List * PostprocessCreateFunctionStmt(Node *stmt,
const char *queryString);
extern ObjectAddress * AlterFunctionSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt,
extern ObjectAddress CreateFunctionStmtObjectAddress(Node *stmt,
bool missing_ok);
extern void ProcessAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt,
extern ObjectAddress DefineAggregateStmtObjectAddress(Node *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 * PlanDropFunctionStmt(DropStmt *stmt, const char *queryString);
extern List * PlanAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt,
extern List * PreprocessDropFunctionStmt(Node *stmt, const char *queryString);
extern List * PreprocessAlterFunctionDependsStmt(Node *stmt,
const char *queryString);
extern ObjectAddress * AlterFunctionDependsStmtObjectAddress(AlterObjectDependsStmt *stmt,
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,
extern List * PreprocessIndexStmt(Node *createIndexStatement,
const char *createIndexCommand);
extern List * PlanReindexStmt(ReindexStmt *ReindexStatement,
extern List * PreprocessReindexStmt(Node *ReindexStatement,
const char *ReindexCommand);
extern List * PlanDropIndexStmt(DropStmt *dropIndexStatement,
extern List * PreprocessDropIndexStmt(Node *dropIndexStatement,
const char *dropIndexCommand);
extern void PostProcessIndexStmt(IndexStmt *indexStmt);
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,25 +175,24 @@ 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,
extern List * PreprocessAlterTableSchemaStmt(Node *stmt,
const char *queryString);
extern List * PreprocessAlterObjectSchemaStmt(Node *alterObjectSchemaStmt,
const char *alterObjectSchemaCommand);
extern void ProcessAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt,
const char *queryString);
/* sequence.c - forward declarations */
extern void ErrorIfUnsupportedSeqStmt(CreateSeqStmt *createSeqStmt);
@ -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,
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(RenameStmt *stmt, bool
missing_ok);
extern ObjectAddress * AlterTypeOwnerObjectAddress(AlterOwnerStmt *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 */

View File

@ -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,

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);