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"
|
#include "distributed/metadata_cache.h"
|
||||||
|
|
||||||
|
|
||||||
/* placeholder for PlanClusterStmt */
|
/* placeholder for PreprocessClusterStmt */
|
||||||
List *
|
List *
|
||||||
PlanClusterStmt(ClusterStmt *clusterStmt, const char *clusterCommand)
|
PreprocessClusterStmt(Node *node, const char *clusterCommand)
|
||||||
{
|
{
|
||||||
|
ClusterStmt *clusterStmt = castNode(ClusterStmt, node);
|
||||||
bool showPropagationWarning = false;
|
bool showPropagationWarning = false;
|
||||||
|
|
||||||
/* CLUSTER all */
|
/* CLUSTER all */
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/deparser.h"
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/master_metadata_utility.h"
|
#include "distributed/master_metadata_utility.h"
|
||||||
#include "distributed/metadata/distobject.h"
|
#include "distributed/metadata/distobject.h"
|
||||||
#include "distributed/metadata_sync.h"
|
#include "distributed/metadata_sync.h"
|
||||||
|
@ -163,14 +164,15 @@ CreateCollationDDLsIdempotent(Oid collationId)
|
||||||
|
|
||||||
|
|
||||||
ObjectAddress
|
ObjectAddress
|
||||||
AlterCollationOwnerObjectAddress(AlterOwnerStmt *stmt)
|
AlterCollationOwnerObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
Relation relation;
|
Relation relation;
|
||||||
|
|
||||||
Assert(stmt->objectType == OBJECT_COLLATION);
|
Assert(stmt->objectType == OBJECT_COLLATION);
|
||||||
|
|
||||||
return get_object_address(stmt->objectType, stmt->object, &relation,
|
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 *
|
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
|
* We swap the list of objects to remove during deparse so we need a reference back to
|
||||||
* the old list to put back
|
* the old list to put back
|
||||||
*/
|
*/
|
||||||
ListCell *addressCell = NULL;
|
|
||||||
List *distributedTypeAddresses = NIL;
|
List *distributedTypeAddresses = NIL;
|
||||||
|
|
||||||
if (!ShouldPropagate())
|
if (!ShouldPropagate())
|
||||||
|
@ -253,10 +256,10 @@ PlanDropCollationStmt(DropStmt *stmt)
|
||||||
/*
|
/*
|
||||||
* remove the entries for the distributed objects on dropping
|
* 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(addressItem);
|
||||||
UnmarkObjectDistributed(address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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.
|
* 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
|
* 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.
|
* the workers to keep the type in sync across the cluster.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanAlterCollationOwnerStmt(AlterOwnerStmt *stmt, const char *queryString)
|
PreprocessAlterCollationOwnerStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
Assert(stmt->objectType == OBJECT_COLLATION);
|
Assert(stmt->objectType == OBJECT_COLLATION);
|
||||||
|
|
||||||
ObjectAddress *collationAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
ObjectAddress collationAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
||||||
if (!ShouldPropagateObject(collationAddress))
|
if (!ShouldPropagateObject(&collationAddress))
|
||||||
{
|
{
|
||||||
return NIL;
|
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.
|
* before the statement is applied locally.
|
||||||
*
|
*
|
||||||
* As the collation already exists we have access to the ObjectAddress for the collation, this is
|
* 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.
|
* executed on all the workers to keep the collation in sync across the cluster.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanRenameCollationStmt(RenameStmt *stmt, const char *queryString)
|
PreprocessRenameCollationStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
ObjectAddress *collationAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
if (!ShouldPropagateObject(collationAddress))
|
ObjectAddress collationAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
||||||
|
if (!ShouldPropagateObject(&collationAddress))
|
||||||
{
|
{
|
||||||
return NIL;
|
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.
|
* postgres instance.
|
||||||
*
|
*
|
||||||
* In this stage we can prepare the commands that need to be run on all workers.
|
* In this stage we can prepare the commands that need to be run on all workers.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString)
|
PreprocessAlterCollationSchemaStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
Assert(stmt->objectType == OBJECT_COLLATION);
|
Assert(stmt->objectType == OBJECT_COLLATION);
|
||||||
|
|
||||||
ObjectAddress *collationAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
ObjectAddress collationAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
||||||
if (!ShouldPropagateObject(collationAddress))
|
if (!ShouldPropagateObject(&collationAddress))
|
||||||
{
|
{
|
||||||
return NIL;
|
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
|
* can now use the new dependencies of the type to ensure all its dependencies exist on
|
||||||
* the workers before we apply the commands remotely.
|
* the workers before we apply the commands remotely.
|
||||||
*/
|
*/
|
||||||
void
|
List *
|
||||||
ProcessAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString)
|
PostprocessAlterCollationSchemaStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
Assert(stmt->objectType == OBJECT_COLLATION);
|
Assert(stmt->objectType == OBJECT_COLLATION);
|
||||||
|
|
||||||
ObjectAddress *collationAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
ObjectAddress collationAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
||||||
if (!ShouldPropagateObject(collationAddress))
|
if (!ShouldPropagateObject(&collationAddress))
|
||||||
{
|
{
|
||||||
return;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dependencies have changed (schema) let's ensure they exist */
|
/* 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
|
* RenameCollationStmtObjectAddress returns the ObjectAddress of the type that is the object
|
||||||
* of the RenameStmt. Errors if missing_ok is false.
|
* of the RenameStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
RenameCollationStmtObjectAddress(RenameStmt *stmt, bool missing_ok)
|
RenameCollationStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
Assert(stmt->renameType == OBJECT_COLLATION);
|
Assert(stmt->renameType == OBJECT_COLLATION);
|
||||||
|
|
||||||
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
|
||||||
Oid collationOid = get_collation_oid((List *) stmt->object, missing_ok);
|
Oid collationOid = get_collation_oid((List *) stmt->object, missing_ok);
|
||||||
|
ObjectAddress address = { 0 };
|
||||||
|
ObjectAddressSet(address, CollationRelationId, collationOid);
|
||||||
|
|
||||||
ObjectAddressSet(*address, CollationRelationId, collationOid);
|
|
||||||
return address;
|
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
|
* new schema. Errors if missing_ok is false and the type cannot be found in either of the
|
||||||
* schemas.
|
* schemas.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
AlterCollationSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, bool missing_ok)
|
AlterCollationSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
Assert(stmt->objectType == OBJECT_COLLATION);
|
Assert(stmt->objectType == OBJECT_COLLATION);
|
||||||
|
|
||||||
List *name = (List *) stmt->object;
|
List *name = (List *) stmt->object;
|
||||||
|
@ -445,8 +456,8 @@ AlterCollationSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, bool missing_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
ObjectAddress address = { 0 };
|
||||||
ObjectAddressSet(*address, CollationRelationId, collationOid);
|
ObjectAddressSet(address, CollationRelationId, collationOid);
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,31 +555,31 @@ GenerateBackupNameForCollationCollision(const ObjectAddress *address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
DefineCollationStmtObjectAddress(DefineStmt *stmt, bool missing_ok)
|
DefineCollationStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
DefineStmt *stmt = castNode(DefineStmt, node);
|
||||||
Assert(stmt->kind == OBJECT_COLLATION);
|
Assert(stmt->kind == OBJECT_COLLATION);
|
||||||
|
|
||||||
Oid collOid = get_collation_oid(stmt->defnames, missing_ok);
|
Oid collOid = get_collation_oid(stmt->defnames, missing_ok);
|
||||||
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
ObjectAddress address = { 0 };
|
||||||
|
ObjectAddressSet(address, CollationRelationId, collOid);
|
||||||
ObjectAddressSet(*address, CollationRelationId, collOid);
|
|
||||||
|
|
||||||
return address;
|
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.
|
* 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
|
* created, we can mark it as distributed to make sure that its
|
||||||
* dependencies exist on all nodes.
|
* dependencies exist on all nodes.
|
||||||
*/
|
*/
|
||||||
List *
|
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())
|
if (!ShouldPropagate())
|
||||||
{
|
{
|
||||||
|
@ -584,18 +595,13 @@ ProcessCollationDefineStmt(DefineStmt *stmt, const char *queryString)
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress *collationAddress =
|
ObjectAddress collationAddress =
|
||||||
DefineCollationStmtObjectAddress(stmt, false);
|
DefineCollationStmtObjectAddress(node, false);
|
||||||
|
|
||||||
if (collationAddress->objectId == InvalidOid)
|
EnsureDependenciesExistOnAllNodes(&collationAddress);
|
||||||
{
|
|
||||||
return NIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
EnsureDependenciesExistsOnAllNodes(collationAddress);
|
MarkObjectDistributed(&collationAddress);
|
||||||
|
|
||||||
MarkObjectDistributed(collationAddress);
|
|
||||||
|
|
||||||
return NodeDDLTaskList(ALL_WORKERS, CreateCollationDDLsIdempotent(
|
return NodeDDLTaskList(ALL_WORKERS, CreateCollationDDLsIdempotent(
|
||||||
collationAddress->objectId));
|
collationAddress.objectId));
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ master_create_distributed_table(PG_FUNCTION_ARGS)
|
||||||
* sessions creating shards.
|
* sessions creating shards.
|
||||||
*/
|
*/
|
||||||
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
|
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
|
||||||
EnsureDependenciesExistsOnAllNodes(&tableAddress);
|
EnsureDependenciesExistOnAllNodes(&tableAddress);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lock target relation with an exclusive lock - there's no way to make
|
* 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.
|
* sessions creating shards.
|
||||||
*/
|
*/
|
||||||
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
|
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
|
||||||
EnsureDependenciesExistsOnAllNodes(&tableAddress);
|
EnsureDependenciesExistOnAllNodes(&tableAddress);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lock target relation with an exclusive lock - there's no way to make
|
* 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.
|
* sessions creating shards.
|
||||||
*/
|
*/
|
||||||
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
|
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
|
||||||
EnsureDependenciesExistsOnAllNodes(&tableAddress);
|
EnsureDependenciesExistOnAllNodes(&tableAddress);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lock target relation with an exclusive lock - there's no way to make
|
* Lock target relation with an exclusive lock - there's no way to make
|
||||||
|
|
|
@ -24,16 +24,17 @@
|
||||||
#include "storage/lmgr.h"
|
#include "storage/lmgr.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
|
typedef bool (*AddressPredicate)(const ObjectAddress *);
|
||||||
|
|
||||||
static List * GetDependencyCreateDDLCommands(const ObjectAddress *dependency);
|
static List * GetDependencyCreateDDLCommands(const ObjectAddress *dependency);
|
||||||
static List * FilterObjectAddressListByPredicate(List *objectAddressList,
|
static List * FilterObjectAddressListByPredicate(List *objectAddressList,
|
||||||
bool (*predicate)(const
|
AddressPredicate predicate);
|
||||||
ObjectAddress *));
|
|
||||||
|
|
||||||
bool EnableDependencyCreation = true;
|
bool EnableDependencyCreation = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* EnsureDependenciesExists finds all the dependencies that we support and makes sure
|
* EnsureDependenciesExistOnAllNodes finds all the dependencies that we support and makes
|
||||||
* these are available on all workers. If not available they will be created on the
|
* 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
|
* workers via a separate session that will be committed directly so that the objects are
|
||||||
* visible to potentially multiple sessions creating the shards.
|
* 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.
|
* postgres native CREATE IF NOT EXISTS, or citus helper functions.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
EnsureDependenciesExistsOnAllNodes(const ObjectAddress *target)
|
EnsureDependenciesExistOnAllNodes(const ObjectAddress *target)
|
||||||
{
|
{
|
||||||
/* local variables to work with dependencies */
|
/* local variables to work with dependencies */
|
||||||
List *dependenciesWithCommands = NIL;
|
List *dependenciesWithCommands = NIL;
|
||||||
|
@ -324,8 +325,7 @@ ShouldPropagateObject(const ObjectAddress *address)
|
||||||
* only containing the ObjectAddress *'s for which the predicate returned true.
|
* only containing the ObjectAddress *'s for which the predicate returned true.
|
||||||
*/
|
*/
|
||||||
static List *
|
static List *
|
||||||
FilterObjectAddressListByPredicate(List *objectAddressList,
|
FilterObjectAddressListByPredicate(List *objectAddressList, AddressPredicate predicate)
|
||||||
bool (*predicate)(const ObjectAddress *))
|
|
||||||
{
|
{
|
||||||
List *result = NIL;
|
List *result = NIL;
|
||||||
ListCell *objectAddressListCell = NULL;
|
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.
|
* PostprocessCreateExtensionStmt is called after the creation of an extension.
|
||||||
* It is executed before the statement is applied locally.
|
|
||||||
* We decide if the extension needs to be replicated to the worker, and
|
* 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
|
* if that is the case return a list of DDLJob's that describe how and
|
||||||
* where the extension needs to be created.
|
* 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 *
|
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;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -161,9 +166,9 @@ PlanCreateExtensionStmt(CreateExtensionStmt *createExtensionStmt, const char *qu
|
||||||
* Here we append "schema" field to the "options" list (if not specified)
|
* Here we append "schema" field to the "options" list (if not specified)
|
||||||
* to satisfy the schema consistency between worker nodes and the coordinator.
|
* 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
|
* To prevent recursive propagation in mx architecture, we disable ddl
|
||||||
|
@ -173,6 +178,12 @@ PlanCreateExtensionStmt(CreateExtensionStmt *createExtensionStmt, const char *qu
|
||||||
(void *) createExtensionStmtSql,
|
(void *) createExtensionStmtSql,
|
||||||
ENABLE_DDL_PROPAGATION);
|
ENABLE_DDL_PROPAGATION);
|
||||||
|
|
||||||
|
ObjectAddress extensionAddress = GetObjectAddressFromParseTree(node, false);
|
||||||
|
|
||||||
|
EnsureDependenciesExistOnAllNodes(&extensionAddress);
|
||||||
|
|
||||||
|
MarkObjectDistributed(&extensionAddress);
|
||||||
|
|
||||||
return NodeDDLTaskList(ALL_WORKERS, commands);
|
return NodeDDLTaskList(ALL_WORKERS, commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,42 +225,7 @@ AddSchemaFieldIfMissing(CreateExtensionStmt *createExtensionStmt)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ProcessCreateExtensionStmt is executed after the extension has been
|
* PreprocessDropExtensionStmt is called to drop extension(s) in coordinator and
|
||||||
* 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
|
|
||||||
* in worker nodes if distributed before.
|
* in worker nodes if distributed before.
|
||||||
* We first ensure that we keep only the distributed ones before propagating
|
* We first ensure that we keep only the distributed ones before propagating
|
||||||
* the statement to worker nodes.
|
* the statement to worker nodes.
|
||||||
|
@ -257,19 +233,18 @@ ProcessCreateExtensionStmt(CreateExtensionStmt *createExtensionStmt, const
|
||||||
* be made to the workers.
|
* be made to the workers.
|
||||||
*/
|
*/
|
||||||
List *
|
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;
|
ListCell *addressCell = NULL;
|
||||||
|
|
||||||
if (!ShouldPropagateExtensionCommand((Node *) dropStmt))
|
if (!ShouldPropagateExtensionCommand(node))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get distributed extensions to be dropped in worker nodes as well */
|
/* get distributed extensions to be dropped in worker nodes as well */
|
||||||
|
List *allDroppedExtensions = stmt->objects;
|
||||||
List *distributedExtensions = FilterDistributedExtensions(allDroppedExtensions);
|
List *distributedExtensions = FilterDistributedExtensions(allDroppedExtensions);
|
||||||
|
|
||||||
if (list_length(distributedExtensions) <= 0)
|
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
|
* Temporary swap the lists of objects to delete with the distributed
|
||||||
* objects and deparse to an sql statement for the workers.
|
* objects and deparse to an sql statement for the workers.
|
||||||
* Then switch back to allDroppedExtensions to drop all specified
|
* Then switch back to allDroppedExtensions to drop all specified
|
||||||
* extensions in coordinator after PlanDropExtensionStmt completes
|
* extensions in coordinator after PreprocessDropExtensionStmt completes
|
||||||
* its execution.
|
* its execution.
|
||||||
*/
|
*/
|
||||||
dropStmt->objects = distributedExtensions;
|
stmt->objects = distributedExtensions;
|
||||||
const char *deparsedStmt = DeparseTreeNode((Node *) dropStmt);
|
const char *deparsedStmt = DeparseTreeNode((Node *) stmt);
|
||||||
|
|
||||||
dropStmt->objects = allDroppedExtensions;
|
stmt->objects = allDroppedExtensions;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To prevent recursive propagation in mx architecture, we disable ddl
|
* To prevent recursive propagation in mx architecture, we disable ddl
|
||||||
|
@ -348,8 +323,6 @@ FilterDistributedExtensions(List *extensionObjectList)
|
||||||
{
|
{
|
||||||
char *extensionName = strVal(lfirst(objectCell));
|
char *extensionName = strVal(lfirst(objectCell));
|
||||||
|
|
||||||
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
|
||||||
|
|
||||||
Oid extensionOid = get_extension_oid(extensionName, missingOk);
|
Oid extensionOid = get_extension_oid(extensionName, missingOk);
|
||||||
|
|
||||||
if (!OidIsValid(extensionOid))
|
if (!OidIsValid(extensionOid))
|
||||||
|
@ -357,9 +330,10 @@ FilterDistributedExtensions(List *extensionObjectList)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddressSet(*address, ExtensionRelationId, extensionOid);
|
ObjectAddress address = { 0 };
|
||||||
|
ObjectAddressSet(address, ExtensionRelationId, extensionOid);
|
||||||
|
|
||||||
if (!IsObjectDistributed(address))
|
if (!IsObjectDistributed(&address))
|
||||||
{
|
{
|
||||||
continue;
|
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 *
|
List *
|
||||||
PlanAlterExtensionSchemaStmt(AlterObjectSchemaStmt *alterExtensionStmt, const
|
PreprocessAlterExtensionSchemaStmt(Node *node, const char *queryString)
|
||||||
char *queryString)
|
|
||||||
{
|
{
|
||||||
if (!ShouldPropagateExtensionCommand((Node *) alterExtensionStmt))
|
if (!ShouldPropagateExtensionCommand(node))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -437,7 +410,7 @@ PlanAlterExtensionSchemaStmt(AlterObjectSchemaStmt *alterExtensionStmt, const
|
||||||
*/
|
*/
|
||||||
EnsureSequentialModeForExtensionDDL();
|
EnsureSequentialModeForExtensionDDL();
|
||||||
|
|
||||||
const char *alterExtensionStmtSql = DeparseTreeNode((Node *) alterExtensionStmt);
|
const char *alterExtensionStmtSql = DeparseTreeNode(node);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To prevent recursive propagation in mx architecture, we disable ddl
|
* 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
|
* 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.
|
* all its dependencies exist on the workers before we apply the commands remotely.
|
||||||
*/
|
*/
|
||||||
void
|
List *
|
||||||
ProcessAlterExtensionSchemaStmt(AlterObjectSchemaStmt *alterExtensionStmt, const
|
PostprocessAlterExtensionSchemaStmt(Node *node, const char *queryString)
|
||||||
char *queryString)
|
|
||||||
{
|
{
|
||||||
const ObjectAddress *extensionAddress = GetObjectAddressFromParseTree(
|
ObjectAddress extensionAddress = GetObjectAddressFromParseTree(node, false);
|
||||||
(Node *) alterExtensionStmt, false);
|
|
||||||
|
|
||||||
if (!ShouldPropagateExtensionCommand((Node *) alterExtensionStmt))
|
if (!ShouldPropagateExtensionCommand(node))
|
||||||
{
|
{
|
||||||
return;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dependencies (schema) have changed let's ensure they exist */
|
/* 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 *
|
List *
|
||||||
PlanAlterExtensionUpdateStmt(AlterExtensionStmt *alterExtensionStmt, const
|
PreprocessAlterExtensionUpdateStmt(Node *node, const char *queryString)
|
||||||
char *queryString)
|
|
||||||
{
|
{
|
||||||
|
AlterExtensionStmt *alterExtensionStmt = castNode(AlterExtensionStmt, node);
|
||||||
if (!ShouldPropagateExtensionCommand((Node *) alterExtensionStmt))
|
if (!ShouldPropagateExtensionCommand((Node *) alterExtensionStmt))
|
||||||
{
|
{
|
||||||
return NIL;
|
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
|
* 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
|
* 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
|
* AlterExtensionSchemaStmtObjectAddress returns the ObjectAddress of the extension that is
|
||||||
* the subject of the AlterObjectSchemaStmt. Errors if missing_ok is false.
|
* the subject of the AlterObjectSchemaStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
AlterExtensionSchemaStmtObjectAddress(AlterObjectSchemaStmt *alterExtensionSchemaStmt,
|
AlterExtensionSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
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);
|
Oid extensionOid = get_extension_oid(extensionName, missing_ok);
|
||||||
|
|
||||||
|
@ -770,10 +758,10 @@ AlterExtensionSchemaStmtObjectAddress(AlterObjectSchemaStmt *alterExtensionSchem
|
||||||
extensionName)));
|
extensionName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress *extensionAddress = palloc0(sizeof(ObjectAddress));
|
ObjectAddress address = { 0 };
|
||||||
ObjectAddressSet(*extensionAddress, ExtensionRelationId, extensionOid);
|
ObjectAddressSet(address, ExtensionRelationId, extensionOid);
|
||||||
|
|
||||||
return extensionAddress;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -781,11 +769,11 @@ AlterExtensionSchemaStmtObjectAddress(AlterObjectSchemaStmt *alterExtensionSchem
|
||||||
* AlterExtensionUpdateStmtObjectAddress returns the ObjectAddress of the extension that is
|
* AlterExtensionUpdateStmtObjectAddress returns the ObjectAddress of the extension that is
|
||||||
* the subject of the AlterExtensionStmt. Errors if missing_ok is false.
|
* the subject of the AlterExtensionStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
AlterExtensionUpdateStmtObjectAddress(AlterExtensionStmt *alterExtensionStmt,
|
AlterExtensionUpdateStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
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);
|
Oid extensionOid = get_extension_oid(extensionName, missing_ok);
|
||||||
|
|
||||||
|
@ -796,8 +784,8 @@ AlterExtensionUpdateStmtObjectAddress(AlterExtensionStmt *alterExtensionStmt,
|
||||||
extensionName)));
|
extensionName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress *extensionAddress = palloc0(sizeof(ObjectAddress));
|
ObjectAddress address = { 0 };
|
||||||
ObjectAddressSet(*extensionAddress, ExtensionRelationId, extensionOid);
|
ObjectAddressSet(address, ExtensionRelationId, extensionOid);
|
||||||
|
|
||||||
return extensionAddress;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,9 +75,9 @@ static void EnsureSequentialModeForFunctionDDL(void);
|
||||||
static void TriggerSyncMetadataToPrimaryNodes(void);
|
static void TriggerSyncMetadataToPrimaryNodes(void);
|
||||||
static bool ShouldPropagateCreateFunction(CreateFunctionStmt *stmt);
|
static bool ShouldPropagateCreateFunction(CreateFunctionStmt *stmt);
|
||||||
static bool ShouldPropagateAlterFunction(const ObjectAddress *address);
|
static bool ShouldPropagateAlterFunction(const ObjectAddress *address);
|
||||||
static ObjectAddress * FunctionToObjectAddress(ObjectType objectType,
|
static ObjectAddress FunctionToObjectAddress(ObjectType objectType,
|
||||||
ObjectWithArgs *objectWithArgs,
|
ObjectWithArgs *objectWithArgs,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
static void ErrorIfUnsupportedAlterFunctionStmt(AlterFunctionStmt *stmt);
|
static void ErrorIfUnsupportedAlterFunctionStmt(AlterFunctionStmt *stmt);
|
||||||
static void ErrorIfFunctionDependsOnExtension(const ObjectAddress *functionAddress);
|
static void ErrorIfFunctionDependsOnExtension(const ObjectAddress *functionAddress);
|
||||||
static char * quote_qualified_func_name(Oid funcOid);
|
static char * quote_qualified_func_name(Oid funcOid);
|
||||||
|
@ -155,7 +155,7 @@ create_distributed_function(PG_FUNCTION_ARGS)
|
||||||
*/
|
*/
|
||||||
EnsureSequentialModeForFunctionDDL();
|
EnsureSequentialModeForFunctionDDL();
|
||||||
|
|
||||||
EnsureDependenciesExistsOnAllNodes(&functionAddress);
|
EnsureDependenciesExistOnAllNodes(&functionAddress);
|
||||||
|
|
||||||
const char *createFunctionSQL = GetFunctionDDLCommand(funcOid, true);
|
const char *createFunctionSQL = GetFunctionDDLCommand(funcOid, true);
|
||||||
const char *alterFunctionOwnerSQL = GetFunctionAlterOwnerCommand(funcOid);
|
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
|
* Even though its a replace we should accept an non-existing function, it will just
|
||||||
* not be distributed
|
* not be distributed
|
||||||
*/
|
*/
|
||||||
const ObjectAddress *address = GetObjectAddressFromParseTree((Node *) stmt, true);
|
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, true);
|
||||||
if (!IsObjectDistributed(address))
|
if (!IsObjectDistributed(&address))
|
||||||
{
|
{
|
||||||
/* do not propagate alter function for non-distributed functions */
|
/* do not propagate alter function for non-distributed functions */
|
||||||
return false;
|
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
|
* FUNCTION. We primarily care for the replace variant of this statement to keep
|
||||||
* distributed functions in sync. We bail via a check on ShouldPropagateCreateFunction
|
* distributed functions in sync. We bail via a check on ShouldPropagateCreateFunction
|
||||||
* which checks for the OR REPLACE modifier.
|
* which checks for the OR REPLACE modifier.
|
||||||
|
@ -1156,8 +1156,10 @@ ShouldPropagateAlterFunction(const ObjectAddress *address)
|
||||||
* can propagate the function in sequential mode.
|
* can propagate the function in sequential mode.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanCreateFunctionStmt(CreateFunctionStmt *stmt, const char *queryString)
|
PreprocessCreateFunctionStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
CreateFunctionStmt *stmt = castNode(CreateFunctionStmt, node);
|
||||||
|
|
||||||
if (!ShouldPropagateCreateFunction(stmt))
|
if (!ShouldPropagateCreateFunction(stmt))
|
||||||
{
|
{
|
||||||
return NIL;
|
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.
|
* 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
|
* Besides creating the plan we also make sure all (new) dependencies of the function are
|
||||||
* created on all nodes.
|
* created on all nodes.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
ProcessCreateFunctionStmt(CreateFunctionStmt *stmt, const char *queryString)
|
PostprocessCreateFunctionStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
CreateFunctionStmt *stmt = castNode(CreateFunctionStmt, node);
|
||||||
|
|
||||||
if (!ShouldPropagateCreateFunction(stmt))
|
if (!ShouldPropagateCreateFunction(stmt))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ObjectAddress *address = GetObjectAddressFromParseTree((Node *) stmt, false);
|
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, false);
|
||||||
EnsureDependenciesExistsOnAllNodes(address);
|
EnsureDependenciesExistOnAllNodes(&address);
|
||||||
|
|
||||||
List *commands = list_make4(DISABLE_DDL_PROPAGATION,
|
List *commands = list_make4(DISABLE_DDL_PROPAGATION,
|
||||||
GetFunctionDDLCommand(address->objectId, true),
|
GetFunctionDDLCommand(address.objectId, true),
|
||||||
GetFunctionAlterOwnerCommand(address->objectId),
|
GetFunctionAlterOwnerCommand(address.objectId),
|
||||||
ENABLE_DDL_PROPAGATION);
|
ENABLE_DDL_PROPAGATION);
|
||||||
|
|
||||||
return NodeDDLTaskList(ALL_WORKERS, commands);
|
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
|
* CREATE [OR REPLACE] FUNCTION statement. If missing_ok is false it will error with the
|
||||||
* normal postgres error for unfound functions.
|
* normal postgres error for unfound functions.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
CreateFunctionStmtObjectAddress(CreateFunctionStmt *stmt, bool missing_ok)
|
CreateFunctionStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
CreateFunctionStmt *stmt = castNode(CreateFunctionStmt, node);
|
||||||
ObjectType objectType = OBJECT_FUNCTION;
|
ObjectType objectType = OBJECT_FUNCTION;
|
||||||
ListCell *parameterCell = NULL;
|
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
|
* by the DefineStmtObjectAddress. If missing_ok is false this function throws an error if the
|
||||||
* aggregate does not exist.
|
* aggregate does not exist.
|
||||||
*
|
*
|
||||||
* Never returns NULL, but the objid in the address could be invalid if missing_ok was set
|
* objectId in the address can be invalid if missing_ok was set to true.
|
||||||
* to true.
|
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
DefineAggregateStmtObjectAddress(DefineStmt *stmt, bool missing_ok)
|
DefineAggregateStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
DefineStmt *stmt = castNode(DefineStmt, node);
|
||||||
ListCell *parameterCell = NULL;
|
ListCell *parameterCell = NULL;
|
||||||
|
|
||||||
Assert(stmt->kind == OBJECT_AGGREGATE);
|
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
|
* plan the jobs to be executed on the workers for functions that have been distributed in
|
||||||
* the cluster.
|
* the cluster.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanAlterFunctionStmt(AlterFunctionStmt *stmt, const char *queryString)
|
PreprocessAlterFunctionStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
AlterFunctionStmt *stmt = castNode(AlterFunctionStmt, node);
|
||||||
AssertObjectTypeIsFunctional(stmt->objtype);
|
AssertObjectTypeIsFunctional(stmt->objtype);
|
||||||
|
|
||||||
const ObjectAddress *address = GetObjectAddressFromParseTree((Node *) stmt, false);
|
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, false);
|
||||||
if (!ShouldPropagateAlterFunction(address))
|
if (!ShouldPropagateAlterFunction(&address))
|
||||||
{
|
{
|
||||||
return NIL;
|
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.
|
* happens before the statement is applied locally.
|
||||||
*
|
*
|
||||||
* As the function already exists we have access to the ObjectAddress, this is used to
|
* 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.
|
* types in sync across the cluster.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanRenameFunctionStmt(RenameStmt *stmt, const char *queryString)
|
PreprocessRenameFunctionStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
AssertObjectTypeIsFunctional(stmt->renameType);
|
AssertObjectTypeIsFunctional(stmt->renameType);
|
||||||
|
|
||||||
const ObjectAddress *address = GetObjectAddressFromParseTree((Node *) stmt, false);
|
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, false);
|
||||||
if (!ShouldPropagateAlterFunction(address))
|
if (!ShouldPropagateAlterFunction(&address))
|
||||||
{
|
{
|
||||||
return NIL;
|
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.
|
* postgres instance.
|
||||||
*
|
*
|
||||||
* In this stage we can prepare the commands that need to be run on all workers.
|
* In this stage we can prepare the commands that need to be run on all workers.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString)
|
PreprocessAlterFunctionSchemaStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
AssertObjectTypeIsFunctional(stmt->objectType);
|
AssertObjectTypeIsFunctional(stmt->objectType);
|
||||||
|
|
||||||
const ObjectAddress *address = GetObjectAddressFromParseTree((Node *) stmt, false);
|
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, false);
|
||||||
if (!ShouldPropagateAlterFunction(address))
|
if (!ShouldPropagateAlterFunction(&address))
|
||||||
{
|
{
|
||||||
return NIL;
|
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.
|
* ship is changed on the local instance.
|
||||||
*
|
*
|
||||||
* If the function for which the owner is changed is distributed we execute the change on
|
* 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.
|
* all the workers to keep the type in sync across the cluster.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanAlterFunctionOwnerStmt(AlterOwnerStmt *stmt, const char *queryString)
|
PreprocessAlterFunctionOwnerStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
AssertObjectTypeIsFunctional(stmt->objectType);
|
AssertObjectTypeIsFunctional(stmt->objectType);
|
||||||
|
|
||||||
const ObjectAddress *address = GetObjectAddressFromParseTree((Node *) stmt, false);
|
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, false);
|
||||||
if (!ShouldPropagateAlterFunction(address))
|
if (!ShouldPropagateAlterFunction(&address))
|
||||||
{
|
{
|
||||||
return NIL;
|
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
|
* and returns a list of DDLJob's that will drop any distributed functions from the
|
||||||
* workers.
|
* workers.
|
||||||
*
|
*
|
||||||
|
@ -1392,8 +1401,9 @@ PlanAlterFunctionOwnerStmt(AlterOwnerStmt *stmt, const char *queryString)
|
||||||
* functions will still be dropped locally but not on the workers.
|
* functions will still be dropped locally but not on the workers.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanDropFunctionStmt(DropStmt *stmt, const char *queryString)
|
PreprocessDropFunctionStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
DropStmt *stmt = castNode(DropStmt, node);
|
||||||
List *deletingObjectWithArgsList = stmt->objects;
|
List *deletingObjectWithArgsList = stmt->objects;
|
||||||
List *distributedObjectWithArgsList = NIL;
|
List *distributedObjectWithArgsList = NIL;
|
||||||
List *distributedFunctionAddresses = NIL;
|
List *distributedFunctionAddresses = NIL;
|
||||||
|
@ -1433,16 +1443,18 @@ PlanDropFunctionStmt(DropStmt *stmt, const char *queryString)
|
||||||
foreach(objectWithArgsListCell, deletingObjectWithArgsList)
|
foreach(objectWithArgsListCell, deletingObjectWithArgsList)
|
||||||
{
|
{
|
||||||
ObjectWithArgs *func = castNode(ObjectWithArgs, lfirst(objectWithArgsListCell));
|
ObjectWithArgs *func = castNode(ObjectWithArgs, lfirst(objectWithArgsListCell));
|
||||||
ObjectAddress *address = FunctionToObjectAddress(stmt->removeType, func,
|
ObjectAddress address = FunctionToObjectAddress(stmt->removeType, func,
|
||||||
stmt->missing_ok);
|
stmt->missing_ok);
|
||||||
|
|
||||||
if (!IsObjectDistributed(address))
|
if (!IsObjectDistributed(&address))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* collect information for all distributed functions */
|
/* 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);
|
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
|
* 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
|
* extensions are assumed to be Owned by an extension we assume the extension to keep the
|
||||||
* function in sync.
|
* function in sync.
|
||||||
|
@ -1495,8 +1507,9 @@ PlanDropFunctionStmt(DropStmt *stmt, const char *queryString)
|
||||||
* don't allow this dependency to be created.
|
* don't allow this dependency to be created.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt, const char *queryString)
|
PreprocessAlterFunctionDependsStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
AlterObjectDependsStmt *stmt = castNode(AlterObjectDependsStmt, node);
|
||||||
AssertObjectTypeIsFunctional(stmt->objectType);
|
AssertObjectTypeIsFunctional(stmt->objectType);
|
||||||
|
|
||||||
if (creating_extension)
|
if (creating_extension)
|
||||||
|
@ -1516,8 +1529,8 @@ PlanAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt, const char *queryStri
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ObjectAddress *address = GetObjectAddressFromParseTree((Node *) stmt, true);
|
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, true);
|
||||||
if (!IsObjectDistributed(address))
|
if (!IsObjectDistributed(&address))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -1528,7 +1541,7 @@ PlanAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt, const char *queryStri
|
||||||
* workers
|
* workers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const char *functionName = getObjectIdentity(address);
|
const char *functionName = getObjectIdentity(&address);
|
||||||
ereport(ERROR, (errmsg("distrtibuted functions are not allowed to depend on an "
|
ereport(ERROR, (errmsg("distrtibuted functions are not allowed to depend on an "
|
||||||
"extension"),
|
"extension"),
|
||||||
errdetail("Function \"%s\" is already distributed. Functions from "
|
errdetail("Function \"%s\" is already distributed. Functions from "
|
||||||
|
@ -1542,9 +1555,10 @@ PlanAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt, const char *queryStri
|
||||||
* is the subject of an ALTER FUNCTION ... DEPENS ON EXTENSION ... statement. If
|
* is the subject of an ALTER FUNCTION ... DEPENS ON EXTENSION ... statement. If
|
||||||
* missing_ok is set to false the lookup will raise an error.
|
* missing_ok is set to false the lookup will raise an error.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
AlterFunctionDependsStmtObjectAddress(AlterObjectDependsStmt *stmt, bool missing_ok)
|
AlterFunctionDependsStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
AlterObjectDependsStmt *stmt = castNode(AlterObjectDependsStmt, node);
|
||||||
AssertObjectTypeIsFunctional(stmt->objectType);
|
AssertObjectTypeIsFunctional(stmt->objectType);
|
||||||
|
|
||||||
return FunctionToObjectAddress(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
|
* 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.
|
* exist on the workers before we apply the commands remotely.
|
||||||
*/
|
*/
|
||||||
void
|
List *
|
||||||
ProcessAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString)
|
PostprocessAlterFunctionSchemaStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
AssertObjectTypeIsFunctional(stmt->objectType);
|
AssertObjectTypeIsFunctional(stmt->objectType);
|
||||||
|
|
||||||
const ObjectAddress *address = GetObjectAddressFromParseTree((Node *) stmt, false);
|
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, false);
|
||||||
if (!ShouldPropagateAlterFunction(address))
|
if (!ShouldPropagateAlterFunction(&address))
|
||||||
{
|
{
|
||||||
return;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dependencies have changed (schema) let's ensure they exist */
|
/* 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
|
* AlterFunctionStmt. If missing_ok is set to false an error will be raised if postgres
|
||||||
* was unable to find the function/procedure that was the target of the statement.
|
* was unable to find the function/procedure that was the target of the statement.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
AlterFunctionStmtObjectAddress(AlterFunctionStmt *stmt, bool missing_ok)
|
AlterFunctionStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
AlterFunctionStmt *stmt = castNode(AlterFunctionStmt, node);
|
||||||
return FunctionToObjectAddress(stmt->objtype, stmt->func, missing_ok);
|
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
|
* RenameFunctionStmtObjectAddress returns the ObjectAddress of the function that is the
|
||||||
* subject of the RenameStmt. Errors if missing_ok is false.
|
* subject of the RenameStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
RenameFunctionStmtObjectAddress(RenameStmt *stmt, bool missing_ok)
|
RenameFunctionStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
return FunctionToObjectAddress(stmt->renameType,
|
return FunctionToObjectAddress(stmt->renameType,
|
||||||
castNode(ObjectWithArgs, stmt->object), missing_ok);
|
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
|
* AlterFunctionOwnerObjectAddress returns the ObjectAddress of the function that is the
|
||||||
* subject of the AlterOwnerStmt. Errors if missing_ok is false.
|
* subject of the AlterOwnerStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
AlterFunctionOwnerObjectAddress(AlterOwnerStmt *stmt, bool missing_ok)
|
AlterFunctionOwnerObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
return FunctionToObjectAddress(stmt->objectType,
|
return FunctionToObjectAddress(stmt->objectType,
|
||||||
castNode(ObjectWithArgs, stmt->object), missing_ok);
|
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 new schema. Errors if missing_ok is false and the type cannot be found in either of
|
||||||
* the schemas.
|
* the schemas.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
AlterFunctionSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, bool missing_ok)
|
AlterFunctionSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
AssertObjectTypeIsFunctional(stmt->objectType);
|
AssertObjectTypeIsFunctional(stmt->objectType);
|
||||||
|
|
||||||
ObjectWithArgs *objectWithArgs = castNode(ObjectWithArgs, stmt->object);
|
ObjectWithArgs *objectWithArgs = castNode(ObjectWithArgs, stmt->object);
|
||||||
|
@ -1662,8 +1683,8 @@ AlterFunctionSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, bool missing_o
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
ObjectAddress address = { 0 };
|
||||||
ObjectAddressSet(*address, ProcedureRelationId, funcOid);
|
ObjectAddressSet(address, ProcedureRelationId, funcOid);
|
||||||
|
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
@ -1780,15 +1801,15 @@ ObjectWithArgsFromOid(Oid funcOid)
|
||||||
* false an error will be raised by postgres explaining the Function/Procedure could not
|
* false an error will be raised by postgres explaining the Function/Procedure could not
|
||||||
* be found.
|
* be found.
|
||||||
*/
|
*/
|
||||||
static ObjectAddress *
|
static ObjectAddress
|
||||||
FunctionToObjectAddress(ObjectType objectType, ObjectWithArgs *objectWithArgs,
|
FunctionToObjectAddress(ObjectType objectType, ObjectWithArgs *objectWithArgs,
|
||||||
bool missing_ok)
|
bool missing_ok)
|
||||||
{
|
{
|
||||||
AssertObjectTypeIsFunctional(objectType);
|
AssertObjectTypeIsFunctional(objectType);
|
||||||
|
|
||||||
Oid funcOid = LookupFuncWithArgs(objectType, objectWithArgs, missing_ok);
|
Oid funcOid = LookupFuncWithArgs(objectType, objectWithArgs, missing_ok);
|
||||||
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
ObjectAddress address = { 0 };
|
||||||
ObjectAddressSet(*address, ProcedureRelationId, funcOid);
|
ObjectAddressSet(address, ProcedureRelationId, funcOid);
|
||||||
|
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,9 @@
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
|
|
||||||
|
|
||||||
/* placeholder for PlanGrantStmt */
|
/* placeholder for PreprocessGrantStmt */
|
||||||
List *
|
List *
|
||||||
PlanGrantStmt(GrantStmt *grantStmt)
|
PreprocessGrantStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
return NIL;
|
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
|
* a distributed table. If so (and if the statement does not use unsupported
|
||||||
* options), it modifies the input statement to ensure proper execution against
|
* options), it modifies the input statement to ensure proper execution against
|
||||||
* the master node table and creates a DDLJob to encapsulate information needed
|
* 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.
|
* in a List. If no distributed table is involved, this function returns NIL.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanIndexStmt(IndexStmt *createIndexStatement, const char *createIndexCommand)
|
PreprocessIndexStmt(Node *node, const char *createIndexCommand)
|
||||||
{
|
{
|
||||||
|
IndexStmt *createIndexStatement = castNode(IndexStmt, node);
|
||||||
List *ddlJobs = NIL;
|
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
|
* a distributed table. If so (and if the statement does not use unsupported
|
||||||
* options), it modifies the input statement to ensure proper execution against
|
* options), it modifies the input statement to ensure proper execution against
|
||||||
* the master node table and creates a DDLJob to encapsulate information needed
|
* 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.
|
* in a List. If no distributed table is involved, this function returns NIL.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanReindexStmt(ReindexStmt *reindexStatement, const char *reindexCommand)
|
PreprocessReindexStmt(Node *node, const char *reindexCommand)
|
||||||
{
|
{
|
||||||
|
ReindexStmt *reindexStatement = castNode(ReindexStmt, node);
|
||||||
List *ddlJobs = NIL;
|
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
|
* a distributed table. If so (and if the statement does not use unsupported
|
||||||
* options), it modifies the input statement to ensure proper execution against
|
* options), it modifies the input statement to ensure proper execution against
|
||||||
* the master node table and creates a DDLJob to encapsulate information needed
|
* 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.
|
* in a List. If no distributed table is involved, this function returns NIL.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanDropIndexStmt(DropStmt *dropIndexStatement, const char *dropIndexCommand)
|
PreprocessDropIndexStmt(Node *node, const char *dropIndexCommand)
|
||||||
{
|
{
|
||||||
|
DropStmt *dropIndexStatement = castNode(DropStmt, node);
|
||||||
List *ddlJobs = NIL;
|
List *ddlJobs = NIL;
|
||||||
ListCell *dropObjectCell = NULL;
|
ListCell *dropObjectCell = NULL;
|
||||||
Oid distributedIndexId = InvalidOid;
|
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
|
* CONCURRENTLY flag. This (non-transactional) change provides the fallback
|
||||||
* state if an error is raised, otherwise a sub-sequent change to valid will be
|
* state if an error is raised, otherwise a sub-sequent change to valid will be
|
||||||
* committed.
|
* committed.
|
||||||
*/
|
*/
|
||||||
void
|
List *
|
||||||
PostProcessIndexStmt(IndexStmt *indexStmt)
|
PostprocessIndexStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
IndexStmt *indexStmt = castNode(IndexStmt, node);
|
||||||
|
|
||||||
/* we are only processing CONCURRENT index statements */
|
/* we are only processing CONCURRENT index statements */
|
||||||
if (!indexStmt->concurrent)
|
if (!indexStmt->concurrent)
|
||||||
{
|
{
|
||||||
return;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this logic only applies to the coordinator */
|
/* this logic only applies to the coordinator */
|
||||||
if (!IsCoordinator())
|
if (!IsCoordinator())
|
||||||
{
|
{
|
||||||
return;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* commit the current transaction and start anew */
|
/* 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 */
|
/* clean up; index now marked valid, but ROLLBACK will mark invalid */
|
||||||
heap_freetuple(indexTuple);
|
heap_freetuple(indexTuple);
|
||||||
heap_close(pg_index, RowExclusiveLock);
|
heap_close(pg_index, RowExclusiveLock);
|
||||||
|
|
||||||
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,11 @@ CreatePolicyCommands(Oid relationId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* placeholder for PlanCreatePolicyStmt */
|
/* placeholder for PreprocessCreatePolicyStmt */
|
||||||
List *
|
List *
|
||||||
PlanCreatePolicyStmt(CreatePolicyStmt *stmt)
|
PreprocessCreatePolicyStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
CreatePolicyStmt *stmt = castNode(CreatePolicyStmt, node);
|
||||||
Oid relationId = RangeVarGetRelid(stmt->table,
|
Oid relationId = RangeVarGetRelid(stmt->table,
|
||||||
AccessExclusiveLock,
|
AccessExclusiveLock,
|
||||||
false);
|
false);
|
||||||
|
@ -45,9 +46,9 @@ PlanCreatePolicyStmt(CreatePolicyStmt *stmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* placeholder for PlanAlterPolicyStmt */
|
/* placeholder for PreprocessAlterPolicyStmt */
|
||||||
List *
|
List *
|
||||||
PlanAlterPolicyStmt(AlterPolicyStmt *stmt)
|
PreprocessAlterPolicyStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
/* placeholder for future implementation */
|
/* placeholder for future implementation */
|
||||||
return NIL;
|
return NIL;
|
||||||
|
@ -76,9 +77,9 @@ ErrorIfUnsupportedPolicyExpr(Node *expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* placeholder for PlanDropPolicyStmt */
|
/* placeholder for PreprocessDropPolicyStmt */
|
||||||
List *
|
List *
|
||||||
PlanDropPolicyStmt(DropStmt *stmt, const char *queryString)
|
PreprocessDropPolicyStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
/* placeholder for future implementation */
|
/* placeholder for future implementation */
|
||||||
return NIL;
|
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),
|
* 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
|
* 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-
|
* portion of DDL execution before returning that DDLJob in a List. If no dis-
|
||||||
* tributed table is involved, this function returns NIL.
|
* tributed table is involved, this function returns NIL.
|
||||||
*/
|
*/
|
||||||
List *
|
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 objectRelationId = InvalidOid; /* SQL Object OID */
|
||||||
Oid tableRelationId = InvalidOid; /* Relation OID, maybe not the same. */
|
Oid tableRelationId = InvalidOid; /* Relation OID, maybe not the same. */
|
||||||
|
|
||||||
|
@ -136,3 +137,30 @@ ErrorIfUnsupportedRenameStmt(RenameStmt *renameStmt)
|
||||||
"currently unsupported")));
|
"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;
|
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
|
* 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.
|
* password, which is, in some cases, created at standardProcessUtility.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
ProcessAlterRoleStmt(AlterRoleStmt *stmt, const char *queryString)
|
PostprocessAlterRoleStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
AlterRoleStmt *stmt = castNode(AlterRoleStmt, node);
|
||||||
ListCell *optionCell = NULL;
|
ListCell *optionCell = NULL;
|
||||||
|
|
||||||
if (!EnableAlterRolePropagation || !IsCoordinator())
|
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.
|
* under dropped schema involved in any foreign key relationship.
|
||||||
*/
|
*/
|
||||||
void
|
List *
|
||||||
ProcessDropSchemaStmt(DropStmt *dropStatement)
|
PreprocessDropSchemaStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
DropStmt *dropStatement = castNode(DropStmt, node);
|
||||||
Relation pgClass = NULL;
|
Relation pgClass = NULL;
|
||||||
HeapTuple heapTuple = NULL;
|
HeapTuple heapTuple = NULL;
|
||||||
SysScanDesc scanDescriptor = NULL;
|
SysScanDesc scanDescriptor = NULL;
|
||||||
|
@ -48,7 +49,7 @@ ProcessDropSchemaStmt(DropStmt *dropStatement)
|
||||||
|
|
||||||
if (dropStatement->behavior != DROP_CASCADE)
|
if (dropStatement->behavior != DROP_CASCADE)
|
||||||
{
|
{
|
||||||
return;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(dropSchemaCell, dropStatement->objects)
|
foreach(dropSchemaCell, dropStatement->objects)
|
||||||
|
@ -91,7 +92,7 @@ ProcessDropSchemaStmt(DropStmt *dropStatement)
|
||||||
|
|
||||||
systable_endscan(scanDescriptor);
|
systable_endscan(scanDescriptor);
|
||||||
heap_close(pgClass, NoLock);
|
heap_close(pgClass, NoLock);
|
||||||
return;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
heapTuple = systable_getnext(scanDescriptor);
|
heapTuple = systable_getnext(scanDescriptor);
|
||||||
|
@ -100,69 +101,21 @@ ProcessDropSchemaStmt(DropStmt *dropStatement)
|
||||||
systable_endscan(scanDescriptor);
|
systable_endscan(scanDescriptor);
|
||||||
heap_close(pgClass, NoLock);
|
heap_close(pgClass, NoLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PlanAlterObjectSchemaStmt is called by citus' utility hook for AlterObjectSchemaStmt
|
* PreprocessAlterTableSchemaStmt determines whether a given ALTER ... SET SCHEMA
|
||||||
* 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
|
|
||||||
* statement involves a distributed table and issues a warning if so. Because
|
* statement involves a distributed table and issues a warning if so. Because
|
||||||
* we do not support distributed ALTER ... SET SCHEMA, this function always
|
* we do not support distributed ALTER ... SET SCHEMA, this function always
|
||||||
* returns NIL.
|
* returns NIL.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanAlterTableSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString)
|
PreprocessAlterTableSchemaStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
if (stmt->relation == NULL)
|
if (stmt->relation == NULL)
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
|
@ -186,49 +139,3 @@ PlanAlterTableSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString)
|
||||||
|
|
||||||
return NIL;
|
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);
|
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
|
* 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
|
* 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
|
* 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
|
* Postgres catalogs via performDeletion function, thus we need to be cautious
|
||||||
* about not processing same DROP command twice.
|
* about not processing same DROP command twice.
|
||||||
*/
|
*/
|
||||||
void
|
List *
|
||||||
ProcessDropTableStmt(DropStmt *dropTableStatement)
|
PreprocessDropTableStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
DropStmt *dropTableStatement = castNode(DropStmt, node);
|
||||||
ListCell *dropTableCell = NULL;
|
ListCell *dropTableCell = NULL;
|
||||||
|
|
||||||
Assert(dropTableStatement->removeType == OBJECT_TABLE);
|
Assert(dropTableStatement->removeType == OBJECT_TABLE);
|
||||||
|
@ -114,11 +115,13 @@ ProcessDropTableStmt(DropStmt *dropTableStatement)
|
||||||
SendCommandToWorkersWithMetadata(detachPartitionCommand);
|
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
|
* 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,
|
* 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,
|
* 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 ...
|
* This function does nothing if the provided CreateStmt is not a CREATE TABLE ...
|
||||||
* PARTITION OF command.
|
* PARTITION OF command.
|
||||||
*/
|
*/
|
||||||
void
|
List *
|
||||||
ProcessCreateTableStmtPartitionOf(CreateStmt *createStatement)
|
PostprocessCreateTableStmtPartitionOf(CreateStmt *createStatement, const
|
||||||
|
char *queryString)
|
||||||
{
|
{
|
||||||
if (createStatement->inhRelations != NIL && createStatement->partbound != NULL)
|
if (createStatement->inhRelations != NIL && createStatement->partbound != NULL)
|
||||||
{
|
{
|
||||||
|
@ -162,11 +166,13 @@ ProcessCreateTableStmtPartitionOf(CreateStmt *createStatement)
|
||||||
viaDeprecatedAPI);
|
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
|
* but it only processes into ALTER TABLE ... ATTACH PARTITION commands and
|
||||||
* distributes the partition if necessary. There are four cases to consider;
|
* 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 ...
|
* This function does nothing if the provided CreateStmt is not an ALTER TABLE ...
|
||||||
* ATTACH PARTITION OF command.
|
* ATTACH PARTITION OF command.
|
||||||
*/
|
*/
|
||||||
void
|
List *
|
||||||
ProcessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement)
|
PostprocessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement,
|
||||||
|
const char *queryString)
|
||||||
{
|
{
|
||||||
List *commandList = alterTableStatement->cmds;
|
List *commandList = alterTableStatement->cmds;
|
||||||
ListCell *commandCell = NULL;
|
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
|
* a distributed table. If so (and if the statement does not use unsupported
|
||||||
* options), it modifies the input statement to ensure proper execution against
|
* options), it modifies the input statement to ensure proper execution against
|
||||||
* the master node table and creates a DDLJob to encapsulate information needed
|
* 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.
|
* in a List. If no distributed table is involved, this function returns NIL.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanAlterTableStmt(AlterTableStmt *alterTableStatement, const char *alterTableCommand)
|
PreprocessAlterTableStmt(Node *node, const char *alterTableCommand)
|
||||||
{
|
{
|
||||||
|
AlterTableStmt *alterTableStatement = castNode(AlterTableStmt, node);
|
||||||
Oid rightRelationId = InvalidOid;
|
Oid rightRelationId = InvalidOid;
|
||||||
ListCell *commandCell = NULL;
|
ListCell *commandCell = NULL;
|
||||||
bool executeSequentially = false;
|
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
|
* WorkerProcessAlterTableStmt checks and processes the alter table statement to be
|
||||||
* worked on the distributed table of the worker node. Currently, it only processes
|
* 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
|
* 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
|
* (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
|
* 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.
|
* will return back to the state before the ALTER TABLE command.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
PostProcessAlterTableStmt(AlterTableStmt *alterTableStatement)
|
PostprocessAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
{
|
{
|
||||||
List *commandList = alterTableStatement->cmds;
|
List *commandList = alterTableStatement->cmds;
|
||||||
ListCell *commandCell = NULL;
|
ListCell *commandCell = NULL;
|
||||||
|
@ -607,7 +635,7 @@ PostProcessAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
/* changing a relation could introduce new dependencies */
|
/* changing a relation could introduce new dependencies */
|
||||||
ObjectAddress tableAddress = { 0 };
|
ObjectAddress tableAddress = { 0 };
|
||||||
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
|
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
|
||||||
EnsureDependenciesExistsOnAllNodes(&tableAddress);
|
EnsureDependenciesExistOnAllNodes(&tableAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(commandCell, commandList)
|
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
|
* done before standard process utility is called for truncate
|
||||||
* command.
|
* command.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ProcessTruncateStatement(TruncateStmt *truncateStatement)
|
PostprocessTruncateStatement(TruncateStmt *truncateStatement)
|
||||||
{
|
{
|
||||||
ErrorIfUnsupportedTruncateStmt(truncateStatement);
|
ErrorIfUnsupportedTruncateStmt(truncateStatement);
|
||||||
EnsurePartitionTableNotReplicatedForTruncate(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.
|
* before the statement is applied locally.
|
||||||
*
|
*
|
||||||
* We decide if the compisite type needs to be replicated to the worker, and if that is
|
* 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.
|
* access to the ObjectAddress of the new type.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanCompositeTypeStmt(CompositeTypeStmt *stmt, const char *queryString)
|
PreprocessCompositeTypeStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
if (!ShouldPropagateTypeCreate())
|
if (!ShouldPropagateTypeCreate())
|
||||||
{
|
{
|
||||||
|
@ -136,7 +136,7 @@ PlanCompositeTypeStmt(CompositeTypeStmt *stmt, const char *queryString)
|
||||||
LockRelationOid(DistNodeRelationId(), RowShareLock);
|
LockRelationOid(DistNodeRelationId(), RowShareLock);
|
||||||
|
|
||||||
/* fully qualify before lookup and later deparsing */
|
/* fully qualify before lookup and later deparsing */
|
||||||
QualifyTreeNode((Node *) stmt);
|
QualifyTreeNode(node);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* reconstruct creation statement in a portable fashion. The create_or_replace helper
|
* 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
|
* type previously has been attempted to be created in a transaction which did not
|
||||||
* commit on the coordinator.
|
* commit on the coordinator.
|
||||||
*/
|
*/
|
||||||
const char *compositeTypeStmtSql = DeparseCompositeTypeStmt(stmt);
|
const char *compositeTypeStmtSql = DeparseCompositeTypeStmt(node);
|
||||||
compositeTypeStmtSql = WrapCreateOrReplace(compositeTypeStmtSql);
|
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
|
* 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.
|
* type which we use to make sure the type's dependencies are on all nodes.
|
||||||
*/
|
*/
|
||||||
void
|
List *
|
||||||
ProcessCompositeTypeStmt(CompositeTypeStmt *stmt, const char *queryString)
|
PostprocessCompositeTypeStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
/* same check we perform during planning of the statement */
|
/* same check we perform during planning of the statement */
|
||||||
if (!ShouldPropagateTypeCreate())
|
if (!ShouldPropagateTypeCreate())
|
||||||
{
|
{
|
||||||
return;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* find object address of the just created object, because the type has been created
|
* find object address of the just created object, because the type has been created
|
||||||
* locally it can't be missing
|
* locally it can't be missing
|
||||||
*/
|
*/
|
||||||
const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt,
|
ObjectAddress typeAddress = GetObjectAddressFromParseTree(node, false);
|
||||||
false);
|
EnsureDependenciesExistOnAllNodes(&typeAddress);
|
||||||
EnsureDependenciesExistsOnAllNodes(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
|
* 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.
|
* this is already implemented by the post processing for adding columns to tables.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanAlterTypeStmt(AlterTableStmt *stmt, const char *queryString)
|
PreprocessAlterTypeStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
||||||
Assert(stmt->relkind == OBJECT_TYPE);
|
Assert(stmt->relkind == OBJECT_TYPE);
|
||||||
|
|
||||||
const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt,
|
ObjectAddress typeAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
||||||
false);
|
if (!ShouldPropagateObject(&typeAddress))
|
||||||
if (!ShouldPropagateObject(typeAddress))
|
|
||||||
{
|
{
|
||||||
return NIL;
|
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
|
* 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
|
* 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.
|
* ObjectAddress for the new type just yet.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanCreateEnumStmt(CreateEnumStmt *stmt, const char *queryString)
|
PreprocessCreateEnumStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
if (!ShouldPropagateTypeCreate())
|
if (!ShouldPropagateTypeCreate())
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* managing types can only be done on the coordinator */
|
||||||
* managing types can only be done on the coordinator if ddl propagation is on. when
|
|
||||||
* it is off we will never get here
|
|
||||||
*/
|
|
||||||
EnsureCoordinator();
|
EnsureCoordinator();
|
||||||
|
|
||||||
/* enforce fully qualified typeName for correct deparsing and lookup */
|
/* enforce fully qualified typeName for correct deparsing and lookup */
|
||||||
QualifyTreeNode((Node *) stmt);
|
QualifyTreeNode(node);
|
||||||
|
|
||||||
/* reconstruct creation statement in a portable fashion */
|
/* reconstruct creation statement in a portable fashion */
|
||||||
const char *createEnumStmtSql = DeparseCreateEnumStmt(stmt);
|
const char *createEnumStmtSql = DeparseCreateEnumStmt(node);
|
||||||
createEnumStmtSql = WrapCreateOrReplace(createEnumStmtSql);
|
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.
|
* 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
|
* 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
|
* case we resolve the ObjectAddress for the just created object, distribute its
|
||||||
* dependencies to all the nodes, and mark the object as distributed.
|
* dependencies to all the nodes, and mark the object as distributed.
|
||||||
*/
|
*/
|
||||||
void
|
List *
|
||||||
ProcessCreateEnumStmt(CreateEnumStmt *stmt, const char *queryString)
|
PostprocessCreateEnumStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
if (!ShouldPropagateTypeCreate())
|
if (!ShouldPropagateTypeCreate())
|
||||||
{
|
{
|
||||||
return;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lookup type address of just created type */
|
/* lookup type address of just created type */
|
||||||
const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt,
|
ObjectAddress typeAddress = GetObjectAddressFromParseTree(node, false);
|
||||||
false);
|
EnsureDependenciesExistOnAllNodes(&typeAddress);
|
||||||
EnsureDependenciesExistsOnAllNodes(typeAddress);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* now that the object has been created and distributed to the workers we mark them as
|
* 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
|
* distributed so we know to keep them up to date and recreate on a new node in the
|
||||||
* future
|
* 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.
|
* happens before the statement has been applied locally.
|
||||||
*
|
*
|
||||||
* Since it is an alter of an existing type we actually have the ObjectAddress. This is
|
* 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.
|
* workers directly to keep the types in sync accross the cluster.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanAlterEnumStmt(AlterEnumStmt *stmt, const char *queryString)
|
PreprocessAlterEnumStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
List *commands = NIL;
|
List *commands = NIL;
|
||||||
|
|
||||||
const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt,
|
ObjectAddress typeAddress = GetObjectAddressFromParseTree(node, false);
|
||||||
false);
|
if (!ShouldPropagateObject(&typeAddress))
|
||||||
if (!ShouldPropagateObject(typeAddress))
|
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -338,8 +336,8 @@ PlanAlterEnumStmt(AlterEnumStmt *stmt, const char *queryString)
|
||||||
*/
|
*/
|
||||||
EnsureCoordinator();
|
EnsureCoordinator();
|
||||||
|
|
||||||
QualifyTreeNode((Node *) stmt);
|
QualifyTreeNode(node);
|
||||||
const char *alterEnumStmtSql = DeparseTreeNode((Node *) stmt);
|
const char *alterEnumStmtSql = DeparseTreeNode(node);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Before pg12 ALTER ENUM ... ADD VALUE could not be within a xact block. Instead of
|
* 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.
|
* we directly connect to workers and execute the commands remotely.
|
||||||
*/
|
*/
|
||||||
#if PG_VERSION_NUM < 120000
|
#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
|
* 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
|
* 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
|
* 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
|
* 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.
|
* when the transaction commits. This is behaviour that is ok to perform in a 2PC.
|
||||||
*/
|
*/
|
||||||
void
|
List *
|
||||||
ProcessAlterEnumStmt(AlterEnumStmt *stmt, const char *queryString)
|
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
|
* 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.
|
* 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.
|
* planning.
|
||||||
*/
|
*/
|
||||||
#if PG_VERSION_NUM < 120000
|
#if PG_VERSION_NUM < 120000
|
||||||
|
AlterEnumStmt *stmt = castNode(AlterEnumStmt, node);
|
||||||
|
ObjectAddress typeAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
||||||
|
if (!ShouldPropagateObject(&typeAddress))
|
||||||
|
{
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
|
||||||
if (AlterEnumIsAddValue(stmt))
|
if (AlterEnumIsAddValue(stmt))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -433,17 +431,21 @@ ProcessAlterEnumStmt(AlterEnumStmt *stmt, const char *queryString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
* 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.
|
* no types in the drop list are distributed no calls will be made to the workers.
|
||||||
*/
|
*/
|
||||||
List *
|
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
|
* We swap the list of objects to remove during deparse so we need a reference back to
|
||||||
* the old list to put back
|
* 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.
|
* before the statement is applied locally.
|
||||||
*
|
*
|
||||||
* As the type already exists we have access to the ObjectAddress for the type, this is
|
* 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.
|
* executed on all the workers to keep the types in sync across the cluster.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanRenameTypeStmt(RenameStmt *stmt, const char *queryString)
|
PreprocessRenameTypeStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt,
|
ObjectAddress typeAddress = GetObjectAddressFromParseTree(node, false);
|
||||||
false);
|
if (!ShouldPropagateObject(&typeAddress))
|
||||||
if (!ShouldPropagateObject(typeAddress))
|
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fully qualify */
|
/* fully qualify */
|
||||||
QualifyTreeNode((Node *) stmt);
|
QualifyTreeNode(node);
|
||||||
|
|
||||||
/* deparse sql*/
|
/* deparse sql*/
|
||||||
const char *renameStmtSql = DeparseTreeNode((Node *) stmt);
|
const char *renameStmtSql = DeparseTreeNode(node);
|
||||||
|
|
||||||
EnsureSequentialModeForTypeDDL();
|
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.
|
* types. Planning is called before the statement is applied locally.
|
||||||
*
|
*
|
||||||
* For distributed types we apply the attribute renames directly on all the workers to
|
* For distributed types we apply the attribute renames directly on all the workers to
|
||||||
* keep the type in sync across the cluster.
|
* keep the type in sync across the cluster.
|
||||||
*/
|
*/
|
||||||
List *
|
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->renameType == OBJECT_ATTRIBUTE);
|
||||||
Assert(stmt->relationType == OBJECT_TYPE);
|
Assert(stmt->relationType == OBJECT_TYPE);
|
||||||
|
|
||||||
const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt,
|
ObjectAddress typeAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
||||||
false);
|
if (!ShouldPropagateObject(&typeAddress))
|
||||||
if (!ShouldPropagateObject(typeAddress))
|
|
||||||
{
|
{
|
||||||
return NIL;
|
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.
|
* postgres instance.
|
||||||
*
|
*
|
||||||
* In this stage we can prepare the commands that need to be run on all workers.
|
* In this stage we can prepare the commands that need to be run on all workers.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString)
|
PreprocessAlterTypeSchemaStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
Assert(stmt->objectType == OBJECT_TYPE);
|
Assert(stmt->objectType == OBJECT_TYPE);
|
||||||
|
|
||||||
const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt,
|
ObjectAddress typeAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
||||||
false);
|
if (!ShouldPropagateObject(&typeAddress))
|
||||||
if (!ShouldPropagateObject(typeAddress))
|
|
||||||
{
|
{
|
||||||
return NIL;
|
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
|
* can now use the new dependencies of the type to ensure all its dependencies exist on
|
||||||
* the workers before we apply the commands remotely.
|
* the workers before we apply the commands remotely.
|
||||||
*/
|
*/
|
||||||
void
|
List *
|
||||||
ProcessAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt, const char *queryString)
|
PostprocessAlterTypeSchemaStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
Assert(stmt->objectType == OBJECT_TYPE);
|
Assert(stmt->objectType == OBJECT_TYPE);
|
||||||
|
|
||||||
const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt,
|
ObjectAddress typeAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
||||||
false);
|
if (!ShouldPropagateObject(&typeAddress))
|
||||||
if (!ShouldPropagateObject(typeAddress))
|
|
||||||
{
|
{
|
||||||
return;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dependencies have changed (schema) let's ensure they exist */
|
/* 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.
|
* ownership is changed on the local instance.
|
||||||
*
|
*
|
||||||
* If the type for which the owner is changed is distributed we execute the change on all
|
* 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.
|
* the workers to keep the type in sync across the cluster.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
PlanAlterTypeOwnerStmt(AlterOwnerStmt *stmt, const char *queryString)
|
PreprocessAlterTypeOwnerStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
Assert(stmt->objectType == OBJECT_TYPE);
|
Assert(stmt->objectType == OBJECT_TYPE);
|
||||||
|
|
||||||
const ObjectAddress *typeAddress = GetObjectAddressFromParseTree((Node *) stmt,
|
ObjectAddress typeAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
||||||
false);
|
if (!ShouldPropagateObject(&typeAddress))
|
||||||
if (!ShouldPropagateObject(typeAddress))
|
|
||||||
{
|
{
|
||||||
return NIL;
|
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
|
* Never returns NULL, but the objid in the address could be invalid if missing_ok was set
|
||||||
* to true.
|
* to true.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
CompositeTypeStmtObjectAddress(CompositeTypeStmt *stmt, bool missing_ok)
|
CompositeTypeStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
CompositeTypeStmt *stmt = castNode(CompositeTypeStmt, node);
|
||||||
TypeName *typeName = MakeTypeNameFromRangeVar(stmt->typevar);
|
TypeName *typeName = MakeTypeNameFromRangeVar(stmt->typevar);
|
||||||
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
||||||
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
ObjectAddress address = { 0 };
|
||||||
ObjectAddressSet(*address, TypeRelationId, typeOid);
|
ObjectAddressSet(address, TypeRelationId, typeOid);
|
||||||
|
|
||||||
return address;
|
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
|
* Never returns NULL, but the objid in the address could be invalid if missing_ok was set
|
||||||
* to true.
|
* to true.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
CreateEnumStmtObjectAddress(CreateEnumStmt *stmt, bool missing_ok)
|
CreateEnumStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
CreateEnumStmt *stmt = castNode(CreateEnumStmt, node);
|
||||||
TypeName *typeName = makeTypeNameFromNameList(stmt->typeName);
|
TypeName *typeName = makeTypeNameFromNameList(stmt->typeName);
|
||||||
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
||||||
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
ObjectAddress address = { 0 };
|
||||||
ObjectAddressSet(*address, TypeRelationId, typeOid);
|
ObjectAddressSet(address, TypeRelationId, typeOid);
|
||||||
|
|
||||||
return address;
|
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
|
* Never returns NULL, but the objid in the address could be invalid if missing_ok was set
|
||||||
* to true.
|
* to true.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
AlterTypeStmtObjectAddress(AlterTableStmt *stmt, bool missing_ok)
|
AlterTypeStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
||||||
Assert(stmt->relkind == OBJECT_TYPE);
|
Assert(stmt->relkind == OBJECT_TYPE);
|
||||||
|
|
||||||
TypeName *typeName = MakeTypeNameFromRangeVar(stmt->relation);
|
TypeName *typeName = MakeTypeNameFromRangeVar(stmt->relation);
|
||||||
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
||||||
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
ObjectAddress address = { 0 };
|
||||||
ObjectAddressSet(*address, TypeRelationId, typeOid);
|
ObjectAddressSet(address, TypeRelationId, typeOid);
|
||||||
|
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
@ -873,13 +879,14 @@ AlterTypeStmtObjectAddress(AlterTableStmt *stmt, bool missing_ok)
|
||||||
* AlterEnumStmtObjectAddress return the ObjectAddress of the enum type that is the
|
* AlterEnumStmtObjectAddress return the ObjectAddress of the enum type that is the
|
||||||
* object of the AlterEnumStmt. Errors is missing_ok is false.
|
* object of the AlterEnumStmt. Errors is missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
AlterEnumStmtObjectAddress(AlterEnumStmt *stmt, bool missing_ok)
|
AlterEnumStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
AlterEnumStmt *stmt = castNode(AlterEnumStmt, node);
|
||||||
TypeName *typeName = makeTypeNameFromNameList(stmt->typeName);
|
TypeName *typeName = makeTypeNameFromNameList(stmt->typeName);
|
||||||
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
||||||
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
ObjectAddress address = { 0 };
|
||||||
ObjectAddressSet(*address, TypeRelationId, typeOid);
|
ObjectAddressSet(address, TypeRelationId, typeOid);
|
||||||
|
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
@ -889,15 +896,16 @@ AlterEnumStmtObjectAddress(AlterEnumStmt *stmt, bool missing_ok)
|
||||||
* RenameTypeStmtObjectAddress returns the ObjectAddress of the type that is the object
|
* RenameTypeStmtObjectAddress returns the ObjectAddress of the type that is the object
|
||||||
* of the RenameStmt. Errors if missing_ok is false.
|
* of the RenameStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
RenameTypeStmtObjectAddress(RenameStmt *stmt, bool missing_ok)
|
RenameTypeStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
Assert(stmt->renameType == OBJECT_TYPE);
|
Assert(stmt->renameType == OBJECT_TYPE);
|
||||||
|
|
||||||
TypeName *typeName = makeTypeNameFromNameList((List *) stmt->object);
|
TypeName *typeName = makeTypeNameFromNameList((List *) stmt->object);
|
||||||
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
||||||
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
ObjectAddress address = { 0 };
|
||||||
ObjectAddressSet(*address, TypeRelationId, typeOid);
|
ObjectAddressSet(address, TypeRelationId, typeOid);
|
||||||
|
|
||||||
return address;
|
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
|
* new schema. Errors if missing_ok is false and the type cannot be found in either of the
|
||||||
* schemas.
|
* schemas.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
AlterTypeSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, bool missing_ok)
|
AlterTypeSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
Assert(stmt->objectType == OBJECT_TYPE);
|
Assert(stmt->objectType == OBJECT_TYPE);
|
||||||
|
|
||||||
List *names = (List *) stmt->object;
|
List *names = (List *) stmt->object;
|
||||||
|
@ -956,8 +965,8 @@ AlterTypeSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt, bool missing_ok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
ObjectAddress address = { 0 };
|
||||||
ObjectAddressSet(*address, TypeRelationId, typeOid);
|
ObjectAddressSet(address, TypeRelationId, typeOid);
|
||||||
|
|
||||||
return address;
|
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
|
* changed as Attributes are not distributed on their own but as a side effect of the
|
||||||
* whole type distribution.
|
* whole type distribution.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
RenameTypeAttributeStmtObjectAddress(RenameStmt *stmt, bool missing_ok)
|
RenameTypeAttributeStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
Assert(stmt->renameType == OBJECT_ATTRIBUTE);
|
Assert(stmt->renameType == OBJECT_ATTRIBUTE);
|
||||||
Assert(stmt->relationType == OBJECT_TYPE);
|
Assert(stmt->relationType == OBJECT_TYPE);
|
||||||
|
|
||||||
TypeName *typeName = MakeTypeNameFromRangeVar(stmt->relation);
|
TypeName *typeName = MakeTypeNameFromRangeVar(stmt->relation);
|
||||||
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
||||||
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
ObjectAddress address = { 0 };
|
||||||
ObjectAddressSet(*address, TypeRelationId, typeOid);
|
ObjectAddressSet(address, TypeRelationId, typeOid);
|
||||||
|
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
@ -990,15 +1000,16 @@ RenameTypeAttributeStmtObjectAddress(RenameStmt *stmt, bool missing_ok)
|
||||||
* AlterTypeOwnerObjectAddress returns the ObjectAddress of the type that is the object
|
* AlterTypeOwnerObjectAddress returns the ObjectAddress of the type that is the object
|
||||||
* of the AlterOwnerStmt. Errors if missing_ok is false.
|
* of the AlterOwnerStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
AlterTypeOwnerObjectAddress(AlterOwnerStmt *stmt, bool missing_ok)
|
AlterTypeOwnerObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
Assert(stmt->objectType == OBJECT_TYPE);
|
Assert(stmt->objectType == OBJECT_TYPE);
|
||||||
|
|
||||||
TypeName *typeName = makeTypeNameFromNameList((List *) stmt->object);
|
TypeName *typeName = makeTypeNameFromNameList((List *) stmt->object);
|
||||||
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
||||||
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
ObjectAddress address = { 0 };
|
||||||
ObjectAddressSet(*address, TypeRelationId, typeOid);
|
ObjectAddressSet(address, TypeRelationId, typeOid);
|
||||||
|
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*
|
*
|
||||||
* The utility hook is called by PostgreSQL when processing any command
|
* The utility hook is called by PostgreSQL when processing any command
|
||||||
* that is not SELECT, UPDATE, DELETE, INSERT, in place of the regular
|
* 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.
|
* some cases prevent) DDL commands and COPY on distributed tables.
|
||||||
*
|
*
|
||||||
* For DDL commands that affect distributed tables, we check whether
|
* 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
|
* on their distribution column value instead of writing it to the local
|
||||||
* table on the coordinator. For COPY from a distributed table, we
|
* table on the coordinator. For COPY from a distributed table, we
|
||||||
* replace the table with a SELECT * FROM table and pass it back to
|
* 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.
|
* hook.
|
||||||
*
|
*
|
||||||
* Copyright (c) Citus Data, Inc.
|
* Copyright (c) Citus Data, Inc.
|
||||||
|
@ -41,6 +41,7 @@
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/multi_copy.h"
|
#include "distributed/commands/multi_copy.h"
|
||||||
#include "distributed/commands/utility_hook.h" /* IWYU pragma: keep */
|
#include "distributed/commands/utility_hook.h" /* IWYU pragma: keep */
|
||||||
|
#include "distributed/deparser.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/local_executor.h"
|
#include "distributed/local_executor.h"
|
||||||
#include "distributed/maintenanced.h"
|
#include "distributed/maintenanced.h"
|
||||||
|
@ -72,11 +73,6 @@ static int activeDropSchemaOrDBs = 0;
|
||||||
static void ExecuteDistributedDDLJob(DDLJob *ddlJob);
|
static void ExecuteDistributedDDLJob(DDLJob *ddlJob);
|
||||||
static char * SetSearchPathToCurrentSearchPathCommand(void);
|
static char * SetSearchPathToCurrentSearchPathCommand(void);
|
||||||
static char * CurrentSearchPath(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);
|
static bool IsDropSchemaOrDB(Node *parsetree);
|
||||||
|
|
||||||
|
|
||||||
|
@ -289,7 +285,7 @@ multi_ProcessUtility(PlannedStmt *pstmt,
|
||||||
|
|
||||||
if (IsMultiStatementTransaction() && ShouldPropagateSetCommand(setStmt))
|
if (IsMultiStatementTransaction() && ShouldPropagateSetCommand(setStmt))
|
||||||
{
|
{
|
||||||
ProcessVariableSetStmt(setStmt, queryString);
|
PostprocessVariableSetStmt(setStmt, queryString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,245 +364,21 @@ multi_ProcessUtility(PlannedStmt *pstmt,
|
||||||
|
|
||||||
if (IsA(parsetree, TruncateStmt))
|
if (IsA(parsetree, TruncateStmt))
|
||||||
{
|
{
|
||||||
ProcessTruncateStatement((TruncateStmt *) parsetree);
|
PostprocessTruncateStatement((TruncateStmt *) parsetree);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* only generate worker DDLJobs if propagation is enabled */
|
/* only generate worker DDLJobs if propagation is enabled */
|
||||||
|
const DistributeObjectOps *ops = NULL;
|
||||||
if (EnableDDLPropagation)
|
if (EnableDDLPropagation)
|
||||||
{
|
{
|
||||||
/* copy planned statement since we might scribble on it or its utilityStmt */
|
/* copy planned statement since we might scribble on it or its utilityStmt */
|
||||||
pstmt = copyObject(pstmt);
|
pstmt = copyObject(pstmt);
|
||||||
parsetree = pstmt->utilityStmt;
|
parsetree = pstmt->utilityStmt;
|
||||||
|
ops = GetDistributeObjectOps(parsetree);
|
||||||
|
|
||||||
if (IsA(parsetree, IndexStmt))
|
if (ops && ops->preprocess)
|
||||||
{
|
{
|
||||||
ddlJobs = PlanIndexStmt((IndexStmt *) parsetree, queryString);
|
ddlJobs = ops->preprocess(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.")));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -635,9 +407,8 @@ multi_ProcessUtility(PlannedStmt *pstmt,
|
||||||
* the validation step should be skipped on the distributed table.
|
* the validation step should be skipped on the distributed table.
|
||||||
* Therefore, we check whether the given ALTER TABLE statement is a
|
* Therefore, we check whether the given ALTER TABLE statement is a
|
||||||
* FOREIGN KEY constraint and if so disable the validation step.
|
* FOREIGN KEY constraint and if so disable the validation step.
|
||||||
* Note that validation is done on the shard level when DDL
|
* Note validation is done on the shard level when DDL propagation
|
||||||
* propagation is enabled. Unlike the preceeding Plan* calls, the
|
* is enabled. The following eagerly executes some tasks on workers.
|
||||||
* following eagerly executes some tasks on workers.
|
|
||||||
*/
|
*/
|
||||||
parsetree = WorkerProcessAlterTableStmt(alterTableStmt, queryString);
|
parsetree = WorkerProcessAlterTableStmt(alterTableStmt, queryString);
|
||||||
}
|
}
|
||||||
|
@ -743,51 +514,17 @@ multi_ProcessUtility(PlannedStmt *pstmt,
|
||||||
*/
|
*/
|
||||||
if (EnableDDLPropagation)
|
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))
|
if (processJobs)
|
||||||
{
|
|
||||||
ProcessCreateEnumStmt(castNode(CreateEnumStmt, parsetree), queryString);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsA(parsetree, DefineStmt))
|
|
||||||
{
|
|
||||||
DefineStmt *defineStmt = castNode(DefineStmt, parsetree);
|
|
||||||
|
|
||||||
if (defineStmt->kind == OBJECT_COLLATION)
|
|
||||||
{
|
{
|
||||||
ddlJobs = ProcessCollationDefineStmt(defineStmt, queryString);
|
Assert(ddlJobs == NIL); /* jobs should not have been set before */
|
||||||
|
ddlJobs = processJobs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsA(parsetree, AlterObjectSchemaStmt))
|
|
||||||
{
|
|
||||||
ProcessAlterObjectSchemaStmt(castNode(AlterObjectSchemaStmt, parsetree),
|
|
||||||
queryString);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsA(parsetree, AlterEnumStmt))
|
|
||||||
{
|
|
||||||
ProcessAlterEnumStmt(castNode(AlterEnumStmt, parsetree), queryString);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsA(parsetree, CreateFunctionStmt))
|
|
||||||
{
|
|
||||||
Assert(ddlJobs == NIL); /* jobs should not have been set before */
|
|
||||||
ddlJobs = ProcessCreateFunctionStmt(castNode(CreateFunctionStmt, parsetree),
|
|
||||||
queryString);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsA(parsetree, AlterRoleStmt))
|
|
||||||
{
|
|
||||||
Assert(ddlJobs == NIL); /* jobs should not have been set before */
|
|
||||||
ddlJobs = ProcessAlterRoleStmt(castNode(AlterRoleStmt, parsetree),
|
|
||||||
queryString);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsA(parsetree, AlterRoleSetStmt) && EnableAlterRolePropagation)
|
if (IsA(parsetree, AlterRoleSetStmt) && EnableAlterRolePropagation)
|
||||||
{
|
{
|
||||||
ereport(NOTICE, (errmsg("Citus partially supports ALTER ROLE for "
|
ereport(NOTICE, (errmsg("Citus partially supports ALTER ROLE for "
|
||||||
|
@ -822,7 +559,7 @@ multi_ProcessUtility(PlannedStmt *pstmt,
|
||||||
{
|
{
|
||||||
CreateStmt *createStatement = (CreateStmt *) parsetree;
|
CreateStmt *createStatement = (CreateStmt *) parsetree;
|
||||||
|
|
||||||
ProcessCreateTableStmtPartitionOf(createStatement);
|
PostprocessCreateTableStmtPartitionOf(createStatement, queryString);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -833,27 +570,7 @@ multi_ProcessUtility(PlannedStmt *pstmt,
|
||||||
{
|
{
|
||||||
AlterTableStmt *alterTableStatement = (AlterTableStmt *) parsetree;
|
AlterTableStmt *alterTableStatement = (AlterTableStmt *) parsetree;
|
||||||
|
|
||||||
ProcessAlterTableStmtAttachPartition(alterTableStatement);
|
PostprocessAlterTableStmtAttachPartition(alterTableStatement, queryString);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -869,17 +586,14 @@ multi_ProcessUtility(PlannedStmt *pstmt,
|
||||||
/* after local command has completed, finish by executing worker DDLJobs, if any */
|
/* after local command has completed, finish by executing worker DDLJobs, if any */
|
||||||
if (ddlJobs != NIL)
|
if (ddlJobs != NIL)
|
||||||
{
|
{
|
||||||
ListCell *ddlJobCell = NULL;
|
|
||||||
|
|
||||||
if (IsA(parsetree, AlterTableStmt))
|
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);
|
ExecuteDistributedDDLJob(ddlJob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -889,7 +603,7 @@ multi_ProcessUtility(PlannedStmt *pstmt,
|
||||||
{
|
{
|
||||||
VacuumStmt *vacuumStmt = (VacuumStmt *) parsetree;
|
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-
|
* ExecuteDistributedDDLJob simply executes a provided DDLJob in a distributed trans-
|
||||||
* action, including metadata sync if needed. If the multi shard commit protocol is
|
* 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
|
* MarkInvalidateForeignKeyGraph marks whether the foreign key graph should be
|
||||||
* invalidated due to a DDL.
|
* invalidated due to a DDL.
|
||||||
|
|
|
@ -49,7 +49,7 @@ static List * ExtractVacuumTargetRels(VacuumStmt *vacuumStmt);
|
||||||
static CitusVacuumParams VacuumStmtParams(VacuumStmt *vacstmt);
|
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
|
* distributed tables. If a VACUUM or ANALYZE command references a distributed
|
||||||
* table, it is propagated to all involved nodes; otherwise, this function will
|
* table, it is propagated to all involved nodes; otherwise, this function will
|
||||||
* immediately exit after some error checking.
|
* immediately exit after some error checking.
|
||||||
|
@ -59,7 +59,7 @@ static CitusVacuumParams VacuumStmtParams(VacuumStmt *vacstmt);
|
||||||
* ANALYZE has already been processed.
|
* ANALYZE has already been processed.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ProcessVacuumStmt(VacuumStmt *vacuumStmt, const char *vacuumCommand)
|
PostprocessVacuumStmt(VacuumStmt *vacuumStmt, const char *vacuumCommand)
|
||||||
{
|
{
|
||||||
int relationIndex = 0;
|
int relationIndex = 0;
|
||||||
List *vacuumRelationList = ExtractVacuumTargetRels(vacuumStmt);
|
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
|
* 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.
|
* keeping track of all propagated SET commands since (sub-)xact start.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ProcessVariableSetStmt(VariableSetStmt *setStmt, const char *setStmtString)
|
PostprocessVariableSetStmt(VariableSetStmt *setStmt, const char *setStmtString)
|
||||||
{
|
{
|
||||||
dlist_iter iter;
|
dlist_iter iter;
|
||||||
const bool raiseInterrupts = true;
|
const bool raiseInterrupts = true;
|
||||||
|
|
|
@ -197,8 +197,8 @@ StartNodeConnection(uint32 flags, const char *hostname, int32 port)
|
||||||
* See StartNodeUserDatabaseConnection for details.
|
* See StartNodeUserDatabaseConnection for details.
|
||||||
*/
|
*/
|
||||||
MultiConnection *
|
MultiConnection *
|
||||||
GetNodeUserDatabaseConnection(uint32 flags, const char *hostname, int32 port, const
|
GetNodeUserDatabaseConnection(uint32 flags, const char *hostname, int32 port,
|
||||||
char *user, const char *database)
|
const char *user, const char *database)
|
||||||
{
|
{
|
||||||
MultiConnection *connection = StartNodeUserDatabaseConnection(flags, hostname, port,
|
MultiConnection *connection = StartNodeUserDatabaseConnection(flags, hostname, port,
|
||||||
user, database);
|
user, database);
|
||||||
|
@ -250,8 +250,8 @@ StartWorkerListConnections(List *workerNodeList, uint32 flags, const char *user,
|
||||||
* that's not desired use the Get* variant.
|
* that's not desired use the Get* variant.
|
||||||
*/
|
*/
|
||||||
MultiConnection *
|
MultiConnection *
|
||||||
StartNodeUserDatabaseConnection(uint32 flags, const char *hostname, int32 port, const
|
StartNodeUserDatabaseConnection(uint32 flags, const char *hostname, int32 port,
|
||||||
char *user, const char *database)
|
const char *user, const char *database)
|
||||||
{
|
{
|
||||||
ConnectionHashKey key;
|
ConnectionHashKey key;
|
||||||
MultiConnection *connection;
|
MultiConnection *connection;
|
||||||
|
|
|
@ -15,344 +15,23 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "distributed/commands.h"
|
||||||
#include "distributed/deparser.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
|
* DeparseTreeNode aims to be the inverse of postgres' ParseTreeNode. Currently with
|
||||||
* limited support. Check support before using, and add support for new statements as
|
* limited support. Check support before using, and add support for new statements as
|
||||||
* required.
|
* 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 *
|
char *
|
||||||
DeparseTreeNode(Node *stmt)
|
DeparseTreeNode(Node *stmt)
|
||||||
{
|
{
|
||||||
switch (nodeTag(stmt))
|
const DistributeObjectOps *ops = GetDistributeObjectOps(stmt);
|
||||||
|
|
||||||
|
if (!ops->deparse)
|
||||||
{
|
{
|
||||||
case T_DropStmt:
|
ereport(ERROR, (errmsg("unsupported statement for deparsing")));
|
||||||
{
|
|
||||||
return DeparseDropStmt(castNode(DropStmt, stmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_CompositeTypeStmt:
|
|
||||||
{
|
|
||||||
return DeparseCompositeTypeStmt(castNode(CompositeTypeStmt, stmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_CreateEnumStmt:
|
|
||||||
{
|
|
||||||
return DeparseCreateEnumStmt(castNode(CreateEnumStmt, stmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterTableStmt:
|
|
||||||
{
|
|
||||||
return DeparseAlterTableStmt(castNode(AlterTableStmt, stmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterEnumStmt:
|
|
||||||
{
|
|
||||||
return DeparseAlterEnumStmt(castNode(AlterEnumStmt, stmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterFunctionStmt:
|
|
||||||
{
|
|
||||||
return DeparseAlterFunctionStmt(castNode(AlterFunctionStmt, stmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_RenameStmt:
|
|
||||||
{
|
|
||||||
return DeparseRenameStmt(castNode(RenameStmt, stmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterObjectSchemaStmt:
|
|
||||||
{
|
|
||||||
return DeparseAlterObjectSchemaStmt(castNode(AlterObjectSchemaStmt, stmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterOwnerStmt:
|
|
||||||
{
|
|
||||||
return DeparseAlterOwnerStmt(castNode(AlterOwnerStmt, stmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterObjectDependsStmt:
|
|
||||||
{
|
|
||||||
return DeparseAlterObjectDependsStmt(castNode(AlterObjectDependsStmt, stmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterRoleStmt:
|
|
||||||
{
|
|
||||||
return DeparseAlterRoleStmt(castNode(AlterRoleStmt, stmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_CreateExtensionStmt:
|
|
||||||
{
|
|
||||||
return DeparseCreateExtensionStmt(castNode(CreateExtensionStmt, stmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterExtensionStmt:
|
|
||||||
{
|
|
||||||
return DeparseAlterExtensionStmt(castNode(AlterExtensionStmt, stmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("unsupported statement for deparsing")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* DeparseDropStmt aims to deparse DROP statements.
|
|
||||||
*
|
|
||||||
* Currently with limited support. Check support before using, and add support for new
|
|
||||||
* statements as required.
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
DeparseDropStmt(DropStmt *stmt)
|
|
||||||
{
|
|
||||||
switch (stmt->removeType)
|
|
||||||
{
|
|
||||||
case OBJECT_TYPE:
|
|
||||||
{
|
|
||||||
return DeparseDropTypeStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
case OBJECT_COLLATION:
|
|
||||||
{
|
|
||||||
return DeparseDropCollationStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
case OBJECT_PROCEDURE:
|
|
||||||
case OBJECT_AGGREGATE:
|
|
||||||
case OBJECT_FUNCTION:
|
|
||||||
{
|
|
||||||
return DeparseDropFunctionStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
case OBJECT_EXTENSION:
|
|
||||||
{
|
|
||||||
return DeparseDropExtensionStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("unsupported drop statement for deparsing")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* DeparseAlterTableStmt deparses an AlterTableStmt to its SQL command.
|
|
||||||
* Contrary to its name these statements are covering not only ALTER TABLE ...
|
|
||||||
* statements but are used for almost all relation-esque objects in postgres,
|
|
||||||
* including but not limited to, Tables, Types, ...
|
|
||||||
*
|
|
||||||
* Currently with limited support. Check support before using, and add support for new
|
|
||||||
* statements as required.
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
DeparseAlterTableStmt(AlterTableStmt *stmt)
|
|
||||||
{
|
|
||||||
switch (stmt->relkind)
|
|
||||||
{
|
|
||||||
case OBJECT_TYPE:
|
|
||||||
{
|
|
||||||
return DeparseAlterTypeStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("unsupported alter statement for deparsing")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* DeparseRenameStmt deparses an RenameStmt to its SQL command.
|
|
||||||
* Contrary to its name these statements are not covering all ALTER .. RENAME
|
|
||||||
* statements.
|
|
||||||
*
|
|
||||||
* e.g. ALTER TYPE name RENAME VALUE old TO new is an AlterEnumStmt
|
|
||||||
*
|
|
||||||
* Currently with limited support. Check support before using, and add support for new
|
|
||||||
* statements as required.
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
DeparseRenameStmt(RenameStmt *stmt)
|
|
||||||
{
|
|
||||||
switch (stmt->renameType)
|
|
||||||
{
|
|
||||||
case OBJECT_TYPE:
|
|
||||||
{
|
|
||||||
return DeparseRenameTypeStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
case OBJECT_ATTRIBUTE:
|
|
||||||
{
|
|
||||||
return DeparseRenameAttributeStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
case OBJECT_COLLATION:
|
|
||||||
{
|
|
||||||
return DeparseRenameCollationStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
case OBJECT_PROCEDURE:
|
|
||||||
case OBJECT_AGGREGATE:
|
|
||||||
case OBJECT_FUNCTION:
|
|
||||||
{
|
|
||||||
return DeparseRenameFunctionStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("unsupported rename statement for deparsing")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static char *
|
|
||||||
DeparseRenameAttributeStmt(RenameStmt *stmt)
|
|
||||||
{
|
|
||||||
Assert(stmt->renameType == OBJECT_ATTRIBUTE);
|
|
||||||
|
|
||||||
switch (stmt->relationType)
|
|
||||||
{
|
|
||||||
case OBJECT_TYPE:
|
|
||||||
{
|
|
||||||
return DeparseRenameTypeAttributeStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("unsupported rename attribute statement for"
|
|
||||||
" deparsing")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* DeparseAlterObjectSchemaStmt aims to deparse
|
|
||||||
* ALTER .. SET SCHEMA ..
|
|
||||||
* statements.
|
|
||||||
*
|
|
||||||
* Currently with limited support. Check support before using, and add support for new
|
|
||||||
* statements as required.
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
DeparseAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
|
|
||||||
{
|
|
||||||
switch (stmt->objectType)
|
|
||||||
{
|
|
||||||
case OBJECT_TYPE:
|
|
||||||
{
|
|
||||||
return DeparseAlterTypeSchemaStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
case OBJECT_COLLATION:
|
|
||||||
{
|
|
||||||
return DeparseAlterCollationSchemaStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
case OBJECT_PROCEDURE:
|
|
||||||
case OBJECT_AGGREGATE:
|
|
||||||
case OBJECT_FUNCTION:
|
|
||||||
{
|
|
||||||
return DeparseAlterFunctionSchemaStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
case OBJECT_EXTENSION:
|
|
||||||
{
|
|
||||||
return DeparseAlterExtensionSchemaStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("unsupported rename statement for deparsing")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* DeparseAlterOwnerStmt aims to deparse
|
|
||||||
* ALTER .. OWNER TO ..
|
|
||||||
* statements.
|
|
||||||
*
|
|
||||||
* Currently with limited support. Check support before using, and add support for new
|
|
||||||
* statements as required.
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
DeparseAlterOwnerStmt(AlterOwnerStmt *stmt)
|
|
||||||
{
|
|
||||||
switch (stmt->objectType)
|
|
||||||
{
|
|
||||||
case OBJECT_TYPE:
|
|
||||||
{
|
|
||||||
return DeparseAlterTypeOwnerStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
case OBJECT_COLLATION:
|
|
||||||
{
|
|
||||||
return DeparseAlterCollationOwnerStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
case OBJECT_PROCEDURE:
|
|
||||||
case OBJECT_AGGREGATE:
|
|
||||||
case OBJECT_FUNCTION:
|
|
||||||
{
|
|
||||||
return DeparseAlterFunctionOwnerStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("unsupported alter owner statement for deparsing")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* DeparseAlterObjectDependsStmt aims to deparse
|
|
||||||
* ALTER .. DEPENDS ON EXTENSION ..
|
|
||||||
* statements.
|
|
||||||
*
|
|
||||||
* Currently with limited support. Check support before using, and add support for new
|
|
||||||
* statements as required.
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
DeparseAlterObjectDependsStmt(AlterObjectDependsStmt *stmt)
|
|
||||||
{
|
|
||||||
switch (stmt->objectType)
|
|
||||||
{
|
|
||||||
case OBJECT_PROCEDURE:
|
|
||||||
case OBJECT_AGGREGATE:
|
|
||||||
case OBJECT_FUNCTION:
|
|
||||||
{
|
|
||||||
return DeparseAlterFunctionDependsStmt(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("unsupported alter depends statement for deparsing")));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
* DeparseDropCollationStmt builds and returns a string representing the DropStmt
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
DeparseDropCollationStmt(DropStmt *stmt)
|
DeparseDropCollationStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
DropStmt *stmt = castNode(DropStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
@ -67,8 +68,9 @@ AppendDropCollationStmt(StringInfo buf, DropStmt *stmt)
|
||||||
* DeparseRenameCollationStmt builds and returns a string representing the RenameStmt
|
* DeparseRenameCollationStmt builds and returns a string representing the RenameStmt
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
DeparseRenameCollationStmt(RenameStmt *stmt)
|
DeparseRenameCollationStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
@ -88,8 +90,8 @@ AppendRenameCollationStmt(StringInfo buf, RenameStmt *stmt)
|
||||||
{
|
{
|
||||||
List *names = (List *) stmt->object;
|
List *names = (List *) stmt->object;
|
||||||
|
|
||||||
appendStringInfo(buf, "ALTER COLLATION %s RENAME TO %s;", NameListToQuotedString(
|
appendStringInfo(buf, "ALTER COLLATION %s RENAME TO %s;",
|
||||||
names),
|
NameListToQuotedString(names),
|
||||||
quote_identifier(stmt->newname));
|
quote_identifier(stmt->newname));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,8 +100,9 @@ AppendRenameCollationStmt(StringInfo buf, RenameStmt *stmt)
|
||||||
* DeparseAlterCollationSchemaStmt builds and returns a string representing the AlterObjectSchemaStmt
|
* DeparseAlterCollationSchemaStmt builds and returns a string representing the AlterObjectSchemaStmt
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
DeparseAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt)
|
DeparseAlterCollationSchemaStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
@ -130,8 +133,9 @@ AppendAlterCollationSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt)
|
||||||
* DeparseAlterCollationOwnerStmt builds and returns a string representing the AlterOwnerStmt
|
* DeparseAlterCollationOwnerStmt builds and returns a string representing the AlterOwnerStmt
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
DeparseAlterCollationOwnerStmt(AlterOwnerStmt *stmt)
|
DeparseAlterCollationOwnerStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
|
|
@ -68,12 +68,13 @@ GetExtensionOption(List *extensionOptions, const char *defname)
|
||||||
* CreateExtensionStmt to be sent to worker nodes.
|
* CreateExtensionStmt to be sent to worker nodes.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
DeparseCreateExtensionStmt(CreateExtensionStmt *createExtensionStmt)
|
DeparseCreateExtensionStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
CreateExtensionStmt *stmt = castNode(CreateExtensionStmt, node);
|
||||||
StringInfoData sql = { 0 };
|
StringInfoData sql = { 0 };
|
||||||
initStringInfo(&sql);
|
initStringInfo(&sql);
|
||||||
|
|
||||||
AppendCreateExtensionStmt(&sql, createExtensionStmt);
|
AppendCreateExtensionStmt(&sql, stmt);
|
||||||
|
|
||||||
return sql.data;
|
return sql.data;
|
||||||
}
|
}
|
||||||
|
@ -141,12 +142,13 @@ AppendCreateExtensionStmt(StringInfo buf, CreateExtensionStmt *createExtensionSt
|
||||||
* AlterExtensionStmt to be sent to worker nodes.
|
* AlterExtensionStmt to be sent to worker nodes.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
DeparseAlterExtensionStmt(AlterExtensionStmt *alterExtensionStmt)
|
DeparseAlterExtensionStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterExtensionStmt *stmt = castNode(AlterExtensionStmt, node);
|
||||||
StringInfoData sql = { 0 };
|
StringInfoData sql = { 0 };
|
||||||
initStringInfo(&sql);
|
initStringInfo(&sql);
|
||||||
|
|
||||||
AppendAlterExtensionStmt(&sql, alterExtensionStmt);
|
AppendAlterExtensionStmt(&sql, stmt);
|
||||||
|
|
||||||
return sql.data;
|
return sql.data;
|
||||||
}
|
}
|
||||||
|
@ -184,12 +186,13 @@ AppendAlterExtensionStmt(StringInfo buf, AlterExtensionStmt *alterExtensionStmt)
|
||||||
* DeparseDropExtensionStmt builds and returns a string representing the DropStmt
|
* DeparseDropExtensionStmt builds and returns a string representing the DropStmt
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
DeparseDropExtensionStmt(DropStmt *dropStmt)
|
DeparseDropExtensionStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
DropStmt *stmt = castNode(DropStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
AppendDropExtensionStmt(&str, dropStmt);
|
AppendDropExtensionStmt(&str, stmt);
|
||||||
|
|
||||||
return str.data;
|
return str.data;
|
||||||
}
|
}
|
||||||
|
@ -252,14 +255,15 @@ AppendExtensionNameList(StringInfo str, List *objects)
|
||||||
* AlterObjectSchemaStmt (ALTER EXTENSION SET SCHEMA).
|
* AlterObjectSchemaStmt (ALTER EXTENSION SET SCHEMA).
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
DeparseAlterExtensionSchemaStmt(AlterObjectSchemaStmt *alterExtensionSchemaStmt)
|
DeparseAlterExtensionSchemaStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
Assert(alterExtensionSchemaStmt->objectType == OBJECT_EXTENSION);
|
Assert(stmt->objectType == OBJECT_EXTENSION);
|
||||||
|
|
||||||
AppendAlterExtensionSchemaStmt(&str, alterExtensionSchemaStmt);
|
AppendAlterExtensionSchemaStmt(&str, stmt);
|
||||||
|
|
||||||
return str.data;
|
return str.data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,8 +71,9 @@ static char * CopyAndConvertToUpperCase(const char *str);
|
||||||
* DeparseAlterFunctionStmt builds and returns a string representing the AlterFunctionStmt
|
* DeparseAlterFunctionStmt builds and returns a string representing the AlterFunctionStmt
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
DeparseAlterFunctionStmt(AlterFunctionStmt *stmt)
|
DeparseAlterFunctionStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterFunctionStmt *stmt = castNode(AlterFunctionStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
@ -427,8 +428,9 @@ AppendVarSetValue(StringInfo buf, VariableSetStmt *setStmt)
|
||||||
* DeparseRenameFunctionStmt builds and returns a string representing the RenameStmt
|
* DeparseRenameFunctionStmt builds and returns a string representing the RenameStmt
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
DeparseRenameFunctionStmt(RenameStmt *stmt)
|
DeparseRenameFunctionStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
@ -458,8 +460,9 @@ AppendRenameFunctionStmt(StringInfo buf, RenameStmt *stmt)
|
||||||
* DeparseAlterFunctionSchemaStmt builds and returns a string representing the AlterObjectSchemaStmt
|
* DeparseAlterFunctionSchemaStmt builds and returns a string representing the AlterObjectSchemaStmt
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
DeparseAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt)
|
DeparseAlterFunctionSchemaStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
@ -489,8 +492,9 @@ AppendAlterFunctionSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt)
|
||||||
* DeparseAlterFunctionOwnerStmt builds and returns a string representing the AlterOwnerStmt
|
* DeparseAlterFunctionOwnerStmt builds and returns a string representing the AlterOwnerStmt
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
DeparseAlterFunctionOwnerStmt(AlterOwnerStmt *stmt)
|
DeparseAlterFunctionOwnerStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
@ -520,8 +524,9 @@ AppendAlterFunctionOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt)
|
||||||
* DeparseAlterFunctionDependsStmt builds and returns a string representing the AlterObjectDependsStmt
|
* DeparseAlterFunctionDependsStmt builds and returns a string representing the AlterObjectDependsStmt
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
DeparseAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt)
|
DeparseAlterFunctionDependsStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterObjectDependsStmt *stmt = castNode(AlterObjectDependsStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
@ -551,8 +556,9 @@ AppendAlterFunctionDependsStmt(StringInfo buf, AlterObjectDependsStmt *stmt)
|
||||||
* DeparseDropFunctionStmt builds and returns a string representing the DropStmt
|
* DeparseDropFunctionStmt builds and returns a string representing the DropStmt
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
DeparseDropFunctionStmt(DropStmt *stmt)
|
DeparseDropFunctionStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
DropStmt *stmt = castNode(DropStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,9 @@ static void AppendAlterRoleStmt(StringInfo buf, AlterRoleStmt *stmt);
|
||||||
* AlterRoleStmt for application on a remote server.
|
* AlterRoleStmt for application on a remote server.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
DeparseAlterRoleStmt(AlterRoleStmt *stmt)
|
DeparseAlterRoleStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterRoleStmt *stmt = castNode(AlterRoleStmt, node);
|
||||||
StringInfoData buf = { 0 };
|
StringInfoData buf = { 0 };
|
||||||
initStringInfo(&buf);
|
initStringInfo(&buf);
|
||||||
|
|
||||||
|
|
|
@ -62,8 +62,9 @@ static void AppendAlterTypeOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt);
|
||||||
* CompositeTypeStmt for application on a remote server.
|
* CompositeTypeStmt for application on a remote server.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
DeparseCompositeTypeStmt(CompositeTypeStmt *stmt)
|
DeparseCompositeTypeStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
CompositeTypeStmt *stmt = castNode(CompositeTypeStmt, node);
|
||||||
StringInfoData sql = { 0 };
|
StringInfoData sql = { 0 };
|
||||||
initStringInfo(&sql);
|
initStringInfo(&sql);
|
||||||
|
|
||||||
|
@ -74,8 +75,9 @@ DeparseCompositeTypeStmt(CompositeTypeStmt *stmt)
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
DeparseCreateEnumStmt(CreateEnumStmt *stmt)
|
DeparseCreateEnumStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
CreateEnumStmt *stmt = castNode(CreateEnumStmt, node);
|
||||||
StringInfoData sql = { 0 };
|
StringInfoData sql = { 0 };
|
||||||
initStringInfo(&sql);
|
initStringInfo(&sql);
|
||||||
|
|
||||||
|
@ -86,8 +88,9 @@ DeparseCreateEnumStmt(CreateEnumStmt *stmt)
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
DeparseAlterEnumStmt(AlterEnumStmt *stmt)
|
DeparseAlterEnumStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterEnumStmt *stmt = castNode(AlterEnumStmt, node);
|
||||||
StringInfoData sql = { 0 };
|
StringInfoData sql = { 0 };
|
||||||
initStringInfo(&sql);
|
initStringInfo(&sql);
|
||||||
|
|
||||||
|
@ -98,8 +101,9 @@ DeparseAlterEnumStmt(AlterEnumStmt *stmt)
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
DeparseDropTypeStmt(DropStmt *stmt)
|
DeparseDropTypeStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
DropStmt *stmt = castNode(DropStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
@ -112,8 +116,9 @@ DeparseDropTypeStmt(DropStmt *stmt)
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
DeparseAlterTypeStmt(AlterTableStmt *stmt)
|
DeparseAlterTypeStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
@ -395,8 +400,9 @@ AppendColumnDef(StringInfo str, ColumnDef *columnDef)
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
DeparseRenameTypeStmt(RenameStmt *stmt)
|
DeparseRenameTypeStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
@ -419,8 +425,9 @@ AppendRenameTypeStmt(StringInfo buf, RenameStmt *stmt)
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
DeparseRenameTypeAttributeStmt(RenameStmt *stmt)
|
DeparseRenameTypeAttributeStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
@ -452,8 +459,9 @@ AppendRenameTypeAttributeStmt(StringInfo buf, RenameStmt *stmt)
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
DeparseAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt)
|
DeparseAlterTypeSchemaStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
@ -477,8 +485,9 @@ AppendAlterTypeSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt)
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
DeparseAlterTypeOwnerStmt(AlterOwnerStmt *stmt)
|
DeparseAlterTypeOwnerStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
StringInfoData str = { 0 };
|
StringInfoData str = { 0 };
|
||||||
initStringInfo(&str);
|
initStringInfo(&str);
|
||||||
|
|
||||||
|
|
|
@ -18,241 +18,36 @@
|
||||||
#include "catalog/objectaddress.h"
|
#include "catalog/objectaddress.h"
|
||||||
#include "catalog/pg_extension_d.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
|
* GetObjectAddressFromParseTree returns the ObjectAddress of the main target of the parse
|
||||||
* tree.
|
* tree.
|
||||||
*/
|
*/
|
||||||
ObjectAddress *
|
ObjectAddress
|
||||||
GetObjectAddressFromParseTree(Node *parseTree, bool missing_ok)
|
GetObjectAddressFromParseTree(Node *parseTree, bool missing_ok)
|
||||||
{
|
{
|
||||||
switch (parseTree->type)
|
const DistributeObjectOps *ops = GetDistributeObjectOps(parseTree);
|
||||||
|
|
||||||
|
if (!ops->address)
|
||||||
{
|
{
|
||||||
case T_CompositeTypeStmt:
|
ereport(ERROR, (errmsg("unsupported statement to get object address for")));
|
||||||
{
|
|
||||||
return CompositeTypeStmtObjectAddress(castNode(CompositeTypeStmt, parseTree),
|
|
||||||
missing_ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterTableStmt:
|
|
||||||
{
|
|
||||||
return AlterTableStmtObjectAddress(castNode(AlterTableStmt, parseTree),
|
|
||||||
missing_ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_CreateEnumStmt:
|
|
||||||
{
|
|
||||||
return CreateEnumStmtObjectAddress(castNode(CreateEnumStmt, parseTree),
|
|
||||||
missing_ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterEnumStmt:
|
|
||||||
{
|
|
||||||
return AlterEnumStmtObjectAddress(castNode(AlterEnumStmt, parseTree),
|
|
||||||
missing_ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_RenameStmt:
|
|
||||||
{
|
|
||||||
return RenameStmtObjectAddress(castNode(RenameStmt, parseTree), missing_ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterObjectSchemaStmt:
|
|
||||||
{
|
|
||||||
return AlterObjectSchemaStmtObjectAddress(castNode(AlterObjectSchemaStmt,
|
|
||||||
parseTree), missing_ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterOwnerStmt:
|
|
||||||
{
|
|
||||||
return AlterOwnerStmtObjectAddress(castNode(AlterOwnerStmt, parseTree),
|
|
||||||
missing_ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterFunctionStmt:
|
|
||||||
{
|
|
||||||
return AlterFunctionStmtObjectAddress(castNode(AlterFunctionStmt, parseTree),
|
|
||||||
missing_ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_CreateFunctionStmt:
|
|
||||||
{
|
|
||||||
return CreateFunctionStmtObjectAddress(
|
|
||||||
castNode(CreateFunctionStmt, parseTree), missing_ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterObjectDependsStmt:
|
|
||||||
{
|
|
||||||
return AlterObjectDependsStmtObjectAddress(
|
|
||||||
castNode(AlterObjectDependsStmt, parseTree), missing_ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_DefineStmt:
|
|
||||||
{
|
|
||||||
DefineStmt *stmt = castNode(DefineStmt, parseTree);
|
|
||||||
|
|
||||||
switch (stmt->kind)
|
|
||||||
{
|
|
||||||
case OBJECT_AGGREGATE:
|
|
||||||
{
|
|
||||||
return DefineAggregateStmtObjectAddress(stmt, missing_ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
case OBJECT_COLLATION:
|
|
||||||
{
|
|
||||||
return DefineCollationStmtObjectAddress(stmt, missing_ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ereport(ERROR, (errmsg(
|
|
||||||
"unsupported object type to get object address for DefineStmt")));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_CreateExtensionStmt:
|
|
||||||
{
|
|
||||||
return CreateExtensionStmtObjectAddress(castNode(CreateExtensionStmt,
|
|
||||||
parseTree), missing_ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterExtensionStmt:
|
|
||||||
{
|
|
||||||
return AlterExtensionStmtObjectAddress(castNode(AlterExtensionStmt,
|
|
||||||
parseTree), missing_ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* should not be reached, indicates the coordinator is sending unsupported
|
|
||||||
* statements
|
|
||||||
*/
|
|
||||||
ereport(ERROR, (errmsg("unsupported statement to get object address for")));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ops->address(parseTree, missing_ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ObjectAddress *
|
ObjectAddress
|
||||||
AlterTableStmtObjectAddress(AlterTableStmt *stmt, bool missing_ok)
|
RenameAttributeStmtObjectAddress(Node *node, 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)
|
|
||||||
{
|
{
|
||||||
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
Assert(stmt->renameType == OBJECT_ATTRIBUTE);
|
Assert(stmt->renameType == OBJECT_ATTRIBUTE);
|
||||||
|
|
||||||
switch (stmt->relationType)
|
switch (stmt->relationType)
|
||||||
{
|
{
|
||||||
case OBJECT_TYPE:
|
case OBJECT_TYPE:
|
||||||
{
|
{
|
||||||
return RenameTypeAttributeStmtObjectAddress(stmt, missing_ok);
|
return RenameTypeAttributeStmtObjectAddress(node, missing_ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
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
|
* CreateExtensionStmtObjectAddress finds the ObjectAddress for the extension described
|
||||||
* by the CreateExtensionStmt. If missing_ok is false, then this function throws an
|
* 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
|
* Never returns NULL, but the objid in the address could be invalid if missing_ok was set
|
||||||
* to true.
|
* to true.
|
||||||
*/
|
*/
|
||||||
static ObjectAddress *
|
ObjectAddress
|
||||||
CreateExtensionStmtObjectAddress(CreateExtensionStmt *createExtensionStmt, bool
|
CreateExtensionStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
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);
|
Oid extensionoid = get_extension_oid(extensionName, missing_ok);
|
||||||
|
|
||||||
|
@ -353,7 +85,7 @@ CreateExtensionStmtObjectAddress(CreateExtensionStmt *createExtensionStmt, bool
|
||||||
extensionName)));
|
extensionName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddressSet(*address, ExtensionRelationId, extensionoid);
|
ObjectAddressSet(address, ExtensionRelationId, extensionoid);
|
||||||
|
|
||||||
return address;
|
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
|
* Never returns NULL, but the objid in the address could be invalid if missing_ok was set
|
||||||
* to true.
|
* to true.
|
||||||
*/
|
*/
|
||||||
static ObjectAddress *
|
ObjectAddress
|
||||||
AlterExtensionStmtObjectAddress(AlterExtensionStmt *alterExtensionStmt, bool
|
AlterExtensionStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
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);
|
Oid extensionoid = get_extension_oid(extensionName, missing_ok);
|
||||||
|
|
||||||
|
@ -385,7 +117,7 @@ AlterExtensionStmtObjectAddress(AlterExtensionStmt *alterExtensionStmt, bool
|
||||||
extensionName)));
|
extensionName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddressSet(*address, ExtensionRelationId, extensionoid);
|
ObjectAddressSet(address, ExtensionRelationId, extensionoid);
|
||||||
|
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,17 +21,10 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "distributed/commands.h"
|
||||||
#include "distributed/deparser.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
|
* QualifyTreeNode transforms the statement in place and makes all (supported) statements
|
||||||
* fully qualified. Fully qualified statements allow for application on a remote postgres
|
* fully qualified. Fully qualified statements allow for application on a remote postgres
|
||||||
|
@ -40,117 +33,11 @@ static void QualifyDropObjectStmt(DropStmt *stmt);
|
||||||
void
|
void
|
||||||
QualifyTreeNode(Node *stmt)
|
QualifyTreeNode(Node *stmt)
|
||||||
{
|
{
|
||||||
switch (nodeTag(stmt))
|
const DistributeObjectOps *ops = GetDistributeObjectOps(stmt);
|
||||||
|
|
||||||
|
if (ops && ops->qualify)
|
||||||
{
|
{
|
||||||
case T_RenameStmt:
|
ops->qualify(stmt);
|
||||||
{
|
|
||||||
QualifyRenameStmt(castNode(RenameStmt, stmt));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterEnumStmt:
|
|
||||||
{
|
|
||||||
QualifyAlterEnumStmt(castNode(AlterEnumStmt, stmt));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterTableStmt:
|
|
||||||
{
|
|
||||||
QualifyAlterTableStmt(castNode(AlterTableStmt, stmt));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_CompositeTypeStmt:
|
|
||||||
{
|
|
||||||
QualifyCompositeTypeStmt(castNode(CompositeTypeStmt, stmt));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_CreateEnumStmt:
|
|
||||||
{
|
|
||||||
QualifyCreateEnumStmt(castNode(CreateEnumStmt, stmt));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterObjectSchemaStmt:
|
|
||||||
{
|
|
||||||
QualifyAlterObjectSchemaStmt(castNode(AlterObjectSchemaStmt, stmt));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterOwnerStmt:
|
|
||||||
{
|
|
||||||
QualifyAlterOwnerStmt(castNode(AlterOwnerStmt, stmt));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterFunctionStmt:
|
|
||||||
{
|
|
||||||
QualifyAlterFunctionStmt(castNode(AlterFunctionStmt, stmt));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_AlterObjectDependsStmt:
|
|
||||||
{
|
|
||||||
QualifyAlterObjectDependsStmt(castNode(AlterObjectDependsStmt, stmt));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case T_DropStmt:
|
|
||||||
{
|
|
||||||
QualifyDropObjectStmt(castNode(DropStmt, stmt));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
/* skip unsupported statements */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* QualifyRenameStmt transforms a RENAME statement in place and makes all (supported)
|
|
||||||
* statements fully qualified.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
QualifyRenameStmt(RenameStmt *stmt)
|
|
||||||
{
|
|
||||||
switch (stmt->renameType)
|
|
||||||
{
|
|
||||||
case OBJECT_TYPE:
|
|
||||||
{
|
|
||||||
QualifyRenameTypeStmt(stmt);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OBJECT_ATTRIBUTE:
|
|
||||||
{
|
|
||||||
QualifyRenameAttributeStmt(stmt);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OBJECT_COLLATION:
|
|
||||||
{
|
|
||||||
QualifyRenameCollationStmt(stmt);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OBJECT_AGGREGATE:
|
|
||||||
case OBJECT_FUNCTION:
|
|
||||||
case OBJECT_PROCEDURE:
|
|
||||||
{
|
|
||||||
QualifyRenameFunctionStmt(stmt);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
/* skip unsupported statements */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,142 +46,17 @@ QualifyRenameStmt(RenameStmt *stmt)
|
||||||
* QualifyRenameAttributeStmt transforms a RENAME ATTRIBUTE statement in place and makes all (supported)
|
* QualifyRenameAttributeStmt transforms a RENAME ATTRIBUTE statement in place and makes all (supported)
|
||||||
* statements fully qualified.
|
* statements fully qualified.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
QualifyRenameAttributeStmt(RenameStmt *stmt)
|
QualifyRenameAttributeStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
Assert(stmt->renameType == OBJECT_ATTRIBUTE);
|
Assert(stmt->renameType == OBJECT_ATTRIBUTE);
|
||||||
|
|
||||||
switch (stmt->relationType)
|
switch (stmt->relationType)
|
||||||
{
|
{
|
||||||
case OBJECT_TYPE:
|
case OBJECT_TYPE:
|
||||||
{
|
{
|
||||||
QualifyRenameTypeAttributeStmt(stmt);
|
QualifyRenameTypeAttributeStmt(node);
|
||||||
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);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,9 @@ static Node * QualifyCollationName(List *func);
|
||||||
* statement in place and makes the collation name fully qualified.
|
* statement in place and makes the collation name fully qualified.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
QualifyRenameCollationStmt(RenameStmt *stmt)
|
QualifyRenameCollationStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
Assert(stmt->renameType == OBJECT_COLLATION);
|
Assert(stmt->renameType == OBJECT_COLLATION);
|
||||||
|
|
||||||
stmt->object = QualifyCollationName(castNode(List, stmt->object));
|
stmt->object = QualifyCollationName(castNode(List, stmt->object));
|
||||||
|
@ -46,8 +47,9 @@ QualifyRenameCollationStmt(RenameStmt *stmt)
|
||||||
* statement in place and makes the collation name fully qualified.
|
* statement in place and makes the collation name fully qualified.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
QualifyAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt)
|
QualifyAlterCollationSchemaStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
Assert(stmt->objectType == OBJECT_COLLATION);
|
Assert(stmt->objectType == OBJECT_COLLATION);
|
||||||
|
|
||||||
stmt->object = QualifyCollationName(castNode(List, stmt->object));
|
stmt->object = QualifyCollationName(castNode(List, stmt->object));
|
||||||
|
@ -60,8 +62,9 @@ QualifyAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt)
|
||||||
* statement in place and makes the collation name fully qualified.
|
* statement in place and makes the collation name fully qualified.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
QualifyAlterCollationOwnerStmt(AlterOwnerStmt *stmt)
|
QualifyAlterCollationOwnerStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
Assert(stmt->objectType == OBJECT_COLLATION);
|
Assert(stmt->objectType == OBJECT_COLLATION);
|
||||||
|
|
||||||
stmt->object = QualifyCollationName(castNode(List, stmt->object));
|
stmt->object = QualifyCollationName(castNode(List, stmt->object));
|
||||||
|
@ -74,8 +77,9 @@ QualifyAlterCollationOwnerStmt(AlterOwnerStmt *stmt)
|
||||||
* statement in place and makes the collation name fully qualified.
|
* statement in place and makes the collation name fully qualified.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
QualifyDropCollationStmt(DropStmt *stmt)
|
QualifyDropCollationStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
DropStmt *stmt = castNode(DropStmt, node);
|
||||||
List *names = NIL;
|
List *names = NIL;
|
||||||
List *name = NIL;
|
List *name = NIL;
|
||||||
|
|
||||||
|
|
|
@ -51,8 +51,9 @@ AssertObjectTypeIsFunctional(ObjectType type)
|
||||||
* (e.g. ALTER FUNCTION .. RENAME .. queries are RenameStmt )
|
* (e.g. ALTER FUNCTION .. RENAME .. queries are RenameStmt )
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
QualifyAlterFunctionStmt(AlterFunctionStmt *stmt)
|
QualifyAlterFunctionStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterFunctionStmt *stmt = castNode(AlterFunctionStmt, node);
|
||||||
AssertObjectTypeIsFunctional(stmt->objtype);
|
AssertObjectTypeIsFunctional(stmt->objtype);
|
||||||
|
|
||||||
QualifyFunction(stmt->func, stmt->objtype);
|
QualifyFunction(stmt->func, stmt->objtype);
|
||||||
|
@ -65,8 +66,9 @@ QualifyAlterFunctionStmt(AlterFunctionStmt *stmt)
|
||||||
* statement in place and makes the function name fully qualified.
|
* statement in place and makes the function name fully qualified.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
QualifyRenameFunctionStmt(RenameStmt *stmt)
|
QualifyRenameFunctionStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
AssertObjectTypeIsFunctional(stmt->renameType);
|
AssertObjectTypeIsFunctional(stmt->renameType);
|
||||||
|
|
||||||
QualifyFunction(castNode(ObjectWithArgs, stmt->object), 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.
|
* statement in place and makes the function name fully qualified.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
QualifyAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt)
|
QualifyAlterFunctionSchemaStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
AssertObjectTypeIsFunctional(stmt->objectType);
|
AssertObjectTypeIsFunctional(stmt->objectType);
|
||||||
|
|
||||||
QualifyFunction(castNode(ObjectWithArgs, stmt->object), 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.
|
* statement in place and makes the function name fully qualified.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
QualifyAlterFunctionOwnerStmt(AlterOwnerStmt *stmt)
|
QualifyAlterFunctionOwnerStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
AssertObjectTypeIsFunctional(stmt->objectType);
|
AssertObjectTypeIsFunctional(stmt->objectType);
|
||||||
|
|
||||||
QualifyFunction(castNode(ObjectWithArgs, stmt->object), 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.
|
* statement in place and makes the function name fully qualified.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
QualifyAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt)
|
QualifyAlterFunctionDependsStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterObjectDependsStmt *stmt = castNode(AlterObjectDependsStmt, node);
|
||||||
AssertObjectTypeIsFunctional(stmt->objectType);
|
AssertObjectTypeIsFunctional(stmt->objectType);
|
||||||
|
|
||||||
QualifyFunction(castNode(ObjectWithArgs, stmt->object), stmt->objectType);
|
QualifyFunction(castNode(ObjectWithArgs, stmt->object), stmt->objectType);
|
||||||
|
|
|
@ -70,8 +70,9 @@ TypeOidGetNamespaceOid(Oid typeOid)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
QualifyRenameTypeStmt(RenameStmt *stmt)
|
QualifyRenameTypeStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
List *names = (List *) stmt->object;
|
List *names = (List *) stmt->object;
|
||||||
|
|
||||||
Assert(stmt->renameType == OBJECT_TYPE);
|
Assert(stmt->renameType == OBJECT_TYPE);
|
||||||
|
@ -88,8 +89,9 @@ QualifyRenameTypeStmt(RenameStmt *stmt)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
QualifyRenameTypeAttributeStmt(RenameStmt *stmt)
|
QualifyRenameTypeAttributeStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
Assert(stmt->renameType == OBJECT_ATTRIBUTE);
|
Assert(stmt->renameType == OBJECT_ATTRIBUTE);
|
||||||
Assert(stmt->relationType == OBJECT_TYPE);
|
Assert(stmt->relationType == OBJECT_TYPE);
|
||||||
|
|
||||||
|
@ -103,8 +105,9 @@ QualifyRenameTypeAttributeStmt(RenameStmt *stmt)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
QualifyAlterEnumStmt(AlterEnumStmt *stmt)
|
QualifyAlterEnumStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterEnumStmt *stmt = castNode(AlterEnumStmt, node);
|
||||||
List *names = stmt->typeName;
|
List *names = stmt->typeName;
|
||||||
|
|
||||||
if (list_length(names) == 1)
|
if (list_length(names) == 1)
|
||||||
|
@ -119,8 +122,9 @@ QualifyAlterEnumStmt(AlterEnumStmt *stmt)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
QualifyAlterTypeStmt(AlterTableStmt *stmt)
|
QualifyAlterTypeStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
||||||
Assert(stmt->relkind == OBJECT_TYPE);
|
Assert(stmt->relkind == OBJECT_TYPE);
|
||||||
|
|
||||||
if (stmt->relation->schemaname == NULL)
|
if (stmt->relation->schemaname == NULL)
|
||||||
|
@ -133,8 +137,10 @@ QualifyAlterTypeStmt(AlterTableStmt *stmt)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
QualifyCompositeTypeStmt(CompositeTypeStmt *stmt)
|
QualifyCompositeTypeStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
CompositeTypeStmt *stmt = castNode(CompositeTypeStmt, node);
|
||||||
|
|
||||||
if (stmt->typevar->schemaname == NULL)
|
if (stmt->typevar->schemaname == NULL)
|
||||||
{
|
{
|
||||||
Oid creationSchema = RangeVarGetCreationNamespace(stmt->typevar);
|
Oid creationSchema = RangeVarGetCreationNamespace(stmt->typevar);
|
||||||
|
@ -144,8 +150,10 @@ QualifyCompositeTypeStmt(CompositeTypeStmt *stmt)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
QualifyCreateEnumStmt(CreateEnumStmt *stmt)
|
QualifyCreateEnumStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
CreateEnumStmt *stmt = castNode(CreateEnumStmt, node);
|
||||||
|
|
||||||
if (list_length(stmt->typeName) == 1)
|
if (list_length(stmt->typeName) == 1)
|
||||||
{
|
{
|
||||||
char *objname = NULL;
|
char *objname = NULL;
|
||||||
|
@ -157,8 +165,9 @@ QualifyCreateEnumStmt(CreateEnumStmt *stmt)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
QualifyAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt)
|
QualifyAlterTypeSchemaStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
Assert(stmt->objectType == OBJECT_TYPE);
|
Assert(stmt->objectType == OBJECT_TYPE);
|
||||||
|
|
||||||
List *names = (List *) stmt->object;
|
List *names = (List *) stmt->object;
|
||||||
|
@ -173,8 +182,9 @@ QualifyAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
QualifyAlterTypeOwnerStmt(AlterOwnerStmt *stmt)
|
QualifyAlterTypeOwnerStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
Assert(stmt->objectType == OBJECT_TYPE);
|
Assert(stmt->objectType == OBJECT_TYPE);
|
||||||
|
|
||||||
List *names = (List *) stmt->object;
|
List *names = (List *) stmt->object;
|
||||||
|
|
|
@ -84,7 +84,7 @@ master_create_worker_shards(PG_FUNCTION_ARGS)
|
||||||
* sessions creating shards.
|
* sessions creating shards.
|
||||||
*/
|
*/
|
||||||
ObjectAddressSet(tableAddress, RelationRelationId, distributedTableId);
|
ObjectAddressSet(tableAddress, RelationRelationId, distributedTableId);
|
||||||
EnsureDependenciesExistsOnAllNodes(&tableAddress);
|
EnsureDependenciesExistOnAllNodes(&tableAddress);
|
||||||
|
|
||||||
CreateShardsWithRoundRobinPolicy(distributedTableId, shardCount, replicationFactor,
|
CreateShardsWithRoundRobinPolicy(distributedTableId, shardCount, replicationFactor,
|
||||||
useExclusiveConnections);
|
useExclusiveConnections);
|
||||||
|
|
|
@ -105,7 +105,7 @@ master_create_empty_shard(PG_FUNCTION_ARGS)
|
||||||
* sessions creating shards.
|
* sessions creating shards.
|
||||||
*/
|
*/
|
||||||
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
|
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
|
||||||
EnsureDependenciesExistsOnAllNodes(&tableAddress);
|
EnsureDependenciesExistOnAllNodes(&tableAddress);
|
||||||
|
|
||||||
/* don't allow the table to be dropped */
|
/* don't allow the table to be dropped */
|
||||||
LockRelationOid(relationId, AccessShareLock);
|
LockRelationOid(relationId, AccessShareLock);
|
||||||
|
|
|
@ -46,8 +46,8 @@ typedef struct ObjectAddressCollector
|
||||||
|
|
||||||
/* forward declarations for functions to interact with the ObjectAddressCollector */
|
/* forward declarations for functions to interact with the ObjectAddressCollector */
|
||||||
static void InitObjectAddressCollector(ObjectAddressCollector *collector);
|
static void InitObjectAddressCollector(ObjectAddressCollector *collector);
|
||||||
static void CollectObjectAddress(ObjectAddressCollector *collector, const
|
static void CollectObjectAddress(ObjectAddressCollector *collector,
|
||||||
ObjectAddress *address);
|
const ObjectAddress *address);
|
||||||
static bool IsObjectAddressCollected(const ObjectAddress *findAddress,
|
static bool IsObjectAddressCollected(const ObjectAddress *findAddress,
|
||||||
ObjectAddressCollector *collector);
|
ObjectAddressCollector *collector);
|
||||||
static void MarkObjectVisited(ObjectAddressCollector *collector,
|
static void MarkObjectVisited(ObjectAddressCollector *collector,
|
||||||
|
|
|
@ -394,7 +394,7 @@ MetadataCreateCommands(void)
|
||||||
* visible to all sessions creating shards.
|
* visible to all sessions creating shards.
|
||||||
*/
|
*/
|
||||||
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
|
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
|
||||||
EnsureDependenciesExistsOnAllNodes(&tableAddress);
|
EnsureDependenciesExistOnAllNodes(&tableAddress);
|
||||||
|
|
||||||
metadataSnapshotCommandList = list_concat(metadataSnapshotCommandList,
|
metadataSnapshotCommandList = list_concat(metadataSnapshotCommandList,
|
||||||
workerSequenceDDLCommands);
|
workerSequenceDDLCommands);
|
||||||
|
|
|
@ -35,12 +35,12 @@
|
||||||
|
|
||||||
static void SendCommandToMetadataWorkersParams(const char *command,
|
static void SendCommandToMetadataWorkersParams(const char *command,
|
||||||
const char *user, int parameterCount,
|
const char *user, int parameterCount,
|
||||||
const Oid *parameterTypes, const
|
const Oid *parameterTypes,
|
||||||
char *const *parameterValues);
|
const char *const *parameterValues);
|
||||||
static void SendCommandToWorkersParamsInternal(TargetWorkerSet targetWorkerSet,
|
static void SendCommandToWorkersParamsInternal(TargetWorkerSet targetWorkerSet,
|
||||||
const char *command, const char *user,
|
const char *command, const char *user,
|
||||||
int parameterCount, const
|
int parameterCount,
|
||||||
Oid *parameterTypes,
|
const Oid *parameterTypes,
|
||||||
const char *const *parameterValues);
|
const char *const *parameterValues);
|
||||||
static void ErrorIfAnyMetadataNodeOutOfSync(List *metadataNodeList);
|
static void ErrorIfAnyMetadataNodeOutOfSync(List *metadataNodeList);
|
||||||
static void SendCommandListToAllWorkersInternal(List *commandList, bool failOnError,
|
static void SendCommandListToAllWorkersInternal(List *commandList, bool failOnError,
|
||||||
|
@ -316,8 +316,8 @@ SendBareOptionalCommandListToAllWorkersAsUser(List *commandList, const char *use
|
||||||
static void
|
static void
|
||||||
SendCommandToMetadataWorkersParams(const char *command,
|
SendCommandToMetadataWorkersParams(const char *command,
|
||||||
const char *user, int parameterCount,
|
const char *user, int parameterCount,
|
||||||
const Oid *parameterTypes, const
|
const Oid *parameterTypes,
|
||||||
char *const *parameterValues)
|
const char *const *parameterValues)
|
||||||
{
|
{
|
||||||
List *workerNodeList = TargetWorkerSetNodeList(WORKERS_WITH_METADATA, ShareLock);
|
List *workerNodeList = TargetWorkerSetNodeList(WORKERS_WITH_METADATA, ShareLock);
|
||||||
|
|
||||||
|
@ -340,8 +340,8 @@ SendCommandToMetadataWorkersParams(const char *command,
|
||||||
static void
|
static void
|
||||||
SendCommandToWorkersParamsInternal(TargetWorkerSet targetWorkerSet, const char *command,
|
SendCommandToWorkersParamsInternal(TargetWorkerSet targetWorkerSet, const char *command,
|
||||||
const char *user, int parameterCount,
|
const char *user, int parameterCount,
|
||||||
const Oid *parameterTypes, const
|
const Oid *parameterTypes,
|
||||||
char *const *parameterValues)
|
const char *const *parameterValues)
|
||||||
{
|
{
|
||||||
List *connectionList = NIL;
|
List *connectionList = NIL;
|
||||||
ListCell *connectionCell = NULL;
|
ListCell *connectionCell = NULL;
|
||||||
|
|
|
@ -75,8 +75,8 @@ static ForeignConstraintRelationshipGraph *fConstraintRelationshipGraph = NULL;
|
||||||
|
|
||||||
static void CreateForeignConstraintRelationshipGraph(void);
|
static void CreateForeignConstraintRelationshipGraph(void);
|
||||||
static void PopulateAdjacencyLists(void);
|
static void PopulateAdjacencyLists(void);
|
||||||
static int CompareForeignConstraintRelationshipEdges(const void *leftElement, const
|
static int CompareForeignConstraintRelationshipEdges(const void *leftElement,
|
||||||
void *rightElement);
|
const void *rightElement);
|
||||||
static void AddForeignConstraintRelationshipEdge(Oid referencingOid, Oid referencedOid);
|
static void AddForeignConstraintRelationshipEdge(Oid referencingOid, Oid referencedOid);
|
||||||
static ForeignConstraintRelationshipNode * CreateOrFindNode(HTAB *adjacencyLists, Oid
|
static ForeignConstraintRelationshipNode * CreateOrFindNode(HTAB *adjacencyLists, Oid
|
||||||
relid);
|
relid);
|
||||||
|
@ -360,15 +360,13 @@ PopulateAdjacencyLists(void)
|
||||||
* ForeignConstraintRelationshipEdge using referencing and referenced ids respectively.
|
* ForeignConstraintRelationshipEdge using referencing and referenced ids respectively.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
CompareForeignConstraintRelationshipEdges(const void *leftElement, const
|
CompareForeignConstraintRelationshipEdges(const void *leftElement,
|
||||||
void *rightElement)
|
const void *rightElement)
|
||||||
{
|
{
|
||||||
const ForeignConstraintRelationshipEdge *leftEdge = *((const
|
const ForeignConstraintRelationshipEdge *leftEdge =
|
||||||
ForeignConstraintRelationshipEdge
|
*((const ForeignConstraintRelationshipEdge **) leftElement);
|
||||||
**) leftElement);
|
const ForeignConstraintRelationshipEdge *rightEdge =
|
||||||
const ForeignConstraintRelationshipEdge *rightEdge = *((const
|
*((const ForeignConstraintRelationshipEdge **) rightElement);
|
||||||
ForeignConstraintRelationshipEdge
|
|
||||||
**) rightElement);
|
|
||||||
|
|
||||||
int referencingDiff = leftEdge->referencingRelationOID -
|
int referencingDiff = leftEdge->referencingRelationOID -
|
||||||
rightEdge->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
|
* if the type actually exists instead of adding the IF EXISTS keyword to the
|
||||||
* statement.
|
* statement.
|
||||||
*/
|
*/
|
||||||
const ObjectAddress *address = GetObjectAddressFromParseTree(parseTree, true);
|
ObjectAddress address = GetObjectAddressFromParseTree(parseTree, true);
|
||||||
if (ObjectExists(address))
|
if (ObjectExists(&address))
|
||||||
{
|
{
|
||||||
const char *localSqlStatement = CreateStmtByObjectAddress(address);
|
const char *localSqlStatement = CreateStmtByObjectAddress(&address);
|
||||||
|
|
||||||
if (strcmp(sqlStatement, localSqlStatement) == 0)
|
if (strcmp(sqlStatement, localSqlStatement) == 0)
|
||||||
{
|
{
|
||||||
|
@ -106,9 +106,9 @@ worker_create_or_replace_object(PG_FUNCTION_ARGS)
|
||||||
PG_RETURN_BOOL(false);
|
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);
|
const char *sqlRenameStmt = DeparseTreeNode((Node *) renameStmt);
|
||||||
CitusProcessUtility((Node *) renameStmt, sqlRenameStmt,
|
CitusProcessUtility((Node *) renameStmt, sqlRenameStmt,
|
||||||
PROCESS_UTILITY_TOPLEVEL,
|
PROCESS_UTILITY_TOPLEVEL,
|
||||||
|
|
|
@ -57,6 +57,8 @@ static uint32 FileBufferSizeInBytes = 0; /* file buffer size to init later */
|
||||||
|
|
||||||
|
|
||||||
/* Local functions forward declarations */
|
/* Local functions forward declarations */
|
||||||
|
typedef uint32 (*PartitionIdFunction)(Datum, Oid, const void *);
|
||||||
|
|
||||||
static ShardInterval ** SyntheticShardIntervalArrayForShardMinValues(
|
static ShardInterval ** SyntheticShardIntervalArrayForShardMinValues(
|
||||||
Datum *shardMinValues,
|
Datum *shardMinValues,
|
||||||
int shardCount);
|
int shardCount);
|
||||||
|
@ -69,8 +71,7 @@ static void FileOutputStreamWrite(FileOutputStream *file, StringInfo dataToWrite
|
||||||
static void FileOutputStreamFlush(FileOutputStream *file);
|
static void FileOutputStreamFlush(FileOutputStream *file);
|
||||||
static void FilterAndPartitionTable(const char *filterQuery,
|
static void FilterAndPartitionTable(const char *filterQuery,
|
||||||
const char *columnName, Oid columnType,
|
const char *columnName, Oid columnType,
|
||||||
uint32 (*PartitionIdFunction)(Datum, Oid, const
|
PartitionIdFunction partitionIdFunction,
|
||||||
void *),
|
|
||||||
const void *partitionIdContext,
|
const void *partitionIdContext,
|
||||||
FileOutputStream *partitionFileArray,
|
FileOutputStream *partitionFileArray,
|
||||||
uint32 fileCount);
|
uint32 fileCount);
|
||||||
|
@ -79,10 +80,10 @@ static CopyOutState InitRowOutputState(void);
|
||||||
static void ClearRowOutputState(CopyOutState copyState);
|
static void ClearRowOutputState(CopyOutState copyState);
|
||||||
static void OutputBinaryHeaders(FileOutputStream *partitionFileArray, uint32 fileCount);
|
static void OutputBinaryHeaders(FileOutputStream *partitionFileArray, uint32 fileCount);
|
||||||
static void OutputBinaryFooters(FileOutputStream *partitionFileArray, uint32 fileCount);
|
static void OutputBinaryFooters(FileOutputStream *partitionFileArray, uint32 fileCount);
|
||||||
static uint32 RangePartitionId(Datum partitionValue, Oid partitionCollation, const
|
static uint32 RangePartitionId(Datum partitionValue, Oid partitionCollation,
|
||||||
void *context);
|
const void *context);
|
||||||
static uint32 HashPartitionId(Datum partitionValue, Oid partitionCollation, const
|
static uint32 HashPartitionId(Datum partitionValue, Oid partitionCollation,
|
||||||
void *context);
|
const void *context);
|
||||||
static StringInfo UserPartitionFilename(StringInfo directoryName, uint32 partitionId);
|
static StringInfo UserPartitionFilename(StringInfo directoryName, uint32 partitionId);
|
||||||
static bool FileIsLink(char *filename, struct stat filestat);
|
static bool FileIsLink(char *filename, struct stat filestat);
|
||||||
|
|
||||||
|
@ -854,7 +855,7 @@ FileOutputStreamFlush(FileOutputStream *file)
|
||||||
static void
|
static void
|
||||||
FilterAndPartitionTable(const char *filterQuery,
|
FilterAndPartitionTable(const char *filterQuery,
|
||||||
const char *partitionColumnName, Oid partitionColumnType,
|
const char *partitionColumnName, Oid partitionColumnType,
|
||||||
uint32 (*PartitionIdFunction)(Datum, Oid, const void *),
|
PartitionIdFunction partitionIdFunction,
|
||||||
const void *partitionIdContext,
|
const void *partitionIdContext,
|
||||||
FileOutputStream *partitionFileArray,
|
FileOutputStream *partitionFileArray,
|
||||||
uint32 fileCount)
|
uint32 fileCount)
|
||||||
|
@ -941,7 +942,7 @@ FilterAndPartitionTable(const char *filterQuery,
|
||||||
*/
|
*/
|
||||||
if (!partitionKeyNull)
|
if (!partitionKeyNull)
|
||||||
{
|
{
|
||||||
partitionId = (*PartitionIdFunction)(partitionKey,
|
partitionId = (*partitionIdFunction)(partitionKey,
|
||||||
partitionColumnCollation,
|
partitionColumnCollation,
|
||||||
partitionIdContext);
|
partitionIdContext);
|
||||||
if (partitionId == INVALID_SHARD_INDEX)
|
if (partitionId == INVALID_SHARD_INDEX)
|
||||||
|
|
|
@ -19,62 +19,84 @@
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
#include "tcop/dest.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 */
|
/* cluster.c - forward declarations */
|
||||||
extern List * PlanClusterStmt(ClusterStmt *clusterStmt, const char *clusterCommand);
|
extern List * PreprocessClusterStmt(Node *node, const char *clusterCommand);
|
||||||
|
|
||||||
|
|
||||||
/* call.c */
|
/* call.c */
|
||||||
extern bool CallDistributedProcedureRemotely(CallStmt *callStmt, DestReceiver *dest);
|
extern bool CallDistributedProcedureRemotely(CallStmt *callStmt, DestReceiver *dest);
|
||||||
|
|
||||||
|
|
||||||
/* collation.c - forward declarations */
|
/* collation.c - forward declarations */
|
||||||
extern char * CreateCollationDDL(Oid collationId);
|
extern char * CreateCollationDDL(Oid collationId);
|
||||||
extern List * CreateCollationDDLsIdempotent(Oid collationId);
|
extern List * CreateCollationDDLsIdempotent(Oid collationId);
|
||||||
extern ObjectAddress AlterCollationOwnerObjectAddress(AlterOwnerStmt *stmt);
|
extern ObjectAddress AlterCollationOwnerObjectAddress(Node *stmt, bool missing_ok);
|
||||||
extern List * PlanDropCollationStmt(DropStmt *stmt);
|
extern List * PreprocessDropCollationStmt(Node *stmt, const char *queryString);
|
||||||
extern List * PlanAlterCollationOwnerStmt(AlterOwnerStmt *stmt, const char *queryString);
|
extern List * PreprocessAlterCollationOwnerStmt(Node *stmt, const char *queryString);
|
||||||
extern List * PlanAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt,
|
extern List * PreprocessAlterCollationSchemaStmt(Node *stmt, const char *queryString);
|
||||||
const char *queryString);
|
extern List * PreprocessRenameCollationStmt(Node *stmt, const char *queryString);
|
||||||
extern List * PlanRenameCollationStmt(RenameStmt *stmt, const char *queryString);
|
extern ObjectAddress RenameCollationStmtObjectAddress(Node *stmt, bool missing_ok);
|
||||||
extern ObjectAddress * RenameCollationStmtObjectAddress(RenameStmt *stmt,
|
extern ObjectAddress AlterCollationSchemaStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress * AlterCollationSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt,
|
extern List * PostprocessAlterCollationSchemaStmt(Node *stmt, const char *queryString);
|
||||||
bool missing_ok);
|
|
||||||
extern void ProcessAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt,
|
|
||||||
const char *queryString);
|
|
||||||
extern char * GenerateBackupNameForCollationCollision(const ObjectAddress *address);
|
extern char * GenerateBackupNameForCollationCollision(const ObjectAddress *address);
|
||||||
extern ObjectAddress * DefineCollationStmtObjectAddress(DefineStmt *stmt, bool
|
extern ObjectAddress DefineCollationStmtObjectAddress(Node *stmt, bool missing_ok);
|
||||||
missing_ok);
|
extern List * PostprocessDefineCollationStmt(Node *stmt, const char *queryString);
|
||||||
extern List * ProcessCollationDefineStmt(DefineStmt *stmt, const char *queryString);
|
|
||||||
|
|
||||||
/* extension.c - forward declarations */
|
/* extension.c - forward declarations */
|
||||||
extern bool IsCreateAlterExtensionUpdateCitusStmt(Node *parsetree);
|
extern bool IsCreateAlterExtensionUpdateCitusStmt(Node *parsetree);
|
||||||
extern void ErrorIfUnstableCreateOrAlterExtensionStmt(Node *parsetree);
|
extern void ErrorIfUnstableCreateOrAlterExtensionStmt(Node *parsetree);
|
||||||
extern List * PlanCreateExtensionStmt(CreateExtensionStmt *stmt, const char *queryString);
|
extern List * PostprocessCreateExtensionStmt(Node *stmt, const char *queryString);
|
||||||
extern void ProcessCreateExtensionStmt(CreateExtensionStmt *stmt, const
|
extern List * PreprocessDropExtensionStmt(Node *stmt, const char *queryString);
|
||||||
char *queryString);
|
extern List * PreprocessAlterExtensionSchemaStmt(Node *stmt,
|
||||||
extern List * PlanDropExtensionStmt(DropStmt *stmt, const char *queryString);
|
const char *queryString);
|
||||||
extern List * PlanAlterExtensionSchemaStmt(AlterObjectSchemaStmt *alterExtensionStmt,
|
extern List * PostprocessAlterExtensionSchemaStmt(Node *stmt,
|
||||||
const char *queryString);
|
const char *queryString);
|
||||||
extern void ProcessAlterExtensionSchemaStmt(AlterObjectSchemaStmt *alterExtensionStmt,
|
extern List * PreprocessAlterExtensionUpdateStmt(Node *stmt,
|
||||||
const char *queryString);
|
const char *queryString);
|
||||||
extern List * PlanAlterExtensionUpdateStmt(AlterExtensionStmt *alterExtensionStmt, const
|
extern List * PreprocessAlterExtensionContentsStmt(Node *node,
|
||||||
char *queryString);
|
const char *queryString);
|
||||||
extern List * CreateExtensionDDLCommand(const ObjectAddress *extensionAddress);
|
extern List * CreateExtensionDDLCommand(const ObjectAddress *extensionAddress);
|
||||||
extern ObjectAddress * AlterExtensionSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt,
|
extern ObjectAddress AlterExtensionSchemaStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress * AlterExtensionUpdateStmtObjectAddress(
|
extern ObjectAddress AlterExtensionUpdateStmtObjectAddress(Node *stmt,
|
||||||
AlterExtensionStmt *alterExtensionStmt,
|
bool missing_ok);
|
||||||
bool missing_ok);
|
|
||||||
|
|
||||||
|
|
||||||
/* foreign_constraint.c - forward declarations */
|
/* foreign_constraint.c - forward declarations */
|
||||||
extern bool ConstraintIsAForeignKeyToReferenceTable(char *constraintName,
|
extern bool ConstraintIsAForeignKeyToReferenceTable(char *constraintName,
|
||||||
Oid leftRelationId);
|
Oid leftRelationId);
|
||||||
extern void ErrorIfUnsupportedForeignConstraintExists(Relation relation, char
|
extern void ErrorIfUnsupportedForeignConstraintExists(Relation relation,
|
||||||
distributionMethod,
|
char distributionMethod,
|
||||||
Var *distributionColumn, uint32
|
Var *distributionColumn,
|
||||||
colocationId);
|
uint32 colocationId);
|
||||||
extern bool ColumnAppearsInForeignKeyToReferenceTable(char *columnName, Oid
|
extern bool ColumnAppearsInForeignKeyToReferenceTable(char *columnName, Oid
|
||||||
relationId);
|
relationId);
|
||||||
extern List * GetTableForeignConstraintCommands(Oid relationId);
|
extern List * GetTableForeignConstraintCommands(Oid relationId);
|
||||||
|
@ -85,58 +107,62 @@ extern bool ConstraintIsAForeignKey(char *constraintName, Oid relationId);
|
||||||
|
|
||||||
|
|
||||||
/* function.c - forward declarations */
|
/* function.c - forward declarations */
|
||||||
extern List * PlanCreateFunctionStmt(CreateFunctionStmt *stmt, const char *queryString);
|
extern List * PreprocessCreateFunctionStmt(Node *stmt, const char *queryString);
|
||||||
extern List * ProcessCreateFunctionStmt(CreateFunctionStmt *stmt, const
|
extern List * PostprocessCreateFunctionStmt(Node *stmt,
|
||||||
char *queryString);
|
const char *queryString);
|
||||||
extern ObjectAddress * CreateFunctionStmtObjectAddress(CreateFunctionStmt *stmt,
|
extern ObjectAddress CreateFunctionStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress * DefineAggregateStmtObjectAddress(DefineStmt *stmt, bool
|
extern ObjectAddress DefineAggregateStmtObjectAddress(Node *stmt,
|
||||||
missing_ok);
|
|
||||||
extern List * PlanAlterFunctionStmt(AlterFunctionStmt *stmt, const char *queryString);
|
|
||||||
extern ObjectAddress * AlterFunctionStmtObjectAddress(AlterFunctionStmt *stmt,
|
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern List * PlanRenameFunctionStmt(RenameStmt *stmt, const char *queryString);
|
extern List * PreprocessAlterFunctionStmt(Node *stmt, const char *queryString);
|
||||||
extern ObjectAddress * RenameFunctionStmtObjectAddress(RenameStmt *stmt,
|
extern ObjectAddress AlterFunctionStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern List * PlanAlterFunctionOwnerStmt(AlterOwnerStmt *stmt, const char *queryString);
|
extern List * PreprocessRenameFunctionStmt(Node *stmt, const char *queryString);
|
||||||
extern ObjectAddress * AlterFunctionOwnerObjectAddress(AlterOwnerStmt *stmt,
|
extern ObjectAddress RenameFunctionStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern List * PlanAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt,
|
extern List * PreprocessAlterFunctionOwnerStmt(Node *stmt, const char *queryString);
|
||||||
const char *queryString);
|
extern ObjectAddress AlterFunctionOwnerObjectAddress(Node *stmt,
|
||||||
extern ObjectAddress * AlterFunctionSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt,
|
bool missing_ok);
|
||||||
bool missing_ok);
|
extern List * PreprocessAlterFunctionSchemaStmt(Node *stmt, const char *queryString);
|
||||||
extern void ProcessAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt,
|
extern ObjectAddress AlterFunctionSchemaStmtObjectAddress(Node *stmt,
|
||||||
const char *queryString);
|
bool missing_ok);
|
||||||
extern List * PlanDropFunctionStmt(DropStmt *stmt, const char *queryString);
|
extern List * PostprocessAlterFunctionSchemaStmt(Node *stmt,
|
||||||
extern List * PlanAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt,
|
const char *queryString);
|
||||||
const char *queryString);
|
extern List * PreprocessDropFunctionStmt(Node *stmt, const char *queryString);
|
||||||
extern ObjectAddress * AlterFunctionDependsStmtObjectAddress(AlterObjectDependsStmt *stmt,
|
extern List * PreprocessAlterFunctionDependsStmt(Node *stmt,
|
||||||
bool missing_ok);
|
const char *queryString);
|
||||||
|
extern ObjectAddress AlterFunctionDependsStmtObjectAddress(Node *stmt,
|
||||||
|
bool missing_ok);
|
||||||
|
|
||||||
|
|
||||||
/* grant.c - forward declarations */
|
/* grant.c - forward declarations */
|
||||||
extern List * PlanGrantStmt(GrantStmt *grantStmt);
|
extern List * PreprocessGrantStmt(Node *node, const char *queryString);
|
||||||
|
|
||||||
|
|
||||||
/* index.c - forward declarations */
|
/* index.c - forward declarations */
|
||||||
extern bool IsIndexRenameStmt(RenameStmt *renameStmt);
|
extern bool IsIndexRenameStmt(RenameStmt *renameStmt);
|
||||||
extern List * PlanIndexStmt(IndexStmt *createIndexStatement,
|
extern List * PreprocessIndexStmt(Node *createIndexStatement,
|
||||||
const char *createIndexCommand);
|
const char *createIndexCommand);
|
||||||
extern List * PlanReindexStmt(ReindexStmt *ReindexStatement,
|
extern List * PreprocessReindexStmt(Node *ReindexStatement,
|
||||||
const char *ReindexCommand);
|
const char *ReindexCommand);
|
||||||
extern List * PlanDropIndexStmt(DropStmt *dropIndexStatement,
|
extern List * PreprocessDropIndexStmt(Node *dropIndexStatement,
|
||||||
const char *dropIndexCommand);
|
const char *dropIndexCommand);
|
||||||
extern void PostProcessIndexStmt(IndexStmt *indexStmt);
|
extern List * PostprocessIndexStmt(Node *node,
|
||||||
|
const char *queryString);
|
||||||
extern void ErrorIfUnsupportedAlterIndexStmt(AlterTableStmt *alterTableStatement);
|
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 */
|
/* policy.c - forward declarations */
|
||||||
extern List * CreatePolicyCommands(Oid relationId);
|
extern List * CreatePolicyCommands(Oid relationId);
|
||||||
extern void ErrorIfUnsupportedPolicy(Relation relation);
|
extern void ErrorIfUnsupportedPolicy(Relation relation);
|
||||||
extern void ErrorIfUnsupportedPolicyExpr(Node *expr);
|
extern void ErrorIfUnsupportedPolicyExpr(Node *expr);
|
||||||
extern List * PlanCreatePolicyStmt(CreatePolicyStmt *stmt);
|
extern List * PreprocessCreatePolicyStmt(Node *node, const char *queryString);
|
||||||
extern List * PlanAlterPolicyStmt(AlterPolicyStmt *stmt);
|
extern List * PreprocessAlterPolicyStmt(Node *node, const char *queryString);
|
||||||
extern List * PlanDropPolicyStmt(DropStmt *stmt, const char *queryString);
|
extern List * PreprocessDropPolicyStmt(Node *stmt, const char *queryString);
|
||||||
extern bool IsPolicyRenameStmt(RenameStmt *stmt);
|
extern bool IsPolicyRenameStmt(RenameStmt *stmt);
|
||||||
extern void CreatePolicyEventExtendNames(CreatePolicyStmt *stmt, const char *schemaName,
|
extern void CreatePolicyEventExtendNames(CreatePolicyStmt *stmt, const char *schemaName,
|
||||||
uint64 shardId);
|
uint64 shardId);
|
||||||
|
@ -149,24 +175,23 @@ extern void DropPolicyEventExtendNames(DropStmt *stmt, const char *schemaName, u
|
||||||
|
|
||||||
|
|
||||||
/* rename.c - forward declarations*/
|
/* 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 void ErrorIfUnsupportedRenameStmt(RenameStmt *renameStmt);
|
||||||
|
extern List * PreprocessRenameAttributeStmt(Node *stmt, const char *queryString);
|
||||||
|
|
||||||
|
|
||||||
/* role.c - forward declarations*/
|
/* role.c - forward declarations*/
|
||||||
extern List * ProcessAlterRoleStmt(AlterRoleStmt *stmt, const char *queryString);
|
extern List * PostprocessAlterRoleStmt(Node *stmt, const char *queryString);
|
||||||
extern List * GenerateAlterRoleIfExistsCommandAllRoles(void);
|
extern List * GenerateAlterRoleIfExistsCommandAllRoles(void);
|
||||||
|
|
||||||
|
|
||||||
/* schema.c - forward declarations */
|
/* schema.c - forward declarations */
|
||||||
extern void ProcessDropSchemaStmt(DropStmt *dropSchemaStatement);
|
extern List * PreprocessDropSchemaStmt(Node *dropSchemaStatement,
|
||||||
extern List * PlanAlterTableSchemaStmt(AlterObjectSchemaStmt *stmt,
|
|
||||||
const char *queryString);
|
const char *queryString);
|
||||||
extern List * PlanAlterObjectSchemaStmt(AlterObjectSchemaStmt *alterObjectSchemaStmt,
|
extern List * PreprocessAlterTableSchemaStmt(Node *stmt,
|
||||||
const char *alterObjectSchemaCommand);
|
const char *queryString);
|
||||||
|
extern List * PreprocessAlterObjectSchemaStmt(Node *alterObjectSchemaStmt,
|
||||||
extern void ProcessAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt,
|
const char *alterObjectSchemaCommand);
|
||||||
const char *queryString);
|
|
||||||
|
|
||||||
|
|
||||||
/* sequence.c - forward declarations */
|
/* sequence.c - forward declarations */
|
||||||
|
@ -179,16 +204,19 @@ extern Node * ProcessCreateSubscriptionStmt(CreateSubscriptionStmt *createSubStm
|
||||||
|
|
||||||
|
|
||||||
/* table.c - forward declarations */
|
/* table.c - forward declarations */
|
||||||
extern void ProcessDropTableStmt(DropStmt *dropTableStatement);
|
extern List * PreprocessDropTableStmt(Node *stmt, const char *queryString);
|
||||||
extern void ProcessCreateTableStmtPartitionOf(CreateStmt *createStatement);
|
extern List * PostprocessCreateTableStmtPartitionOf(CreateStmt *createStatement,
|
||||||
extern void ProcessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement);
|
const char *queryString);
|
||||||
extern List * PlanAlterTableStmt(AlterTableStmt *alterTableStatement,
|
extern List * PostprocessAlterTableStmtAttachPartition(
|
||||||
const char *alterTableCommand);
|
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,
|
extern Node * WorkerProcessAlterTableStmt(AlterTableStmt *alterTableStatement,
|
||||||
const char *alterTableCommand);
|
const char *alterTableCommand);
|
||||||
extern bool IsAlterTableRenameStmt(RenameStmt *renameStmt);
|
extern bool IsAlterTableRenameStmt(RenameStmt *renameStmt);
|
||||||
extern void ErrorIfAlterDropsPartitionColumn(AlterTableStmt *alterTableStatement);
|
extern void ErrorIfAlterDropsPartitionColumn(AlterTableStmt *alterTableStatement);
|
||||||
extern void PostProcessAlterTableStmt(AlterTableStmt *pStmt);
|
extern void PostprocessAlterTableStmt(AlterTableStmt *pStmt);
|
||||||
extern void ErrorUnsupportedAlterTableAddColumn(Oid relationId, AlterTableCmd *command,
|
extern void ErrorUnsupportedAlterTableAddColumn(Oid relationId, AlterTableCmd *command,
|
||||||
Constraint *constraint);
|
Constraint *constraint);
|
||||||
extern void ErrorIfUnsupportedConstraint(Relation relation, char distributionMethod,
|
extern void ErrorIfUnsupportedConstraint(Relation relation, char distributionMethod,
|
||||||
|
@ -196,36 +224,33 @@ extern void ErrorIfUnsupportedConstraint(Relation relation, char distributionMet
|
||||||
|
|
||||||
|
|
||||||
/* truncate.c - forward declarations */
|
/* truncate.c - forward declarations */
|
||||||
extern void ProcessTruncateStatement(TruncateStmt *truncateStatement);
|
extern void PostprocessTruncateStatement(TruncateStmt *truncateStatement);
|
||||||
|
|
||||||
/* type.c - forward declarations */
|
/* type.c - forward declarations */
|
||||||
extern List * PlanCompositeTypeStmt(CompositeTypeStmt *stmt, const char *queryString);
|
extern List * PreprocessCompositeTypeStmt(Node *stmt, const char *queryString);
|
||||||
extern void ProcessCompositeTypeStmt(CompositeTypeStmt *stmt, const char *queryString);
|
extern List * PostprocessCompositeTypeStmt(Node *stmt, const char *queryString);
|
||||||
extern List * PlanAlterTypeStmt(AlterTableStmt *stmt, const char *queryString);
|
extern List * PreprocessAlterTypeStmt(Node *stmt, const char *queryString);
|
||||||
extern List * PlanCreateEnumStmt(CreateEnumStmt *createEnumStmt, const char *queryString);
|
extern List * PreprocessCreateEnumStmt(Node *stmt, const char *queryString);
|
||||||
extern void ProcessCreateEnumStmt(CreateEnumStmt *stmt, const char *queryString);
|
extern List * PostprocessCreateEnumStmt(Node *stmt, const char *queryString);
|
||||||
extern List * PlanAlterEnumStmt(AlterEnumStmt *stmt, const char *queryString);
|
extern List * PreprocessAlterEnumStmt(Node *stmt, const char *queryString);
|
||||||
extern void ProcessAlterEnumStmt(AlterEnumStmt *stmt, const char *queryString);
|
extern List * PostprocessAlterEnumStmt(Node *stmt, const char *queryString);
|
||||||
extern List * PlanDropTypeStmt(DropStmt *stmt, const char *queryString);
|
extern List * PreprocessDropTypeStmt(Node *stmt, const char *queryString);
|
||||||
extern List * PlanRenameTypeStmt(RenameStmt *stmt, const char *queryString);
|
extern List * PreprocessRenameTypeStmt(Node *stmt, const char *queryString);
|
||||||
extern List * PlanRenameTypeAttributeStmt(RenameStmt *stmt, const char *queryString);
|
extern List * PreprocessRenameTypeAttributeStmt(Node *stmt, const char *queryString);
|
||||||
extern List * PlanAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt,
|
extern List * PreprocessAlterTypeSchemaStmt(Node *stmt, const char *queryString);
|
||||||
const char *queryString);
|
extern List * PreprocessAlterTypeOwnerStmt(Node *stmt, const char *queryString);
|
||||||
extern List * PlanAlterTypeOwnerStmt(AlterOwnerStmt *stmt, const char *queryString);
|
extern List * PostprocessAlterTypeSchemaStmt(Node *stmt, const char *queryString);
|
||||||
extern void ProcessAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt,
|
|
||||||
const char *queryString);
|
|
||||||
extern Node * CreateTypeStmtByObjectAddress(const ObjectAddress *address);
|
extern Node * CreateTypeStmtByObjectAddress(const ObjectAddress *address);
|
||||||
extern ObjectAddress * CompositeTypeStmtObjectAddress(CompositeTypeStmt *stmt, bool
|
extern ObjectAddress CompositeTypeStmtObjectAddress(Node *stmt, bool missing_ok);
|
||||||
missing_ok);
|
extern ObjectAddress CreateEnumStmtObjectAddress(Node *stmt, bool missing_ok);
|
||||||
extern ObjectAddress * CreateEnumStmtObjectAddress(CreateEnumStmt *stmt, bool missing_ok);
|
extern ObjectAddress AlterTypeStmtObjectAddress(Node *stmt, bool missing_ok);
|
||||||
extern ObjectAddress * AlterTypeStmtObjectAddress(AlterTableStmt *stmt, bool missing_ok);
|
extern ObjectAddress AlterEnumStmtObjectAddress(Node *stmt, bool missing_ok);
|
||||||
extern ObjectAddress * AlterEnumStmtObjectAddress(AlterEnumStmt *stmt, bool missing_ok);
|
extern ObjectAddress RenameTypeStmtObjectAddress(Node *stmt, bool missing_ok);
|
||||||
extern ObjectAddress * RenameTypeStmtObjectAddress(RenameStmt *stmt, bool missing_ok);
|
extern ObjectAddress AlterTypeSchemaStmtObjectAddress(Node *stmt,
|
||||||
extern ObjectAddress * AlterTypeSchemaStmtObjectAddress(AlterObjectSchemaStmt *stmt,
|
bool missing_ok);
|
||||||
bool missing_ok);
|
extern ObjectAddress RenameTypeAttributeStmtObjectAddress(Node *stmt,
|
||||||
extern ObjectAddress * RenameTypeAttributeStmtObjectAddress(RenameStmt *stmt, bool
|
bool missing_ok);
|
||||||
missing_ok);
|
extern ObjectAddress AlterTypeOwnerObjectAddress(Node *stmt, bool missing_ok);
|
||||||
extern ObjectAddress * AlterTypeOwnerObjectAddress(AlterOwnerStmt *stmt, bool missing_ok);
|
|
||||||
extern List * CreateTypeDDLCommandsIdempotent(const ObjectAddress *typeAddress);
|
extern List * CreateTypeDDLCommandsIdempotent(const ObjectAddress *typeAddress);
|
||||||
extern char * GenerateBackupNameForTypeCollision(const ObjectAddress *address);
|
extern char * GenerateBackupNameForTypeCollision(const ObjectAddress *address);
|
||||||
|
|
||||||
|
@ -236,9 +261,9 @@ extern char * GenerateBackupNameForProcCollision(const ObjectAddress *address);
|
||||||
extern ObjectWithArgs * ObjectWithArgsFromOid(Oid funcOid);
|
extern ObjectWithArgs * ObjectWithArgsFromOid(Oid funcOid);
|
||||||
|
|
||||||
/* vacuum.c - froward declarations */
|
/* 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 bool ShouldPropagateSetCommand(VariableSetStmt *setStmt);
|
||||||
extern void ProcessVariableSetStmt(VariableSetStmt *setStmt, const char *setCommand);
|
extern void PostprocessVariableSetStmt(VariableSetStmt *setStmt, const char *setCommand);
|
||||||
|
|
||||||
#endif /*CITUS_COMMANDS_H */
|
#endif /*CITUS_COMMANDS_H */
|
||||||
|
|
|
@ -209,8 +209,8 @@ extern MultiConnection * GetNodeConnection(uint32 flags, const char *hostname,
|
||||||
extern MultiConnection * StartNodeConnection(uint32 flags, const char *hostname,
|
extern MultiConnection * StartNodeConnection(uint32 flags, const char *hostname,
|
||||||
int32 port);
|
int32 port);
|
||||||
extern MultiConnection * GetNodeUserDatabaseConnection(uint32 flags, const char *hostname,
|
extern MultiConnection * GetNodeUserDatabaseConnection(uint32 flags, const char *hostname,
|
||||||
int32 port, const char *user, const
|
int32 port, const char *user,
|
||||||
char *database);
|
const char *database);
|
||||||
extern List * StartWorkerListConnections(List *workerList, uint32 flags, const char *user,
|
extern List * StartWorkerListConnections(List *workerList, uint32 flags, const char *user,
|
||||||
const char *database);
|
const char *database);
|
||||||
extern MultiConnection * StartNodeUserDatabaseConnection(uint32 flags,
|
extern MultiConnection * StartNodeUserDatabaseConnection(uint32 flags,
|
||||||
|
|
|
@ -32,64 +32,68 @@ extern void AssertObjectTypeIsFunctional(ObjectType type);
|
||||||
extern void QualifyTreeNode(Node *stmt);
|
extern void QualifyTreeNode(Node *stmt);
|
||||||
extern char * DeparseTreeNode(Node *stmt);
|
extern char * DeparseTreeNode(Node *stmt);
|
||||||
|
|
||||||
/* forward declarations for deparse_collation_stmts.c */
|
/* forward declarations for deparse_attribute_stmts.c */
|
||||||
extern char * DeparseDropCollationStmt(DropStmt *stmt);
|
extern char * DeparseRenameAttributeStmt(Node *);
|
||||||
extern char * DeparseRenameCollationStmt(RenameStmt *stmt);
|
|
||||||
extern char * DeparseAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt);
|
|
||||||
extern char * DeparseAlterCollationOwnerStmt(AlterOwnerStmt *stmt);
|
|
||||||
|
|
||||||
extern void QualifyDropCollationStmt(DropStmt *stmt);
|
/* forward declarations for deparse_collation_stmts.c */
|
||||||
extern void QualifyRenameCollationStmt(RenameStmt *stmt);
|
extern char * DeparseDropCollationStmt(Node *stmt);
|
||||||
extern void QualifyAlterCollationSchemaStmt(AlterObjectSchemaStmt *stmt);
|
extern char * DeparseRenameCollationStmt(Node *stmt);
|
||||||
extern void QualifyAlterCollationOwnerStmt(AlterOwnerStmt *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 */
|
/* forward declarations for deparse_type_stmts.c */
|
||||||
extern char * DeparseCompositeTypeStmt(CompositeTypeStmt *stmt);
|
extern char * DeparseCompositeTypeStmt(Node *stmt);
|
||||||
extern char * DeparseCreateEnumStmt(CreateEnumStmt *stmt);
|
extern char * DeparseCreateEnumStmt(Node *stmt);
|
||||||
extern char * DeparseDropTypeStmt(DropStmt *stmt);
|
extern char * DeparseDropTypeStmt(Node *stmt);
|
||||||
extern char * DeparseAlterEnumStmt(AlterEnumStmt *stmt);
|
extern char * DeparseAlterEnumStmt(Node *stmt);
|
||||||
extern char * DeparseAlterTypeStmt(AlterTableStmt *stmt);
|
extern char * DeparseAlterTypeStmt(Node *stmt);
|
||||||
extern char * DeparseRenameTypeStmt(RenameStmt *stmt);
|
extern char * DeparseRenameTypeStmt(Node *stmt);
|
||||||
extern char * DeparseRenameTypeAttributeStmt(RenameStmt *stmt);
|
extern char * DeparseRenameTypeAttributeStmt(Node *stmt);
|
||||||
extern char * DeparseAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt);
|
extern char * DeparseAlterTypeSchemaStmt(Node *stmt);
|
||||||
extern char * DeparseAlterTypeOwnerStmt(AlterOwnerStmt *stmt);
|
extern char * DeparseAlterTypeOwnerStmt(Node *stmt);
|
||||||
|
|
||||||
extern void QualifyRenameTypeStmt(RenameStmt *stmt);
|
extern void QualifyRenameAttributeStmt(Node *stmt);
|
||||||
extern void QualifyRenameTypeAttributeStmt(RenameStmt *stmt);
|
extern void QualifyRenameTypeStmt(Node *stmt);
|
||||||
extern void QualifyAlterEnumStmt(AlterEnumStmt *stmt);
|
extern void QualifyRenameTypeAttributeStmt(Node *stmt);
|
||||||
extern void QualifyAlterTypeStmt(AlterTableStmt *stmt);
|
extern void QualifyAlterEnumStmt(Node *stmt);
|
||||||
extern void QualifyCompositeTypeStmt(CompositeTypeStmt *stmt);
|
extern void QualifyAlterTypeStmt(Node *stmt);
|
||||||
extern void QualifyCreateEnumStmt(CreateEnumStmt *stmt);
|
extern void QualifyCompositeTypeStmt(Node *stmt);
|
||||||
extern void QualifyAlterTypeSchemaStmt(AlterObjectSchemaStmt *stmt);
|
extern void QualifyCreateEnumStmt(Node *stmt);
|
||||||
extern void QualifyAlterTypeOwnerStmt(AlterOwnerStmt *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 */
|
/* forward declarations for deparse_function_stmts.c */
|
||||||
extern char * DeparseDropFunctionStmt(DropStmt *stmt);
|
extern char * DeparseDropFunctionStmt(Node *stmt);
|
||||||
extern char * DeparseAlterFunctionStmt(AlterFunctionStmt *stmt);
|
extern char * DeparseAlterFunctionStmt(Node *stmt);
|
||||||
|
|
||||||
extern char * DeparseRenameFunctionStmt(RenameStmt *stmt);
|
extern char * DeparseRenameFunctionStmt(Node *stmt);
|
||||||
extern char * DeparseAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt);
|
extern char * DeparseAlterFunctionSchemaStmt(Node *stmt);
|
||||||
extern char * DeparseAlterFunctionOwnerStmt(AlterOwnerStmt *stmt);
|
extern char * DeparseAlterFunctionOwnerStmt(Node *stmt);
|
||||||
extern char * DeparseAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt);
|
extern char * DeparseAlterFunctionDependsStmt(Node *stmt);
|
||||||
|
|
||||||
extern void QualifyAlterFunctionStmt(AlterFunctionStmt *stmt);
|
extern void QualifyAlterFunctionStmt(Node *stmt);
|
||||||
extern void QualifyRenameFunctionStmt(RenameStmt *stmt);
|
extern void QualifyRenameFunctionStmt(Node *stmt);
|
||||||
extern void QualifyAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt);
|
extern void QualifyAlterFunctionSchemaStmt(Node *stmt);
|
||||||
extern void QualifyAlterFunctionOwnerStmt(AlterOwnerStmt *stmt);
|
extern void QualifyAlterFunctionOwnerStmt(Node *stmt);
|
||||||
extern void QualifyAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt);
|
extern void QualifyAlterFunctionDependsStmt(Node *stmt);
|
||||||
|
|
||||||
/* forward declarations for deparse_role_stmts.c */
|
/* forward declarations for deparse_role_stmts.c */
|
||||||
extern char * DeparseAlterRoleStmt(AlterRoleStmt *stmt);
|
extern char * DeparseAlterRoleStmt(Node *stmt);
|
||||||
|
|
||||||
/* forward declarations for deparse_extension_stmts.c */
|
/* forward declarations for deparse_extension_stmts.c */
|
||||||
extern Value * GetExtensionOption(List *extensionOptions, const
|
extern Value * GetExtensionOption(List *extensionOptions,
|
||||||
char *defname);
|
const char *defname);
|
||||||
extern char * DeparseCreateExtensionStmt(CreateExtensionStmt *stmt);
|
extern char * DeparseCreateExtensionStmt(Node *stmt);
|
||||||
extern char * DeparseDropExtensionStmt(DropStmt *stmt);
|
extern char * DeparseDropExtensionStmt(Node *stmt);
|
||||||
extern char * DeparseAlterExtensionSchemaStmt(
|
extern char * DeparseAlterExtensionSchemaStmt(Node *stmt);
|
||||||
AlterObjectSchemaStmt *alterExtensionSchemaStmt);
|
extern char * DeparseAlterExtensionStmt(Node *stmt);
|
||||||
extern char * DeparseAlterExtensionStmt(AlterExtensionStmt *alterExtensionStmt);
|
|
||||||
|
|
||||||
#endif /* CITUS_DEPARSER_H */
|
#endif /* CITUS_DEPARSER_H */
|
||||||
|
|
|
@ -38,8 +38,8 @@ typedef struct DeferredErrorMessage
|
||||||
DeferredErrorInternal(code, message, detail, hint, __FILE__, __LINE__, \
|
DeferredErrorInternal(code, message, detail, hint, __FILE__, __LINE__, \
|
||||||
PG_FUNCNAME_MACRO)
|
PG_FUNCNAME_MACRO)
|
||||||
|
|
||||||
DeferredErrorMessage * DeferredErrorInternal(int code, const char *message, const
|
DeferredErrorMessage * DeferredErrorInternal(int code, const char *message,
|
||||||
char *detail, const char *hint,
|
const char *detail, const char *hint,
|
||||||
const char *filename, int linenumber, const
|
const char *filename, int linenumber, const
|
||||||
char *functionname);
|
char *functionname);
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ extern void CreateDistributedTable(Oid relationId, Var *distributionColumn,
|
||||||
bool viaDeprecatedAPI);
|
bool viaDeprecatedAPI);
|
||||||
extern void CreateTruncateTrigger(Oid relationId);
|
extern void CreateTruncateTrigger(Oid relationId);
|
||||||
|
|
||||||
extern void EnsureDependenciesExistsOnAllNodes(const ObjectAddress *target);
|
extern void EnsureDependenciesExistOnAllNodes(const ObjectAddress *target);
|
||||||
extern bool ShouldPropagate(void);
|
extern bool ShouldPropagate(void);
|
||||||
extern bool ShouldPropagateObject(const ObjectAddress *address);
|
extern bool ShouldPropagateObject(const ObjectAddress *address);
|
||||||
extern void ReplicateAllDependenciesToNode(const char *nodeName, int nodePort);
|
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,
|
extern int CompareShardIntervals(const void *leftElement, const void *rightElement,
|
||||||
SortShardIntervalContext *sortContext);
|
SortShardIntervalContext *sortContext);
|
||||||
extern int CompareShardIntervalsById(const void *leftElement, const void *rightElement);
|
extern int CompareShardIntervalsById(const void *leftElement, const void *rightElement);
|
||||||
extern int CompareShardPlacementsByShardId(const void *leftElement, const
|
extern int CompareShardPlacementsByShardId(const void *leftElement,
|
||||||
void *rightElement);
|
const void *rightElement);
|
||||||
extern int CompareRelationShards(const void *leftElement,
|
extern int CompareRelationShards(const void *leftElement,
|
||||||
const void *rightElement);
|
const void *rightElement);
|
||||||
extern int ShardIndex(ShardInterval *shardInterval);
|
extern int ShardIndex(ShardInterval *shardInterval);
|
||||||
|
|
|
@ -32,9 +32,8 @@ typedef enum TargetWorkerSet
|
||||||
extern List * GetWorkerTransactions(void);
|
extern List * GetWorkerTransactions(void);
|
||||||
extern List * TargetWorkerSetNodeList(TargetWorkerSet targetWorkerSet, LOCKMODE lockMode);
|
extern List * TargetWorkerSetNodeList(TargetWorkerSet targetWorkerSet, LOCKMODE lockMode);
|
||||||
extern void SendCommandToWorker(char *nodeName, int32 nodePort, const char *command);
|
extern void SendCommandToWorker(char *nodeName, int32 nodePort, const char *command);
|
||||||
extern void SendCommandToWorkersAsUser(TargetWorkerSet targetWorkerSet, const
|
extern void SendCommandToWorkersAsUser(TargetWorkerSet targetWorkerSet,
|
||||||
char *nodeUser,
|
const char *nodeUser, const char *command);
|
||||||
const char *command);
|
|
||||||
extern void SendCommandToWorkerAsUser(char *nodeName, int32 nodePort,
|
extern void SendCommandToWorkerAsUser(char *nodeName, int32 nodePort,
|
||||||
const char *nodeUser, const char *command);
|
const char *nodeUser, const char *command);
|
||||||
extern void SendCommandToWorkersWithMetadata(const char *command);
|
extern void SendCommandToWorkersWithMetadata(const char *command);
|
||||||
|
|
Loading…
Reference in New Issue