mirror of https://github.com/citusdata/citus.git
Introduce GetDistributeObjectOps to organize dispatch of logic dependent on node/object type
parent
22cc5b1240
commit
73c06fae3b
|
@ -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 */
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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")));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue