mirror of https://github.com/citusdata/citus.git
Merge remote-tracking branch 'origin' into users/saawasek/non_blocking_split_integrated
commit
9e88c14096
|
@ -128,7 +128,7 @@ jobs:
|
||||||
name: 'Configure'
|
name: 'Configure'
|
||||||
command: |
|
command: |
|
||||||
chown -R circleci .
|
chown -R circleci .
|
||||||
gosu circleci ./configure
|
gosu circleci ./configure --without-pg-version-check
|
||||||
- run:
|
- run:
|
||||||
name: 'Enable core dumps'
|
name: 'Enable core dumps'
|
||||||
command: |
|
command: |
|
||||||
|
@ -209,7 +209,7 @@ jobs:
|
||||||
name: 'Configure'
|
name: 'Configure'
|
||||||
command: |
|
command: |
|
||||||
chown -R circleci .
|
chown -R circleci .
|
||||||
gosu circleci ./configure
|
gosu circleci ./configure --without-pg-version-check
|
||||||
- run:
|
- run:
|
||||||
name: 'Enable core dumps'
|
name: 'Enable core dumps'
|
||||||
command: |
|
command: |
|
||||||
|
@ -283,7 +283,7 @@ jobs:
|
||||||
name: 'Configure'
|
name: 'Configure'
|
||||||
command: |
|
command: |
|
||||||
chown -R circleci .
|
chown -R circleci .
|
||||||
gosu circleci ./configure
|
gosu circleci ./configure --without-pg-version-check
|
||||||
- run:
|
- run:
|
||||||
name: 'Enable core dumps'
|
name: 'Enable core dumps'
|
||||||
command: |
|
command: |
|
||||||
|
@ -371,7 +371,7 @@ jobs:
|
||||||
name: 'Configure'
|
name: 'Configure'
|
||||||
command: |
|
command: |
|
||||||
chown -R circleci .
|
chown -R circleci .
|
||||||
gosu circleci ./configure
|
gosu circleci ./configure --without-pg-version-check
|
||||||
- run:
|
- run:
|
||||||
name: 'Enable core dumps'
|
name: 'Enable core dumps'
|
||||||
command: |
|
command: |
|
||||||
|
@ -448,7 +448,7 @@ jobs:
|
||||||
name: 'Configure'
|
name: 'Configure'
|
||||||
command: |
|
command: |
|
||||||
chown -R circleci .
|
chown -R circleci .
|
||||||
gosu circleci ./configure
|
gosu circleci ./configure --without-pg-version-check
|
||||||
- run:
|
- run:
|
||||||
name: 'Enable core dumps'
|
name: 'Enable core dumps'
|
||||||
command: |
|
command: |
|
||||||
|
|
|
@ -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
|
$(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
|
cd @abs_top_builddir@ && ./config.status --recheck && ./config.status
|
||||||
|
|
||||||
# Regenerate configure if configure.in changed
|
# Regenerate configure if configure.ac changed
|
||||||
$(citus_abs_top_srcdir)/configure: $(citus_abs_top_srcdir)/configure.in
|
$(citus_abs_top_srcdir)/configure: $(citus_abs_top_srcdir)/configure.ac
|
||||||
cd ${citus_abs_top_srcdir} && ./autogen.sh
|
cd ${citus_abs_top_srcdir} && ./autogen.sh
|
||||||
|
|
||||||
# If specified via configure, replace the default compiler. Normally
|
# If specified via configure, replace the default compiler. Normally
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/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
|
# citus_config.h.in. The resuting resulting files are checked into
|
||||||
# the SCM, to avoid everyone needing autoconf installed.
|
# the SCM, to avoid everyone needing autoconf installed.
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
# argument (other than "yes/no"), etc.
|
# argument (other than "yes/no"), etc.
|
||||||
#
|
#
|
||||||
# The point of this implementation is to reduce code size and
|
# 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.
|
# in the option evaluation code.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -644,6 +644,7 @@ LDFLAGS
|
||||||
CFLAGS
|
CFLAGS
|
||||||
CC
|
CC
|
||||||
vpath_build
|
vpath_build
|
||||||
|
with_pg_version_check
|
||||||
PATH
|
PATH
|
||||||
PG_CONFIG
|
PG_CONFIG
|
||||||
FLEX
|
FLEX
|
||||||
|
@ -692,6 +693,7 @@ ac_subst_files=''
|
||||||
ac_user_opts='
|
ac_user_opts='
|
||||||
enable_option_checking
|
enable_option_checking
|
||||||
with_extra_version
|
with_extra_version
|
||||||
|
with_pg_version_check
|
||||||
enable_coverage
|
enable_coverage
|
||||||
with_libcurl
|
with_libcurl
|
||||||
with_reports_hostname
|
with_reports_hostname
|
||||||
|
@ -1337,6 +1339,8 @@ Optional Packages:
|
||||||
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
|
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
|
||||||
--with-extra-version=STRING
|
--with-extra-version=STRING
|
||||||
append STRING to version
|
append STRING to version
|
||||||
|
--without-pg-version-check
|
||||||
|
do not check postgres version during configure
|
||||||
--without-libcurl do not use libcurl for anonymous statistics
|
--without-libcurl do not use libcurl for anonymous statistics
|
||||||
collection
|
collection
|
||||||
--with-reports-hostname=HOSTNAME
|
--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
|
as_fn_error $? "Could not detect PostgreSQL version from pg_config." "$LINENO" 5
|
||||||
fi
|
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
|
as_fn_error $? "Citus is not compatible with the detected PostgreSQL version ${version_num}." "$LINENO" 5
|
||||||
else
|
else
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: building against PostgreSQL $version_num" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: building against PostgreSQL $version_num" >&5
|
||||||
|
|
|
@ -74,7 +74,13 @@ if test -z "$version_num"; then
|
||||||
AC_MSG_ERROR([Could not detect PostgreSQL version from pg_config.])
|
AC_MSG_ERROR([Could not detect PostgreSQL version from pg_config.])
|
||||||
fi
|
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}.])
|
AC_MSG_ERROR([Citus is not compatible with the detected PostgreSQL version ${version_num}.])
|
||||||
else
|
else
|
||||||
AC_MSG_NOTICE([building against PostgreSQL $version_num])
|
AC_MSG_NOTICE([building against PostgreSQL $version_num])
|
|
@ -121,10 +121,8 @@ static void ColumnarScan_ExplainCustomScan(CustomScanState *node, List *ancestor
|
||||||
static const char * ColumnarPushdownClausesStr(List *context, List *clauses);
|
static const char * ColumnarPushdownClausesStr(List *context, List *clauses);
|
||||||
static const char * ColumnarProjectedColumnsStr(List *context,
|
static const char * ColumnarProjectedColumnsStr(List *context,
|
||||||
List *projectedColumns);
|
List *projectedColumns);
|
||||||
#if PG_VERSION_NUM >= 130000
|
|
||||||
static List * set_deparse_context_planstate(List *dpcontext, Node *node,
|
static List * set_deparse_context_planstate(List *dpcontext, Node *node,
|
||||||
List *ancestors);
|
List *ancestors);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* other helpers */
|
/* other helpers */
|
||||||
static List * ColumnarVarNeeded(ColumnarScanState *columnarScanState);
|
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+.
|
* 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;
|
PlanState *ps = (PlanState *) node;
|
||||||
return set_deparse_context_plan(dpcontext, ps->plan, ancestors);
|
return set_deparse_context_plan(dpcontext, ps->plan, ancestors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -12,11 +12,7 @@
|
||||||
#include "access/rewriteheap.h"
|
#include "access/rewriteheap.h"
|
||||||
#include "access/tableam.h"
|
#include "access/tableam.h"
|
||||||
#include "access/tsmapi.h"
|
#include "access/tsmapi.h"
|
||||||
#if PG_VERSION_NUM >= 130000
|
|
||||||
#include "access/detoast.h"
|
#include "access/detoast.h"
|
||||||
#else
|
|
||||||
#include "access/tuptoaster.h"
|
|
||||||
#endif
|
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
|
@ -1676,15 +1672,8 @@ ColumnarReadRowsIntoIndex(TableScanDesc scan, Relation indexRelation,
|
||||||
|
|
||||||
/* currently, columnar tables can't have dead tuples */
|
/* currently, columnar tables can't have dead tuples */
|
||||||
bool tupleIsAlive = true;
|
bool tupleIsAlive = true;
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
indexCallback(indexRelation, &itemPointerData, indexValues, indexNulls,
|
indexCallback(indexRelation, &itemPointerData, indexValues, indexNulls,
|
||||||
tupleIsAlive, indexCallbackState);
|
tupleIsAlive, indexCallbackState);
|
||||||
#else
|
|
||||||
HeapTuple scanTuple = ExecCopySlotHeapTuple(slot);
|
|
||||||
scanTuple->t_self = itemPointerData;
|
|
||||||
indexCallback(indexRelation, scanTuple, indexValues, indexNulls,
|
|
||||||
tupleIsAlive, indexCallbackState);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
reltuples++;
|
reltuples++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,12 +14,8 @@
|
||||||
#include "access/multixact.h"
|
#include "access/multixact.h"
|
||||||
#include "access/rewriteheap.h"
|
#include "access/rewriteheap.h"
|
||||||
#include "access/tsmapi.h"
|
#include "access/tsmapi.h"
|
||||||
#if PG_VERSION_NUM >= 130000
|
|
||||||
#include "access/heaptoast.h"
|
#include "access/heaptoast.h"
|
||||||
#include "common/hashfn.h"
|
#include "common/hashfn.h"
|
||||||
#else
|
|
||||||
#include "access/tuptoaster.h"
|
|
||||||
#endif
|
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
|
|
|
@ -1302,7 +1302,7 @@ ErrorIfUnsupportedCascadeObjects(Oid relationId)
|
||||||
*
|
*
|
||||||
* Extension dependency is different than the rest. If an object depends on an extension
|
* Extension dependency is different than the rest. If an object depends on an extension
|
||||||
* dropping the object would drop the extension too.
|
* dropping the object would drop the extension too.
|
||||||
* So we check with IsObjectAddressOwnedByExtension function.
|
* So we check with IsAnyObjectAddressOwnedByExtension function.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
DoesCascadeDropUnsupportedObject(Oid classId, Oid objectId, HTAB *nodeMap)
|
DoesCascadeDropUnsupportedObject(Oid classId, Oid objectId, HTAB *nodeMap)
|
||||||
|
@ -1315,10 +1315,9 @@ DoesCascadeDropUnsupportedObject(Oid classId, Oid objectId, HTAB *nodeMap)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress objectAddress = { 0 };
|
ObjectAddress *objectAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(objectAddress, classId, objectId);
|
ObjectAddressSet(*objectAddress, classId, objectId);
|
||||||
|
if (IsAnyObjectAddressOwnedByExtension(list_make1(objectAddress), NULL))
|
||||||
if (IsObjectAddressOwnedByExtension(&objectAddress, NULL))
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1568,11 +1567,7 @@ ReplaceTable(Oid sourceId, Oid targetId, List *justBeforeDropCommands,
|
||||||
ExecuteQueryViaSPI(query->data, SPI_OK_INSERT);
|
ExecuteQueryViaSPI(query->data, SPI_OK_INSERT);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
List *ownedSequences = getOwnedSequences(sourceId);
|
List *ownedSequences = getOwnedSequences(sourceId);
|
||||||
#else
|
|
||||||
List *ownedSequences = getOwnedSequences(sourceId, InvalidAttrNumber);
|
|
||||||
#endif
|
|
||||||
Oid sequenceOid = InvalidOid;
|
Oid sequenceOid = InvalidOid;
|
||||||
foreach_oid(sequenceOid, ownedSequences)
|
foreach_oid(sequenceOid, ownedSequences)
|
||||||
{
|
{
|
||||||
|
|
|
@ -307,8 +307,8 @@ CreateCitusLocalTable(Oid relationId, bool cascadeViaForeignKeys, bool autoConve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress tableAddress = { 0 };
|
ObjectAddress *tableAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
|
ObjectAddressSet(*tableAddress, RelationRelationId, relationId);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ensure that the sequences used in column defaults of the table
|
* 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
|
* Ensure dependencies exist as we will create shell table on the other nodes
|
||||||
* in the MX case.
|
* in the MX case.
|
||||||
*/
|
*/
|
||||||
EnsureDependenciesExistOnAllNodes(&tableAddress);
|
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(tableAddress));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure that existing reference tables have been replicated to all
|
* Make sure that existing reference tables have been replicated to all
|
||||||
|
|
|
@ -36,7 +36,6 @@ PreprocessClusterStmt(Node *node, const char *clusterCommand,
|
||||||
{
|
{
|
||||||
ClusterStmt *clusterStmt = castNode(ClusterStmt, node);
|
ClusterStmt *clusterStmt = castNode(ClusterStmt, node);
|
||||||
bool missingOK = false;
|
bool missingOK = false;
|
||||||
DDLJob *ddlJob = NULL;
|
|
||||||
|
|
||||||
if (clusterStmt->relation == NULL)
|
if (clusterStmt->relation == NULL)
|
||||||
{
|
{
|
||||||
|
@ -67,18 +66,14 @@ PreprocessClusterStmt(Node *node, const char *clusterCommand,
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= 120000
|
|
||||||
if (IsClusterStmtVerbose_compat(clusterStmt))
|
if (IsClusterStmtVerbose_compat(clusterStmt))
|
||||||
#else
|
|
||||||
if (clusterStmt->verbose)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
ereport(ERROR, (errmsg("cannot run CLUSTER command"),
|
ereport(ERROR, (errmsg("cannot run CLUSTER command"),
|
||||||
errdetail("VERBOSE option is currently unsupported "
|
errdetail("VERBOSE option is currently unsupported "
|
||||||
"for distributed tables.")));
|
"for distributed tables.")));
|
||||||
}
|
}
|
||||||
|
|
||||||
ddlJob = palloc0(sizeof(DDLJob));
|
DDLJob *ddlJob = palloc0(sizeof(DDLJob));
|
||||||
ObjectAddressSet(ddlJob->targetObjectAddress, RelationRelationId, relationId);
|
ObjectAddressSet(ddlJob->targetObjectAddress, RelationRelationId, relationId);
|
||||||
ddlJob->metadataSyncCommand = clusterCommand;
|
ddlJob->metadataSyncCommand = clusterCommand;
|
||||||
ddlJob->taskList = DDLTaskList(relationId, clusterCommand);
|
ddlJob->taskList = DDLTaskList(relationId, clusterCommand);
|
||||||
|
|
|
@ -169,7 +169,7 @@ CreateCollationDDLsIdempotent(Oid collationId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ObjectAddress
|
List *
|
||||||
AlterCollationOwnerObjectAddress(Node *node, bool missing_ok)
|
AlterCollationOwnerObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
|
@ -177,8 +177,13 @@ AlterCollationOwnerObjectAddress(Node *node, bool missing_ok)
|
||||||
|
|
||||||
Assert(stmt->objectType == OBJECT_COLLATION);
|
Assert(stmt->objectType == OBJECT_COLLATION);
|
||||||
|
|
||||||
return get_object_address(stmt->objectType, stmt->object, &relation,
|
ObjectAddress objectAddress = get_object_address(stmt->objectType, stmt->object,
|
||||||
AccessExclusiveLock, missing_ok);
|
&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
|
* RenameCollationStmtObjectAddress returns the ObjectAddress of the type that is the object
|
||||||
* of the RenameStmt. Errors if missing_ok is false.
|
* of the RenameStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
RenameCollationStmtObjectAddress(Node *node, bool missing_ok)
|
RenameCollationStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
RenameStmt *stmt = castNode(RenameStmt, node);
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
Assert(stmt->renameType == OBJECT_COLLATION);
|
Assert(stmt->renameType == OBJECT_COLLATION);
|
||||||
|
|
||||||
Oid collationOid = get_collation_oid((List *) stmt->object, missing_ok);
|
Oid collationOid = get_collation_oid((List *) stmt->object, missing_ok);
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, CollationRelationId, collationOid);
|
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
|
* new schema. Errors if missing_ok is false and the type cannot be found in either of the
|
||||||
* schemas.
|
* schemas.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterCollationSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
AlterCollationSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
|
@ -232,9 +237,9 @@ AlterCollationSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, CollationRelationId, collationOid);
|
ObjectAddressSet(*address, CollationRelationId, collationOid);
|
||||||
return address;
|
return list_make1(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -291,15 +296,15 @@ GenerateBackupNameForCollationCollision(const ObjectAddress *address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ObjectAddress
|
List *
|
||||||
DefineCollationStmtObjectAddress(Node *node, bool missing_ok)
|
DefineCollationStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
DefineStmt *stmt = castNode(DefineStmt, node);
|
DefineStmt *stmt = castNode(DefineStmt, node);
|
||||||
Assert(stmt->kind == OBJECT_COLLATION);
|
Assert(stmt->kind == OBJECT_COLLATION);
|
||||||
|
|
||||||
Oid collOid = get_collation_oid(stmt->defnames, missing_ok);
|
Oid collOid = get_collation_oid(stmt->defnames, missing_ok);
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, CollationRelationId, collOid);
|
ObjectAddressSet(*address, CollationRelationId, collOid);
|
||||||
|
|
||||||
return address;
|
return list_make1(address);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,22 +61,26 @@ PostprocessCreateDistributedObjectFromCatalogStmt(Node *stmt, const char *queryS
|
||||||
return NIL;
|
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();
|
EnsureCoordinator();
|
||||||
EnsureSequentialMode(ops->objectType);
|
EnsureSequentialMode(ops->objectType);
|
||||||
|
|
||||||
/* If the object has any unsupported dependency warn, and only create locally */
|
/* If the object has any unsupported dependency warn, and only create locally */
|
||||||
DeferredErrorMessage *depError = DeferErrorIfHasUnsupportedDependency(&address);
|
DeferredErrorMessage *depError = DeferErrorIfAnyObjectHasUnsupportedDependency(
|
||||||
|
addresses);
|
||||||
if (depError != NULL)
|
if (depError != NULL)
|
||||||
{
|
{
|
||||||
RaiseDeferredError(depError, WARNING);
|
RaiseDeferredError(depError, WARNING);
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnsureDependenciesExistOnAllNodes(&address);
|
EnsureAllObjectDependenciesExistOnAllNodes(addresses);
|
||||||
|
|
||||||
List *commands = GetDependencyCreateDDLCommands(&address);
|
List *commands = GetAllDependencyCreateDDLCommands(addresses);
|
||||||
|
|
||||||
commands = lcons(DISABLE_DDL_PROPAGATION, commands);
|
commands = lcons(DISABLE_DDL_PROPAGATION, commands);
|
||||||
commands = lappend(commands, ENABLE_DDL_PROPAGATION);
|
commands = lappend(commands, ENABLE_DDL_PROPAGATION);
|
||||||
|
@ -111,8 +115,12 @@ PreprocessAlterDistributedObjectStmt(Node *stmt, const char *queryString,
|
||||||
const DistributeObjectOps *ops = GetDistributeObjectOps(stmt);
|
const DistributeObjectOps *ops = GetDistributeObjectOps(stmt);
|
||||||
Assert(ops != NULL);
|
Assert(ops != NULL);
|
||||||
|
|
||||||
ObjectAddress address = GetObjectAddressFromParseTree(stmt, false);
|
List *addresses = GetObjectAddressListFromParseTree(stmt, false);
|
||||||
if (!ShouldPropagateObject(&address))
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(addresses) == 1);
|
||||||
|
|
||||||
|
if (!ShouldPropagateAnyObject(addresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -156,8 +164,12 @@ PostprocessAlterDistributedObjectStmt(Node *stmt, const char *queryString)
|
||||||
const DistributeObjectOps *ops = GetDistributeObjectOps(stmt);
|
const DistributeObjectOps *ops = GetDistributeObjectOps(stmt);
|
||||||
Assert(ops != NULL);
|
Assert(ops != NULL);
|
||||||
|
|
||||||
ObjectAddress address = GetObjectAddressFromParseTree(stmt, false);
|
List *addresses = GetObjectAddressListFromParseTree(stmt, false);
|
||||||
if (!ShouldPropagateObject(&address))
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(addresses) == 1);
|
||||||
|
|
||||||
|
if (!ShouldPropagateAnyObject(addresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -168,7 +180,7 @@ PostprocessAlterDistributedObjectStmt(Node *stmt, const char *queryString)
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnsureDependenciesExistOnAllNodes(&address);
|
EnsureAllObjectDependenciesExistOnAllNodes(addresses);
|
||||||
|
|
||||||
return NIL;
|
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 */
|
Relation rel = NULL; /* not used, but required to pass to get_object_address */
|
||||||
ObjectAddress address = get_object_address(stmt->removeType, object, &rel,
|
ObjectAddress address = get_object_address(stmt->removeType, object, &rel,
|
||||||
AccessShareLock, stmt->missing_ok);
|
AccessShareLock, stmt->missing_ok);
|
||||||
if (IsObjectDistributed(&address))
|
|
||||||
{
|
|
||||||
ObjectAddress *addressPtr = palloc0(sizeof(ObjectAddress));
|
ObjectAddress *addressPtr = palloc0(sizeof(ObjectAddress));
|
||||||
*addressPtr = address;
|
*addressPtr = address;
|
||||||
|
if (IsAnyObjectDistributed(list_make1(addressPtr)))
|
||||||
|
{
|
||||||
distributedObjects = lappend(distributedObjects, object);
|
distributedObjects = lappend(distributedObjects, object);
|
||||||
distributedObjectAddresses = lappend(distributedObjectAddresses, addressPtr);
|
distributedObjectAddresses = lappend(distributedObjectAddresses, addressPtr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -442,10 +442,9 @@ CreateDistributedTable(Oid relationId, char *distributionColumnName,
|
||||||
* via their own connection and committed immediately so they become visible to all
|
* via their own connection and committed immediately so they become visible to all
|
||||||
* sessions creating shards.
|
* sessions creating shards.
|
||||||
*/
|
*/
|
||||||
ObjectAddress tableAddress = { 0 };
|
ObjectAddress *tableAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
|
ObjectAddressSet(*tableAddress, RelationRelationId, relationId);
|
||||||
|
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(tableAddress));
|
||||||
EnsureDependenciesExistOnAllNodes(&tableAddress);
|
|
||||||
|
|
||||||
char replicationModel = DecideReplicationModel(distributionMethod,
|
char replicationModel = DecideReplicationModel(distributionMethod,
|
||||||
colocateWithTableName,
|
colocateWithTableName,
|
||||||
|
|
|
@ -40,17 +40,17 @@ bool EnableAlterDatabaseOwner = true;
|
||||||
* AlterDatabaseOwnerObjectAddress returns the ObjectAddress of the database that is the
|
* AlterDatabaseOwnerObjectAddress returns the ObjectAddress of the database that is the
|
||||||
* object of the AlterOwnerStmt. Errors if missing_ok is false.
|
* object of the AlterOwnerStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterDatabaseOwnerObjectAddress(Node *node, bool missing_ok)
|
AlterDatabaseOwnerObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
Assert(stmt->objectType == OBJECT_DATABASE);
|
Assert(stmt->objectType == OBJECT_DATABASE);
|
||||||
|
|
||||||
Oid databaseOid = get_database_oid(strVal((String *) stmt->object), missing_ok);
|
Oid databaseOid = get_database_oid(strVal((String *) stmt->object), missing_ok);
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, DatabaseRelationId, databaseOid);
|
ObjectAddressSet(*address, DatabaseRelationId, databaseOid);
|
||||||
|
|
||||||
return address;
|
return list_make1(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,9 @@ static void ErrorIfCircularDependencyExists(const ObjectAddress *objectAddress);
|
||||||
static int ObjectAddressComparator(const void *a, const void *b);
|
static int ObjectAddressComparator(const void *a, const void *b);
|
||||||
static List * FilterObjectAddressListByPredicate(List *objectAddressList,
|
static List * FilterObjectAddressListByPredicate(List *objectAddressList,
|
||||||
AddressPredicate predicate);
|
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
|
* 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
|
* This is solved by creating the dependencies in an idempotent manner, either via
|
||||||
* postgres native CREATE IF NOT EXISTS, or citus helper functions.
|
* postgres native CREATE IF NOT EXISTS, or citus helper functions.
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
EnsureDependenciesExistOnAllNodes(const ObjectAddress *target)
|
EnsureDependenciesExistOnAllNodes(const ObjectAddress *target)
|
||||||
{
|
{
|
||||||
List *dependenciesWithCommands = NIL;
|
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
|
* EnsureDependenciesCanBeDistributed ensures all dependencies of the given object
|
||||||
* can be distributed.
|
* can be distributed.
|
||||||
|
@ -153,7 +171,8 @@ EnsureDependenciesCanBeDistributed(const ObjectAddress *objectAddress)
|
||||||
ErrorIfCircularDependencyExists(objectAddress);
|
ErrorIfCircularDependencyExists(objectAddress);
|
||||||
|
|
||||||
/* If the object has any unsupported dependency, error out */
|
/* If the object has any unsupported dependency, error out */
|
||||||
DeferredErrorMessage *depError = DeferErrorIfHasUnsupportedDependency(objectAddress);
|
DeferredErrorMessage *depError = DeferErrorIfAnyObjectHasUnsupportedDependency(
|
||||||
|
list_make1((ObjectAddress *) objectAddress));
|
||||||
|
|
||||||
if (depError != NULL)
|
if (depError != NULL)
|
||||||
{
|
{
|
||||||
|
@ -310,7 +329,7 @@ GetDistributableDependenciesForObject(const ObjectAddress *target)
|
||||||
* GetDependencyCreateDDLCommands returns a list (potentially empty or NIL) of ddl
|
* GetDependencyCreateDDLCommands returns a list (potentially empty or NIL) of ddl
|
||||||
* commands to execute on a worker to create the object.
|
* commands to execute on a worker to create the object.
|
||||||
*/
|
*/
|
||||||
List *
|
static List *
|
||||||
GetDependencyCreateDDLCommands(const ObjectAddress *dependency)
|
GetDependencyCreateDDLCommands(const ObjectAddress *dependency)
|
||||||
{
|
{
|
||||||
switch (getObjectClass(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
|
* ReplicateAllObjectsToNodeCommandList returns commands to replicate all
|
||||||
* previously marked objects to a worker node. The function also sets
|
* previously marked objects to a worker node. The function also sets
|
||||||
|
@ -531,7 +569,7 @@ ReplicateAllObjectsToNodeCommandList(const char *nodeName, int nodePort)
|
||||||
ObjectAddress *dependency = NULL;
|
ObjectAddress *dependency = NULL;
|
||||||
foreach_ptr(dependency, dependencies)
|
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
|
* 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
|
* ShouldPropagateObject determines if we should be propagating DDLs based
|
||||||
* on their object address.
|
* on their object address.
|
||||||
*/
|
*/
|
||||||
bool
|
static bool
|
||||||
ShouldPropagateObject(const ObjectAddress *address)
|
ShouldPropagateObject(const ObjectAddress *address)
|
||||||
{
|
{
|
||||||
if (!ShouldPropagate())
|
if (!ShouldPropagate())
|
||||||
|
@ -671,7 +709,7 @@ ShouldPropagateObject(const ObjectAddress *address)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsObjectDistributed(address))
|
if (!IsAnyObjectDistributed(list_make1((ObjectAddress *) address)))
|
||||||
{
|
{
|
||||||
/* do not propagate for non-distributed types */
|
/* do not propagate for non-distributed types */
|
||||||
return false;
|
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
|
* FilterObjectAddressListByPredicate takes a list of ObjectAddress *'s and returns a list
|
||||||
* only containing the ObjectAddress *'s for which the predicate returned true.
|
* only containing the ObjectAddress *'s for which the predicate returned true.
|
||||||
|
|
|
@ -874,7 +874,6 @@ static DistributeObjectOps Schema_Rename = {
|
||||||
.address = AlterSchemaRenameStmtObjectAddress,
|
.address = AlterSchemaRenameStmtObjectAddress,
|
||||||
.markDistributed = false,
|
.markDistributed = false,
|
||||||
};
|
};
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
static DistributeObjectOps Statistics_Alter = {
|
static DistributeObjectOps Statistics_Alter = {
|
||||||
.deparse = DeparseAlterStatisticsStmt,
|
.deparse = DeparseAlterStatisticsStmt,
|
||||||
.qualify = QualifyAlterStatisticsStmt,
|
.qualify = QualifyAlterStatisticsStmt,
|
||||||
|
@ -883,7 +882,6 @@ static DistributeObjectOps Statistics_Alter = {
|
||||||
.address = NULL,
|
.address = NULL,
|
||||||
.markDistributed = false,
|
.markDistributed = false,
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
static DistributeObjectOps Statistics_AlterObjectSchema = {
|
static DistributeObjectOps Statistics_AlterObjectSchema = {
|
||||||
.deparse = DeparseAlterStatisticsSchemaStmt,
|
.deparse = DeparseAlterStatisticsSchemaStmt,
|
||||||
.qualify = QualifyAlterStatisticsSchemaStmt,
|
.qualify = QualifyAlterStatisticsSchemaStmt,
|
||||||
|
@ -1304,13 +1302,11 @@ GetDistributeObjectOps(Node *node)
|
||||||
return &Sequence_Alter;
|
return &Sequence_Alter;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
case T_AlterStatsStmt:
|
case T_AlterStatsStmt:
|
||||||
{
|
{
|
||||||
return &Statistics_Alter;
|
return &Statistics_Alter;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
case T_AlterTableStmt:
|
case T_AlterTableStmt:
|
||||||
{
|
{
|
||||||
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
|
|
||||||
static CollateClause * MakeCollateClauseFromOid(Oid collationOid);
|
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
|
* 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
|
* InvalidOid. When missing_ok is false this function will raise an error instead when the
|
||||||
* domain can't be found.
|
* domain can't be found.
|
||||||
*/
|
*/
|
||||||
static ObjectAddress
|
static List *
|
||||||
GetDomainAddressByName(TypeName *domainName, bool missing_ok)
|
GetDomainAddressByName(TypeName *domainName, bool missing_ok)
|
||||||
{
|
{
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
Oid domainOid = LookupTypeNameOid(NULL, domainName, missing_ok);
|
Oid domainOid = LookupTypeNameOid(NULL, domainName, missing_ok);
|
||||||
ObjectAddressSet(address, TypeRelationId, domainOid);
|
ObjectAddressSet(*address, TypeRelationId, domainOid);
|
||||||
return address;
|
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
|
* 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.
|
* the domain cannot be found in the local catalog.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
CreateDomainStmtObjectAddress(Node *node, bool missing_ok)
|
CreateDomainStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
CreateDomainStmt *stmt = castNode(CreateDomainStmt, node);
|
CreateDomainStmt *stmt = castNode(CreateDomainStmt, node);
|
||||||
|
|
||||||
TypeName *typeName = makeTypeNameFromNameList(stmt->domainname);
|
TypeName *typeName = makeTypeNameFromNameList(stmt->domainname);
|
||||||
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TypeRelationId, typeOid);
|
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
|
* When missing_ok is false this function will raise an error when the domain is not
|
||||||
* found.
|
* found.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterDomainStmtObjectAddress(Node *node, bool missing_ok)
|
AlterDomainStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterDomainStmt *stmt = castNode(AlterDomainStmt, node);
|
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
|
* which the constraint is being renamed. When missing_ok this function will raise an
|
||||||
* error if the domain cannot be found.
|
* error if the domain cannot be found.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
DomainRenameConstraintStmtObjectAddress(Node *node, bool missing_ok)
|
DomainRenameConstraintStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
RenameStmt *stmt = castNode(RenameStmt, node);
|
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
|
* being changed. When missing_ok is false this function will raise an error if the domain
|
||||||
* cannot be found.
|
* cannot be found.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterDomainOwnerStmtObjectAddress(Node *node, bool missing_ok)
|
AlterDomainOwnerStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
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
|
* When missing_ok is false this function will raise an error when the domain cannot be
|
||||||
* found.
|
* found.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
RenameDomainStmtObjectAddress(Node *node, bool missing_ok)
|
RenameDomainStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
RenameStmt *stmt = castNode(RenameStmt, node);
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
|
|
|
@ -181,9 +181,12 @@ PostprocessCreateExtensionStmt(Node *node, const char *queryString)
|
||||||
(void *) createExtensionStmtSql,
|
(void *) createExtensionStmtSql,
|
||||||
ENABLE_DDL_PROPAGATION);
|
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);
|
return NodeDDLTaskList(NON_COORDINATOR_NODES, commands);
|
||||||
}
|
}
|
||||||
|
@ -319,10 +322,9 @@ FilterDistributedExtensions(List *extensionObjectList)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, ExtensionRelationId, extensionOid);
|
ObjectAddressSet(*address, ExtensionRelationId, extensionOid);
|
||||||
|
if (!IsAnyObjectDistributed(list_make1(address)))
|
||||||
if (!IsObjectDistributed(&address))
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -411,7 +413,10 @@ PreprocessAlterExtensionSchemaStmt(Node *node, const char *queryString,
|
||||||
List *
|
List *
|
||||||
PostprocessAlterExtensionSchemaStmt(Node *node, const char *queryString)
|
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))
|
if (!ShouldPropagateExtensionCommand(node))
|
||||||
{
|
{
|
||||||
|
@ -419,7 +424,7 @@ PostprocessAlterExtensionSchemaStmt(Node *node, const char *queryString)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dependencies (schema) have changed let's ensure they exist */
|
/* dependencies (schema) have changed let's ensure they exist */
|
||||||
EnsureDependenciesExistOnAllNodes(&extensionAddress);
|
EnsureAllObjectDependenciesExistOnAllNodes(extensionAddresses);
|
||||||
|
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -504,7 +509,7 @@ PostprocessAlterExtensionCitusUpdateStmt(Node *node)
|
||||||
*
|
*
|
||||||
* Note that this function is not responsible for ensuring if dependencies exist on
|
* 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
|
* 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.
|
* 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
|
* 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.
|
* 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
|
* AlterExtensionSchemaStmtObjectAddress returns the ObjectAddress of the extension that is
|
||||||
* the subject of the AlterObjectSchemaStmt. Errors if missing_ok is false.
|
* the subject of the AlterObjectSchemaStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterExtensionSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
AlterExtensionSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
|
@ -1145,10 +1150,10 @@ AlterExtensionSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
extensionName)));
|
extensionName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, ExtensionRelationId, extensionOid);
|
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
|
* AlterExtensionUpdateStmtObjectAddress returns the ObjectAddress of the extension that is
|
||||||
* the subject of the AlterExtensionStmt. Errors if missing_ok is false.
|
* the subject of the AlterExtensionStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterExtensionUpdateStmtObjectAddress(Node *node, bool missing_ok)
|
AlterExtensionUpdateStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterExtensionStmt *stmt = castNode(AlterExtensionStmt, node);
|
AlterExtensionStmt *stmt = castNode(AlterExtensionStmt, node);
|
||||||
|
@ -1171,10 +1176,10 @@ AlterExtensionUpdateStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
extensionName)));
|
extensionName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, ExtensionRelationId, extensionOid);
|
ObjectAddressSet(*address, ExtensionRelationId, extensionOid);
|
||||||
|
|
||||||
return address;
|
return list_make1(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ PreprocessGrantOnFDWStmt(Node *node, const char *queryString,
|
||||||
|
|
||||||
EnsureCoordinator();
|
EnsureCoordinator();
|
||||||
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
Assert(list_length(stmt->objects) == 1);
|
Assert(list_length(stmt->objects) == 1);
|
||||||
|
|
||||||
char *sql = DeparseTreeNode((Node *) stmt);
|
char *sql = DeparseTreeNode((Node *) stmt);
|
||||||
|
@ -83,16 +84,19 @@ PreprocessGrantOnFDWStmt(Node *node, const char *queryString,
|
||||||
static bool
|
static bool
|
||||||
NameListHasFDWOwnedByDistributedExtension(List *FDWNames)
|
NameListHasFDWOwnedByDistributedExtension(List *FDWNames)
|
||||||
{
|
{
|
||||||
Value *FDWValue = NULL;
|
String *FDWValue = NULL;
|
||||||
foreach_ptr(FDWValue, FDWNames)
|
foreach_ptr(FDWValue, FDWNames)
|
||||||
{
|
{
|
||||||
/* captures the extension address during lookup */
|
/* captures the extension address during lookup */
|
||||||
ObjectAddress extensionAddress = { 0 };
|
ObjectAddress *extensionAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddress FDWAddress = GetObjectAddressByFDWName(strVal(FDWValue), false);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/deparser.h"
|
#include "distributed/deparser.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/log_utils.h"
|
||||||
#include "distributed/metadata/distobject.h"
|
#include "distributed/metadata/distobject.h"
|
||||||
#include "distributed/metadata_sync.h"
|
#include "distributed/metadata_sync.h"
|
||||||
#include "distributed/multi_executor.h"
|
#include "distributed/multi_executor.h"
|
||||||
|
@ -29,7 +30,7 @@
|
||||||
static char * GetForeignServerAlterOwnerCommand(Oid serverId);
|
static char * GetForeignServerAlterOwnerCommand(Oid serverId);
|
||||||
static Node * RecreateForeignServerStmt(Oid serverId);
|
static Node * RecreateForeignServerStmt(Oid serverId);
|
||||||
static bool NameListHasDistributedServer(List *serverNames);
|
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
|
* Never returns NULL, but the objid in the address can be invalid if missingOk
|
||||||
* was set to true.
|
* was set to true.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
CreateForeignServerStmtObjectAddress(Node *node, bool missing_ok)
|
CreateForeignServerStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
CreateForeignServerStmt *stmt = castNode(CreateForeignServerStmt, node);
|
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
|
* Never returns NULL, but the objid in the address can be invalid if missingOk
|
||||||
* was set to true.
|
* was set to true.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterForeignServerStmtObjectAddress(Node *node, bool missing_ok)
|
AlterForeignServerStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterForeignServerStmt *stmt = castNode(AlterForeignServerStmt, node);
|
AlterForeignServerStmt *stmt = castNode(AlterForeignServerStmt, node);
|
||||||
|
@ -101,6 +102,7 @@ PreprocessGrantOnForeignServerStmt(Node *node, const char *queryString,
|
||||||
|
|
||||||
EnsureCoordinator();
|
EnsureCoordinator();
|
||||||
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
Assert(list_length(stmt->objects) == 1);
|
Assert(list_length(stmt->objects) == 1);
|
||||||
|
|
||||||
char *sql = DeparseTreeNode((Node *) stmt);
|
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
|
* Never returns NULL, but the objid in the address can be invalid if missingOk
|
||||||
* was set to true.
|
* was set to true.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
RenameForeignServerStmtObjectAddress(Node *node, bool missing_ok)
|
RenameForeignServerStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
RenameStmt *stmt = castNode(RenameStmt, node);
|
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
|
* Never returns NULL, but the objid in the address can be invalid if missingOk
|
||||||
* was set to true.
|
* was set to true.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterForeignServerOwnerStmtObjectAddress(Node *node, bool missing_ok)
|
AlterForeignServerOwnerStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
|
@ -245,9 +247,15 @@ NameListHasDistributedServer(List *serverNames)
|
||||||
String *serverValue = NULL;
|
String *serverValue = NULL;
|
||||||
foreach_ptr(serverValue, serverNames)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -257,13 +265,13 @@ NameListHasDistributedServer(List *serverNames)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ObjectAddress
|
static List *
|
||||||
GetObjectAddressByServerName(char *serverName, bool missing_ok)
|
GetObjectAddressByServerName(char *serverName, bool missing_ok)
|
||||||
{
|
{
|
||||||
ForeignServer *server = GetForeignServerByName(serverName, missing_ok);
|
ForeignServer *server = GetForeignServerByName(serverName, missing_ok);
|
||||||
Oid serverOid = server->serverid;
|
Oid serverOid = server->serverid;
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, ForeignServerRelationId, serverOid);
|
ObjectAddressSet(*address, ForeignServerRelationId, serverOid);
|
||||||
|
|
||||||
return address;
|
return list_make1(address);
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ static void EnsureFunctionCanBeColocatedWithTable(Oid functionOid, Oid
|
||||||
static bool ShouldPropagateCreateFunction(CreateFunctionStmt *stmt);
|
static bool ShouldPropagateCreateFunction(CreateFunctionStmt *stmt);
|
||||||
static bool ShouldPropagateAlterFunction(const ObjectAddress *address);
|
static bool ShouldPropagateAlterFunction(const ObjectAddress *address);
|
||||||
static bool ShouldAddFunctionSignature(FunctionParameterMode mode);
|
static bool ShouldAddFunctionSignature(FunctionParameterMode mode);
|
||||||
static ObjectAddress FunctionToObjectAddress(ObjectType objectType,
|
static List * FunctionToObjectAddress(ObjectType objectType,
|
||||||
ObjectWithArgs *objectWithArgs,
|
ObjectWithArgs *objectWithArgs,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
static void ErrorIfUnsupportedAlterFunctionStmt(AlterFunctionStmt *stmt);
|
static void ErrorIfUnsupportedAlterFunctionStmt(AlterFunctionStmt *stmt);
|
||||||
|
@ -128,7 +128,7 @@ create_distributed_function(PG_FUNCTION_ARGS)
|
||||||
text *colocateWithText = NULL; /* optional */
|
text *colocateWithText = NULL; /* optional */
|
||||||
|
|
||||||
StringInfoData ddlCommand = { 0 };
|
StringInfoData ddlCommand = { 0 };
|
||||||
ObjectAddress functionAddress = { 0 };
|
ObjectAddress *functionAddress = palloc0(sizeof(ObjectAddress));
|
||||||
|
|
||||||
Oid distributionArgumentOid = InvalidOid;
|
Oid distributionArgumentOid = InvalidOid;
|
||||||
bool colocatedWithReferenceTable = false;
|
bool colocatedWithReferenceTable = false;
|
||||||
|
@ -203,9 +203,9 @@ create_distributed_function(PG_FUNCTION_ARGS)
|
||||||
EnsureCoordinator();
|
EnsureCoordinator();
|
||||||
EnsureFunctionOwner(funcOid);
|
EnsureFunctionOwner(funcOid);
|
||||||
|
|
||||||
ObjectAddressSet(functionAddress, ProcedureRelationId, funcOid);
|
ObjectAddressSet(*functionAddress, ProcedureRelationId, funcOid);
|
||||||
|
|
||||||
if (RecreateSameNonColocatedFunction(functionAddress,
|
if (RecreateSameNonColocatedFunction(*functionAddress,
|
||||||
distributionArgumentName,
|
distributionArgumentName,
|
||||||
colocateWithTableNameDefault,
|
colocateWithTableNameDefault,
|
||||||
forceDelegationAddress))
|
forceDelegationAddress))
|
||||||
|
@ -224,9 +224,10 @@ create_distributed_function(PG_FUNCTION_ARGS)
|
||||||
* pg_dist_object, and not propagate the CREATE FUNCTION. Function
|
* pg_dist_object, and not propagate the CREATE FUNCTION. Function
|
||||||
* will be created by the virtue of the extension creation.
|
* 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);
|
distributionArgumentName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -237,7 +238,7 @@ create_distributed_function(PG_FUNCTION_ARGS)
|
||||||
*/
|
*/
|
||||||
EnsureSequentialMode(OBJECT_FUNCTION);
|
EnsureSequentialMode(OBJECT_FUNCTION);
|
||||||
|
|
||||||
EnsureDependenciesExistOnAllNodes(&functionAddress);
|
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(functionAddress));
|
||||||
|
|
||||||
const char *createFunctionSQL = GetFunctionDDLCommand(funcOid, true);
|
const char *createFunctionSQL = GetFunctionDDLCommand(funcOid, true);
|
||||||
const char *alterFunctionOwnerSQL = GetFunctionAlterOwnerCommand(funcOid);
|
const char *alterFunctionOwnerSQL = GetFunctionAlterOwnerCommand(funcOid);
|
||||||
|
@ -257,7 +258,7 @@ create_distributed_function(PG_FUNCTION_ARGS)
|
||||||
ddlCommand.data);
|
ddlCommand.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
MarkObjectDistributed(&functionAddress);
|
MarkObjectDistributed(functionAddress);
|
||||||
|
|
||||||
if (distributionArgumentName != NULL)
|
if (distributionArgumentName != NULL)
|
||||||
{
|
{
|
||||||
|
@ -272,12 +273,12 @@ create_distributed_function(PG_FUNCTION_ARGS)
|
||||||
distributionArgumentOid,
|
distributionArgumentOid,
|
||||||
colocateWithTableName,
|
colocateWithTableName,
|
||||||
forceDelegationAddress,
|
forceDelegationAddress,
|
||||||
&functionAddress);
|
functionAddress);
|
||||||
}
|
}
|
||||||
else if (!colocatedWithReferenceTable)
|
else if (!colocatedWithReferenceTable)
|
||||||
{
|
{
|
||||||
DistributeFunctionColocatedWithDistributedTable(funcOid, colocateWithTableName,
|
DistributeFunctionColocatedWithDistributedTable(funcOid, colocateWithTableName,
|
||||||
&functionAddress);
|
functionAddress);
|
||||||
}
|
}
|
||||||
else if (colocatedWithReferenceTable)
|
else if (colocatedWithReferenceTable)
|
||||||
{
|
{
|
||||||
|
@ -288,7 +289,7 @@ create_distributed_function(PG_FUNCTION_ARGS)
|
||||||
*/
|
*/
|
||||||
ErrorIfAnyNodeDoesNotHaveMetadata();
|
ErrorIfAnyNodeDoesNotHaveMetadata();
|
||||||
|
|
||||||
DistributeFunctionColocatedWithReferenceTable(&functionAddress);
|
DistributeFunctionColocatedWithReferenceTable(functionAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
|
@ -919,11 +920,8 @@ GetFunctionAlterOwnerCommand(const RegProcedure funcOid)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GetAggregateDDLCommand returns a string for creating an aggregate.
|
* GetAggregateDDLCommand returns a string for creating an aggregate.
|
||||||
* CREATE OR REPLACE AGGREGATE was only introduced in pg12,
|
* A second parameter useCreateOrReplace signals whether to
|
||||||
* so a second parameter useCreateOrReplace signals whether to
|
* to create a plain CREATE AGGREGATE or not.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
static char *
|
static char *
|
||||||
GetAggregateDDLCommand(const RegProcedure funcOid, bool useCreateOrReplace)
|
GetAggregateDDLCommand(const RegProcedure funcOid, bool useCreateOrReplace)
|
||||||
|
@ -1308,7 +1306,7 @@ ShouldPropagateAlterFunction(const ObjectAddress *address)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsObjectDistributed(address))
|
if (!IsAnyObjectDistributed(list_make1((ObjectAddress *) address)))
|
||||||
{
|
{
|
||||||
/* do not propagate alter function for non-distributed functions */
|
/* do not propagate alter function for non-distributed functions */
|
||||||
return false;
|
return false;
|
||||||
|
@ -1373,15 +1371,19 @@ PostprocessCreateFunctionStmt(Node *node, const char *queryString)
|
||||||
return NIL;
|
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;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the function has any unsupported dependency, create it locally */
|
/* If the function has any unsupported dependency, create it locally */
|
||||||
DeferredErrorMessage *errMsg = DeferErrorIfHasUnsupportedDependency(&functionAddress);
|
DeferredErrorMessage *errMsg = DeferErrorIfAnyObjectHasUnsupportedDependency(
|
||||||
|
functionAddresses);
|
||||||
|
|
||||||
if (errMsg != NULL)
|
if (errMsg != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1389,11 +1391,14 @@ PostprocessCreateFunctionStmt(Node *node, const char *queryString)
|
||||||
return NIL;
|
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);
|
List *commands = list_make1(DISABLE_DDL_PROPAGATION);
|
||||||
commands = list_concat(commands, CreateFunctionDDLCommandsIdempotent(
|
commands = list_concat(commands, CreateFunctionDDLCommandsIdempotent(
|
||||||
&functionAddress));
|
functionAddress));
|
||||||
commands = list_concat(commands, list_make1(ENABLE_DDL_PROPAGATION));
|
commands = list_concat(commands, list_make1(ENABLE_DDL_PROPAGATION));
|
||||||
|
|
||||||
return NodeDDLTaskList(NON_COORDINATOR_NODES, commands);
|
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
|
* CREATE [OR REPLACE] FUNCTION statement. If missing_ok is false it will error with the
|
||||||
* normal postgres error for unfound functions.
|
* normal postgres error for unfound functions.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
CreateFunctionStmtObjectAddress(Node *node, bool missing_ok)
|
CreateFunctionStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
CreateFunctionStmt *stmt = castNode(CreateFunctionStmt, node);
|
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.
|
* objectId in the address can be invalid if missing_ok was set to true.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
DefineAggregateStmtObjectAddress(Node *node, bool missing_ok)
|
DefineAggregateStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
DefineStmt *stmt = castNode(DefineStmt, node);
|
DefineStmt *stmt = castNode(DefineStmt, node);
|
||||||
|
@ -1494,8 +1499,15 @@ PreprocessAlterFunctionStmt(Node *node, const char *queryString,
|
||||||
AlterFunctionStmt *stmt = castNode(AlterFunctionStmt, node);
|
AlterFunctionStmt *stmt = castNode(AlterFunctionStmt, node);
|
||||||
AssertObjectTypeIsFunctional(stmt->objtype);
|
AssertObjectTypeIsFunctional(stmt->objtype);
|
||||||
|
|
||||||
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, false);
|
List *addresses = GetObjectAddressListFromParseTree((Node *) stmt, false);
|
||||||
if (!ShouldPropagateAlterFunction(&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 (!ShouldPropagateAlterFunction(address))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -1549,20 +1561,26 @@ PreprocessAlterFunctionDependsStmt(Node *node, const char *queryString,
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt, true);
|
List *addresses = GetObjectAddressListFromParseTree((Node *) stmt, true);
|
||||||
if (!IsObjectDistributed(&address))
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(addresses) == 1);
|
||||||
|
|
||||||
|
if (!IsAnyObjectDistributed(addresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
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
|
* Distributed objects should not start depending on an extension, this will break
|
||||||
* the dependency resolving mechanism we use to replicate distributed objects to new
|
* the dependency resolving mechanism we use to replicate distributed objects to new
|
||||||
* workers
|
* workers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const char *functionName =
|
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 "
|
ereport(ERROR, (errmsg("distrtibuted functions are not allowed to depend on an "
|
||||||
"extension"),
|
"extension"),
|
||||||
errdetail("Function \"%s\" is already distributed. Functions from "
|
errdetail("Function \"%s\" is already distributed. Functions from "
|
||||||
|
@ -1576,7 +1594,7 @@ PreprocessAlterFunctionDependsStmt(Node *node, const char *queryString,
|
||||||
* is the subject of an ALTER FUNCTION ... DEPENS ON EXTENSION ... statement. If
|
* is the subject of an ALTER FUNCTION ... DEPENS ON EXTENSION ... statement. If
|
||||||
* missing_ok is set to false the lookup will raise an error.
|
* missing_ok is set to false the lookup will raise an error.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterFunctionDependsStmtObjectAddress(Node *node, bool missing_ok)
|
AlterFunctionDependsStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterObjectDependsStmt *stmt = castNode(AlterObjectDependsStmt, node);
|
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
|
* AlterFunctionStmt. If missing_ok is set to false an error will be raised if postgres
|
||||||
* was unable to find the function/procedure that was the target of the statement.
|
* was unable to find the function/procedure that was the target of the statement.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterFunctionStmtObjectAddress(Node *node, bool missing_ok)
|
AlterFunctionStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterFunctionStmt *stmt = castNode(AlterFunctionStmt, node);
|
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
|
* RenameFunctionStmtObjectAddress returns the ObjectAddress of the function that is the
|
||||||
* subject of the RenameStmt. Errors if missing_ok is false.
|
* subject of the RenameStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
RenameFunctionStmtObjectAddress(Node *node, bool missing_ok)
|
RenameFunctionStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
RenameStmt *stmt = castNode(RenameStmt, node);
|
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
|
* AlterFunctionOwnerObjectAddress returns the ObjectAddress of the function that is the
|
||||||
* subject of the AlterOwnerStmt. Errors if missing_ok is false.
|
* subject of the AlterOwnerStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterFunctionOwnerObjectAddress(Node *node, bool missing_ok)
|
AlterFunctionOwnerObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
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 new schema. Errors if missing_ok is false and the type cannot be found in either of
|
||||||
* the schemas.
|
* the schemas.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterFunctionSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
AlterFunctionSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
|
@ -1680,10 +1698,10 @@ AlterFunctionSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, ProcedureRelationId, funcOid);
|
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
|
* 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.
|
* raised by postgres explaining the Function/Procedure could not be found.
|
||||||
*/
|
*/
|
||||||
static ObjectAddress
|
static List *
|
||||||
FunctionToObjectAddress(ObjectType objectType, ObjectWithArgs *objectWithArgs,
|
FunctionToObjectAddress(ObjectType objectType, ObjectWithArgs *objectWithArgs,
|
||||||
bool missing_ok)
|
bool missing_ok)
|
||||||
{
|
{
|
||||||
AssertObjectTypeIsFunctional(objectType);
|
AssertObjectTypeIsFunctional(objectType);
|
||||||
|
|
||||||
Oid funcOid = LookupFuncWithArgs(objectType, objectWithArgs, missing_ok);
|
Oid funcOid = LookupFuncWithArgs(objectType, objectWithArgs, missing_ok);
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, ProcedureRelationId, funcOid);
|
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.
|
* Ensure corresponding extension is in pg_dist_object.
|
||||||
* Functions owned by an extension are depending internally on that extension,
|
* 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
|
* turn creates the function, and thus we don't have to create it ourself like
|
||||||
* we do for non-extension functions.
|
* we do for non-extension functions.
|
||||||
*/
|
*/
|
||||||
|
@ -1930,7 +1948,9 @@ EnsureExtensionFunctionCanBeDistributed(const ObjectAddress functionAddress,
|
||||||
get_extension_name(extensionAddress.objectId),
|
get_extension_name(extensionAddress.objectId),
|
||||||
get_func_name(functionAddress.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;
|
ObjectAddress *functionAddress = NULL;
|
||||||
foreach_ptr(functionAddress, distributedFunctions)
|
foreach_ptr(functionAddress, distributedFunctions)
|
||||||
{
|
{
|
||||||
EnsureDependenciesExistOnAllNodes(functionAddress);
|
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(functionAddress));
|
||||||
}
|
}
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -2038,7 +2058,7 @@ FilterDistributedFunctions(GrantStmt *grantStmt)
|
||||||
List *namespaceOidList = NIL;
|
List *namespaceOidList = NIL;
|
||||||
|
|
||||||
/* iterate over all namespace names provided to get their oid's */
|
/* iterate over all namespace names provided to get their oid's */
|
||||||
Value *namespaceValue = NULL;
|
String *namespaceValue = NULL;
|
||||||
foreach_ptr(namespaceValue, grantStmt->objects)
|
foreach_ptr(namespaceValue, grantStmt->objects)
|
||||||
{
|
{
|
||||||
char *nspname = strVal(namespaceValue);
|
char *nspname = strVal(namespaceValue);
|
||||||
|
@ -2083,7 +2103,7 @@ FilterDistributedFunctions(GrantStmt *grantStmt)
|
||||||
* if this function from GRANT .. ON FUNCTION .. is a distributed
|
* if this function from GRANT .. ON FUNCTION .. is a distributed
|
||||||
* function, add it to the list
|
* function, add it to the list
|
||||||
*/
|
*/
|
||||||
if (IsObjectDistributed(functionAddress))
|
if (IsAnyObjectDistributed(list_make1(functionAddress)))
|
||||||
{
|
{
|
||||||
grantFunctionList = lappend(grantFunctionList, functionAddress);
|
grantFunctionList = lappend(grantFunctionList, functionAddress);
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,9 +238,9 @@ CollectGrantTableIdList(GrantStmt *grantStmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for distributed sequences included in GRANT ON TABLE statement */
|
/* check for distributed sequences included in GRANT ON TABLE statement */
|
||||||
ObjectAddress sequenceAddress = { 0 };
|
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(sequenceAddress, RelationRelationId, relationId);
|
ObjectAddressSet(*sequenceAddress, RelationRelationId, relationId);
|
||||||
if (IsObjectDistributed(&sequenceAddress))
|
if (IsAnyObjectDistributed(list_make1(sequenceAddress)))
|
||||||
{
|
{
|
||||||
grantTableList = lappend_oid(grantTableList, relationId);
|
grantTableList = lappend_oid(grantTableList, relationId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -761,9 +761,9 @@ PostprocessIndexStmt(Node *node, const char *queryString)
|
||||||
Oid indexRelationId = get_relname_relid(indexStmt->idxname, schemaId);
|
Oid indexRelationId = get_relname_relid(indexStmt->idxname, schemaId);
|
||||||
|
|
||||||
/* ensure dependencies of index exist on all nodes */
|
/* ensure dependencies of index exist on all nodes */
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, RelationRelationId, indexRelationId);
|
ObjectAddressSet(*address, RelationRelationId, indexRelationId);
|
||||||
EnsureDependenciesExistOnAllNodes(&address);
|
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(address));
|
||||||
|
|
||||||
/* furtheron we are only processing CONCURRENT index statements */
|
/* furtheron we are only processing CONCURRENT index statements */
|
||||||
if (!indexStmt->concurrent)
|
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
|
* 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
|
* 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.
|
* that we will pop any snapshot if we have any right before we commit.
|
||||||
|
|
|
@ -106,9 +106,7 @@
|
||||||
#include "nodes/nodeFuncs.h"
|
#include "nodes/nodeFuncs.h"
|
||||||
#include "parser/parse_func.h"
|
#include "parser/parse_func.h"
|
||||||
#include "parser/parse_type.h"
|
#include "parser/parse_type.h"
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
#include "tcop/cmdtag.h"
|
#include "tcop/cmdtag.h"
|
||||||
#endif
|
|
||||||
#include "tsearch/ts_locale.h"
|
#include "tsearch/ts_locale.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
|
@ -764,12 +762,7 @@ FindJsonbInputColumns(TupleDesc tupleDescriptor, List *inputColumnNameList)
|
||||||
static void
|
static void
|
||||||
CompleteCopyQueryTagCompat(QueryCompletionCompat *completionTag, uint64 processedRowCount)
|
CompleteCopyQueryTagCompat(QueryCompletionCompat *completionTag, uint64 processedRowCount)
|
||||||
{
|
{
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
SetQueryCompletion(completionTag, CMDTAG_COPY, processedRowCount);
|
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)
|
RemoveOptionFromList(List *optionList, char *optionName)
|
||||||
{
|
{
|
||||||
ListCell *optionCell = NULL;
|
ListCell *optionCell = NULL;
|
||||||
#if PG_VERSION_NUM < PG_VERSION_13
|
|
||||||
ListCell *previousCell = NULL;
|
|
||||||
#endif
|
|
||||||
foreach(optionCell, optionList)
|
foreach(optionCell, optionList)
|
||||||
{
|
{
|
||||||
DefElem *option = (DefElem *) lfirst(optionCell);
|
DefElem *option = (DefElem *) lfirst(optionCell);
|
||||||
|
@ -792,9 +782,6 @@ RemoveOptionFromList(List *optionList, char *optionName)
|
||||||
{
|
{
|
||||||
return list_delete_cell_compat(optionList, optionCell, previousCell);
|
return list_delete_cell_compat(optionList, optionCell, previousCell);
|
||||||
}
|
}
|
||||||
#if PG_VERSION_NUM < PG_VERSION_13
|
|
||||||
previousCell = optionCell;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return optionList;
|
return optionList;
|
||||||
|
|
|
@ -290,22 +290,10 @@ PostprocessCreatePolicyStmt(Node *node, const char *queryString)
|
||||||
static void
|
static void
|
||||||
AddRangeTableEntryToQueryCompat(ParseState *parseState, Relation relation)
|
AddRangeTableEntryToQueryCompat(ParseState *parseState, Relation relation)
|
||||||
{
|
{
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
ParseNamespaceItem *rte = addRangeTableEntryForRelation(parseState, relation,
|
||||||
ParseNamespaceItem *rte = NULL;
|
AccessShareLock, NULL,
|
||||||
#else
|
false, false);
|
||||||
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
|
|
||||||
addNSItemToQuery(parseState, rte, false, true, true);
|
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
|
void
|
||||||
DropPolicyEventExtendNames(DropStmt *dropStmt, const char *schemaName, uint64 shardId)
|
DropPolicyEventExtendNames(DropStmt *dropStmt, const char *schemaName, uint64 shardId)
|
||||||
{
|
{
|
||||||
Value *relationSchemaNameValue = NULL;
|
String *relationSchemaNameValue = NULL;
|
||||||
Value *relationNameValue = NULL;
|
String *relationNameValue = NULL;
|
||||||
|
|
||||||
uint32 dropCount = list_length(dropStmt->objects);
|
uint32 dropCount = list_length(dropStmt->objects);
|
||||||
if (dropCount > 1)
|
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 */
|
/* prefix with schema name if it is not added already */
|
||||||
if (relationSchemaNameValue == NULL)
|
if (relationSchemaNameValue == NULL)
|
||||||
{
|
{
|
||||||
Value *schemaNameValue = makeString(pstrdup(schemaName));
|
String *schemaNameValue = makeString(pstrdup(schemaName));
|
||||||
relationNameList = lcons(schemaNameValue, relationNameList);
|
relationNameList = lcons(schemaNameValue, relationNameList);
|
||||||
}
|
}
|
||||||
|
|
||||||
char **relationName = &(relationNameValue->val.str);
|
char **relationName = &(strVal(relationNameValue));
|
||||||
AppendShardIdToName(relationName, shardId);
|
AppendShardIdToName(relationName, shardId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ static Node * makeFloatConst(char *str, int location);
|
||||||
static const char * WrapQueryInAlterRoleIfExistsCall(const char *query, RoleSpec *role);
|
static const char * WrapQueryInAlterRoleIfExistsCall(const char *query, RoleSpec *role);
|
||||||
static VariableSetStmt * MakeVariableSetStmt(const char *config);
|
static VariableSetStmt * MakeVariableSetStmt(const char *config);
|
||||||
static int ConfigGenericNameCompare(const void *lhs, const void *rhs);
|
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 */
|
/* controlled via GUC */
|
||||||
bool EnableCreateRolePropagation = true;
|
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
|
* 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.
|
* was unable to find the role that was the target of the statement.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterRoleStmtObjectAddress(Node *node, bool missing_ok)
|
AlterRoleStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterRoleStmt *stmt = castNode(AlterRoleStmt, node);
|
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
|
* 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.
|
* was unable to find the role that was the target of the statement.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterRoleSetStmtObjectAddress(Node *node, bool missing_ok)
|
AlterRoleSetStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterRoleSetStmt *stmt = castNode(AlterRoleSetStmt, node);
|
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
|
* RoleSpec. If missing_ok is set to false an error will be raised by postgres
|
||||||
* explaining the Role could not be found.
|
* explaining the Role could not be found.
|
||||||
*/
|
*/
|
||||||
static ObjectAddress
|
static List *
|
||||||
RoleSpecToObjectAddress(RoleSpec *role, bool missing_ok)
|
RoleSpecToObjectAddress(RoleSpec *role, bool missing_ok)
|
||||||
{
|
{
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
|
|
||||||
if (role != NULL)
|
if (role != NULL)
|
||||||
{
|
{
|
||||||
/* roles can be NULL for statements on ALL roles eg. ALTER ROLE ALL SET ... */
|
/* roles can be NULL for statements on ALL roles eg. ALTER ROLE ALL SET ... */
|
||||||
Oid roleOid = get_rolespec_oid(role, missing_ok);
|
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 *
|
List *
|
||||||
PostprocessAlterRoleStmt(Node *node, const char *queryString)
|
PostprocessAlterRoleStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
ObjectAddress address = GetObjectAddressFromParseTree(node, false);
|
List *addresses = GetObjectAddressListFromParseTree(node, false);
|
||||||
if (!ShouldPropagateObject(&address))
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(addresses) == 1);
|
||||||
|
|
||||||
|
if (!ShouldPropagateAnyObject(addresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -208,14 +212,17 @@ PreprocessAlterRoleSetStmt(Node *node, const char *queryString,
|
||||||
return NIL;
|
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
|
* 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
|
* 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
|
* distributed we will not propagate the statement
|
||||||
*/
|
*/
|
||||||
if (stmt->role != NULL && !IsObjectDistributed(&address))
|
if (stmt->role != NULL && !IsAnyObjectDistributed(addresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -1056,7 +1063,6 @@ FilterDistributedRoles(List *roles)
|
||||||
foreach_ptr(roleNode, roles)
|
foreach_ptr(roleNode, roles)
|
||||||
{
|
{
|
||||||
RoleSpec *role = castNode(RoleSpec, roleNode);
|
RoleSpec *role = castNode(RoleSpec, roleNode);
|
||||||
ObjectAddress roleAddress = { 0 };
|
|
||||||
Oid roleOid = get_rolespec_oid(role, true);
|
Oid roleOid = get_rolespec_oid(role, true);
|
||||||
if (roleOid == InvalidOid)
|
if (roleOid == InvalidOid)
|
||||||
{
|
{
|
||||||
|
@ -1066,8 +1072,9 @@ FilterDistributedRoles(List *roles)
|
||||||
*/
|
*/
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ObjectAddressSet(roleAddress, AuthIdRelationId, roleOid);
|
ObjectAddress *roleAddress = palloc0(sizeof(ObjectAddress));
|
||||||
if (IsObjectDistributed(&roleAddress))
|
ObjectAddressSet(*roleAddress, AuthIdRelationId, roleOid);
|
||||||
|
if (IsAnyObjectDistributed(list_make1(roleAddress)))
|
||||||
{
|
{
|
||||||
distributedRoles = lappend(distributedRoles, role);
|
distributedRoles = lappend(distributedRoles, role);
|
||||||
}
|
}
|
||||||
|
@ -1137,12 +1144,13 @@ PostprocessGrantRoleStmt(Node *node, const char *queryString)
|
||||||
RoleSpec *role = NULL;
|
RoleSpec *role = NULL;
|
||||||
foreach_ptr(role, stmt->grantee_roles)
|
foreach_ptr(role, stmt->grantee_roles)
|
||||||
{
|
{
|
||||||
ObjectAddress roleAddress = { 0 };
|
|
||||||
Oid roleOid = get_rolespec_oid(role, false);
|
Oid roleOid = get_rolespec_oid(role, false);
|
||||||
ObjectAddressSet(roleAddress, AuthIdRelationId, roleOid);
|
ObjectAddress *roleAddress = palloc0(sizeof(ObjectAddress));
|
||||||
if (IsObjectDistributed(&roleAddress))
|
ObjectAddressSet(*roleAddress, AuthIdRelationId, roleOid);
|
||||||
|
|
||||||
|
if (IsAnyObjectDistributed(list_make1(roleAddress)))
|
||||||
{
|
{
|
||||||
EnsureDependenciesExistOnAllNodes(&roleAddress);
|
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(roleAddress));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NIL;
|
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
|
* Never returns NULL, but the objid in the address could be invalid if missing_ok was set
|
||||||
* to true.
|
* to true.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
CreateRoleStmtObjectAddress(Node *node, bool missing_ok)
|
CreateRoleStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
CreateRoleStmt *stmt = castNode(CreateRoleStmt, node);
|
CreateRoleStmt *stmt = castNode(CreateRoleStmt, node);
|
||||||
Oid roleOid = get_role_oid(stmt->role, missing_ok);
|
Oid roleOid = get_role_oid(stmt->role, missing_ok);
|
||||||
ObjectAddress roleAddress = { 0 };
|
ObjectAddress *roleAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(roleAddress, AuthIdRelationId, roleOid);
|
ObjectAddressSet(*roleAddress, AuthIdRelationId, roleOid);
|
||||||
|
|
||||||
return roleAddress;
|
return list_make1(roleAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
#include "utils/relcache.h"
|
#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 List * FilterDistributedSchemas(List *schemas);
|
||||||
static bool SchemaHasDistributedTableWithFKey(char *schemaName);
|
static bool SchemaHasDistributedTableWithFKey(char *schemaName);
|
||||||
static bool ShouldPropagateCreateSchemaStmt(void);
|
static bool ShouldPropagateCreateSchemaStmt(void);
|
||||||
|
@ -183,7 +183,7 @@ PreprocessGrantOnSchemaStmt(Node *node, const char *queryString,
|
||||||
* CreateSchemaStmtObjectAddress returns the ObjectAddress of the schema that is
|
* CreateSchemaStmtObjectAddress returns the ObjectAddress of the schema that is
|
||||||
* the object of the CreateSchemaStmt. Errors if missing_ok is false.
|
* the object of the CreateSchemaStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
CreateSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
CreateSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
CreateSchemaStmt *stmt = castNode(CreateSchemaStmt, node);
|
CreateSchemaStmt *stmt = castNode(CreateSchemaStmt, node);
|
||||||
|
@ -213,7 +213,7 @@ CreateSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
* AlterSchemaRenameStmtObjectAddress returns the ObjectAddress of the schema that is
|
* AlterSchemaRenameStmtObjectAddress returns the ObjectAddress of the schema that is
|
||||||
* the object of the RenameStmt. Errors if missing_ok is false.
|
* the object of the RenameStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterSchemaRenameStmtObjectAddress(Node *node, bool missing_ok)
|
AlterSchemaRenameStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
RenameStmt *stmt = castNode(RenameStmt, node);
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
|
@ -227,15 +227,15 @@ AlterSchemaRenameStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
* GetObjectAddressBySchemaName returns the ObjectAddress of the schema with the
|
* GetObjectAddressBySchemaName returns the ObjectAddress of the schema with the
|
||||||
* given name. Errors out if schema is not found and missing_ok is false.
|
* given name. Errors out if schema is not found and missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
GetObjectAddressBySchemaName(char *schemaName, bool missing_ok)
|
GetObjectAddressBySchemaName(char *schemaName, bool missing_ok)
|
||||||
{
|
{
|
||||||
Oid schemaOid = get_namespace_oid(schemaName, missing_ok);
|
Oid schemaOid = get_namespace_oid(schemaName, missing_ok);
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, NamespaceRelationId, schemaOid);
|
ObjectAddressSet(*address, NamespaceRelationId, schemaOid);
|
||||||
|
|
||||||
return address;
|
return list_make1(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -259,10 +259,9 @@ FilterDistributedSchemas(List *schemas)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, NamespaceRelationId, schemaOid);
|
ObjectAddressSet(*address, NamespaceRelationId, schemaOid);
|
||||||
|
if (!IsAnyObjectDistributed(list_make1(address)))
|
||||||
if (!IsObjectDistributed(&address))
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,11 +197,7 @@ ExtractDefaultColumnsAndOwnedSequences(Oid relationId, List **columnNameList,
|
||||||
if (list_length(columnOwnedSequences) != 0)
|
if (list_length(columnOwnedSequences) != 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* A column might only own one sequence. We intentionally use
|
* A column might only own one sequence.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
Assert(list_length(columnOwnedSequences) == 1);
|
Assert(list_length(columnOwnedSequences) == 1);
|
||||||
ownedSequenceId = linitial_oid(columnOwnedSequences);
|
ownedSequenceId = linitial_oid(columnOwnedSequences);
|
||||||
|
@ -268,18 +264,16 @@ PreprocessDropSequenceStmt(Node *node, const char *queryString,
|
||||||
|
|
||||||
Oid seqOid = RangeVarGetRelid(seq, NoLock, stmt->missing_ok);
|
Oid seqOid = RangeVarGetRelid(seq, NoLock, stmt->missing_ok);
|
||||||
|
|
||||||
ObjectAddress sequenceAddress = { 0 };
|
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(sequenceAddress, RelationRelationId, seqOid);
|
ObjectAddressSet(*sequenceAddress, RelationRelationId, seqOid);
|
||||||
|
if (!IsAnyObjectDistributed(list_make1(sequenceAddress)))
|
||||||
if (!IsObjectDistributed(&sequenceAddress))
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* collect information for all distributed sequences */
|
/* collect information for all distributed sequences */
|
||||||
ObjectAddress *addressp = palloc(sizeof(ObjectAddress));
|
distributedSequenceAddresses = lappend(distributedSequenceAddresses,
|
||||||
*addressp = sequenceAddress;
|
sequenceAddress);
|
||||||
distributedSequenceAddresses = lappend(distributedSequenceAddresses, addressp);
|
|
||||||
distributedSequencesList = lappend(distributedSequencesList, objectNameList);
|
distributedSequencesList = lappend(distributedSequencesList, objectNameList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,10 +328,13 @@ PreprocessRenameSequenceStmt(Node *node, const char *queryString, ProcessUtility
|
||||||
RenameStmt *stmt = castNode(RenameStmt, node);
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
Assert(stmt->renameType == OBJECT_SEQUENCE);
|
Assert(stmt->renameType == OBJECT_SEQUENCE);
|
||||||
|
|
||||||
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt,
|
List *addresses = GetObjectAddressListFromParseTree((Node *) stmt,
|
||||||
stmt->missing_ok);
|
stmt->missing_ok);
|
||||||
|
|
||||||
if (!ShouldPropagateObject(&address))
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(addresses) == 1);
|
||||||
|
|
||||||
|
if (!ShouldPropagateAnyObject(addresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -358,7 +355,7 @@ PreprocessRenameSequenceStmt(Node *node, const char *queryString, ProcessUtility
|
||||||
* RenameSequenceStmtObjectAddress returns the ObjectAddress of the sequence that is the
|
* RenameSequenceStmtObjectAddress returns the ObjectAddress of the sequence that is the
|
||||||
* subject of the RenameStmt.
|
* subject of the RenameStmt.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
RenameSequenceStmtObjectAddress(Node *node, bool missing_ok)
|
RenameSequenceStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
RenameStmt *stmt = castNode(RenameStmt, node);
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
|
@ -366,10 +363,10 @@ RenameSequenceStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
|
|
||||||
RangeVar *sequence = stmt->relation;
|
RangeVar *sequence = stmt->relation;
|
||||||
Oid seqOid = RangeVarGetRelid(sequence, NoLock, missing_ok);
|
Oid seqOid = RangeVarGetRelid(sequence, NoLock, missing_ok);
|
||||||
ObjectAddress sequenceAddress = { 0 };
|
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(sequenceAddress, RelationRelationId, seqOid);
|
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);
|
AlterSeqStmt *stmt = castNode(AlterSeqStmt, node);
|
||||||
|
|
||||||
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt,
|
List *addresses = GetObjectAddressListFromParseTree((Node *) stmt,
|
||||||
stmt->missing_ok);
|
stmt->missing_ok);
|
||||||
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(addresses) == 1);
|
||||||
|
|
||||||
/* error out if the sequence is distributed */
|
/* error out if the sequence is distributed */
|
||||||
if (IsObjectDistributed(&address))
|
if (IsAnyObjectDistributed(addresses))
|
||||||
{
|
{
|
||||||
ereport(ERROR, (errmsg(
|
ereport(ERROR, (errmsg(
|
||||||
"Altering a distributed sequence is currently not supported.")));
|
"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
|
* error out if the sequence is used in a distributed table
|
||||||
* and this is an ALTER SEQUENCE .. AS .. statement
|
* and this is an ALTER SEQUENCE .. AS .. statement
|
||||||
*/
|
*/
|
||||||
Oid citusTableId = SequenceUsedInDistributedTable(&address);
|
Oid citusTableId = SequenceUsedInDistributedTable(address);
|
||||||
if (citusTableId != InvalidOid)
|
if (citusTableId != InvalidOid)
|
||||||
{
|
{
|
||||||
List *options = stmt->options;
|
List *options = stmt->options;
|
||||||
|
@ -463,6 +466,7 @@ SequenceUsedInDistributedTable(const ObjectAddress *sequenceAddress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return InvalidOid;
|
return InvalidOid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,17 +475,17 @@ SequenceUsedInDistributedTable(const ObjectAddress *sequenceAddress)
|
||||||
* AlterSequenceStmtObjectAddress returns the ObjectAddress of the sequence that is the
|
* AlterSequenceStmtObjectAddress returns the ObjectAddress of the sequence that is the
|
||||||
* subject of the AlterSeqStmt.
|
* subject of the AlterSeqStmt.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterSequenceStmtObjectAddress(Node *node, bool missing_ok)
|
AlterSequenceStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterSeqStmt *stmt = castNode(AlterSeqStmt, node);
|
AlterSeqStmt *stmt = castNode(AlterSeqStmt, node);
|
||||||
|
|
||||||
RangeVar *sequence = stmt->sequence;
|
RangeVar *sequence = stmt->sequence;
|
||||||
Oid seqOid = RangeVarGetRelid(sequence, NoLock, stmt->missing_ok);
|
Oid seqOid = RangeVarGetRelid(sequence, NoLock, stmt->missing_ok);
|
||||||
ObjectAddress sequenceAddress = { 0 };
|
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(sequenceAddress, RelationRelationId, seqOid);
|
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);
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
Assert(stmt->objectType == OBJECT_SEQUENCE);
|
Assert(stmt->objectType == OBJECT_SEQUENCE);
|
||||||
|
|
||||||
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt,
|
List *addresses = GetObjectAddressListFromParseTree((Node *) stmt,
|
||||||
stmt->missing_ok);
|
stmt->missing_ok);
|
||||||
if (!ShouldPropagateObject(&address))
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(addresses) == 1);
|
||||||
|
|
||||||
|
if (!ShouldPropagateAnyObject(addresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -521,7 +529,7 @@ PreprocessAlterSequenceSchemaStmt(Node *node, const char *queryString,
|
||||||
* AlterSequenceSchemaStmtObjectAddress returns the ObjectAddress of the sequence that is
|
* AlterSequenceSchemaStmtObjectAddress returns the ObjectAddress of the sequence that is
|
||||||
* the subject of the AlterObjectSchemaStmt.
|
* the subject of the AlterObjectSchemaStmt.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
|
@ -555,10 +563,10 @@ AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress sequenceAddress = { 0 };
|
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(sequenceAddress, RelationRelationId, seqOid);
|
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);
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
Assert(stmt->objectType == OBJECT_SEQUENCE);
|
Assert(stmt->objectType == OBJECT_SEQUENCE);
|
||||||
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt,
|
List *addresses = GetObjectAddressListFromParseTree((Node *) stmt,
|
||||||
stmt->missing_ok);
|
stmt->missing_ok);
|
||||||
|
|
||||||
if (!ShouldPropagateObject(&address))
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(addresses) == 1);
|
||||||
|
|
||||||
|
if (!ShouldPropagateAnyObject(addresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dependencies have changed (schema) let's ensure they exist */
|
/* dependencies have changed (schema) let's ensure they exist */
|
||||||
EnsureDependenciesExistOnAllNodes(&address);
|
EnsureAllObjectDependenciesExistOnAllNodes(addresses);
|
||||||
|
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -601,8 +612,12 @@ PreprocessAlterSequenceOwnerStmt(Node *node, const char *queryString,
|
||||||
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
||||||
Assert(AlterTableStmtObjType_compat(stmt) == OBJECT_SEQUENCE);
|
Assert(AlterTableStmtObjType_compat(stmt) == OBJECT_SEQUENCE);
|
||||||
|
|
||||||
ObjectAddress sequenceAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
List *sequenceAddresses = GetObjectAddressListFromParseTree((Node *) stmt, false);
|
||||||
if (!ShouldPropagateObject(&sequenceAddress))
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(sequenceAddresses) == 1);
|
||||||
|
|
||||||
|
if (!ShouldPropagateAnyObject(sequenceAddresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -623,7 +638,7 @@ PreprocessAlterSequenceOwnerStmt(Node *node, const char *queryString,
|
||||||
* AlterSequenceOwnerStmtObjectAddress returns the ObjectAddress of the sequence that is the
|
* AlterSequenceOwnerStmtObjectAddress returns the ObjectAddress of the sequence that is the
|
||||||
* subject of the AlterOwnerStmt.
|
* subject of the AlterOwnerStmt.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok)
|
AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
||||||
|
@ -631,10 +646,10 @@ AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
|
|
||||||
RangeVar *sequence = stmt->relation;
|
RangeVar *sequence = stmt->relation;
|
||||||
Oid seqOid = RangeVarGetRelid(sequence, NoLock, missing_ok);
|
Oid seqOid = RangeVarGetRelid(sequence, NoLock, missing_ok);
|
||||||
ObjectAddress sequenceAddress = { 0 };
|
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(sequenceAddress, RelationRelationId, seqOid);
|
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);
|
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
||||||
Assert(AlterTableStmtObjType_compat(stmt) == OBJECT_SEQUENCE);
|
Assert(AlterTableStmtObjType_compat(stmt) == OBJECT_SEQUENCE);
|
||||||
|
|
||||||
ObjectAddress sequenceAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
List *sequenceAddresses = GetObjectAddressListFromParseTree((Node *) stmt, false);
|
||||||
if (!ShouldPropagateObject(&sequenceAddress))
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(sequenceAddresses) == 1);
|
||||||
|
|
||||||
|
if (!ShouldPropagateAnyObject(sequenceAddresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dependencies have changed (owner) let's ensure they exist */
|
/* dependencies have changed (owner) let's ensure they exist */
|
||||||
EnsureDependenciesExistOnAllNodes(&sequenceAddress);
|
EnsureAllObjectDependenciesExistOnAllNodes(sequenceAddresses);
|
||||||
|
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -744,10 +763,10 @@ PostprocessGrantOnSequenceStmt(Node *node, const char *queryString)
|
||||||
RangeVar *sequence = NULL;
|
RangeVar *sequence = NULL;
|
||||||
foreach_ptr(sequence, distributedSequences)
|
foreach_ptr(sequence, distributedSequences)
|
||||||
{
|
{
|
||||||
ObjectAddress sequenceAddress = { 0 };
|
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
|
||||||
Oid sequenceOid = RangeVarGetRelid(sequence, NoLock, false);
|
Oid sequenceOid = RangeVarGetRelid(sequence, NoLock, false);
|
||||||
ObjectAddressSet(sequenceAddress, RelationRelationId, sequenceOid);
|
ObjectAddressSet(*sequenceAddress, RelationRelationId, sequenceOid);
|
||||||
EnsureDependenciesExistOnAllNodes(&sequenceAddress);
|
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(sequenceAddress));
|
||||||
}
|
}
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -825,7 +844,7 @@ FilterDistributedSequences(GrantStmt *stmt)
|
||||||
{
|
{
|
||||||
/* iterate over all namespace names provided to get their oid's */
|
/* iterate over all namespace names provided to get their oid's */
|
||||||
List *namespaceOidList = NIL;
|
List *namespaceOidList = NIL;
|
||||||
Value *namespaceValue = NULL;
|
String *namespaceValue = NULL;
|
||||||
foreach_ptr(namespaceValue, stmt->objects)
|
foreach_ptr(namespaceValue, stmt->objects)
|
||||||
{
|
{
|
||||||
char *nspname = strVal(namespaceValue);
|
char *nspname = strVal(namespaceValue);
|
||||||
|
@ -866,15 +885,15 @@ FilterDistributedSequences(GrantStmt *stmt)
|
||||||
RangeVar *sequenceRangeVar = NULL;
|
RangeVar *sequenceRangeVar = NULL;
|
||||||
foreach_ptr(sequenceRangeVar, stmt->objects)
|
foreach_ptr(sequenceRangeVar, stmt->objects)
|
||||||
{
|
{
|
||||||
ObjectAddress sequenceAddress = { 0 };
|
|
||||||
Oid sequenceOid = RangeVarGetRelid(sequenceRangeVar, NoLock, missing_ok);
|
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
|
* if this sequence from GRANT .. ON SEQUENCE .. is a distributed
|
||||||
* sequence, add it to the list
|
* sequence, add it to the list
|
||||||
*/
|
*/
|
||||||
if (IsObjectDistributed(&sequenceAddress))
|
if (IsAnyObjectDistributed(list_make1(sequenceAddress)))
|
||||||
{
|
{
|
||||||
grantSequenceList = lappend(grantSequenceList, sequenceRangeVar);
|
grantSequenceList = lappend(grantSequenceList, sequenceRangeVar);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,9 +55,7 @@ static char * GenerateAlterIndexColumnSetStatsCommand(char *indexNameWithSchema,
|
||||||
int32 attstattarget);
|
int32 attstattarget);
|
||||||
static Oid GetRelIdByStatsOid(Oid statsOid);
|
static Oid GetRelIdByStatsOid(Oid statsOid);
|
||||||
static char * CreateAlterCommandIfOwnerNotDefault(Oid statsOid);
|
static char * CreateAlterCommandIfOwnerNotDefault(Oid statsOid);
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
static char * CreateAlterCommandIfTargetNotDefault(Oid statsOid);
|
static char * CreateAlterCommandIfTargetNotDefault(Oid statsOid);
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PreprocessCreateStatisticsStmt is called during the planning phase for
|
* PreprocessCreateStatisticsStmt is called during the planning phase for
|
||||||
|
@ -122,9 +120,12 @@ PostprocessCreateStatisticsStmt(Node *node, const char *queryString)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool missingOk = false;
|
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;
|
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
|
* Never returns NULL, but the objid in the address can be invalid if missingOk
|
||||||
* was set to true.
|
* was set to true.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
CreateStatisticsStmtObjectAddress(Node *node, bool missingOk)
|
CreateStatisticsStmtObjectAddress(Node *node, bool missingOk)
|
||||||
{
|
{
|
||||||
CreateStatsStmt *stmt = castNode(CreateStatsStmt, node);
|
CreateStatsStmt *stmt = castNode(CreateStatsStmt, node);
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
Oid statsOid = get_statistics_object_oid(stmt->defnames, missingOk);
|
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;
|
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;
|
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
|
* Never returns NULL, but the objid in the address can be invalid if missingOk
|
||||||
* was set to true.
|
* was set to true.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterStatisticsSchemaStmtObjectAddress(Node *node, bool missingOk)
|
AlterStatisticsSchemaStmtObjectAddress(Node *node, bool missingOk)
|
||||||
{
|
{
|
||||||
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
String *statName = llast((List *) stmt->object);
|
String *statName = llast((List *) stmt->object);
|
||||||
Oid statsOid = get_statistics_object_oid(list_make2(makeString(stmt->newschema),
|
Oid statsOid = get_statistics_object_oid(list_make2(makeString(stmt->newschema),
|
||||||
statName), missingOk);
|
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
|
* PreprocessAlterStatisticsStmt is called during the planning phase for
|
||||||
* ALTER STATISTICS .. SET STATISTICS.
|
* ALTER STATISTICS .. SET STATISTICS.
|
||||||
|
@ -387,8 +389,6 @@ PreprocessAlterStatisticsStmt(Node *node, const char *queryString,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PreprocessAlterStatisticsOwnerStmt is called during the planning phase for
|
* PreprocessAlterStatisticsOwnerStmt is called during the planning phase for
|
||||||
* ALTER STATISTICS .. OWNER TO.
|
* ALTER STATISTICS .. OWNER TO.
|
||||||
|
@ -449,10 +449,9 @@ PostprocessAlterStatisticsOwnerStmt(Node *node, const char *queryString)
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress statisticsAddress = { 0 };
|
ObjectAddress *statisticsAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(statisticsAddress, StatisticExtRelationId, statsOid);
|
ObjectAddressSet(*statisticsAddress, StatisticExtRelationId, statsOid);
|
||||||
|
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(statisticsAddress));
|
||||||
EnsureDependenciesExistOnAllNodes(&statisticsAddress);
|
|
||||||
|
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -502,7 +501,6 @@ GetExplicitStatisticsCommandList(Oid relationId)
|
||||||
explicitStatisticsCommandList =
|
explicitStatisticsCommandList =
|
||||||
lappend(explicitStatisticsCommandList,
|
lappend(explicitStatisticsCommandList,
|
||||||
makeTableDDLCommandString(createStatisticsCommand));
|
makeTableDDLCommandString(createStatisticsCommand));
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
|
|
||||||
/* we need to alter stats' target if it's getting distributed after creation */
|
/* we need to alter stats' target if it's getting distributed after creation */
|
||||||
char *alterStatisticsTargetCommand =
|
char *alterStatisticsTargetCommand =
|
||||||
|
@ -514,7 +512,6 @@ GetExplicitStatisticsCommandList(Oid relationId)
|
||||||
lappend(explicitStatisticsCommandList,
|
lappend(explicitStatisticsCommandList,
|
||||||
makeTableDDLCommandString(alterStatisticsTargetCommand));
|
makeTableDDLCommandString(alterStatisticsTargetCommand));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* we need to alter stats' owner if it's getting distributed after creation */
|
/* we need to alter stats' owner if it's getting distributed after creation */
|
||||||
char *alterStatisticsOwnerCommand =
|
char *alterStatisticsOwnerCommand =
|
||||||
|
@ -704,8 +701,6 @@ CreateAlterCommandIfOwnerNotDefault(Oid statsOid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CreateAlterCommandIfTargetNotDefault returns an ALTER STATISTICS .. SET STATISTICS
|
* CreateAlterCommandIfTargetNotDefault returns an ALTER STATISTICS .. SET STATISTICS
|
||||||
* command if the stats object with given id has a target different than the default one.
|
* 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);
|
return DeparseAlterStatisticsStmt((Node *) alterStatsStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -35,9 +35,6 @@ Node *
|
||||||
ProcessCreateSubscriptionStmt(CreateSubscriptionStmt *createSubStmt)
|
ProcessCreateSubscriptionStmt(CreateSubscriptionStmt *createSubStmt)
|
||||||
{
|
{
|
||||||
ListCell *currCell = NULL;
|
ListCell *currCell = NULL;
|
||||||
#if PG_VERSION_NUM < PG_VERSION_13
|
|
||||||
ListCell *prevCell = NULL;
|
|
||||||
#endif
|
|
||||||
bool useAuthinfo = false;
|
bool useAuthinfo = false;
|
||||||
|
|
||||||
foreach(currCell, createSubStmt->options)
|
foreach(currCell, createSubStmt->options)
|
||||||
|
@ -54,9 +51,6 @@ ProcessCreateSubscriptionStmt(CreateSubscriptionStmt *createSubStmt)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if PG_VERSION_NUM < PG_VERSION_13
|
|
||||||
prevCell = currCell;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useAuthinfo)
|
if (useAuthinfo)
|
||||||
|
@ -103,7 +97,7 @@ GenerateConninfoWithAuth(char *conninfo)
|
||||||
}
|
}
|
||||||
else if (strcmp(option->keyword, "port") == 0)
|
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)
|
else if (strcmp(option->keyword, "user") == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -649,13 +649,19 @@ PostprocessAlterTableSchemaStmt(Node *node, const char *queryString)
|
||||||
/*
|
/*
|
||||||
* We will let Postgres deal with missing_ok
|
* 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
|
* Check whether we are dealing with a sequence or view here and route queries
|
||||||
* accordingly to the right processor function.
|
* accordingly to the right processor function.
|
||||||
*/
|
*/
|
||||||
char relKind = get_rel_relkind(tableAddress.objectId);
|
char relKind = get_rel_relkind(tableAddress->objectId);
|
||||||
if (relKind == RELKIND_SEQUENCE)
|
if (relKind == RELKIND_SEQUENCE)
|
||||||
{
|
{
|
||||||
stmt->objectType = OBJECT_SEQUENCE;
|
stmt->objectType = OBJECT_SEQUENCE;
|
||||||
|
@ -667,12 +673,12 @@ PostprocessAlterTableSchemaStmt(Node *node, const char *queryString)
|
||||||
return PostprocessAlterViewSchemaStmt((Node *) stmt, queryString);
|
return PostprocessAlterViewSchemaStmt((Node *) stmt, queryString);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ShouldPropagate() || !IsCitusTable(tableAddress.objectId))
|
if (!ShouldPropagate() || !IsCitusTable(tableAddress->objectId))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnsureDependenciesExistOnAllNodes(&tableAddress);
|
EnsureAllObjectDependenciesExistOnAllNodes(tableAddresses);
|
||||||
|
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -751,9 +757,9 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We don't process subcommands generated by postgres.
|
* We don't process subcommands generated by postgres.
|
||||||
* This is mainly because postgres started to issue ALTER TABLE commands
|
* This is mainly because postgres issues ALTER TABLE commands
|
||||||
* for some set of objects that are defined via CREATE TABLE commands as
|
* for some set of objects that are defined via CREATE TABLE commands.
|
||||||
* of pg13. However, citus already has a separate logic for CREATE TABLE
|
* However, citus already has a separate logic for CREATE TABLE
|
||||||
* commands.
|
* commands.
|
||||||
*
|
*
|
||||||
* To support foreign keys from/to postgres local tables to/from reference
|
* To support foreign keys from/to postgres local tables to/from reference
|
||||||
|
@ -1776,9 +1782,15 @@ PreprocessAlterTableSchemaStmt(Node *node, const char *queryString,
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress address = GetObjectAddressFromParseTree((Node *) stmt,
|
List *addresses = GetObjectAddressListFromParseTree((Node *) stmt,
|
||||||
stmt->missing_ok);
|
stmt->missing_ok);
|
||||||
Oid relationId = address.objectId;
|
|
||||||
|
/* 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
|
* Check whether we are dealing with a sequence or view here and route queries
|
||||||
|
@ -1990,9 +2002,9 @@ PostprocessAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
EnsureRelationHasCompatibleSequenceTypes(relationId);
|
EnsureRelationHasCompatibleSequenceTypes(relationId);
|
||||||
|
|
||||||
/* changing a relation could introduce new dependencies */
|
/* changing a relation could introduce new dependencies */
|
||||||
ObjectAddress tableAddress = { 0 };
|
ObjectAddress *tableAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
|
ObjectAddressSet(*tableAddress, RelationRelationId, relationId);
|
||||||
EnsureDependenciesExistOnAllNodes(&tableAddress);
|
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(tableAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* for the new sequences coming with this ALTER TABLE statement */
|
/* 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
|
* will look in the new schema. Errors if missing_ok is false and the table cannot
|
||||||
* be found in either of the schemas.
|
* be found in either of the schemas.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterTableSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
AlterTableSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
|
@ -3389,10 +3401,10 @@ AlterTableSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, RelationRelationId, tableOid);
|
ObjectAddressSet(*address, RelationRelationId, tableOid);
|
||||||
|
|
||||||
return address;
|
return list_make1(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
* 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.
|
* the text search configuration described in the statement doesn't exist.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
CreateTextSearchConfigurationObjectAddress(Node *node, bool missing_ok)
|
CreateTextSearchConfigurationObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
DefineStmt *stmt = castNode(DefineStmt, node);
|
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);
|
Oid objid = get_ts_config_oid(stmt->defnames, missing_ok);
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TSConfigRelationId, objid);
|
ObjectAddressSet(*address, TSConfigRelationId, objid);
|
||||||
return address;
|
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
|
* 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.
|
* the text search dictionary described in the statement doesn't exist.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
CreateTextSearchDictObjectAddress(Node *node, bool missing_ok)
|
CreateTextSearchDictObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
DefineStmt *stmt = castNode(DefineStmt, node);
|
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);
|
Oid objid = get_ts_dict_oid(stmt->defnames, missing_ok);
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TSDictionaryRelationId, objid);
|
ObjectAddressSet(*address, TSDictionaryRelationId, objid);
|
||||||
return address;
|
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
|
* SEARCH CONFIGURATION being renamed. Optionally errors if the configuration does not
|
||||||
* exist based on the missing_ok flag passed in by the caller.
|
* exist based on the missing_ok flag passed in by the caller.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
RenameTextSearchConfigurationStmtObjectAddress(Node *node, bool missing_ok)
|
RenameTextSearchConfigurationStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
RenameStmt *stmt = castNode(RenameStmt, node);
|
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);
|
Oid objid = get_ts_config_oid(castNode(List, stmt->object), missing_ok);
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TSConfigRelationId, objid);
|
ObjectAddressSet(*address, TSConfigRelationId, objid);
|
||||||
return address;
|
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
|
* SEARCH DICTIONARY being renamed. Optionally errors if the dictionary does not
|
||||||
* exist based on the missing_ok flag passed in by the caller.
|
* exist based on the missing_ok flag passed in by the caller.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
RenameTextSearchDictionaryStmtObjectAddress(Node *node, bool missing_ok)
|
RenameTextSearchDictionaryStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
RenameStmt *stmt = castNode(RenameStmt, node);
|
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);
|
Oid objid = get_ts_dict_oid(castNode(List, stmt->object), missing_ok);
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TSDictionaryRelationId, objid);
|
ObjectAddressSet(*address, TSDictionaryRelationId, objid);
|
||||||
return address;
|
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
|
* SEARCH CONFIGURATION being altered. Optionally errors if the configuration does not
|
||||||
* exist based on the missing_ok flag passed in by the caller.
|
* exist based on the missing_ok flag passed in by the caller.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterTextSearchConfigurationStmtObjectAddress(Node *node, bool missing_ok)
|
AlterTextSearchConfigurationStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterTSConfigurationStmt *stmt = castNode(AlterTSConfigurationStmt, node);
|
AlterTSConfigurationStmt *stmt = castNode(AlterTSConfigurationStmt, node);
|
||||||
|
|
||||||
Oid objid = get_ts_config_oid(stmt->cfgname, missing_ok);
|
Oid objid = get_ts_config_oid(stmt->cfgname, missing_ok);
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TSConfigRelationId, objid);
|
ObjectAddressSet(*address, TSConfigRelationId, objid);
|
||||||
return address;
|
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
|
* SEARCH CONFIGURATION being altered. Optionally errors if the configuration does not
|
||||||
* exist based on the missing_ok flag passed in by the caller.
|
* exist based on the missing_ok flag passed in by the caller.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterTextSearchDictionaryStmtObjectAddress(Node *node, bool missing_ok)
|
AlterTextSearchDictionaryStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterTSDictionaryStmt *stmt = castNode(AlterTSDictionaryStmt, node);
|
AlterTSDictionaryStmt *stmt = castNode(AlterTSDictionaryStmt, node);
|
||||||
|
|
||||||
Oid objid = get_ts_dict_oid(stmt->dictname, missing_ok);
|
Oid objid = get_ts_dict_oid(stmt->dictname, missing_ok);
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TSDictionaryRelationId, objid);
|
ObjectAddressSet(*address, TSDictionaryRelationId, objid);
|
||||||
return address;
|
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
|
* 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.
|
* in edgecases will be raised by postgres while executing the move.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterTextSearchConfigurationSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
AlterTextSearchConfigurationSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
|
@ -723,9 +723,9 @@ AlterTextSearchConfigurationSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress sequenceAddress = { 0 };
|
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(sequenceAddress, TSConfigRelationId, objid);
|
ObjectAddressSet(*sequenceAddress, TSConfigRelationId, objid);
|
||||||
return sequenceAddress;
|
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
|
* 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.
|
* in edgecases will be raised by postgres while executing the move.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterTextSearchDictionarySchemaStmtObjectAddress(Node *node, bool missing_ok)
|
AlterTextSearchDictionarySchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
|
@ -776,9 +776,9 @@ AlterTextSearchDictionarySchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress sequenceAddress = { 0 };
|
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(sequenceAddress, TSDictionaryRelationId, objid);
|
ObjectAddressSet(*sequenceAddress, TSDictionaryRelationId, objid);
|
||||||
return sequenceAddress;
|
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
|
* 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.
|
* configuration does not exist based on the missing_ok flag passed in by the caller.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
TextSearchConfigurationCommentObjectAddress(Node *node, bool missing_ok)
|
TextSearchConfigurationCommentObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
CommentStmt *stmt = castNode(CommentStmt, node);
|
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);
|
Oid objid = get_ts_config_oid(castNode(List, stmt->object), missing_ok);
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TSConfigRelationId, objid);
|
ObjectAddressSet(*address, TSConfigRelationId, objid);
|
||||||
return address;
|
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
|
* 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.
|
* exist based on the missing_ok flag passed in by the caller.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
TextSearchDictCommentObjectAddress(Node *node, bool missing_ok)
|
TextSearchDictCommentObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
CommentStmt *stmt = castNode(CommentStmt, node);
|
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);
|
Oid objid = get_ts_dict_oid(castNode(List, stmt->object), missing_ok);
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TSDictionaryRelationId, objid);
|
ObjectAddressSet(*address, TSDictionaryRelationId, objid);
|
||||||
return address;
|
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
|
* 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.
|
* configuration does not exist based on the missing_ok flag passed in by the caller.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterTextSearchConfigurationOwnerObjectAddress(Node *node, bool missing_ok)
|
AlterTextSearchConfigurationOwnerObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
|
@ -833,8 +833,14 @@ AlterTextSearchConfigurationOwnerObjectAddress(Node *node, bool missing_ok)
|
||||||
|
|
||||||
Assert(stmt->objectType == OBJECT_TSCONFIGURATION);
|
Assert(stmt->objectType == OBJECT_TSCONFIGURATION);
|
||||||
|
|
||||||
return get_object_address(stmt->objectType, stmt->object, &relation, AccessShareLock,
|
ObjectAddress objectAddress = get_object_address(stmt->objectType, stmt->object,
|
||||||
|
&relation, AccessShareLock,
|
||||||
missing_ok);
|
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
|
* 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.
|
* configuration does not exist based on the missing_ok flag passed in by the caller.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterTextSearchDictOwnerObjectAddress(Node *node, bool missing_ok)
|
AlterTextSearchDictOwnerObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
Relation relation = NULL;
|
Relation relation = NULL;
|
||||||
|
|
||||||
Assert(stmt->objectType == OBJECT_TSDICTIONARY);
|
Assert(stmt->objectType == OBJECT_TSDICTIONARY);
|
||||||
|
ObjectAddress objectAddress = get_object_address(stmt->objectType, stmt->object,
|
||||||
return get_object_address(stmt->objectType, stmt->object, &relation, AccessShareLock,
|
&relation, AccessShareLock,
|
||||||
missing_ok);
|
missing_ok);
|
||||||
|
ObjectAddress *objectAddressCopy = palloc0(sizeof(ObjectAddress));
|
||||||
|
*objectAddressCopy = objectAddress;
|
||||||
|
|
||||||
|
return list_make1(objectAddressCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -224,8 +224,12 @@ PostprocessCreateTriggerStmt(Node *node, const char *queryString)
|
||||||
EnsureCoordinator();
|
EnsureCoordinator();
|
||||||
ErrorOutForTriggerIfNotSupported(relationId);
|
ErrorOutForTriggerIfNotSupported(relationId);
|
||||||
|
|
||||||
ObjectAddress objectAddress = GetObjectAddressFromParseTree(node, missingOk);
|
List *objectAddresses = GetObjectAddressListFromParseTree(node, missingOk);
|
||||||
EnsureDependenciesExistOnAllNodes(&objectAddress);
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(objectAddresses) == 1);
|
||||||
|
|
||||||
|
EnsureAllObjectDependenciesExistOnAllNodes(objectAddresses);
|
||||||
|
|
||||||
char *triggerName = createTriggerStmt->trigname;
|
char *triggerName = createTriggerStmt->trigname;
|
||||||
return CitusCreateTriggerCommandDDLJob(relationId, triggerName,
|
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
|
* Never returns NULL, but the objid in the address can be invalid if missingOk
|
||||||
* was set to true.
|
* was set to true.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
CreateTriggerStmtObjectAddress(Node *node, bool missingOk)
|
CreateTriggerStmtObjectAddress(Node *node, bool missingOk)
|
||||||
{
|
{
|
||||||
CreateTrigStmt *createTriggerStmt = castNode(CreateTrigStmt, node);
|
CreateTrigStmt *createTriggerStmt = castNode(CreateTrigStmt, node);
|
||||||
|
@ -260,9 +264,9 @@ CreateTriggerStmtObjectAddress(Node *node, bool missingOk)
|
||||||
triggerName, relationName)));
|
triggerName, relationName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TriggerRelationId, triggerId);
|
ObjectAddressSet(*address, TriggerRelationId, triggerId);
|
||||||
return address;
|
return list_make1(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -117,8 +117,12 @@ PreprocessRenameTypeAttributeStmt(Node *node, const char *queryString,
|
||||||
Assert(stmt->renameType == OBJECT_ATTRIBUTE);
|
Assert(stmt->renameType == OBJECT_ATTRIBUTE);
|
||||||
Assert(stmt->relationType == OBJECT_TYPE);
|
Assert(stmt->relationType == OBJECT_TYPE);
|
||||||
|
|
||||||
ObjectAddress typeAddress = GetObjectAddressFromParseTree((Node *) stmt, false);
|
List *typeAddresses = GetObjectAddressListFromParseTree((Node *) stmt, false);
|
||||||
if (!ShouldPropagateObject(&typeAddress))
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(typeAddresses) == 1);
|
||||||
|
|
||||||
|
if (!ShouldPropagateAnyObject(typeAddresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
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
|
* Never returns NULL, but the objid in the address could be invalid if missing_ok was set
|
||||||
* to true.
|
* to true.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
CompositeTypeStmtObjectAddress(Node *node, bool missing_ok)
|
CompositeTypeStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
CompositeTypeStmt *stmt = castNode(CompositeTypeStmt, node);
|
CompositeTypeStmt *stmt = castNode(CompositeTypeStmt, node);
|
||||||
TypeName *typeName = MakeTypeNameFromRangeVar(stmt->typevar);
|
TypeName *typeName = MakeTypeNameFromRangeVar(stmt->typevar);
|
||||||
Oid typeOid = LookupNonAssociatedArrayTypeNameOid(NULL, typeName, missing_ok);
|
Oid typeOid = LookupNonAssociatedArrayTypeNameOid(NULL, typeName, missing_ok);
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TypeRelationId, typeOid);
|
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
|
* Never returns NULL, but the objid in the address could be invalid if missing_ok was set
|
||||||
* to true.
|
* to true.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
CreateEnumStmtObjectAddress(Node *node, bool missing_ok)
|
CreateEnumStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
CreateEnumStmt *stmt = castNode(CreateEnumStmt, node);
|
CreateEnumStmt *stmt = castNode(CreateEnumStmt, node);
|
||||||
TypeName *typeName = makeTypeNameFromNameList(stmt->typeName);
|
TypeName *typeName = makeTypeNameFromNameList(stmt->typeName);
|
||||||
Oid typeOid = LookupNonAssociatedArrayTypeNameOid(NULL, typeName, missing_ok);
|
Oid typeOid = LookupNonAssociatedArrayTypeNameOid(NULL, typeName, missing_ok);
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TypeRelationId, typeOid);
|
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
|
* Never returns NULL, but the objid in the address could be invalid if missing_ok was set
|
||||||
* to true.
|
* to true.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterTypeStmtObjectAddress(Node *node, bool missing_ok)
|
AlterTypeStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
||||||
|
@ -350,10 +354,10 @@ AlterTypeStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
|
|
||||||
TypeName *typeName = MakeTypeNameFromRangeVar(stmt->relation);
|
TypeName *typeName = MakeTypeNameFromRangeVar(stmt->relation);
|
||||||
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TypeRelationId, typeOid);
|
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
|
* AlterEnumStmtObjectAddress return the ObjectAddress of the enum type that is the
|
||||||
* object of the AlterEnumStmt. Errors is missing_ok is false.
|
* object of the AlterEnumStmt. Errors is missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterEnumStmtObjectAddress(Node *node, bool missing_ok)
|
AlterEnumStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterEnumStmt *stmt = castNode(AlterEnumStmt, node);
|
AlterEnumStmt *stmt = castNode(AlterEnumStmt, node);
|
||||||
TypeName *typeName = makeTypeNameFromNameList(stmt->typeName);
|
TypeName *typeName = makeTypeNameFromNameList(stmt->typeName);
|
||||||
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TypeRelationId, typeOid);
|
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
|
* RenameTypeStmtObjectAddress returns the ObjectAddress of the type that is the object
|
||||||
* of the RenameStmt. Errors if missing_ok is false.
|
* of the RenameStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
RenameTypeStmtObjectAddress(Node *node, bool missing_ok)
|
RenameTypeStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
RenameStmt *stmt = castNode(RenameStmt, node);
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
|
@ -386,10 +390,10 @@ RenameTypeStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
|
|
||||||
TypeName *typeName = makeTypeNameFromNameList((List *) stmt->object);
|
TypeName *typeName = makeTypeNameFromNameList((List *) stmt->object);
|
||||||
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TypeRelationId, typeOid);
|
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
|
* new schema. Errors if missing_ok is false and the type cannot be found in either of the
|
||||||
* schemas.
|
* schemas.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterTypeSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
AlterTypeSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
|
@ -447,10 +451,10 @@ AlterTypeSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TypeRelationId, typeOid);
|
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
|
* changed as Attributes are not distributed on their own but as a side effect of the
|
||||||
* whole type distribution.
|
* whole type distribution.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
RenameTypeAttributeStmtObjectAddress(Node *node, bool missing_ok)
|
RenameTypeAttributeStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
RenameStmt *stmt = castNode(RenameStmt, node);
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
|
@ -471,10 +475,10 @@ RenameTypeAttributeStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
|
|
||||||
TypeName *typeName = MakeTypeNameFromRangeVar(stmt->relation);
|
TypeName *typeName = MakeTypeNameFromRangeVar(stmt->relation);
|
||||||
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TypeRelationId, typeOid);
|
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
|
* AlterTypeOwnerObjectAddress returns the ObjectAddress of the type that is the object
|
||||||
* of the AlterOwnerStmt. Errors if missing_ok is false.
|
* of the AlterOwnerStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterTypeOwnerObjectAddress(Node *node, bool missing_ok)
|
AlterTypeOwnerObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node);
|
||||||
|
@ -490,10 +494,10 @@ AlterTypeOwnerObjectAddress(Node *node, bool missing_ok)
|
||||||
|
|
||||||
TypeName *typeName = makeTypeNameFromNameList((List *) stmt->object);
|
TypeName *typeName = makeTypeNameFromNameList((List *) stmt->object);
|
||||||
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
Oid typeOid = LookupTypeNameOid(NULL, typeName, missing_ok);
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(address, TypeRelationId, typeOid);
|
ObjectAddressSet(*address, TypeRelationId, typeOid);
|
||||||
|
|
||||||
return address;
|
return list_make1(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -853,8 +853,12 @@ ProcessUtilityInternal(PlannedStmt *pstmt,
|
||||||
*/
|
*/
|
||||||
if (ops && ops->markDistributed)
|
if (ops && ops->markDistributed)
|
||||||
{
|
{
|
||||||
ObjectAddress address = GetObjectAddressFromParseTree(parsetree, false);
|
List *addresses = GetObjectAddressListFromParseTree(parsetree, false);
|
||||||
MarkObjectDistributed(&address);
|
ObjectAddress *address = NULL;
|
||||||
|
foreach_ptr(address, addresses)
|
||||||
|
{
|
||||||
|
MarkObjectDistributed(address);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,10 +41,7 @@ typedef struct CitusVacuumParams
|
||||||
int options;
|
int options;
|
||||||
VacOptValue truncate;
|
VacOptValue truncate;
|
||||||
VacOptValue index_cleanup;
|
VacOptValue index_cleanup;
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
int nworkers;
|
int nworkers;
|
||||||
#endif
|
|
||||||
} CitusVacuumParams;
|
} CitusVacuumParams;
|
||||||
|
|
||||||
/* Local functions forward declarations for processing distributed table commands */
|
/* Local functions forward declarations for processing distributed table commands */
|
||||||
|
@ -323,10 +320,8 @@ DeparseVacuumStmtPrefix(CitusVacuumParams vacuumParams)
|
||||||
/* if no flags remain, exit early */
|
/* if no flags remain, exit early */
|
||||||
if (vacuumFlags == 0 &&
|
if (vacuumFlags == 0 &&
|
||||||
vacuumParams.truncate == VACOPTVALUE_UNSPECIFIED &&
|
vacuumParams.truncate == VACOPTVALUE_UNSPECIFIED &&
|
||||||
vacuumParams.index_cleanup == VACOPTVALUE_UNSPECIFIED
|
vacuumParams.index_cleanup == VACOPTVALUE_UNSPECIFIED &&
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
vacuumParams.nworkers == VACUUM_PARALLEL_NOTSET
|
||||||
&& vacuumParams.nworkers == VACUUM_PARALLEL_NOTSET
|
|
||||||
#endif
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return vacuumPrefix->data;
|
return vacuumPrefix->data;
|
||||||
|
@ -409,12 +404,10 @@ DeparseVacuumStmtPrefix(CitusVacuumParams vacuumParams)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
if (vacuumParams.nworkers != VACUUM_PARALLEL_NOTSET)
|
if (vacuumParams.nworkers != VACUUM_PARALLEL_NOTSET)
|
||||||
{
|
{
|
||||||
appendStringInfo(vacuumPrefix, "PARALLEL %d,", vacuumParams.nworkers);
|
appendStringInfo(vacuumPrefix, "PARALLEL %d,", vacuumParams.nworkers);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
vacuumPrefix->data[vacuumPrefix->len - 1] = ')';
|
vacuumPrefix->data[vacuumPrefix->len - 1] = ')';
|
||||||
|
|
||||||
|
@ -515,9 +508,7 @@ VacuumStmtParams(VacuumStmt *vacstmt)
|
||||||
/* Set default value */
|
/* Set default value */
|
||||||
params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
|
params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
|
||||||
params.truncate = VACOPTVALUE_UNSPECIFIED;
|
params.truncate = VACOPTVALUE_UNSPECIFIED;
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
params.nworkers = VACUUM_PARALLEL_NOTSET;
|
params.nworkers = VACUUM_PARALLEL_NOTSET;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Parse options list */
|
/* Parse options list */
|
||||||
DefElem *opt = NULL;
|
DefElem *opt = NULL;
|
||||||
|
@ -596,7 +587,6 @@ VacuumStmtParams(VacuumStmt *vacstmt)
|
||||||
params.truncate = defGetBoolean(opt) ? VACOPTVALUE_ENABLED :
|
params.truncate = defGetBoolean(opt) ? VACOPTVALUE_ENABLED :
|
||||||
VACOPTVALUE_DISABLED;
|
VACOPTVALUE_DISABLED;
|
||||||
}
|
}
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
else if (strcmp(opt->defname, "parallel") == 0)
|
else if (strcmp(opt->defname, "parallel") == 0)
|
||||||
{
|
{
|
||||||
if (opt->arg == NULL)
|
if (opt->arg == NULL)
|
||||||
|
@ -620,7 +610,6 @@ VacuumStmtParams(VacuumStmt *vacstmt)
|
||||||
params.nworkers = nworkers;
|
params.nworkers = nworkers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
|
|
|
@ -94,22 +94,27 @@ PostprocessViewStmt(Node *node, const char *queryString)
|
||||||
return NIL;
|
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;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the view has any unsupported dependency, create it locally */
|
/* If the view has any unsupported dependency, create it locally */
|
||||||
if (ErrorOrWarnIfObjectHasUnsupportedDependency(&viewAddress))
|
if (ErrorOrWarnIfAnyObjectHasUnsupportedDependency(viewAddresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
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,
|
* 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 *ddlJob = palloc0(sizeof(DDLJob));
|
||||||
ddlJob->targetObjectAddress = viewAddress;
|
ddlJob->targetObjectAddress = *viewAddress;
|
||||||
ddlJob->metadataSyncCommand = command;
|
ddlJob->metadataSyncCommand = command;
|
||||||
ddlJob->taskList = NIL;
|
ddlJob->taskList = NIL;
|
||||||
|
|
||||||
|
@ -152,17 +157,17 @@ PostprocessViewStmt(Node *node, const char *queryString)
|
||||||
* ViewStmtObjectAddress returns the ObjectAddress for the subject of the
|
* ViewStmtObjectAddress returns the ObjectAddress for the subject of the
|
||||||
* CREATE [OR REPLACE] VIEW statement.
|
* CREATE [OR REPLACE] VIEW statement.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
ViewStmtObjectAddress(Node *node, bool missing_ok)
|
ViewStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
ViewStmt *stmt = castNode(ViewStmt, node);
|
ViewStmt *stmt = castNode(ViewStmt, node);
|
||||||
|
|
||||||
Oid viewOid = RangeVarGetRelid(stmt->view, NoLock, missing_ok);
|
Oid viewOid = RangeVarGetRelid(stmt->view, NoLock, missing_ok);
|
||||||
|
|
||||||
ObjectAddress viewAddress = { 0 };
|
ObjectAddress *viewAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(viewAddress, RelationRelationId, viewOid);
|
ObjectAddressSet(*viewAddress, RelationRelationId, viewOid);
|
||||||
|
|
||||||
return viewAddress;
|
return list_make1(viewAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -442,10 +447,9 @@ IsViewDistributed(Oid viewOid)
|
||||||
Assert(get_rel_relkind(viewOid) == RELKIND_VIEW ||
|
Assert(get_rel_relkind(viewOid) == RELKIND_VIEW ||
|
||||||
get_rel_relkind(viewOid) == RELKIND_MATVIEW);
|
get_rel_relkind(viewOid) == RELKIND_MATVIEW);
|
||||||
|
|
||||||
ObjectAddress viewAddress = { 0 };
|
ObjectAddress *viewAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(viewAddress, RelationRelationId, viewOid);
|
ObjectAddressSet(*viewAddress, RelationRelationId, viewOid);
|
||||||
|
return IsAnyObjectDistributed(list_make1(viewAddress));
|
||||||
return IsObjectDistributed(&viewAddress);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -458,8 +462,12 @@ PreprocessAlterViewStmt(Node *node, const char *queryString, ProcessUtilityConte
|
||||||
{
|
{
|
||||||
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
||||||
|
|
||||||
ObjectAddress viewAddress = GetObjectAddressFromParseTree((Node *) stmt, true);
|
List *viewAddresses = GetObjectAddressListFromParseTree((Node *) stmt, true);
|
||||||
if (!ShouldPropagateObject(&viewAddress))
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(viewAddresses) == 1);
|
||||||
|
|
||||||
|
if (!ShouldPropagateAnyObject(viewAddresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -471,12 +479,15 @@ PreprocessAlterViewStmt(Node *node, const char *queryString, ProcessUtilityConte
|
||||||
/* reconstruct alter statement in a portable fashion */
|
/* reconstruct alter statement in a portable fashion */
|
||||||
const char *alterViewStmtSql = DeparseTreeNode((Node *) stmt);
|
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
|
* To avoid sequential mode, we are using metadata connection. For the
|
||||||
* detailed explanation, please check the comment on PostprocessViewStmt.
|
* detailed explanation, please check the comment on PostprocessViewStmt.
|
||||||
*/
|
*/
|
||||||
DDLJob *ddlJob = palloc0(sizeof(DDLJob));
|
DDLJob *ddlJob = palloc0(sizeof(DDLJob));
|
||||||
ddlJob->targetObjectAddress = viewAddress;
|
ddlJob->targetObjectAddress = *viewAddress;
|
||||||
ddlJob->metadataSyncCommand = alterViewStmtSql;
|
ddlJob->metadataSyncCommand = alterViewStmtSql;
|
||||||
ddlJob->taskList = NIL;
|
ddlJob->taskList = NIL;
|
||||||
|
|
||||||
|
@ -493,24 +504,28 @@ PostprocessAlterViewStmt(Node *node, const char *queryString)
|
||||||
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
||||||
Assert(AlterTableStmtObjType_compat(stmt) == OBJECT_VIEW);
|
Assert(AlterTableStmtObjType_compat(stmt) == OBJECT_VIEW);
|
||||||
|
|
||||||
ObjectAddress viewAddress = GetObjectAddressFromParseTree((Node *) stmt, true);
|
List *viewAddresses = GetObjectAddressListFromParseTree((Node *) stmt, true);
|
||||||
if (!ShouldPropagateObject(&viewAddress))
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(viewAddresses) == 1);
|
||||||
|
|
||||||
|
if (!ShouldPropagateAnyObject(viewAddresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsObjectAddressOwnedByExtension(&viewAddress, NULL))
|
if (IsAnyObjectAddressOwnedByExtension(viewAddresses, NULL))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the view has any unsupported dependency, create it locally */
|
/* If the view has any unsupported dependency, create it locally */
|
||||||
if (ErrorOrWarnIfObjectHasUnsupportedDependency(&viewAddress))
|
if (ErrorOrWarnIfAnyObjectHasUnsupportedDependency(viewAddresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnsureDependenciesExistOnAllNodes(&viewAddress);
|
EnsureAllObjectDependenciesExistOnAllNodes(viewAddresses);
|
||||||
|
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -520,16 +535,16 @@ PostprocessAlterViewStmt(Node *node, const char *queryString)
|
||||||
* AlterViewStmtObjectAddress returns the ObjectAddress for the subject of the
|
* AlterViewStmtObjectAddress returns the ObjectAddress for the subject of the
|
||||||
* ALTER VIEW statement.
|
* ALTER VIEW statement.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterViewStmtObjectAddress(Node *node, bool missing_ok)
|
AlterViewStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
AlterTableStmt *stmt = castNode(AlterTableStmt, node);
|
||||||
Oid viewOid = RangeVarGetRelid(stmt->relation, NoLock, missing_ok);
|
Oid viewOid = RangeVarGetRelid(stmt->relation, NoLock, missing_ok);
|
||||||
|
|
||||||
ObjectAddress viewAddress = { 0 };
|
ObjectAddress *viewAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(viewAddress, RelationRelationId, viewOid);
|
ObjectAddressSet(*viewAddress, RelationRelationId, viewOid);
|
||||||
|
|
||||||
return viewAddress;
|
return list_make1(viewAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -541,8 +556,12 @@ List *
|
||||||
PreprocessRenameViewStmt(Node *node, const char *queryString,
|
PreprocessRenameViewStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext)
|
ProcessUtilityContext processUtilityContext)
|
||||||
{
|
{
|
||||||
ObjectAddress viewAddress = GetObjectAddressFromParseTree(node, true);
|
List *viewAddresses = GetObjectAddressListFromParseTree(node, true);
|
||||||
if (!ShouldPropagateObject(&viewAddress))
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(viewAddresses) == 1);
|
||||||
|
|
||||||
|
if (!ShouldPropagateAnyObject(viewAddresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -555,12 +574,15 @@ PreprocessRenameViewStmt(Node *node, const char *queryString,
|
||||||
/* deparse sql*/
|
/* deparse sql*/
|
||||||
const char *renameStmtSql = DeparseTreeNode(node);
|
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
|
* To avoid sequential mode, we are using metadata connection. For the
|
||||||
* detailed explanation, please check the comment on PostprocessViewStmt.
|
* detailed explanation, please check the comment on PostprocessViewStmt.
|
||||||
*/
|
*/
|
||||||
DDLJob *ddlJob = palloc0(sizeof(DDLJob));
|
DDLJob *ddlJob = palloc0(sizeof(DDLJob));
|
||||||
ddlJob->targetObjectAddress = viewAddress;
|
ddlJob->targetObjectAddress = *viewAddress;
|
||||||
ddlJob->metadataSyncCommand = renameStmtSql;
|
ddlJob->metadataSyncCommand = renameStmtSql;
|
||||||
ddlJob->taskList = NIL;
|
ddlJob->taskList = NIL;
|
||||||
|
|
||||||
|
@ -572,17 +594,17 @@ PreprocessRenameViewStmt(Node *node, const char *queryString,
|
||||||
* RenameViewStmtObjectAddress returns the ObjectAddress of the view that is the object
|
* RenameViewStmtObjectAddress returns the ObjectAddress of the view that is the object
|
||||||
* of the RenameStmt. Errors if missing_ok is false.
|
* of the RenameStmt. Errors if missing_ok is false.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
RenameViewStmtObjectAddress(Node *node, bool missing_ok)
|
RenameViewStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
RenameStmt *stmt = castNode(RenameStmt, node);
|
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||||
|
|
||||||
Oid viewOid = RangeVarGetRelid(stmt->relation, NoLock, missing_ok);
|
Oid viewOid = RangeVarGetRelid(stmt->relation, NoLock, missing_ok);
|
||||||
|
|
||||||
ObjectAddress viewAddress = { 0 };
|
ObjectAddress *viewAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(viewAddress, RelationRelationId, viewOid);
|
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);
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
|
|
||||||
ObjectAddress viewAddress = GetObjectAddressFromParseTree((Node *) stmt, true);
|
List *viewAddresses = GetObjectAddressListFromParseTree((Node *) stmt, true);
|
||||||
if (!ShouldPropagateObject(&viewAddress))
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(viewAddresses) == 1);
|
||||||
|
|
||||||
|
if (!ShouldPropagateAnyObject(viewAddresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -608,12 +634,15 @@ PreprocessAlterViewSchemaStmt(Node *node, const char *queryString,
|
||||||
|
|
||||||
const char *sql = DeparseTreeNode((Node *) stmt);
|
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
|
* To avoid sequential mode, we are using metadata connection. For the
|
||||||
* detailed explanation, please check the comment on PostprocessViewStmt.
|
* detailed explanation, please check the comment on PostprocessViewStmt.
|
||||||
*/
|
*/
|
||||||
DDLJob *ddlJob = palloc0(sizeof(DDLJob));
|
DDLJob *ddlJob = palloc0(sizeof(DDLJob));
|
||||||
ddlJob->targetObjectAddress = viewAddress;
|
ddlJob->targetObjectAddress = *viewAddress;
|
||||||
ddlJob->metadataSyncCommand = sql;
|
ddlJob->metadataSyncCommand = sql;
|
||||||
ddlJob->taskList = NIL;
|
ddlJob->taskList = NIL;
|
||||||
|
|
||||||
|
@ -631,14 +660,18 @@ PostprocessAlterViewSchemaStmt(Node *node, const char *queryString)
|
||||||
{
|
{
|
||||||
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
|
|
||||||
ObjectAddress viewAddress = GetObjectAddressFromParseTree((Node *) stmt, true);
|
List *viewAddresses = GetObjectAddressListFromParseTree((Node *) stmt, true);
|
||||||
if (!ShouldPropagateObject(&viewAddress))
|
|
||||||
|
/* the code-path only supports a single object */
|
||||||
|
Assert(list_length(viewAddresses) == 1);
|
||||||
|
|
||||||
|
if (!ShouldPropagateAnyObject(viewAddresses))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dependencies have changed (schema) let's ensure they exist */
|
/* dependencies have changed (schema) let's ensure they exist */
|
||||||
EnsureDependenciesExistOnAllNodes(&viewAddress);
|
EnsureAllObjectDependenciesExistOnAllNodes(viewAddresses);
|
||||||
|
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -648,7 +681,7 @@ PostprocessAlterViewSchemaStmt(Node *node, const char *queryString)
|
||||||
* AlterViewSchemaStmtObjectAddress returns the ObjectAddress of the view that is the object
|
* AlterViewSchemaStmtObjectAddress returns the ObjectAddress of the view that is the object
|
||||||
* of the alter schema statement.
|
* of the alter schema statement.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
AlterViewSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
AlterViewSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
AlterObjectSchemaStmt *stmt = castNode(AlterObjectSchemaStmt, node);
|
||||||
|
@ -676,10 +709,10 @@ AlterViewSchemaStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress viewAddress = { 0 };
|
ObjectAddress *viewAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(viewAddress, RelationRelationId, viewOid);
|
ObjectAddressSet(*viewAddress, RelationRelationId, viewOid);
|
||||||
|
|
||||||
return viewAddress;
|
return list_make1(viewAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -462,7 +462,7 @@ GetEffectiveConnKey(ConnectionHashKey *key)
|
||||||
}
|
}
|
||||||
else if (strcmp(option->keyword, "port") == 0)
|
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)
|
else if (strcmp(option->keyword, "dbname") == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,11 +48,7 @@
|
||||||
#include "distributed/tuplestore.h"
|
#include "distributed/tuplestore.h"
|
||||||
#include "distributed/worker_manager.h"
|
#include "distributed/worker_manager.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#if PG_VERSION_NUM < PG_VERSION_13
|
|
||||||
#include "utils/hashutils.h"
|
|
||||||
#else
|
|
||||||
#include "common/hashfn.h"
|
#include "common/hashfn.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define RESERVED_CONNECTION_COLUMNS 4
|
#define RESERVED_CONNECTION_COLUMNS 4
|
||||||
|
|
|
@ -26,9 +26,7 @@
|
||||||
#include "distributed/placement_connection.h"
|
#include "distributed/placement_connection.h"
|
||||||
#include "distributed/relation_access_tracking.h"
|
#include "distributed/relation_access_tracking.h"
|
||||||
#include "utils/hsearch.h"
|
#include "utils/hsearch.h"
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
#include "common/hashfn.h"
|
#include "common/hashfn.h"
|
||||||
#endif
|
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,12 +36,7 @@
|
||||||
#include "distributed/time_constants.h"
|
#include "distributed/time_constants.h"
|
||||||
#include "distributed/tuplestore.h"
|
#include "distributed/tuplestore.h"
|
||||||
#include "utils/builtins.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"
|
#include "common/hashfn.h"
|
||||||
#endif
|
|
||||||
#include "storage/ipc.h"
|
#include "storage/ipc.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -123,8 +118,6 @@ static void StoreAllRemoteConnectionStats(Tuplestorestate *tupleStore, TupleDesc
|
||||||
tupleDescriptor);
|
tupleDescriptor);
|
||||||
static void LockConnectionSharedMemory(LWLockMode lockMode);
|
static void LockConnectionSharedMemory(LWLockMode lockMode);
|
||||||
static void UnLockConnectionSharedMemory(void);
|
static void UnLockConnectionSharedMemory(void);
|
||||||
static void SharedConnectionStatsShmemInit(void);
|
|
||||||
static size_t SharedConnectionStatsShmemSize(void);
|
|
||||||
static bool ShouldWaitForConnection(int currentConnectionCount);
|
static bool ShouldWaitForConnection(int currentConnectionCount);
|
||||||
static uint32 SharedConnectionHashHash(const void *key, Size keysize);
|
static uint32 SharedConnectionHashHash(const void *key, Size keysize);
|
||||||
static int SharedConnectionHashCompare(const void *a, const void *b, Size keysize);
|
static int SharedConnectionHashCompare(const void *a, const void *b, Size keysize);
|
||||||
|
@ -617,11 +610,15 @@ WaitForSharedConnection(void)
|
||||||
void
|
void
|
||||||
InitializeSharedConnectionStats(void)
|
InitializeSharedConnectionStats(void)
|
||||||
{
|
{
|
||||||
|
/* on PG 15, we use shmem_request_hook_type */
|
||||||
|
#if PG_VERSION_NUM < PG_VERSION_15
|
||||||
|
|
||||||
/* allocate shared memory */
|
/* allocate shared memory */
|
||||||
if (!IsUnderPostmaster)
|
if (!IsUnderPostmaster)
|
||||||
{
|
{
|
||||||
RequestAddinShmemSpace(SharedConnectionStatsShmemSize());
|
RequestAddinShmemSpace(SharedConnectionStatsShmemSize());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
prev_shmem_startup_hook = shmem_startup_hook;
|
prev_shmem_startup_hook = shmem_startup_hook;
|
||||||
shmem_startup_hook = SharedConnectionStatsShmemInit;
|
shmem_startup_hook = SharedConnectionStatsShmemInit;
|
||||||
|
@ -632,7 +629,7 @@ InitializeSharedConnectionStats(void)
|
||||||
* SharedConnectionStatsShmemSize returns the size that should be allocated
|
* SharedConnectionStatsShmemSize returns the size that should be allocated
|
||||||
* on the shared memory for shared connection stats.
|
* on the shared memory for shared connection stats.
|
||||||
*/
|
*/
|
||||||
static size_t
|
size_t
|
||||||
SharedConnectionStatsShmemSize(void)
|
SharedConnectionStatsShmemSize(void)
|
||||||
{
|
{
|
||||||
Size size = 0;
|
Size size = 0;
|
||||||
|
@ -652,7 +649,7 @@ SharedConnectionStatsShmemSize(void)
|
||||||
* SharedConnectionStatsShmemInit initializes the shared memory used
|
* SharedConnectionStatsShmemInit initializes the shared memory used
|
||||||
* for keeping track of connection stats across backends.
|
* for keeping track of connection stats across backends.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
SharedConnectionStatsShmemInit(void)
|
SharedConnectionStatsShmemInit(void)
|
||||||
{
|
{
|
||||||
bool alreadyInitialized = false;
|
bool alreadyInitialized = false;
|
||||||
|
|
|
@ -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
|
* access method
|
||||||
*/
|
*/
|
||||||
if (accessMethod)
|
if (accessMethod)
|
||||||
|
@ -999,7 +999,6 @@ deparse_index_columns(StringInfo buffer, List *indexParameterList, List *deparse
|
||||||
appendStringInfo(buffer, "%s ",
|
appendStringInfo(buffer, "%s ",
|
||||||
NameListToQuotedString(indexElement->opclass));
|
NameListToQuotedString(indexElement->opclass));
|
||||||
}
|
}
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
|
|
||||||
/* Commit on postgres: 911e70207703799605f5a0e8aad9f06cff067c63*/
|
/* Commit on postgres: 911e70207703799605f5a0e8aad9f06cff067c63*/
|
||||||
if (indexElement->opclassopts != NIL)
|
if (indexElement->opclassopts != NIL)
|
||||||
|
@ -1008,7 +1007,6 @@ deparse_index_columns(StringInfo buffer, List *indexParameterList, List *deparse
|
||||||
AppendStorageParametersToString(buffer, indexElement->opclassopts);
|
AppendStorageParametersToString(buffer, indexElement->opclassopts);
|
||||||
appendStringInfoString(buffer, ") ");
|
appendStringInfoString(buffer, ") ");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (indexElement->ordering != SORTBY_DEFAULT)
|
if (indexElement->ordering != SORTBY_DEFAULT)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,9 +27,7 @@ static void AppendCreateStatisticsStmt(StringInfo buf, CreateStatsStmt *stmt);
|
||||||
static void AppendDropStatisticsStmt(StringInfo buf, List *nameList, bool ifExists);
|
static void AppendDropStatisticsStmt(StringInfo buf, List *nameList, bool ifExists);
|
||||||
static void AppendAlterStatisticsRenameStmt(StringInfo buf, RenameStmt *stmt);
|
static void AppendAlterStatisticsRenameStmt(StringInfo buf, RenameStmt *stmt);
|
||||||
static void AppendAlterStatisticsSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt);
|
static void AppendAlterStatisticsSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt);
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
static void AppendAlterStatisticsStmt(StringInfo buf, AlterStatsStmt *stmt);
|
static void AppendAlterStatisticsStmt(StringInfo buf, AlterStatsStmt *stmt);
|
||||||
#endif
|
|
||||||
static void AppendAlterStatisticsOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt);
|
static void AppendAlterStatisticsOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt);
|
||||||
static void AppendStatisticsName(StringInfo buf, CreateStatsStmt *stmt);
|
static void AppendStatisticsName(StringInfo buf, CreateStatsStmt *stmt);
|
||||||
static void AppendStatTypes(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 *
|
char *
|
||||||
DeparseAlterStatisticsStmt(Node *node)
|
DeparseAlterStatisticsStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
@ -105,7 +102,6 @@ DeparseAlterStatisticsStmt(Node *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
char *
|
char *
|
||||||
DeparseAlterStatisticsOwnerStmt(Node *node)
|
DeparseAlterStatisticsOwnerStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
@ -177,7 +173,6 @@ AppendAlterStatisticsSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
static void
|
static void
|
||||||
AppendAlterStatisticsStmt(StringInfo buf, AlterStatsStmt *stmt)
|
AppendAlterStatisticsStmt(StringInfo buf, AlterStatsStmt *stmt)
|
||||||
{
|
{
|
||||||
|
@ -186,7 +181,6 @@ AppendAlterStatisticsStmt(StringInfo buf, AlterStatsStmt *stmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
static void
|
static void
|
||||||
AppendAlterStatisticsOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt)
|
AppendAlterStatisticsOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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.
|
* tree.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
GetObjectAddressFromParseTree(Node *parseTree, bool missing_ok)
|
GetObjectAddressListFromParseTree(Node *parseTree, bool missing_ok)
|
||||||
{
|
{
|
||||||
const DistributeObjectOps *ops = GetDistributeObjectOps(parseTree);
|
const DistributeObjectOps *ops = GetDistributeObjectOps(parseTree);
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ GetObjectAddressFromParseTree(Node *parseTree, bool missing_ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ObjectAddress
|
List *
|
||||||
RenameAttributeStmtObjectAddress(Node *node, bool missing_ok)
|
RenameAttributeStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
RenameStmt *stmt = castNode(RenameStmt, node);
|
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
|
* Never returns NULL, but the objid in the address could be invalid if missing_ok was set
|
||||||
* to true.
|
* to true.
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
List *
|
||||||
CreateExtensionStmtObjectAddress(Node *node, bool missing_ok)
|
CreateExtensionStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
{
|
{
|
||||||
CreateExtensionStmt *stmt = castNode(CreateExtensionStmt, node);
|
CreateExtensionStmt *stmt = castNode(CreateExtensionStmt, node);
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress *address = palloc0(sizeof(ObjectAddress));
|
||||||
|
|
||||||
const char *extensionName = stmt->extname;
|
const char *extensionName = stmt->extname;
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ CreateExtensionStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
extensionName)));
|
extensionName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddressSet(address, ExtensionRelationId, extensionoid);
|
ObjectAddressSet(*address, ExtensionRelationId, extensionoid);
|
||||||
|
|
||||||
return address;
|
return list_make1(address);
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,8 +152,6 @@ QualifyAlterStatisticsSchemaStmt(Node *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* QualifyAlterStatisticsStmt qualifies AlterStatsStmt's with schema name for
|
* QualifyAlterStatisticsStmt qualifies AlterStatsStmt's with schema name for
|
||||||
* ALTER STATISTICS .. SET STATISTICS statements.
|
* ALTER STATISTICS .. SET STATISTICS statements.
|
||||||
|
@ -180,8 +178,6 @@ QualifyAlterStatisticsStmt(Node *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* QualifyAlterStatisticsOwnerStmt qualifies AlterOwnerStmt's with schema
|
* QualifyAlterStatisticsOwnerStmt qualifies AlterOwnerStmt's with schema
|
||||||
* name for ALTER STATISTICS .. OWNER TO statements.
|
* name for ALTER STATISTICS .. OWNER TO statements.
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1790,17 +1790,9 @@ AcquireExecutorShardLocksForExecution(DistributedExecution *execution)
|
||||||
/* Acquire additional locks for SELECT .. FOR UPDATE on reference tables */
|
/* Acquire additional locks for SELECT .. FOR UPDATE on reference tables */
|
||||||
AcquireExecutorShardLocksForRelationRowLockList(task->relationRowLockList);
|
AcquireExecutorShardLocksForRelationRowLockList(task->relationRowLockList);
|
||||||
|
|
||||||
/*
|
|
||||||
* Due to PG commit 5ee190f8ec37c1bbfb3061e18304e155d600bc8e we copy the
|
|
||||||
* second parameter in pre-13.
|
|
||||||
*/
|
|
||||||
relationRowLockList =
|
relationRowLockList =
|
||||||
list_concat(relationRowLockList,
|
list_concat(relationRowLockList,
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_12) && (PG_VERSION_NUM < PG_VERSION_13)
|
|
||||||
list_copy(task->relationRowLockList));
|
|
||||||
#else
|
|
||||||
task->relationRowLockList);
|
task->relationRowLockList);
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the task has a subselect, then we may need to lock the shards from which
|
* 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
|
* and therefore prevents other modifications from running
|
||||||
* concurrently.
|
* concurrently.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Due to PG commit 5ee190f8ec37c1bbfb3061e18304e155d600bc8e we copy the
|
|
||||||
* second parameter in pre-13.
|
|
||||||
*/
|
|
||||||
requiresConsistentSnapshotRelationShardList =
|
requiresConsistentSnapshotRelationShardList =
|
||||||
list_concat(requiresConsistentSnapshotRelationShardList,
|
list_concat(requiresConsistentSnapshotRelationShardList,
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_12) && (PG_VERSION_NUM < PG_VERSION_13)
|
|
||||||
|
|
||||||
list_copy(task->relationShardList));
|
|
||||||
#else
|
|
||||||
task->relationShardList);
|
task->relationShardList);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,6 @@
|
||||||
#define STICKY_DECREASE_FACTOR (0.50) /* factor for sticky entries */
|
#define STICKY_DECREASE_FACTOR (0.50) /* factor for sticky entries */
|
||||||
#define USAGE_DEALLOC_PERCENT 5 /* free this % of entries at once */
|
#define USAGE_DEALLOC_PERCENT 5 /* free this % of entries at once */
|
||||||
#define USAGE_INIT (1.0) /* including initial planning */
|
#define USAGE_INIT (1.0) /* including initial planning */
|
||||||
#define STATS_SHARED_MEM_NAME "citus_query_stats"
|
|
||||||
|
|
||||||
#define MAX_KEY_LENGTH NAMEDATALEN
|
#define MAX_KEY_LENGTH NAMEDATALEN
|
||||||
|
|
||||||
|
@ -124,7 +123,6 @@ PG_FUNCTION_INFO_V1(citus_executor_name);
|
||||||
|
|
||||||
static char * CitusExecutorName(MultiExecutorType executorType);
|
static char * CitusExecutorName(MultiExecutorType executorType);
|
||||||
|
|
||||||
static Size CitusQueryStatsSharedMemSize(void);
|
|
||||||
|
|
||||||
static void CitusQueryStatsShmemStartup(void);
|
static void CitusQueryStatsShmemStartup(void);
|
||||||
static void CitusQueryStatsShmemShutdown(int code, Datum arg);
|
static void CitusQueryStatsShmemShutdown(int code, Datum arg);
|
||||||
|
@ -142,11 +140,19 @@ static void CitusQueryStatsRemoveExpiredEntries(HTAB *existingQueryIdHash);
|
||||||
|
|
||||||
void
|
void
|
||||||
InitializeCitusQueryStats(void)
|
InitializeCitusQueryStats(void)
|
||||||
|
{
|
||||||
|
/* on PG 15, we use shmem_request_hook_type */
|
||||||
|
#if PG_VERSION_NUM < PG_VERSION_15
|
||||||
|
|
||||||
|
/* allocate shared memory */
|
||||||
|
if (!IsUnderPostmaster)
|
||||||
{
|
{
|
||||||
RequestAddinShmemSpace(CitusQueryStatsSharedMemSize());
|
RequestAddinShmemSpace(CitusQueryStatsSharedMemSize());
|
||||||
|
|
||||||
elog(LOG, "requesting named LWLockTranch for %s", STATS_SHARED_MEM_NAME);
|
elog(LOG, "requesting named LWLockTranch for %s", STATS_SHARED_MEM_NAME);
|
||||||
RequestNamedLWLockTranche(STATS_SHARED_MEM_NAME, 1);
|
RequestNamedLWLockTranche(STATS_SHARED_MEM_NAME, 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Install hook */
|
/* Install hook */
|
||||||
prev_shmem_startup_hook = shmem_startup_hook;
|
prev_shmem_startup_hook = shmem_startup_hook;
|
||||||
|
@ -373,7 +379,7 @@ error:
|
||||||
* CitusQueryStatsSharedMemSize calculates and returns shared memory size
|
* CitusQueryStatsSharedMemSize calculates and returns shared memory size
|
||||||
* required to keep query statistics.
|
* required to keep query statistics.
|
||||||
*/
|
*/
|
||||||
static Size
|
Size
|
||||||
CitusQueryStatsSharedMemSize(void)
|
CitusQueryStatsSharedMemSize(void)
|
||||||
{
|
{
|
||||||
Assert(StatStatementsMax >= 0);
|
Assert(StatStatementsMax >= 0);
|
||||||
|
@ -947,7 +953,7 @@ GetPGStatStatementsMax(void)
|
||||||
*/
|
*/
|
||||||
if (pgssMax)
|
if (pgssMax)
|
||||||
{
|
{
|
||||||
maxValue = pg_atoi(pgssMax, 4, 0);
|
maxValue = pg_strtoint32(pgssMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
return maxValue;
|
return maxValue;
|
||||||
|
|
|
@ -34,9 +34,7 @@
|
||||||
#include "catalog/pg_rewrite_d.h"
|
#include "catalog/pg_rewrite_d.h"
|
||||||
#include "catalog/pg_shdepend.h"
|
#include "catalog/pg_shdepend.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
#include "common/hashfn.h"
|
#include "common/hashfn.h"
|
||||||
#endif
|
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
|
@ -137,6 +135,8 @@ static DependencyDefinition * CreateObjectAddressDependencyDef(Oid classId, Oid
|
||||||
static List * GetTypeConstraintDependencyDefinition(Oid typeId);
|
static List * GetTypeConstraintDependencyDefinition(Oid typeId);
|
||||||
static List * CreateObjectAddressDependencyDefList(Oid classId, List *objectIdList);
|
static List * CreateObjectAddressDependencyDefList(Oid classId, List *objectIdList);
|
||||||
static ObjectAddress DependencyDefinitionObjectAddress(DependencyDefinition *definition);
|
static ObjectAddress DependencyDefinitionObjectAddress(DependencyDefinition *definition);
|
||||||
|
static DeferredErrorMessage * DeferErrorIfHasUnsupportedDependency(const ObjectAddress *
|
||||||
|
objectAddress);
|
||||||
|
|
||||||
/* forward declarations for functions to interact with the ObjectAddressCollector */
|
/* forward declarations for functions to interact with the ObjectAddressCollector */
|
||||||
static void InitObjectAddressCollector(ObjectAddressCollector *collector);
|
static void InitObjectAddressCollector(ObjectAddressCollector *collector);
|
||||||
|
@ -176,7 +176,10 @@ static List * ExpandCitusSupportedTypes(ObjectAddressCollector *collector,
|
||||||
static List * GetDependentRoleIdsFDW(Oid FDWOid);
|
static List * GetDependentRoleIdsFDW(Oid FDWOid);
|
||||||
static List * ExpandRolesToGroups(Oid roleid);
|
static List * ExpandRolesToGroups(Oid roleid);
|
||||||
static ViewDependencyNode * BuildViewDependencyGraph(Oid relationId, HTAB *nodeMap);
|
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
|
* 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
|
* 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.
|
* (except the cluster doesn't have any node) and return true.
|
||||||
*/
|
*/
|
||||||
bool
|
static bool
|
||||||
ErrorOrWarnIfObjectHasUnsupportedDependency(ObjectAddress *objectAddress)
|
ErrorOrWarnIfObjectHasUnsupportedDependency(const ObjectAddress *objectAddress)
|
||||||
{
|
{
|
||||||
DeferredErrorMessage *errMsg = DeferErrorIfHasUnsupportedDependency(objectAddress);
|
DeferredErrorMessage *errMsg = DeferErrorIfHasUnsupportedDependency(objectAddress);
|
||||||
if (errMsg != NULL)
|
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
|
* is not distributed yet, we can create it locally to not affect user's local
|
||||||
* usage experience.
|
* usage experience.
|
||||||
*/
|
*/
|
||||||
else if (IsObjectDistributed(objectAddress))
|
else if (IsAnyObjectDistributed(list_make1((ObjectAddress *) objectAddress)))
|
||||||
{
|
{
|
||||||
RaiseDeferredError(errMsg, ERROR);
|
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
|
* DeferErrorIfHasUnsupportedDependency returns deferred error message if the given
|
||||||
* object has any undistributable dependency.
|
* object has any undistributable dependency.
|
||||||
*/
|
*/
|
||||||
DeferredErrorMessage *
|
static DeferredErrorMessage *
|
||||||
DeferErrorIfHasUnsupportedDependency(const ObjectAddress *objectAddress)
|
DeferErrorIfHasUnsupportedDependency(const ObjectAddress *objectAddress)
|
||||||
{
|
{
|
||||||
ObjectAddress *undistributableDependency = GetUndistributableDependency(
|
ObjectAddress *undistributableDependency = GetUndistributableDependency(
|
||||||
|
@ -858,7 +881,7 @@ DeferErrorIfHasUnsupportedDependency(const ObjectAddress *objectAddress)
|
||||||
* Otherwise, callers are expected to throw the error returned from this
|
* Otherwise, callers are expected to throw the error returned from this
|
||||||
* function as a hard one by ignoring the detail part.
|
* 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",
|
appendStringInfo(detailInfo, "\"%s\" will be created only locally",
|
||||||
objectDescription);
|
objectDescription);
|
||||||
|
@ -873,7 +896,7 @@ DeferErrorIfHasUnsupportedDependency(const ObjectAddress *objectAddress)
|
||||||
objectDescription,
|
objectDescription,
|
||||||
dependencyDescription);
|
dependencyDescription);
|
||||||
|
|
||||||
if (IsObjectDistributed(objectAddress))
|
if (IsAnyObjectDistributed(list_make1((ObjectAddress *) objectAddress)))
|
||||||
{
|
{
|
||||||
appendStringInfo(hintInfo,
|
appendStringInfo(hintInfo,
|
||||||
"Distribute \"%s\" first to modify \"%s\" on worker nodes",
|
"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
|
* GetUndistributableDependency checks whether object has any non-distributable
|
||||||
* dependency. If any one found, it will be returned.
|
* 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 object is distributed already, ignore it.
|
||||||
*/
|
*/
|
||||||
if (IsObjectDistributed(dependency))
|
if (IsAnyObjectDistributed(list_make1(dependency)))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1015,7 +1060,7 @@ IsTableOwnedByExtension(Oid relationId)
|
||||||
* If extensionAddress is not set to a NULL pointer the function will write the extension
|
* If extensionAddress is not set to a NULL pointer the function will write the extension
|
||||||
* address this function depends on into this location.
|
* address this function depends on into this location.
|
||||||
*/
|
*/
|
||||||
bool
|
static bool
|
||||||
IsObjectAddressOwnedByExtension(const ObjectAddress *target,
|
IsObjectAddressOwnedByExtension(const ObjectAddress *target,
|
||||||
ObjectAddress *extensionAddress)
|
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
|
* FollowNewSupportedDependencies applies filters on pg_depend entries to follow all
|
||||||
* objects which should be distributed before the root object can safely be created.
|
* 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
|
* If the object is already distributed it is not a `new` object that needs to be
|
||||||
* distributed before we create a dependent object
|
* distributed before we create a dependent object
|
||||||
*/
|
*/
|
||||||
if (IsObjectDistributed(&address))
|
ObjectAddress *copyAddress = palloc0(sizeof(ObjectAddress));
|
||||||
|
*copyAddress = address;
|
||||||
|
if (IsAnyObjectDistributed(list_make1(copyAddress)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
static char * CreatePgDistObjectEntryCommand(const ObjectAddress *objectAddress);
|
static char * CreatePgDistObjectEntryCommand(const ObjectAddress *objectAddress);
|
||||||
static int ExecuteCommandAsSuperuser(char *query, int paramCount, Oid *paramTypes,
|
static int ExecuteCommandAsSuperuser(char *query, int paramCount, Oid *paramTypes,
|
||||||
Datum *paramValues);
|
Datum *paramValues);
|
||||||
|
static bool IsObjectDistributed(const ObjectAddress *address);
|
||||||
|
|
||||||
PG_FUNCTION_INFO_V1(citus_unmark_object_distributed);
|
PG_FUNCTION_INFO_V1(citus_unmark_object_distributed);
|
||||||
PG_FUNCTION_INFO_V1(master_unmark_object_distributed);
|
PG_FUNCTION_INFO_V1(master_unmark_object_distributed);
|
||||||
|
@ -240,17 +241,18 @@ ShouldMarkRelationDistributed(Oid relationId)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress relationAddress = { 0 };
|
ObjectAddress *relationAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(relationAddress, RelationRelationId, relationId);
|
ObjectAddressSet(*relationAddress, RelationRelationId, relationId);
|
||||||
|
|
||||||
bool pgObject = (relationId < FirstNormalObjectId);
|
bool pgObject = (relationId < FirstNormalObjectId);
|
||||||
bool isObjectSupported = SupportedDependencyByCitus(&relationAddress);
|
bool isObjectSupported = SupportedDependencyByCitus(relationAddress);
|
||||||
bool ownedByExtension = IsTableOwnedByExtension(relationId);
|
bool ownedByExtension = IsTableOwnedByExtension(relationId);
|
||||||
bool alreadyDistributed = IsObjectDistributed(&relationAddress);
|
bool alreadyDistributed = IsObjectDistributed(relationAddress);
|
||||||
bool hasUnsupportedDependency =
|
bool hasUnsupportedDependency =
|
||||||
DeferErrorIfHasUnsupportedDependency(&relationAddress) != NULL;
|
DeferErrorIfAnyObjectHasUnsupportedDependency(list_make1(relationAddress)) !=
|
||||||
|
NULL;
|
||||||
bool hasCircularDependency =
|
bool hasCircularDependency =
|
||||||
DeferErrorIfCircularDependencyExists(&relationAddress) != NULL;
|
DeferErrorIfCircularDependencyExists(relationAddress) != NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pgObject: Citus never marks pg objects as distributed
|
* 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
|
* IsObjectDistributed returns if the object addressed is already distributed in the
|
||||||
* cluster. This performs a local indexed lookup in pg_dist_object.
|
* cluster. This performs a local indexed lookup in pg_dist_object.
|
||||||
*/
|
*/
|
||||||
bool
|
static bool
|
||||||
IsObjectDistributed(const ObjectAddress *address)
|
IsObjectDistributed(const ObjectAddress *address)
|
||||||
{
|
{
|
||||||
ScanKeyData key[3];
|
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
|
* GetDistributedObjectAddressList returns a list of ObjectAddresses that contains all
|
||||||
* distributed objects as marked in pg_dist_object
|
* distributed objects as marked in pg_dist_object
|
||||||
|
|
|
@ -75,9 +75,7 @@
|
||||||
#include "utils/elog.h"
|
#include "utils/elog.h"
|
||||||
#include "utils/hsearch.h"
|
#include "utils/hsearch.h"
|
||||||
#include "utils/jsonb.h"
|
#include "utils/jsonb.h"
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
#include "common/hashfn.h"
|
#include "common/hashfn.h"
|
||||||
#endif
|
|
||||||
#include "utils/inval.h"
|
#include "utils/inval.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
|
|
|
@ -356,10 +356,9 @@ CreateDependingViewsOnWorkers(Oid relationId)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress viewAddress = { 0 };
|
ObjectAddress *viewAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(viewAddress, RelationRelationId, viewOid);
|
ObjectAddressSet(*viewAddress, RelationRelationId, viewOid);
|
||||||
|
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(viewAddress));
|
||||||
EnsureDependenciesExistOnAllNodes(&viewAddress);
|
|
||||||
|
|
||||||
char *createViewCommand = CreateViewDDLCommand(viewOid);
|
char *createViewCommand = CreateViewDDLCommand(viewOid);
|
||||||
char *alterViewOwnerCommand = AlterViewOwnerCommand(viewOid);
|
char *alterViewOwnerCommand = AlterViewOwnerCommand(viewOid);
|
||||||
|
@ -367,7 +366,7 @@ CreateDependingViewsOnWorkers(Oid relationId)
|
||||||
SendCommandToWorkersWithMetadata(createViewCommand);
|
SendCommandToWorkersWithMetadata(createViewCommand);
|
||||||
SendCommandToWorkersWithMetadata(alterViewOwnerCommand);
|
SendCommandToWorkersWithMetadata(alterViewOwnerCommand);
|
||||||
|
|
||||||
MarkObjectDistributed(&viewAddress);
|
MarkObjectDistributed(viewAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendCommandToWorkersWithMetadata(ENABLE_DDL_PROPAGATION);
|
SendCommandToWorkersWithMetadata(ENABLE_DDL_PROPAGATION);
|
||||||
|
@ -603,10 +602,10 @@ ShouldSyncSequenceMetadata(Oid relationId)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress sequenceAddress = { 0 };
|
ObjectAddress *sequenceAddress = palloc0(sizeof(ObjectAddress));
|
||||||
ObjectAddressSet(sequenceAddress, RelationRelationId, relationId);
|
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
|
* RemoteCollationIdExpression returns an expression in text form that can
|
||||||
* be used to obtain the OID of a type on a different node when included
|
* be used to obtain the OID of a collation on a different node when included
|
||||||
* in a query string. Currently this is a sublink because regcollation type
|
* in a query string.
|
||||||
* is not available in PG12.
|
|
||||||
*/
|
*/
|
||||||
static char *
|
static char *
|
||||||
RemoteCollationIdExpression(Oid colocationId)
|
RemoteCollationIdExpression(Oid colocationId)
|
||||||
|
@ -3826,16 +3824,15 @@ RemoteCollationIdExpression(Oid colocationId)
|
||||||
(Form_pg_collation) GETSTRUCT(collationTuple);
|
(Form_pg_collation) GETSTRUCT(collationTuple);
|
||||||
char *collationName = NameStr(collationform->collname);
|
char *collationName = NameStr(collationform->collname);
|
||||||
char *collationSchemaName = get_namespace_name(collationform->collnamespace);
|
char *collationSchemaName = get_namespace_name(collationform->collnamespace);
|
||||||
|
char *qualifiedCollationName = quote_qualified_identifier(collationSchemaName,
|
||||||
|
collationName);
|
||||||
|
|
||||||
StringInfo colocationIdQuery = makeStringInfo();
|
StringInfo regcollationExpression = makeStringInfo();
|
||||||
appendStringInfo(colocationIdQuery,
|
appendStringInfo(regcollationExpression,
|
||||||
"(select oid from pg_collation"
|
"%s::regcollation",
|
||||||
" where collname = %s"
|
quote_literal_cstr(qualifiedCollationName));
|
||||||
" and collnamespace = %s::regnamespace)",
|
|
||||||
quote_literal_cstr(collationName),
|
|
||||||
quote_literal_cstr(collationSchemaName));
|
|
||||||
|
|
||||||
expression = colocationIdQuery->data;
|
expression = regcollationExpression->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReleaseSysCache(collationTuple);
|
ReleaseSysCache(collationTuple);
|
||||||
|
|
|
@ -66,9 +66,6 @@
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
#if PG_VERSION_NUM < 120000
|
|
||||||
#include "utils/tqual.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DISK_SPACE_FIELDS 2
|
#define DISK_SPACE_FIELDS 2
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,6 @@ master_create_worker_shards(PG_FUNCTION_ARGS)
|
||||||
text *tableNameText = PG_GETARG_TEXT_P(0);
|
text *tableNameText = PG_GETARG_TEXT_P(0);
|
||||||
int32 shardCount = PG_GETARG_INT32(1);
|
int32 shardCount = PG_GETARG_INT32(1);
|
||||||
int32 replicationFactor = PG_GETARG_INT32(2);
|
int32 replicationFactor = PG_GETARG_INT32(2);
|
||||||
ObjectAddress tableAddress = { 0 };
|
|
||||||
|
|
||||||
Oid distributedTableId = ResolveRelationId(tableNameText, false);
|
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
|
* via their own connection and committed immediately so they become visible to all
|
||||||
* sessions creating shards.
|
* sessions creating shards.
|
||||||
*/
|
*/
|
||||||
ObjectAddressSet(tableAddress, RelationRelationId, distributedTableId);
|
ObjectAddress *tableAddress = palloc0(sizeof(ObjectAddress));
|
||||||
EnsureDependenciesExistOnAllNodes(&tableAddress);
|
ObjectAddressSet(*tableAddress, RelationRelationId, distributedTableId);
|
||||||
|
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(tableAddress));
|
||||||
|
|
||||||
EnsureReferenceTablesExistOnAllNodes();
|
EnsureReferenceTablesExistOnAllNodes();
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,18 @@
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
#include "utils/syscache.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 */
|
/* local function forward declarations */
|
||||||
static void VerifyTablesHaveReplicaIdentity(List *colocatedTableList);
|
static void VerifyTablesHaveReplicaIdentity(List *colocatedTableList);
|
||||||
static bool RelationCanPublishAllModifications(Oid relationId);
|
static bool RelationCanPublishAllModifications(Oid relationId);
|
||||||
|
@ -114,6 +126,8 @@ static List * CopyShardContentsCommandList(ShardInterval *shardInterval,
|
||||||
static List * PostLoadShardCreationCommandList(ShardInterval *shardInterval,
|
static List * PostLoadShardCreationCommandList(ShardInterval *shardInterval,
|
||||||
const char *sourceNodeName,
|
const char *sourceNodeName,
|
||||||
int32 sourceNodePort);
|
int32 sourceNodePort);
|
||||||
|
static ShardCommandList * CreateShardCommandList(ShardInterval *shardInterval,
|
||||||
|
List *ddlCommandList);
|
||||||
|
|
||||||
|
|
||||||
/* declarations for dynamic loading */
|
/* 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
|
* 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
|
* 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.
|
* 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.
|
||||||
* Iterate through the colocated shards and create the foreign constraints and
|
*/
|
||||||
* 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)
|
foreach_ptr(shardInterval, shardIntervalList)
|
||||||
{
|
{
|
||||||
|
@ -1201,25 +1249,25 @@ CopyShardTablesViaBlockWrites(List *shardIntervalList, char *sourceNodeName,
|
||||||
&shardForeignConstraintCommandList,
|
&shardForeignConstraintCommandList,
|
||||||
&referenceTableForeignConstraintList);
|
&referenceTableForeignConstraintList);
|
||||||
|
|
||||||
List *commandList = NIL;
|
ShardCommandList *shardCommandList = CreateShardCommandList(
|
||||||
commandList = list_concat(commandList, shardForeignConstraintCommandList);
|
shardInterval,
|
||||||
commandList = list_concat(commandList, referenceTableForeignConstraintList);
|
list_concat(shardForeignConstraintCommandList,
|
||||||
|
referenceTableForeignConstraintList));
|
||||||
if (PartitionTable(shardInterval->relationId))
|
shardIntervalWithDDCommandsList = lappend(shardIntervalWithDDCommandsList,
|
||||||
{
|
shardCommandList);
|
||||||
char *attachPartitionCommand =
|
|
||||||
GenerateAttachShardPartitionCommand(shardInterval);
|
|
||||||
|
|
||||||
commandList = lappend(commandList, attachPartitionCommand);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *tableOwner = TableOwner(shardInterval->relationId);
|
/* Now execute the Partitioning & Foreign constraints creation commads. */
|
||||||
|
ShardCommandList *shardCommandList = NULL;
|
||||||
|
foreach_ptr(shardCommandList, shardIntervalWithDDCommandsList)
|
||||||
|
{
|
||||||
|
char *tableOwner = TableOwner(shardCommandList->shardInterval->relationId);
|
||||||
SendCommandListToWorkerOutsideTransaction(targetNodeName, targetNodePort,
|
SendCommandListToWorkerOutsideTransaction(targetNodeName, targetNodePort,
|
||||||
tableOwner, commandList);
|
tableOwner,
|
||||||
|
shardCommandList->ddlCommandList);
|
||||||
|
}
|
||||||
|
|
||||||
MemoryContextReset(localContext);
|
MemoryContextReset(localContext);
|
||||||
}
|
|
||||||
|
|
||||||
MemoryContextSwitchTo(oldContext);
|
MemoryContextSwitchTo(oldContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,10 +60,7 @@
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
#include "common/hashfn.h"
|
#include "common/hashfn.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* RebalanceOptions are the options used to control the rebalance algorithm */
|
/* RebalanceOptions are the options used to control the rebalance algorithm */
|
||||||
|
|
|
@ -77,6 +77,8 @@ static void SplitShardReplicationSetup(ShardInterval *shardIntervalToSplit,
|
||||||
WorkerNode *sourceWorkerNode,
|
WorkerNode *sourceWorkerNode,
|
||||||
List *workersForPlacementList);
|
List *workersForPlacementList);
|
||||||
static HTAB * CreateWorkerForPlacementSet(List *workersForPlacementList);
|
static HTAB * CreateWorkerForPlacementSet(List *workersForPlacementList);
|
||||||
|
static void CreateAuxiliaryStructuresForShardGroup(List *shardGroupSplitIntervalListList,
|
||||||
|
List *workersForPlacementList);
|
||||||
static void CreateObjectOnPlacement(List *objectCreationCommandList,
|
static void CreateObjectOnPlacement(List *objectCreationCommandList,
|
||||||
WorkerNode *workerNode);
|
WorkerNode *workerNode);
|
||||||
static List * CreateSplitIntervalsForShardGroup(List *sourceColocatedShardList,
|
static List * CreateSplitIntervalsForShardGroup(List *sourceColocatedShardList,
|
||||||
|
@ -98,11 +100,17 @@ static void DoSplitCopy(WorkerNode *sourceShardNode,
|
||||||
List *shardGroupSplitIntervalListList,
|
List *shardGroupSplitIntervalListList,
|
||||||
List *workersForPlacementList,
|
List *workersForPlacementList,
|
||||||
char *snapShotName);
|
char *snapShotName);
|
||||||
|
static void DoSplitCopy(WorkerNode *sourceShardNode,
|
||||||
|
List *sourceColocatedShardIntervalList,
|
||||||
|
List *shardGroupSplitIntervalListList,
|
||||||
|
List *workersForPlacementList);
|
||||||
static StringInfo CreateSplitCopyCommand(ShardInterval *sourceShardSplitInterval,
|
static StringInfo CreateSplitCopyCommand(ShardInterval *sourceShardSplitInterval,
|
||||||
List *splitChildrenShardIntervalList,
|
List *splitChildrenShardIntervalList,
|
||||||
List *workersForPlacementList);
|
List *workersForPlacementList);
|
||||||
static void InsertSplitChildrenShardMetadata(List *shardGroupSplitIntervalListList,
|
static void InsertSplitChildrenShardMetadata(List *shardGroupSplitIntervalListList,
|
||||||
List *workersForPlacementList);
|
List *workersForPlacementList);
|
||||||
|
static void CreatePartitioningHierarchy(List *shardGroupSplitIntervalListList,
|
||||||
|
List *workersForPlacementList);
|
||||||
static void CreateForeignKeyConstraints(List *shardGroupSplitIntervalListList,
|
static void CreateForeignKeyConstraints(List *shardGroupSplitIntervalListList,
|
||||||
List *workersForPlacementList);
|
List *workersForPlacementList);
|
||||||
static void TryDropSplitShardsOnFailure(HTAB *mapOfShardToPlacementCreatedByWorkflow);
|
static void TryDropSplitShardsOnFailure(HTAB *mapOfShardToPlacementCreatedByWorkflow);
|
||||||
|
@ -456,8 +464,8 @@ SplitShard(SplitMode splitMode,
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ShardIntervalHashCode computes the hash code for a shard from the
|
* ShardIntervalHashCode computes the hash code for a Shardinterval using
|
||||||
* placement's shard id.
|
* shardId.
|
||||||
*/
|
*/
|
||||||
static uint32
|
static uint32
|
||||||
ShardIntervalHashCode(const void *key, Size keySize)
|
ShardIntervalHashCode(const void *key, Size keySize)
|
||||||
|
@ -568,6 +576,12 @@ BlockingShardSplit(SplitOperation splitOperation,
|
||||||
shardGroupSplitIntervalListList,
|
shardGroupSplitIntervalListList,
|
||||||
workersForPlacementList);
|
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
|
* Drop old shards and delete related metadata. Have to do that before
|
||||||
* creating the new shard metadata, because there's cross-checks
|
* creating the new shard metadata, because there's cross-checks
|
||||||
|
@ -579,6 +593,10 @@ BlockingShardSplit(SplitOperation splitOperation,
|
||||||
InsertSplitChildrenShardMetadata(shardGroupSplitIntervalListList,
|
InsertSplitChildrenShardMetadata(shardGroupSplitIntervalListList,
|
||||||
workersForPlacementList);
|
workersForPlacementList);
|
||||||
|
|
||||||
|
/* create partitioning hierarchy, if any */
|
||||||
|
CreatePartitioningHierarchy(shardGroupSplitIntervalListList,
|
||||||
|
workersForPlacementList);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create foreign keys if exists after the metadata changes happening in
|
* Create foreign keys if exists after the metadata changes happening in
|
||||||
* DropShardList() and InsertSplitChildrenShardMetadata() because the foreign
|
* DropShardList() and InsertSplitChildrenShardMetadata() because the foreign
|
||||||
|
@ -666,7 +684,7 @@ CreateTaskForDDLCommandList(List *ddlCommandList, WorkerNode *workerNode)
|
||||||
/* Create ShardGroup auxiliary structures (indexes, stats, replicaindentities, triggers)
|
/* Create ShardGroup auxiliary structures (indexes, stats, replicaindentities, triggers)
|
||||||
* on a list of corresponding workers.
|
* on a list of corresponding workers.
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
CreateAuxiliaryStructuresForShardGroup(List *shardGroupSplitIntervalListList,
|
CreateAuxiliaryStructuresForShardGroup(List *shardGroupSplitIntervalListList,
|
||||||
List *workersForPlacementList)
|
List *workersForPlacementList)
|
||||||
{
|
{
|
||||||
|
@ -761,6 +779,13 @@ DoSplitCopy(WorkerNode *sourceShardNode, List *sourceColocatedShardIntervalList,
|
||||||
List *splitCopyTaskList = NIL;
|
List *splitCopyTaskList = NIL;
|
||||||
forboth_ptr(sourceShardIntervalToCopy, sourceColocatedShardIntervalList,
|
forboth_ptr(sourceShardIntervalToCopy, sourceColocatedShardIntervalList,
|
||||||
splitShardIntervalList, shardGroupSplitIntervalListList)
|
splitShardIntervalList, shardGroupSplitIntervalListList)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 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,
|
StringInfo splitCopyUdfCommand = CreateSplitCopyCommand(sourceShardIntervalToCopy,
|
||||||
splitShardIntervalList,
|
splitShardIntervalList,
|
||||||
|
@ -803,6 +828,8 @@ DoSplitCopy(WorkerNode *sourceShardNode, List *sourceColocatedShardIntervalList,
|
||||||
|
|
||||||
splitCopyTaskList = lappend(splitCopyTaskList, splitCopyTask);
|
splitCopyTaskList = lappend(splitCopyTaskList, splitCopyTask);
|
||||||
taskId++;
|
taskId++;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecuteTaskListOutsideTransaction(ROW_MODIFY_NONE, splitCopyTaskList,
|
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.
|
* 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.
|
* coordinator and mx nodes.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -96,7 +96,7 @@ master_create_empty_shard(PG_FUNCTION_ARGS)
|
||||||
text *relationNameText = PG_GETARG_TEXT_P(0);
|
text *relationNameText = PG_GETARG_TEXT_P(0);
|
||||||
char *relationName = text_to_cstring(relationNameText);
|
char *relationName = text_to_cstring(relationNameText);
|
||||||
uint32 attemptableNodeCount = 0;
|
uint32 attemptableNodeCount = 0;
|
||||||
ObjectAddress tableAddress = { 0 };
|
ObjectAddress *tableAddress = palloc0(sizeof(ObjectAddress));
|
||||||
|
|
||||||
uint32 candidateNodeIndex = 0;
|
uint32 candidateNodeIndex = 0;
|
||||||
List *candidateNodeList = NIL;
|
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
|
* via their own connection and committed immediately so they become visible to all
|
||||||
* sessions creating shards.
|
* sessions creating shards.
|
||||||
*/
|
*/
|
||||||
ObjectAddressSet(tableAddress, RelationRelationId, relationId);
|
ObjectAddressSet(*tableAddress, RelationRelationId, relationId);
|
||||||
EnsureDependenciesExistOnAllNodes(&tableAddress);
|
EnsureAllObjectDependenciesExistOnAllNodes(list_make1(tableAddress));
|
||||||
EnsureReferenceTablesExistOnAllNodes();
|
EnsureReferenceTablesExistOnAllNodes();
|
||||||
|
|
||||||
/* don't allow the table to be dropped */
|
/* don't allow the table to be dropped */
|
||||||
|
|
|
@ -131,9 +131,7 @@ static void WarnIfListHasForeignDistributedTable(List *rangeTableList);
|
||||||
/* Distributed planner hook */
|
/* Distributed planner hook */
|
||||||
PlannedStmt *
|
PlannedStmt *
|
||||||
distributed_planner(Query *parse,
|
distributed_planner(Query *parse,
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
const char *query_string,
|
const char *query_string,
|
||||||
#endif
|
|
||||||
int cursorOptions,
|
int cursorOptions,
|
||||||
ParamListInfo boundParams)
|
ParamListInfo boundParams)
|
||||||
{
|
{
|
||||||
|
@ -1839,7 +1837,7 @@ TranslatedVars(PlannerInfo *root, int relationIndex)
|
||||||
FindTargetAppendRelInfo(root, relationIndex);
|
FindTargetAppendRelInfo(root, relationIndex);
|
||||||
if (targetAppendRelInfo != NULL)
|
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;
|
Node *targetNode = NULL;
|
||||||
foreach_ptr(targetNode, targetAppendRelInfo->translated_vars)
|
foreach_ptr(targetNode, targetAppendRelInfo->translated_vars)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
* When we arrive here, standard_planner has already been called which calls
|
||||||
* replace_empty_jointree() which replaces empty fromlist with a list of
|
* replace_empty_jointree() which replaces empty fromlist with a list of
|
||||||
* single RTE_RESULT RangleTableRef node.
|
* single RTE_RESULT RangleTableRef node.
|
||||||
|
|
|
@ -21,9 +21,7 @@
|
||||||
#include "distributed/query_utils.h"
|
#include "distributed/query_utils.h"
|
||||||
#include "distributed/worker_manager.h"
|
#include "distributed/worker_manager.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
#include "common/hashfn.h"
|
#include "common/hashfn.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
/* controlled via GUC, used mostly for testing */
|
/* controlled via GUC, used mostly for testing */
|
||||||
bool LogIntermediateResults = false;
|
bool LogIntermediateResults = false;
|
||||||
|
@ -373,9 +371,6 @@ RemoveLocalNodeFromWorkerList(List *workerNodeList)
|
||||||
int32 localGroupId = GetLocalGroupId();
|
int32 localGroupId = GetLocalGroupId();
|
||||||
|
|
||||||
ListCell *workerNodeCell = NULL;
|
ListCell *workerNodeCell = NULL;
|
||||||
#if PG_VERSION_NUM < PG_VERSION_13
|
|
||||||
ListCell *prev = NULL;
|
|
||||||
#endif
|
|
||||||
foreach(workerNodeCell, workerNodeList)
|
foreach(workerNodeCell, workerNodeList)
|
||||||
{
|
{
|
||||||
WorkerNode *workerNode = (WorkerNode *) lfirst(workerNodeCell);
|
WorkerNode *workerNode = (WorkerNode *) lfirst(workerNodeCell);
|
||||||
|
@ -383,9 +378,6 @@ RemoveLocalNodeFromWorkerList(List *workerNodeList)
|
||||||
{
|
{
|
||||||
return list_delete_cell_compat(workerNodeList, workerNodeCell, prev);
|
return list_delete_cell_compat(workerNodeList, workerNodeCell, prev);
|
||||||
}
|
}
|
||||||
#if PG_VERSION_NUM < PG_VERSION_13
|
|
||||||
prev = workerNodeCell;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return workerNodeList;
|
return workerNodeList;
|
||||||
|
|
|
@ -297,8 +297,6 @@ ExplainSubPlans(DistributedPlan *distributedPlan, ExplainState *es)
|
||||||
*/
|
*/
|
||||||
char *queryString = pstrdup("");
|
char *queryString = pstrdup("");
|
||||||
instr_time planduration;
|
instr_time planduration;
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
|
|
||||||
BufferUsage bufusage_start,
|
BufferUsage bufusage_start,
|
||||||
bufusage;
|
bufusage;
|
||||||
|
|
||||||
|
@ -306,7 +304,7 @@ ExplainSubPlans(DistributedPlan *distributedPlan, ExplainState *es)
|
||||||
{
|
{
|
||||||
bufusage_start = pgBufferUsage;
|
bufusage_start = pgBufferUsage;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (es->format == EXPLAIN_FORMAT_TEXT)
|
if (es->format == EXPLAIN_FORMAT_TEXT)
|
||||||
{
|
{
|
||||||
char *resultId = GenerateResultId(planId, subPlan->subPlanId);
|
char *resultId = GenerateResultId(planId, subPlan->subPlanId);
|
||||||
|
@ -350,15 +348,12 @@ ExplainSubPlans(DistributedPlan *distributedPlan, ExplainState *es)
|
||||||
|
|
||||||
INSTR_TIME_SET_ZERO(planduration);
|
INSTR_TIME_SET_ZERO(planduration);
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
|
|
||||||
/* calc differences of buffer counters. */
|
/* calc differences of buffer counters. */
|
||||||
if (es->buffers)
|
if (es->buffers)
|
||||||
{
|
{
|
||||||
memset(&bufusage, 0, sizeof(BufferUsage));
|
memset(&bufusage, 0, sizeof(BufferUsage));
|
||||||
BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start);
|
BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
ExplainOpenGroup("PlannedStmt", "PlannedStmt", false, es);
|
ExplainOpenGroup("PlannedStmt", "PlannedStmt", false, es);
|
||||||
|
|
||||||
|
@ -923,18 +918,13 @@ BuildRemoteExplainQuery(char *queryString, ExplainState *es)
|
||||||
|
|
||||||
appendStringInfo(explainQuery,
|
appendStringInfo(explainQuery,
|
||||||
"EXPLAIN (ANALYZE %s, VERBOSE %s, "
|
"EXPLAIN (ANALYZE %s, VERBOSE %s, "
|
||||||
"COSTS %s, BUFFERS %s, "
|
"COSTS %s, BUFFERS %s, WAL %s, "
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
"WAL %s, "
|
|
||||||
#endif
|
|
||||||
"TIMING %s, SUMMARY %s, FORMAT %s) %s",
|
"TIMING %s, SUMMARY %s, FORMAT %s) %s",
|
||||||
es->analyze ? "TRUE" : "FALSE",
|
es->analyze ? "TRUE" : "FALSE",
|
||||||
es->verbose ? "TRUE" : "FALSE",
|
es->verbose ? "TRUE" : "FALSE",
|
||||||
es->costs ? "TRUE" : "FALSE",
|
es->costs ? "TRUE" : "FALSE",
|
||||||
es->buffers ? "TRUE" : "FALSE",
|
es->buffers ? "TRUE" : "FALSE",
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
es->wal ? "TRUE" : "FALSE",
|
es->wal ? "TRUE" : "FALSE",
|
||||||
#endif
|
|
||||||
es->timing ? "TRUE" : "FALSE",
|
es->timing ? "TRUE" : "FALSE",
|
||||||
es->summary ? "TRUE" : "FALSE",
|
es->summary ? "TRUE" : "FALSE",
|
||||||
formatStr,
|
formatStr,
|
||||||
|
@ -1028,9 +1018,7 @@ worker_save_query_explain_analyze(PG_FUNCTION_ARGS)
|
||||||
|
|
||||||
/* use the same defaults as NewExplainState() for following options */
|
/* use the same defaults as NewExplainState() for following options */
|
||||||
es->buffers = ExtractFieldBoolean(explainOptions, "buffers", es->buffers);
|
es->buffers = ExtractFieldBoolean(explainOptions, "buffers", es->buffers);
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
es->wal = ExtractFieldBoolean(explainOptions, "wal", es->wal);
|
es->wal = ExtractFieldBoolean(explainOptions, "wal", es->wal);
|
||||||
#endif
|
|
||||||
es->costs = ExtractFieldBoolean(explainOptions, "costs", es->costs);
|
es->costs = ExtractFieldBoolean(explainOptions, "costs", es->costs);
|
||||||
es->summary = ExtractFieldBoolean(explainOptions, "summary", es->summary);
|
es->summary = ExtractFieldBoolean(explainOptions, "summary", es->summary);
|
||||||
es->verbose = ExtractFieldBoolean(explainOptions, "verbose", es->verbose);
|
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 */
|
/* save the flags of current EXPLAIN command */
|
||||||
CurrentDistributedQueryExplainOptions.costs = es->costs;
|
CurrentDistributedQueryExplainOptions.costs = es->costs;
|
||||||
CurrentDistributedQueryExplainOptions.buffers = es->buffers;
|
CurrentDistributedQueryExplainOptions.buffers = es->buffers;
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
CurrentDistributedQueryExplainOptions.wal = es->wal;
|
CurrentDistributedQueryExplainOptions.wal = es->wal;
|
||||||
#endif
|
|
||||||
CurrentDistributedQueryExplainOptions.verbose = es->verbose;
|
CurrentDistributedQueryExplainOptions.verbose = es->verbose;
|
||||||
CurrentDistributedQueryExplainOptions.summary = es->summary;
|
CurrentDistributedQueryExplainOptions.summary = es->summary;
|
||||||
CurrentDistributedQueryExplainOptions.timing = es->timing;
|
CurrentDistributedQueryExplainOptions.timing = es->timing;
|
||||||
|
@ -1189,7 +1175,6 @@ CitusExplainOneQuery(Query *query, int cursorOptions, IntoClause *into,
|
||||||
/* rest is copied from ExplainOneQuery() */
|
/* rest is copied from ExplainOneQuery() */
|
||||||
instr_time planstart,
|
instr_time planstart,
|
||||||
planduration;
|
planduration;
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
BufferUsage bufusage_start,
|
BufferUsage bufusage_start,
|
||||||
bufusage;
|
bufusage;
|
||||||
|
|
||||||
|
@ -1197,7 +1182,6 @@ CitusExplainOneQuery(Query *query, int cursorOptions, IntoClause *into,
|
||||||
{
|
{
|
||||||
bufusage_start = pgBufferUsage;
|
bufusage_start = pgBufferUsage;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
INSTR_TIME_SET_CURRENT(planstart);
|
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);
|
PlannedStmt *plan = pg_plan_query_compat(query, NULL, cursorOptions, params);
|
||||||
INSTR_TIME_SET_CURRENT(planduration);
|
INSTR_TIME_SET_CURRENT(planduration);
|
||||||
INSTR_TIME_SUBTRACT(planduration, planstart);
|
INSTR_TIME_SUBTRACT(planduration, planstart);
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
|
|
||||||
/* calc differences of buffer counters. */
|
/* calc differences of buffer counters. */
|
||||||
if (es->buffers)
|
if (es->buffers)
|
||||||
|
@ -1213,7 +1196,6 @@ CitusExplainOneQuery(Query *query, int cursorOptions, IntoClause *into,
|
||||||
memset(&bufusage, 0, sizeof(BufferUsage));
|
memset(&bufusage, 0, sizeof(BufferUsage));
|
||||||
BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start);
|
BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* run it (if needed) and produce output */
|
/* run it (if needed) and produce output */
|
||||||
ExplainOnePlanCompat(plan, into, es, queryString, params, queryEnv,
|
ExplainOnePlanCompat(plan, into, es, queryString, params, queryEnv,
|
||||||
|
@ -1467,17 +1449,12 @@ WrapQueryForExplainAnalyze(const char *queryString, TupleDesc tupleDesc,
|
||||||
|
|
||||||
StringInfo explainOptions = makeStringInfo();
|
StringInfo explainOptions = makeStringInfo();
|
||||||
appendStringInfo(explainOptions,
|
appendStringInfo(explainOptions,
|
||||||
"{\"verbose\": %s, \"costs\": %s, \"buffers\": %s, "
|
"{\"verbose\": %s, \"costs\": %s, \"buffers\": %s, \"wal\": %s, "
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
"\"wal\": %s, "
|
|
||||||
#endif
|
|
||||||
"\"timing\": %s, \"summary\": %s, \"format\": \"%s\"}",
|
"\"timing\": %s, \"summary\": %s, \"format\": \"%s\"}",
|
||||||
CurrentDistributedQueryExplainOptions.verbose ? "true" : "false",
|
CurrentDistributedQueryExplainOptions.verbose ? "true" : "false",
|
||||||
CurrentDistributedQueryExplainOptions.costs ? "true" : "false",
|
CurrentDistributedQueryExplainOptions.costs ? "true" : "false",
|
||||||
CurrentDistributedQueryExplainOptions.buffers ? "true" : "false",
|
CurrentDistributedQueryExplainOptions.buffers ? "true" : "false",
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
CurrentDistributedQueryExplainOptions.wal ? "true" : "false",
|
CurrentDistributedQueryExplainOptions.wal ? "true" : "false",
|
||||||
#endif
|
|
||||||
CurrentDistributedQueryExplainOptions.timing ? "true" : "false",
|
CurrentDistributedQueryExplainOptions.timing ? "true" : "false",
|
||||||
CurrentDistributedQueryExplainOptions.summary ? "true" : "false",
|
CurrentDistributedQueryExplainOptions.summary ? "true" : "false",
|
||||||
ExplainFormatStr(CurrentDistributedQueryExplainOptions.format));
|
ExplainFormatStr(CurrentDistributedQueryExplainOptions.format));
|
||||||
|
@ -1632,13 +1609,11 @@ ExplainOneQuery(Query *query, int cursorOptions,
|
||||||
{
|
{
|
||||||
instr_time planstart,
|
instr_time planstart,
|
||||||
planduration;
|
planduration;
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
BufferUsage bufusage_start,
|
BufferUsage bufusage_start,
|
||||||
bufusage;
|
bufusage;
|
||||||
|
|
||||||
if (es->buffers)
|
if (es->buffers)
|
||||||
bufusage_start = pgBufferUsage;
|
bufusage_start = pgBufferUsage;
|
||||||
#endif
|
|
||||||
INSTR_TIME_SET_CURRENT(planstart);
|
INSTR_TIME_SET_CURRENT(planstart);
|
||||||
|
|
||||||
/* plan the query */
|
/* plan the query */
|
||||||
|
@ -1647,15 +1622,13 @@ ExplainOneQuery(Query *query, int cursorOptions,
|
||||||
INSTR_TIME_SET_CURRENT(planduration);
|
INSTR_TIME_SET_CURRENT(planduration);
|
||||||
INSTR_TIME_SUBTRACT(planduration, planstart);
|
INSTR_TIME_SUBTRACT(planduration, planstart);
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
|
|
||||||
/* calc differences of buffer counters. */
|
/* calc differences of buffer counters. */
|
||||||
if (es->buffers)
|
if (es->buffers)
|
||||||
{
|
{
|
||||||
memset(&bufusage, 0, sizeof(BufferUsage));
|
memset(&bufusage, 0, sizeof(BufferUsage));
|
||||||
BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start);
|
BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
/* run it (if needed) and produce output */
|
/* run it (if needed) and produce output */
|
||||||
ExplainOnePlanCompat(plan, into, es, queryString, params, queryEnv,
|
ExplainOnePlanCompat(plan, into, es, queryString, params, queryEnv,
|
||||||
&planduration, (es->buffers ? &bufusage : NULL));
|
&planduration, (es->buffers ? &bufusage : NULL));
|
||||||
|
@ -1696,10 +1669,10 @@ ExplainWorkerPlan(PlannedStmt *plannedstmt, DestReceiver *dest, ExplainState *es
|
||||||
|
|
||||||
if (es->buffers)
|
if (es->buffers)
|
||||||
instrument_option |= INSTRUMENT_BUFFERS;
|
instrument_option |= INSTRUMENT_BUFFERS;
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
if (es->wal)
|
if (es->wal)
|
||||||
instrument_option |= INSTRUMENT_WAL;
|
instrument_option |= INSTRUMENT_WAL;
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* We always collect timing for the entire statement, even when node-level
|
* 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
|
* timing is off, so we don't look at es->timing here. (We could skip
|
||||||
|
|
|
@ -1490,9 +1490,7 @@ MasterExtendedOpNode(MultiExtendedOp *originalOpNode,
|
||||||
masterExtendedOpNode->hasDistinctOn = originalOpNode->hasDistinctOn;
|
masterExtendedOpNode->hasDistinctOn = originalOpNode->hasDistinctOn;
|
||||||
masterExtendedOpNode->limitCount = originalOpNode->limitCount;
|
masterExtendedOpNode->limitCount = originalOpNode->limitCount;
|
||||||
masterExtendedOpNode->limitOffset = originalOpNode->limitOffset;
|
masterExtendedOpNode->limitOffset = originalOpNode->limitOffset;
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
masterExtendedOpNode->limitOption = originalOpNode->limitOption;
|
masterExtendedOpNode->limitOption = originalOpNode->limitOption;
|
||||||
#endif
|
|
||||||
masterExtendedOpNode->havingQual = newHavingQual;
|
masterExtendedOpNode->havingQual = newHavingQual;
|
||||||
|
|
||||||
if (!extendedOpNodeProperties->onlyPushableWindowFunctions)
|
if (!extendedOpNodeProperties->onlyPushableWindowFunctions)
|
||||||
|
@ -2489,14 +2487,12 @@ WorkerExtendedOpNode(MultiExtendedOp *originalOpNode,
|
||||||
workerExtendedOpNode->windowClause = queryWindowClause.workerWindowClauseList;
|
workerExtendedOpNode->windowClause = queryWindowClause.workerWindowClauseList;
|
||||||
workerExtendedOpNode->sortClauseList = queryOrderByLimit.workerSortClauseList;
|
workerExtendedOpNode->sortClauseList = queryOrderByLimit.workerSortClauseList;
|
||||||
workerExtendedOpNode->limitCount = queryOrderByLimit.workerLimitCount;
|
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
|
* If the limitCount cannot be pushed down it will be NULL, so the deparser will
|
||||||
* ignore the limitOption.
|
* ignore the limitOption.
|
||||||
*/
|
*/
|
||||||
workerExtendedOpNode->limitOption = originalOpNode->limitOption;
|
workerExtendedOpNode->limitOption = originalOpNode->limitOption;
|
||||||
#endif
|
|
||||||
|
|
||||||
return workerExtendedOpNode;
|
return workerExtendedOpNode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1734,9 +1734,7 @@ MultiExtendedOpNode(Query *queryTree, Query *originalQuery)
|
||||||
extendedOpNode->sortClauseList = queryTree->sortClause;
|
extendedOpNode->sortClauseList = queryTree->sortClause;
|
||||||
extendedOpNode->limitCount = queryTree->limitCount;
|
extendedOpNode->limitCount = queryTree->limitCount;
|
||||||
extendedOpNode->limitOffset = queryTree->limitOffset;
|
extendedOpNode->limitOffset = queryTree->limitOffset;
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
extendedOpNode->limitOption = queryTree->limitOption;
|
extendedOpNode->limitOption = queryTree->limitOption;
|
||||||
#endif
|
|
||||||
extendedOpNode->havingQual = queryTree->havingQual;
|
extendedOpNode->havingQual = queryTree->havingQual;
|
||||||
extendedOpNode->distinctClause = queryTree->distinctClause;
|
extendedOpNode->distinctClause = queryTree->distinctClause;
|
||||||
extendedOpNode->hasDistinctOn = queryTree->hasDistinctOn;
|
extendedOpNode->hasDistinctOn = queryTree->hasDistinctOn;
|
||||||
|
|
|
@ -230,9 +230,7 @@ static List * FetchEqualityAttrNumsForRTEOpExpr(OpExpr *opExpr);
|
||||||
static List * FetchEqualityAttrNumsForRTEBoolExpr(BoolExpr *boolExpr);
|
static List * FetchEqualityAttrNumsForRTEBoolExpr(BoolExpr *boolExpr);
|
||||||
static List * FetchEqualityAttrNumsForList(List *nodeList);
|
static List * FetchEqualityAttrNumsForList(List *nodeList);
|
||||||
static int PartitionColumnIndex(Var *targetVar, List *targetList);
|
static int PartitionColumnIndex(Var *targetVar, List *targetList);
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
static List * GetColumnOriginalIndexes(Oid relationId);
|
static List * GetColumnOriginalIndexes(Oid relationId);
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -541,9 +539,7 @@ BuildJobQuery(MultiNode *multiNode, List *dependentJobList)
|
||||||
List *sortClauseList = NIL;
|
List *sortClauseList = NIL;
|
||||||
Node *limitCount = NULL;
|
Node *limitCount = NULL;
|
||||||
Node *limitOffset = NULL;
|
Node *limitOffset = NULL;
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
LimitOption limitOption = LIMIT_OPTION_DEFAULT;
|
LimitOption limitOption = LIMIT_OPTION_DEFAULT;
|
||||||
#endif
|
|
||||||
Node *havingQual = NULL;
|
Node *havingQual = NULL;
|
||||||
bool hasDistinctOn = false;
|
bool hasDistinctOn = false;
|
||||||
List *distinctClause = NIL;
|
List *distinctClause = NIL;
|
||||||
|
@ -625,9 +621,7 @@ BuildJobQuery(MultiNode *multiNode, List *dependentJobList)
|
||||||
|
|
||||||
limitCount = extendedOp->limitCount;
|
limitCount = extendedOp->limitCount;
|
||||||
limitOffset = extendedOp->limitOffset;
|
limitOffset = extendedOp->limitOffset;
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
limitOption = extendedOp->limitOption;
|
limitOption = extendedOp->limitOption;
|
||||||
#endif
|
|
||||||
sortClauseList = extendedOp->sortClauseList;
|
sortClauseList = extendedOp->sortClauseList;
|
||||||
havingQual = extendedOp->havingQual;
|
havingQual = extendedOp->havingQual;
|
||||||
}
|
}
|
||||||
|
@ -683,9 +677,7 @@ BuildJobQuery(MultiNode *multiNode, List *dependentJobList)
|
||||||
jobQuery->groupClause = groupClauseList;
|
jobQuery->groupClause = groupClauseList;
|
||||||
jobQuery->limitOffset = limitOffset;
|
jobQuery->limitOffset = limitOffset;
|
||||||
jobQuery->limitCount = limitCount;
|
jobQuery->limitCount = limitCount;
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
jobQuery->limitOption = limitOption;
|
jobQuery->limitOption = limitOption;
|
||||||
#endif
|
|
||||||
jobQuery->havingQual = havingQual;
|
jobQuery->havingQual = havingQual;
|
||||||
jobQuery->hasAggs = contain_aggs_of_level((Node *) targetList, 0) ||
|
jobQuery->hasAggs = contain_aggs_of_level((Node *) targetList, 0) ||
|
||||||
contain_aggs_of_level((Node *) havingQual, 0);
|
contain_aggs_of_level((Node *) havingQual, 0);
|
||||||
|
@ -1338,8 +1330,6 @@ static void
|
||||||
SetJoinRelatedColumnsCompat(RangeTblEntry *rangeTableEntry, Oid leftRelId, Oid rightRelId,
|
SetJoinRelatedColumnsCompat(RangeTblEntry *rangeTableEntry, Oid leftRelId, Oid rightRelId,
|
||||||
List *leftColumnVars, List *rightColumnVars)
|
List *leftColumnVars, List *rightColumnVars)
|
||||||
{
|
{
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
|
|
||||||
/* We don't have any merged columns so set it to 0 */
|
/* We don't have any merged columns so set it to 0 */
|
||||||
rangeTableEntry->joinmergedcols = 0;
|
rangeTableEntry->joinmergedcols = 0;
|
||||||
|
|
||||||
|
@ -1362,13 +1352,9 @@ SetJoinRelatedColumnsCompat(RangeTblEntry *rangeTableEntry, Oid leftRelId, Oid r
|
||||||
int rightColsSize = list_length(rightColumnVars);
|
int rightColsSize = list_length(rightColumnVars);
|
||||||
rangeTableEntry->joinrightcols = GeneratePositiveIntSequenceList(rightColsSize);
|
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.
|
* 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
|
* ExtractRangeTableId gets the range table id from a node that could
|
||||||
* either be a JoinExpr or RangeTblRef.
|
* either be a JoinExpr or RangeTblRef.
|
||||||
|
|
|
@ -167,10 +167,7 @@ static bool FindQueryContainingRTEIdentityInternal(Node *node,
|
||||||
FindQueryContainingRteIdentityContext *
|
FindQueryContainingRteIdentityContext *
|
||||||
context);
|
context);
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
static int ParentCountPriorToAppendRel(List *appendRelList, AppendRelInfo *appendRelInfo);
|
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.
|
* RangeTableOffsetCompat returns the range table offset(in glob->finalrtable) for the appendRelInfo.
|
||||||
* For PG < 13 this is a no op.
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
RangeTableOffsetCompat(PlannerInfo *root, AppendRelInfo *appendRelInfo)
|
RangeTableOffsetCompat(PlannerInfo *root, AppendRelInfo *appendRelInfo)
|
||||||
{
|
{
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
int parentCount = ParentCountPriorToAppendRel(root->append_rel_list, appendRelInfo);
|
int parentCount = ParentCountPriorToAppendRel(root->append_rel_list, appendRelInfo);
|
||||||
int skipParentCount = parentCount - 1;
|
int skipParentCount = parentCount - 1;
|
||||||
|
|
||||||
|
@ -434,9 +429,6 @@ RangeTableOffsetCompat(PlannerInfo *root, AppendRelInfo *appendRelInfo)
|
||||||
*/
|
*/
|
||||||
int parentRelIndex = appendRelInfo->parent_relid - 1;
|
int parentRelIndex = appendRelInfo->parent_relid - 1;
|
||||||
return parentRelIndex - indexInRtable;
|
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
|
* ParentCountPriorToAppendRel returns the number of parents that come before
|
||||||
* the given append rel info.
|
* the given append rel info.
|
||||||
|
@ -1506,8 +1496,6 @@ ParentCountPriorToAppendRel(List *appendRelList, AppendRelInfo *targetAppendRelI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AddUnionSetOperationsToAttributeEquivalenceClass recursively iterates on all the
|
* AddUnionSetOperationsToAttributeEquivalenceClass recursively iterates on all the
|
||||||
* setOperations and adds each corresponding target entry to the given equivalence
|
* setOperations and adds each corresponding target entry to the given equivalence
|
||||||
|
|
|
@ -112,7 +112,6 @@ RelayEventExtendNames(Node *parseTree, char *schemaName, uint64 shardId)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
case T_AlterStatsStmt:
|
case T_AlterStatsStmt:
|
||||||
{
|
{
|
||||||
AlterStatsStmt *alterStatsStmt = (AlterStatsStmt *) parseTree;
|
AlterStatsStmt *alterStatsStmt = (AlterStatsStmt *) parseTree;
|
||||||
|
@ -124,7 +123,6 @@ RelayEventExtendNames(Node *parseTree, char *schemaName, uint64 shardId)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
case T_AlterTableStmt:
|
case T_AlterTableStmt:
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,13 +17,9 @@
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
#include "distributed/pg_version_constants.h"
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_12
|
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
#include "postmaster/interrupt.h"
|
#include "postmaster/interrupt.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
#include "access/sysattr.h"
|
#include "access/sysattr.h"
|
||||||
|
@ -33,6 +29,7 @@
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_constraint.h"
|
#include "catalog/pg_constraint.h"
|
||||||
#include "distributed/adaptive_executor.h"
|
#include "distributed/adaptive_executor.h"
|
||||||
|
#include "distributed/citus_safe_lib.h"
|
||||||
#include "distributed/colocation_utils.h"
|
#include "distributed/colocation_utils.h"
|
||||||
#include "distributed/connection_management.h"
|
#include "distributed/connection_management.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
|
@ -1815,7 +1812,7 @@ TotalRelationSizeForSubscription(MultiConnection *connection, char *command)
|
||||||
{
|
{
|
||||||
char *resultString = PQgetvalue(result, 0, 0);
|
char *resultString = PQgetvalue(result, 0, 0);
|
||||||
|
|
||||||
remoteTotalSize = pg_strtouint64(resultString, NULL, 10);
|
remoteTotalSize = SafeStringToUint64(resultString);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2049,13 +2046,11 @@ WaitForMiliseconds(long timeout)
|
||||||
CHECK_FOR_INTERRUPTS();
|
CHECK_FOR_INTERRUPTS();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
if (ConfigReloadPending)
|
if (ConfigReloadPending)
|
||||||
{
|
{
|
||||||
ConfigReloadPending = false;
|
ConfigReloadPending = false;
|
||||||
ProcessConfigFile(PGC_SIGHUP);
|
ProcessConfigFile(PGC_SIGHUP);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,7 @@ DEFINE_COLUMNAR_PASSTHROUGH_FUNC(test_columnar_storage_write_new_page)
|
||||||
|
|
||||||
#define DUMMY_REAL_TIME_EXECUTOR_ENUM_VALUE 9999999
|
#define DUMMY_REAL_TIME_EXECUTOR_ENUM_VALUE 9999999
|
||||||
static char *CitusVersion = CITUS_VERSION;
|
static char *CitusVersion = CITUS_VERSION;
|
||||||
|
static char *DeprecatedEmptyString = "";
|
||||||
|
|
||||||
/* deprecated GUC value that should not be used anywhere outside this file */
|
/* deprecated GUC value that should not be used anywhere outside this file */
|
||||||
static int ReplicationModel = REPLICATION_MODEL_STREAMING;
|
static int ReplicationModel = REPLICATION_MODEL_STREAMING;
|
||||||
|
@ -149,8 +150,15 @@ static GucStringAssignHook OldApplicationNameAssignHook = NULL;
|
||||||
|
|
||||||
static object_access_hook_type PrevObjectAccessHook = 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);
|
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
|
static void CitusObjectAccessHook(ObjectAccessType access, Oid classId, Oid objectId, int
|
||||||
subId, void *arg);
|
subId, void *arg);
|
||||||
static void DoInitialCleanup(void);
|
static void DoInitialCleanup(void);
|
||||||
|
@ -367,6 +375,11 @@ _PG_init(void)
|
||||||
original_client_auth_hook = ClientAuthentication_hook;
|
original_client_auth_hook = ClientAuthentication_hook;
|
||||||
ClientAuthentication_hook = CitusAuthHook;
|
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();
|
InitializeMaintenanceDaemon();
|
||||||
|
|
||||||
/* initialize coordinated transaction management */
|
/* initialize coordinated transaction management */
|
||||||
|
@ -402,6 +415,7 @@ _PG_init(void)
|
||||||
PrevObjectAccessHook = object_access_hook;
|
PrevObjectAccessHook = object_access_hook;
|
||||||
object_access_hook = CitusObjectAccessHook;
|
object_access_hook = CitusObjectAccessHook;
|
||||||
|
|
||||||
|
|
||||||
/* ensure columnar module is loaded at the right time */
|
/* ensure columnar module is loaded at the right time */
|
||||||
load_file(COLUMNAR_MODULE_NAME, false);
|
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.
|
* DoInitialCleanup does cleanup at start time.
|
||||||
* Currently it:
|
* Currently it:
|
||||||
|
@ -1236,6 +1274,26 @@ RegisterCitusConfigVariables(void)
|
||||||
GUC_NO_SHOW_ALL,
|
GUC_NO_SHOW_ALL,
|
||||||
NULL, NULL, NULL);
|
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(
|
DefineCustomIntVariable(
|
||||||
"citus.isolation_test_session_process_id",
|
"citus.isolation_test_session_process_id",
|
||||||
NULL,
|
NULL,
|
||||||
|
|
|
@ -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_create_schema(bigint,text);
|
||||||
DROP FUNCTION pg_catalog.worker_cleanup_job_schema_cache();
|
DROP FUNCTION pg_catalog.worker_cleanup_job_schema_cache();
|
||||||
DROP FUNCTION pg_catalog.worker_fetch_foreign_file(text, text, bigint, text[], integer[]);
|
DROP FUNCTION pg_catalog.worker_fetch_foreign_file(text, text, bigint, text[], integer[]);
|
||||||
|
|
|
@ -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 worker_query BOOL, OUT transaction_number int8, OUT transaction_stamp timestamptz,
|
||||||
OUT global_pid int8);
|
OUT global_pid int8);
|
||||||
#include "../udfs/get_all_active_transactions/11.0-1.sql"
|
#include "../udfs/get_all_active_transactions/11.0-1.sql"
|
||||||
|
|
||||||
|
DROP VIEW pg_catalog.citus_locks;
|
||||||
|
DROP FUNCTION pg_catalog.citus_locks();
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -104,8 +104,6 @@ static BackendData *MyBackendData = NULL;
|
||||||
static CitusBackendType CurrentBackendType = CITUS_BACKEND_NOT_ASSIGNED;
|
static CitusBackendType CurrentBackendType = CITUS_BACKEND_NOT_ASSIGNED;
|
||||||
|
|
||||||
|
|
||||||
static void BackendManagementShmemInit(void);
|
|
||||||
static size_t BackendManagementShmemSize(void);
|
|
||||||
static void DetermineCitusBackendType(void);
|
static void DetermineCitusBackendType(void);
|
||||||
|
|
||||||
|
|
||||||
|
@ -515,12 +513,15 @@ UserHasPermissionToViewStatsOf(Oid currentUserId, Oid backendOwnedId)
|
||||||
void
|
void
|
||||||
InitializeBackendManagement(void)
|
InitializeBackendManagement(void)
|
||||||
{
|
{
|
||||||
|
/* on PG 15, we use shmem_request_hook_type */
|
||||||
|
#if PG_VERSION_NUM < PG_VERSION_15
|
||||||
|
|
||||||
/* allocate shared memory */
|
/* allocate shared memory */
|
||||||
if (!IsUnderPostmaster)
|
if (!IsUnderPostmaster)
|
||||||
{
|
{
|
||||||
RequestAddinShmemSpace(BackendManagementShmemSize());
|
RequestAddinShmemSpace(BackendManagementShmemSize());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
prev_shmem_startup_hook = shmem_startup_hook;
|
prev_shmem_startup_hook = shmem_startup_hook;
|
||||||
shmem_startup_hook = BackendManagementShmemInit;
|
shmem_startup_hook = BackendManagementShmemInit;
|
||||||
}
|
}
|
||||||
|
@ -531,7 +532,7 @@ InitializeBackendManagement(void)
|
||||||
* memory startup hook. The function sets up the necessary shared memory
|
* memory startup hook. The function sets up the necessary shared memory
|
||||||
* segment for the backend manager.
|
* segment for the backend manager.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
BackendManagementShmemInit(void)
|
BackendManagementShmemInit(void)
|
||||||
{
|
{
|
||||||
bool alreadyInitialized = false;
|
bool alreadyInitialized = false;
|
||||||
|
@ -599,7 +600,7 @@ BackendManagementShmemInit(void)
|
||||||
* BackendManagementShmemSize returns the size that should be allocated
|
* BackendManagementShmemSize returns the size that should be allocated
|
||||||
* on the shared memory for backend management.
|
* on the shared memory for backend management.
|
||||||
*/
|
*/
|
||||||
static size_t
|
size_t
|
||||||
BackendManagementShmemSize(void)
|
BackendManagementShmemSize(void)
|
||||||
{
|
{
|
||||||
Size size = 0;
|
Size size = 0;
|
||||||
|
|
|
@ -29,9 +29,7 @@
|
||||||
#include "distributed/metadata_cache.h"
|
#include "distributed/metadata_cache.h"
|
||||||
#include "distributed/relation_access_tracking.h"
|
#include "distributed/relation_access_tracking.h"
|
||||||
#include "utils/hsearch.h"
|
#include "utils/hsearch.h"
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
#include "common/hashfn.h"
|
#include "common/hashfn.h"
|
||||||
#endif
|
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -323,9 +323,7 @@ OutMultiExtendedOp(OUTFUNC_ARGS)
|
||||||
WRITE_NODE_FIELD(sortClauseList);
|
WRITE_NODE_FIELD(sortClauseList);
|
||||||
WRITE_NODE_FIELD(limitCount);
|
WRITE_NODE_FIELD(limitCount);
|
||||||
WRITE_NODE_FIELD(limitOffset);
|
WRITE_NODE_FIELD(limitOffset);
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
WRITE_ENUM_FIELD(limitOption, LimitOption);
|
WRITE_ENUM_FIELD(limitOption, LimitOption);
|
||||||
#endif
|
|
||||||
WRITE_NODE_FIELD(havingQual);
|
WRITE_NODE_FIELD(havingQual);
|
||||||
WRITE_BOOL_FIELD(hasDistinctOn);
|
WRITE_BOOL_FIELD(hasDistinctOn);
|
||||||
WRITE_NODE_FIELD(distinctClause);
|
WRITE_NODE_FIELD(distinctClause);
|
||||||
|
|
|
@ -29,9 +29,7 @@
|
||||||
#include "storage/lockdefs.h"
|
#include "storage/lockdefs.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/hsearch.h"
|
#include "utils/hsearch.h"
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
#include "common/hashfn.h"
|
#include "common/hashfn.h"
|
||||||
#endif
|
|
||||||
#include "utils/inval.h"
|
#include "utils/inval.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,7 @@
|
||||||
#include "storage/lmgr.h"
|
#include "storage/lmgr.h"
|
||||||
#include "storage/lwlock.h"
|
#include "storage/lwlock.h"
|
||||||
#include "tcop/tcopprot.h"
|
#include "tcop/tcopprot.h"
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
#include "common/hashfn.h"
|
#include "common/hashfn.h"
|
||||||
#endif
|
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
|
@ -117,8 +115,6 @@ static bool IsMaintenanceDaemon = false;
|
||||||
|
|
||||||
static void MaintenanceDaemonSigTermHandler(SIGNAL_ARGS);
|
static void MaintenanceDaemonSigTermHandler(SIGNAL_ARGS);
|
||||||
static void MaintenanceDaemonSigHupHandler(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 MaintenanceDaemonShmemExit(int code, Datum arg);
|
||||||
static void MaintenanceDaemonErrorContext(void *arg);
|
static void MaintenanceDaemonErrorContext(void *arg);
|
||||||
static bool MetadataSyncTriggeredCheckAndReset(MaintenanceDaemonDBData *dbData);
|
static bool MetadataSyncTriggeredCheckAndReset(MaintenanceDaemonDBData *dbData);
|
||||||
|
@ -133,11 +129,6 @@ static void WarnMaintenanceDaemonNotStarted(void);
|
||||||
void
|
void
|
||||||
InitializeMaintenanceDaemon(void)
|
InitializeMaintenanceDaemon(void)
|
||||||
{
|
{
|
||||||
if (!IsUnderPostmaster)
|
|
||||||
{
|
|
||||||
RequestAddinShmemSpace(MaintenanceDaemonShmemSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
prev_shmem_startup_hook = shmem_startup_hook;
|
prev_shmem_startup_hook = shmem_startup_hook;
|
||||||
shmem_startup_hook = MaintenanceDaemonShmemInit;
|
shmem_startup_hook = MaintenanceDaemonShmemInit;
|
||||||
}
|
}
|
||||||
|
@ -743,7 +734,7 @@ CitusMaintenanceDaemonMain(Datum main_arg)
|
||||||
/*
|
/*
|
||||||
* MaintenanceDaemonShmemSize computes how much shared memory is required.
|
* MaintenanceDaemonShmemSize computes how much shared memory is required.
|
||||||
*/
|
*/
|
||||||
static size_t
|
size_t
|
||||||
MaintenanceDaemonShmemSize(void)
|
MaintenanceDaemonShmemSize(void)
|
||||||
{
|
{
|
||||||
Size size = 0;
|
Size size = 0;
|
||||||
|
@ -767,7 +758,7 @@ MaintenanceDaemonShmemSize(void)
|
||||||
* MaintenanceDaemonShmemInit initializes the requested shared memory for the
|
* MaintenanceDaemonShmemInit initializes the requested shared memory for the
|
||||||
* maintenance daemon.
|
* maintenance daemon.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
MaintenanceDaemonShmemInit(void)
|
MaintenanceDaemonShmemInit(void)
|
||||||
{
|
{
|
||||||
bool alreadyInitialized = false;
|
bool alreadyInitialized = false;
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
|
|
||||||
#include "distributed/pg_version_constants.h"
|
#include "distributed/pg_version_constants.h"
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
#include "common/hashfn.h"
|
#include "common/hashfn.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "commands/dbcommands.h"
|
#include "commands/dbcommands.h"
|
||||||
#include "distributed/citus_custom_scan.h"
|
#include "distributed/citus_custom_scan.h"
|
||||||
|
|
|
@ -181,8 +181,13 @@ WorkerCreateOrReplaceObject(List *sqlStatements)
|
||||||
* same subject.
|
* same subject.
|
||||||
*/
|
*/
|
||||||
Node *parseTree = ParseTreeNode(linitial(sqlStatements));
|
Node *parseTree = ParseTreeNode(linitial(sqlStatements));
|
||||||
ObjectAddress address = GetObjectAddressFromParseTree(parseTree, true);
|
List *addresses = GetObjectAddressListFromParseTree(parseTree, true);
|
||||||
if (ObjectExists(&address))
|
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
|
* 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
|
* recreate our version of the object. This we can compare to what the coordinator
|
||||||
* sent us. If they match we don't do anything.
|
* sent us. If they match we don't do anything.
|
||||||
*/
|
*/
|
||||||
List *localSqlStatements = CreateStmtListByObjectAddress(&address);
|
List *localSqlStatements = CreateStmtListByObjectAddress(address);
|
||||||
if (CompareStringList(sqlStatements, localSqlStatements))
|
if (CompareStringList(sqlStatements, localSqlStatements))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -208,9 +213,9 @@ WorkerCreateOrReplaceObject(List *sqlStatements)
|
||||||
return false;
|
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);
|
const char *sqlRenameStmt = DeparseTreeNode((Node *) renameStmt);
|
||||||
ProcessUtilityParseTree((Node *) renameStmt, sqlRenameStmt,
|
ProcessUtilityParseTree((Node *) renameStmt, sqlRenameStmt,
|
||||||
PROCESS_UTILITY_QUERY,
|
PROCESS_UTILITY_QUERY,
|
||||||
|
|
|
@ -18,9 +18,6 @@
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/dependency.h"
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/pg_depend.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 "catalog/pg_foreign_server.h"
|
||||||
#include "distributed/citus_ruleutils.h"
|
#include "distributed/citus_ruleutils.h"
|
||||||
#include "distributed/distribution_column.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);
|
PG_FUNCTION_INFO_V1(worker_drop_sequence_dependency);
|
||||||
|
|
||||||
static void WorkerDropDistributedTable(Oid relationId);
|
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);
|
relation_close(distributedRelation, AccessShareLock);
|
||||||
|
|
||||||
/* prepare distributedTableObject for dropping the table */
|
/* 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 */
|
/* Drop dependent sequences from pg_dist_object */
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
List *ownedSequences = getOwnedSequences(relationId);
|
List *ownedSequences = getOwnedSequences(relationId);
|
||||||
#else
|
|
||||||
List *ownedSequences = getOwnedSequences(relationId, InvalidAttrNumber);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Oid ownedSequenceOid = InvalidOid;
|
Oid ownedSequenceOid = InvalidOid;
|
||||||
foreach_oid(ownedSequenceOid, ownedSequences)
|
foreach_oid(ownedSequenceOid, ownedSequences)
|
||||||
|
@ -144,7 +134,7 @@ WorkerDropDistributedTable(Oid relationId)
|
||||||
UnmarkObjectDistributed(&ownedSequenceAddress);
|
UnmarkObjectDistributed(&ownedSequenceAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
UnmarkObjectDistributed(&distributedTableObject);
|
UnmarkObjectDistributed(distributedTableObject);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove metadata before object's itself to make functions no-op within
|
* 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
|
* until the user runs DROP EXTENSION. Therefore, we skip dropping the
|
||||||
* table.
|
* table.
|
||||||
*/
|
*/
|
||||||
if (!IsObjectAddressOwnedByExtension(&distributedTableObject, NULL))
|
if (!IsAnyObjectAddressOwnedByExtension(list_make1(distributedTableObject), NULL))
|
||||||
{
|
{
|
||||||
char *relName = get_rel_name(relationId);
|
char *relName = get_rel_name(relationId);
|
||||||
Oid schemaId = get_rel_namespace(relationId);
|
Oid schemaId = get_rel_namespace(relationId);
|
||||||
|
@ -238,22 +228,15 @@ worker_drop_shell_table(PG_FUNCTION_ARGS)
|
||||||
relation_close(distributedRelation, AccessShareLock);
|
relation_close(distributedRelation, AccessShareLock);
|
||||||
|
|
||||||
/* prepare distributedTableObject for dropping the table */
|
/* prepare distributedTableObject for dropping the table */
|
||||||
ObjectAddress distributedTableObject = { InvalidOid, InvalidOid, 0 };
|
ObjectAddress *distributedTableObject = palloc0(sizeof(ObjectAddress));
|
||||||
distributedTableObject.classId = RelationRelationId;
|
ObjectAddressSet(*distributedTableObject, RelationRelationId, relationId);
|
||||||
distributedTableObject.objectId = relationId;
|
if (IsAnyObjectAddressOwnedByExtension(list_make1(distributedTableObject), NULL))
|
||||||
distributedTableObject.objectSubId = 0;
|
|
||||||
|
|
||||||
if (IsObjectAddressOwnedByExtension(&distributedTableObject, NULL))
|
|
||||||
{
|
{
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Drop dependent sequences from pg_dist_object */
|
/* Drop dependent sequences from pg_dist_object */
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
List *ownedSequences = getOwnedSequences(relationId);
|
List *ownedSequences = getOwnedSequences(relationId);
|
||||||
#else
|
|
||||||
List *ownedSequences = getOwnedSequences(relationId, InvalidAttrNumber);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Oid ownedSequenceOid = InvalidOid;
|
Oid ownedSequenceOid = InvalidOid;
|
||||||
foreach_oid(ownedSequenceOid, ownedSequences)
|
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.
|
* 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);
|
PERFORM_DELETION_INTERNAL);
|
||||||
|
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
|
@ -301,11 +284,7 @@ worker_drop_sequence_dependency(PG_FUNCTION_ARGS)
|
||||||
EnsureTableOwner(relationId);
|
EnsureTableOwner(relationId);
|
||||||
|
|
||||||
/* break the dependent sequences from the table */
|
/* break the dependent sequences from the table */
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
List *ownedSequences = getOwnedSequences(relationId);
|
List *ownedSequences = getOwnedSequences(relationId);
|
||||||
#else
|
|
||||||
List *ownedSequences = getOwnedSequences(relationId, InvalidAttrNumber);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Oid ownedSequenceOid = InvalidOid;
|
Oid ownedSequenceOid = InvalidOid;
|
||||||
foreach_oid(ownedSequenceOid, ownedSequences)
|
foreach_oid(ownedSequenceOid, ownedSequences)
|
||||||
|
@ -324,59 +303,3 @@ worker_drop_sequence_dependency(PG_FUNCTION_ARGS)
|
||||||
|
|
||||||
PG_RETURN_VOID();
|
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* */
|
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -50,8 +50,4 @@
|
||||||
#define ExplainPropertyLong(qlabel, value, es) \
|
#define ExplainPropertyLong(qlabel, value, es) \
|
||||||
ExplainPropertyInteger(qlabel, NULL, 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 */
|
#endif /* COLUMNAR_COMPAT_H */
|
||||||
|
|
|
@ -45,6 +45,8 @@ typedef struct BackendData
|
||||||
} BackendData;
|
} BackendData;
|
||||||
|
|
||||||
|
|
||||||
|
extern void BackendManagementShmemInit(void);
|
||||||
|
extern size_t BackendManagementShmemSize(void);
|
||||||
extern void InitializeBackendManagement(void);
|
extern void InitializeBackendManagement(void);
|
||||||
extern int TotalProcCount(void);
|
extern int TotalProcCount(void);
|
||||||
extern void InitializeBackendData(void);
|
extern void InitializeBackendData(void);
|
||||||
|
|
|
@ -63,7 +63,7 @@ typedef struct DistributeObjectOps
|
||||||
void (*qualify)(Node *);
|
void (*qualify)(Node *);
|
||||||
List * (*preprocess)(Node *, const char *, ProcessUtilityContext);
|
List * (*preprocess)(Node *, const char *, ProcessUtilityContext);
|
||||||
List * (*postprocess)(Node *, const char *);
|
List * (*postprocess)(Node *, const char *);
|
||||||
ObjectAddress (*address)(Node *, bool);
|
List * (*address)(Node *, bool);
|
||||||
bool markDistributed;
|
bool markDistributed;
|
||||||
|
|
||||||
/* fields used by common implementations, omitted for specialized implementations */
|
/* fields used by common implementations, omitted for specialized implementations */
|
||||||
|
@ -159,24 +159,24 @@ extern bool CallDistributedProcedureRemotely(CallStmt *callStmt, DestReceiver *d
|
||||||
/* collation.c - forward declarations */
|
/* collation.c - forward declarations */
|
||||||
extern char * CreateCollationDDL(Oid collationId);
|
extern char * CreateCollationDDL(Oid collationId);
|
||||||
extern List * CreateCollationDDLsIdempotent(Oid collationId);
|
extern List * CreateCollationDDLsIdempotent(Oid collationId);
|
||||||
extern ObjectAddress AlterCollationOwnerObjectAddress(Node *stmt, bool missing_ok);
|
extern List * AlterCollationOwnerObjectAddress(Node *stmt, bool missing_ok);
|
||||||
extern ObjectAddress RenameCollationStmtObjectAddress(Node *stmt, bool missing_ok);
|
extern List * RenameCollationStmtObjectAddress(Node *stmt, bool missing_ok);
|
||||||
extern ObjectAddress AlterCollationSchemaStmtObjectAddress(Node *stmt,
|
extern List * AlterCollationSchemaStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern char * GenerateBackupNameForCollationCollision(const ObjectAddress *address);
|
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 */
|
/* 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);
|
extern List * DatabaseOwnerDDLCommands(const ObjectAddress *address);
|
||||||
|
|
||||||
/* domain.c - forward declarations */
|
/* domain.c - forward declarations */
|
||||||
extern ObjectAddress CreateDomainStmtObjectAddress(Node *node, bool missing_ok);
|
extern List * CreateDomainStmtObjectAddress(Node *node, bool missing_ok);
|
||||||
extern ObjectAddress AlterDomainStmtObjectAddress(Node *node, bool missing_ok);
|
extern List * AlterDomainStmtObjectAddress(Node *node, bool missing_ok);
|
||||||
extern ObjectAddress DomainRenameConstraintStmtObjectAddress(Node *node,
|
extern List * DomainRenameConstraintStmtObjectAddress(Node *node,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress AlterDomainOwnerStmtObjectAddress(Node *node, bool missing_ok);
|
extern List * AlterDomainOwnerStmtObjectAddress(Node *node, bool missing_ok);
|
||||||
extern ObjectAddress RenameDomainStmtObjectAddress(Node *node, bool missing_ok);
|
extern List * RenameDomainStmtObjectAddress(Node *node, bool missing_ok);
|
||||||
extern CreateDomainStmt * RecreateDomainStmt(Oid domainOid);
|
extern CreateDomainStmt * RecreateDomainStmt(Oid domainOid);
|
||||||
extern Oid get_constraint_typid(Oid conoid);
|
extern Oid get_constraint_typid(Oid conoid);
|
||||||
|
|
||||||
|
@ -208,9 +208,9 @@ extern List * PreprocessAlterExtensionContentsStmt(Node *node,
|
||||||
ProcessUtilityContext
|
ProcessUtilityContext
|
||||||
processUtilityContext);
|
processUtilityContext);
|
||||||
extern List * CreateExtensionDDLCommand(const ObjectAddress *extensionAddress);
|
extern List * CreateExtensionDDLCommand(const ObjectAddress *extensionAddress);
|
||||||
extern ObjectAddress AlterExtensionSchemaStmtObjectAddress(Node *stmt,
|
extern List * AlterExtensionSchemaStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress AlterExtensionUpdateStmtObjectAddress(Node *stmt,
|
extern List * AlterExtensionUpdateStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern void CreateExtensionWithVersion(char *extname, char *extVersion);
|
extern void CreateExtensionWithVersion(char *extname, char *extVersion);
|
||||||
extern void AlterExtensionUpdateStmt(char *extname, char *extVersion);
|
extern void AlterExtensionUpdateStmt(char *extname, char *extVersion);
|
||||||
|
@ -263,10 +263,10 @@ extern Acl * GetPrivilegesForFDW(Oid FDWOid);
|
||||||
extern List * PreprocessGrantOnForeignServerStmt(Node *node, const char *queryString,
|
extern List * PreprocessGrantOnForeignServerStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext
|
ProcessUtilityContext
|
||||||
processUtilityContext);
|
processUtilityContext);
|
||||||
extern ObjectAddress CreateForeignServerStmtObjectAddress(Node *node, bool missing_ok);
|
extern List * CreateForeignServerStmtObjectAddress(Node *node, bool missing_ok);
|
||||||
extern ObjectAddress AlterForeignServerStmtObjectAddress(Node *node, bool missing_ok);
|
extern List * AlterForeignServerStmtObjectAddress(Node *node, bool missing_ok);
|
||||||
extern ObjectAddress RenameForeignServerStmtObjectAddress(Node *node, bool missing_ok);
|
extern List * RenameForeignServerStmtObjectAddress(Node *node, bool missing_ok);
|
||||||
extern ObjectAddress AlterForeignServerOwnerStmtObjectAddress(Node *node, bool
|
extern List * AlterForeignServerOwnerStmtObjectAddress(Node *node, bool
|
||||||
missing_ok);
|
missing_ok);
|
||||||
extern List * GetForeignServerCreateDDLCommand(Oid serverId);
|
extern List * GetForeignServerCreateDDLCommand(Oid serverId);
|
||||||
|
|
||||||
|
@ -282,25 +282,25 @@ extern List * PreprocessCreateFunctionStmt(Node *stmt, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
extern List * PostprocessCreateFunctionStmt(Node *stmt,
|
extern List * PostprocessCreateFunctionStmt(Node *stmt,
|
||||||
const char *queryString);
|
const char *queryString);
|
||||||
extern ObjectAddress CreateFunctionStmtObjectAddress(Node *stmt,
|
extern List * CreateFunctionStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress DefineAggregateStmtObjectAddress(Node *stmt,
|
extern List * DefineAggregateStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern List * PreprocessAlterFunctionStmt(Node *stmt, const char *queryString,
|
extern List * PreprocessAlterFunctionStmt(Node *stmt, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
extern ObjectAddress AlterFunctionStmtObjectAddress(Node *stmt,
|
extern List * AlterFunctionStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress RenameFunctionStmtObjectAddress(Node *stmt,
|
extern List * RenameFunctionStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress AlterFunctionOwnerObjectAddress(Node *stmt,
|
extern List * AlterFunctionOwnerObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress AlterFunctionSchemaStmtObjectAddress(Node *stmt,
|
extern List * AlterFunctionSchemaStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern List * PreprocessAlterFunctionDependsStmt(Node *stmt,
|
extern List * PreprocessAlterFunctionDependsStmt(Node *stmt,
|
||||||
const char *queryString,
|
const char *queryString,
|
||||||
ProcessUtilityContext
|
ProcessUtilityContext
|
||||||
processUtilityContext);
|
processUtilityContext);
|
||||||
extern ObjectAddress AlterFunctionDependsStmtObjectAddress(Node *stmt,
|
extern List * AlterFunctionDependsStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern List * PreprocessGrantOnFunctionStmt(Node *node, const char *queryString,
|
extern List * PreprocessGrantOnFunctionStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
|
@ -340,7 +340,7 @@ extern List * ExecuteFunctionOnEachTableIndex(Oid relationId, PGIndexProcessor
|
||||||
extern bool IsReindexWithParam_compat(ReindexStmt *stmt, char *paramName);
|
extern bool IsReindexWithParam_compat(ReindexStmt *stmt, char *paramName);
|
||||||
|
|
||||||
/* objectaddress.c - forward declarations */
|
/* objectaddress.c - forward declarations */
|
||||||
extern ObjectAddress CreateExtensionStmtObjectAddress(Node *stmt, bool missing_ok);
|
extern List * CreateExtensionStmtObjectAddress(Node *stmt, bool missing_ok);
|
||||||
|
|
||||||
|
|
||||||
/* policy.c - forward declarations */
|
/* policy.c - forward declarations */
|
||||||
|
@ -376,9 +376,9 @@ extern List * PostprocessAlterRoleStmt(Node *stmt, const char *queryString);
|
||||||
extern List * PreprocessAlterRoleSetStmt(Node *stmt, const char *queryString,
|
extern List * PreprocessAlterRoleSetStmt(Node *stmt, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
extern List * GenerateAlterRoleSetCommandForRole(Oid roleid);
|
extern List * GenerateAlterRoleSetCommandForRole(Oid roleid);
|
||||||
extern ObjectAddress AlterRoleStmtObjectAddress(Node *node,
|
extern List * AlterRoleStmtObjectAddress(Node *node,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress AlterRoleSetStmtObjectAddress(Node *node,
|
extern List * AlterRoleSetStmtObjectAddress(Node *node,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern List * PreprocessCreateRoleStmt(Node *stmt, const char *queryString,
|
extern List * PreprocessCreateRoleStmt(Node *stmt, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
|
@ -388,7 +388,7 @@ extern List * PreprocessGrantRoleStmt(Node *stmt, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
extern List * PostprocessGrantRoleStmt(Node *stmt, const char *queryString);
|
extern List * PostprocessGrantRoleStmt(Node *stmt, const char *queryString);
|
||||||
extern List * GenerateCreateOrAlterRoleCommand(Oid roleOid);
|
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 void UnmarkRolesDistributed(List *roles);
|
||||||
extern List * FilterDistributedRoles(List *roles);
|
extern List * FilterDistributedRoles(List *roles);
|
||||||
|
|
||||||
|
@ -402,8 +402,8 @@ extern List * PreprocessAlterObjectSchemaStmt(Node *alterObjectSchemaStmt,
|
||||||
const char *alterObjectSchemaCommand);
|
const char *alterObjectSchemaCommand);
|
||||||
extern List * PreprocessGrantOnSchemaStmt(Node *node, const char *queryString,
|
extern List * PreprocessGrantOnSchemaStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
extern ObjectAddress CreateSchemaStmtObjectAddress(Node *node, bool missing_ok);
|
extern List * CreateSchemaStmtObjectAddress(Node *node, bool missing_ok);
|
||||||
extern ObjectAddress AlterSchemaRenameStmtObjectAddress(Node *node, bool missing_ok);
|
extern List * AlterSchemaRenameStmtObjectAddress(Node *node, bool missing_ok);
|
||||||
|
|
||||||
/* sequence.c - forward declarations */
|
/* sequence.c - forward declarations */
|
||||||
extern List * PreprocessAlterSequenceStmt(Node *node, const char *queryString,
|
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,
|
extern List * PreprocessGrantOnSequenceStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
extern List * PostprocessGrantOnSequenceStmt(Node *node, const char *queryString);
|
extern List * PostprocessGrantOnSequenceStmt(Node *node, const char *queryString);
|
||||||
extern ObjectAddress AlterSequenceStmtObjectAddress(Node *node, bool missing_ok);
|
extern List * AlterSequenceStmtObjectAddress(Node *node, bool missing_ok);
|
||||||
extern ObjectAddress AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok);
|
extern List * AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok);
|
||||||
extern ObjectAddress AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok);
|
extern List * AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok);
|
||||||
extern ObjectAddress RenameSequenceStmtObjectAddress(Node *node, bool missing_ok);
|
extern List * RenameSequenceStmtObjectAddress(Node *node, bool missing_ok);
|
||||||
extern void ErrorIfUnsupportedSeqStmt(CreateSeqStmt *createSeqStmt);
|
extern void ErrorIfUnsupportedSeqStmt(CreateSeqStmt *createSeqStmt);
|
||||||
extern void ErrorIfDistributedAlterSeqOwnedBy(AlterSeqStmt *alterSeqStmt);
|
extern void ErrorIfDistributedAlterSeqOwnedBy(AlterSeqStmt *alterSeqStmt);
|
||||||
extern char * GenerateBackupNameForSequenceCollision(const ObjectAddress *address);
|
extern char * GenerateBackupNameForSequenceCollision(const ObjectAddress *address);
|
||||||
|
@ -436,7 +436,7 @@ extern void RenameExistingSequenceWithDifferentTypeIfExists(RangeVar *sequence,
|
||||||
extern List * PreprocessCreateStatisticsStmt(Node *node, const char *queryString,
|
extern List * PreprocessCreateStatisticsStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
extern List * PostprocessCreateStatisticsStmt(Node *node, const char *queryString);
|
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,
|
extern List * PreprocessDropStatisticsStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
extern List * PreprocessAlterStatisticsRenameStmt(Node *node, const char *queryString,
|
extern List * PreprocessAlterStatisticsRenameStmt(Node *node, const char *queryString,
|
||||||
|
@ -446,7 +446,7 @@ extern List * PreprocessAlterStatisticsSchemaStmt(Node *node, const char *queryS
|
||||||
ProcessUtilityContext
|
ProcessUtilityContext
|
||||||
processUtilityContext);
|
processUtilityContext);
|
||||||
extern List * PostprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString);
|
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,
|
extern List * PreprocessAlterStatisticsStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
extern List * PreprocessAlterStatisticsOwnerStmt(Node *node, const char *queryString,
|
extern List * PreprocessAlterStatisticsOwnerStmt(Node *node, const char *queryString,
|
||||||
|
@ -487,7 +487,7 @@ extern void ErrorUnsupportedAlterTableAddColumn(Oid relationId, AlterTableCmd *c
|
||||||
extern void ErrorIfUnsupportedConstraint(Relation relation, char distributionMethod,
|
extern void ErrorIfUnsupportedConstraint(Relation relation, char distributionMethod,
|
||||||
char referencingReplicationModel,
|
char referencingReplicationModel,
|
||||||
Var *distributionColumn, uint32 colocationId);
|
Var *distributionColumn, uint32 colocationId);
|
||||||
extern ObjectAddress AlterTableSchemaStmtObjectAddress(Node *stmt,
|
extern List * AlterTableSchemaStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern List * MakeNameListFromRangeVar(const RangeVar *rel);
|
extern List * MakeNameListFromRangeVar(const RangeVar *rel);
|
||||||
extern Oid GetSequenceOid(Oid relationId, AttrNumber attnum);
|
extern Oid GetSequenceOid(Oid relationId, AttrNumber attnum);
|
||||||
|
@ -499,29 +499,29 @@ extern List * GetCreateTextSearchConfigStatements(const ObjectAddress *address);
|
||||||
extern List * GetCreateTextSearchDictionaryStatements(const ObjectAddress *address);
|
extern List * GetCreateTextSearchDictionaryStatements(const ObjectAddress *address);
|
||||||
extern List * CreateTextSearchConfigDDLCommandsIdempotent(const ObjectAddress *address);
|
extern List * CreateTextSearchConfigDDLCommandsIdempotent(const ObjectAddress *address);
|
||||||
extern List * CreateTextSearchDictDDLCommandsIdempotent(const ObjectAddress *address);
|
extern List * CreateTextSearchDictDDLCommandsIdempotent(const ObjectAddress *address);
|
||||||
extern ObjectAddress CreateTextSearchConfigurationObjectAddress(Node *node,
|
extern List * CreateTextSearchConfigurationObjectAddress(Node *node,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress CreateTextSearchDictObjectAddress(Node *node,
|
extern List * CreateTextSearchDictObjectAddress(Node *node,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress RenameTextSearchConfigurationStmtObjectAddress(Node *node,
|
extern List * RenameTextSearchConfigurationStmtObjectAddress(Node *node,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress RenameTextSearchDictionaryStmtObjectAddress(Node *node,
|
extern List * RenameTextSearchDictionaryStmtObjectAddress(Node *node,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress AlterTextSearchConfigurationStmtObjectAddress(Node *node,
|
extern List * AlterTextSearchConfigurationStmtObjectAddress(Node *node,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress AlterTextSearchDictionaryStmtObjectAddress(Node *node,
|
extern List * AlterTextSearchDictionaryStmtObjectAddress(Node *node,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress AlterTextSearchConfigurationSchemaStmtObjectAddress(Node *node,
|
extern List * AlterTextSearchConfigurationSchemaStmtObjectAddress(Node *node,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress AlterTextSearchDictionarySchemaStmtObjectAddress(Node *node,
|
extern List * AlterTextSearchDictionarySchemaStmtObjectAddress(Node *node,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress TextSearchConfigurationCommentObjectAddress(Node *node,
|
extern List * TextSearchConfigurationCommentObjectAddress(Node *node,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress TextSearchDictCommentObjectAddress(Node *node,
|
extern List * TextSearchDictCommentObjectAddress(Node *node,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress AlterTextSearchConfigurationOwnerObjectAddress(Node *node,
|
extern List * AlterTextSearchConfigurationOwnerObjectAddress(Node *node,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress AlterTextSearchDictOwnerObjectAddress(Node *node,
|
extern List * AlterTextSearchDictOwnerObjectAddress(Node *node,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern char * GenerateBackupNameForTextSearchConfiguration(const ObjectAddress *address);
|
extern char * GenerateBackupNameForTextSearchConfiguration(const ObjectAddress *address);
|
||||||
extern char * GenerateBackupNameForTextSearchDict(const ObjectAddress *address);
|
extern char * GenerateBackupNameForTextSearchDict(const ObjectAddress *address);
|
||||||
|
@ -535,16 +535,16 @@ extern List * PreprocessRenameTypeAttributeStmt(Node *stmt, const char *queryStr
|
||||||
ProcessUtilityContext
|
ProcessUtilityContext
|
||||||
processUtilityContext);
|
processUtilityContext);
|
||||||
extern Node * CreateTypeStmtByObjectAddress(const ObjectAddress *address);
|
extern Node * CreateTypeStmtByObjectAddress(const ObjectAddress *address);
|
||||||
extern ObjectAddress CompositeTypeStmtObjectAddress(Node *stmt, bool missing_ok);
|
extern List * CompositeTypeStmtObjectAddress(Node *stmt, bool missing_ok);
|
||||||
extern ObjectAddress CreateEnumStmtObjectAddress(Node *stmt, bool missing_ok);
|
extern List * CreateEnumStmtObjectAddress(Node *stmt, bool missing_ok);
|
||||||
extern ObjectAddress AlterTypeStmtObjectAddress(Node *stmt, bool missing_ok);
|
extern List * AlterTypeStmtObjectAddress(Node *stmt, bool missing_ok);
|
||||||
extern ObjectAddress AlterEnumStmtObjectAddress(Node *stmt, bool missing_ok);
|
extern List * AlterEnumStmtObjectAddress(Node *stmt, bool missing_ok);
|
||||||
extern ObjectAddress RenameTypeStmtObjectAddress(Node *stmt, bool missing_ok);
|
extern List * RenameTypeStmtObjectAddress(Node *stmt, bool missing_ok);
|
||||||
extern ObjectAddress AlterTypeSchemaStmtObjectAddress(Node *stmt,
|
extern List * AlterTypeSchemaStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress RenameTypeAttributeStmtObjectAddress(Node *stmt,
|
extern List * RenameTypeAttributeStmtObjectAddress(Node *stmt,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
extern ObjectAddress AlterTypeOwnerObjectAddress(Node *stmt, bool missing_ok);
|
extern List * AlterTypeOwnerObjectAddress(Node *stmt, bool missing_ok);
|
||||||
extern List * CreateTypeDDLCommandsIdempotent(const ObjectAddress *typeAddress);
|
extern List * CreateTypeDDLCommandsIdempotent(const ObjectAddress *typeAddress);
|
||||||
extern char * GenerateBackupNameForTypeCollision(const ObjectAddress *address);
|
extern char * GenerateBackupNameForTypeCollision(const ObjectAddress *address);
|
||||||
|
|
||||||
|
@ -565,8 +565,8 @@ extern List * PostprocessVacuumStmt(Node *node, const char *vacuumCommand);
|
||||||
extern List * PreprocessViewStmt(Node *node, const char *queryString,
|
extern List * PreprocessViewStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
extern List * PostprocessViewStmt(Node *node, const char *queryString);
|
extern List * PostprocessViewStmt(Node *node, const char *queryString);
|
||||||
extern ObjectAddress ViewStmtObjectAddress(Node *node, bool missing_ok);
|
extern List * ViewStmtObjectAddress(Node *node, bool missing_ok);
|
||||||
extern ObjectAddress AlterViewStmtObjectAddress(Node *node, bool missing_ok);
|
extern List * AlterViewStmtObjectAddress(Node *node, bool missing_ok);
|
||||||
extern List * PreprocessDropViewStmt(Node *node, const char *queryString,
|
extern List * PreprocessDropViewStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
extern char * CreateViewDDLCommand(Oid viewOid);
|
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 * PostprocessAlterViewStmt(Node *node, const char *queryString);
|
||||||
extern List * PreprocessRenameViewStmt(Node *node, const char *queryString,
|
extern List * PreprocessRenameViewStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
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,
|
extern List * PreprocessAlterViewSchemaStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
extern List * PostprocessAlterViewSchemaStmt(Node *node, const char *queryString);
|
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);
|
extern bool IsViewRenameStmt(RenameStmt *renameStmt);
|
||||||
|
|
||||||
/* trigger.c - forward declarations */
|
/* trigger.c - forward declarations */
|
||||||
|
@ -594,7 +594,7 @@ extern List * GetExplicitTriggerCommandList(Oid relationId);
|
||||||
extern HeapTuple GetTriggerTupleById(Oid triggerId, bool missingOk);
|
extern HeapTuple GetTriggerTupleById(Oid triggerId, bool missingOk);
|
||||||
extern List * GetExplicitTriggerIdList(Oid relationId);
|
extern List * GetExplicitTriggerIdList(Oid relationId);
|
||||||
extern List * PostprocessCreateTriggerStmt(Node *node, const char *queryString);
|
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,
|
extern void CreateTriggerEventExtendNames(CreateTrigStmt *createTriggerStmt,
|
||||||
char *schemaName, uint64 shardId);
|
char *schemaName, uint64 shardId);
|
||||||
extern List * PostprocessAlterTriggerRenameStmt(Node *node, const char *queryString);
|
extern List * PostprocessAlterTriggerRenameStmt(Node *node, const char *queryString);
|
||||||
|
|
|
@ -148,8 +148,8 @@ extern void QualifyAlterTypeOwnerStmt(Node *stmt);
|
||||||
extern char * GetTypeNamespaceNameByNameList(List *names);
|
extern char * GetTypeNamespaceNameByNameList(List *names);
|
||||||
extern Oid TypeOidGetNamespaceOid(Oid typeOid);
|
extern Oid TypeOidGetNamespaceOid(Oid typeOid);
|
||||||
|
|
||||||
extern ObjectAddress GetObjectAddressFromParseTree(Node *parseTree, bool missing_ok);
|
extern List * GetObjectAddressListFromParseTree(Node *parseTree, bool missing_ok);
|
||||||
extern ObjectAddress RenameAttributeStmtObjectAddress(Node *stmt, bool missing_ok);
|
extern List * RenameAttributeStmtObjectAddress(Node *stmt, bool missing_ok);
|
||||||
|
|
||||||
/* forward declarations for deparse_view_stmts.c */
|
/* forward declarations for deparse_view_stmts.c */
|
||||||
extern void QualifyDropViewStmt(Node *node);
|
extern void QualifyDropViewStmt(Node *node);
|
||||||
|
|
|
@ -199,16 +199,10 @@ typedef struct CitusCustomScanPath
|
||||||
} CitusCustomScanPath;
|
} CitusCustomScanPath;
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
extern PlannedStmt * distributed_planner(Query *parse,
|
extern PlannedStmt * distributed_planner(Query *parse,
|
||||||
const char *query_string,
|
const char *query_string,
|
||||||
int cursorOptions,
|
int cursorOptions,
|
||||||
ParamListInfo boundParams);
|
ParamListInfo boundParams);
|
||||||
#else
|
|
||||||
extern PlannedStmt * distributed_planner(Query *parse,
|
|
||||||
int cursorOptions,
|
|
||||||
ParamListInfo boundParams);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -145,10 +145,7 @@ typedef struct ListCellAndListWrapper
|
||||||
*
|
*
|
||||||
* For more information, see postgres commit with sha
|
* For more information, see postgres commit with sha
|
||||||
* 1cff1b95ab6ddae32faa3efe0d95a820dbfdc164
|
* 1cff1b95ab6ddae32faa3efe0d95a820dbfdc164
|
||||||
*/
|
*
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
|
|
||||||
/*
|
|
||||||
* How it works:
|
* How it works:
|
||||||
* - An index is declared with the name {var}PositionDoNotUse and used
|
* - An index is declared with the name {var}PositionDoNotUse and used
|
||||||
* throughout the for loop using ## to concat.
|
* throughout the for loop using ## to concat.
|
||||||
|
@ -162,9 +159,6 @@ typedef struct ListCellAndListWrapper
|
||||||
(var ## PositionDoNotUse) < list_length(l) && \
|
(var ## PositionDoNotUse) < list_length(l) && \
|
||||||
(((var) = list_nth(l, var ## PositionDoNotUse)) || true); \
|
(((var) = list_nth(l, var ## PositionDoNotUse)) || true); \
|
||||||
var ## PositionDoNotUse ++)
|
var ## PositionDoNotUse ++)
|
||||||
#else
|
|
||||||
#define foreach_ptr_append(var, l) foreach_ptr(var, l)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* utility functions declaration shared within this module */
|
/* utility functions declaration shared within this module */
|
||||||
extern List * SortList(List *pointerList,
|
extern List * SortList(List *pointerList,
|
||||||
|
|
|
@ -24,6 +24,8 @@ extern double DistributedDeadlockDetectionTimeoutFactor;
|
||||||
extern void StopMaintenanceDaemon(Oid databaseId);
|
extern void StopMaintenanceDaemon(Oid databaseId);
|
||||||
extern void TriggerNodeMetadataSync(Oid databaseId);
|
extern void TriggerNodeMetadataSync(Oid databaseId);
|
||||||
extern void InitializeMaintenanceDaemon(void);
|
extern void InitializeMaintenanceDaemon(void);
|
||||||
|
extern size_t MaintenanceDaemonShmemSize(void);
|
||||||
|
extern void MaintenanceDaemonShmemInit(void);
|
||||||
extern void InitializeMaintenanceDaemonBackend(void);
|
extern void InitializeMaintenanceDaemonBackend(void);
|
||||||
extern bool LockCitusExtension(void);
|
extern bool LockCitusExtension(void);
|
||||||
|
|
||||||
|
|
|
@ -23,10 +23,9 @@ extern List * GetUniqueDependenciesList(List *objectAddressesList);
|
||||||
extern List * GetDependenciesForObject(const ObjectAddress *target);
|
extern List * GetDependenciesForObject(const ObjectAddress *target);
|
||||||
extern List * GetAllSupportedDependenciesForObject(const ObjectAddress *target);
|
extern List * GetAllSupportedDependenciesForObject(const ObjectAddress *target);
|
||||||
extern List * GetAllDependenciesForObject(const ObjectAddress *target);
|
extern List * GetAllDependenciesForObject(const ObjectAddress *target);
|
||||||
extern bool ErrorOrWarnIfObjectHasUnsupportedDependency(ObjectAddress *objectAddress);
|
extern bool ErrorOrWarnIfAnyObjectHasUnsupportedDependency(List *objectAddresses);
|
||||||
extern DeferredErrorMessage * DeferErrorIfHasUnsupportedDependency(const
|
extern DeferredErrorMessage * DeferErrorIfAnyObjectHasUnsupportedDependency(const List *
|
||||||
ObjectAddress *
|
objectAddresses);
|
||||||
objectAddress);
|
|
||||||
extern List * OrderObjectAddressListInDependencyOrder(List *objectAddressList);
|
extern List * OrderObjectAddressListInDependencyOrder(List *objectAddressList);
|
||||||
extern bool SupportedDependencyByCitus(const ObjectAddress *address);
|
extern bool SupportedDependencyByCitus(const ObjectAddress *address);
|
||||||
extern List * GetPgDependTuplesForDependingObjects(Oid targetObjectClassId,
|
extern List * GetPgDependTuplesForDependingObjects(Oid targetObjectClassId,
|
||||||
|
|
|
@ -20,14 +20,14 @@
|
||||||
|
|
||||||
extern bool ObjectExists(const ObjectAddress *address);
|
extern bool ObjectExists(const ObjectAddress *address);
|
||||||
extern bool CitusExtensionObject(const ObjectAddress *objectAddress);
|
extern bool CitusExtensionObject(const ObjectAddress *objectAddress);
|
||||||
extern bool IsObjectDistributed(const ObjectAddress *address);
|
extern bool IsAnyObjectDistributed(const List *addresses);
|
||||||
extern bool ClusterHasDistributedFunctionWithDistArgument(void);
|
extern bool ClusterHasDistributedFunctionWithDistArgument(void);
|
||||||
extern void MarkObjectDistributed(const ObjectAddress *distAddress);
|
extern void MarkObjectDistributed(const ObjectAddress *distAddress);
|
||||||
extern void MarkObjectDistributedViaSuperUser(const ObjectAddress *distAddress);
|
extern void MarkObjectDistributedViaSuperUser(const ObjectAddress *distAddress);
|
||||||
extern void MarkObjectDistributedLocally(const ObjectAddress *distAddress);
|
extern void MarkObjectDistributedLocally(const ObjectAddress *distAddress);
|
||||||
extern void UnmarkObjectDistributed(const ObjectAddress *address);
|
extern void UnmarkObjectDistributed(const ObjectAddress *address);
|
||||||
extern bool IsTableOwnedByExtension(Oid relationId);
|
extern bool IsTableOwnedByExtension(Oid relationId);
|
||||||
extern bool IsObjectAddressOwnedByExtension(const ObjectAddress *target,
|
extern bool IsAnyObjectAddressOwnedByExtension(const List *targets,
|
||||||
ObjectAddress *extensionAddress);
|
ObjectAddress *extensionAddress);
|
||||||
extern ObjectAddress PgGetObjectAddress(char *ttype, ArrayType *namearr,
|
extern ObjectAddress PgGetObjectAddress(char *ttype, ArrayType *namearr,
|
||||||
ArrayType *argsarr);
|
ArrayType *argsarr);
|
||||||
|
|
|
@ -258,15 +258,15 @@ extern void CreateDistributedTable(Oid relationId, char *distributionColumnName,
|
||||||
extern void CreateTruncateTrigger(Oid relationId);
|
extern void CreateTruncateTrigger(Oid relationId);
|
||||||
extern TableConversionReturn * UndistributeTable(TableConversionParameters *params);
|
extern TableConversionReturn * UndistributeTable(TableConversionParameters *params);
|
||||||
|
|
||||||
extern void EnsureDependenciesExistOnAllNodes(const ObjectAddress *target);
|
extern void EnsureAllObjectDependenciesExistOnAllNodes(const List *targets);
|
||||||
extern DeferredErrorMessage * DeferErrorIfCircularDependencyExists(const
|
extern DeferredErrorMessage * DeferErrorIfCircularDependencyExists(const
|
||||||
ObjectAddress *
|
ObjectAddress *
|
||||||
objectAddress);
|
objectAddress);
|
||||||
extern List * GetDistributableDependenciesForObject(const ObjectAddress *target);
|
extern List * GetDistributableDependenciesForObject(const ObjectAddress *target);
|
||||||
extern List * GetDependencyCreateDDLCommands(const ObjectAddress *dependency);
|
extern List * GetAllDependencyCreateDDLCommands(const List *dependencies);
|
||||||
extern bool ShouldPropagate(void);
|
extern bool ShouldPropagate(void);
|
||||||
extern bool ShouldPropagateCreateInCoordinatedTransction(void);
|
extern bool ShouldPropagateCreateInCoordinatedTransction(void);
|
||||||
extern bool ShouldPropagateObject(const ObjectAddress *address);
|
extern bool ShouldPropagateAnyObject(List *addresses);
|
||||||
extern List * ReplicateAllObjectsToNodeCommandList(const char *nodeName, int nodePort);
|
extern List * ReplicateAllObjectsToNodeCommandList(const char *nodeName, int nodePort);
|
||||||
|
|
||||||
/* Remaining metadata utility functions */
|
/* Remaining metadata utility functions */
|
||||||
|
|
|
@ -178,9 +178,7 @@ typedef struct MultiExtendedOp
|
||||||
List *sortClauseList;
|
List *sortClauseList;
|
||||||
Node *limitCount;
|
Node *limitCount;
|
||||||
Node *limitOffset;
|
Node *limitOffset;
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
LimitOption limitOption;
|
LimitOption limitOption;
|
||||||
#endif
|
|
||||||
Node *havingQual;
|
Node *havingQual;
|
||||||
List *distinctClause;
|
List *distinctClause;
|
||||||
List *windowClause;
|
List *windowClause;
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#ifndef PG_VERSION_CONSTANTS
|
#ifndef PG_VERSION_CONSTANTS
|
||||||
#define PG_VERSION_CONSTANTS
|
#define PG_VERSION_CONSTANTS
|
||||||
|
|
||||||
#define PG_VERSION_12 120000
|
|
||||||
#define PG_VERSION_13 130000
|
#define PG_VERSION_13 130000
|
||||||
#define PG_VERSION_14 140000
|
#define PG_VERSION_14 140000
|
||||||
#define PG_VERSION_15 150000
|
#define PG_VERSION_15 150000
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
|
|
||||||
#include "distributed/multi_server_executor.h"
|
#include "distributed/multi_server_executor.h"
|
||||||
|
|
||||||
|
#define STATS_SHARED_MEM_NAME "citus_query_stats"
|
||||||
|
|
||||||
|
extern Size CitusQueryStatsSharedMemSize(void);
|
||||||
extern void InitializeCitusQueryStats(void);
|
extern void InitializeCitusQueryStats(void);
|
||||||
extern void CitusQueryStatsExecutorsEntry(uint64 queryId, MultiExecutorType executorType,
|
extern void CitusQueryStatsExecutorsEntry(uint64 queryId, MultiExecutorType executorType,
|
||||||
char *partitionKey);
|
char *partitionKey);
|
||||||
|
|
|
@ -47,8 +47,8 @@ typedef struct ShardSplitInfo
|
||||||
} ShardSplitInfo;
|
} ShardSplitInfo;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SplitShard API to split a given shard (or shard group) in blocking / non-blocking fashion
|
* SplitShard API to split a given shard (or shard group) using split mode and
|
||||||
* based on specified split points to a set of destination nodes.
|
* specified split points to a set of destination nodes.
|
||||||
*/
|
*/
|
||||||
extern void SplitShard(SplitMode splitMode,
|
extern void SplitShard(SplitMode splitMode,
|
||||||
SplitOperation splitOperation,
|
SplitOperation splitOperation,
|
||||||
|
|
|
@ -25,6 +25,8 @@ extern int MaxClientConnections;
|
||||||
extern void InitializeSharedConnectionStats(void);
|
extern void InitializeSharedConnectionStats(void);
|
||||||
extern void WaitForSharedConnection(void);
|
extern void WaitForSharedConnection(void);
|
||||||
extern void WakeupWaiterBackendsForSharedConnection(void);
|
extern void WakeupWaiterBackendsForSharedConnection(void);
|
||||||
|
extern size_t SharedConnectionStatsShmemSize(void);
|
||||||
|
extern void SharedConnectionStatsShmemInit(void);
|
||||||
extern int GetMaxClientConnections(void);
|
extern int GetMaxClientConnections(void);
|
||||||
extern int GetMaxSharedPoolSize(void);
|
extern int GetMaxSharedPoolSize(void);
|
||||||
extern int GetLocalSharedPoolSize(void);
|
extern int GetLocalSharedPoolSize(void);
|
||||||
|
|
|
@ -24,14 +24,10 @@
|
||||||
#include "parser/parse_func.h"
|
#include "parser/parse_func.h"
|
||||||
#include "optimizer/optimizer.h"
|
#include "optimizer/optimizer.h"
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_13)
|
|
||||||
#include "tcop/tcopprot.h"
|
#include "tcop/tcopprot.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pg_version_compat.h"
|
#include "pg_version_compat.h"
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_12
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
File fd;
|
File fd;
|
||||||
|
@ -76,6 +72,4 @@ FileCompatFromFileStart(File fileDesc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* PG12 */
|
|
||||||
|
|
||||||
#endif /* VERSION_COMPAT_H */
|
#endif /* VERSION_COMPAT_H */
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue