Merge remote-tracking branch 'origin' into users/saawasek/non_blocking_split_integrated

users/saawasek/non_blocking_split_integrated
Sameer Awasekar 2022-07-21 11:19:27 +05:30
commit 9e88c14096
187 changed files with 3387 additions and 10421 deletions

View File

@ -128,7 +128,7 @@ jobs:
name: 'Configure'
command: |
chown -R circleci .
gosu circleci ./configure
gosu circleci ./configure --without-pg-version-check
- run:
name: 'Enable core dumps'
command: |
@ -209,7 +209,7 @@ jobs:
name: 'Configure'
command: |
chown -R circleci .
gosu circleci ./configure
gosu circleci ./configure --without-pg-version-check
- run:
name: 'Enable core dumps'
command: |
@ -283,7 +283,7 @@ jobs:
name: 'Configure'
command: |
chown -R circleci .
gosu circleci ./configure
gosu circleci ./configure --without-pg-version-check
- run:
name: 'Enable core dumps'
command: |
@ -371,7 +371,7 @@ jobs:
name: 'Configure'
command: |
chown -R circleci .
gosu circleci ./configure
gosu circleci ./configure --without-pg-version-check
- run:
name: 'Enable core dumps'
command: |
@ -448,7 +448,7 @@ jobs:
name: 'Configure'
command: |
chown -R circleci .
gosu circleci ./configure
gosu circleci ./configure --without-pg-version-check
- run:
name: 'Enable core dumps'
command: |

View File

@ -64,8 +64,8 @@ $(citus_top_builddir)/Makefile.global: $(citus_abs_top_srcdir)/configure $(citus
$(citus_top_builddir)/config.status: $(citus_abs_top_srcdir)/configure $(citus_abs_top_srcdir)/src/backend/distributed/citus.control
cd @abs_top_builddir@ && ./config.status --recheck && ./config.status
# Regenerate configure if configure.in changed
$(citus_abs_top_srcdir)/configure: $(citus_abs_top_srcdir)/configure.in
# Regenerate configure if configure.ac changed
$(citus_abs_top_srcdir)/configure: $(citus_abs_top_srcdir)/configure.ac
cd ${citus_abs_top_srcdir} && ./autogen.sh
# If specified via configure, replace the default compiler. Normally

View File

@ -1,6 +1,6 @@
#!/bin/bash
#
# autogen.sh converts configure.in to configure and creates
# autogen.sh converts configure.ac to configure and creates
# citus_config.h.in. The resuting resulting files are checked into
# the SCM, to avoid everyone needing autoconf installed.

View File

@ -10,7 +10,7 @@
# argument (other than "yes/no"), etc.
#
# The point of this implementation is to reduce code size and
# redundancy in configure.in and to improve robustness and consistency
# redundancy in configure.ac and to improve robustness and consistency
# in the option evaluation code.

35
configure vendored
View File

@ -644,6 +644,7 @@ LDFLAGS
CFLAGS
CC
vpath_build
with_pg_version_check
PATH
PG_CONFIG
FLEX
@ -692,6 +693,7 @@ ac_subst_files=''
ac_user_opts='
enable_option_checking
with_extra_version
with_pg_version_check
enable_coverage
with_libcurl
with_reports_hostname
@ -1337,6 +1339,8 @@ Optional Packages:
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-extra-version=STRING
append STRING to version
--without-pg-version-check
do not check postgres version during configure
--without-libcurl do not use libcurl for anonymous statistics
collection
--with-reports-hostname=HOSTNAME
@ -2555,7 +2559,36 @@ if test -z "$version_num"; then
as_fn_error $? "Could not detect PostgreSQL version from pg_config." "$LINENO" 5
fi
if test "$version_num" != '13' -a "$version_num" != '14'; then
# Check whether --with-pg-version-check was given.
if test "${with_pg_version_check+set}" = set; then :
withval=$with_pg_version_check;
case $withval in
yes)
:
;;
no)
:
;;
*)
as_fn_error $? "no argument expected for --with-pg-version-check option" "$LINENO" 5
;;
esac
else
with_pg_version_check=yes
fi
if test "$with_pg_version_check" = no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: building against PostgreSQL $version_num (skipped compatibility check)" >&5
$as_echo "$as_me: building against PostgreSQL $version_num (skipped compatibility check)" >&6;}
elif test "$version_num" != '13' -a "$version_num" != '14'; then
as_fn_error $? "Citus is not compatible with the detected PostgreSQL version ${version_num}." "$LINENO" 5
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: building against PostgreSQL $version_num" >&5

View File

@ -74,7 +74,13 @@ if test -z "$version_num"; then
AC_MSG_ERROR([Could not detect PostgreSQL version from pg_config.])
fi
if test "$version_num" != '13' -a "$version_num" != '14'; then
PGAC_ARG_BOOL(with, pg-version-check, yes,
[do not check postgres version during configure])
AC_SUBST(with_pg_version_check)
if test "$with_pg_version_check" = no; then
AC_MSG_NOTICE([building against PostgreSQL $version_num (skipped compatibility check)])
elif test "$version_num" != '13' -a "$version_num" != '14'; then
AC_MSG_ERROR([Citus is not compatible with the detected PostgreSQL version ${version_num}.])
else
AC_MSG_NOTICE([building against PostgreSQL $version_num])

View File

@ -121,10 +121,8 @@ static void ColumnarScan_ExplainCustomScan(CustomScanState *node, List *ancestor
static const char * ColumnarPushdownClausesStr(List *context, List *clauses);
static const char * ColumnarProjectedColumnsStr(List *context,
List *projectedColumns);
#if PG_VERSION_NUM >= 130000
static List * set_deparse_context_planstate(List *dpcontext, Node *node,
List *ancestors);
#endif
/* other helpers */
static List * ColumnarVarNeeded(ColumnarScanState *columnarScanState);
@ -1986,8 +1984,6 @@ ColumnarVarNeeded(ColumnarScanState *columnarScanState)
}
#if PG_VERSION_NUM >= 130000
/*
* set_deparse_context_planstate is a compatibility wrapper for versions 13+.
*/
@ -1997,6 +1993,3 @@ set_deparse_context_planstate(List *dpcontext, Node *node, List *ancestors)
PlanState *ps = (PlanState *) node;
return set_deparse_context_plan(dpcontext, ps->plan, ancestors);
}
#endif

View File

@ -12,11 +12,7 @@
#include "access/rewriteheap.h"
#include "access/tableam.h"
#include "access/tsmapi.h"
#if PG_VERSION_NUM >= 130000
#include "access/detoast.h"
#else
#include "access/tuptoaster.h"
#endif
#include "access/xact.h"
#include "catalog/catalog.h"
#include "catalog/index.h"
@ -1676,15 +1672,8 @@ ColumnarReadRowsIntoIndex(TableScanDesc scan, Relation indexRelation,
/* currently, columnar tables can't have dead tuples */
bool tupleIsAlive = true;
#if PG_VERSION_NUM >= PG_VERSION_13
indexCallback(indexRelation, &itemPointerData, indexValues, indexNulls,
tupleIsAlive, indexCallbackState);
#else
HeapTuple scanTuple = ExecCopySlotHeapTuple(slot);
scanTuple->t_self = itemPointerData;
indexCallback(indexRelation, scanTuple, indexValues, indexNulls,
tupleIsAlive, indexCallbackState);
#endif
reltuples++;
}

View File

@ -14,12 +14,8 @@
#include "access/multixact.h"
#include "access/rewriteheap.h"
#include "access/tsmapi.h"
#if PG_VERSION_NUM >= 130000
#include "access/heaptoast.h"
#include "common/hashfn.h"
#else
#include "access/tuptoaster.h"
#endif
#include "access/xact.h"
#include "catalog/catalog.h"
#include "catalog/index.h"

View File

@ -1302,7 +1302,7 @@ ErrorIfUnsupportedCascadeObjects(Oid relationId)
*
* Extension dependency is different than the rest. If an object depends on an extension
* dropping the object would drop the extension too.
* So we check with IsObjectAddressOwnedByExtension function.
* So we check with IsAnyObjectAddressOwnedByExtension function.
*/
static bool
DoesCascadeDropUnsupportedObject(Oid classId, Oid objectId, HTAB *nodeMap)
@ -1315,10 +1315,9 @@ DoesCascadeDropUnsupportedObject(Oid classId, Oid objectId, HTAB *nodeMap)
return false;
}
ObjectAddress objectAddress = { 0 };
ObjectAddressSet(objectAddress, classId, objectId);
if (IsObjectAddressOwnedByExtension(&objectAddress, NULL))
ObjectAddress *objectAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*objectAddress, classId, objectId);
if (IsAnyObjectAddressOwnedByExtension(list_make1(objectAddress), NULL))
{
return true;
}
@ -1568,11 +1567,7 @@ ReplaceTable(Oid sourceId, Oid targetId, List *justBeforeDropCommands,
ExecuteQueryViaSPI(query->data, SPI_OK_INSERT);
}
#if PG_VERSION_NUM >= PG_VERSION_13
List *ownedSequences = getOwnedSequences(sourceId);
#else
List *ownedSequences = getOwnedSequences(sourceId, InvalidAttrNumber);
#endif
Oid sequenceOid = InvalidOid;
foreach_oid(sequenceOid, ownedSequences)
{

View File

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

View File

@ -36,7 +36,6 @@ PreprocessClusterStmt(Node *node, const char *clusterCommand,
{
ClusterStmt *clusterStmt = castNode(ClusterStmt, node);
bool missingOK = false;
DDLJob *ddlJob = NULL;
if (clusterStmt->relation == NULL)
{
@ -67,18 +66,14 @@ PreprocessClusterStmt(Node *node, const char *clusterCommand,
return NIL;
}
#if PG_VERSION_NUM >= 120000
if (IsClusterStmtVerbose_compat(clusterStmt))
#else
if (clusterStmt->verbose)
#endif
{
ereport(ERROR, (errmsg("cannot run CLUSTER command"),
errdetail("VERBOSE option is currently unsupported "
"for distributed tables.")));
}
ddlJob = palloc0(sizeof(DDLJob));
DDLJob *ddlJob = palloc0(sizeof(DDLJob));
ObjectAddressSet(ddlJob->targetObjectAddress, RelationRelationId, relationId);
ddlJob->metadataSyncCommand = clusterCommand;
ddlJob->taskList = DDLTaskList(relationId, clusterCommand);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -874,7 +874,6 @@ static DistributeObjectOps Schema_Rename = {
.address = AlterSchemaRenameStmtObjectAddress,
.markDistributed = false,
};
#if PG_VERSION_NUM >= PG_VERSION_13
static DistributeObjectOps Statistics_Alter = {
.deparse = DeparseAlterStatisticsStmt,
.qualify = QualifyAlterStatisticsStmt,
@ -883,7 +882,6 @@ static DistributeObjectOps Statistics_Alter = {
.address = NULL,
.markDistributed = false,
};
#endif
static DistributeObjectOps Statistics_AlterObjectSchema = {
.deparse = DeparseAlterStatisticsSchemaStmt,
.qualify = QualifyAlterStatisticsSchemaStmt,
@ -1304,13 +1302,11 @@ GetDistributeObjectOps(Node *node)
return &Sequence_Alter;
}
#if PG_VERSION_NUM >= PG_VERSION_13
case T_AlterStatsStmt:
{
return &Statistics_Alter;
}
#endif
case T_AlterTableStmt:
{
AlterTableStmt *stmt = castNode(AlterTableStmt, node);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -106,9 +106,7 @@
#include "nodes/nodeFuncs.h"
#include "parser/parse_func.h"
#include "parser/parse_type.h"
#if PG_VERSION_NUM >= PG_VERSION_13
#include "tcop/cmdtag.h"
#endif
#include "tsearch/ts_locale.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
@ -764,12 +762,7 @@ FindJsonbInputColumns(TupleDesc tupleDescriptor, List *inputColumnNameList)
static void
CompleteCopyQueryTagCompat(QueryCompletionCompat *completionTag, uint64 processedRowCount)
{
#if PG_VERSION_NUM >= PG_VERSION_13
SetQueryCompletion(completionTag, CMDTAG_COPY, processedRowCount);
#else
SafeSnprintf(completionTag, COMPLETION_TAG_BUFSIZE,
"COPY " UINT64_FORMAT, processedRowCount);
#endif
}
@ -781,9 +774,6 @@ static List *
RemoveOptionFromList(List *optionList, char *optionName)
{
ListCell *optionCell = NULL;
#if PG_VERSION_NUM < PG_VERSION_13
ListCell *previousCell = NULL;
#endif
foreach(optionCell, optionList)
{
DefElem *option = (DefElem *) lfirst(optionCell);
@ -792,9 +782,6 @@ RemoveOptionFromList(List *optionList, char *optionName)
{
return list_delete_cell_compat(optionList, optionCell, previousCell);
}
#if PG_VERSION_NUM < PG_VERSION_13
previousCell = optionCell;
#endif
}
return optionList;

View File

@ -290,22 +290,10 @@ PostprocessCreatePolicyStmt(Node *node, const char *queryString)
static void
AddRangeTableEntryToQueryCompat(ParseState *parseState, Relation relation)
{
#if PG_VERSION_NUM >= PG_VERSION_13
ParseNamespaceItem *rte = NULL;
#else
RangeTblEntry *rte = NULL;
#endif
rte = addRangeTableEntryForRelation(parseState, relation,
#if PG_VERSION_NUM >= PG_VERSION_12
AccessShareLock,
#endif
NULL, false, false);
#if PG_VERSION_NUM >= PG_VERSION_13
ParseNamespaceItem *rte = addRangeTableEntryForRelation(parseState, relation,
AccessShareLock, NULL,
false, false);
addNSItemToQuery(parseState, rte, false, true, true);
#else
addRTEtoQuery(parseState, rte, false, true, true);
#endif
}
@ -612,8 +600,8 @@ RenamePolicyEventExtendNames(RenameStmt *stmt, const char *schemaName, uint64 sh
void
DropPolicyEventExtendNames(DropStmt *dropStmt, const char *schemaName, uint64 shardId)
{
Value *relationSchemaNameValue = NULL;
Value *relationNameValue = NULL;
String *relationSchemaNameValue = NULL;
String *relationNameValue = NULL;
uint32 dropCount = list_length(dropStmt->objects);
if (dropCount > 1)
@ -652,10 +640,10 @@ DropPolicyEventExtendNames(DropStmt *dropStmt, const char *schemaName, uint64 sh
/* prefix with schema name if it is not added already */
if (relationSchemaNameValue == NULL)
{
Value *schemaNameValue = makeString(pstrdup(schemaName));
String *schemaNameValue = makeString(pstrdup(schemaName));
relationNameList = lcons(schemaNameValue, relationNameList);
}
char **relationName = &(relationNameValue->val.str);
char **relationName = &(strVal(relationNameValue));
AppendShardIdToName(relationName, shardId);
}

View File

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

View File

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

View File

@ -197,11 +197,7 @@ ExtractDefaultColumnsAndOwnedSequences(Oid relationId, List **columnNameList,
if (list_length(columnOwnedSequences) != 0)
{
/*
* A column might only own one sequence. We intentionally use
* GetSequencesOwnedByColumn macro and pick initial oid from the
* list instead of using getOwnedSequence. This is both because
* getOwnedSequence is removed in pg13 and is also because it
* errors out if column does not have any sequences.
* A column might only own one sequence.
*/
Assert(list_length(columnOwnedSequences) == 1);
ownedSequenceId = linitial_oid(columnOwnedSequences);
@ -268,18 +264,16 @@ PreprocessDropSequenceStmt(Node *node, const char *queryString,
Oid seqOid = RangeVarGetRelid(seq, NoLock, stmt->missing_ok);
ObjectAddress sequenceAddress = { 0 };
ObjectAddressSet(sequenceAddress, RelationRelationId, seqOid);
if (!IsObjectDistributed(&sequenceAddress))
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*sequenceAddress, RelationRelationId, seqOid);
if (!IsAnyObjectDistributed(list_make1(sequenceAddress)))
{
continue;
}
/* collect information for all distributed sequences */
ObjectAddress *addressp = palloc(sizeof(ObjectAddress));
*addressp = sequenceAddress;
distributedSequenceAddresses = lappend(distributedSequenceAddresses, addressp);
distributedSequenceAddresses = lappend(distributedSequenceAddresses,
sequenceAddress);
distributedSequencesList = lappend(distributedSequencesList, objectNameList);
}
@ -334,10 +328,13 @@ PreprocessRenameSequenceStmt(Node *node, const char *queryString, ProcessUtility
RenameStmt *stmt = castNode(RenameStmt, node);
Assert(stmt->renameType == OBJECT_SEQUENCE);
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt,
stmt->missing_ok);
List *addresses = GetObjectAddressListFromParseTree((Node *) stmt,
stmt->missing_ok);
if (!ShouldPropagateObject(&address))
/* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
if (!ShouldPropagateAnyObject(addresses))
{
return NIL;
}
@ -358,7 +355,7 @@ PreprocessRenameSequenceStmt(Node *node, const char *queryString, ProcessUtility
* RenameSequenceStmtObjectAddress returns the ObjectAddress of the sequence that is the
* subject of the RenameStmt.
*/
ObjectAddress
List *
RenameSequenceStmtObjectAddress(Node *node, bool missing_ok)
{
RenameStmt *stmt = castNode(RenameStmt, node);
@ -366,10 +363,10 @@ RenameSequenceStmtObjectAddress(Node *node, bool missing_ok)
RangeVar *sequence = stmt->relation;
Oid seqOid = RangeVarGetRelid(sequence, NoLock, missing_ok);
ObjectAddress sequenceAddress = { 0 };
ObjectAddressSet(sequenceAddress, RelationRelationId, seqOid);
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*sequenceAddress, RelationRelationId, seqOid);
return sequenceAddress;
return list_make1(sequenceAddress);
}
@ -395,21 +392,27 @@ PreprocessAlterSequenceStmt(Node *node, const char *queryString,
{
AlterSeqStmt *stmt = castNode(AlterSeqStmt, node);
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt,
stmt->missing_ok);
List *addresses = GetObjectAddressListFromParseTree((Node *) stmt,
stmt->missing_ok);
/* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
/* error out if the sequence is distributed */
if (IsObjectDistributed(&address))
if (IsAnyObjectDistributed(addresses))
{
ereport(ERROR, (errmsg(
"Altering a distributed sequence is currently not supported.")));
}
/* We have already asserted that we have exactly 1 address in the addresses. */
ObjectAddress *address = linitial(addresses);
/*
* error out if the sequence is used in a distributed table
* and this is an ALTER SEQUENCE .. AS .. statement
*/
Oid citusTableId = SequenceUsedInDistributedTable(&address);
Oid citusTableId = SequenceUsedInDistributedTable(address);
if (citusTableId != InvalidOid)
{
List *options = stmt->options;
@ -463,6 +466,7 @@ SequenceUsedInDistributedTable(const ObjectAddress *sequenceAddress)
}
}
}
return InvalidOid;
}
@ -471,17 +475,17 @@ SequenceUsedInDistributedTable(const ObjectAddress *sequenceAddress)
* AlterSequenceStmtObjectAddress returns the ObjectAddress of the sequence that is the
* subject of the AlterSeqStmt.
*/
ObjectAddress
List *
AlterSequenceStmtObjectAddress(Node *node, bool missing_ok)
{
AlterSeqStmt *stmt = castNode(AlterSeqStmt, node);
RangeVar *sequence = stmt->sequence;
Oid seqOid = RangeVarGetRelid(sequence, NoLock, stmt->missing_ok);
ObjectAddress sequenceAddress = { 0 };
ObjectAddressSet(sequenceAddress, RelationRelationId, seqOid);
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*sequenceAddress, RelationRelationId, seqOid);
return sequenceAddress;
return list_make1(sequenceAddress);
}
@ -498,9 +502,13 @@ PreprocessAlterSequenceSchemaStmt(Node *node, const char *queryString,
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
Assert(stmt->objectType == OBJECT_SEQUENCE);
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt,
stmt->missing_ok);
if (!ShouldPropagateObject(&address))
List *addresses = GetObjectAddressListFromParseTree((Node *) stmt,
stmt->missing_ok);
/* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
if (!ShouldPropagateAnyObject(addresses))
{
return NIL;
}
@ -521,7 +529,7 @@ PreprocessAlterSequenceSchemaStmt(Node *node, const char *queryString,
* AlterSequenceSchemaStmtObjectAddress returns the ObjectAddress of the sequence that is
* the subject of the AlterObjectSchemaStmt.
*/
ObjectAddress
List *
AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok)
{
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
@ -555,10 +563,10 @@ AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok)
}
}
ObjectAddress sequenceAddress = { 0 };
ObjectAddressSet(sequenceAddress, RelationRelationId, seqOid);
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*sequenceAddress, RelationRelationId, seqOid);
return sequenceAddress;
return list_make1(sequenceAddress);
}
@ -572,16 +580,19 @@ PostprocessAlterSequenceSchemaStmt(Node *node, const char *queryString)
{
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
Assert(stmt->objectType == OBJECT_SEQUENCE);
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt,
stmt->missing_ok);
List *addresses = GetObjectAddressListFromParseTree((Node *) stmt,
stmt->missing_ok);
if (!ShouldPropagateObject(&address))
/* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
if (!ShouldPropagateAnyObject(addresses))
{
return NIL;
}
/* dependencies have changed (schema) let's ensure they exist */
EnsureDependenciesExistOnAllNodes(&address);
EnsureAllObjectDependenciesExistOnAllNodes(addresses);
return NIL;
}
@ -601,8 +612,12 @@ PreprocessAlterSequenceOwnerStmt(Node *node, const char *queryString,
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
Assert(AlterTableStmtObjType_compat(stmt) == OBJECT_SEQUENCE);
ObjectAddress sequenceAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
if (!ShouldPropagateObject(&sequenceAddress))
List *sequenceAddresses = GetObjectAddressListFromParseTree((Node *) stmt, false);
/* the code-path only supports a single object */
Assert(list_length(sequenceAddresses) == 1);
if (!ShouldPropagateAnyObject(sequenceAddresses))
{
return NIL;
}
@ -623,7 +638,7 @@ PreprocessAlterSequenceOwnerStmt(Node *node, const char *queryString,
* AlterSequenceOwnerStmtObjectAddress returns the ObjectAddress of the sequence that is the
* subject of the AlterOwnerStmt.
*/
ObjectAddress
List *
AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok)
{
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
@ -631,10 +646,10 @@ AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok)
RangeVar *sequence = stmt->relation;
Oid seqOid = RangeVarGetRelid(sequence, NoLock, missing_ok);
ObjectAddress sequenceAddress = { 0 };
ObjectAddressSet(sequenceAddress, RelationRelationId, seqOid);
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*sequenceAddress, RelationRelationId, seqOid);
return sequenceAddress;
return list_make1(sequenceAddress);
}
@ -649,14 +664,18 @@ PostprocessAlterSequenceOwnerStmt(Node *node, const char *queryString)
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
Assert(AlterTableStmtObjType_compat(stmt) == OBJECT_SEQUENCE);
ObjectAddress sequenceAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
if (!ShouldPropagateObject(&sequenceAddress))
List *sequenceAddresses = GetObjectAddressListFromParseTree((Node *) stmt, false);
/* the code-path only supports a single object */
Assert(list_length(sequenceAddresses) == 1);
if (!ShouldPropagateAnyObject(sequenceAddresses))
{
return NIL;
}
/* dependencies have changed (owner) let's ensure they exist */
EnsureDependenciesExistOnAllNodes(&sequenceAddress);
EnsureAllObjectDependenciesExistOnAllNodes(sequenceAddresses);
return NIL;
}
@ -744,10 +763,10 @@ PostprocessGrantOnSequenceStmt(Node *node, const char *queryString)
RangeVar *sequence = NULL;
foreach_ptr(sequence, distributedSequences)
{
ObjectAddress sequenceAddress = { 0 };
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
Oid sequenceOid = RangeVarGetRelid(sequence, NoLock, false);
ObjectAddressSet(sequenceAddress, RelationRelationId, sequenceOid);
EnsureDependenciesExistOnAllNodes(&sequenceAddress);
ObjectAddressSet(*sequenceAddress, RelationRelationId, sequenceOid);
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(sequenceAddress));
}
return NIL;
}
@ -825,7 +844,7 @@ FilterDistributedSequences(GrantStmt *stmt)
{
/* iterate over all namespace names provided to get their oid's */
List *namespaceOidList = NIL;
Value *namespaceValue = NULL;
String *namespaceValue = NULL;
foreach_ptr(namespaceValue, stmt->objects)
{
char *nspname = strVal(namespaceValue);
@ -866,15 +885,15 @@ FilterDistributedSequences(GrantStmt *stmt)
RangeVar *sequenceRangeVar = NULL;
foreach_ptr(sequenceRangeVar, stmt->objects)
{
ObjectAddress sequenceAddress = { 0 };
Oid sequenceOid = RangeVarGetRelid(sequenceRangeVar, NoLock, missing_ok);
ObjectAddressSet(sequenceAddress, RelationRelationId, sequenceOid);
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*sequenceAddress, RelationRelationId, sequenceOid);
/*
* if this sequence from GRANT .. ON SEQUENCE .. is a distributed
* sequence, add it to the list
*/
if (IsObjectDistributed(&sequenceAddress))
if (IsAnyObjectDistributed(list_make1(sequenceAddress)))
{
grantSequenceList = lappend(grantSequenceList, sequenceRangeVar);
}

View File

@ -55,9 +55,7 @@ static char * GenerateAlterIndexColumnSetStatsCommand(char *indexNameWithSchema,
int32 attstattarget);
static Oid GetRelIdByStatsOid(Oid statsOid);
static char * CreateAlterCommandIfOwnerNotDefault(Oid statsOid);
#if PG_VERSION_NUM >= PG_VERSION_13
static char * CreateAlterCommandIfTargetNotDefault(Oid statsOid);
#endif
/*
* PreprocessCreateStatisticsStmt is called during the planning phase for
@ -122,9 +120,12 @@ PostprocessCreateStatisticsStmt(Node *node, const char *queryString)
}
bool missingOk = false;
ObjectAddress objectAddress = GetObjectAddressFromParseTree((Node *) stmt, missingOk);
List *objectAddresses = GetObjectAddressListFromParseTree((Node *) stmt, missingOk);
EnsureDependenciesExistOnAllNodes(&objectAddress);
/* the code-path only supports a single object */
Assert(list_length(objectAddresses) == 1);
EnsureAllObjectDependenciesExistOnAllNodes(objectAddresses);
return NIL;
}
@ -138,16 +139,16 @@ PostprocessCreateStatisticsStmt(Node *node, const char *queryString)
* Never returns NULL, but the objid in the address can be invalid if missingOk
* was set to true.
*/
ObjectAddress
List *
CreateStatisticsStmtObjectAddress(Node *node, bool missingOk)
{
CreateStatsStmt *stmt = castNode(CreateStatsStmt, node);
ObjectAddress address = { 0 };
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
Oid statsOid = get_statistics_object_oid(stmt->defnames, missingOk);
ObjectAddressSet(address, StatisticExtRelationId, statsOid);
ObjectAddressSet(*address, StatisticExtRelationId, statsOid);
return address;
return list_make1(address);
}
@ -306,9 +307,12 @@ PostprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString)
}
bool missingOk = false;
ObjectAddress objectAddress = GetObjectAddressFromParseTree((Node *) stmt, missingOk);
List *objectAddresses = GetObjectAddressListFromParseTree((Node *) stmt, missingOk);
EnsureDependenciesExistOnAllNodes(&objectAddress);
/* the code-path only supports a single object */
Assert(list_length(objectAddresses) == 1);
EnsureAllObjectDependenciesExistOnAllNodes(objectAddresses);
return NIL;
}
@ -322,23 +326,21 @@ PostprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString)
* Never returns NULL, but the objid in the address can be invalid if missingOk
* was set to true.
*/
ObjectAddress
List *
AlterStatisticsSchemaStmtObjectAddress(Node *node, bool missingOk)
{
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
ObjectAddress address = { 0 };
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
String *statName = llast((List *) stmt->object);
Oid statsOid = get_statistics_object_oid(list_make2(makeString(stmt->newschema),
statName), missingOk);
ObjectAddressSet(address, StatisticExtRelationId, statsOid);
ObjectAddressSet(*address, StatisticExtRelationId, statsOid);
return address;
return list_make1(address);
}
#if PG_VERSION_NUM >= PG_VERSION_13
/*
* PreprocessAlterStatisticsStmt is called during the planning phase for
* ALTER STATISTICS .. SET STATISTICS.
@ -387,8 +389,6 @@ PreprocessAlterStatisticsStmt(Node *node, const char *queryString,
}
#endif
/*
* PreprocessAlterStatisticsOwnerStmt is called during the planning phase for
* ALTER STATISTICS .. OWNER TO.
@ -449,10 +449,9 @@ PostprocessAlterStatisticsOwnerStmt(Node *node, const char *queryString)
return NIL;
}
ObjectAddress statisticsAddress = { 0 };
ObjectAddressSet(statisticsAddress, StatisticExtRelationId, statsOid);
EnsureDependenciesExistOnAllNodes(&statisticsAddress);
ObjectAddress *statisticsAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*statisticsAddress, StatisticExtRelationId, statsOid);
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(statisticsAddress));
return NIL;
}
@ -502,7 +501,6 @@ GetExplicitStatisticsCommandList(Oid relationId)
explicitStatisticsCommandList =
lappend(explicitStatisticsCommandList,
makeTableDDLCommandString(createStatisticsCommand));
#if PG_VERSION_NUM >= PG_VERSION_13
/* we need to alter stats' target if it's getting distributed after creation */
char *alterStatisticsTargetCommand =
@ -514,7 +512,6 @@ GetExplicitStatisticsCommandList(Oid relationId)
lappend(explicitStatisticsCommandList,
makeTableDDLCommandString(alterStatisticsTargetCommand));
}
#endif
/* we need to alter stats' owner if it's getting distributed after creation */
char *alterStatisticsOwnerCommand =
@ -704,8 +701,6 @@ CreateAlterCommandIfOwnerNotDefault(Oid statsOid)
}
#if PG_VERSION_NUM >= PG_VERSION_13
/*
* CreateAlterCommandIfTargetNotDefault returns an ALTER STATISTICS .. SET STATISTICS
* command if the stats object with given id has a target different than the default one.
@ -740,6 +735,3 @@ CreateAlterCommandIfTargetNotDefault(Oid statsOid)
return DeparseAlterStatisticsStmt((Node *) alterStatsStmt);
}
#endif

View File

@ -35,9 +35,6 @@ Node *
ProcessCreateSubscriptionStmt(CreateSubscriptionStmt *createSubStmt)
{
ListCell *currCell = NULL;
#if PG_VERSION_NUM < PG_VERSION_13
ListCell *prevCell = NULL;
#endif
bool useAuthinfo = false;
foreach(currCell, createSubStmt->options)
@ -54,9 +51,6 @@ ProcessCreateSubscriptionStmt(CreateSubscriptionStmt *createSubStmt)
break;
}
#if PG_VERSION_NUM < PG_VERSION_13
prevCell = currCell;
#endif
}
if (useAuthinfo)
@ -103,7 +97,7 @@ GenerateConninfoWithAuth(char *conninfo)
}
else if (strcmp(option->keyword, "port") == 0)
{
port = pg_atoi(option->val, 4, 0);
port = pg_strtoint32(option->val);
}
else if (strcmp(option->keyword, "user") == 0)
{

View File

@ -649,13 +649,19 @@ PostprocessAlterTableSchemaStmt(Node *node, const char *queryString)
/*
* We will let Postgres deal with missing_ok
*/
ObjectAddress tableAddress = GetObjectAddressFromParseTree((Node *) stmt, true);
List *tableAddresses = GetObjectAddressListFromParseTree((Node *) stmt, true);
/* the code-path only supports a single object */
Assert(list_length(tableAddresses) == 1);
/* We have already asserted that we have exactly 1 address in the addresses. */
ObjectAddress *tableAddress = linitial(tableAddresses);
/*
* Check whether we are dealing with a sequence or view here and route queries
* accordingly to the right processor function.
*/
char relKind = get_rel_relkind(tableAddress.objectId);
char relKind = get_rel_relkind(tableAddress->objectId);
if (relKind == RELKIND_SEQUENCE)
{
stmt->objectType = OBJECT_SEQUENCE;
@ -667,12 +673,12 @@ PostprocessAlterTableSchemaStmt(Node *node, const char *queryString)
return PostprocessAlterViewSchemaStmt((Node *) stmt, queryString);
}
if (!ShouldPropagate() || !IsCitusTable(tableAddress.objectId))
if (!ShouldPropagate() || !IsCitusTable(tableAddress->objectId))
{
return NIL;
}
EnsureDependenciesExistOnAllNodes(&tableAddress);
EnsureAllObjectDependenciesExistOnAllNodes(tableAddresses);
return NIL;
}
@ -751,9 +757,9 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
{
/*
* We don't process subcommands generated by postgres.
* This is mainly because postgres started to issue ALTER TABLE commands
* for some set of objects that are defined via CREATE TABLE commands as
* of pg13. However, citus already has a separate logic for CREATE TABLE
* This is mainly because postgres issues ALTER TABLE commands
* for some set of objects that are defined via CREATE TABLE commands.
* However, citus already has a separate logic for CREATE TABLE
* commands.
*
* To support foreign keys from/to postgres local tables to/from reference
@ -1776,9 +1782,15 @@ PreprocessAlterTableSchemaStmt(Node *node, const char *queryString,
return NIL;
}
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt,
stmt->missing_ok);
Oid relationId = address.objectId;
List *addresses = GetObjectAddressListFromParseTree((Node *) stmt,
stmt->missing_ok);
/* the code-path only supports a single object */
Assert(list_length(addresses) == 1);
/* We have already asserted that we have exactly 1 address in the addresses. */
ObjectAddress *address = linitial(addresses);
Oid relationId = address->objectId;
/*
* Check whether we are dealing with a sequence or view here and route queries
@ -1990,9 +2002,9 @@ PostprocessAlterTableStmt(AlterTableStmt *alterTableStatement)
EnsureRelationHasCompatibleSequenceTypes(relationId);
/* changing a relation could introduce new dependencies */
ObjectAddress tableAddress = { 0 };
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
EnsureDependenciesExistOnAllNodes(&tableAddress);
ObjectAddress *tableAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*tableAddress, RelationRelationId, relationId);
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(tableAddress));
}
/* for the new sequences coming with this ALTER TABLE statement */
@ -3353,7 +3365,7 @@ ErrorIfUnsupportedAlterAddConstraintStmt(AlterTableStmt *alterTableStatement)
* will look in the new schema. Errors if missing_ok is false and the table cannot
* be found in either of the schemas.
*/
ObjectAddress
List *
AlterTableSchemaStmtObjectAddress(Node *node, bool missing_ok)
{
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
@ -3389,10 +3401,10 @@ AlterTableSchemaStmtObjectAddress(Node *node, bool missing_ok)
}
}
ObjectAddress address = { 0 };
ObjectAddressSet(address, RelationRelationId, tableOid);
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*address, RelationRelationId, tableOid);
return address;
return list_make1(address);
}

View File

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

View File

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

View File

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

View File

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

View File

@ -41,10 +41,7 @@ typedef struct CitusVacuumParams
int options;
VacOptValue truncate;
VacOptValue index_cleanup;
#if PG_VERSION_NUM >= PG_VERSION_13
int nworkers;
#endif
} CitusVacuumParams;
/* Local functions forward declarations for processing distributed table commands */
@ -323,10 +320,8 @@ DeparseVacuumStmtPrefix(CitusVacuumParams vacuumParams)
/* if no flags remain, exit early */
if (vacuumFlags == 0 &&
vacuumParams.truncate == VACOPTVALUE_UNSPECIFIED &&
vacuumParams.index_cleanup == VACOPTVALUE_UNSPECIFIED
#if PG_VERSION_NUM >= PG_VERSION_13
&& vacuumParams.nworkers == VACUUM_PARALLEL_NOTSET
#endif
vacuumParams.index_cleanup == VACOPTVALUE_UNSPECIFIED &&
vacuumParams.nworkers == VACUUM_PARALLEL_NOTSET
)
{
return vacuumPrefix->data;
@ -409,12 +404,10 @@ DeparseVacuumStmtPrefix(CitusVacuumParams vacuumParams)
}
}
#if PG_VERSION_NUM >= PG_VERSION_13
if (vacuumParams.nworkers != VACUUM_PARALLEL_NOTSET)
{
appendStringInfo(vacuumPrefix, "PARALLEL %d,", vacuumParams.nworkers);
}
#endif
vacuumPrefix->data[vacuumPrefix->len - 1] = ')';
@ -515,9 +508,7 @@ VacuumStmtParams(VacuumStmt *vacstmt)
/* Set default value */
params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
params.truncate = VACOPTVALUE_UNSPECIFIED;
#if PG_VERSION_NUM >= PG_VERSION_13
params.nworkers = VACUUM_PARALLEL_NOTSET;
#endif
/* Parse options list */
DefElem *opt = NULL;
@ -596,7 +587,6 @@ VacuumStmtParams(VacuumStmt *vacstmt)
params.truncate = defGetBoolean(opt) ? VACOPTVALUE_ENABLED :
VACOPTVALUE_DISABLED;
}
#if PG_VERSION_NUM >= PG_VERSION_13
else if (strcmp(opt->defname, "parallel") == 0)
{
if (opt->arg == NULL)
@ -620,7 +610,6 @@ VacuumStmtParams(VacuumStmt *vacstmt)
params.nworkers = nworkers;
}
}
#endif
else
{
ereport(ERROR,

View File

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

View File

@ -462,7 +462,7 @@ GetEffectiveConnKey(ConnectionHashKey *key)
}
else if (strcmp(option->keyword, "port") == 0)
{
effectiveKey->port = pg_atoi(option->val, 4, 0);
effectiveKey->port = pg_strtoint32(option->val);
}
else if (strcmp(option->keyword, "dbname") == 0)
{

View File

@ -48,11 +48,7 @@
#include "distributed/tuplestore.h"
#include "distributed/worker_manager.h"
#include "utils/builtins.h"
#if PG_VERSION_NUM < PG_VERSION_13
#include "utils/hashutils.h"
#else
#include "common/hashfn.h"
#endif
#define RESERVED_CONNECTION_COLUMNS 4

View File

@ -26,9 +26,7 @@
#include "distributed/placement_connection.h"
#include "distributed/relation_access_tracking.h"
#include "utils/hsearch.h"
#if PG_VERSION_NUM >= PG_VERSION_13
#include "common/hashfn.h"
#endif
#include "utils/memutils.h"

View File

@ -36,12 +36,7 @@
#include "distributed/time_constants.h"
#include "distributed/tuplestore.h"
#include "utils/builtins.h"
#if PG_VERSION_NUM < PG_VERSION_13
#include "utils/hsearch.h"
#include "utils/hashutils.h"
#else
#include "common/hashfn.h"
#endif
#include "storage/ipc.h"
@ -123,8 +118,6 @@ static void StoreAllRemoteConnectionStats(Tuplestorestate *tupleStore, TupleDesc
tupleDescriptor);
static void LockConnectionSharedMemory(LWLockMode lockMode);
static void UnLockConnectionSharedMemory(void);
static void SharedConnectionStatsShmemInit(void);
static size_t SharedConnectionStatsShmemSize(void);
static bool ShouldWaitForConnection(int currentConnectionCount);
static uint32 SharedConnectionHashHash(const void *key, Size keysize);
static int SharedConnectionHashCompare(const void *a, const void *b, Size keysize);
@ -617,11 +610,15 @@ WaitForSharedConnection(void)
void
InitializeSharedConnectionStats(void)
{
/* on PG 15, we use shmem_request_hook_type */
#if PG_VERSION_NUM < PG_VERSION_15
/* allocate shared memory */
if (!IsUnderPostmaster)
{
RequestAddinShmemSpace(SharedConnectionStatsShmemSize());
}
#endif
prev_shmem_startup_hook = shmem_startup_hook;
shmem_startup_hook = SharedConnectionStatsShmemInit;
@ -632,7 +629,7 @@ InitializeSharedConnectionStats(void)
* SharedConnectionStatsShmemSize returns the size that should be allocated
* on the shared memory for shared connection stats.
*/
static size_t
size_t
SharedConnectionStatsShmemSize(void)
{
Size size = 0;
@ -652,7 +649,7 @@ SharedConnectionStatsShmemSize(void)
* SharedConnectionStatsShmemInit initializes the shared memory used
* for keeping track of connection stats across backends.
*/
static void
void
SharedConnectionStatsShmemInit(void)
{
bool alreadyInitialized = false;

View File

@ -526,7 +526,7 @@ pg_get_tableschemadef_string(Oid tableRelationId, IncludeSequenceDefaults
}
/*
* Add table access methods for pg12 and higher when the table is configured with an
* Add table access methods when the table is configured with an
* access method
*/
if (accessMethod)
@ -999,7 +999,6 @@ deparse_index_columns(StringInfo buffer, List *indexParameterList, List *deparse
appendStringInfo(buffer, "%s ",
NameListToQuotedString(indexElement->opclass));
}
#if PG_VERSION_NUM >= PG_VERSION_13
/* Commit on postgres: 911e70207703799605f5a0e8aad9f06cff067c63*/
if (indexElement->opclassopts != NIL)
@ -1008,7 +1007,6 @@ deparse_index_columns(StringInfo buffer, List *indexParameterList, List *deparse
AppendStorageParametersToString(buffer, indexElement->opclassopts);
appendStringInfoString(buffer, ") ");
}
#endif
if (indexElement->ordering != SORTBY_DEFAULT)
{

View File

@ -27,9 +27,7 @@ static void AppendCreateStatisticsStmt(StringInfo buf, CreateStatsStmt *stmt);
static void AppendDropStatisticsStmt(StringInfo buf, List *nameList, bool ifExists);
static void AppendAlterStatisticsRenameStmt(StringInfo buf, RenameStmt *stmt);
static void AppendAlterStatisticsSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt);
#if PG_VERSION_NUM >= PG_VERSION_13
static void AppendAlterStatisticsStmt(StringInfo buf, AlterStatsStmt *stmt);
#endif
static void AppendAlterStatisticsOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt);
static void AppendStatisticsName(StringInfo buf, CreateStatsStmt *stmt);
static void AppendStatTypes(StringInfo buf, CreateStatsStmt *stmt);
@ -90,7 +88,6 @@ DeparseAlterStatisticsSchemaStmt(Node *node)
}
#if PG_VERSION_NUM >= PG_VERSION_13
char *
DeparseAlterStatisticsStmt(Node *node)
{
@ -105,7 +102,6 @@ DeparseAlterStatisticsStmt(Node *node)
}
#endif
char *
DeparseAlterStatisticsOwnerStmt(Node *node)
{
@ -177,7 +173,6 @@ AppendAlterStatisticsSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt)
}
#if PG_VERSION_NUM >= PG_VERSION_13
static void
AppendAlterStatisticsStmt(StringInfo buf, AlterStatsStmt *stmt)
{
@ -186,7 +181,6 @@ AppendAlterStatisticsStmt(StringInfo buf, AlterStatsStmt *stmt)
}
#endif
static void
AppendAlterStatisticsOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt)
{

View File

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

View File

@ -152,8 +152,6 @@ QualifyAlterStatisticsSchemaStmt(Node *node)
}
#if PG_VERSION_NUM >= PG_VERSION_13
/*
* QualifyAlterStatisticsStmt qualifies AlterStatsStmt's with schema name for
* ALTER STATISTICS .. SET STATISTICS statements.
@ -180,8 +178,6 @@ QualifyAlterStatisticsStmt(Node *node)
}
#endif
/*
* QualifyAlterStatisticsOwnerStmt qualifies AlterOwnerStmt's with schema
* name for ALTER STATISTICS .. OWNER TO statements.

File diff suppressed because it is too large Load Diff

View File

@ -1790,17 +1790,9 @@ AcquireExecutorShardLocksForExecution(DistributedExecution *execution)
/* Acquire additional locks for SELECT .. FOR UPDATE on reference tables */
AcquireExecutorShardLocksForRelationRowLockList(task->relationRowLockList);
/*
* Due to PG commit 5ee190f8ec37c1bbfb3061e18304e155d600bc8e we copy the
* second parameter in pre-13.
*/
relationRowLockList =
list_concat(relationRowLockList,
#if (PG_VERSION_NUM >= PG_VERSION_12) && (PG_VERSION_NUM < PG_VERSION_13)
list_copy(task->relationRowLockList));
#else
task->relationRowLockList);
#endif
/*
* If the task has a subselect, then we may need to lock the shards from which
@ -1814,19 +1806,9 @@ AcquireExecutorShardLocksForExecution(DistributedExecution *execution)
* and therefore prevents other modifications from running
* concurrently.
*/
/*
* Due to PG commit 5ee190f8ec37c1bbfb3061e18304e155d600bc8e we copy the
* second parameter in pre-13.
*/
requiresConsistentSnapshotRelationShardList =
list_concat(requiresConsistentSnapshotRelationShardList,
#if (PG_VERSION_NUM >= PG_VERSION_12) && (PG_VERSION_NUM < PG_VERSION_13)
list_copy(task->relationShardList));
#else
task->relationShardList);
#endif
}
}

View File

@ -49,7 +49,6 @@
#define STICKY_DECREASE_FACTOR (0.50) /* factor for sticky entries */
#define USAGE_DEALLOC_PERCENT 5 /* free this % of entries at once */
#define USAGE_INIT (1.0) /* including initial planning */
#define STATS_SHARED_MEM_NAME "citus_query_stats"
#define MAX_KEY_LENGTH NAMEDATALEN
@ -124,7 +123,6 @@ PG_FUNCTION_INFO_V1(citus_executor_name);
static char * CitusExecutorName(MultiExecutorType executorType);
static Size CitusQueryStatsSharedMemSize(void);
static void CitusQueryStatsShmemStartup(void);
static void CitusQueryStatsShmemShutdown(int code, Datum arg);
@ -143,10 +141,18 @@ static void CitusQueryStatsRemoveExpiredEntries(HTAB *existingQueryIdHash);
void
InitializeCitusQueryStats(void)
{
RequestAddinShmemSpace(CitusQueryStatsSharedMemSize());
/* on PG 15, we use shmem_request_hook_type */
#if PG_VERSION_NUM < PG_VERSION_15
elog(LOG, "requesting named LWLockTranch for %s", STATS_SHARED_MEM_NAME);
RequestNamedLWLockTranche(STATS_SHARED_MEM_NAME, 1);
/* allocate shared memory */
if (!IsUnderPostmaster)
{
RequestAddinShmemSpace(CitusQueryStatsSharedMemSize());
elog(LOG, "requesting named LWLockTranch for %s", STATS_SHARED_MEM_NAME);
RequestNamedLWLockTranche(STATS_SHARED_MEM_NAME, 1);
}
#endif
/* Install hook */
prev_shmem_startup_hook = shmem_startup_hook;
@ -373,7 +379,7 @@ error:
* CitusQueryStatsSharedMemSize calculates and returns shared memory size
* required to keep query statistics.
*/
static Size
Size
CitusQueryStatsSharedMemSize(void)
{
Assert(StatStatementsMax >= 0);
@ -947,7 +953,7 @@ GetPGStatStatementsMax(void)
*/
if (pgssMax)
{
maxValue = pg_atoi(pgssMax, 4, 0);
maxValue = pg_strtoint32(pgssMax);
}
return maxValue;

View File

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

View File

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

View File

@ -75,9 +75,7 @@
#include "utils/elog.h"
#include "utils/hsearch.h"
#include "utils/jsonb.h"
#if PG_VERSION_NUM >= PG_VERSION_13
#include "common/hashfn.h"
#endif
#include "utils/inval.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"

View File

@ -356,10 +356,9 @@ CreateDependingViewsOnWorkers(Oid relationId)
continue;
}
ObjectAddress viewAddress = { 0 };
ObjectAddressSet(viewAddress, RelationRelationId, viewOid);
EnsureDependenciesExistOnAllNodes(&viewAddress);
ObjectAddress *viewAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*viewAddress, RelationRelationId, viewOid);
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(viewAddress));
char *createViewCommand = CreateViewDDLCommand(viewOid);
char *alterViewOwnerCommand = AlterViewOwnerCommand(viewOid);
@ -367,7 +366,7 @@ CreateDependingViewsOnWorkers(Oid relationId)
SendCommandToWorkersWithMetadata(createViewCommand);
SendCommandToWorkersWithMetadata(alterViewOwnerCommand);
MarkObjectDistributed(&viewAddress);
MarkObjectDistributed(viewAddress);
}
SendCommandToWorkersWithMetadata(ENABLE_DDL_PROPAGATION);
@ -603,10 +602,10 @@ ShouldSyncSequenceMetadata(Oid relationId)
return false;
}
ObjectAddress sequenceAddress = { 0 };
ObjectAddressSet(sequenceAddress, RelationRelationId, relationId);
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*sequenceAddress, RelationRelationId, relationId);
return IsObjectDistributed(&sequenceAddress);
return IsAnyObjectDistributed(list_make1(sequenceAddress));
}
@ -3805,9 +3804,8 @@ RemoteTypeIdExpression(Oid typeId)
/*
* RemoteCollationIdExpression returns an expression in text form that can
* be used to obtain the OID of a type on a different node when included
* in a query string. Currently this is a sublink because regcollation type
* is not available in PG12.
* be used to obtain the OID of a collation on a different node when included
* in a query string.
*/
static char *
RemoteCollationIdExpression(Oid colocationId)
@ -3826,16 +3824,15 @@ RemoteCollationIdExpression(Oid colocationId)
(Form_pg_collation) GETSTRUCT(collationTuple);
char *collationName = NameStr(collationform->collname);
char *collationSchemaName = get_namespace_name(collationform->collnamespace);
char *qualifiedCollationName = quote_qualified_identifier(collationSchemaName,
collationName);
StringInfo colocationIdQuery = makeStringInfo();
appendStringInfo(colocationIdQuery,
"(select oid from pg_collation"
" where collname = %s"
" and collnamespace = %s::regnamespace)",
quote_literal_cstr(collationName),
quote_literal_cstr(collationSchemaName));
StringInfo regcollationExpression = makeStringInfo();
appendStringInfo(regcollationExpression,
"%s::regcollation",
quote_literal_cstr(qualifiedCollationName));
expression = colocationIdQuery->data;
expression = regcollationExpression->data;
}
ReleaseSysCache(collationTuple);

View File

@ -66,9 +66,6 @@
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
#if PG_VERSION_NUM < 120000
#include "utils/tqual.h"
#endif
#define DISK_SPACE_FIELDS 2

View File

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

View File

@ -53,6 +53,18 @@
#include "utils/rel.h"
#include "utils/syscache.h"
/* local type declarations */
/*
* ShardInterval along with to be executed
* DDL command list.
*/
typedef struct ShardCommandList
{
ShardInterval *shardInterval;
List *ddlCommandList;
} ShardCommandList;
/* local function forward declarations */
static void VerifyTablesHaveReplicaIdentity(List *colocatedTableList);
static bool RelationCanPublishAllModifications(Oid relationId);
@ -114,6 +126,8 @@ static List * CopyShardContentsCommandList(ShardInterval *shardInterval,
static List * PostLoadShardCreationCommandList(ShardInterval *shardInterval,
const char *sourceNodeName,
int32 sourceNodePort);
static ShardCommandList * CreateShardCommandList(ShardInterval *shardInterval,
List *ddlCommandList);
/* declarations for dynamic loading */
@ -1129,6 +1143,22 @@ CopyShardTablesViaLogicalReplication(List *shardIntervalList, char *sourceNodeNa
}
/*
* CreateShardCommandList creates a struct for shard interval
* along with DDL commands to be executed.
*/
static ShardCommandList *
CreateShardCommandList(ShardInterval *shardInterval, List *ddlCommandList)
{
ShardCommandList *shardCommandList = palloc0(
sizeof(ShardCommandList));
shardCommandList->shardInterval = shardInterval;
shardCommandList->ddlCommandList = ddlCommandList;
return shardCommandList;
}
/*
* CopyShardTablesViaBlockWrites copies a shard along with its co-located shards
* from a source node to target node via COPY command. While the command is in
@ -1187,10 +1217,28 @@ CopyShardTablesViaBlockWrites(List *shardIntervalList, char *sourceNodeName,
}
/*
* Once all shards are created, we can recreate relationships between shards.
*
* Iterate through the colocated shards and create the foreign constraints and
* attach child tables to their parents in a partitioning hierarchy.
* Once all shards are copied, we can recreate relationships between shards.
* Create DDL commands to Attach child tables to their parents in a partitioning hierarchy.
*/
List *shardIntervalWithDDCommandsList = NIL;
foreach_ptr(shardInterval, shardIntervalList)
{
if (PartitionTable(shardInterval->relationId))
{
char *attachPartitionCommand =
GenerateAttachShardPartitionCommand(shardInterval);
ShardCommandList *shardCommandList = CreateShardCommandList(
shardInterval,
list_make1(attachPartitionCommand));
shardIntervalWithDDCommandsList = lappend(shardIntervalWithDDCommandsList,
shardCommandList);
}
}
/*
* Iterate through the colocated shards and create DDL commamnds
* to create the foreign constraints.
*/
foreach_ptr(shardInterval, shardIntervalList)
{
@ -1201,25 +1249,25 @@ CopyShardTablesViaBlockWrites(List *shardIntervalList, char *sourceNodeName,
&shardForeignConstraintCommandList,
&referenceTableForeignConstraintList);
List *commandList = NIL;
commandList = list_concat(commandList, shardForeignConstraintCommandList);
commandList = list_concat(commandList, referenceTableForeignConstraintList);
if (PartitionTable(shardInterval->relationId))
{
char *attachPartitionCommand =
GenerateAttachShardPartitionCommand(shardInterval);
commandList = lappend(commandList, attachPartitionCommand);
}
char *tableOwner = TableOwner(shardInterval->relationId);
SendCommandListToWorkerOutsideTransaction(targetNodeName, targetNodePort,
tableOwner, commandList);
MemoryContextReset(localContext);
ShardCommandList *shardCommandList = CreateShardCommandList(
shardInterval,
list_concat(shardForeignConstraintCommandList,
referenceTableForeignConstraintList));
shardIntervalWithDDCommandsList = lappend(shardIntervalWithDDCommandsList,
shardCommandList);
}
/* Now execute the Partitioning & Foreign constraints creation commads. */
ShardCommandList *shardCommandList = NULL;
foreach_ptr(shardCommandList, shardIntervalWithDDCommandsList)
{
char *tableOwner = TableOwner(shardCommandList->shardInterval->relationId);
SendCommandListToWorkerOutsideTransaction(targetNodeName, targetNodePort,
tableOwner,
shardCommandList->ddlCommandList);
}
MemoryContextReset(localContext);
MemoryContextSwitchTo(oldContext);
}

View File

@ -60,10 +60,7 @@
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/syscache.h"
#if PG_VERSION_NUM >= PG_VERSION_13
#include "common/hashfn.h"
#endif
/* RebalanceOptions are the options used to control the rebalance algorithm */

View File

@ -77,6 +77,8 @@ static void SplitShardReplicationSetup(ShardInterval *shardIntervalToSplit,
WorkerNode *sourceWorkerNode,
List *workersForPlacementList);
static HTAB * CreateWorkerForPlacementSet(List *workersForPlacementList);
static void CreateAuxiliaryStructuresForShardGroup(List *shardGroupSplitIntervalListList,
List *workersForPlacementList);
static void CreateObjectOnPlacement(List *objectCreationCommandList,
WorkerNode *workerNode);
static List * CreateSplitIntervalsForShardGroup(List *sourceColocatedShardList,
@ -98,11 +100,17 @@ static void DoSplitCopy(WorkerNode *sourceShardNode,
List *shardGroupSplitIntervalListList,
List *workersForPlacementList,
char *snapShotName);
static void DoSplitCopy(WorkerNode *sourceShardNode,
List *sourceColocatedShardIntervalList,
List *shardGroupSplitIntervalListList,
List *workersForPlacementList);
static StringInfo CreateSplitCopyCommand(ShardInterval *sourceShardSplitInterval,
List *splitChildrenShardIntervalList,
List *workersForPlacementList);
static void InsertSplitChildrenShardMetadata(List *shardGroupSplitIntervalListList,
List *workersForPlacementList);
static void CreatePartitioningHierarchy(List *shardGroupSplitIntervalListList,
List *workersForPlacementList);
static void CreateForeignKeyConstraints(List *shardGroupSplitIntervalListList,
List *workersForPlacementList);
static void TryDropSplitShardsOnFailure(HTAB *mapOfShardToPlacementCreatedByWorkflow);
@ -456,8 +464,8 @@ SplitShard(SplitMode splitMode,
/*
* ShardIntervalHashCode computes the hash code for a shard from the
* placement's shard id.
* ShardIntervalHashCode computes the hash code for a Shardinterval using
* shardId.
*/
static uint32
ShardIntervalHashCode(const void *key, Size keySize)
@ -568,6 +576,12 @@ BlockingShardSplit(SplitOperation splitOperation,
shardGroupSplitIntervalListList,
workersForPlacementList);
/*
* Up to this point, we performed various subtransactions that may
* require additional clean-up in case of failure. The remaining operations
* going forward are part of the same distributed transaction.
*/
/*
* Drop old shards and delete related metadata. Have to do that before
* creating the new shard metadata, because there's cross-checks
@ -579,6 +593,10 @@ BlockingShardSplit(SplitOperation splitOperation,
InsertSplitChildrenShardMetadata(shardGroupSplitIntervalListList,
workersForPlacementList);
/* create partitioning hierarchy, if any */
CreatePartitioningHierarchy(shardGroupSplitIntervalListList,
workersForPlacementList);
/*
* Create foreign keys if exists after the metadata changes happening in
* DropShardList() and InsertSplitChildrenShardMetadata() because the foreign
@ -666,7 +684,7 @@ CreateTaskForDDLCommandList(List *ddlCommandList, WorkerNode *workerNode)
/* Create ShardGroup auxiliary structures (indexes, stats, replicaindentities, triggers)
* on a list of corresponding workers.
*/
void
static void
CreateAuxiliaryStructuresForShardGroup(List *shardGroupSplitIntervalListList,
List *workersForPlacementList)
{
@ -762,47 +780,56 @@ DoSplitCopy(WorkerNode *sourceShardNode, List *sourceColocatedShardIntervalList,
forboth_ptr(sourceShardIntervalToCopy, sourceColocatedShardIntervalList,
splitShardIntervalList, shardGroupSplitIntervalListList)
{
StringInfo splitCopyUdfCommand = CreateSplitCopyCommand(sourceShardIntervalToCopy,
/*
* Skip copying data for partitioned tables, because they contain no
* data themselves. Their partitions do contain data, but those are
* different colocated shards that will be copied seperately.
*/
if (!PartitionedTable(sourceShardIntervalToCopy->relationId))
{
StringInfo splitCopyUdfCommand = CreateSplitCopyCommand(sourceShardIntervalToCopy,
splitShardIntervalList,
destinationWorkerNodesList);
List *ddlCommandList = NIL;
StringInfo beginTransaction = makeStringInfo();
appendStringInfo(beginTransaction,
"BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;");
ddlCommandList = lappend(ddlCommandList, beginTransaction->data);
List *ddlCommandList = NIL;
StringInfo beginTransaction = makeStringInfo();
appendStringInfo(beginTransaction,
"BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;");
ddlCommandList = lappend(ddlCommandList, beginTransaction->data);
/* Set snapshot */
if (snapShotName != NULL)
{
StringInfo snapShotString = makeStringInfo();
appendStringInfo(snapShotString, "SET TRANSACTION SNAPSHOT %s;",
quote_literal_cstr(
snapShotName));
ddlCommandList = lappend(ddlCommandList, snapShotString->data);
printf("Sameer final string snapshotted:%s\n", snapShotString->data);
}
ddlCommandList = lappend(ddlCommandList, splitCopyUdfCommand->data);
StringInfo commitCommand = makeStringInfo();
appendStringInfo(commitCommand, "COMMIT;");
ddlCommandList = lappend(ddlCommandList, commitCommand->data);
Task *splitCopyTask = CitusMakeNode(Task);
splitCopyTask->jobId = sourceShardIntervalToCopy->shardId;
splitCopyTask->taskId = taskId;
splitCopyTask->taskType = READ_TASK;
splitCopyTask->replicationModel = REPLICATION_MODEL_INVALID;
SetTaskQueryStringList(splitCopyTask, ddlCommandList);
ShardPlacement *taskPlacement = CitusMakeNode(ShardPlacement);
SetPlacementNodeMetadata(taskPlacement, sourceShardNode);
splitCopyTask->taskPlacementList = list_make1(taskPlacement);
splitCopyTaskList = lappend(splitCopyTaskList, splitCopyTask);
taskId++;
/* Set snapshot */
if (snapShotName != NULL)
{
StringInfo snapShotString = makeStringInfo();
appendStringInfo(snapShotString, "SET TRANSACTION SNAPSHOT %s;",
quote_literal_cstr(
snapShotName));
ddlCommandList = lappend(ddlCommandList, snapShotString->data);
printf("Sameer final string snapshotted:%s\n", snapShotString->data);
}
ddlCommandList = lappend(ddlCommandList, splitCopyUdfCommand->data);
StringInfo commitCommand = makeStringInfo();
appendStringInfo(commitCommand, "COMMIT;");
ddlCommandList = lappend(ddlCommandList, commitCommand->data);
Task *splitCopyTask = CitusMakeNode(Task);
splitCopyTask->jobId = sourceShardIntervalToCopy->shardId;
splitCopyTask->taskId = taskId;
splitCopyTask->taskType = READ_TASK;
splitCopyTask->replicationModel = REPLICATION_MODEL_INVALID;
SetTaskQueryStringList(splitCopyTask, ddlCommandList);
ShardPlacement *taskPlacement = CitusMakeNode(ShardPlacement);
SetPlacementNodeMetadata(taskPlacement, sourceShardNode);
splitCopyTask->taskPlacementList = list_make1(taskPlacement);
splitCopyTaskList = lappend(splitCopyTaskList, splitCopyTask);
taskId++;
}
ExecuteTaskListOutsideTransaction(ROW_MODIFY_NONE, splitCopyTaskList,
@ -1022,6 +1049,46 @@ InsertSplitChildrenShardMetadata(List *shardGroupSplitIntervalListList,
}
/*
* CreatePartitioningHierarchy creates the partitioning
* hierarchy between the shardList, if any.
*/
static void
CreatePartitioningHierarchy(List *shardGroupSplitIntervalListList,
List *workersForPlacementList)
{
/* Create partition heirarchy between shards */
List *shardIntervalList = NIL;
/*
* Iterate over all the shards in the shard group.
*/
foreach_ptr(shardIntervalList, shardGroupSplitIntervalListList)
{
ShardInterval *shardInterval = NULL;
WorkerNode *workerPlacementNode = NULL;
/*
* Iterate on split shards list for a given shard and create constraints.
*/
forboth_ptr(shardInterval, shardIntervalList, workerPlacementNode,
workersForPlacementList)
{
if (PartitionTable(shardInterval->relationId))
{
char *attachPartitionCommand =
GenerateAttachShardPartitionCommand(shardInterval);
SendCommandToWorker(
workerPlacementNode->workerName,
workerPlacementNode->workerPort,
attachPartitionCommand);
}
}
}
}
/*
* Create foreign key constraints on the split children shards.
*/
@ -1141,7 +1208,7 @@ DropShardList(List *shardIntervalList)
/*
* In case of failure, DropShardPlacementList drops shard placements and their metadata from both the
* In case of failure, TryDropSplitShardsOnFailure drops in-progress shard placements from both the
* coordinator and mx nodes.
*/
static void

View File

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

View File

@ -131,9 +131,7 @@ static void WarnIfListHasForeignDistributedTable(List *rangeTableList);
/* Distributed planner hook */
PlannedStmt *
distributed_planner(Query *parse,
#if PG_VERSION_NUM >= PG_VERSION_13
const char *query_string,
#endif
int cursorOptions,
ParamListInfo boundParams)
{
@ -1839,7 +1837,7 @@ TranslatedVars(PlannerInfo *root, int relationIndex)
FindTargetAppendRelInfo(root, relationIndex);
if (targetAppendRelInfo != NULL)
{
/* postgres deletes translated_vars after pg13, hence we deep copy them here */
/* postgres deletes translated_vars, hence we deep copy them here */
Node *targetNode = NULL;
foreach_ptr(targetNode, targetAppendRelInfo->translated_vars)
{

View File

@ -170,7 +170,7 @@ TryToDelegateFunctionCall(DistributedPlanningContext *planContext)
}
/*
* In pg12's planning phase empty FROMs are represented with an RTE_RESULT.
* In the planning phase empty FROMs are represented with an RTE_RESULT.
* When we arrive here, standard_planner has already been called which calls
* replace_empty_jointree() which replaces empty fromlist with a list of
* single RTE_RESULT RangleTableRef node.

View File

@ -21,9 +21,7 @@
#include "distributed/query_utils.h"
#include "distributed/worker_manager.h"
#include "utils/builtins.h"
#if PG_VERSION_NUM >= PG_VERSION_13
#include "common/hashfn.h"
#endif
/* controlled via GUC, used mostly for testing */
bool LogIntermediateResults = false;
@ -373,9 +371,6 @@ RemoveLocalNodeFromWorkerList(List *workerNodeList)
int32 localGroupId = GetLocalGroupId();
ListCell *workerNodeCell = NULL;
#if PG_VERSION_NUM < PG_VERSION_13
ListCell *prev = NULL;
#endif
foreach(workerNodeCell, workerNodeList)
{
WorkerNode *workerNode = (WorkerNode *) lfirst(workerNodeCell);
@ -383,9 +378,6 @@ RemoveLocalNodeFromWorkerList(List *workerNodeList)
{
return list_delete_cell_compat(workerNodeList, workerNodeCell, prev);
}
#if PG_VERSION_NUM < PG_VERSION_13
prev = workerNodeCell;
#endif
}
return workerNodeList;

View File

@ -297,8 +297,6 @@ ExplainSubPlans(DistributedPlan *distributedPlan, ExplainState *es)
*/
char *queryString = pstrdup("");
instr_time planduration;
#if PG_VERSION_NUM >= PG_VERSION_13
BufferUsage bufusage_start,
bufusage;
@ -306,7 +304,7 @@ ExplainSubPlans(DistributedPlan *distributedPlan, ExplainState *es)
{
bufusage_start = pgBufferUsage;
}
#endif
if (es->format == EXPLAIN_FORMAT_TEXT)
{
char *resultId = GenerateResultId(planId, subPlan->subPlanId);
@ -350,15 +348,12 @@ ExplainSubPlans(DistributedPlan *distributedPlan, ExplainState *es)
INSTR_TIME_SET_ZERO(planduration);
#if PG_VERSION_NUM >= PG_VERSION_13
/* calc differences of buffer counters. */
if (es->buffers)
{
memset(&bufusage, 0, sizeof(BufferUsage));
BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start);
}
#endif
ExplainOpenGroup("PlannedStmt", "PlannedStmt", false, es);
@ -923,18 +918,13 @@ BuildRemoteExplainQuery(char *queryString, ExplainState *es)
appendStringInfo(explainQuery,
"EXPLAIN (ANALYZE %s, VERBOSE %s, "
"COSTS %s, BUFFERS %s, "
#if PG_VERSION_NUM >= PG_VERSION_13
"WAL %s, "
#endif
"COSTS %s, BUFFERS %s, WAL %s, "
"TIMING %s, SUMMARY %s, FORMAT %s) %s",
es->analyze ? "TRUE" : "FALSE",
es->verbose ? "TRUE" : "FALSE",
es->costs ? "TRUE" : "FALSE",
es->buffers ? "TRUE" : "FALSE",
#if PG_VERSION_NUM >= PG_VERSION_13
es->wal ? "TRUE" : "FALSE",
#endif
es->timing ? "TRUE" : "FALSE",
es->summary ? "TRUE" : "FALSE",
formatStr,
@ -1028,9 +1018,7 @@ worker_save_query_explain_analyze(PG_FUNCTION_ARGS)
/* use the same defaults as NewExplainState() for following options */
es->buffers = ExtractFieldBoolean(explainOptions, "buffers", es->buffers);
#if PG_VERSION_NUM >= PG_VERSION_13
es->wal = ExtractFieldBoolean(explainOptions, "wal", es->wal);
#endif
es->costs = ExtractFieldBoolean(explainOptions, "costs", es->costs);
es->summary = ExtractFieldBoolean(explainOptions, "summary", es->summary);
es->verbose = ExtractFieldBoolean(explainOptions, "verbose", es->verbose);
@ -1178,9 +1166,7 @@ CitusExplainOneQuery(Query *query, int cursorOptions, IntoClause *into,
/* save the flags of current EXPLAIN command */
CurrentDistributedQueryExplainOptions.costs = es->costs;
CurrentDistributedQueryExplainOptions.buffers = es->buffers;
#if PG_VERSION_NUM >= PG_VERSION_13
CurrentDistributedQueryExplainOptions.wal = es->wal;
#endif
CurrentDistributedQueryExplainOptions.verbose = es->verbose;
CurrentDistributedQueryExplainOptions.summary = es->summary;
CurrentDistributedQueryExplainOptions.timing = es->timing;
@ -1189,7 +1175,6 @@ CitusExplainOneQuery(Query *query, int cursorOptions, IntoClause *into,
/* rest is copied from ExplainOneQuery() */
instr_time planstart,
planduration;
#if PG_VERSION_NUM >= PG_VERSION_13
BufferUsage bufusage_start,
bufusage;
@ -1197,7 +1182,6 @@ CitusExplainOneQuery(Query *query, int cursorOptions, IntoClause *into,
{
bufusage_start = pgBufferUsage;
}
#endif
INSTR_TIME_SET_CURRENT(planstart);
@ -1205,7 +1189,6 @@ CitusExplainOneQuery(Query *query, int cursorOptions, IntoClause *into,
PlannedStmt *plan = pg_plan_query_compat(query, NULL, cursorOptions, params);
INSTR_TIME_SET_CURRENT(planduration);
INSTR_TIME_SUBTRACT(planduration, planstart);
#if PG_VERSION_NUM >= PG_VERSION_13
/* calc differences of buffer counters. */
if (es->buffers)
@ -1213,7 +1196,6 @@ CitusExplainOneQuery(Query *query, int cursorOptions, IntoClause *into,
memset(&bufusage, 0, sizeof(BufferUsage));
BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start);
}
#endif
/* run it (if needed) and produce output */
ExplainOnePlanCompat(plan, into, es, queryString, params, queryEnv,
@ -1467,17 +1449,12 @@ WrapQueryForExplainAnalyze(const char *queryString, TupleDesc tupleDesc,
StringInfo explainOptions = makeStringInfo();
appendStringInfo(explainOptions,
"{\"verbose\": %s, \"costs\": %s, \"buffers\": %s, "
#if PG_VERSION_NUM >= PG_VERSION_13
"\"wal\": %s, "
#endif
"{\"verbose\": %s, \"costs\": %s, \"buffers\": %s, \"wal\": %s, "
"\"timing\": %s, \"summary\": %s, \"format\": \"%s\"}",
CurrentDistributedQueryExplainOptions.verbose ? "true" : "false",
CurrentDistributedQueryExplainOptions.costs ? "true" : "false",
CurrentDistributedQueryExplainOptions.buffers ? "true" : "false",
#if PG_VERSION_NUM >= PG_VERSION_13
CurrentDistributedQueryExplainOptions.wal ? "true" : "false",
#endif
CurrentDistributedQueryExplainOptions.timing ? "true" : "false",
CurrentDistributedQueryExplainOptions.summary ? "true" : "false",
ExplainFormatStr(CurrentDistributedQueryExplainOptions.format));
@ -1632,13 +1609,11 @@ ExplainOneQuery(Query *query, int cursorOptions,
{
instr_time planstart,
planduration;
#if PG_VERSION_NUM >= PG_VERSION_13
BufferUsage bufusage_start,
bufusage;
if (es->buffers)
bufusage_start = pgBufferUsage;
#endif
INSTR_TIME_SET_CURRENT(planstart);
/* plan the query */
@ -1647,15 +1622,13 @@ ExplainOneQuery(Query *query, int cursorOptions,
INSTR_TIME_SET_CURRENT(planduration);
INSTR_TIME_SUBTRACT(planduration, planstart);
#if PG_VERSION_NUM >= PG_VERSION_13
/* calc differences of buffer counters. */
if (es->buffers)
{
memset(&bufusage, 0, sizeof(BufferUsage));
BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start);
}
#endif
/* run it (if needed) and produce output */
ExplainOnePlanCompat(plan, into, es, queryString, params, queryEnv,
&planduration, (es->buffers ? &bufusage : NULL));
@ -1696,10 +1669,10 @@ ExplainWorkerPlan(PlannedStmt *plannedstmt, DestReceiver *dest, ExplainState *es
if (es->buffers)
instrument_option |= INSTRUMENT_BUFFERS;
#if PG_VERSION_NUM >= PG_VERSION_13
if (es->wal)
instrument_option |= INSTRUMENT_WAL;
#endif
/*
* We always collect timing for the entire statement, even when node-level
* timing is off, so we don't look at es->timing here. (We could skip

View File

@ -1490,9 +1490,7 @@ MasterExtendedOpNode(MultiExtendedOp *originalOpNode,
masterExtendedOpNode->hasDistinctOn = originalOpNode->hasDistinctOn;
masterExtendedOpNode->limitCount = originalOpNode->limitCount;
masterExtendedOpNode->limitOffset = originalOpNode->limitOffset;
#if PG_VERSION_NUM >= PG_VERSION_13
masterExtendedOpNode->limitOption = originalOpNode->limitOption;
#endif
masterExtendedOpNode->havingQual = newHavingQual;
if (!extendedOpNodeProperties->onlyPushableWindowFunctions)
@ -2489,14 +2487,12 @@ WorkerExtendedOpNode(MultiExtendedOp *originalOpNode,
workerExtendedOpNode->windowClause = queryWindowClause.workerWindowClauseList;
workerExtendedOpNode->sortClauseList = queryOrderByLimit.workerSortClauseList;
workerExtendedOpNode->limitCount = queryOrderByLimit.workerLimitCount;
#if PG_VERSION_NUM >= PG_VERSION_13
/*
* If the limitCount cannot be pushed down it will be NULL, so the deparser will
* ignore the limitOption.
*/
workerExtendedOpNode->limitOption = originalOpNode->limitOption;
#endif
return workerExtendedOpNode;
}

View File

@ -1734,9 +1734,7 @@ MultiExtendedOpNode(Query *queryTree, Query *originalQuery)
extendedOpNode->sortClauseList = queryTree->sortClause;
extendedOpNode->limitCount = queryTree->limitCount;
extendedOpNode->limitOffset = queryTree->limitOffset;
#if PG_VERSION_NUM >= PG_VERSION_13
extendedOpNode->limitOption = queryTree->limitOption;
#endif
extendedOpNode->havingQual = queryTree->havingQual;
extendedOpNode->distinctClause = queryTree->distinctClause;
extendedOpNode->hasDistinctOn = queryTree->hasDistinctOn;

View File

@ -230,9 +230,7 @@ static List * FetchEqualityAttrNumsForRTEOpExpr(OpExpr *opExpr);
static List * FetchEqualityAttrNumsForRTEBoolExpr(BoolExpr *boolExpr);
static List * FetchEqualityAttrNumsForList(List *nodeList);
static int PartitionColumnIndex(Var *targetVar, List *targetList);
#if PG_VERSION_NUM >= PG_VERSION_13
static List * GetColumnOriginalIndexes(Oid relationId);
#endif
/*
@ -541,9 +539,7 @@ BuildJobQuery(MultiNode *multiNode, List *dependentJobList)
List *sortClauseList = NIL;
Node *limitCount = NULL;
Node *limitOffset = NULL;
#if PG_VERSION_NUM >= PG_VERSION_13
LimitOption limitOption = LIMIT_OPTION_DEFAULT;
#endif
Node *havingQual = NULL;
bool hasDistinctOn = false;
List *distinctClause = NIL;
@ -625,9 +621,7 @@ BuildJobQuery(MultiNode *multiNode, List *dependentJobList)
limitCount = extendedOp->limitCount;
limitOffset = extendedOp->limitOffset;
#if PG_VERSION_NUM >= PG_VERSION_13
limitOption = extendedOp->limitOption;
#endif
sortClauseList = extendedOp->sortClauseList;
havingQual = extendedOp->havingQual;
}
@ -683,9 +677,7 @@ BuildJobQuery(MultiNode *multiNode, List *dependentJobList)
jobQuery->groupClause = groupClauseList;
jobQuery->limitOffset = limitOffset;
jobQuery->limitCount = limitCount;
#if PG_VERSION_NUM >= PG_VERSION_13
jobQuery->limitOption = limitOption;
#endif
jobQuery->havingQual = havingQual;
jobQuery->hasAggs = contain_aggs_of_level((Node *) targetList, 0) ||
contain_aggs_of_level((Node *) havingQual, 0);
@ -1338,8 +1330,6 @@ static void
SetJoinRelatedColumnsCompat(RangeTblEntry *rangeTableEntry, Oid leftRelId, Oid rightRelId,
List *leftColumnVars, List *rightColumnVars)
{
#if PG_VERSION_NUM >= PG_VERSION_13
/* We don't have any merged columns so set it to 0 */
rangeTableEntry->joinmergedcols = 0;
@ -1362,13 +1352,9 @@ SetJoinRelatedColumnsCompat(RangeTblEntry *rangeTableEntry, Oid leftRelId, Oid r
int rightColsSize = list_length(rightColumnVars);
rangeTableEntry->joinrightcols = GeneratePositiveIntSequenceList(rightColsSize);
}
#endif
}
#if PG_VERSION_NUM >= PG_VERSION_13
/*
* GetColumnOriginalIndexes gets the original indexes of columns by taking column drops into account.
*/
@ -1392,8 +1378,6 @@ GetColumnOriginalIndexes(Oid relationId)
}
#endif
/*
* ExtractRangeTableId gets the range table id from a node that could
* either be a JoinExpr or RangeTblRef.

View File

@ -167,10 +167,7 @@ static bool FindQueryContainingRTEIdentityInternal(Node *node,
FindQueryContainingRteIdentityContext *
context);
#if PG_VERSION_NUM >= PG_VERSION_13
static int ParentCountPriorToAppendRel(List *appendRelList, AppendRelInfo *appendRelInfo);
#endif
/*
@ -398,12 +395,10 @@ SafeToPushdownUnionSubquery(Query *originalQuery,
/*
* RangeTableOffsetCompat returns the range table offset(in glob->finalrtable) for the appendRelInfo.
* For PG < 13 this is a no op.
*/
static int
RangeTableOffsetCompat(PlannerInfo *root, AppendRelInfo *appendRelInfo)
{
#if PG_VERSION_NUM >= PG_VERSION_13
int parentCount = ParentCountPriorToAppendRel(root->append_rel_list, appendRelInfo);
int skipParentCount = parentCount - 1;
@ -434,9 +429,6 @@ RangeTableOffsetCompat(PlannerInfo *root, AppendRelInfo *appendRelInfo)
*/
int parentRelIndex = appendRelInfo->parent_relid - 1;
return parentRelIndex - indexInRtable;
#else
return 0;
#endif
}
@ -1482,8 +1474,6 @@ AddUnionAllSetOperationsToAttributeEquivalenceClass(AttributeEquivalenceClass *
}
#if PG_VERSION_NUM >= PG_VERSION_13
/*
* ParentCountPriorToAppendRel returns the number of parents that come before
* the given append rel info.
@ -1506,8 +1496,6 @@ ParentCountPriorToAppendRel(List *appendRelList, AppendRelInfo *targetAppendRelI
}
#endif
/*
* AddUnionSetOperationsToAttributeEquivalenceClass recursively iterates on all the
* setOperations and adds each corresponding target entry to the given equivalence

View File

@ -112,7 +112,6 @@ RelayEventExtendNames(Node *parseTree, char *schemaName, uint64 shardId)
break;
}
#if PG_VERSION_NUM >= PG_VERSION_13
case T_AlterStatsStmt:
{
AlterStatsStmt *alterStatsStmt = (AlterStatsStmt *) parseTree;
@ -124,7 +123,6 @@ RelayEventExtendNames(Node *parseTree, char *schemaName, uint64 shardId)
break;
}
#endif
case T_AlterTableStmt:
{

View File

@ -17,13 +17,9 @@
#include "distributed/pg_version_constants.h"
#if PG_VERSION_NUM >= PG_VERSION_12
#include "access/genam.h"
#endif
#if PG_VERSION_NUM >= PG_VERSION_13
#include "postmaster/interrupt.h"
#endif
#include "access/htup_details.h"
#include "access/sysattr.h"
@ -33,6 +29,7 @@
#include "catalog/namespace.h"
#include "catalog/pg_constraint.h"
#include "distributed/adaptive_executor.h"
#include "distributed/citus_safe_lib.h"
#include "distributed/colocation_utils.h"
#include "distributed/connection_management.h"
#include "distributed/listutils.h"
@ -1815,7 +1812,7 @@ TotalRelationSizeForSubscription(MultiConnection *connection, char *command)
{
char *resultString = PQgetvalue(result, 0, 0);
remoteTotalSize = pg_strtouint64(resultString, NULL, 10);
remoteTotalSize = SafeStringToUint64(resultString);
}
else
{
@ -2049,13 +2046,11 @@ WaitForMiliseconds(long timeout)
CHECK_FOR_INTERRUPTS();
}
#if PG_VERSION_NUM >= PG_VERSION_13
if (ConfigReloadPending)
{
ConfigReloadPending = false;
ProcessConfigFile(PGC_SIGHUP);
}
#endif
}

View File

@ -140,6 +140,7 @@ DEFINE_COLUMNAR_PASSTHROUGH_FUNC(test_columnar_storage_write_new_page)
#define DUMMY_REAL_TIME_EXECUTOR_ENUM_VALUE 9999999
static char *CitusVersion = CITUS_VERSION;
static char *DeprecatedEmptyString = "";
/* deprecated GUC value that should not be used anywhere outside this file */
static int ReplicationModel = REPLICATION_MODEL_STREAMING;
@ -149,8 +150,15 @@ static GucStringAssignHook OldApplicationNameAssignHook = NULL;
static object_access_hook_type PrevObjectAccessHook = NULL;
#if PG_VERSION_NUM >= PG_VERSION_15
static shmem_request_hook_type prev_shmem_request_hook = NULL;
#endif
void _PG_init(void);
#if PG_VERSION_NUM >= PG_VERSION_15
static void citus_shmem_request(void);
#endif
static void CitusObjectAccessHook(ObjectAccessType access, Oid classId, Oid objectId, int
subId, void *arg);
static void DoInitialCleanup(void);
@ -367,6 +375,11 @@ _PG_init(void)
original_client_auth_hook = ClientAuthentication_hook;
ClientAuthentication_hook = CitusAuthHook;
#if PG_VERSION_NUM >= PG_VERSION_15
prev_shmem_request_hook = shmem_request_hook;
shmem_request_hook = citus_shmem_request;
#endif
InitializeMaintenanceDaemon();
/* initialize coordinated transaction management */
@ -402,6 +415,7 @@ _PG_init(void)
PrevObjectAccessHook = object_access_hook;
object_access_hook = CitusObjectAccessHook;
/* ensure columnar module is loaded at the right time */
load_file(COLUMNAR_MODULE_NAME, false);
@ -444,6 +458,30 @@ _PG_init(void)
}
#if PG_VERSION_NUM >= PG_VERSION_15
/*
* Requests any additional shared memory required for citus.
*/
static void
citus_shmem_request(void)
{
if (prev_shmem_request_hook)
{
prev_shmem_request_hook();
}
RequestAddinShmemSpace(BackendManagementShmemSize());
RequestAddinShmemSpace(SharedConnectionStatsShmemSize());
RequestAddinShmemSpace(MaintenanceDaemonShmemSize());
RequestAddinShmemSpace(CitusQueryStatsSharedMemSize());
RequestNamedLWLockTranche(STATS_SHARED_MEM_NAME, 1);
}
#endif
/*
* DoInitialCleanup does cleanup at start time.
* Currently it:
@ -1236,6 +1274,26 @@ RegisterCitusConfigVariables(void)
GUC_NO_SHOW_ALL,
NULL, NULL, NULL);
/*
* This was a GUC we added on Citus 11.0.1, and
* replaced with another name on 11.0.2 via #5920.
* However, as this GUC has been used in
* citus_shard_indexes_on_worker-11.0.1
* script. So, it is not easy to completely get rid
* of the GUC. Especially with PG 15+, Postgres verifies
* existence of the GUCs that are used. So, without this
* CREATE EXTENSION fails.
*/
DefineCustomStringVariable(
"citus.hide_shards_from_app_name_prefixes",
gettext_noop("Deprecated, use citus.show_shards_for_app_name_prefixes"),
NULL,
&DeprecatedEmptyString,
"",
PGC_SUSET,
GUC_NO_SHOW_ALL,
NULL, NULL, NULL);
DefineCustomIntVariable(
"citus.isolation_test_session_process_id",
NULL,

View File

@ -1,3 +1,5 @@
#include "udfs/citus_locks/11.1-1.sql"
DROP FUNCTION pg_catalog.worker_create_schema(bigint,text);
DROP FUNCTION pg_catalog.worker_cleanup_job_schema_cache();
DROP FUNCTION pg_catalog.worker_fetch_foreign_file(text, text, bigint, text[], integer[]);

View File

@ -78,3 +78,6 @@ DROP FUNCTION pg_catalog.get_all_active_transactions(OUT datid oid, OUT process_
OUT worker_query BOOL, OUT transaction_number int8, OUT transaction_stamp timestamptz,
OUT global_pid int8);
#include "../udfs/get_all_active_transactions/11.0-1.sql"
DROP VIEW pg_catalog.citus_locks;
DROP FUNCTION pg_catalog.citus_locks();

View File

@ -0,0 +1,86 @@
-- citus_locks combines the pg_locks views from all nodes and adds global_pid, nodeid, and
-- relation_name. The columns of citus_locks don't change based on the Postgres version,
-- however the pg_locks's columns do. Postgres 14 added one more column to pg_locks
-- (waitstart timestamptz). citus_locks has the most expansive column set, including the
-- newly added column. If citus_locks is queried in a Postgres version where pg_locks
-- doesn't have some columns, the values for those columns in citus_locks will be NULL
CREATE OR REPLACE FUNCTION pg_catalog.citus_locks (
OUT global_pid bigint,
OUT nodeid int,
OUT locktype text,
OUT database oid,
OUT relation oid,
OUT relation_name text,
OUT page integer,
OUT tuple smallint,
OUT virtualxid text,
OUT transactionid xid,
OUT classid oid,
OUT objid oid,
OUT objsubid smallint,
OUT virtualtransaction text,
OUT pid integer,
OUT mode text,
OUT granted boolean,
OUT fastpath boolean,
OUT waitstart timestamp with time zone
)
RETURNS SETOF record
LANGUAGE plpgsql
AS $function$
BEGIN
RETURN QUERY
SELECT *
FROM jsonb_to_recordset((
SELECT
jsonb_agg(all_citus_locks_rows_as_jsonb.citus_locks_row_as_jsonb)::jsonb
FROM (
SELECT
jsonb_array_elements(run_command_on_all_nodes.result::jsonb)::jsonb ||
('{"nodeid":' || run_command_on_all_nodes.nodeid || '}')::jsonb AS citus_locks_row_as_jsonb
FROM
run_command_on_all_nodes (
$$
SELECT
coalesce(to_jsonb (array_agg(citus_locks_from_one_node.*)), '[{}]'::jsonb)
FROM (
SELECT
global_pid, pg_locks.relation::regclass::text AS relation_name, pg_locks.*
FROM pg_locks
LEFT JOIN get_all_active_transactions () ON process_id = pid) AS citus_locks_from_one_node;
$$,
parallel:= TRUE,
give_warning_for_connection_errors:= TRUE)
WHERE
success = 't')
AS all_citus_locks_rows_as_jsonb))
AS (
global_pid bigint,
nodeid int,
locktype text,
database oid,
relation oid,
relation_name text,
page integer,
tuple smallint,
virtualxid text,
transactionid xid,
classid oid,
objid oid,
objsubid smallint,
virtualtransaction text,
pid integer,
mode text,
granted boolean,
fastpath boolean,
waitstart timestamp with time zone
);
END;
$function$;
CREATE OR REPLACE VIEW citus.citus_locks AS
SELECT * FROM pg_catalog.citus_locks();
ALTER VIEW citus.citus_locks SET SCHEMA pg_catalog;
GRANT SELECT ON pg_catalog.citus_locks TO PUBLIC;

View File

@ -0,0 +1,86 @@
-- citus_locks combines the pg_locks views from all nodes and adds global_pid, nodeid, and
-- relation_name. The columns of citus_locks don't change based on the Postgres version,
-- however the pg_locks's columns do. Postgres 14 added one more column to pg_locks
-- (waitstart timestamptz). citus_locks has the most expansive column set, including the
-- newly added column. If citus_locks is queried in a Postgres version where pg_locks
-- doesn't have some columns, the values for those columns in citus_locks will be NULL
CREATE OR REPLACE FUNCTION pg_catalog.citus_locks (
OUT global_pid bigint,
OUT nodeid int,
OUT locktype text,
OUT database oid,
OUT relation oid,
OUT relation_name text,
OUT page integer,
OUT tuple smallint,
OUT virtualxid text,
OUT transactionid xid,
OUT classid oid,
OUT objid oid,
OUT objsubid smallint,
OUT virtualtransaction text,
OUT pid integer,
OUT mode text,
OUT granted boolean,
OUT fastpath boolean,
OUT waitstart timestamp with time zone
)
RETURNS SETOF record
LANGUAGE plpgsql
AS $function$
BEGIN
RETURN QUERY
SELECT *
FROM jsonb_to_recordset((
SELECT
jsonb_agg(all_citus_locks_rows_as_jsonb.citus_locks_row_as_jsonb)::jsonb
FROM (
SELECT
jsonb_array_elements(run_command_on_all_nodes.result::jsonb)::jsonb ||
('{"nodeid":' || run_command_on_all_nodes.nodeid || '}')::jsonb AS citus_locks_row_as_jsonb
FROM
run_command_on_all_nodes (
$$
SELECT
coalesce(to_jsonb (array_agg(citus_locks_from_one_node.*)), '[{}]'::jsonb)
FROM (
SELECT
global_pid, pg_locks.relation::regclass::text AS relation_name, pg_locks.*
FROM pg_locks
LEFT JOIN get_all_active_transactions () ON process_id = pid) AS citus_locks_from_one_node;
$$,
parallel:= TRUE,
give_warning_for_connection_errors:= TRUE)
WHERE
success = 't')
AS all_citus_locks_rows_as_jsonb))
AS (
global_pid bigint,
nodeid int,
locktype text,
database oid,
relation oid,
relation_name text,
page integer,
tuple smallint,
virtualxid text,
transactionid xid,
classid oid,
objid oid,
objsubid smallint,
virtualtransaction text,
pid integer,
mode text,
granted boolean,
fastpath boolean,
waitstart timestamp with time zone
);
END;
$function$;
CREATE OR REPLACE VIEW citus.citus_locks AS
SELECT * FROM pg_catalog.citus_locks();
ALTER VIEW citus.citus_locks SET SCHEMA pg_catalog;
GRANT SELECT ON pg_catalog.citus_locks TO PUBLIC;

View File

@ -104,8 +104,6 @@ static BackendData *MyBackendData = NULL;
static CitusBackendType CurrentBackendType = CITUS_BACKEND_NOT_ASSIGNED;
static void BackendManagementShmemInit(void);
static size_t BackendManagementShmemSize(void);
static void DetermineCitusBackendType(void);
@ -515,12 +513,15 @@ UserHasPermissionToViewStatsOf(Oid currentUserId, Oid backendOwnedId)
void
InitializeBackendManagement(void)
{
/* on PG 15, we use shmem_request_hook_type */
#if PG_VERSION_NUM < PG_VERSION_15
/* allocate shared memory */
if (!IsUnderPostmaster)
{
RequestAddinShmemSpace(BackendManagementShmemSize());
}
#endif
prev_shmem_startup_hook = shmem_startup_hook;
shmem_startup_hook = BackendManagementShmemInit;
}
@ -531,7 +532,7 @@ InitializeBackendManagement(void)
* memory startup hook. The function sets up the necessary shared memory
* segment for the backend manager.
*/
static void
void
BackendManagementShmemInit(void)
{
bool alreadyInitialized = false;
@ -599,7 +600,7 @@ BackendManagementShmemInit(void)
* BackendManagementShmemSize returns the size that should be allocated
* on the shared memory for backend management.
*/
static size_t
size_t
BackendManagementShmemSize(void)
{
Size size = 0;

View File

@ -29,9 +29,7 @@
#include "distributed/metadata_cache.h"
#include "distributed/relation_access_tracking.h"
#include "utils/hsearch.h"
#if PG_VERSION_NUM >= PG_VERSION_13
#include "common/hashfn.h"
#endif
#include "utils/lsyscache.h"

View File

@ -323,9 +323,7 @@ OutMultiExtendedOp(OUTFUNC_ARGS)
WRITE_NODE_FIELD(sortClauseList);
WRITE_NODE_FIELD(limitCount);
WRITE_NODE_FIELD(limitOffset);
#if PG_VERSION_NUM >= PG_VERSION_13
WRITE_ENUM_FIELD(limitOption, LimitOption);
#endif
WRITE_NODE_FIELD(havingQual);
WRITE_BOOL_FIELD(hasDistinctOn);
WRITE_NODE_FIELD(distinctClause);

View File

@ -29,9 +29,7 @@
#include "storage/lockdefs.h"
#include "utils/fmgroids.h"
#include "utils/hsearch.h"
#if PG_VERSION_NUM >= PG_VERSION_13
#include "common/hashfn.h"
#endif
#include "utils/inval.h"
#include "utils/memutils.h"

View File

@ -53,9 +53,7 @@
#include "storage/lmgr.h"
#include "storage/lwlock.h"
#include "tcop/tcopprot.h"
#if PG_VERSION_NUM >= PG_VERSION_13
#include "common/hashfn.h"
#endif
#include "utils/memutils.h"
#include "utils/lsyscache.h"
@ -117,8 +115,6 @@ static bool IsMaintenanceDaemon = false;
static void MaintenanceDaemonSigTermHandler(SIGNAL_ARGS);
static void MaintenanceDaemonSigHupHandler(SIGNAL_ARGS);
static size_t MaintenanceDaemonShmemSize(void);
static void MaintenanceDaemonShmemInit(void);
static void MaintenanceDaemonShmemExit(int code, Datum arg);
static void MaintenanceDaemonErrorContext(void *arg);
static bool MetadataSyncTriggeredCheckAndReset(MaintenanceDaemonDBData *dbData);
@ -133,11 +129,6 @@ static void WarnMaintenanceDaemonNotStarted(void);
void
InitializeMaintenanceDaemon(void)
{
if (!IsUnderPostmaster)
{
RequestAddinShmemSpace(MaintenanceDaemonShmemSize());
}
prev_shmem_startup_hook = shmem_startup_hook;
shmem_startup_hook = MaintenanceDaemonShmemInit;
}
@ -743,7 +734,7 @@ CitusMaintenanceDaemonMain(Datum main_arg)
/*
* MaintenanceDaemonShmemSize computes how much shared memory is required.
*/
static size_t
size_t
MaintenanceDaemonShmemSize(void)
{
Size size = 0;
@ -767,7 +758,7 @@ MaintenanceDaemonShmemSize(void)
* MaintenanceDaemonShmemInit initializes the requested shared memory for the
* maintenance daemon.
*/
static void
void
MaintenanceDaemonShmemInit(void)
{
bool alreadyInitialized = false;

View File

@ -8,9 +8,7 @@
#include "distributed/pg_version_constants.h"
#if PG_VERSION_NUM >= PG_VERSION_13
#include "common/hashfn.h"
#endif
#include "commands/dbcommands.h"
#include "distributed/citus_custom_scan.h"

View File

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

View File

@ -18,9 +18,6 @@
#include "access/xact.h"
#include "catalog/dependency.h"
#include "catalog/pg_depend.h"
#if PG_VERSION_NUM < PG_VERSION_13
#include "catalog/pg_depend_d.h"
#endif
#include "catalog/pg_foreign_server.h"
#include "distributed/citus_ruleutils.h"
#include "distributed/distribution_column.h"
@ -43,10 +40,6 @@ PG_FUNCTION_INFO_V1(worker_drop_shell_table);
PG_FUNCTION_INFO_V1(worker_drop_sequence_dependency);
static void WorkerDropDistributedTable(Oid relationId);
#if PG_VERSION_NUM < PG_VERSION_13
static long deleteDependencyRecordsForSpecific(Oid classId, Oid objectId, char deptype,
Oid refclassId, Oid refobjectId);
#endif
/*
@ -127,14 +120,11 @@ WorkerDropDistributedTable(Oid relationId)
relation_close(distributedRelation, AccessShareLock);
/* prepare distributedTableObject for dropping the table */
ObjectAddress distributedTableObject = { RelationRelationId, relationId, 0 };
ObjectAddress *distributedTableObject = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*distributedTableObject, RelationRelationId, relationId);
/* Drop dependent sequences from pg_dist_object */
#if PG_VERSION_NUM >= PG_VERSION_13
List *ownedSequences = getOwnedSequences(relationId);
#else
List *ownedSequences = getOwnedSequences(relationId, InvalidAttrNumber);
#endif
Oid ownedSequenceOid = InvalidOid;
foreach_oid(ownedSequenceOid, ownedSequences)
@ -144,7 +134,7 @@ WorkerDropDistributedTable(Oid relationId)
UnmarkObjectDistributed(&ownedSequenceAddress);
}
UnmarkObjectDistributed(&distributedTableObject);
UnmarkObjectDistributed(distributedTableObject);
/*
* Remove metadata before object's itself to make functions no-op within
@ -177,7 +167,7 @@ WorkerDropDistributedTable(Oid relationId)
* until the user runs DROP EXTENSION. Therefore, we skip dropping the
* table.
*/
if (!IsObjectAddressOwnedByExtension(&distributedTableObject, NULL))
if (!IsAnyObjectAddressOwnedByExtension(list_make1(distributedTableObject), NULL))
{
char *relName = get_rel_name(relationId);
Oid schemaId = get_rel_namespace(relationId);
@ -238,22 +228,15 @@ worker_drop_shell_table(PG_FUNCTION_ARGS)
relation_close(distributedRelation, AccessShareLock);
/* prepare distributedTableObject for dropping the table */
ObjectAddress distributedTableObject = { InvalidOid, InvalidOid, 0 };
distributedTableObject.classId = RelationRelationId;
distributedTableObject.objectId = relationId;
distributedTableObject.objectSubId = 0;
if (IsObjectAddressOwnedByExtension(&distributedTableObject, NULL))
ObjectAddress *distributedTableObject = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*distributedTableObject, RelationRelationId, relationId);
if (IsAnyObjectAddressOwnedByExtension(list_make1(distributedTableObject), NULL))
{
PG_RETURN_VOID();
}
/* Drop dependent sequences from pg_dist_object */
#if PG_VERSION_NUM >= PG_VERSION_13
List *ownedSequences = getOwnedSequences(relationId);
#else
List *ownedSequences = getOwnedSequences(relationId, InvalidAttrNumber);
#endif
Oid ownedSequenceOid = InvalidOid;
foreach_oid(ownedSequenceOid, ownedSequences)
@ -270,7 +253,7 @@ worker_drop_shell_table(PG_FUNCTION_ARGS)
*
* We drop the table with cascade since other tables may be referring to it.
*/
performDeletion(&distributedTableObject, DROP_CASCADE,
performDeletion(distributedTableObject, DROP_CASCADE,
PERFORM_DELETION_INTERNAL);
PG_RETURN_VOID();
@ -301,11 +284,7 @@ worker_drop_sequence_dependency(PG_FUNCTION_ARGS)
EnsureTableOwner(relationId);
/* break the dependent sequences from the table */
#if PG_VERSION_NUM >= PG_VERSION_13
List *ownedSequences = getOwnedSequences(relationId);
#else
List *ownedSequences = getOwnedSequences(relationId, InvalidAttrNumber);
#endif
Oid ownedSequenceOid = InvalidOid;
foreach_oid(ownedSequenceOid, ownedSequences)
@ -324,59 +303,3 @@ worker_drop_sequence_dependency(PG_FUNCTION_ARGS)
PG_RETURN_VOID();
}
/* *INDENT-OFF* */
#if PG_VERSION_NUM < PG_VERSION_13
/*
* This function is already available on PG 13+.
* deleteDependencyRecordsForSpecific -- delete all records with given depender
* classId/objectId, dependee classId/objectId, of the given deptype.
* Returns the number of records deleted.
*/
static long
deleteDependencyRecordsForSpecific(Oid classId, Oid objectId, char deptype,
Oid refclassId, Oid refobjectId)
{
long count = 0;
Relation depRel;
ScanKeyData key[2];
HeapTuple tup;
depRel = table_open(DependRelationId, RowExclusiveLock);
ScanKeyInit(&key[0],
Anum_pg_depend_classid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(classId));
ScanKeyInit(&key[1],
Anum_pg_depend_objid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(objectId));
SysScanDesc scan =
systable_beginscan(depRel, DependDependerIndexId, true,
NULL, 2, key);
while (HeapTupleIsValid(tup = systable_getnext(scan)))
{
Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
if (depform->refclassid == refclassId &&
depform->refobjid == refobjectId &&
depform->deptype == deptype)
{
CatalogTupleDelete(depRel, &tup->t_self);
count++;
}
}
systable_endscan(scan);
table_close(depRel, RowExclusiveLock);
return count;
}
#endif
/* *INDENT-ON* */

View File

@ -1,4 +1,4 @@
/* src/include/citus_config.h.in. Generated from configure.in by autoheader. */
/* src/include/citus_config.h.in. Generated from configure.ac by autoheader. */
/*

View File

@ -50,8 +50,4 @@
#define ExplainPropertyLong(qlabel, value, es) \
ExplainPropertyInteger(qlabel, NULL, value, es)
#if PG_VERSION_NUM < 130000
#define detoast_attr(X) heap_tuple_untoast_attr(X)
#endif
#endif /* COLUMNAR_COMPAT_H */

View File

@ -45,6 +45,8 @@ typedef struct BackendData
} BackendData;
extern void BackendManagementShmemInit(void);
extern size_t BackendManagementShmemSize(void);
extern void InitializeBackendManagement(void);
extern int TotalProcCount(void);
extern void InitializeBackendData(void);

View File

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

View File

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

View File

@ -199,16 +199,10 @@ typedef struct CitusCustomScanPath
} CitusCustomScanPath;
#if PG_VERSION_NUM >= PG_VERSION_13
extern PlannedStmt * distributed_planner(Query *parse,
const char *query_string,
int cursorOptions,
ParamListInfo boundParams);
#else
extern PlannedStmt * distributed_planner(Query *parse,
int cursorOptions,
ParamListInfo boundParams);
#endif
/*

View File

@ -145,10 +145,7 @@ typedef struct ListCellAndListWrapper
*
* For more information, see postgres commit with sha
* 1cff1b95ab6ddae32faa3efe0d95a820dbfdc164
*/
#if PG_VERSION_NUM >= PG_VERSION_13
/*
*
* How it works:
* - An index is declared with the name {var}PositionDoNotUse and used
* throughout the for loop using ## to concat.
@ -162,9 +159,6 @@ typedef struct ListCellAndListWrapper
(var ## PositionDoNotUse) < list_length(l) && \
(((var) = list_nth(l, var ## PositionDoNotUse)) || true); \
var ## PositionDoNotUse ++)
#else
#define foreach_ptr_append(var, l) foreach_ptr(var, l)
#endif
/* utility functions declaration shared within this module */
extern List * SortList(List *pointerList,

View File

@ -24,6 +24,8 @@ extern double DistributedDeadlockDetectionTimeoutFactor;
extern void StopMaintenanceDaemon(Oid databaseId);
extern void TriggerNodeMetadataSync(Oid databaseId);
extern void InitializeMaintenanceDaemon(void);
extern size_t MaintenanceDaemonShmemSize(void);
extern void MaintenanceDaemonShmemInit(void);
extern void InitializeMaintenanceDaemonBackend(void);
extern bool LockCitusExtension(void);

View File

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

View File

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

View File

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

View File

@ -178,9 +178,7 @@ typedef struct MultiExtendedOp
List *sortClauseList;
Node *limitCount;
Node *limitOffset;
#if PG_VERSION_NUM >= PG_VERSION_13
LimitOption limitOption;
#endif
Node *havingQual;
List *distinctClause;
List *windowClause;

View File

@ -11,7 +11,6 @@
#ifndef PG_VERSION_CONSTANTS
#define PG_VERSION_CONSTANTS
#define PG_VERSION_12 120000
#define PG_VERSION_13 130000
#define PG_VERSION_14 140000
#define PG_VERSION_15 150000

View File

@ -12,6 +12,9 @@
#include "distributed/multi_server_executor.h"
#define STATS_SHARED_MEM_NAME "citus_query_stats"
extern Size CitusQueryStatsSharedMemSize(void);
extern void InitializeCitusQueryStats(void);
extern void CitusQueryStatsExecutorsEntry(uint64 queryId, MultiExecutorType executorType,
char *partitionKey);

View File

@ -47,8 +47,8 @@ typedef struct ShardSplitInfo
} ShardSplitInfo;
/*
* SplitShard API to split a given shard (or shard group) in blocking / non-blocking fashion
* based on specified split points to a set of destination nodes.
* SplitShard API to split a given shard (or shard group) using split mode and
* specified split points to a set of destination nodes.
*/
extern void SplitShard(SplitMode splitMode,
SplitOperation splitOperation,

View File

@ -25,6 +25,8 @@ extern int MaxClientConnections;
extern void InitializeSharedConnectionStats(void);
extern void WaitForSharedConnection(void);
extern void WakeupWaiterBackendsForSharedConnection(void);
extern size_t SharedConnectionStatsShmemSize(void);
extern void SharedConnectionStatsShmemInit(void);
extern int GetMaxClientConnections(void);
extern int GetMaxSharedPoolSize(void);
extern int GetLocalSharedPoolSize(void);

View File

@ -24,14 +24,10 @@
#include "parser/parse_func.h"
#include "optimizer/optimizer.h"
#if (PG_VERSION_NUM >= PG_VERSION_13)
#include "tcop/tcopprot.h"
#endif
#include "pg_version_compat.h"
#if PG_VERSION_NUM >= PG_VERSION_12
typedef struct
{
File fd;
@ -76,6 +72,4 @@ FileCompatFromFileStart(File fileDesc)
}
#endif /* PG12 */
#endif /* VERSION_COMPAT_H */

Some files were not shown because too many files have changed in this diff Show More