mirror of https://github.com/citusdata/citus.git
Drops PG14 support (#7753)
DESCRIPTION: Drops PG14 support 1. Remove "$version_num" != 'xx' from configure file 2. delete all PG_VERSION_NUM = PG_VERSION_XX references in the code 3. Look at pg_version_compat.h file, remove all _compat functions etc defined specifically for PGXX differences 4. delete all PG_VERSION_NUM >= PG_VERSION_(XX+1), PG_VERSION_NUM < PG_VERSION_(XX+1) ifs in the codebase 5. delete ruleutils_xx.c file 6. cleanup normalize.sed file from pg14 specific lines 7. delete all alternative output files for that particular PG version, server_version_ge variable helps herepull/7922/head
parent
d5618b6b4c
commit
3b1c082791
|
@ -25,8 +25,6 @@ configure -whitespace
|
||||||
|
|
||||||
# except these exceptions...
|
# except these exceptions...
|
||||||
src/backend/distributed/utils/citus_outfuncs.c -citus-style
|
src/backend/distributed/utils/citus_outfuncs.c -citus-style
|
||||||
src/backend/distributed/deparser/ruleutils_13.c -citus-style
|
|
||||||
src/backend/distributed/deparser/ruleutils_14.c -citus-style
|
|
||||||
src/backend/distributed/deparser/ruleutils_15.c -citus-style
|
src/backend/distributed/deparser/ruleutils_15.c -citus-style
|
||||||
src/backend/distributed/deparser/ruleutils_16.c -citus-style
|
src/backend/distributed/deparser/ruleutils_16.c -citus-style
|
||||||
src/backend/distributed/deparser/ruleutils_17.c -citus-style
|
src/backend/distributed/deparser/ruleutils_17.c -citus-style
|
||||||
|
|
|
@ -33,7 +33,7 @@ jobs:
|
||||||
style_checker_tools_version: "0.8.18"
|
style_checker_tools_version: "0.8.18"
|
||||||
sql_snapshot_pg_version: "17.2"
|
sql_snapshot_pg_version: "17.2"
|
||||||
image_suffix: "-v889e4c1"
|
image_suffix: "-v889e4c1"
|
||||||
pg14_version: '{ "major": "14", "full": "14.15" }'
|
image_suffix_citus_upgrade: "-dev-2ad1f90"
|
||||||
pg15_version: '{ "major": "15", "full": "15.10" }'
|
pg15_version: '{ "major": "15", "full": "15.10" }'
|
||||||
pg16_version: '{ "major": "16", "full": "16.6" }'
|
pg16_version: '{ "major": "16", "full": "16.6" }'
|
||||||
pg17_version: '{ "major": "17", "full": "17.2" }'
|
pg17_version: '{ "major": "17", "full": "17.2" }'
|
||||||
|
@ -111,7 +111,6 @@ jobs:
|
||||||
image_suffix:
|
image_suffix:
|
||||||
- ${{ needs.params.outputs.image_suffix}}
|
- ${{ needs.params.outputs.image_suffix}}
|
||||||
pg_version:
|
pg_version:
|
||||||
- ${{ needs.params.outputs.pg14_version }}
|
|
||||||
- ${{ needs.params.outputs.pg15_version }}
|
- ${{ needs.params.outputs.pg15_version }}
|
||||||
- ${{ needs.params.outputs.pg16_version }}
|
- ${{ needs.params.outputs.pg16_version }}
|
||||||
- ${{ needs.params.outputs.pg17_version }}
|
- ${{ needs.params.outputs.pg17_version }}
|
||||||
|
@ -143,7 +142,6 @@ jobs:
|
||||||
image_name:
|
image_name:
|
||||||
- ${{ needs.params.outputs.test_image_name }}
|
- ${{ needs.params.outputs.test_image_name }}
|
||||||
pg_version:
|
pg_version:
|
||||||
- ${{ needs.params.outputs.pg14_version }}
|
|
||||||
- ${{ needs.params.outputs.pg15_version }}
|
- ${{ needs.params.outputs.pg15_version }}
|
||||||
- ${{ needs.params.outputs.pg16_version }}
|
- ${{ needs.params.outputs.pg16_version }}
|
||||||
- ${{ needs.params.outputs.pg17_version }}
|
- ${{ needs.params.outputs.pg17_version }}
|
||||||
|
@ -164,10 +162,6 @@ jobs:
|
||||||
- check-enterprise-isolation-logicalrep-2
|
- check-enterprise-isolation-logicalrep-2
|
||||||
- check-enterprise-isolation-logicalrep-3
|
- check-enterprise-isolation-logicalrep-3
|
||||||
include:
|
include:
|
||||||
- make: check-failure
|
|
||||||
pg_version: ${{ needs.params.outputs.pg14_version }}
|
|
||||||
suite: regress
|
|
||||||
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
|
||||||
- make: check-failure
|
- make: check-failure
|
||||||
pg_version: ${{ needs.params.outputs.pg15_version }}
|
pg_version: ${{ needs.params.outputs.pg15_version }}
|
||||||
suite: regress
|
suite: regress
|
||||||
|
@ -180,10 +174,6 @@ jobs:
|
||||||
pg_version: ${{ needs.params.outputs.pg17_version }}
|
pg_version: ${{ needs.params.outputs.pg17_version }}
|
||||||
suite: regress
|
suite: regress
|
||||||
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
||||||
- make: check-enterprise-failure
|
|
||||||
pg_version: ${{ needs.params.outputs.pg14_version }}
|
|
||||||
suite: regress
|
|
||||||
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
|
||||||
- make: check-enterprise-failure
|
- make: check-enterprise-failure
|
||||||
pg_version: ${{ needs.params.outputs.pg15_version }}
|
pg_version: ${{ needs.params.outputs.pg15_version }}
|
||||||
suite: regress
|
suite: regress
|
||||||
|
@ -196,10 +186,6 @@ jobs:
|
||||||
pg_version: ${{ needs.params.outputs.pg17_version }}
|
pg_version: ${{ needs.params.outputs.pg17_version }}
|
||||||
suite: regress
|
suite: regress
|
||||||
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
||||||
- make: check-pytest
|
|
||||||
pg_version: ${{ needs.params.outputs.pg14_version }}
|
|
||||||
suite: regress
|
|
||||||
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
|
||||||
- make: check-pytest
|
- make: check-pytest
|
||||||
pg_version: ${{ needs.params.outputs.pg15_version }}
|
pg_version: ${{ needs.params.outputs.pg15_version }}
|
||||||
suite: regress
|
suite: regress
|
||||||
|
@ -224,10 +210,6 @@ jobs:
|
||||||
suite: cdc
|
suite: cdc
|
||||||
image_name: ${{ needs.params.outputs.test_image_name }}
|
image_name: ${{ needs.params.outputs.test_image_name }}
|
||||||
pg_version: ${{ needs.params.outputs.pg17_version }}
|
pg_version: ${{ needs.params.outputs.pg17_version }}
|
||||||
- make: check-query-generator
|
|
||||||
pg_version: ${{ needs.params.outputs.pg14_version }}
|
|
||||||
suite: regress
|
|
||||||
image_name: ${{ needs.params.outputs.fail_test_image_name }}
|
|
||||||
- make: check-query-generator
|
- make: check-query-generator
|
||||||
pg_version: ${{ needs.params.outputs.pg15_version }}
|
pg_version: ${{ needs.params.outputs.pg15_version }}
|
||||||
suite: regress
|
suite: regress
|
||||||
|
@ -280,7 +262,6 @@ jobs:
|
||||||
image_name:
|
image_name:
|
||||||
- ${{ needs.params.outputs.fail_test_image_name }}
|
- ${{ needs.params.outputs.fail_test_image_name }}
|
||||||
pg_version:
|
pg_version:
|
||||||
- ${{ needs.params.outputs.pg14_version }}
|
|
||||||
- ${{ needs.params.outputs.pg15_version }}
|
- ${{ needs.params.outputs.pg15_version }}
|
||||||
- ${{ needs.params.outputs.pg16_version }}
|
- ${{ needs.params.outputs.pg16_version }}
|
||||||
- ${{ needs.params.outputs.pg17_version }}
|
- ${{ needs.params.outputs.pg17_version }}
|
||||||
|
@ -328,18 +309,12 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- old_pg_major: 14
|
|
||||||
new_pg_major: 15
|
|
||||||
- old_pg_major: 15
|
- old_pg_major: 15
|
||||||
new_pg_major: 16
|
new_pg_major: 16
|
||||||
- old_pg_major: 14
|
|
||||||
new_pg_major: 16
|
|
||||||
- old_pg_major: 16
|
- old_pg_major: 16
|
||||||
new_pg_major: 17
|
new_pg_major: 17
|
||||||
- old_pg_major: 15
|
- old_pg_major: 15
|
||||||
new_pg_major: 17
|
new_pg_major: 17
|
||||||
- old_pg_major: 14
|
|
||||||
new_pg_major: 17
|
|
||||||
env:
|
env:
|
||||||
old_pg_major: ${{ matrix.old_pg_major }}
|
old_pg_major: ${{ matrix.old_pg_major }}
|
||||||
new_pg_major: ${{ matrix.new_pg_major }}
|
new_pg_major: ${{ matrix.new_pg_major }}
|
||||||
|
@ -375,10 +350,10 @@ jobs:
|
||||||
flags: ${{ env.old_pg_major }}_${{ env.new_pg_major }}_upgrade
|
flags: ${{ env.old_pg_major }}_${{ env.new_pg_major }}_upgrade
|
||||||
codecov_token: ${{ secrets.CODECOV_TOKEN }}
|
codecov_token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
test-citus-upgrade:
|
test-citus-upgrade:
|
||||||
name: PG${{ fromJson(needs.params.outputs.pg14_version).major }} - check-citus-upgrade
|
name: PG${{ fromJson(needs.params.outputs.pg15_version).major }} - check-citus-upgrade
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
container:
|
container:
|
||||||
image: "${{ needs.params.outputs.citusupgrade_image_name }}:${{ fromJson(needs.params.outputs.pg14_version).full }}${{ needs.params.outputs.image_suffix }}"
|
image: "${{ needs.params.outputs.citusupgrade_image_name }}:${{ fromJson(needs.params.outputs.pg15_version).full }}${{ needs.params.outputs.image_suffix_citus_upgrade }}"
|
||||||
options: --user root
|
options: --user root
|
||||||
needs:
|
needs:
|
||||||
- params
|
- params
|
||||||
|
|
|
@ -2588,7 +2588,7 @@ fi
|
||||||
if test "$with_pg_version_check" = no; then
|
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:${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;}
|
$as_echo "$as_me: building against PostgreSQL $version_num (skipped compatibility check)" >&6;}
|
||||||
elif test "$version_num" != '14' -a "$version_num" != '15' -a "$version_num" != '16' -a "$version_num" != '17'; then
|
elif test "$version_num" != '15' -a "$version_num" != '16' -a "$version_num" != '17'; 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
|
||||||
|
|
|
@ -80,7 +80,7 @@ AC_SUBST(with_pg_version_check)
|
||||||
|
|
||||||
if test "$with_pg_version_check" = no; then
|
if test "$with_pg_version_check" = no; then
|
||||||
AC_MSG_NOTICE([building against PostgreSQL $version_num (skipped compatibility check)])
|
AC_MSG_NOTICE([building against PostgreSQL $version_num (skipped compatibility check)])
|
||||||
elif test "$version_num" != '14' -a "$version_num" != '15' -a "$version_num" != '16' -a "$version_num" != '17'; then
|
elif test "$version_num" != '15' -a "$version_num" != '16' -a "$version_num" != '17'; 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])
|
||||||
|
|
|
@ -1312,11 +1312,8 @@ AddColumnarScanPath(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte,
|
||||||
|
|
||||||
cpath->methods = &ColumnarScanPathMethods;
|
cpath->methods = &ColumnarScanPathMethods;
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/* necessary to avoid extra Result node in PG15 */
|
/* necessary to avoid extra Result node in PG15 */
|
||||||
cpath->flags = CUSTOMPATH_SUPPORT_PROJECTION;
|
cpath->flags = CUSTOMPATH_SUPPORT_PROJECTION;
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* populate generic path information
|
* populate generic path information
|
||||||
|
|
|
@ -1685,7 +1685,7 @@ DeleteTupleAndEnforceConstraints(ModifyState *state, HeapTuple heapTuple)
|
||||||
simple_heap_delete(state->rel, tid);
|
simple_heap_delete(state->rel, tid);
|
||||||
|
|
||||||
/* execute AFTER ROW DELETE Triggers to enforce constraints */
|
/* execute AFTER ROW DELETE Triggers to enforce constraints */
|
||||||
ExecARDeleteTriggers_compat(estate, resultRelInfo, tid, NULL, NULL, false);
|
ExecARDeleteTriggers(estate, resultRelInfo, tid, NULL, NULL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -877,7 +877,7 @@ columnar_relation_set_new_filelocator(Relation rel,
|
||||||
|
|
||||||
*freezeXid = RecentXmin;
|
*freezeXid = RecentXmin;
|
||||||
*minmulti = GetOldestMultiXactId();
|
*minmulti = GetOldestMultiXactId();
|
||||||
SMgrRelation srel = RelationCreateStorage_compat(*newrlocator, persistence, true);
|
SMgrRelation srel = RelationCreateStorage(*newrlocator, persistence, true);
|
||||||
|
|
||||||
ColumnarStorageInit(srel, ColumnarMetadataNewStorageId());
|
ColumnarStorageInit(srel, ColumnarMetadataNewStorageId());
|
||||||
InitColumnarOptions(rel->rd_id);
|
InitColumnarOptions(rel->rd_id);
|
||||||
|
@ -2245,7 +2245,6 @@ ColumnarProcessAlterTable(AlterTableStmt *alterTableStmt, List **columnarOptions
|
||||||
columnarRangeVar = alterTableStmt->relation;
|
columnarRangeVar = alterTableStmt->relation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
else if (alterTableCmd->subtype == AT_SetAccessMethod)
|
else if (alterTableCmd->subtype == AT_SetAccessMethod)
|
||||||
{
|
{
|
||||||
if (columnarRangeVar || *columnarOptions)
|
if (columnarRangeVar || *columnarOptions)
|
||||||
|
@ -2265,7 +2264,6 @@ ColumnarProcessAlterTable(AlterTableStmt *alterTableStmt, List **columnarOptions
|
||||||
DeleteColumnarTableOptions(RelationGetRelid(rel), true);
|
DeleteColumnarTableOptions(RelationGetRelid(rel), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* PG_VERSION_15 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
relation_close(rel, NoLock);
|
relation_close(rel, NoLock);
|
||||||
|
@ -2649,21 +2647,12 @@ ColumnarCheckLogicalReplication(Relation rel)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
{
|
{
|
||||||
PublicationDesc pubdesc;
|
PublicationDesc pubdesc;
|
||||||
|
|
||||||
RelationBuildPublicationDesc(rel, &pubdesc);
|
RelationBuildPublicationDesc(rel, &pubdesc);
|
||||||
pubActionInsert = pubdesc.pubactions.pubinsert;
|
pubActionInsert = pubdesc.pubactions.pubinsert;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (rel->rd_pubactions == NULL)
|
|
||||||
{
|
|
||||||
GetRelationPublicationActions(rel);
|
|
||||||
Assert(rel->rd_pubactions != NULL);
|
|
||||||
}
|
|
||||||
pubActionInsert = rel->rd_pubactions->pubinsert;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (pubActionInsert)
|
if (pubActionInsert)
|
||||||
{
|
{
|
||||||
|
|
|
@ -145,17 +145,6 @@ LogicalClockShmemSize(void)
|
||||||
void
|
void
|
||||||
InitializeClusterClockMem(void)
|
InitializeClusterClockMem(void)
|
||||||
{
|
{
|
||||||
/* On PG 15 and above, we use shmem_request_hook_type */
|
|
||||||
#if PG_VERSION_NUM < PG_VERSION_15
|
|
||||||
|
|
||||||
/* allocate shared memory for pre PG-15 versions */
|
|
||||||
if (!IsUnderPostmaster)
|
|
||||||
{
|
|
||||||
RequestAddinShmemSpace(LogicalClockShmemSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
prev_shmem_startup_hook = shmem_startup_hook;
|
prev_shmem_startup_hook = shmem_startup_hook;
|
||||||
shmem_startup_hook = LogicalClockShmemInit;
|
shmem_startup_hook = LogicalClockShmemInit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,8 +68,6 @@ CreateCollationDDLInternal(Oid collationId, Oid *collowner, char **quotedCollati
|
||||||
char *collcollate;
|
char *collcollate;
|
||||||
char *collctype;
|
char *collctype;
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In PG15, there is an added option to use ICU as global locale provider.
|
* In PG15, there is an added option to use ICU as global locale provider.
|
||||||
* pg_collation has three locale-related fields: collcollate and collctype,
|
* pg_collation has three locale-related fields: collcollate and collctype,
|
||||||
|
@ -112,16 +110,6 @@ CreateCollationDDLInternal(Oid collationId, Oid *collowner, char **quotedCollati
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert((collcollate && collctype) || colllocale);
|
Assert((collcollate && collctype) || colllocale);
|
||||||
#else
|
|
||||||
|
|
||||||
/*
|
|
||||||
* In versions before 15, collcollate and collctype were type "name". Use
|
|
||||||
* pstrdup() to match the interface of 15 so that we consistently free the
|
|
||||||
* result later.
|
|
||||||
*/
|
|
||||||
collcollate = pstrdup(NameStr(collationForm->collcollate));
|
|
||||||
collctype = pstrdup(NameStr(collationForm->collctype));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (collowner != NULL)
|
if (collowner != NULL)
|
||||||
{
|
{
|
||||||
|
@ -147,7 +135,6 @@ CreateCollationDDLInternal(Oid collationId, Oid *collowner, char **quotedCollati
|
||||||
"CREATE COLLATION %s (provider = '%s'",
|
"CREATE COLLATION %s (provider = '%s'",
|
||||||
*quotedCollationName, providerString);
|
*quotedCollationName, providerString);
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
if (colllocale)
|
if (colllocale)
|
||||||
{
|
{
|
||||||
appendStringInfo(&collationNameDef,
|
appendStringInfo(&collationNameDef,
|
||||||
|
@ -173,24 +160,7 @@ CreateCollationDDLInternal(Oid collationId, Oid *collowner, char **quotedCollati
|
||||||
pfree(collcollate);
|
pfree(collcollate);
|
||||||
pfree(collctype);
|
pfree(collctype);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (strcmp(collcollate, collctype) == 0)
|
|
||||||
{
|
|
||||||
appendStringInfo(&collationNameDef,
|
|
||||||
", locale = %s",
|
|
||||||
quote_literal_cstr(collcollate));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
appendStringInfo(&collationNameDef,
|
|
||||||
", lc_collate = %s, lc_ctype = %s",
|
|
||||||
quote_literal_cstr(collcollate),
|
|
||||||
quote_literal_cstr(collctype));
|
|
||||||
}
|
|
||||||
|
|
||||||
pfree(collcollate);
|
|
||||||
pfree(collctype);
|
|
||||||
#endif
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_16
|
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||||
char *collicurules = NULL;
|
char *collicurules = NULL;
|
||||||
datum = SysCacheGetAttr(COLLOID, heapTuple, Anum_pg_collation_collicurules, &isnull);
|
datum = SysCacheGetAttr(COLLOID, heapTuple, Anum_pg_collation_collicurules, &isnull);
|
||||||
|
|
|
@ -170,12 +170,10 @@ static void EnsureDistributedSequencesHaveOneType(Oid relationId,
|
||||||
static void CopyLocalDataIntoShards(Oid distributedTableId);
|
static void CopyLocalDataIntoShards(Oid distributedTableId);
|
||||||
static List * TupleDescColumnNameList(TupleDesc tupleDescriptor);
|
static List * TupleDescColumnNameList(TupleDesc tupleDescriptor);
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
static bool DistributionColumnUsesNumericColumnNegativeScale(TupleDesc relationDesc,
|
static bool DistributionColumnUsesNumericColumnNegativeScale(TupleDesc relationDesc,
|
||||||
Var *distributionColumn);
|
Var *distributionColumn);
|
||||||
static int numeric_typmod_scale(int32 typmod);
|
static int numeric_typmod_scale(int32 typmod);
|
||||||
static bool is_valid_numeric_typmod(int32 typmod);
|
static bool is_valid_numeric_typmod(int32 typmod);
|
||||||
#endif
|
|
||||||
|
|
||||||
static bool DistributionColumnUsesGeneratedStoredColumn(TupleDesc relationDesc,
|
static bool DistributionColumnUsesGeneratedStoredColumn(TupleDesc relationDesc,
|
||||||
Var *distributionColumn);
|
Var *distributionColumn);
|
||||||
|
@ -2114,8 +2112,6 @@ EnsureRelationCanBeDistributed(Oid relationId, Var *distributionColumn,
|
||||||
"AS (...) STORED.")));
|
"AS (...) STORED.")));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/* verify target relation is not distributed by a column of type numeric with negative scale */
|
/* verify target relation is not distributed by a column of type numeric with negative scale */
|
||||||
if (distributionMethod != DISTRIBUTE_BY_NONE &&
|
if (distributionMethod != DISTRIBUTE_BY_NONE &&
|
||||||
DistributionColumnUsesNumericColumnNegativeScale(relationDesc,
|
DistributionColumnUsesNumericColumnNegativeScale(relationDesc,
|
||||||
|
@ -2126,7 +2122,6 @@ EnsureRelationCanBeDistributed(Oid relationId, Var *distributionColumn,
|
||||||
errdetail("Distribution column must not use numeric type "
|
errdetail("Distribution column must not use numeric type "
|
||||||
"with negative scale")));
|
"with negative scale")));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* check for support function needed by specified partition method */
|
/* check for support function needed by specified partition method */
|
||||||
if (distributionMethod == DISTRIBUTE_BY_HASH)
|
if (distributionMethod == DISTRIBUTE_BY_HASH)
|
||||||
|
@ -2844,8 +2839,6 @@ TupleDescColumnNameList(TupleDesc tupleDescriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* is_valid_numeric_typmod checks if the typmod value is valid
|
* is_valid_numeric_typmod checks if the typmod value is valid
|
||||||
*
|
*
|
||||||
|
@ -2895,8 +2888,6 @@ DistributionColumnUsesNumericColumnNegativeScale(TupleDesc relationDesc,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DistributionColumnUsesGeneratedStoredColumn returns whether a given relation uses
|
* DistributionColumnUsesGeneratedStoredColumn returns whether a given relation uses
|
||||||
* GENERATED ALWAYS AS (...) STORED on distribution column
|
* GENERATED ALWAYS AS (...) STORED on distribution column
|
||||||
|
|
|
@ -79,11 +79,8 @@ typedef struct DatabaseCollationInfo
|
||||||
{
|
{
|
||||||
char *datcollate;
|
char *datcollate;
|
||||||
char *datctype;
|
char *datctype;
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
char *daticulocale;
|
char *daticulocale;
|
||||||
char *datcollversion;
|
char *datcollversion;
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_16
|
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||||
char *daticurules;
|
char *daticurules;
|
||||||
|
@ -94,9 +91,7 @@ static char * GenerateCreateDatabaseStatementFromPgDatabase(Form_pg_database
|
||||||
databaseForm);
|
databaseForm);
|
||||||
static DatabaseCollationInfo GetDatabaseCollation(Oid dbOid);
|
static DatabaseCollationInfo GetDatabaseCollation(Oid dbOid);
|
||||||
static AlterOwnerStmt * RecreateAlterDatabaseOwnerStmt(Oid databaseOid);
|
static AlterOwnerStmt * RecreateAlterDatabaseOwnerStmt(Oid databaseOid);
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
static char * GetLocaleProviderString(char datlocprovider);
|
static char * GetLocaleProviderString(char datlocprovider);
|
||||||
#endif
|
|
||||||
static char * GetTablespaceName(Oid tablespaceOid);
|
static char * GetTablespaceName(Oid tablespaceOid);
|
||||||
static ObjectAddress * GetDatabaseAddressFromDatabaseName(char *databaseName,
|
static ObjectAddress * GetDatabaseAddressFromDatabaseName(char *databaseName,
|
||||||
bool missingOk);
|
bool missingOk);
|
||||||
|
@ -320,8 +315,6 @@ PreprocessAlterDatabaseStmt(Node *node, const char *queryString,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PreprocessAlterDatabaseRefreshCollStmt is executed before the statement is applied to
|
* PreprocessAlterDatabaseRefreshCollStmt is executed before the statement is applied to
|
||||||
* the local postgres instance.
|
* the local postgres instance.
|
||||||
|
@ -359,9 +352,6 @@ PreprocessAlterDatabaseRefreshCollStmt(Node *node, const char *queryString,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PreprocessAlterDatabaseRenameStmt is executed before the statement is applied to
|
* PreprocessAlterDatabaseRenameStmt is executed before the statement is applied to
|
||||||
* the local postgres instance.
|
* the local postgres instance.
|
||||||
|
@ -849,8 +839,6 @@ GetDatabaseCollation(Oid dbOid)
|
||||||
Datum ctypeDatum = heap_getattr(tup, Anum_pg_database_datctype, tupdesc, &isNull);
|
Datum ctypeDatum = heap_getattr(tup, Anum_pg_database_datctype, tupdesc, &isNull);
|
||||||
info.datctype = TextDatumGetCString(ctypeDatum);
|
info.datctype = TextDatumGetCString(ctypeDatum);
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
|
|
||||||
Datum icuLocaleDatum = heap_getattr(tup, Anum_pg_database_daticulocale, tupdesc,
|
Datum icuLocaleDatum = heap_getattr(tup, Anum_pg_database_daticulocale, tupdesc,
|
||||||
&isNull);
|
&isNull);
|
||||||
if (!isNull)
|
if (!isNull)
|
||||||
|
@ -864,7 +852,6 @@ GetDatabaseCollation(Oid dbOid)
|
||||||
{
|
{
|
||||||
info.datcollversion = TextDatumGetCString(collverDatum);
|
info.datcollversion = TextDatumGetCString(collverDatum);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_16
|
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||||
Datum icurulesDatum = heap_getattr(tup, Anum_pg_database_daticurules, tupdesc,
|
Datum icurulesDatum = heap_getattr(tup, Anum_pg_database_daticurules, tupdesc,
|
||||||
|
@ -882,8 +869,6 @@ GetDatabaseCollation(Oid dbOid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GetLocaleProviderString gets the datlocprovider stored in pg_database
|
* GetLocaleProviderString gets the datlocprovider stored in pg_database
|
||||||
* and returns the string representation of the datlocprovider
|
* and returns the string representation of the datlocprovider
|
||||||
|
@ -912,9 +897,6 @@ GetLocaleProviderString(char datlocprovider)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GenerateCreateDatabaseStatementFromPgDatabase gets the pg_database tuple and returns the
|
* GenerateCreateDatabaseStatementFromPgDatabase gets the pg_database tuple and returns the
|
||||||
* CREATE DATABASE statement that can be used to create given database.
|
* CREATE DATABASE statement that can be used to create given database.
|
||||||
|
@ -956,7 +938,6 @@ GenerateCreateDatabaseStatementFromPgDatabase(Form_pg_database databaseForm)
|
||||||
appendStringInfo(&str, " ENCODING = %s",
|
appendStringInfo(&str, " ENCODING = %s",
|
||||||
quote_literal_cstr(pg_encoding_to_char(databaseForm->encoding)));
|
quote_literal_cstr(pg_encoding_to_char(databaseForm->encoding)));
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
if (collInfo.datcollversion != NULL)
|
if (collInfo.datcollversion != NULL)
|
||||||
{
|
{
|
||||||
appendStringInfo(&str, " COLLATION_VERSION = %s",
|
appendStringInfo(&str, " COLLATION_VERSION = %s",
|
||||||
|
@ -972,7 +953,6 @@ GenerateCreateDatabaseStatementFromPgDatabase(Form_pg_database databaseForm)
|
||||||
appendStringInfo(&str, " LOCALE_PROVIDER = %s",
|
appendStringInfo(&str, " LOCALE_PROVIDER = %s",
|
||||||
quote_identifier(GetLocaleProviderString(
|
quote_identifier(GetLocaleProviderString(
|
||||||
databaseForm->datlocprovider)));
|
databaseForm->datlocprovider)));
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_16
|
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||||
if (collInfo.daticurules != NULL)
|
if (collInfo.daticurules != NULL)
|
||||||
|
|
|
@ -521,7 +521,6 @@ static DistributeObjectOps Database_Drop = {
|
||||||
.markDistributed = false,
|
.markDistributed = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
static DistributeObjectOps Database_RefreshColl = {
|
static DistributeObjectOps Database_RefreshColl = {
|
||||||
.deparse = DeparseAlterDatabaseRefreshCollStmt,
|
.deparse = DeparseAlterDatabaseRefreshCollStmt,
|
||||||
.qualify = NULL,
|
.qualify = NULL,
|
||||||
|
@ -532,7 +531,6 @@ static DistributeObjectOps Database_RefreshColl = {
|
||||||
.address = NULL,
|
.address = NULL,
|
||||||
.markDistributed = false,
|
.markDistributed = false,
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
static DistributeObjectOps Database_Set = {
|
static DistributeObjectOps Database_Set = {
|
||||||
.deparse = DeparseAlterDatabaseSetStmt,
|
.deparse = DeparseAlterDatabaseSetStmt,
|
||||||
|
@ -926,7 +924,6 @@ static DistributeObjectOps Sequence_AlterOwner = {
|
||||||
.address = AlterSequenceOwnerStmtObjectAddress,
|
.address = AlterSequenceOwnerStmtObjectAddress,
|
||||||
.markDistributed = false,
|
.markDistributed = false,
|
||||||
};
|
};
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
static DistributeObjectOps Sequence_AlterPersistence = {
|
static DistributeObjectOps Sequence_AlterPersistence = {
|
||||||
.deparse = DeparseAlterSequencePersistenceStmt,
|
.deparse = DeparseAlterSequencePersistenceStmt,
|
||||||
.qualify = QualifyAlterSequencePersistenceStmt,
|
.qualify = QualifyAlterSequencePersistenceStmt,
|
||||||
|
@ -936,7 +933,6 @@ static DistributeObjectOps Sequence_AlterPersistence = {
|
||||||
.address = AlterSequencePersistenceStmtObjectAddress,
|
.address = AlterSequencePersistenceStmtObjectAddress,
|
||||||
.markDistributed = false,
|
.markDistributed = false,
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
static DistributeObjectOps Sequence_Drop = {
|
static DistributeObjectOps Sequence_Drop = {
|
||||||
.deparse = DeparseDropSequenceStmt,
|
.deparse = DeparseDropSequenceStmt,
|
||||||
.qualify = QualifyDropSequenceStmt,
|
.qualify = QualifyDropSequenceStmt,
|
||||||
|
@ -1393,7 +1389,7 @@ static DistributeObjectOps View_Rename = {
|
||||||
static DistributeObjectOps Trigger_Rename = {
|
static DistributeObjectOps Trigger_Rename = {
|
||||||
.deparse = NULL,
|
.deparse = NULL,
|
||||||
.qualify = NULL,
|
.qualify = NULL,
|
||||||
.preprocess = PreprocessAlterTriggerRenameStmt,
|
.preprocess = NULL,
|
||||||
.operationType = DIST_OPS_ALTER,
|
.operationType = DIST_OPS_ALTER,
|
||||||
.postprocess = PostprocessAlterTriggerRenameStmt,
|
.postprocess = PostprocessAlterTriggerRenameStmt,
|
||||||
.address = NULL,
|
.address = NULL,
|
||||||
|
@ -1425,14 +1421,11 @@ GetDistributeObjectOps(Node *node)
|
||||||
return &Database_Drop;
|
return &Database_Drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
case T_AlterDatabaseRefreshCollStmt:
|
case T_AlterDatabaseRefreshCollStmt:
|
||||||
{
|
{
|
||||||
return &Database_RefreshColl;
|
return &Database_RefreshColl;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case T_AlterDatabaseSetStmt:
|
case T_AlterDatabaseSetStmt:
|
||||||
{
|
{
|
||||||
return &Database_Set;
|
return &Database_Set;
|
||||||
|
@ -1723,7 +1716,6 @@ GetDistributeObjectOps(Node *node)
|
||||||
|
|
||||||
case OBJECT_SEQUENCE:
|
case OBJECT_SEQUENCE:
|
||||||
{
|
{
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
ListCell *cmdCell = NULL;
|
ListCell *cmdCell = NULL;
|
||||||
foreach(cmdCell, stmt->cmds)
|
foreach(cmdCell, stmt->cmds)
|
||||||
{
|
{
|
||||||
|
@ -1751,7 +1743,6 @@ GetDistributeObjectOps(Node *node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prior to PG15, the only Alter Table statement
|
* Prior to PG15, the only Alter Table statement
|
||||||
|
|
|
@ -467,7 +467,6 @@ ForeignKeyGetDefaultingAttrs(HeapTuple pgConstraintTuple)
|
||||||
}
|
}
|
||||||
|
|
||||||
List *onDeleteSetDefColumnList = NIL;
|
List *onDeleteSetDefColumnList = NIL;
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
Datum onDeleteSetDefColumnsDatum = SysCacheGetAttr(CONSTROID, pgConstraintTuple,
|
Datum onDeleteSetDefColumnsDatum = SysCacheGetAttr(CONSTROID, pgConstraintTuple,
|
||||||
Anum_pg_constraint_confdelsetcols,
|
Anum_pg_constraint_confdelsetcols,
|
||||||
&isNull);
|
&isNull);
|
||||||
|
@ -482,7 +481,6 @@ ForeignKeyGetDefaultingAttrs(HeapTuple pgConstraintTuple)
|
||||||
onDeleteSetDefColumnList =
|
onDeleteSetDefColumnList =
|
||||||
IntegerArrayTypeToList(DatumGetArrayTypeP(onDeleteSetDefColumnsDatum));
|
IntegerArrayTypeToList(DatumGetArrayTypeP(onDeleteSetDefColumnsDatum));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (list_length(onDeleteSetDefColumnList) == 0)
|
if (list_length(onDeleteSetDefColumnList) == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,11 +33,9 @@
|
||||||
|
|
||||||
|
|
||||||
static CreatePublicationStmt * BuildCreatePublicationStmt(Oid publicationId);
|
static CreatePublicationStmt * BuildCreatePublicationStmt(Oid publicationId);
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
static PublicationObjSpec * BuildPublicationRelationObjSpec(Oid relationId,
|
static PublicationObjSpec * BuildPublicationRelationObjSpec(Oid relationId,
|
||||||
Oid publicationId,
|
Oid publicationId,
|
||||||
bool tableOnly);
|
bool tableOnly);
|
||||||
#endif
|
|
||||||
static void AppendPublishOptionList(StringInfo str, List *strings);
|
static void AppendPublishOptionList(StringInfo str, List *strings);
|
||||||
static char * AlterPublicationOwnerCommand(Oid publicationId);
|
static char * AlterPublicationOwnerCommand(Oid publicationId);
|
||||||
static bool ShouldPropagateCreatePublication(CreatePublicationStmt *stmt);
|
static bool ShouldPropagateCreatePublication(CreatePublicationStmt *stmt);
|
||||||
|
@ -154,7 +152,6 @@ BuildCreatePublicationStmt(Oid publicationId)
|
||||||
|
|
||||||
ReleaseSysCache(publicationTuple);
|
ReleaseSysCache(publicationTuple);
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
List *schemaIds = GetPublicationSchemas(publicationId);
|
List *schemaIds = GetPublicationSchemas(publicationId);
|
||||||
Oid schemaId = InvalidOid;
|
Oid schemaId = InvalidOid;
|
||||||
|
|
||||||
|
@ -170,7 +167,6 @@ BuildCreatePublicationStmt(Oid publicationId)
|
||||||
|
|
||||||
createPubStmt->pubobjects = lappend(createPubStmt->pubobjects, publicationObject);
|
createPubStmt->pubobjects = lappend(createPubStmt->pubobjects, publicationObject);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
List *relationIds = GetPublicationRelations(publicationId,
|
List *relationIds = GetPublicationRelations(publicationId,
|
||||||
publicationForm->pubviaroot ?
|
publicationForm->pubviaroot ?
|
||||||
|
@ -183,7 +179,6 @@ BuildCreatePublicationStmt(Oid publicationId)
|
||||||
|
|
||||||
foreach_declared_oid(relationId, relationIds)
|
foreach_declared_oid(relationId, relationIds)
|
||||||
{
|
{
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
bool tableOnly = false;
|
bool tableOnly = false;
|
||||||
|
|
||||||
/* since postgres 15, tables can have a column list and filter */
|
/* since postgres 15, tables can have a column list and filter */
|
||||||
|
@ -270,8 +265,6 @@ AppendPublishOptionList(StringInfo str, List *options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BuildPublicationRelationObjSpec returns a PublicationObjSpec that
|
* BuildPublicationRelationObjSpec returns a PublicationObjSpec that
|
||||||
* can be included in a CREATE or ALTER PUBLICATION statement.
|
* can be included in a CREATE or ALTER PUBLICATION statement.
|
||||||
|
@ -351,9 +344,6 @@ BuildPublicationRelationObjSpec(Oid relationId, Oid publicationId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PreprocessAlterPublicationStmt handles ALTER PUBLICATION statements
|
* PreprocessAlterPublicationStmt handles ALTER PUBLICATION statements
|
||||||
* in a way that is mostly similar to PreprocessAlterDistributedObjectStmt,
|
* in a way that is mostly similar to PreprocessAlterDistributedObjectStmt,
|
||||||
|
@ -452,7 +442,6 @@ GetAlterPublicationTableDDLCommand(Oid publicationId, Oid relationId,
|
||||||
|
|
||||||
ReleaseSysCache(pubTuple);
|
ReleaseSysCache(pubTuple);
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
bool tableOnly = !isAdd;
|
bool tableOnly = !isAdd;
|
||||||
|
|
||||||
/* since postgres 15, tables can have a column list and filter */
|
/* since postgres 15, tables can have a column list and filter */
|
||||||
|
@ -461,16 +450,6 @@ GetAlterPublicationTableDDLCommand(Oid publicationId, Oid relationId,
|
||||||
|
|
||||||
alterPubStmt->pubobjects = lappend(alterPubStmt->pubobjects, publicationObject);
|
alterPubStmt->pubobjects = lappend(alterPubStmt->pubobjects, publicationObject);
|
||||||
alterPubStmt->action = isAdd ? AP_AddObjects : AP_DropObjects;
|
alterPubStmt->action = isAdd ? AP_AddObjects : AP_DropObjects;
|
||||||
#else
|
|
||||||
|
|
||||||
/* before postgres 15, only full tables are supported */
|
|
||||||
char *schemaName = get_namespace_name(get_rel_namespace(relationId));
|
|
||||||
char *tableName = get_rel_name(relationId);
|
|
||||||
RangeVar *rangeVar = makeRangeVar(schemaName, tableName, -1);
|
|
||||||
|
|
||||||
alterPubStmt->tables = lappend(alterPubStmt->tables, rangeVar);
|
|
||||||
alterPubStmt->tableAction = isAdd ? DEFELEM_ADD : DEFELEM_DROP;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* we take the WHERE clause from the catalog where it is already transformed */
|
/* we take the WHERE clause from the catalog where it is already transformed */
|
||||||
bool whereClauseNeedsTransform = false;
|
bool whereClauseNeedsTransform = false;
|
||||||
|
|
|
@ -1072,13 +1072,8 @@ makeStringConst(char *str, int location)
|
||||||
{
|
{
|
||||||
A_Const *n = makeNode(A_Const);
|
A_Const *n = makeNode(A_Const);
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
n->val.sval.type = T_String;
|
n->val.sval.type = T_String;
|
||||||
n->val.sval.sval = str;
|
n->val.sval.sval = str;
|
||||||
#else
|
|
||||||
n->val.type = T_String;
|
|
||||||
n->val.val.str = str;
|
|
||||||
#endif
|
|
||||||
n->location = location;
|
n->location = location;
|
||||||
|
|
||||||
return (Node *) n;
|
return (Node *) n;
|
||||||
|
@ -1098,13 +1093,8 @@ makeIntConst(int val, int location)
|
||||||
{
|
{
|
||||||
A_Const *n = makeNode(A_Const);
|
A_Const *n = makeNode(A_Const);
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
n->val.ival.type = T_Integer;
|
n->val.ival.type = T_Integer;
|
||||||
n->val.ival.ival = val;
|
n->val.ival.ival = val;
|
||||||
#else
|
|
||||||
n->val.type = T_Integer;
|
|
||||||
n->val.val.ival = val;
|
|
||||||
#endif
|
|
||||||
n->location = location;
|
n->location = location;
|
||||||
|
|
||||||
return (Node *) n;
|
return (Node *) n;
|
||||||
|
@ -1121,13 +1111,8 @@ makeFloatConst(char *str, int location)
|
||||||
{
|
{
|
||||||
A_Const *n = makeNode(A_Const);
|
A_Const *n = makeNode(A_Const);
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
n->val.fval.type = T_Float;
|
n->val.fval.type = T_Float;
|
||||||
n->val.fval.fval = str;
|
n->val.fval.fval = str;
|
||||||
#else
|
|
||||||
n->val.type = T_Float;
|
|
||||||
n->val.val.str = str;
|
|
||||||
#endif
|
|
||||||
n->location = location;
|
n->location = location;
|
||||||
|
|
||||||
return (Node *) n;
|
return (Node *) n;
|
||||||
|
|
|
@ -735,8 +735,6 @@ PostprocessAlterSequenceOwnerStmt(Node *node, const char *queryString)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PreprocessAlterSequencePersistenceStmt is called for change of persistence
|
* PreprocessAlterSequencePersistenceStmt is called for change of persistence
|
||||||
* of sequences before the persistence is changed on the local instance.
|
* of sequences before the persistence is changed on the local instance.
|
||||||
|
@ -847,9 +845,6 @@ PreprocessSequenceAlterTableStmt(Node *node, const char *queryString,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PreprocessGrantOnSequenceStmt is executed before the statement is applied to the local
|
* PreprocessGrantOnSequenceStmt is executed before the statement is applied to the local
|
||||||
* postgres instance.
|
* postgres instance.
|
||||||
|
|
|
@ -1153,7 +1153,6 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
|
||||||
{
|
{
|
||||||
AlterTableStmt *stmtCopy = copyObject(alterTableStatement);
|
AlterTableStmt *stmtCopy = copyObject(alterTableStatement);
|
||||||
stmtCopy->objtype = OBJECT_SEQUENCE;
|
stmtCopy->objtype = OBJECT_SEQUENCE;
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* it must be ALTER TABLE .. OWNER TO ..
|
* it must be ALTER TABLE .. OWNER TO ..
|
||||||
|
@ -1163,16 +1162,6 @@ PreprocessAlterTableStmt(Node *node, const char *alterTableCommand,
|
||||||
*/
|
*/
|
||||||
return PreprocessSequenceAlterTableStmt((Node *) stmtCopy, alterTableCommand,
|
return PreprocessSequenceAlterTableStmt((Node *) stmtCopy, alterTableCommand,
|
||||||
processUtilityContext);
|
processUtilityContext);
|
||||||
#else
|
|
||||||
|
|
||||||
/*
|
|
||||||
* it must be ALTER TABLE .. OWNER TO .. command
|
|
||||||
* since this is the only ALTER command of a sequence that
|
|
||||||
* passes through an AlterTableStmt
|
|
||||||
*/
|
|
||||||
return PreprocessAlterSequenceOwnerStmt((Node *) stmtCopy, alterTableCommand,
|
|
||||||
processUtilityContext);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if (relKind == RELKIND_VIEW)
|
else if (relKind == RELKIND_VIEW)
|
||||||
{
|
{
|
||||||
|
@ -3673,9 +3662,8 @@ ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
"are currently unsupported.")));
|
"are currently unsupported.")));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
case AT_SetAccessMethod:
|
case AT_SetAccessMethod:
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -3695,7 +3683,6 @@ ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
case AT_SetNotNull:
|
case AT_SetNotNull:
|
||||||
case AT_ReplicaIdentity:
|
case AT_ReplicaIdentity:
|
||||||
case AT_ChangeOwner:
|
case AT_ChangeOwner:
|
||||||
|
|
|
@ -57,9 +57,6 @@ static void ExtractDropStmtTriggerAndRelationName(DropStmt *dropTriggerStmt,
|
||||||
static void ErrorIfDropStmtDropsMultipleTriggers(DropStmt *dropTriggerStmt);
|
static void ErrorIfDropStmtDropsMultipleTriggers(DropStmt *dropTriggerStmt);
|
||||||
static char * GetTriggerNameById(Oid triggerId);
|
static char * GetTriggerNameById(Oid triggerId);
|
||||||
static int16 GetTriggerTypeById(Oid triggerId);
|
static int16 GetTriggerTypeById(Oid triggerId);
|
||||||
#if (PG_VERSION_NUM < PG_VERSION_15)
|
|
||||||
static void ErrorOutIfCloneTrigger(Oid tgrelid, const char *tgname);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* GUC that overrides trigger checks for distributed tables and reference tables */
|
/* GUC that overrides trigger checks for distributed tables and reference tables */
|
||||||
|
@ -404,40 +401,6 @@ CreateTriggerEventExtendNames(CreateTrigStmt *createTriggerStmt, char *schemaNam
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PreprocessAlterTriggerRenameStmt is called before a ALTER TRIGGER RENAME
|
|
||||||
* command has been executed by standard process utility. This function errors
|
|
||||||
* out if we are trying to rename a child trigger on a partition of a distributed
|
|
||||||
* table. In PG15, this is not allowed anyway.
|
|
||||||
*/
|
|
||||||
List *
|
|
||||||
PreprocessAlterTriggerRenameStmt(Node *node, const char *queryString,
|
|
||||||
ProcessUtilityContext processUtilityContext)
|
|
||||||
{
|
|
||||||
#if (PG_VERSION_NUM < PG_VERSION_15)
|
|
||||||
RenameStmt *renameTriggerStmt = castNode(RenameStmt, node);
|
|
||||||
Assert(renameTriggerStmt->renameType == OBJECT_TRIGGER);
|
|
||||||
|
|
||||||
RangeVar *relation = renameTriggerStmt->relation;
|
|
||||||
|
|
||||||
bool missingOk = false;
|
|
||||||
Oid relationId = RangeVarGetRelid(relation, ALTER_TRIGGER_LOCK_MODE, missingOk);
|
|
||||||
|
|
||||||
if (!IsCitusTable(relationId))
|
|
||||||
{
|
|
||||||
return NIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
EnsureCoordinator();
|
|
||||||
ErrorOutForTriggerIfNotSupported(relationId);
|
|
||||||
|
|
||||||
ErrorOutIfCloneTrigger(relationId, renameTriggerStmt->subname);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return NIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PostprocessAlterTriggerRenameStmt is called after a ALTER TRIGGER RENAME
|
* PostprocessAlterTriggerRenameStmt is called after a ALTER TRIGGER RENAME
|
||||||
* command has been executed by standard process utility. This function errors
|
* command has been executed by standard process utility. This function errors
|
||||||
|
@ -759,64 +722,6 @@ ErrorIfRelationHasUnsupportedTrigger(Oid relationId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (PG_VERSION_NUM < PG_VERSION_15)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ErrorOutIfCloneTrigger is a helper function to error
|
|
||||||
* out if we are trying to rename a child trigger on a
|
|
||||||
* partition of a distributed table.
|
|
||||||
* A lot of this code is borrowed from PG15 because
|
|
||||||
* renaming clone triggers isn't allowed in PG15 anymore.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
ErrorOutIfCloneTrigger(Oid tgrelid, const char *tgname)
|
|
||||||
{
|
|
||||||
HeapTuple tuple;
|
|
||||||
ScanKeyData key[2];
|
|
||||||
|
|
||||||
Relation tgrel = table_open(TriggerRelationId, RowExclusiveLock);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Search for the trigger to modify.
|
|
||||||
*/
|
|
||||||
ScanKeyInit(&key[0],
|
|
||||||
Anum_pg_trigger_tgrelid,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(tgrelid));
|
|
||||||
ScanKeyInit(&key[1],
|
|
||||||
Anum_pg_trigger_tgname,
|
|
||||||
BTEqualStrategyNumber, F_NAMEEQ,
|
|
||||||
CStringGetDatum(tgname));
|
|
||||||
SysScanDesc tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
|
|
||||||
NULL, 2, key);
|
|
||||||
|
|
||||||
if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
|
|
||||||
{
|
|
||||||
Form_pg_trigger trigform = (Form_pg_trigger) GETSTRUCT(tuple);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the trigger descends from a trigger on a parent partitioned
|
|
||||||
* table, reject the rename.
|
|
||||||
* Appended shard ids to find the trigger on the partition's shards
|
|
||||||
* are not correct. Hence we would fail to find the trigger on the
|
|
||||||
* partition's shard.
|
|
||||||
*/
|
|
||||||
if (OidIsValid(trigform->tgparentid))
|
|
||||||
{
|
|
||||||
ereport(ERROR, (
|
|
||||||
errmsg(
|
|
||||||
"cannot rename child triggers on distributed partitions")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
systable_endscan(tgscan);
|
|
||||||
table_close(tgrel, RowExclusiveLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GetDropTriggerStmtRelation takes a DropStmt for a trigger object and returns
|
* GetDropTriggerStmtRelation takes a DropStmt for a trigger object and returns
|
||||||
* RangeVar for the relation that owns the trigger.
|
* RangeVar for the relation that owns the trigger.
|
||||||
|
|
|
@ -614,16 +614,6 @@ 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 */
|
|
||||||
if (!IsUnderPostmaster)
|
|
||||||
{
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,10 +258,8 @@ pg_get_sequencedef_string(Oid sequenceRelationId)
|
||||||
char *typeName = format_type_be(pgSequenceForm->seqtypid);
|
char *typeName = format_type_be(pgSequenceForm->seqtypid);
|
||||||
|
|
||||||
char *sequenceDef = psprintf(CREATE_SEQUENCE_COMMAND,
|
char *sequenceDef = psprintf(CREATE_SEQUENCE_COMMAND,
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
get_rel_persistence(sequenceRelationId) ==
|
get_rel_persistence(sequenceRelationId) ==
|
||||||
RELPERSISTENCE_UNLOGGED ? "UNLOGGED " : "",
|
RELPERSISTENCE_UNLOGGED ? "UNLOGGED " : "",
|
||||||
#endif
|
|
||||||
qualifiedSequenceName,
|
qualifiedSequenceName,
|
||||||
typeName,
|
typeName,
|
||||||
pgSequenceForm->seqincrement, pgSequenceForm->seqmin,
|
pgSequenceForm->seqincrement, pgSequenceForm->seqmin,
|
||||||
|
@ -857,12 +855,10 @@ deparse_shard_index_statement(IndexStmt *origStmt, Oid distrelid, int64 shardid,
|
||||||
appendStringInfoString(buffer, ") ");
|
appendStringInfoString(buffer, ") ");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
if (indexStmt->nulls_not_distinct)
|
if (indexStmt->nulls_not_distinct)
|
||||||
{
|
{
|
||||||
appendStringInfoString(buffer, "NULLS NOT DISTINCT ");
|
appendStringInfoString(buffer, "NULLS NOT DISTINCT ");
|
||||||
}
|
}
|
||||||
#endif /* PG_VERSION_15 */
|
|
||||||
|
|
||||||
if (indexStmt->options != NIL)
|
if (indexStmt->options != NIL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -211,7 +211,6 @@ DeparseAlterDatabaseStmt(Node *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
char *
|
char *
|
||||||
DeparseAlterDatabaseRefreshCollStmt(Node *node)
|
DeparseAlterDatabaseRefreshCollStmt(Node *node)
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
static void AppendCreatePublicationStmt(StringInfo buf, CreatePublicationStmt *stmt,
|
static void AppendCreatePublicationStmt(StringInfo buf, CreatePublicationStmt *stmt,
|
||||||
bool whereClauseNeedsTransform,
|
bool whereClauseNeedsTransform,
|
||||||
bool includeLocalTables);
|
bool includeLocalTables);
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
static bool AppendPublicationObjects(StringInfo buf, List *publicationObjects,
|
static bool AppendPublicationObjects(StringInfo buf, List *publicationObjects,
|
||||||
bool whereClauseNeedsTransform,
|
bool whereClauseNeedsTransform,
|
||||||
bool includeLocalTables);
|
bool includeLocalTables);
|
||||||
|
@ -40,10 +39,6 @@ static void AppendWhereClauseExpression(StringInfo buf, RangeVar *tableName,
|
||||||
Node *whereClause,
|
Node *whereClause,
|
||||||
bool whereClauseNeedsTransform);
|
bool whereClauseNeedsTransform);
|
||||||
static void AppendAlterPublicationAction(StringInfo buf, AlterPublicationAction action);
|
static void AppendAlterPublicationAction(StringInfo buf, AlterPublicationAction action);
|
||||||
#else
|
|
||||||
static bool AppendTables(StringInfo buf, List *tables, bool includeLocalTables);
|
|
||||||
static void AppendDefElemAction(StringInfo buf, DefElemAction action);
|
|
||||||
#endif
|
|
||||||
static bool AppendAlterPublicationStmt(StringInfo buf, AlterPublicationStmt *stmt,
|
static bool AppendAlterPublicationStmt(StringInfo buf, AlterPublicationStmt *stmt,
|
||||||
bool whereClauseNeedsTransform,
|
bool whereClauseNeedsTransform,
|
||||||
bool includeLocalTables);
|
bool includeLocalTables);
|
||||||
|
@ -108,7 +103,6 @@ AppendCreatePublicationStmt(StringInfo buf, CreatePublicationStmt *stmt,
|
||||||
{
|
{
|
||||||
appendStringInfoString(buf, " FOR ALL TABLES");
|
appendStringInfoString(buf, " FOR ALL TABLES");
|
||||||
}
|
}
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
else if (stmt->pubobjects != NIL)
|
else if (stmt->pubobjects != NIL)
|
||||||
{
|
{
|
||||||
bool hasObjects = false;
|
bool hasObjects = false;
|
||||||
|
@ -146,32 +140,6 @@ AppendCreatePublicationStmt(StringInfo buf, CreatePublicationStmt *stmt,
|
||||||
includeLocalTables);
|
includeLocalTables);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
else if (stmt->tables != NIL)
|
|
||||||
{
|
|
||||||
bool hasTables = false;
|
|
||||||
RangeVar *rangeVar = NULL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check whether there are tables to propagate, mainly to know whether
|
|
||||||
* we should include "FOR".
|
|
||||||
*/
|
|
||||||
foreach_declared_ptr(rangeVar, stmt->tables)
|
|
||||||
{
|
|
||||||
if (includeLocalTables || IsCitusTableRangeVar(rangeVar, NoLock, false))
|
|
||||||
{
|
|
||||||
hasTables = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasTables)
|
|
||||||
{
|
|
||||||
appendStringInfoString(buf, " FOR");
|
|
||||||
AppendTables(buf, stmt->tables, includeLocalTables);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (stmt->options != NIL)
|
if (stmt->options != NIL)
|
||||||
{
|
{
|
||||||
|
@ -182,8 +150,6 @@ AppendCreatePublicationStmt(StringInfo buf, CreatePublicationStmt *stmt,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AppendPublicationObjects appends a string representing a list of publication
|
* AppendPublicationObjects appends a string representing a list of publication
|
||||||
* objects to a buffer.
|
* objects to a buffer.
|
||||||
|
@ -320,57 +286,6 @@ AppendWhereClauseExpression(StringInfo buf, RangeVar *tableName,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AppendPublicationObjects appends a string representing a list of publication
|
|
||||||
* objects to a buffer.
|
|
||||||
*
|
|
||||||
* For instance: TABLE users, departments
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
AppendTables(StringInfo buf, List *tables, bool includeLocalTables)
|
|
||||||
{
|
|
||||||
RangeVar *rangeVar = NULL;
|
|
||||||
bool appendedObject = false;
|
|
||||||
|
|
||||||
foreach_declared_ptr(rangeVar, tables)
|
|
||||||
{
|
|
||||||
if (!includeLocalTables &&
|
|
||||||
!IsCitusTableRangeVar(rangeVar, NoLock, false))
|
|
||||||
{
|
|
||||||
/* do not propagate local tables */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *schemaName = rangeVar->schemaname;
|
|
||||||
char *tableName = rangeVar->relname;
|
|
||||||
|
|
||||||
if (schemaName != NULL)
|
|
||||||
{
|
|
||||||
/* qualified table name */
|
|
||||||
appendStringInfo(buf, "%s %s",
|
|
||||||
appendedObject ? "," : " TABLE",
|
|
||||||
quote_qualified_identifier(schemaName, tableName));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* unqualified table name */
|
|
||||||
appendStringInfo(buf, "%s %s",
|
|
||||||
appendedObject ? "," : " TABLE",
|
|
||||||
quote_identifier(tableName));
|
|
||||||
}
|
|
||||||
|
|
||||||
appendedObject = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return appendedObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DeparseAlterPublicationSchemaStmt builds and returns a string representing
|
* DeparseAlterPublicationSchemaStmt builds and returns a string representing
|
||||||
* an AlterPublicationStmt.
|
* an AlterPublicationStmt.
|
||||||
|
@ -439,19 +354,12 @@ AppendAlterPublicationStmt(StringInfo buf, AlterPublicationStmt *stmt,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
AppendAlterPublicationAction(buf, stmt->action);
|
AppendAlterPublicationAction(buf, stmt->action);
|
||||||
return AppendPublicationObjects(buf, stmt->pubobjects, whereClauseNeedsTransform,
|
return AppendPublicationObjects(buf, stmt->pubobjects, whereClauseNeedsTransform,
|
||||||
includeLocalTables);
|
includeLocalTables);
|
||||||
#else
|
|
||||||
AppendDefElemAction(buf, stmt->tableAction);
|
|
||||||
return AppendTables(buf, stmt->tables, includeLocalTables);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AppendAlterPublicationAction appends a string representing an AlterPublicationAction
|
* AppendAlterPublicationAction appends a string representing an AlterPublicationAction
|
||||||
* to a buffer.
|
* to a buffer.
|
||||||
|
@ -487,46 +395,6 @@ AppendAlterPublicationAction(StringInfo buf, AlterPublicationAction action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AppendDefElemAction appends a string representing a DefElemAction
|
|
||||||
* to a buffer.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
AppendDefElemAction(StringInfo buf, DefElemAction action)
|
|
||||||
{
|
|
||||||
switch (action)
|
|
||||||
{
|
|
||||||
case DEFELEM_ADD:
|
|
||||||
{
|
|
||||||
appendStringInfoString(buf, " ADD");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case DEFELEM_DROP:
|
|
||||||
{
|
|
||||||
appendStringInfoString(buf, " DROP");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case DEFELEM_SET:
|
|
||||||
{
|
|
||||||
appendStringInfoString(buf, " SET");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("unrecognized publication action: %d", action)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DeparseDropPublicationStmt builds and returns a string representing the DropStmt
|
* DeparseDropPublicationStmt builds and returns a string representing the DropStmt
|
||||||
*/
|
*/
|
||||||
|
@ -651,11 +519,7 @@ AppendPublicationOptions(StringInfo stringBuffer, List *optionList)
|
||||||
appendStringInfo(stringBuffer, "%s = ",
|
appendStringInfo(stringBuffer, "%s = ",
|
||||||
quote_identifier(optionName));
|
quote_identifier(optionName));
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
if (valueType == T_Integer || valueType == T_Float || valueType == T_Boolean)
|
if (valueType == T_Integer || valueType == T_Float || valueType == T_Boolean)
|
||||||
#else
|
|
||||||
if (valueType == T_Integer || valueType == T_Float)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
/* string escaping is unnecessary for numeric types and can cause issues */
|
/* string escaping is unnecessary for numeric types and can cause issues */
|
||||||
appendStringInfo(stringBuffer, "%s", optionValue);
|
appendStringInfo(stringBuffer, "%s", optionValue);
|
||||||
|
|
|
@ -28,9 +28,7 @@ static void AppendSequenceNameList(StringInfo buf, List *objects, ObjectType obj
|
||||||
static void AppendRenameSequenceStmt(StringInfo buf, RenameStmt *stmt);
|
static void AppendRenameSequenceStmt(StringInfo buf, RenameStmt *stmt);
|
||||||
static void AppendAlterSequenceSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt);
|
static void AppendAlterSequenceSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt);
|
||||||
static void AppendAlterSequenceOwnerStmt(StringInfo buf, AlterTableStmt *stmt);
|
static void AppendAlterSequenceOwnerStmt(StringInfo buf, AlterTableStmt *stmt);
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
static void AppendAlterSequencePersistenceStmt(StringInfo buf, AlterTableStmt *stmt);
|
static void AppendAlterSequencePersistenceStmt(StringInfo buf, AlterTableStmt *stmt);
|
||||||
#endif
|
|
||||||
static void AppendGrantOnSequenceStmt(StringInfo buf, GrantStmt *stmt);
|
static void AppendGrantOnSequenceStmt(StringInfo buf, GrantStmt *stmt);
|
||||||
static void AppendGrantOnSequenceSequences(StringInfo buf, GrantStmt *stmt);
|
static void AppendGrantOnSequenceSequences(StringInfo buf, GrantStmt *stmt);
|
||||||
|
|
||||||
|
@ -262,8 +260,6 @@ AppendAlterSequenceOwnerStmt(StringInfo buf, AlterTableStmt *stmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DeparseAlterSequencePersistenceStmt builds and returns a string representing
|
* DeparseAlterSequencePersistenceStmt builds and returns a string representing
|
||||||
* the AlterTableStmt consisting of changing the persistence of a sequence
|
* the AlterTableStmt consisting of changing the persistence of a sequence
|
||||||
|
@ -349,9 +345,6 @@ AppendAlterSequencePersistenceStmt(StringInfo buf, AlterTableStmt *stmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DeparseGrantOnSequenceStmt builds and returns a string representing the GrantOnSequenceStmt
|
* DeparseGrantOnSequenceStmt builds and returns a string representing the GrantOnSequenceStmt
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -193,12 +193,10 @@ AppendAlterTableCmdConstraint(StringInfo buf, Constraint *constraint,
|
||||||
{
|
{
|
||||||
appendStringInfoString(buf, " UNIQUE");
|
appendStringInfoString(buf, " UNIQUE");
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
if (constraint->nulls_not_distinct == true)
|
if (constraint->nulls_not_distinct == true)
|
||||||
{
|
{
|
||||||
appendStringInfoString(buf, " NULLS NOT DISTINCT");
|
appendStringInfoString(buf, " NULLS NOT DISTINCT");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subtype == AT_AddConstraint)
|
if (subtype == AT_AddConstraint)
|
||||||
|
|
|
@ -19,11 +19,7 @@
|
||||||
#include "distributed/deparser.h"
|
#include "distributed/deparser.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
static void QualifyPublicationObjects(List *publicationObjects);
|
static void QualifyPublicationObjects(List *publicationObjects);
|
||||||
#else
|
|
||||||
static void QualifyTables(List *tables);
|
|
||||||
#endif
|
|
||||||
static void QualifyPublicationRangeVar(RangeVar *publication);
|
static void QualifyPublicationRangeVar(RangeVar *publication);
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,16 +32,10 @@ QualifyCreatePublicationStmt(Node *node)
|
||||||
{
|
{
|
||||||
CreatePublicationStmt *stmt = castNode(CreatePublicationStmt, node);
|
CreatePublicationStmt *stmt = castNode(CreatePublicationStmt, node);
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
QualifyPublicationObjects(stmt->pubobjects);
|
QualifyPublicationObjects(stmt->pubobjects);
|
||||||
#else
|
|
||||||
QualifyTables(stmt->tables);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* QualifyPublicationObjects ensures all table names in a list of
|
* QualifyPublicationObjects ensures all table names in a list of
|
||||||
* publication objects are fully qualified.
|
* publication objects are fully qualified.
|
||||||
|
@ -68,26 +58,6 @@ QualifyPublicationObjects(List *publicationObjects)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/*
|
|
||||||
* QualifyTables ensures all table names in a list are fully qualified.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
QualifyTables(List *tables)
|
|
||||||
{
|
|
||||||
RangeVar *rangeVar = NULL;
|
|
||||||
|
|
||||||
foreach_declared_ptr(rangeVar, tables)
|
|
||||||
{
|
|
||||||
QualifyPublicationRangeVar(rangeVar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* QualifyPublicationObjects ensures all table names in a list of
|
* QualifyPublicationObjects ensures all table names in a list of
|
||||||
* publication objects are fully qualified.
|
* publication objects are fully qualified.
|
||||||
|
@ -97,11 +67,7 @@ QualifyAlterPublicationStmt(Node *node)
|
||||||
{
|
{
|
||||||
AlterPublicationStmt *stmt = castNode(AlterPublicationStmt, node);
|
AlterPublicationStmt *stmt = castNode(AlterPublicationStmt, node);
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
QualifyPublicationObjects(stmt->pubobjects);
|
QualifyPublicationObjects(stmt->pubobjects);
|
||||||
#else
|
|
||||||
QualifyTables(stmt->tables);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,6 @@ QualifyAlterSequenceOwnerStmt(Node *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* QualifyAlterSequencePersistenceStmt transforms a
|
* QualifyAlterSequencePersistenceStmt transforms a
|
||||||
* ALTER SEQUENCE .. SET LOGGED/UNLOGGED
|
* ALTER SEQUENCE .. SET LOGGED/UNLOGGED
|
||||||
|
@ -80,9 +78,6 @@ QualifyAlterSequencePersistenceStmt(Node *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* QualifyAlterSequenceSchemaStmt transforms a
|
* QualifyAlterSequenceSchemaStmt transforms a
|
||||||
* ALTER SEQUENCE .. SET SCHEMA ..
|
* ALTER SEQUENCE .. SET SCHEMA ..
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -718,10 +718,8 @@ static void RebuildWaitEventSetForSessions(DistributedExecution *execution);
|
||||||
static void AddLatchWaitEventToExecution(DistributedExecution *execution);
|
static void AddLatchWaitEventToExecution(DistributedExecution *execution);
|
||||||
static void ProcessWaitEvents(DistributedExecution *execution, WaitEvent *events, int
|
static void ProcessWaitEvents(DistributedExecution *execution, WaitEvent *events, int
|
||||||
eventCount, bool *cancellationReceived);
|
eventCount, bool *cancellationReceived);
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
static void RemoteSocketClosedForAnySession(DistributedExecution *execution);
|
static void RemoteSocketClosedForAnySession(DistributedExecution *execution);
|
||||||
static void ProcessWaitEventsForSocketClosed(WaitEvent *events, int eventCount);
|
static void ProcessWaitEventsForSocketClosed(WaitEvent *events, int eventCount);
|
||||||
#endif
|
|
||||||
static long MillisecondsBetweenTimestamps(instr_time startTime, instr_time endTime);
|
static long MillisecondsBetweenTimestamps(instr_time startTime, instr_time endTime);
|
||||||
static uint64 MicrosecondsBetweenTimestamps(instr_time startTime, instr_time endTime);
|
static uint64 MicrosecondsBetweenTimestamps(instr_time startTime, instr_time endTime);
|
||||||
static int WorkerPoolCompare(const void *lhsKey, const void *rhsKey);
|
static int WorkerPoolCompare(const void *lhsKey, const void *rhsKey);
|
||||||
|
@ -1784,11 +1782,8 @@ FindOrCreateWorkerSession(WorkerPool *workerPool, MultiConnection *connection)
|
||||||
session->commandsSent = 0;
|
session->commandsSent = 0;
|
||||||
session->waitEventSetIndex = WAIT_EVENT_SET_INDEX_NOT_INITIALIZED;
|
session->waitEventSetIndex = WAIT_EVENT_SET_INDEX_NOT_INITIALIZED;
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
|
|
||||||
/* always detect closed sockets */
|
/* always detect closed sockets */
|
||||||
UpdateConnectionWaitFlags(session, WL_SOCKET_CLOSED);
|
UpdateConnectionWaitFlags(session, WL_SOCKET_CLOSED);
|
||||||
#endif
|
|
||||||
|
|
||||||
dlist_init(&session->pendingTaskQueue);
|
dlist_init(&session->pendingTaskQueue);
|
||||||
dlist_init(&session->readyTaskQueue);
|
dlist_init(&session->readyTaskQueue);
|
||||||
|
@ -1832,7 +1827,6 @@ FindOrCreateWorkerSession(WorkerPool *workerPool, MultiConnection *connection)
|
||||||
* the events, even ignores cancellation events. Future callers of this
|
* the events, even ignores cancellation events. Future callers of this
|
||||||
* function should consider its limitations.
|
* function should consider its limitations.
|
||||||
*/
|
*/
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
static void
|
static void
|
||||||
RemoteSocketClosedForAnySession(DistributedExecution *execution)
|
RemoteSocketClosedForAnySession(DistributedExecution *execution)
|
||||||
{
|
{
|
||||||
|
@ -1850,9 +1844,6 @@ RemoteSocketClosedForAnySession(DistributedExecution *execution)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SequentialRunDistributedExecution gets a distributed execution and
|
* SequentialRunDistributedExecution gets a distributed execution and
|
||||||
* executes each individual task in the execution sequentially, one
|
* executes each individual task in the execution sequentially, one
|
||||||
|
@ -2188,8 +2179,6 @@ ProcessWaitEvents(DistributedExecution *execution, WaitEvent *events, int eventC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ProcessWaitEventsForSocketClosed mainly checks for WL_SOCKET_CLOSED event.
|
* ProcessWaitEventsForSocketClosed mainly checks for WL_SOCKET_CLOSED event.
|
||||||
* If WL_SOCKET_CLOSED is found, the function sets the underlying connection's
|
* If WL_SOCKET_CLOSED is found, the function sets the underlying connection's
|
||||||
|
@ -2222,9 +2211,6 @@ ProcessWaitEventsForSocketClosed(WaitEvent *events, int eventCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ManageWorkerPool ensures the worker pool has the appropriate number of connections
|
* ManageWorkerPool ensures the worker pool has the appropriate number of connections
|
||||||
* based on the number of pending tasks.
|
* based on the number of pending tasks.
|
||||||
|
@ -2719,7 +2705,6 @@ OpenNewConnections(WorkerPool *workerPool, int newConnectionCount,
|
||||||
* Instead, we prefer this slight difference, which in effect has almost no
|
* Instead, we prefer this slight difference, which in effect has almost no
|
||||||
* difference, but doing things in different points in time.
|
* difference, but doing things in different points in time.
|
||||||
*/
|
*/
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
|
|
||||||
/* we added new connections, rebuild the waitEventSet */
|
/* we added new connections, rebuild the waitEventSet */
|
||||||
RebuildWaitEventSetForSessions(execution);
|
RebuildWaitEventSetForSessions(execution);
|
||||||
|
@ -2739,9 +2724,6 @@ OpenNewConnections(WorkerPool *workerPool, int newConnectionCount,
|
||||||
* of the execution.
|
* of the execution.
|
||||||
*/
|
*/
|
||||||
AddLatchWaitEventToExecution(execution);
|
AddLatchWaitEventToExecution(execution);
|
||||||
#else
|
|
||||||
execution->rebuildWaitEventSet = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WorkerSession *session = NULL;
|
WorkerSession *session = NULL;
|
||||||
foreach_declared_ptr(session, newSessionsList)
|
foreach_declared_ptr(session, newSessionsList)
|
||||||
|
@ -3678,13 +3660,8 @@ UpdateConnectionWaitFlags(WorkerSession *session, int waitFlags)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
|
|
||||||
/* always detect closed sockets */
|
/* always detect closed sockets */
|
||||||
connection->waitFlags = waitFlags | WL_SOCKET_CLOSED;
|
connection->waitFlags = waitFlags | WL_SOCKET_CLOSED;
|
||||||
#else
|
|
||||||
connection->waitFlags = waitFlags;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* without signalling the execution, the flag changes won't be reflected */
|
/* without signalling the execution, the flag changes won't be reflected */
|
||||||
execution->waitFlagsChanged = true;
|
execution->waitFlagsChanged = true;
|
||||||
|
@ -3709,13 +3686,11 @@ CheckConnectionReady(WorkerSession *session)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
if ((session->latestUnconsumedWaitEvents & WL_SOCKET_CLOSED) != 0)
|
if ((session->latestUnconsumedWaitEvents & WL_SOCKET_CLOSED) != 0)
|
||||||
{
|
{
|
||||||
connection->connectionState = MULTI_CONNECTION_LOST;
|
connection->connectionState = MULTI_CONNECTION_LOST;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* try to send all pending data */
|
/* try to send all pending data */
|
||||||
int sendStatus = PQflush(connection->pgConn);
|
int sendStatus = PQflush(connection->pgConn);
|
||||||
|
|
|
@ -140,19 +140,6 @@ 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());
|
|
||||||
|
|
||||||
elog(LOG, "requesting named LWLockTranch for %s", STATS_SHARED_MEM_NAME);
|
|
||||||
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;
|
||||||
shmem_startup_hook = CitusQueryStatsShmemStartup;
|
shmem_startup_hook = CitusQueryStatsShmemStartup;
|
||||||
|
|
|
@ -1716,13 +1716,11 @@ ExpandCitusSupportedTypes(ObjectAddressCollector *collector, ObjectAddress targe
|
||||||
/*
|
/*
|
||||||
* As of PostgreSQL 15, the same applies to schemas.
|
* As of PostgreSQL 15, the same applies to schemas.
|
||||||
*/
|
*/
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
List *schemaIdList =
|
List *schemaIdList =
|
||||||
GetPublicationSchemas(publicationId);
|
GetPublicationSchemas(publicationId);
|
||||||
List *schemaDependencyList =
|
List *schemaDependencyList =
|
||||||
CreateObjectAddressDependencyDefList(NamespaceRelationId, schemaIdList);
|
CreateObjectAddressDependencyDefList(NamespaceRelationId, schemaIdList);
|
||||||
result = list_concat(result, schemaDependencyList);
|
result = list_concat(result, schemaDependencyList);
|
||||||
#endif
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1750,48 +1750,6 @@ GetSequencesFromAttrDef(Oid attrdefOid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM < PG_VERSION_15
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Given a pg_attrdef OID, return the relation OID and column number of
|
|
||||||
* the owning column (represented as an ObjectAddress for convenience).
|
|
||||||
*
|
|
||||||
* Returns InvalidObjectAddress if there is no such pg_attrdef entry.
|
|
||||||
*/
|
|
||||||
ObjectAddress
|
|
||||||
GetAttrDefaultColumnAddress(Oid attrdefoid)
|
|
||||||
{
|
|
||||||
ObjectAddress result = InvalidObjectAddress;
|
|
||||||
ScanKeyData skey[1];
|
|
||||||
HeapTuple tup;
|
|
||||||
|
|
||||||
Relation attrdef = table_open(AttrDefaultRelationId, AccessShareLock);
|
|
||||||
ScanKeyInit(&skey[0],
|
|
||||||
Anum_pg_attrdef_oid,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(attrdefoid));
|
|
||||||
SysScanDesc scan = systable_beginscan(attrdef, AttrDefaultOidIndexId, true,
|
|
||||||
NULL, 1, skey);
|
|
||||||
|
|
||||||
if (HeapTupleIsValid(tup = systable_getnext(scan)))
|
|
||||||
{
|
|
||||||
Form_pg_attrdef atdform = (Form_pg_attrdef) GETSTRUCT(tup);
|
|
||||||
|
|
||||||
result.classId = RelationRelationId;
|
|
||||||
result.objectId = atdform->adrelid;
|
|
||||||
result.objectSubId = atdform->adnum;
|
|
||||||
}
|
|
||||||
|
|
||||||
systable_endscan(scan);
|
|
||||||
table_close(attrdef, AccessShareLock);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GetAttrDefsFromSequence returns a list of attrdef OIDs that have
|
* GetAttrDefsFromSequence returns a list of attrdef OIDs that have
|
||||||
* a dependency on the given sequence
|
* a dependency on the given sequence
|
||||||
|
@ -3113,7 +3071,6 @@ SyncNodeMetadataToNodesMain(Datum main_arg)
|
||||||
|
|
||||||
PopActiveSnapshot();
|
PopActiveSnapshot();
|
||||||
CommitTransactionCommand();
|
CommitTransactionCommand();
|
||||||
ProcessCompletedNotifies();
|
|
||||||
|
|
||||||
if (syncedAllNodes)
|
if (syncedAllNodes)
|
||||||
{
|
{
|
||||||
|
|
|
@ -283,9 +283,7 @@ PgGetObjectAddress(char *ttype, ArrayType *namearr, ArrayType *argsarr)
|
||||||
case OBJECT_FDW:
|
case OBJECT_FDW:
|
||||||
case OBJECT_FOREIGN_SERVER:
|
case OBJECT_FOREIGN_SERVER:
|
||||||
case OBJECT_LANGUAGE:
|
case OBJECT_LANGUAGE:
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
case OBJECT_PARAMETER_ACL:
|
case OBJECT_PARAMETER_ACL:
|
||||||
#endif
|
|
||||||
case OBJECT_PUBLICATION:
|
case OBJECT_PUBLICATION:
|
||||||
case OBJECT_ROLE:
|
case OBJECT_ROLE:
|
||||||
case OBJECT_SCHEMA:
|
case OBJECT_SCHEMA:
|
||||||
|
@ -323,9 +321,7 @@ PgGetObjectAddress(char *ttype, ArrayType *namearr, ArrayType *argsarr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
case OBJECT_PUBLICATION_NAMESPACE:
|
case OBJECT_PUBLICATION_NAMESPACE:
|
||||||
#endif
|
|
||||||
case OBJECT_USER_MAPPING:
|
case OBJECT_USER_MAPPING:
|
||||||
{
|
{
|
||||||
objnode = (Node *) list_make2(linitial(name), linitial(args));
|
objnode = (Node *) list_make2(linitial(name), linitial(args));
|
||||||
|
|
|
@ -136,11 +136,8 @@ CreateCitusCustomScanPath(PlannerInfo *root, RelOptInfo *relOptInfo,
|
||||||
path->custom_path.path.pathtarget = relOptInfo->reltarget;
|
path->custom_path.path.pathtarget = relOptInfo->reltarget;
|
||||||
path->custom_path.path.parent = relOptInfo;
|
path->custom_path.path.parent = relOptInfo;
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/* necessary to avoid extra Result node in PG15 */
|
/* necessary to avoid extra Result node in PG15 */
|
||||||
path->custom_path.flags = CUSTOMPATH_SUPPORT_PROJECTION;
|
path->custom_path.flags = CUSTOMPATH_SUPPORT_PROJECTION;
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The 100k rows we put on the cost of the path is kind of arbitrary and could be
|
* The 100k rows we put on the cost of the path is kind of arbitrary and could be
|
||||||
|
|
|
@ -1443,13 +1443,8 @@ FinalizePlan(PlannedStmt *localPlan, DistributedPlan *distributedPlan)
|
||||||
|
|
||||||
customScan->custom_private = list_make1(distributedPlanData);
|
customScan->custom_private = list_make1(distributedPlanData);
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
|
|
||||||
/* necessary to avoid extra Result node in PG15 */
|
/* necessary to avoid extra Result node in PG15 */
|
||||||
customScan->flags = CUSTOMPATH_SUPPORT_BACKWARD_SCAN | CUSTOMPATH_SUPPORT_PROJECTION;
|
customScan->flags = CUSTOMPATH_SUPPORT_BACKWARD_SCAN | CUSTOMPATH_SUPPORT_PROJECTION;
|
||||||
#else
|
|
||||||
customScan->flags = CUSTOMPATH_SUPPORT_BACKWARD_SCAN;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fast path queries cannot have any subplans by definition, so skip
|
* Fast path queries cannot have any subplans by definition, so skip
|
||||||
|
|
|
@ -38,8 +38,6 @@
|
||||||
#include "distributed/shard_pruning.h"
|
#include "distributed/shard_pruning.h"
|
||||||
#include "distributed/shared_library_init.h"
|
#include "distributed/shared_library_init.h"
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
|
|
||||||
static int SourceResultPartitionColumnIndex(Query *mergeQuery,
|
static int SourceResultPartitionColumnIndex(Query *mergeQuery,
|
||||||
List *sourceTargetList,
|
List *sourceTargetList,
|
||||||
CitusTableCacheEntry *targetRelation);
|
CitusTableCacheEntry *targetRelation);
|
||||||
|
@ -100,8 +98,6 @@ static char * MergeCommandResultIdPrefix(uint64 planId);
|
||||||
static void ErrorIfMergeHasReturningList(Query *query);
|
static void ErrorIfMergeHasReturningList(Query *query);
|
||||||
static Node * GetMergeJoinCondition(Query *mergeQuery);
|
static Node * GetMergeJoinCondition(Query *mergeQuery);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CreateMergePlan
|
* CreateMergePlan
|
||||||
|
@ -118,13 +114,6 @@ CreateMergePlan(uint64 planId, Query *originalQuery, Query *query,
|
||||||
PlannerRestrictionContext *plannerRestrictionContext,
|
PlannerRestrictionContext *plannerRestrictionContext,
|
||||||
ParamListInfo boundParams)
|
ParamListInfo boundParams)
|
||||||
{
|
{
|
||||||
/* function is void for pre-15 versions of Postgres */
|
|
||||||
#if PG_VERSION_NUM < PG_VERSION_15
|
|
||||||
|
|
||||||
ereport(ERROR, (errmsg("MERGE is not supported in pre-15 Postgres versions")));
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
Oid targetRelationId = ModifyQueryResultRelationId(originalQuery);
|
Oid targetRelationId = ModifyQueryResultRelationId(originalQuery);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -153,8 +142,6 @@ CreateMergePlan(uint64 planId, Query *originalQuery, Query *query,
|
||||||
}
|
}
|
||||||
|
|
||||||
return distributedPlan;
|
return distributedPlan;
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -184,9 +171,6 @@ GetMergeJoinTree(Query *mergeQuery)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GetMergeJoinCondition returns the quals of the ON condition
|
* GetMergeJoinCondition returns the quals of the ON condition
|
||||||
*/
|
*/
|
||||||
|
@ -1443,9 +1427,6 @@ SourceResultPartitionColumnIndex(Query *mergeQuery, List *sourceTargetList,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ExtractMergeSourceRangeTableEntry returns the range table entry of source
|
* ExtractMergeSourceRangeTableEntry returns the range table entry of source
|
||||||
* table or source query in USING clause.
|
* table or source query in USING clause.
|
||||||
|
@ -1453,13 +1434,6 @@ SourceResultPartitionColumnIndex(Query *mergeQuery, List *sourceTargetList,
|
||||||
RangeTblEntry *
|
RangeTblEntry *
|
||||||
ExtractMergeSourceRangeTableEntry(Query *query, bool joinSourceOk)
|
ExtractMergeSourceRangeTableEntry(Query *query, bool joinSourceOk)
|
||||||
{
|
{
|
||||||
/* function is void for pre-15 versions of Postgres */
|
|
||||||
#if PG_VERSION_NUM < PG_VERSION_15
|
|
||||||
|
|
||||||
ereport(ERROR, (errmsg("MERGE is not supported in pre-15 Postgres versions")));
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
Assert(IsMergeQuery(query));
|
Assert(IsMergeQuery(query));
|
||||||
|
|
||||||
List *fromList = query->jointree->fromlist;
|
List *fromList = query->jointree->fromlist;
|
||||||
|
@ -1498,8 +1472,6 @@ ExtractMergeSourceRangeTableEntry(Query *query, bool joinSourceOk)
|
||||||
RangeTblEntry *subqueryRte = rt_fetch(reference->rtindex, query->rtable);
|
RangeTblEntry *subqueryRte = rt_fetch(reference->rtindex, query->rtable);
|
||||||
|
|
||||||
return subqueryRte;
|
return subqueryRte;
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1516,13 +1488,6 @@ ExtractMergeSourceRangeTableEntry(Query *query, bool joinSourceOk)
|
||||||
Var *
|
Var *
|
||||||
FetchAndValidateInsertVarIfExists(Oid targetRelationId, Query *query)
|
FetchAndValidateInsertVarIfExists(Oid targetRelationId, Query *query)
|
||||||
{
|
{
|
||||||
/* function is void for pre-15 versions of Postgres */
|
|
||||||
#if PG_VERSION_NUM < PG_VERSION_15
|
|
||||||
|
|
||||||
ereport(ERROR, (errmsg("MERGE is not supported in pre-15 Postgres versions")));
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
Assert(IsMergeQuery(query));
|
Assert(IsMergeQuery(query));
|
||||||
|
|
||||||
if (!IsCitusTableType(targetRelationId, DISTRIBUTED_TABLE))
|
if (!IsCitusTableType(targetRelationId, DISTRIBUTED_TABLE))
|
||||||
|
@ -1593,8 +1558,6 @@ FetchAndValidateInsertVarIfExists(Oid targetRelationId, Query *query)
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1287,7 +1287,7 @@ worker_save_query_explain_analyze(PG_FUNCTION_ARGS)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* resolve OIDs of unknown (user-defined) types */
|
/* resolve OIDs of unknown (user-defined) types */
|
||||||
Query *analyzedQuery = parse_analyze_varparams_compat(parseTree, queryString,
|
Query *analyzedQuery = parse_analyze_varparams(parseTree, queryString,
|
||||||
¶mTypes, &numParams, NULL);
|
¶mTypes, &numParams, NULL);
|
||||||
|
|
||||||
/* pg_rewrite_query is a wrapper around QueryRewrite with some debugging logic */
|
/* pg_rewrite_query is a wrapper around QueryRewrite with some debugging logic */
|
||||||
|
|
|
@ -122,11 +122,7 @@ update_replication_progress(LogicalDecodingContext *ctx, bool skipped_xact)
|
||||||
*/
|
*/
|
||||||
if (ctx->end_xact || ++changes_count >= CHANGES_THRESHOLD)
|
if (ctx->end_xact || ++changes_count >= CHANGES_THRESHOLD)
|
||||||
{
|
{
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
OutputPluginUpdateProgress(ctx, skipped_xact);
|
OutputPluginUpdateProgress(ctx, skipped_xact);
|
||||||
#else
|
|
||||||
OutputPluginUpdateProgress(ctx);
|
|
||||||
#endif
|
|
||||||
changes_count = 0;
|
changes_count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,15 +175,11 @@ static bool FinishedStartupCitusBackend = false;
|
||||||
|
|
||||||
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;
|
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);
|
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);
|
||||||
|
@ -476,10 +472,8 @@ _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;
|
prev_shmem_request_hook = shmem_request_hook;
|
||||||
shmem_request_hook = citus_shmem_request;
|
shmem_request_hook = citus_shmem_request;
|
||||||
#endif
|
|
||||||
|
|
||||||
InitializeMaintenanceDaemon();
|
InitializeMaintenanceDaemon();
|
||||||
InitializeMaintenanceDaemonForMainDb();
|
InitializeMaintenanceDaemonForMainDb();
|
||||||
|
@ -604,8 +598,6 @@ AdjustDynamicLibraryPathForCdcDecoders(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Requests any additional shared memory required for citus.
|
* Requests any additional shared memory required for citus.
|
||||||
*/
|
*/
|
||||||
|
@ -626,9 +618,6 @@ citus_shmem_request(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DoInitialCleanup does cleanup at start time.
|
* DoInitialCleanup does cleanup at start time.
|
||||||
* Currently it:
|
* Currently it:
|
||||||
|
|
|
@ -310,7 +310,7 @@ fake_relation_set_new_filenode(Relation rel,
|
||||||
*/
|
*/
|
||||||
*minmulti = GetOldestMultiXactId();
|
*minmulti = GetOldestMultiXactId();
|
||||||
|
|
||||||
SMgrRelation srel = RelationCreateStorage_compat(*newrnode, persistence, true);
|
SMgrRelation srel = RelationCreateStorage(*newrnode, persistence, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If required, set up an init fork for an unlogged table so that it can
|
* If required, set up an init fork for an unlogged table so that it can
|
||||||
|
|
|
@ -49,13 +49,8 @@ makeIntConst(int val, int location)
|
||||||
{
|
{
|
||||||
A_Const *n = makeNode(A_Const);
|
A_Const *n = makeNode(A_Const);
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
n->val.ival.type = T_Integer;
|
n->val.ival.type = T_Integer;
|
||||||
n->val.ival.ival = val;
|
n->val.ival.ival = val;
|
||||||
#else
|
|
||||||
n->val.type = T_Integer;
|
|
||||||
n->val.val.ival = val;
|
|
||||||
#endif
|
|
||||||
n->location = location;
|
n->location = location;
|
||||||
|
|
||||||
return (Node *) n;
|
return (Node *) n;
|
||||||
|
|
|
@ -519,15 +519,6 @@ 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 */
|
|
||||||
if (!IsUnderPostmaster)
|
|
||||||
{
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1397,87 +1397,6 @@ CalculateBackoffDelay(int retryCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM < PG_VERSION_15
|
|
||||||
static const char *
|
|
||||||
error_severity(int elevel)
|
|
||||||
{
|
|
||||||
const char *prefix;
|
|
||||||
|
|
||||||
switch (elevel)
|
|
||||||
{
|
|
||||||
case DEBUG1:
|
|
||||||
case DEBUG2:
|
|
||||||
case DEBUG3:
|
|
||||||
case DEBUG4:
|
|
||||||
case DEBUG5:
|
|
||||||
{
|
|
||||||
prefix = gettext_noop("DEBUG");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case LOG:
|
|
||||||
case LOG_SERVER_ONLY:
|
|
||||||
{
|
|
||||||
prefix = gettext_noop("LOG");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case INFO:
|
|
||||||
{
|
|
||||||
prefix = gettext_noop("INFO");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case NOTICE:
|
|
||||||
{
|
|
||||||
prefix = gettext_noop("NOTICE");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case WARNING:
|
|
||||||
{
|
|
||||||
prefix = gettext_noop("WARNING");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case WARNING_CLIENT_ONLY:
|
|
||||||
{
|
|
||||||
prefix = gettext_noop("WARNING");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ERROR:
|
|
||||||
{
|
|
||||||
prefix = gettext_noop("ERROR");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case FATAL:
|
|
||||||
{
|
|
||||||
prefix = gettext_noop("FATAL");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case PANIC:
|
|
||||||
{
|
|
||||||
prefix = gettext_noop("PANIC");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
prefix = "???";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bgw_generate_returned_message -
|
* bgw_generate_returned_message -
|
||||||
* generates the message to be inserted into the job_run_details table
|
* generates the message to be inserted into the job_run_details table
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "unistd.h"
|
#include "unistd.h"
|
||||||
|
|
||||||
#include "access/hash.h"
|
#include "access/hash.h"
|
||||||
|
#include "common/pg_prng.h"
|
||||||
#include "executor/execdesc.h"
|
#include "executor/execdesc.h"
|
||||||
#include "storage/ipc.h"
|
#include "storage/ipc.h"
|
||||||
#include "storage/lwlock.h"
|
#include "storage/lwlock.h"
|
||||||
|
@ -38,10 +39,6 @@
|
||||||
#include "distributed/tuplestore.h"
|
#include "distributed/tuplestore.h"
|
||||||
#include "distributed/utils/citus_stat_tenants.h"
|
#include "distributed/utils/citus_stat_tenants.h"
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
#include "common/pg_prng.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void AttributeMetricsIfApplicable(void);
|
static void AttributeMetricsIfApplicable(void);
|
||||||
|
|
||||||
ExecutorEnd_hook_type prev_ExecutorEnd = NULL;
|
ExecutorEnd_hook_type prev_ExecutorEnd = NULL;
|
||||||
|
@ -298,13 +295,7 @@ AttributeTask(char *tenantId, int colocationId, CmdType commandType)
|
||||||
/* If the tenant is not found in the hash table, we will track the query with a probability of StatTenantsSampleRateForNewTenants. */
|
/* If the tenant is not found in the hash table, we will track the query with a probability of StatTenantsSampleRateForNewTenants. */
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
double randomValue = pg_prng_double(&pg_global_prng_state);
|
double randomValue = pg_prng_double(&pg_global_prng_state);
|
||||||
#else
|
|
||||||
|
|
||||||
/* Generate a random double between 0 and 1 */
|
|
||||||
double randomValue = (double) random() / MAX_RANDOM_VALUE;
|
|
||||||
#endif
|
|
||||||
bool shouldTrackQuery = randomValue <= StatTenantsSampleRateForNewTenants;
|
bool shouldTrackQuery = randomValue <= StatTenantsSampleRateForNewTenants;
|
||||||
if (!shouldTrackQuery)
|
if (!shouldTrackQuery)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,14 +14,6 @@
|
||||||
|
|
||||||
#include "pg_version_constants.h"
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
#define ExecARDeleteTriggers_compat(a, b, c, d, e, f) \
|
|
||||||
ExecARDeleteTriggers(a, b, c, d, e, f)
|
|
||||||
#else
|
|
||||||
#define ExecARDeleteTriggers_compat(a, b, c, d, e, f) \
|
|
||||||
ExecARDeleteTriggers(a, b, c, d, e)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ACLCHECK_OBJECT_TABLE OBJECT_TABLE
|
#define ACLCHECK_OBJECT_TABLE OBJECT_TABLE
|
||||||
|
|
||||||
#define ExplainPropertyLong(qlabel, value, es) \
|
#define ExplainPropertyLong(qlabel, value, es) \
|
||||||
|
|
|
@ -560,13 +560,11 @@ extern List * PostprocessAlterSequenceSchemaStmt(Node *node, const char *querySt
|
||||||
extern List * PreprocessAlterSequenceOwnerStmt(Node *node, const char *queryString,
|
extern List * PreprocessAlterSequenceOwnerStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
extern List * PostprocessAlterSequenceOwnerStmt(Node *node, const char *queryString);
|
extern List * PostprocessAlterSequenceOwnerStmt(Node *node, const char *queryString);
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
extern List * PreprocessAlterSequencePersistenceStmt(Node *node, const char *queryString,
|
extern List * PreprocessAlterSequencePersistenceStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext
|
ProcessUtilityContext
|
||||||
processUtilityContext);
|
processUtilityContext);
|
||||||
extern List * PreprocessSequenceAlterTableStmt(Node *node, const char *queryString,
|
extern List * PreprocessSequenceAlterTableStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
#endif
|
|
||||||
extern List * PreprocessDropSequenceStmt(Node *node, const char *queryString,
|
extern List * PreprocessDropSequenceStmt(Node *node, const char *queryString,
|
||||||
ProcessUtilityContext processUtilityContext);
|
ProcessUtilityContext processUtilityContext);
|
||||||
extern List * SequenceDropStmtObjectAddress(Node *stmt, bool missing_ok, bool
|
extern List * SequenceDropStmtObjectAddress(Node *stmt, bool missing_ok, bool
|
||||||
|
@ -582,10 +580,8 @@ extern List * AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok,
|
||||||
isPostprocess);
|
isPostprocess);
|
||||||
extern List * AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok, bool
|
extern List * AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok, bool
|
||||||
isPostprocess);
|
isPostprocess);
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
extern List * AlterSequencePersistenceStmtObjectAddress(Node *node, bool missing_ok, bool
|
extern List * AlterSequencePersistenceStmtObjectAddress(Node *node, bool missing_ok, bool
|
||||||
isPostprocess);
|
isPostprocess);
|
||||||
#endif
|
|
||||||
extern List * RenameSequenceStmtObjectAddress(Node *node, bool missing_ok, bool
|
extern List * RenameSequenceStmtObjectAddress(Node *node, bool missing_ok, bool
|
||||||
isPostprocess);
|
isPostprocess);
|
||||||
extern void ErrorIfUnsupportedSeqStmt(CreateSeqStmt *createSeqStmt);
|
extern void ErrorIfUnsupportedSeqStmt(CreateSeqStmt *createSeqStmt);
|
||||||
|
@ -784,8 +780,6 @@ extern List * CreateTriggerStmtObjectAddress(Node *node, bool missingOk, bool
|
||||||
isPostprocess);
|
isPostprocess);
|
||||||
extern void CreateTriggerEventExtendNames(CreateTrigStmt *createTriggerStmt,
|
extern void CreateTriggerEventExtendNames(CreateTrigStmt *createTriggerStmt,
|
||||||
char *schemaName, uint64 shardId);
|
char *schemaName, uint64 shardId);
|
||||||
extern List * PreprocessAlterTriggerRenameStmt(Node *node, const char *queryString,
|
|
||||||
ProcessUtilityContext processUtilityContext);
|
|
||||||
extern List * PostprocessAlterTriggerRenameStmt(Node *node, const char *queryString);
|
extern List * PostprocessAlterTriggerRenameStmt(Node *node, const char *queryString);
|
||||||
extern void AlterTriggerRenameEventExtendNames(RenameStmt *renameTriggerStmt,
|
extern void AlterTriggerRenameEventExtendNames(RenameStmt *renameTriggerStmt,
|
||||||
char *schemaName, uint64 shardId);
|
char *schemaName, uint64 shardId);
|
||||||
|
|
|
@ -299,9 +299,7 @@ extern char * DeparseDropSequenceStmt(Node *node);
|
||||||
extern char * DeparseRenameSequenceStmt(Node *node);
|
extern char * DeparseRenameSequenceStmt(Node *node);
|
||||||
extern char * DeparseAlterSequenceSchemaStmt(Node *node);
|
extern char * DeparseAlterSequenceSchemaStmt(Node *node);
|
||||||
extern char * DeparseAlterSequenceOwnerStmt(Node *node);
|
extern char * DeparseAlterSequenceOwnerStmt(Node *node);
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
extern char * DeparseAlterSequencePersistenceStmt(Node *node);
|
extern char * DeparseAlterSequencePersistenceStmt(Node *node);
|
||||||
#endif
|
|
||||||
extern char * DeparseGrantOnSequenceStmt(Node *node);
|
extern char * DeparseGrantOnSequenceStmt(Node *node);
|
||||||
|
|
||||||
/* forward declarations for qualify_sequence_stmt.c */
|
/* forward declarations for qualify_sequence_stmt.c */
|
||||||
|
@ -309,9 +307,7 @@ extern void QualifyRenameSequenceStmt(Node *node);
|
||||||
extern void QualifyDropSequenceStmt(Node *node);
|
extern void QualifyDropSequenceStmt(Node *node);
|
||||||
extern void QualifyAlterSequenceSchemaStmt(Node *node);
|
extern void QualifyAlterSequenceSchemaStmt(Node *node);
|
||||||
extern void QualifyAlterSequenceOwnerStmt(Node *node);
|
extern void QualifyAlterSequenceOwnerStmt(Node *node);
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
|
||||||
extern void QualifyAlterSequencePersistenceStmt(Node *node);
|
extern void QualifyAlterSequencePersistenceStmt(Node *node);
|
||||||
#endif
|
|
||||||
extern void QualifyGrantOnSequenceStmt(Node *node);
|
extern void QualifyGrantOnSequenceStmt(Node *node);
|
||||||
|
|
||||||
#endif /* CITUS_DEPARSER_H */
|
#endif /* CITUS_DEPARSER_H */
|
||||||
|
|
|
@ -28,11 +28,6 @@
|
||||||
|
|
||||||
#define CURSOR_OPT_FORCE_DISTRIBUTED 0x080000
|
#define CURSOR_OPT_FORCE_DISTRIBUTED 0x080000
|
||||||
|
|
||||||
/* Hack to compile Citus on pre-MERGE Postgres versions */
|
|
||||||
#if PG_VERSION_NUM < PG_VERSION_15
|
|
||||||
#define CMD_MERGE CMD_UNKNOWN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* level of planner calls */
|
/* level of planner calls */
|
||||||
extern int PlannerLevel;
|
extern int PlannerLevel;
|
||||||
|
|
|
@ -130,9 +130,6 @@ extern List * IdentitySequenceDependencyCommandList(Oid targetRelationId);
|
||||||
|
|
||||||
extern List * DDLCommandsForSequence(Oid sequenceOid, char *ownerName);
|
extern List * DDLCommandsForSequence(Oid sequenceOid, char *ownerName);
|
||||||
extern List * GetSequencesFromAttrDef(Oid attrdefOid);
|
extern List * GetSequencesFromAttrDef(Oid attrdefOid);
|
||||||
#if PG_VERSION_NUM < PG_VERSION_15
|
|
||||||
ObjectAddress GetAttrDefaultColumnAddress(Oid attrdefoid);
|
|
||||||
#endif
|
|
||||||
extern List * GetAttrDefsFromSequence(Oid seqOid);
|
extern List * GetAttrDefsFromSequence(Oid seqOid);
|
||||||
extern void GetDependentSequencesWithRelation(Oid relationId, List **seqInfoList,
|
extern void GetDependentSequencesWithRelation(Oid relationId, List **seqInfoList,
|
||||||
AttrNumber attnum, char depType);
|
AttrNumber attnum, char depType);
|
||||||
|
|
|
@ -177,9 +177,7 @@ IsNodeWideObjectClass(ObjectClass objectClass)
|
||||||
case OCLASS_ROLE:
|
case OCLASS_ROLE:
|
||||||
case OCLASS_DATABASE:
|
case OCLASS_DATABASE:
|
||||||
case OCLASS_TBLSPACE:
|
case OCLASS_TBLSPACE:
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
case OCLASS_PARAMETER_ACL:
|
case OCLASS_PARAMETER_ACL:
|
||||||
#endif
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_16
|
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||||
case OCLASS_ROLE_MEMBERSHIP:
|
case OCLASS_ROLE_MEMBERSHIP:
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -320,76 +320,6 @@ typedef RangeTblEntry RTEPermissionInfo;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
|
||||||
#define ProcessCompletedNotifies()
|
|
||||||
#define RelationCreateStorage_compat(a, b, c) RelationCreateStorage(a, b, c)
|
|
||||||
#define parse_analyze_varparams_compat(a, b, c, d, e) parse_analyze_varparams(a, b, c, d, \
|
|
||||||
e)
|
|
||||||
#define CREATE_SEQUENCE_COMMAND \
|
|
||||||
"CREATE %sSEQUENCE IF NOT EXISTS %s AS %s INCREMENT BY " INT64_FORMAT \
|
|
||||||
" MINVALUE " INT64_FORMAT " MAXVALUE " INT64_FORMAT \
|
|
||||||
" START WITH " INT64_FORMAT " CACHE " INT64_FORMAT " %sCYCLE"
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include "nodes/value.h"
|
|
||||||
#include "storage/smgr.h"
|
|
||||||
#include "utils/int8.h"
|
|
||||||
#include "utils/rel.h"
|
|
||||||
|
|
||||||
typedef Value String;
|
|
||||||
|
|
||||||
#ifdef HAVE_LONG_INT_64
|
|
||||||
#define strtoi64(str, endptr, base) ((int64) strtol(str, endptr, base))
|
|
||||||
#define strtou64(str, endptr, base) ((uint64) strtoul(str, endptr, base))
|
|
||||||
#else
|
|
||||||
#define strtoi64(str, endptr, base) ((int64) strtoll(str, endptr, base))
|
|
||||||
#define strtou64(str, endptr, base) ((uint64) strtoull(str, endptr, base))
|
|
||||||
#endif
|
|
||||||
#define RelationCreateStorage_compat(a, b, c) RelationCreateStorage(a, b)
|
|
||||||
#define parse_analyze_varparams_compat(a, b, c, d, e) parse_analyze_varparams(a, b, c, d)
|
|
||||||
#define pgstat_init_relation(r) pgstat_initstats(r)
|
|
||||||
#define pg_analyze_and_rewrite_fixedparams(a, b, c, d, e) pg_analyze_and_rewrite(a, b, c, \
|
|
||||||
d, e)
|
|
||||||
#define boolVal(v) intVal(v)
|
|
||||||
#define makeBoolean(val) makeInteger(val)
|
|
||||||
|
|
||||||
static inline int64
|
|
||||||
pg_strtoint64(char *s)
|
|
||||||
{
|
|
||||||
int64 result;
|
|
||||||
(void) scanint8(s, false, &result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* RelationGetSmgr got backported in 13.10 and 14.7 so redefining it for any
|
|
||||||
* version higher causes compilation errors due to redefining of the function.
|
|
||||||
* We want to use it in all versions. So we backport it ourselves in earlier
|
|
||||||
* versions, and rely on the Postgres provided version in the later versions.
|
|
||||||
*/
|
|
||||||
#if PG_VERSION_NUM < 140007
|
|
||||||
static inline SMgrRelation
|
|
||||||
RelationGetSmgr(Relation rel)
|
|
||||||
{
|
|
||||||
if (unlikely(rel->rd_smgr == NULL))
|
|
||||||
{
|
|
||||||
smgrsetowner(&(rel->rd_smgr), smgropen(rel->rd_node, rel->rd_backend));
|
|
||||||
}
|
|
||||||
return rel->rd_smgr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define CREATE_SEQUENCE_COMMAND \
|
|
||||||
"CREATE SEQUENCE IF NOT EXISTS %s AS %s INCREMENT BY " INT64_FORMAT \
|
|
||||||
" MINVALUE " INT64_FORMAT " MAXVALUE " INT64_FORMAT \
|
|
||||||
" START WITH " INT64_FORMAT " CACHE " INT64_FORMAT " %sCYCLE"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SetListCellPtr(a, b) ((a)->ptr_value = (b))
|
#define SetListCellPtr(a, b) ((a)->ptr_value = (b))
|
||||||
#define RangeTableEntryFromNSItem(a) ((a)->p_rte)
|
#define RangeTableEntryFromNSItem(a) ((a)->p_rte)
|
||||||
#define fcGetArgValue(fc, n) ((fc)->args[n].value)
|
#define fcGetArgValue(fc, n) ((fc)->args[n].value)
|
||||||
|
@ -399,4 +329,9 @@ RelationGetSmgr(Relation rel)
|
||||||
#define fcSetArg(fc, n, value) fcSetArgExt(fc, n, value, false)
|
#define fcSetArg(fc, n, value) fcSetArgExt(fc, n, value, false)
|
||||||
#define fcSetArgNull(fc, n) fcSetArgExt(fc, n, (Datum) 0, true)
|
#define fcSetArgNull(fc, n) fcSetArgExt(fc, n, (Datum) 0, true)
|
||||||
|
|
||||||
|
#define CREATE_SEQUENCE_COMMAND \
|
||||||
|
"CREATE %sSEQUENCE IF NOT EXISTS %s AS %s INCREMENT BY " INT64_FORMAT \
|
||||||
|
" MINVALUE " INT64_FORMAT " MAXVALUE " INT64_FORMAT \
|
||||||
|
" START WITH " INT64_FORMAT " CACHE " INT64_FORMAT " %sCYCLE"
|
||||||
|
|
||||||
#endif /* PG_VERSION_COMPAT_H */
|
#endif /* PG_VERSION_COMPAT_H */
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#ifndef PG_VERSION_CONSTANTS
|
#ifndef PG_VERSION_CONSTANTS
|
||||||
#define PG_VERSION_CONSTANTS
|
#define PG_VERSION_CONSTANTS
|
||||||
|
|
||||||
#define PG_VERSION_14 140000
|
|
||||||
#define PG_VERSION_15 150000
|
#define PG_VERSION_15 150000
|
||||||
#define PG_VERSION_16 160000
|
#define PG_VERSION_16 160000
|
||||||
#define PG_VERSION_17 170000
|
#define PG_VERSION_17 170000
|
||||||
|
|
|
@ -108,19 +108,13 @@ s/(ERROR: |WARNING: |error:) invalid socket/\1 connection not open/g
|
||||||
/^\s*invalid socket$/d
|
/^\s*invalid socket$/d
|
||||||
|
|
||||||
# pg15 changes
|
# pg15 changes
|
||||||
# can be removed when dropping PG13&14 support
|
|
||||||
#if (PG_VERSION_NUM >= PG_VERSION_14) && (PG_VERSION_NUM < PG_VERSION_15)
|
|
||||||
# (This is not preprocessor directive, but a reminder for the developer that will drop PG14 support )
|
|
||||||
s/is not a PostgreSQL server process/is not a PostgreSQL backend process/g
|
|
||||||
s/ AS "\?column\?"//g
|
s/ AS "\?column\?"//g
|
||||||
s/".*\.(.*)": (found .* removable)/"\1": \2/g
|
|
||||||
# We ignore multiline error messages, and substitute first line with a single line
|
# We ignore multiline error messages, and substitute first line with a single line
|
||||||
# alternative that is used in some older libpq versions.
|
# alternative that is used in some older libpq versions.
|
||||||
s/(ERROR: |WARNING: |error:) server closed the connection unexpectedly/\1 connection not open/g
|
s/(ERROR: |WARNING: |error:) server closed the connection unexpectedly/\1 connection not open/g
|
||||||
/^\s*This probably means the server terminated abnormally$/d
|
/^\s*This probably means the server terminated abnormally$/d
|
||||||
/^\s*before or while processing the request.$/d
|
/^\s*before or while processing the request.$/d
|
||||||
/^\s*connection not open$/d
|
/^\s*connection not open$/d
|
||||||
#endif /* (PG_VERSION_NUM >= PG_VERSION_13) && (PG_VERSION_NUM < PG_VERSION_14) */
|
|
||||||
|
|
||||||
# intermediate_results
|
# intermediate_results
|
||||||
s/(ERROR.*)pgsql_job_cache\/([0-9]+_[0-9]+_[0-9]+)\/(.*).data/\1pgsql_job_cache\/xx_x_xxx\/\3.data/g
|
s/(ERROR.*)pgsql_job_cache\/([0-9]+_[0-9]+_[0-9]+)\/(.*).data/\1pgsql_job_cache\/xx_x_xxx\/\3.data/g
|
||||||
|
|
|
@ -1,17 +1,6 @@
|
||||||
--
|
--
|
||||||
-- CITUS_LOCAL_TABLES_QUERIES
|
-- CITUS_LOCAL_TABLES_QUERIES
|
||||||
--
|
--
|
||||||
-- This test file has an alternative output because of the change in the
|
|
||||||
-- display of SQL-standard function's arguments in INSERT/SELECT in PG15.
|
|
||||||
-- The alternative output can be deleted when we drop support for PG14
|
|
||||||
--
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15;
|
|
||||||
server_version_ge_15
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
t
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\set VERBOSITY terse
|
\set VERBOSITY terse
|
||||||
SET citus.next_shard_id TO 1509000;
|
SET citus.next_shard_id TO 1509000;
|
||||||
SET citus.shard_replication_factor TO 1;
|
SET citus.shard_replication_factor TO 1;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +1,3 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
||||||
\endif
|
|
||||||
CREATE TABLE alter_am(i int);
|
CREATE TABLE alter_am(i int);
|
||||||
INSERT INTO alter_am SELECT generate_series(1,1000000);
|
INSERT INTO alter_am SELECT generate_series(1,1000000);
|
||||||
SELECT * FROM columnar.options WHERE relation = 'alter_am'::regclass;
|
SELECT * FROM columnar.options WHERE relation = 'alter_am'::regclass;
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
|
@ -55,7 +55,7 @@ step s1-commit:
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
s2: INFO: vacuuming "public.test_vacuum_vs_insert"
|
s2: INFO: vacuuming "public.test_vacuum_vs_insert"
|
||||||
s2: INFO: "test_vacuum_vs_insert": found 0 removable, 6 nonremovable row versions in 4 pages
|
s2: INFO: "public.test_vacuum_vs_insert": found 0 removable, 6 nonremovable row versions in 4 pages
|
||||||
DETAIL: 0 dead row versions cannot be removed yet.
|
DETAIL: 0 dead row versions cannot be removed yet.
|
||||||
step s2-vacuum-full: <... completed>
|
step s2-vacuum-full: <... completed>
|
||||||
step s2-select:
|
step s2-select:
|
||||||
|
|
|
@ -3,17 +3,6 @@
|
||||||
--
|
--
|
||||||
-- Test queries on a distributed table with shards on the coordinator
|
-- Test queries on a distributed table with shards on the coordinator
|
||||||
--
|
--
|
||||||
-- This test file has an alternative output because of the change in the
|
|
||||||
-- display of SQL-standard function's arguments in INSERT/SELECT in PG15.
|
|
||||||
-- The alternative output can be deleted when we drop support for PG14
|
|
||||||
--
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15;
|
|
||||||
server_version_ge_15
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
t
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
CREATE SCHEMA coordinator_shouldhaveshards;
|
CREATE SCHEMA coordinator_shouldhaveshards;
|
||||||
SET search_path TO coordinator_shouldhaveshards;
|
SET search_path TO coordinator_shouldhaveshards;
|
||||||
SET citus.next_shard_id TO 1503000;
|
SET citus.next_shard_id TO 1503000;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,17 +1,6 @@
|
||||||
--
|
--
|
||||||
-- CTE_INLINE
|
-- CTE_INLINE
|
||||||
--
|
--
|
||||||
-- This test file has an alternative output because of the change in the
|
|
||||||
-- display of SQL-standard function's arguments in INSERT/SELECT in PG15.
|
|
||||||
-- The alternative output can be deleted when we drop support for PG14
|
|
||||||
--
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15;
|
|
||||||
server_version_ge_15
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
t
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
CREATE SCHEMA cte_inline;
|
CREATE SCHEMA cte_inline;
|
||||||
SET search_path TO cte_inline;
|
SET search_path TO cte_inline;
|
||||||
SET citus.next_shard_id TO 1960000;
|
SET citus.next_shard_id TO 1960000;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,13 +1,6 @@
|
||||||
--
|
--
|
||||||
-- PG15+ test as WL_SOCKET_CLOSED exposed for PG15+
|
-- PG15+ test as WL_SOCKET_CLOSED exposed for PG15+
|
||||||
--
|
--
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
||||||
\endif
|
|
||||||
CREATE SCHEMA socket_close;
|
CREATE SCHEMA socket_close;
|
||||||
SET search_path TO socket_close;
|
SET search_path TO socket_close;
|
||||||
CREATE OR REPLACE FUNCTION kill_all_cached_internal_conns(gpid bigint)
|
CREATE OR REPLACE FUNCTION kill_all_cached_internal_conns(gpid bigint)
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
--
|
|
||||||
-- PG15+ test as WL_SOCKET_CLOSED exposed for PG15+
|
|
||||||
--
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
|
@ -1,16 +1,6 @@
|
||||||
--
|
--
|
||||||
-- GRANT_ON_SCHEMA_PROPAGATION
|
-- GRANT_ON_SCHEMA_PROPAGATION
|
||||||
--
|
--
|
||||||
-- this test has different output for PG14 compared to PG15
|
|
||||||
-- In PG15, public schema is owned by pg_database_owner role
|
|
||||||
-- Relevant PG commit: b073c3ccd06e4cb845e121387a43faa8c68a7b62
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15;
|
|
||||||
server_version_ge_15
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
t
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- test grants are propagated when the schema is
|
-- test grants are propagated when the schema is
|
||||||
CREATE SCHEMA dist_schema;
|
CREATE SCHEMA dist_schema;
|
||||||
CREATE TABLE dist_schema.dist_table (id int);
|
CREATE TABLE dist_schema.dist_table (id int);
|
||||||
|
|
|
@ -1,400 +0,0 @@
|
||||||
--
|
|
||||||
-- GRANT_ON_SCHEMA_PROPAGATION
|
|
||||||
--
|
|
||||||
-- this test has different output for PG14 compared to PG15
|
|
||||||
-- In PG15, public schema is owned by pg_database_owner role
|
|
||||||
-- Relevant PG commit: b073c3ccd06e4cb845e121387a43faa8c68a7b62
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15;
|
|
||||||
server_version_ge_15
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
f
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- test grants are propagated when the schema is
|
|
||||||
CREATE SCHEMA dist_schema;
|
|
||||||
CREATE TABLE dist_schema.dist_table (id int);
|
|
||||||
CREATE SCHEMA another_dist_schema;
|
|
||||||
CREATE TABLE another_dist_schema.dist_table (id int);
|
|
||||||
SET citus.enable_ddl_propagation TO off;
|
|
||||||
CREATE SCHEMA non_dist_schema;
|
|
||||||
SET citus.enable_ddl_propagation TO on;
|
|
||||||
-- create roles on all nodes
|
|
||||||
CREATE USER role_1;
|
|
||||||
CREATE USER role_2;
|
|
||||||
CREATE USER role_3;
|
|
||||||
-- do some varying grants
|
|
||||||
GRANT USAGE, CREATE ON SCHEMA dist_schema TO role_1 WITH GRANT OPTION;
|
|
||||||
GRANT USAGE ON SCHEMA dist_schema TO role_2;
|
|
||||||
SET ROLE role_1;
|
|
||||||
GRANT USAGE ON SCHEMA dist_schema TO role_3 WITH GRANT OPTION;
|
|
||||||
GRANT CREATE ON SCHEMA dist_schema TO role_3;
|
|
||||||
GRANT CREATE, USAGE ON SCHEMA dist_schema TO PUBLIC;
|
|
||||||
RESET ROLE;
|
|
||||||
GRANT USAGE ON SCHEMA dist_schema TO PUBLIC;
|
|
||||||
SELECT create_distributed_table('dist_schema.dist_table', 'id');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT create_distributed_table('another_dist_schema.dist_table', 'id');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'dist_schema';
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
dist_schema | {postgres=UC/postgres,role_1=U*C*/postgres,role_2=U/postgres,role_3=U*C/role_1,=UC/role_1,=U/postgres}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :worker_1_port
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'dist_schema';
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
dist_schema | {postgres=UC/postgres,role_1=U*C*/postgres,role_2=U/postgres,role_3=U*C/role_1,=UC/role_1,=U/postgres}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :master_port
|
|
||||||
-- grant all permissions
|
|
||||||
GRANT ALL ON SCHEMA dist_schema, another_dist_schema, non_dist_schema TO role_1, role_2, role_3 WITH GRANT OPTION;
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname IN ('dist_schema', 'another_dist_schema', 'non_dist_schema') ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
another_dist_schema | {postgres=UC/postgres,role_1=U*C*/postgres,role_2=U*C*/postgres,role_3=U*C*/postgres}
|
|
||||||
dist_schema | {postgres=UC/postgres,role_1=U*C*/postgres,role_2=U*C*/postgres,role_3=U*C/role_1,=UC/role_1,=U/postgres,role_3=U*C*/postgres}
|
|
||||||
non_dist_schema | {postgres=UC/postgres,role_1=U*C*/postgres,role_2=U*C*/postgres,role_3=U*C*/postgres}
|
|
||||||
(3 rows)
|
|
||||||
|
|
||||||
\c - - - :worker_1_port
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname IN ('dist_schema', 'another_dist_schema', 'non_dist_schema') ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
another_dist_schema | {postgres=UC/postgres,role_1=U*C*/postgres,role_2=U*C*/postgres,role_3=U*C*/postgres}
|
|
||||||
dist_schema | {postgres=UC/postgres,role_1=U*C*/postgres,role_2=U*C*/postgres,role_3=U*C/role_1,=UC/role_1,=U/postgres,role_3=U*C*/postgres}
|
|
||||||
(2 rows)
|
|
||||||
|
|
||||||
\c - - - :master_port
|
|
||||||
-- revoke all permissions
|
|
||||||
REVOKE ALL ON SCHEMA dist_schema, another_dist_schema, non_dist_schema FROM role_1, role_2, role_3, PUBLIC CASCADE;
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname IN ('dist_schema', 'another_dist_schema', 'non_dist_schema') ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
another_dist_schema | {postgres=UC/postgres}
|
|
||||||
dist_schema | {postgres=UC/postgres}
|
|
||||||
non_dist_schema | {postgres=UC/postgres}
|
|
||||||
(3 rows)
|
|
||||||
|
|
||||||
\c - - - :worker_1_port
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname IN ('dist_schema', 'another_dist_schema', 'non_dist_schema') ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
another_dist_schema | {postgres=UC/postgres}
|
|
||||||
dist_schema | {postgres=UC/postgres}
|
|
||||||
(2 rows)
|
|
||||||
|
|
||||||
\c - - - :master_port
|
|
||||||
-- grant with multiple permissions, roles and schemas
|
|
||||||
GRANT USAGE, CREATE ON SCHEMA dist_schema, another_dist_schema, non_dist_schema TO role_1, role_2, role_3;
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname IN ('dist_schema', 'another_dist_schema', 'non_dist_schema') ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
another_dist_schema | {postgres=UC/postgres,role_1=UC/postgres,role_2=UC/postgres,role_3=UC/postgres}
|
|
||||||
dist_schema | {postgres=UC/postgres,role_1=UC/postgres,role_2=UC/postgres,role_3=UC/postgres}
|
|
||||||
non_dist_schema | {postgres=UC/postgres,role_1=UC/postgres,role_2=UC/postgres,role_3=UC/postgres}
|
|
||||||
(3 rows)
|
|
||||||
|
|
||||||
\c - - - :worker_1_port
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname IN ('dist_schema', 'another_dist_schema', 'non_dist_schema') ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
another_dist_schema | {postgres=UC/postgres,role_1=UC/postgres,role_2=UC/postgres,role_3=UC/postgres}
|
|
||||||
dist_schema | {postgres=UC/postgres,role_1=UC/postgres,role_2=UC/postgres,role_3=UC/postgres}
|
|
||||||
(2 rows)
|
|
||||||
|
|
||||||
\c - - - :master_port
|
|
||||||
-- revoke with multiple permissions, roles and schemas
|
|
||||||
REVOKE USAGE, CREATE ON SCHEMA dist_schema, another_dist_schema, non_dist_schema FROM role_1, role_2;
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname IN ('dist_schema', 'another_dist_schema', 'non_dist_schema') ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
another_dist_schema | {postgres=UC/postgres,role_3=UC/postgres}
|
|
||||||
dist_schema | {postgres=UC/postgres,role_3=UC/postgres}
|
|
||||||
non_dist_schema | {postgres=UC/postgres,role_3=UC/postgres}
|
|
||||||
(3 rows)
|
|
||||||
|
|
||||||
\c - - - :worker_1_port
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname IN ('dist_schema', 'another_dist_schema', 'non_dist_schema') ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
another_dist_schema | {postgres=UC/postgres,role_3=UC/postgres}
|
|
||||||
dist_schema | {postgres=UC/postgres,role_3=UC/postgres}
|
|
||||||
(2 rows)
|
|
||||||
|
|
||||||
\c - - - :master_port
|
|
||||||
-- grant with grant option
|
|
||||||
GRANT USAGE ON SCHEMA dist_schema TO role_1, role_3 WITH GRANT OPTION;
|
|
||||||
\c - - - :worker_1_port
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname IN ('dist_schema', 'another_dist_schema', 'non_dist_schema') ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
another_dist_schema | {postgres=UC/postgres,role_3=UC/postgres}
|
|
||||||
dist_schema | {postgres=UC/postgres,role_3=U*C/postgres,role_1=U*/postgres}
|
|
||||||
(2 rows)
|
|
||||||
|
|
||||||
\c - - - :master_port
|
|
||||||
-- revoke grant option for
|
|
||||||
REVOKE GRANT OPTION FOR USAGE ON SCHEMA dist_schema FROM role_3;
|
|
||||||
\c - - - :worker_1_port
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname IN ('dist_schema', 'another_dist_schema', 'non_dist_schema') ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
another_dist_schema | {postgres=UC/postgres,role_3=UC/postgres}
|
|
||||||
dist_schema | {postgres=UC/postgres,role_3=UC/postgres,role_1=U*/postgres}
|
|
||||||
(2 rows)
|
|
||||||
|
|
||||||
\c - - - :master_port
|
|
||||||
-- test current_user
|
|
||||||
SET citus.enable_alter_role_propagation TO ON;
|
|
||||||
ALTER ROLE role_1 SUPERUSER;
|
|
||||||
SET citus.enable_alter_role_propagation TO OFF;
|
|
||||||
SET ROLE role_1;
|
|
||||||
-- this is only supported on citus enterprise where multiple users can be managed
|
|
||||||
-- The output of the nspname select below will indicate if the create has been granted
|
|
||||||
GRANT CREATE ON SCHEMA dist_schema TO CURRENT_USER;
|
|
||||||
\c - - - :worker_1_port
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname IN ('dist_schema', 'another_dist_schema', 'non_dist_schema') ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
another_dist_schema | {postgres=UC/postgres,role_3=UC/postgres}
|
|
||||||
dist_schema | {postgres=UC/postgres,role_3=UC/postgres,role_1=U*C/postgres}
|
|
||||||
(2 rows)
|
|
||||||
|
|
||||||
\c - - - :master_port
|
|
||||||
RESET ROLE;
|
|
||||||
SET citus.enable_alter_role_propagation TO ON;
|
|
||||||
ALTER ROLE role_1 NOSUPERUSER;
|
|
||||||
SET citus.enable_alter_role_propagation TO OFF;
|
|
||||||
DROP TABLE dist_schema.dist_table, another_dist_schema.dist_table;
|
|
||||||
DROP SCHEMA dist_schema;
|
|
||||||
DROP SCHEMA another_dist_schema;
|
|
||||||
DROP SCHEMA non_dist_schema;
|
|
||||||
-- test if the grantors are propagated correctly
|
|
||||||
-- first remove one of the worker nodes
|
|
||||||
SET citus.shard_replication_factor TO 1;
|
|
||||||
SELECT master_remove_node('localhost', :worker_2_port);
|
|
||||||
master_remove_node
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- create a new schema
|
|
||||||
CREATE SCHEMA grantor_schema;
|
|
||||||
-- give cascading permissions
|
|
||||||
GRANT USAGE, CREATE ON SCHEMA grantor_schema TO role_1 WITH GRANT OPTION;
|
|
||||||
GRANT CREATE ON SCHEMA grantor_schema TO PUBLIC;
|
|
||||||
SET ROLE role_1;
|
|
||||||
GRANT USAGE ON SCHEMA grantor_schema TO role_2 WITH GRANT OPTION;
|
|
||||||
GRANT CREATE ON SCHEMA grantor_schema TO role_2;
|
|
||||||
GRANT USAGE, CREATE ON SCHEMA grantor_schema TO role_3;
|
|
||||||
GRANT CREATE, USAGE ON SCHEMA grantor_schema TO PUBLIC;
|
|
||||||
SET ROLE role_2;
|
|
||||||
GRANT USAGE ON SCHEMA grantor_schema TO role_3;
|
|
||||||
RESET ROLE;
|
|
||||||
-- distribute the schema
|
|
||||||
CREATE TABLE grantor_schema.grantor_table (id INT);
|
|
||||||
SELECT create_distributed_table('grantor_schema.grantor_table', 'id');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- check if the grantors are propagated correctly
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'grantor_schema' ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
grantor_schema | {postgres=UC/postgres,role_1=U*C*/postgres,=C/postgres,role_2=U*C/role_1,role_3=UC/role_1,=UC/role_1,role_3=U/role_2}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :worker_1_port
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'grantor_schema' ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
grantor_schema | {postgres=UC/postgres,role_1=U*C*/postgres,=C/postgres,role_2=U*C/role_1,role_3=UC/role_1,=UC/role_1,role_3=U/role_2}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :master_port
|
|
||||||
-- add the previously removed node
|
|
||||||
SELECT 1 FROM master_add_node('localhost', :worker_2_port);
|
|
||||||
?column?
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
1
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- check if the grantors are propagated correctly
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'grantor_schema' ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
grantor_schema | {postgres=UC/postgres,role_1=U*C*/postgres,=C/postgres,role_2=U*C/role_1,role_3=UC/role_1,=UC/role_1,role_3=U/role_2}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :worker_2_port
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'grantor_schema' ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
grantor_schema | {postgres=UC/postgres,role_1=U*C*/postgres,=C/postgres,role_2=U*C/role_1,role_3=UC/role_1,=UC/role_1,role_3=U/role_2}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :master_port
|
|
||||||
-- revoke one of the permissions
|
|
||||||
REVOKE USAGE ON SCHEMA grantor_schema FROM role_1 CASCADE;
|
|
||||||
-- check if revoke worked correctly
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'grantor_schema' ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
grantor_schema | {postgres=UC/postgres,role_1=C*/postgres,=C/postgres,role_2=C/role_1,role_3=C/role_1,=C/role_1}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :worker_1_port
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'grantor_schema' ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
grantor_schema | {postgres=UC/postgres,role_1=C*/postgres,=C/postgres,role_2=C/role_1,role_3=C/role_1,=C/role_1}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :master_port
|
|
||||||
-- test if grantor propagates correctly on already distributed schemas
|
|
||||||
GRANT USAGE ON SCHEMA grantor_schema TO role_1 WITH GRANT OPTION;
|
|
||||||
SET ROLE role_1;
|
|
||||||
GRANT USAGE ON SCHEMA grantor_schema TO role_2;
|
|
||||||
GRANT USAGE ON SCHEMA grantor_schema TO role_3 WITH GRANT OPTION;
|
|
||||||
SET ROLE role_3;
|
|
||||||
GRANT USAGE ON SCHEMA grantor_schema TO role_2;
|
|
||||||
RESET ROLE;
|
|
||||||
-- check the results
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'grantor_schema' ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
grantor_schema | {postgres=UC/postgres,role_1=U*C*/postgres,=C/postgres,role_2=UC/role_1,role_3=U*C/role_1,=C/role_1,role_2=U/role_3}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :worker_1_port
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'grantor_schema' ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
grantor_schema | {postgres=UC/postgres,role_1=U*C*/postgres,=C/postgres,role_2=UC/role_1,role_3=U*C/role_1,=C/role_1,role_2=U/role_3}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :master_port
|
|
||||||
DROP TABLE grantor_schema.grantor_table;
|
|
||||||
DROP SCHEMA grantor_schema CASCADE;
|
|
||||||
-- test distributing the schema with another user
|
|
||||||
CREATE SCHEMA dist_schema;
|
|
||||||
GRANT ALL ON SCHEMA dist_schema TO role_1 WITH GRANT OPTION;
|
|
||||||
SET ROLE role_1;
|
|
||||||
GRANT ALL ON SCHEMA dist_schema TO role_2 WITH GRANT OPTION;
|
|
||||||
CREATE TABLE dist_schema.dist_table (id int);
|
|
||||||
SELECT create_distributed_table('dist_schema.dist_table', 'id');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'dist_schema' ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
dist_schema | {postgres=UC/postgres,role_1=U*C*/postgres,role_2=U*C*/role_1}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :worker_1_port
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'dist_schema' ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
dist_schema | {postgres=UC/postgres,role_1=U*C*/postgres,role_2=U*C*/role_1}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :master_port
|
|
||||||
DROP TABLE dist_schema.dist_table;
|
|
||||||
DROP SCHEMA dist_schema CASCADE;
|
|
||||||
-- test grants on public schema
|
|
||||||
-- first remove one of the worker nodes
|
|
||||||
SET citus.shard_replication_factor TO 1;
|
|
||||||
SELECT master_remove_node('localhost', :worker_2_port);
|
|
||||||
master_remove_node
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- to avoid different output in PG15
|
|
||||||
GRANT CREATE ON SCHEMA public TO public;
|
|
||||||
-- distribute the public schema (it has to be distributed by now but just in case)
|
|
||||||
CREATE TABLE public_schema_table (id INT);
|
|
||||||
SELECT create_distributed_table('public_schema_table', 'id');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- give cascading permissions
|
|
||||||
GRANT USAGE, CREATE ON SCHEMA PUBLIC TO role_1 WITH GRANT OPTION;
|
|
||||||
SET ROLE role_1;
|
|
||||||
GRANT USAGE ON SCHEMA PUBLIC TO PUBLIC;
|
|
||||||
RESET ROLE;
|
|
||||||
-- check if the grants are propagated correctly
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'public' ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
public | {postgres=UC/postgres,=UC/postgres,role_1=U*C*/postgres,=U/role_1}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :worker_1_port
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'public' ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
public | {postgres=UC/postgres,=UC/postgres,role_1=U*C*/postgres,=U/role_1}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :master_port
|
|
||||||
-- add the previously removed node
|
|
||||||
SELECT 1 FROM master_add_node('localhost', :worker_2_port);
|
|
||||||
?column?
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
1
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- check if the grants are propagated correctly
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'public' ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
public | {postgres=UC/postgres,=UC/postgres,role_1=U*C*/postgres,=U/role_1}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :worker_2_port
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'public' ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
public | {postgres=UC/postgres,=UC/postgres,role_1=U*C*/postgres,=U/role_1}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :master_port
|
|
||||||
-- revoke those new permissions
|
|
||||||
REVOKE CREATE, USAGE ON SCHEMA PUBLIC FROM role_1 CASCADE;
|
|
||||||
-- check if the grants are propagated correctly
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'public' ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
public | {postgres=UC/postgres,=UC/postgres}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :worker_1_port
|
|
||||||
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'public' ORDER BY nspname;
|
|
||||||
nspname | nspacl
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
public | {postgres=UC/postgres,=UC/postgres}
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - - - :master_port
|
|
||||||
DROP TABLE public_schema_table;
|
|
||||||
DROP ROLE role_1, role_2, role_3;
|
|
|
@ -1,17 +1,6 @@
|
||||||
--
|
--
|
||||||
-- INSERT_SELECT_REPARTITION
|
-- INSERT_SELECT_REPARTITION
|
||||||
--
|
--
|
||||||
-- This test file has an alternative output because of the change in the
|
|
||||||
-- display of SQL-standard function's arguments in INSERT/SELECT in PG15.
|
|
||||||
-- The alternative output can be deleted when we drop support for PG14
|
|
||||||
--
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15;
|
|
||||||
server_version_ge_15
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
t
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- tests behaviour of INSERT INTO ... SELECT with repartitioning
|
-- tests behaviour of INSERT INTO ... SELECT with repartitioning
|
||||||
CREATE SCHEMA insert_select_repartition;
|
CREATE SCHEMA insert_select_repartition;
|
||||||
SET search_path TO 'insert_select_repartition';
|
SET search_path TO 'insert_select_repartition';
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,17 +1,6 @@
|
||||||
--
|
--
|
||||||
-- INTERMEDIATE_RESULT_PRUNING
|
-- INTERMEDIATE_RESULT_PRUNING
|
||||||
--
|
--
|
||||||
-- This test file has an alternative output because of the change in the
|
|
||||||
-- display of SQL-standard function's arguments in INSERT/SELECT in PG15.
|
|
||||||
-- The alternative output can be deleted when we drop support for PG14
|
|
||||||
--
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15;
|
|
||||||
server_version_ge_15
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
t
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
CREATE SCHEMA intermediate_result_pruning;
|
CREATE SCHEMA intermediate_result_pruning;
|
||||||
SET search_path TO intermediate_result_pruning;
|
SET search_path TO intermediate_result_pruning;
|
||||||
SET citus.log_intermediate_results TO TRUE;
|
SET citus.log_intermediate_results TO TRUE;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,19 +1,11 @@
|
||||||
--
|
--
|
||||||
-- ISSUE_5248
|
-- ISSUE_5248
|
||||||
--
|
--
|
||||||
-- This test file has an alternative output because of the change in the
|
|
||||||
-- backup modes of Postgres. Specifically, there is a renaming
|
|
||||||
-- issue: pg_stop_backup PRE PG15 vs pg_backup_stop PG15+
|
|
||||||
-- The alternative output can be deleted when we drop support for PG14
|
|
||||||
--
|
|
||||||
CREATE SCHEMA issue_5248;
|
CREATE SCHEMA issue_5248;
|
||||||
SET search_path TO issue_5248;
|
SET search_path TO issue_5248;
|
||||||
SET citus.shard_count TO 4;
|
SET citus.shard_count TO 4;
|
||||||
SET citus.shard_replication_factor TO 1;
|
SET citus.shard_replication_factor TO 1;
|
||||||
SET citus.next_shard_id TO 3013000;
|
SET citus.next_shard_id TO 3013000;
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
create table countries(
|
create table countries(
|
||||||
id serial primary key
|
id serial primary key
|
||||||
, name text
|
, name text
|
||||||
|
@ -219,12 +211,8 @@ FROM (
|
||||||
(
|
(
|
||||||
SELECT utc_offset
|
SELECT utc_offset
|
||||||
FROM pg_catalog.pg_timezone_names limit 1 offset 4) limit 91) AS subq_3
|
FROM pg_catalog.pg_timezone_names limit 1 offset 4) limit 91) AS subq_3
|
||||||
\if :server_version_ge_15
|
|
||||||
WHERE pg_catalog.pg_backup_stop() > cast(NULL AS record) limit 100;
|
WHERE pg_catalog.pg_backup_stop() > cast(NULL AS record) limit 100;
|
||||||
ERROR: cannot push down subquery on the target list
|
ERROR: cannot push down subquery on the target list
|
||||||
DETAIL: Subqueries in the SELECT part of the query can only be pushed down if they happen before aggregates and window functions
|
DETAIL: Subqueries in the SELECT part of the query can only be pushed down if they happen before aggregates and window functions
|
||||||
\else
|
|
||||||
WHERE pg_catalog.pg_stop_backup() > cast(NULL AS pg_lsn) limit 100;
|
|
||||||
\endif
|
|
||||||
SET client_min_messages TO WARNING;
|
SET client_min_messages TO WARNING;
|
||||||
DROP SCHEMA issue_5248 CASCADE;
|
DROP SCHEMA issue_5248 CASCADE;
|
||||||
|
|
|
@ -1,230 +0,0 @@
|
||||||
--
|
|
||||||
-- ISSUE_5248
|
|
||||||
--
|
|
||||||
-- This test file has an alternative output because of the change in the
|
|
||||||
-- backup modes of Postgres. Specifically, there is a renaming
|
|
||||||
-- issue: pg_stop_backup PRE PG15 vs pg_backup_stop PG15+
|
|
||||||
-- The alternative output can be deleted when we drop support for PG14
|
|
||||||
--
|
|
||||||
CREATE SCHEMA issue_5248;
|
|
||||||
SET search_path TO issue_5248;
|
|
||||||
SET citus.shard_count TO 4;
|
|
||||||
SET citus.shard_replication_factor TO 1;
|
|
||||||
SET citus.next_shard_id TO 3013000;
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
create table countries(
|
|
||||||
id serial primary key
|
|
||||||
, name text
|
|
||||||
, code varchar(2) collate "C" unique
|
|
||||||
);
|
|
||||||
insert into countries(name, code) select 'country-'||i, i::text from generate_series(10,99) i;
|
|
||||||
select create_reference_table('countries');
|
|
||||||
NOTICE: Copying data from local table...
|
|
||||||
NOTICE: copying the data has completed
|
|
||||||
DETAIL: The local data in the table is no longer visible, but is still on disk.
|
|
||||||
HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$issue_5248.countries$$)
|
|
||||||
create_reference_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
create table orgs (
|
|
||||||
id bigserial primary key
|
|
||||||
, name text
|
|
||||||
, created_at timestamptz default now()
|
|
||||||
);
|
|
||||||
select create_distributed_table('orgs', 'id');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
create table users (
|
|
||||||
id bigserial
|
|
||||||
, org_id bigint references orgs(id)
|
|
||||||
, name text
|
|
||||||
, created_at timestamptz default now()
|
|
||||||
, country_id int -- references countries(id)
|
|
||||||
, score bigint generated always as (id + country_id) stored
|
|
||||||
, primary key (org_id, id)
|
|
||||||
);
|
|
||||||
select create_distributed_table('users', 'org_id');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
alter table users add constraint fk_user_country foreign key (country_id) references countries(id);
|
|
||||||
create table orders (
|
|
||||||
id bigserial
|
|
||||||
, org_id bigint references orgs(id)
|
|
||||||
, user_id bigint
|
|
||||||
, price int
|
|
||||||
, info jsonb
|
|
||||||
, primary key (org_id, id)
|
|
||||||
, foreign key (org_id, user_id) references users(org_id, id)
|
|
||||||
);
|
|
||||||
select create_distributed_table('orders', 'org_id');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
create table events (
|
|
||||||
id bigserial not null
|
|
||||||
, user_id bigint not null
|
|
||||||
, org_id bigint not null
|
|
||||||
, event_time timestamp not null default now()
|
|
||||||
, event_type int not null default 0
|
|
||||||
, payload jsonb
|
|
||||||
, primary key (user_id, id)
|
|
||||||
);
|
|
||||||
create index event_time_idx on events using BRIN (event_time);
|
|
||||||
create index event_json_idx on events using gin(payload);
|
|
||||||
select create_distributed_table('events', 'user_id'); -- on purpose don't colocate on correctly on org_id
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
create table local_data(
|
|
||||||
id bigserial primary key
|
|
||||||
, val int default ( (random()*100)::int )
|
|
||||||
);
|
|
||||||
insert into orgs(id, name) select i,'org-'||i from generate_series(1,10) i;
|
|
||||||
insert into users(id, name, org_id, country_id) select i,'user-'||i, i+1, (i%90)+1 from generate_series(1,5) i;
|
|
||||||
insert into orders(id, org_id, user_id, price) select i, ((i+1))+1 , i+1, i/100 from generate_series(1,2) i;
|
|
||||||
insert into events(id, org_id, user_id, event_type) select i, ((i+1))+1 , i+1, i/100 from generate_series(1,10) i;
|
|
||||||
insert into local_data(id) select generate_series(1,10);
|
|
||||||
/*
|
|
||||||
* Test that we don't get a crash. See #5248.
|
|
||||||
*/
|
|
||||||
SELECT subq_3.c15 AS c0,
|
|
||||||
subq_3.c0 AS c1,
|
|
||||||
subq_3.c15 AS c2,
|
|
||||||
subq_0.c1 AS c3,
|
|
||||||
pg_catalog.String_agg( Cast(
|
|
||||||
(
|
|
||||||
SELECT tgargs
|
|
||||||
FROM pg_catalog.pg_trigger limit 1 offset 1) AS BYTEA), Cast(
|
|
||||||
(
|
|
||||||
SELECT minimum_value
|
|
||||||
FROM columnar.chunk limit 1 offset 5) AS BYTEA)) OVER (partition BY subq_3.c10 ORDER BY subq_3.c12,subq_0.c2) AS c4,
|
|
||||||
subq_0.c1 AS c5
|
|
||||||
FROM (
|
|
||||||
SELECT ref_1.address AS c0,
|
|
||||||
ref_1.error AS c1,
|
|
||||||
sample_0.NAME AS c2,
|
|
||||||
sample_2.trftosql AS c3
|
|
||||||
FROM pg_catalog.pg_statio_all_sequences AS ref_0
|
|
||||||
INNER JOIN pg_catalog.pg_hba_file_rules AS ref_1
|
|
||||||
ON ((
|
|
||||||
SELECT pg_catalog.Max(aggnumdirectargs)
|
|
||||||
FROM pg_catalog.pg_aggregate) <= ref_0.blks_hit)
|
|
||||||
INNER JOIN countries AS sample_0 TABLESAMPLE system (6.4)
|
|
||||||
INNER JOIN local_data AS sample_1 TABLESAMPLE bernoulli (8)
|
|
||||||
ON ((
|
|
||||||
true)
|
|
||||||
OR (
|
|
||||||
sample_0.NAME IS NOT NULL))
|
|
||||||
INNER JOIN pg_catalog.pg_transform AS sample_2 TABLESAMPLE bernoulli (1.2)
|
|
||||||
INNER JOIN pg_catalog.pg_language AS ref_2
|
|
||||||
ON ((
|
|
||||||
SELECT shard_cost_function
|
|
||||||
FROM pg_catalog.pg_dist_rebalance_strategy limit 1 offset 1) IS NULL)
|
|
||||||
RIGHT JOIN pg_catalog.pg_index AS sample_3 TABLESAMPLE system (0.3)
|
|
||||||
ON ((
|
|
||||||
cast(NULL AS bpchar) ~<=~ cast(NULL AS bpchar))
|
|
||||||
OR ((
|
|
||||||
EXISTS
|
|
||||||
(
|
|
||||||
SELECT sample_3.indnkeyatts AS c0,
|
|
||||||
sample_2.trflang AS c1,
|
|
||||||
sample_2.trftype AS c2
|
|
||||||
FROM pg_catalog.pg_statistic_ext AS sample_4 TABLESAMPLE bernoulli (8.6)
|
|
||||||
WHERE sample_2.trftype IS NOT NULL))
|
|
||||||
AND (
|
|
||||||
false)))
|
|
||||||
ON (
|
|
||||||
EXISTS
|
|
||||||
(
|
|
||||||
SELECT sample_0.id AS c0,
|
|
||||||
sample_3.indisprimary AS c1
|
|
||||||
FROM orgs AS sample_5 TABLESAMPLE system (5.3)
|
|
||||||
WHERE false))
|
|
||||||
ON (
|
|
||||||
cast(NULL AS float8) >
|
|
||||||
(
|
|
||||||
SELECT pg_catalog.avg(enumsortorder)
|
|
||||||
FROM pg_catalog.pg_enum) )
|
|
||||||
WHERE cast(COALESCE(
|
|
||||||
CASE
|
|
||||||
WHEN ref_1.auth_method ~>=~ ref_1.auth_method THEN cast(NULL AS path)
|
|
||||||
ELSE cast(NULL AS path)
|
|
||||||
END , cast(NULL AS path)) AS path) = cast(NULL AS path)) AS subq_0,
|
|
||||||
lateral
|
|
||||||
(
|
|
||||||
SELECT
|
|
||||||
(
|
|
||||||
SELECT pg_catalog.stddev(total_time)
|
|
||||||
FROM pg_catalog.pg_stat_user_functions) AS c0,
|
|
||||||
subq_0.c1 AS c1,
|
|
||||||
subq_2.c0 AS c2,
|
|
||||||
subq_0.c2 AS c3,
|
|
||||||
subq_0.c0 AS c4,
|
|
||||||
cast(COALESCE(subq_2.c0, subq_2.c0) AS text) AS c5,
|
|
||||||
subq_2.c0 AS c6,
|
|
||||||
subq_2.c1 AS c7,
|
|
||||||
subq_2.c1 AS c8,
|
|
||||||
subq_2.c1 AS c9,
|
|
||||||
subq_0.c3 AS c10,
|
|
||||||
pg_catalog.pg_stat_get_db_temp_files( cast(
|
|
||||||
(
|
|
||||||
SELECT objoid
|
|
||||||
FROM pg_catalog.pg_description limit 1 offset 1) AS oid)) AS c11,
|
|
||||||
subq_0.c3 AS c12,
|
|
||||||
subq_2.c1 AS c13,
|
|
||||||
subq_0.c0 AS c14,
|
|
||||||
subq_0.c3 AS c15,
|
|
||||||
subq_0.c3 AS c16,
|
|
||||||
subq_0.c1 AS c17,
|
|
||||||
subq_0.c2 AS c18
|
|
||||||
FROM (
|
|
||||||
SELECT subq_1.c2 AS c0,
|
|
||||||
subq_0.c3 AS c1
|
|
||||||
FROM information_schema.element_types AS ref_3,
|
|
||||||
lateral
|
|
||||||
(
|
|
||||||
SELECT subq_0.c1 AS c0,
|
|
||||||
sample_6.info AS c1,
|
|
||||||
subq_0.c2 AS c2,
|
|
||||||
subq_0.c3 AS c3,
|
|
||||||
sample_6.user_id AS c5,
|
|
||||||
ref_3.collation_name AS c6
|
|
||||||
FROM orders AS sample_6 TABLESAMPLE system (3.8)
|
|
||||||
WHERE sample_6.price = sample_6.org_id limit 58) AS subq_1
|
|
||||||
WHERE (
|
|
||||||
subq_1.c2 <= subq_0.c2)
|
|
||||||
AND (
|
|
||||||
cast(NULL AS line) ?-| cast(NULL AS line)) limit 59) AS subq_2
|
|
||||||
WHERE cast(COALESCE(pg_catalog.age( cast(
|
|
||||||
(
|
|
||||||
SELECT pg_catalog.max(event_time)
|
|
||||||
FROM events) AS "timestamp")),
|
|
||||||
(
|
|
||||||
SELECT write_lag
|
|
||||||
FROM pg_catalog.pg_stat_replication limit 1 offset 3) ) AS "interval") >
|
|
||||||
(
|
|
||||||
SELECT utc_offset
|
|
||||||
FROM pg_catalog.pg_timezone_names limit 1 offset 4) limit 91) AS subq_3
|
|
||||||
\if :server_version_ge_15
|
|
||||||
WHERE pg_catalog.pg_backup_stop() > cast(NULL AS record) limit 100;
|
|
||||||
\else
|
|
||||||
WHERE pg_catalog.pg_stop_backup() > cast(NULL AS pg_lsn) limit 100;
|
|
||||||
ERROR: cannot push down subquery on the target list
|
|
||||||
DETAIL: Subqueries in the SELECT part of the query can only be pushed down if they happen before aggregates and window functions
|
|
||||||
\endif
|
|
||||||
SET client_min_messages TO WARNING;
|
|
||||||
DROP SCHEMA issue_5248 CASCADE;
|
|
|
@ -1,17 +1,6 @@
|
||||||
--
|
--
|
||||||
-- LOCAL_SHARD_EXECUTION
|
-- LOCAL_SHARD_EXECUTION
|
||||||
--
|
--
|
||||||
-- This test file has an alternative output because of the change in the
|
|
||||||
-- display of SQL-standard function's arguments in INSERT/SELECT in PG15.
|
|
||||||
-- The alternative output can be deleted when we drop support for PG14
|
|
||||||
--
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15;
|
|
||||||
server_version_ge_15
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
t
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
CREATE SCHEMA local_shard_execution;
|
CREATE SCHEMA local_shard_execution;
|
||||||
SET search_path TO local_shard_execution;
|
SET search_path TO local_shard_execution;
|
||||||
SET citus.shard_count TO 4;
|
SET citus.shard_count TO 4;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,17 +1,6 @@
|
||||||
--
|
--
|
||||||
-- LOCAL_SHARD_EXECUTION_REPLICATED
|
-- LOCAL_SHARD_EXECUTION_REPLICATED
|
||||||
--
|
--
|
||||||
-- This test file has an alternative output because of the change in the
|
|
||||||
-- display of SQL-standard function's arguments in INSERT/SELECT in PG15.
|
|
||||||
-- The alternative output can be deleted when we drop support for PG14
|
|
||||||
--
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15;
|
|
||||||
server_version_ge_15
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
t
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
CREATE SCHEMA local_shard_execution_replicated;
|
CREATE SCHEMA local_shard_execution_replicated;
|
||||||
SET search_path TO local_shard_execution_replicated;
|
SET search_path TO local_shard_execution_replicated;
|
||||||
SET citus.shard_count TO 4;
|
SET citus.shard_count TO 4;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +1,3 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
||||||
\endif
|
|
||||||
-- MERGE command performs a join from data_source to target_table_name
|
-- MERGE command performs a join from data_source to target_table_name
|
||||||
DROP SCHEMA IF EXISTS merge_schema CASCADE;
|
DROP SCHEMA IF EXISTS merge_schema CASCADE;
|
||||||
NOTICE: schema "merge_schema" does not exist, skipping
|
NOTICE: schema "merge_schema" does not exist, skipping
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
|
@ -1,10 +1,3 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
||||||
\endif
|
|
||||||
SET search_path TO merge_arbitrary_schema;
|
SET search_path TO merge_arbitrary_schema;
|
||||||
INSERT INTO target_cj VALUES (1, 'target', 0);
|
INSERT INTO target_cj VALUES (1, 'target', 0);
|
||||||
INSERT INTO target_cj VALUES (2, 'target', 0);
|
INSERT INTO target_cj VALUES (2, 'target', 0);
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
|
@ -1,10 +1,3 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
||||||
\endif
|
|
||||||
DROP SCHEMA IF EXISTS merge_arbitrary_schema CASCADE;
|
DROP SCHEMA IF EXISTS merge_arbitrary_schema CASCADE;
|
||||||
CREATE SCHEMA merge_arbitrary_schema;
|
CREATE SCHEMA merge_arbitrary_schema;
|
||||||
SET search_path TO merge_arbitrary_schema;
|
SET search_path TO merge_arbitrary_schema;
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
|
@ -1,10 +1,3 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
||||||
\endif
|
|
||||||
-- We create two sets of source and target tables, one set in Postgres and
|
-- We create two sets of source and target tables, one set in Postgres and
|
||||||
-- the other in Citus distributed. We run the _exact_ MERGE SQL on both sets
|
-- the other in Citus distributed. We run the _exact_ MERGE SQL on both sets
|
||||||
-- and compare the final results of the target tables in Postgres and Citus.
|
-- and compare the final results of the target tables in Postgres and Citus.
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
|
@ -1,10 +1,3 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
||||||
\endif
|
|
||||||
-- We create two sets of source and target tables, one set in Postgres and
|
-- We create two sets of source and target tables, one set in Postgres and
|
||||||
-- the other in Citus distributed. We run the _exact_ MERGE SQL on both sets
|
-- the other in Citus distributed. We run the _exact_ MERGE SQL on both sets
|
||||||
-- and compare the final results of the target tables in Postgres and Citus.
|
-- and compare the final results of the target tables in Postgres and Citus.
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
|
@ -1,10 +1,3 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
||||||
\endif
|
|
||||||
-- We create two sets of source and target tables, one set in Postgres and
|
-- We create two sets of source and target tables, one set in Postgres and
|
||||||
-- the other in Citus distributed. We run the _exact_ MERGE SQL on both sets
|
-- the other in Citus distributed. We run the _exact_ MERGE SQL on both sets
|
||||||
-- and compare the final results of the target tables in Postgres and Citus.
|
-- and compare the final results of the target tables in Postgres and Citus.
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
|
@ -1,10 +1,3 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
||||||
\endif
|
|
||||||
-- MERGE command performs a join from data_source to target_table_name
|
-- MERGE command performs a join from data_source to target_table_name
|
||||||
DROP SCHEMA IF EXISTS schema_shard_table1 CASCADE;
|
DROP SCHEMA IF EXISTS schema_shard_table1 CASCADE;
|
||||||
NOTICE: schema "schema_shard_table1" does not exist, skipping
|
NOTICE: schema "schema_shard_table1" does not exist, skipping
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
|
@ -1,10 +1,3 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
||||||
\endif
|
|
||||||
-- MERGE command performs a join from data_source to target_table_name
|
-- MERGE command performs a join from data_source to target_table_name
|
||||||
DROP SCHEMA IF EXISTS merge_vcore_schema CASCADE;
|
DROP SCHEMA IF EXISTS merge_vcore_schema CASCADE;
|
||||||
NOTICE: schema "merge_vcore_schema" does not exist, skipping
|
NOTICE: schema "merge_vcore_schema" does not exist, skipping
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
\else
|
|
||||||
\q
|
|
|
@ -214,13 +214,8 @@ SELECT con.conname
|
||||||
\c - - :master_host :master_port
|
\c - - :master_host :master_port
|
||||||
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_key;
|
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_key;
|
||||||
-- Check "ADD UNIQUE NULLS NOT DISTICT"
|
-- Check "ADD UNIQUE NULLS NOT DISTICT"
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
ALTER TABLE AT_AddConstNoName.products ADD UNIQUE NULLS NOT DISTINCT (product_no, price);
|
ALTER TABLE AT_AddConstNoName.products ADD UNIQUE NULLS NOT DISTINCT (product_no, price);
|
||||||
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_price_key;
|
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_price_key;
|
||||||
\endif
|
|
||||||
-- Check "ADD UNIQUE ... DEFERRABLE"
|
-- Check "ADD UNIQUE ... DEFERRABLE"
|
||||||
ALTER TABLE AT_AddConstNoName.products ADD UNIQUE(product_no) INCLUDE(price) DEFERRABLE;
|
ALTER TABLE AT_AddConstNoName.products ADD UNIQUE(product_no) INCLUDE(price) DEFERRABLE;
|
||||||
\c - - :public_worker_1_host :worker_1_port
|
\c - - :public_worker_1_host :worker_1_port
|
||||||
|
|
|
@ -1,17 +1,6 @@
|
||||||
--
|
--
|
||||||
-- MULTI_DEPARSE_SHARD_QUERY
|
-- MULTI_DEPARSE_SHARD_QUERY
|
||||||
--
|
--
|
||||||
-- This test file has an alternative output because of the change in the
|
|
||||||
-- display of SQL-standard function's arguments in INSERT/SELECT in PG15.
|
|
||||||
-- The alternative output can be deleted when we drop support for PG14
|
|
||||||
--
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15;
|
|
||||||
server_version_ge_15
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
t
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
CREATE SCHEMA multi_deparse_shard_query;
|
CREATE SCHEMA multi_deparse_shard_query;
|
||||||
SET search_path TO multi_deparse_shard_query;
|
SET search_path TO multi_deparse_shard_query;
|
||||||
SET citus.next_shard_id TO 13100000;
|
SET citus.next_shard_id TO 13100000;
|
||||||
|
|
|
@ -1,423 +0,0 @@
|
||||||
--
|
|
||||||
-- MULTI_DEPARSE_SHARD_QUERY
|
|
||||||
--
|
|
||||||
-- This test file has an alternative output because of the change in the
|
|
||||||
-- display of SQL-standard function's arguments in INSERT/SELECT in PG15.
|
|
||||||
-- The alternative output can be deleted when we drop support for PG14
|
|
||||||
--
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15;
|
|
||||||
server_version_ge_15
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
f
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
CREATE SCHEMA multi_deparse_shard_query;
|
|
||||||
SET search_path TO multi_deparse_shard_query;
|
|
||||||
SET citus.next_shard_id TO 13100000;
|
|
||||||
SET citus.shard_replication_factor TO 1;
|
|
||||||
CREATE FUNCTION deparse_shard_query_test(text)
|
|
||||||
RETURNS VOID
|
|
||||||
AS 'citus'
|
|
||||||
LANGUAGE C STRICT;
|
|
||||||
-- create the first table
|
|
||||||
CREATE TABLE raw_events_1
|
|
||||||
(tenant_id bigint,
|
|
||||||
value_1 int,
|
|
||||||
value_2 int,
|
|
||||||
value_3 float,
|
|
||||||
value_4 bigint,
|
|
||||||
value_5 text,
|
|
||||||
value_6 int DEfAULT 10,
|
|
||||||
value_7 int,
|
|
||||||
event_at date DEfAULT now()
|
|
||||||
);
|
|
||||||
SELECT create_distributed_table('raw_events_1', 'tenant_id', 'hash');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- create the first table
|
|
||||||
CREATE TABLE raw_events_2
|
|
||||||
(tenant_id bigint,
|
|
||||||
value_1 int,
|
|
||||||
value_2 int,
|
|
||||||
value_3 float,
|
|
||||||
value_4 bigint,
|
|
||||||
value_5 text,
|
|
||||||
value_6 float DEfAULT (random()*100)::float,
|
|
||||||
value_7 int,
|
|
||||||
event_at date DEfAULT now()
|
|
||||||
);
|
|
||||||
SELECT create_distributed_table('raw_events_2', 'tenant_id', 'hash');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
CREATE TABLE aggregated_events
|
|
||||||
(tenant_id bigint,
|
|
||||||
sum_value_1 bigint,
|
|
||||||
average_value_2 float,
|
|
||||||
average_value_3 float,
|
|
||||||
sum_value_4 bigint,
|
|
||||||
sum_value_5 float,
|
|
||||||
average_value_6 int,
|
|
||||||
rollup_hour date);
|
|
||||||
SELECT create_distributed_table('aggregated_events', 'tenant_id', 'hash');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- start with very simple examples on a single table
|
|
||||||
SELECT deparse_shard_query_test('
|
|
||||||
INSERT INTO raw_events_1
|
|
||||||
SELECT * FROM raw_events_1;
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.raw_events_1 (tenant_id, value_1, value_2, value_3, value_4, value_5, value_6, value_7, event_at) SELECT tenant_id, value_1, value_2, value_3, value_4, value_5, value_6, value_7, event_at FROM multi_deparse_shard_query.raw_events_1
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT deparse_shard_query_test('
|
|
||||||
INSERT INTO raw_events_1(tenant_id, value_4)
|
|
||||||
SELECT
|
|
||||||
tenant_id, value_4
|
|
||||||
FROM
|
|
||||||
raw_events_1;
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.raw_events_1 (tenant_id, value_4, value_6, event_at) SELECT tenant_id, value_4, 10 AS value_6, (now())::date AS event_at FROM multi_deparse_shard_query.raw_events_1
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- now that shuffle columns a bit on a single table
|
|
||||||
SELECT deparse_shard_query_test('
|
|
||||||
INSERT INTO raw_events_1(value_5, value_2, tenant_id, value_4)
|
|
||||||
SELECT
|
|
||||||
value_2::text, value_5::int, tenant_id, value_4
|
|
||||||
FROM
|
|
||||||
raw_events_1;
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.raw_events_1 (tenant_id, value_2, value_4, value_5, value_6, event_at) SELECT tenant_id, (value_5)::integer AS value_5, value_4, (value_2)::text AS value_2, 10 AS value_6, (now())::date AS event_at FROM multi_deparse_shard_query.raw_events_1
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- same test on two different tables
|
|
||||||
SELECT deparse_shard_query_test('
|
|
||||||
INSERT INTO raw_events_1(value_5, value_2, tenant_id, value_4)
|
|
||||||
SELECT
|
|
||||||
value_2::text, value_5::int, tenant_id, value_4
|
|
||||||
FROM
|
|
||||||
raw_events_2;
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.raw_events_1 (tenant_id, value_2, value_4, value_5, value_6, event_at) SELECT tenant_id, (value_5)::integer AS value_5, value_4, (value_2)::text AS value_2, 10 AS value_6, (now())::date AS event_at FROM multi_deparse_shard_query.raw_events_2
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- lets do some simple aggregations
|
|
||||||
SELECT deparse_shard_query_test(E'
|
|
||||||
INSERT INTO aggregated_events (tenant_id, rollup_hour, sum_value_1, average_value_3, average_value_6, sum_value_4)
|
|
||||||
SELECT
|
|
||||||
tenant_id, date_trunc(\'hour\', event_at) , sum(value_1), avg(value_3), avg(value_6), sum(value_4)
|
|
||||||
FROM
|
|
||||||
raw_events_1
|
|
||||||
GROUP BY
|
|
||||||
tenant_id, date_trunc(\'hour\', event_at)
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.aggregated_events (tenant_id, sum_value_1, average_value_3, sum_value_4, average_value_6, rollup_hour) SELECT tenant_id, sum(value_1) AS sum, avg(value_3) AS avg, sum(value_4) AS sum, avg(value_6) AS avg, date_trunc('hour'::text, (event_at)::timestamp with time zone) AS date_trunc FROM multi_deparse_shard_query.raw_events_1 GROUP BY tenant_id, (date_trunc('hour'::text, (event_at)::timestamp with time zone))
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- also some subqueries, JOINS with a complicated target lists
|
|
||||||
-- a simple JOIN
|
|
||||||
SELECT deparse_shard_query_test('
|
|
||||||
INSERT INTO raw_events_1 (value_3, tenant_id)
|
|
||||||
SELECT
|
|
||||||
raw_events_2.value_3, raw_events_1.tenant_id
|
|
||||||
FROM
|
|
||||||
raw_events_1, raw_events_2
|
|
||||||
WHERE
|
|
||||||
raw_events_1.tenant_id = raw_events_2.tenant_id;
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.raw_events_1 (tenant_id, value_3, value_6, event_at) SELECT raw_events_1.tenant_id, raw_events_2.value_3, 10 AS value_6, (now())::date AS event_at FROM multi_deparse_shard_query.raw_events_1, multi_deparse_shard_query.raw_events_2 WHERE (raw_events_1.tenant_id OPERATOR(pg_catalog.=) raw_events_2.tenant_id)
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- join with group by
|
|
||||||
SELECT deparse_shard_query_test('
|
|
||||||
INSERT INTO raw_events_1 (value_3, tenant_id)
|
|
||||||
SELECT
|
|
||||||
max(raw_events_2.value_3), avg(raw_events_1.value_3)
|
|
||||||
FROM
|
|
||||||
raw_events_1, raw_events_2
|
|
||||||
WHERE
|
|
||||||
raw_events_1.tenant_id = raw_events_2.tenant_id GROUP BY raw_events_1.event_at
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.raw_events_1 (tenant_id, value_3, value_6, event_at) SELECT avg(raw_events_1.value_3) AS avg, max(raw_events_2.value_3) AS max, 10 AS value_6, (now())::date AS event_at FROM multi_deparse_shard_query.raw_events_1, multi_deparse_shard_query.raw_events_2 WHERE (raw_events_1.tenant_id OPERATOR(pg_catalog.=) raw_events_2.tenant_id) GROUP BY raw_events_1.event_at
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- a more complicated JOIN
|
|
||||||
SELECT deparse_shard_query_test('
|
|
||||||
INSERT INTO aggregated_events (sum_value_4, tenant_id)
|
|
||||||
SELECT
|
|
||||||
max(r1.value_4), r3.tenant_id
|
|
||||||
FROM
|
|
||||||
raw_events_1 r1, raw_events_2 r2, raw_events_1 r3
|
|
||||||
WHERE
|
|
||||||
r1.tenant_id = r2.tenant_id AND r2.tenant_id = r3.tenant_id
|
|
||||||
GROUP BY
|
|
||||||
r1.value_1, r3.tenant_id, r2.event_at
|
|
||||||
ORDER BY
|
|
||||||
r2.event_at DESC;
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.aggregated_events (tenant_id, sum_value_4) SELECT r3.tenant_id, max(r1.value_4) AS max FROM multi_deparse_shard_query.raw_events_1 r1, multi_deparse_shard_query.raw_events_2 r2, multi_deparse_shard_query.raw_events_1 r3 WHERE ((r1.tenant_id OPERATOR(pg_catalog.=) r2.tenant_id) AND (r2.tenant_id OPERATOR(pg_catalog.=) r3.tenant_id)) GROUP BY r1.value_1, r3.tenant_id, r2.event_at ORDER BY r2.event_at DESC
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- queries with CTEs are supported
|
|
||||||
SELECT deparse_shard_query_test('
|
|
||||||
WITH first_tenant AS (SELECT event_at, value_5, tenant_id FROM raw_events_1)
|
|
||||||
INSERT INTO aggregated_events (rollup_hour, sum_value_5, tenant_id)
|
|
||||||
SELECT
|
|
||||||
event_at, sum(value_5::int), tenant_id
|
|
||||||
FROM
|
|
||||||
raw_events_1
|
|
||||||
GROUP BY
|
|
||||||
event_at, tenant_id;
|
|
||||||
');
|
|
||||||
INFO: query: WITH first_tenant AS (SELECT raw_events_1.event_at, raw_events_1.value_5, raw_events_1.tenant_id FROM multi_deparse_shard_query.raw_events_1) INSERT INTO multi_deparse_shard_query.aggregated_events (tenant_id, sum_value_5, rollup_hour) SELECT tenant_id, sum((value_5)::integer) AS sum, event_at FROM multi_deparse_shard_query.raw_events_1 GROUP BY event_at, tenant_id
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT deparse_shard_query_test('
|
|
||||||
WITH first_tenant AS (SELECT event_at, value_5, tenant_id FROM raw_events_1)
|
|
||||||
INSERT INTO aggregated_events (sum_value_5, tenant_id)
|
|
||||||
SELECT
|
|
||||||
sum(value_5::int), tenant_id
|
|
||||||
FROM
|
|
||||||
raw_events_1
|
|
||||||
GROUP BY
|
|
||||||
event_at, tenant_id;
|
|
||||||
');
|
|
||||||
INFO: query: WITH first_tenant AS (SELECT raw_events_1.event_at, raw_events_1.value_5, raw_events_1.tenant_id FROM multi_deparse_shard_query.raw_events_1) INSERT INTO multi_deparse_shard_query.aggregated_events (tenant_id, sum_value_5) SELECT tenant_id, sum((value_5)::integer) AS sum FROM multi_deparse_shard_query.raw_events_1 GROUP BY event_at, tenant_id
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT deparse_shard_query_test('
|
|
||||||
INSERT INTO aggregated_events (sum_value_1, sum_value_5, tenant_id)
|
|
||||||
WITH RECURSIVE hierarchy as (
|
|
||||||
SELECT value_1, 1 AS LEVEL, tenant_id
|
|
||||||
FROM raw_events_1
|
|
||||||
WHERE tenant_id = 1
|
|
||||||
UNION
|
|
||||||
SELECT re.value_2, (h.level+1), re.tenant_id
|
|
||||||
FROM hierarchy h JOIN raw_events_1 re
|
|
||||||
ON (h.tenant_id = re.tenant_id AND
|
|
||||||
h.value_1 = re.value_6))
|
|
||||||
SELECT * FROM hierarchy WHERE LEVEL <= 2;
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.aggregated_events (tenant_id, sum_value_1, sum_value_5) WITH RECURSIVE hierarchy AS (SELECT raw_events_1.value_1, 1 AS level, raw_events_1.tenant_id FROM multi_deparse_shard_query.raw_events_1 WHERE (raw_events_1.tenant_id OPERATOR(pg_catalog.=) 1) UNION SELECT re.value_2, (h.level OPERATOR(pg_catalog.+) 1), re.tenant_id FROM (hierarchy h JOIN multi_deparse_shard_query.raw_events_1 re ON (((h.tenant_id OPERATOR(pg_catalog.=) re.tenant_id) AND (h.value_1 OPERATOR(pg_catalog.=) re.value_6))))) SELECT tenant_id, value_1, level FROM hierarchy WHERE (level OPERATOR(pg_catalog.<=) 2)
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT deparse_shard_query_test('
|
|
||||||
INSERT INTO aggregated_events (sum_value_1)
|
|
||||||
SELECT
|
|
||||||
DISTINCT value_1
|
|
||||||
FROM
|
|
||||||
raw_events_1;
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.aggregated_events (sum_value_1) SELECT DISTINCT value_1 FROM multi_deparse_shard_query.raw_events_1
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- many filters suffled
|
|
||||||
SELECT deparse_shard_query_test(E'
|
|
||||||
INSERT INTO aggregated_events (sum_value_5, sum_value_1, tenant_id)
|
|
||||||
SELECT value_3, value_2, tenant_id
|
|
||||||
FROM raw_events_1
|
|
||||||
WHERE (value_5 like \'%s\' or value_5 like \'%a\') and (tenant_id = 1) and (value_6 < 3000 or value_3 > 8000);
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.aggregated_events (tenant_id, sum_value_1, sum_value_5) SELECT tenant_id, value_2, value_3 FROM multi_deparse_shard_query.raw_events_1 WHERE (((value_5 OPERATOR(pg_catalog.~~) '%s'::text) OR (value_5 OPERATOR(pg_catalog.~~) '%a'::text)) AND (tenant_id OPERATOR(pg_catalog.=) 1) AND ((value_6 OPERATOR(pg_catalog.<) 3000) OR (value_3 OPERATOR(pg_catalog.>) (8000)::double precision)))
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT deparse_shard_query_test(E'
|
|
||||||
INSERT INTO aggregated_events (sum_value_5, tenant_id)
|
|
||||||
SELECT rank() OVER (PARTITION BY tenant_id ORDER BY value_6), tenant_id
|
|
||||||
FROM raw_events_1
|
|
||||||
WHERE event_at = now();
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.aggregated_events (tenant_id, sum_value_5) SELECT tenant_id, rank() OVER (PARTITION BY tenant_id ORDER BY value_6) AS rank FROM multi_deparse_shard_query.raw_events_1 WHERE (event_at OPERATOR(pg_catalog.=) now())
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT deparse_shard_query_test(E'
|
|
||||||
INSERT INTO aggregated_events (sum_value_5, tenant_id, sum_value_4)
|
|
||||||
SELECT random(), int4eq(1, max(value_1))::int, value_6
|
|
||||||
FROM raw_events_1
|
|
||||||
WHERE event_at = now()
|
|
||||||
GROUP BY event_at, value_7, value_6;
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.aggregated_events (tenant_id, sum_value_4, sum_value_5) SELECT (int4eq(1, max(value_1)))::integer AS int4eq, value_6, random() AS random FROM multi_deparse_shard_query.raw_events_1 WHERE (event_at OPERATOR(pg_catalog.=) now()) GROUP BY event_at, value_7, value_6
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT deparse_shard_query_test('
|
|
||||||
INSERT INTO aggregated_events (sum_value_1, tenant_id)
|
|
||||||
SELECT
|
|
||||||
count(DISTINCT CASE
|
|
||||||
WHEN
|
|
||||||
value_1 > 100
|
|
||||||
THEN
|
|
||||||
tenant_id
|
|
||||||
ELSE
|
|
||||||
value_6
|
|
||||||
END) as c,
|
|
||||||
max(tenant_id)
|
|
||||||
FROM
|
|
||||||
raw_events_1;
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.aggregated_events (tenant_id, sum_value_1) SELECT max(tenant_id) AS max, count(DISTINCT CASE WHEN (value_1 OPERATOR(pg_catalog.>) 100) THEN tenant_id ELSE (value_6)::bigint END) AS c FROM multi_deparse_shard_query.raw_events_1
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT deparse_shard_query_test('
|
|
||||||
INSERT INTO raw_events_1(value_7, value_1, tenant_id)
|
|
||||||
SELECT
|
|
||||||
value_7, value_1, tenant_id
|
|
||||||
FROM
|
|
||||||
(SELECT
|
|
||||||
tenant_id, value_2 as value_7, value_1
|
|
||||||
FROM
|
|
||||||
raw_events_2
|
|
||||||
) as foo
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.raw_events_1 (tenant_id, value_1, value_6, value_7, event_at) SELECT tenant_id, value_1, 10 AS value_6, value_7, (now())::date AS event_at FROM (SELECT raw_events_2.tenant_id, raw_events_2.value_2 AS value_7, raw_events_2.value_1 FROM multi_deparse_shard_query.raw_events_2) foo
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT deparse_shard_query_test(E'
|
|
||||||
INSERT INTO aggregated_events(sum_value_1, tenant_id, sum_value_5)
|
|
||||||
SELECT
|
|
||||||
sum(value_1), tenant_id, sum(value_5::bigint)
|
|
||||||
FROM
|
|
||||||
(SELECT
|
|
||||||
raw_events_1.event_at, raw_events_2.tenant_id, raw_events_2.value_5, raw_events_1.value_1
|
|
||||||
FROM
|
|
||||||
raw_events_2, raw_events_1
|
|
||||||
WHERE
|
|
||||||
raw_events_1.tenant_id = raw_events_2.tenant_id
|
|
||||||
) as foo
|
|
||||||
GROUP BY
|
|
||||||
tenant_id, date_trunc(\'hour\', event_at)
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.aggregated_events (tenant_id, sum_value_1, sum_value_5) SELECT tenant_id, sum(value_1) AS sum, sum((value_5)::bigint) AS sum FROM (SELECT raw_events_1.event_at, raw_events_2.tenant_id, raw_events_2.value_5, raw_events_1.value_1 FROM multi_deparse_shard_query.raw_events_2, multi_deparse_shard_query.raw_events_1 WHERE (raw_events_1.tenant_id OPERATOR(pg_catalog.=) raw_events_2.tenant_id)) foo GROUP BY tenant_id, (date_trunc('hour'::text, (event_at)::timestamp with time zone))
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT deparse_shard_query_test(E'
|
|
||||||
INSERT INTO raw_events_2(tenant_id, value_1, value_2, value_3, value_4)
|
|
||||||
SELECT
|
|
||||||
tenant_id, value_1, value_2, value_3, value_4
|
|
||||||
FROM
|
|
||||||
(SELECT
|
|
||||||
value_2, value_4, tenant_id, value_1, value_3
|
|
||||||
FROM
|
|
||||||
raw_events_1
|
|
||||||
) as foo
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.raw_events_2 (tenant_id, value_1, value_2, value_3, value_4, value_6, event_at) SELECT tenant_id, value_1, value_2, value_3, value_4, (random() OPERATOR(pg_catalog.*) (100)::double precision) AS value_6, (now())::date AS event_at FROM (SELECT raw_events_1.value_2, raw_events_1.value_4, raw_events_1.tenant_id, raw_events_1.value_1, raw_events_1.value_3 FROM multi_deparse_shard_query.raw_events_1) foo
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT deparse_shard_query_test(E'
|
|
||||||
INSERT INTO raw_events_2(tenant_id, value_1, value_4, value_2, value_3)
|
|
||||||
SELECT
|
|
||||||
*
|
|
||||||
FROM
|
|
||||||
(SELECT
|
|
||||||
value_2, value_4, tenant_id, value_1, value_3
|
|
||||||
FROM
|
|
||||||
raw_events_1
|
|
||||||
) as foo
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.raw_events_2 (tenant_id, value_1, value_2, value_3, value_4, value_6, event_at) SELECT value_2, value_4, value_1, value_3, tenant_id, (random() OPERATOR(pg_catalog.*) (100)::double precision) AS value_6, (now())::date AS event_at FROM (SELECT raw_events_1.value_2, raw_events_1.value_4, raw_events_1.tenant_id, raw_events_1.value_1, raw_events_1.value_3 FROM multi_deparse_shard_query.raw_events_1) foo
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- use a column multiple times
|
|
||||||
SELECT deparse_shard_query_test('
|
|
||||||
INSERT INTO raw_events_1(tenant_id, value_7, value_4)
|
|
||||||
SELECT
|
|
||||||
tenant_id, value_7, value_7
|
|
||||||
FROM
|
|
||||||
raw_events_1
|
|
||||||
ORDER BY
|
|
||||||
value_2, value_1;
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.raw_events_1 (tenant_id, value_4, value_6, value_7, event_at) SELECT tenant_id, value_7, 10 AS value_6, value_7, (now())::date AS event_at FROM multi_deparse_shard_query.raw_events_1 ORDER BY value_2, value_1
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- test dropped table as well
|
|
||||||
ALTER TABLE raw_events_1 DROP COLUMN value_5;
|
|
||||||
SELECT deparse_shard_query_test('
|
|
||||||
INSERT INTO raw_events_1(tenant_id, value_7, value_4)
|
|
||||||
SELECT
|
|
||||||
tenant_id, value_7, value_4
|
|
||||||
FROM
|
|
||||||
raw_events_1;
|
|
||||||
');
|
|
||||||
INFO: query: INSERT INTO multi_deparse_shard_query.raw_events_1 (tenant_id, value_4, value_6, value_7, event_at) SELECT tenant_id, value_4, 10 AS value_6, value_7, (now())::date AS event_at FROM multi_deparse_shard_query.raw_events_1
|
|
||||||
deparse_shard_query_test
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SET client_min_messages TO ERROR;
|
|
||||||
DROP SCHEMA multi_deparse_shard_query CASCADE;
|
|
|
@ -747,14 +747,8 @@ SELECT * FROM multi_extension.print_extension_changes();
|
||||||
|
|
||||||
-- recreate public schema, and recreate citus_tables in the public schema by default
|
-- recreate public schema, and recreate citus_tables in the public schema by default
|
||||||
CREATE SCHEMA public;
|
CREATE SCHEMA public;
|
||||||
-- In PG15, public schema is owned by pg_database_owner role
|
-- public schema is owned by pg_database_owner role
|
||||||
-- Relevant PG commit: b073c3ccd06e4cb845e121387a43faa8c68a7b62
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
|
|
||||||
\gset
|
|
||||||
\if :server_version_ge_15
|
|
||||||
ALTER SCHEMA public OWNER TO pg_database_owner;
|
ALTER SCHEMA public OWNER TO pg_database_owner;
|
||||||
\endif
|
|
||||||
GRANT ALL ON SCHEMA public TO public;
|
GRANT ALL ON SCHEMA public TO public;
|
||||||
ALTER EXTENSION citus UPDATE TO '9.5-1';
|
ALTER EXTENSION citus UPDATE TO '9.5-1';
|
||||||
ALTER EXTENSION citus UPDATE TO '10.0-4';
|
ALTER EXTENSION citus UPDATE TO '10.0-4';
|
||||||
|
|
|
@ -1,19 +1,8 @@
|
||||||
--
|
--
|
||||||
-- MULTI_INSERT_SELECT
|
-- MULTI_INSERT_SELECT
|
||||||
--
|
--
|
||||||
-- This test file has an alternative output because of the change in the
|
|
||||||
-- display of SQL-standard function's arguments in INSERT/SELECT in PG15.
|
|
||||||
-- The alternative output can be deleted when we drop support for PG14
|
|
||||||
--
|
|
||||||
CREATE SCHEMA multi_insert_select;
|
CREATE SCHEMA multi_insert_select;
|
||||||
SET search_path = multi_insert_select,public;
|
SET search_path = multi_insert_select,public;
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15;
|
|
||||||
server_version_ge_15
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
t
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SET citus.next_shard_id TO 13300000;
|
SET citus.next_shard_id TO 13300000;
|
||||||
SET citus.next_placement_id TO 13300000;
|
SET citus.next_placement_id TO 13300000;
|
||||||
-- create co-located tables
|
-- create co-located tables
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,17 +1,6 @@
|
||||||
--
|
--
|
||||||
-- MULTI_INSERT_SELECT_CONFLICT
|
-- MULTI_INSERT_SELECT_CONFLICT
|
||||||
--
|
--
|
||||||
-- This test file has an alternative output because of the change in the
|
|
||||||
-- display of SQL-standard function's arguments in INSERT/SELECT in PG15.
|
|
||||||
-- The alternative output can be deleted when we drop support for PG14
|
|
||||||
--
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15;
|
|
||||||
server_version_ge_15
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
t
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
CREATE SCHEMA on_conflict;
|
CREATE SCHEMA on_conflict;
|
||||||
SET search_path TO on_conflict, public;
|
SET search_path TO on_conflict, public;
|
||||||
SET citus.next_shard_id TO 1900000;
|
SET citus.next_shard_id TO 1900000;
|
||||||
|
|
|
@ -1,600 +0,0 @@
|
||||||
--
|
|
||||||
-- MULTI_INSERT_SELECT_CONFLICT
|
|
||||||
--
|
|
||||||
-- This test file has an alternative output because of the change in the
|
|
||||||
-- display of SQL-standard function's arguments in INSERT/SELECT in PG15.
|
|
||||||
-- The alternative output can be deleted when we drop support for PG14
|
|
||||||
--
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15;
|
|
||||||
server_version_ge_15
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
f
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
CREATE SCHEMA on_conflict;
|
|
||||||
SET search_path TO on_conflict, public;
|
|
||||||
SET citus.next_shard_id TO 1900000;
|
|
||||||
SET citus.shard_replication_factor TO 1;
|
|
||||||
CREATE TABLE target_table(col_1 int primary key, col_2 int);
|
|
||||||
SELECT create_distributed_table('target_table','col_1');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
INSERT INTO target_table VALUES(1,2),(2,3),(3,4),(4,5),(5,6);
|
|
||||||
CREATE TABLE source_table_1(col_1 int primary key, col_2 int, col_3 int);
|
|
||||||
SELECT create_distributed_table('source_table_1','col_1');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
INSERT INTO source_table_1 VALUES(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5);
|
|
||||||
CREATE TABLE source_table_2(col_1 int, col_2 int, col_3 int);
|
|
||||||
SELECT create_distributed_table('source_table_2','col_1');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
INSERT INTO source_table_2 VALUES(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
|
|
||||||
SET client_min_messages to debug1;
|
|
||||||
-- Generate series directly on the coordinator and on conflict do nothing
|
|
||||||
INSERT INTO target_table (col_1, col_2)
|
|
||||||
SELECT
|
|
||||||
s, s
|
|
||||||
FROM
|
|
||||||
generate_series(1,10) s
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
DEBUG: distributed INSERT ... SELECT can only select from distributed tables
|
|
||||||
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
|
||||||
-- Generate series directly on the coordinator and on conflict update the target table
|
|
||||||
INSERT INTO target_table (col_1, col_2)
|
|
||||||
SELECT s, s
|
|
||||||
FROM
|
|
||||||
generate_series(1,10) s
|
|
||||||
ON CONFLICT(col_1) DO UPDATE SET col_2 = EXCLUDED.col_2 + 1;
|
|
||||||
DEBUG: distributed INSERT ... SELECT can only select from distributed tables
|
|
||||||
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
|
||||||
-- Since partition columns do not match, pull the data to the coordinator
|
|
||||||
-- and do not change conflicted values
|
|
||||||
INSERT INTO target_table
|
|
||||||
SELECT
|
|
||||||
col_2, col_3
|
|
||||||
FROM
|
|
||||||
source_table_1
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
DEBUG: cannot perform distributed INSERT INTO ... SELECT because the partition columns in the source table and subquery do not match
|
|
||||||
DETAIL: The target table's partition column should correspond to a partition column in the subquery.
|
|
||||||
DEBUG: performing repartitioned INSERT ... SELECT
|
|
||||||
-- Since partition columns do not match, pull the data to the coordinator
|
|
||||||
-- and update the non-partition column. Query is wrapped by CTE to return
|
|
||||||
-- ordered result.
|
|
||||||
WITH inserted_table AS (
|
|
||||||
INSERT INTO target_table
|
|
||||||
SELECT
|
|
||||||
col_2, col_3
|
|
||||||
FROM
|
|
||||||
source_table_1
|
|
||||||
ON CONFLICT(col_1) DO UPDATE SET col_2 = EXCLUDED.col_2 RETURNING *
|
|
||||||
) SELECT * FROM inserted_table ORDER BY 1;
|
|
||||||
DEBUG: generating subplan XXX_1 for CTE inserted_table: INSERT INTO on_conflict.target_table (col_1, col_2) SELECT col_2, col_3 FROM on_conflict.source_table_1 ON CONFLICT(col_1) DO UPDATE SET col_2 = excluded.col_2 RETURNING target_table.col_1, target_table.col_2
|
|
||||||
DEBUG: cannot perform distributed INSERT INTO ... SELECT because the partition columns in the source table and subquery do not match
|
|
||||||
DETAIL: The target table's partition column should correspond to a partition column in the subquery.
|
|
||||||
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT col_1, col_2 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer)) inserted_table ORDER BY col_1
|
|
||||||
DEBUG: performing repartitioned INSERT ... SELECT
|
|
||||||
col_1 | col_2
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
1 | 1
|
|
||||||
2 | 2
|
|
||||||
3 | 3
|
|
||||||
4 | 4
|
|
||||||
5 | 5
|
|
||||||
(5 rows)
|
|
||||||
|
|
||||||
-- Subquery should be recursively planned due to the limit and do nothing on conflict
|
|
||||||
INSERT INTO target_table
|
|
||||||
SELECT
|
|
||||||
col_1, col_2
|
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
col_1, col_2, col_3
|
|
||||||
FROM
|
|
||||||
source_table_1
|
|
||||||
LIMIT 5
|
|
||||||
) as foo
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
DEBUG: cannot push down this subquery
|
|
||||||
DETAIL: Limit clause is currently unsupported when a subquery references a column from another query
|
|
||||||
DEBUG: push down of limit count: 5
|
|
||||||
DEBUG: generating subplan XXX_1 for subquery SELECT col_1, col_2, col_3 FROM on_conflict.source_table_1 LIMIT 5
|
|
||||||
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT col_1, col_2 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2, intermediate_result.col_3 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer, col_3 integer)) foo
|
|
||||||
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
|
||||||
-- Subquery should be recursively planned due to the limit and update on conflict
|
|
||||||
-- Query is wrapped by CTE to return ordered result.
|
|
||||||
WITH inserted_table AS (
|
|
||||||
INSERT INTO target_table
|
|
||||||
SELECT
|
|
||||||
col_1, col_2
|
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
col_1, col_2, col_3
|
|
||||||
FROM
|
|
||||||
source_table_1
|
|
||||||
LIMIT 5
|
|
||||||
) as foo
|
|
||||||
ON CONFLICT(col_1) DO UPDATE SET col_2 = EXCLUDED.col_2 RETURNING *
|
|
||||||
) SELECT * FROM inserted_table ORDER BY 1;
|
|
||||||
DEBUG: generating subplan XXX_1 for CTE inserted_table: INSERT INTO on_conflict.target_table (col_1, col_2) SELECT col_1, col_2 FROM (SELECT source_table_1.col_1, source_table_1.col_2, source_table_1.col_3 FROM on_conflict.source_table_1 LIMIT 5) foo ON CONFLICT(col_1) DO UPDATE SET col_2 = excluded.col_2 RETURNING target_table.col_1, target_table.col_2
|
|
||||||
DEBUG: cannot push down this subquery
|
|
||||||
DETAIL: Limit clause is currently unsupported when a subquery references a column from another query
|
|
||||||
DEBUG: push down of limit count: 5
|
|
||||||
DEBUG: generating subplan XXX_1 for subquery SELECT col_1, col_2, col_3 FROM on_conflict.source_table_1 LIMIT 5
|
|
||||||
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT col_1, col_2 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2, intermediate_result.col_3 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer, col_3 integer)) foo
|
|
||||||
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT col_1, col_2 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer)) inserted_table ORDER BY col_1
|
|
||||||
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
|
||||||
col_1 | col_2
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
1 | 1
|
|
||||||
2 | 2
|
|
||||||
3 | 3
|
|
||||||
4 | 4
|
|
||||||
5 | 5
|
|
||||||
(5 rows)
|
|
||||||
|
|
||||||
-- Test with multiple subqueries. Query is wrapped by CTE to return ordered result.
|
|
||||||
WITH inserted_table AS (
|
|
||||||
INSERT INTO target_table
|
|
||||||
SELECT
|
|
||||||
col_1, col_2
|
|
||||||
FROM (
|
|
||||||
(SELECT
|
|
||||||
col_1, col_2, col_3
|
|
||||||
FROM
|
|
||||||
source_table_1
|
|
||||||
LIMIT 5)
|
|
||||||
UNION
|
|
||||||
(SELECT
|
|
||||||
col_1, col_2, col_3
|
|
||||||
FROM
|
|
||||||
source_table_2
|
|
||||||
LIMIT 5)
|
|
||||||
) as foo
|
|
||||||
ON CONFLICT(col_1) DO UPDATE SET col_2 = 0 RETURNING *
|
|
||||||
) SELECT * FROM inserted_table ORDER BY 1;
|
|
||||||
DEBUG: generating subplan XXX_1 for CTE inserted_table: INSERT INTO on_conflict.target_table (col_1, col_2) SELECT col_1, col_2 FROM ((SELECT source_table_1.col_1, source_table_1.col_2, source_table_1.col_3 FROM on_conflict.source_table_1 LIMIT 5) UNION (SELECT source_table_2.col_1, source_table_2.col_2, source_table_2.col_3 FROM on_conflict.source_table_2 LIMIT 5)) foo ON CONFLICT(col_1) DO UPDATE SET col_2 = 0 RETURNING target_table.col_1, target_table.col_2
|
|
||||||
DEBUG: cannot push down this subquery
|
|
||||||
DETAIL: Limit clause is currently unsupported when a subquery references a column from another query
|
|
||||||
DEBUG: push down of limit count: 5
|
|
||||||
DEBUG: generating subplan XXX_1 for subquery SELECT col_1, col_2, col_3 FROM on_conflict.source_table_1 LIMIT 5
|
|
||||||
DEBUG: push down of limit count: 5
|
|
||||||
DEBUG: generating subplan XXX_2 for subquery SELECT col_1, col_2, col_3 FROM on_conflict.source_table_2 LIMIT 5
|
|
||||||
DEBUG: generating subplan XXX_3 for subquery SELECT intermediate_result.col_1, intermediate_result.col_2, intermediate_result.col_3 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer, col_3 integer) UNION SELECT intermediate_result.col_1, intermediate_result.col_2, intermediate_result.col_3 FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer, col_3 integer)
|
|
||||||
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT col_1, col_2 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2, intermediate_result.col_3 FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer, col_3 integer)) foo
|
|
||||||
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT col_1, col_2 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer)) inserted_table ORDER BY col_1
|
|
||||||
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
|
||||||
col_1 | col_2
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
1 | 0
|
|
||||||
2 | 0
|
|
||||||
3 | 0
|
|
||||||
4 | 0
|
|
||||||
5 | 0
|
|
||||||
6 | 0
|
|
||||||
7 | 0
|
|
||||||
8 | 0
|
|
||||||
9 | 0
|
|
||||||
10 | 0
|
|
||||||
(10 rows)
|
|
||||||
|
|
||||||
-- Get the select part from cte and do nothing on conflict
|
|
||||||
WITH cte AS MATERIALIZED (
|
|
||||||
SELECT col_1, col_2 FROM source_table_1
|
|
||||||
)
|
|
||||||
INSERT INTO target_table SELECT * FROM cte ON CONFLICT DO NOTHING;
|
|
||||||
DEBUG: distributed INSERT ... SELECT can only select from distributed tables
|
|
||||||
DEBUG: generating subplan XXX_1 for CTE cte: SELECT col_1, col_2 FROM on_conflict.source_table_1
|
|
||||||
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT col_1, col_2 FROM (SELECT cte.col_1, cte.col_2 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer)) cte) citus_insert_select_subquery
|
|
||||||
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
|
||||||
-- Get the select part from cte and update on conflict
|
|
||||||
WITH cte AS MATERIALIZED (
|
|
||||||
SELECT col_1, col_2 FROM source_table_1
|
|
||||||
)
|
|
||||||
INSERT INTO target_table SELECT * FROM cte ON CONFLICT(col_1) DO UPDATE SET col_2 = EXCLUDED.col_2 + 1;
|
|
||||||
DEBUG: distributed INSERT ... SELECT can only select from distributed tables
|
|
||||||
DEBUG: generating subplan XXX_1 for CTE cte: SELECT col_1, col_2 FROM on_conflict.source_table_1
|
|
||||||
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT col_1, col_2 FROM (SELECT cte.col_1, cte.col_2 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer)) cte) citus_insert_select_subquery
|
|
||||||
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
|
||||||
SELECT * FROM target_table ORDER BY 1;
|
|
||||||
col_1 | col_2
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
1 | 2
|
|
||||||
2 | 3
|
|
||||||
3 | 4
|
|
||||||
4 | 5
|
|
||||||
5 | 6
|
|
||||||
6 | 0
|
|
||||||
7 | 0
|
|
||||||
8 | 0
|
|
||||||
9 | 0
|
|
||||||
10 | 0
|
|
||||||
(10 rows)
|
|
||||||
|
|
||||||
-- Test with multiple CTEs
|
|
||||||
WITH cte AS(
|
|
||||||
SELECT col_1, col_2 FROM source_table_1
|
|
||||||
), cte_2 AS(
|
|
||||||
SELECT col_1, col_2 FROM source_table_2
|
|
||||||
)
|
|
||||||
INSERT INTO target_table ((SELECT * FROM cte) UNION (SELECT * FROM cte_2)) ON CONFLICT(col_1) DO UPDATE SET col_2 = EXCLUDED.col_2 + 1;
|
|
||||||
DEBUG: distributed INSERT ... SELECT can only select from distributed tables
|
|
||||||
DEBUG: CTE cte is going to be inlined via distributed planning
|
|
||||||
DEBUG: CTE cte_2 is going to be inlined via distributed planning
|
|
||||||
DEBUG: performing repartitioned INSERT ... SELECT
|
|
||||||
SELECT * FROM target_table ORDER BY 1;
|
|
||||||
col_1 | col_2
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
1 | 2
|
|
||||||
2 | 3
|
|
||||||
3 | 4
|
|
||||||
4 | 5
|
|
||||||
5 | 6
|
|
||||||
6 | 7
|
|
||||||
7 | 8
|
|
||||||
8 | 9
|
|
||||||
9 | 10
|
|
||||||
10 | 11
|
|
||||||
(10 rows)
|
|
||||||
|
|
||||||
WITH inserted_table AS MATERIALIZED (
|
|
||||||
WITH cte AS MATERIALIZED (
|
|
||||||
SELECT col_1, col_2, col_3 FROM source_table_1
|
|
||||||
), cte_2 AS MATERIALIZED (
|
|
||||||
SELECT col_1, col_2 FROM cte
|
|
||||||
)
|
|
||||||
INSERT INTO target_table SELECT * FROM cte_2 ON CONFLICT(col_1) DO UPDATE SET col_2 = EXCLUDED.col_2 + 1 RETURNING *
|
|
||||||
) SELECT * FROM inserted_table ORDER BY 1;
|
|
||||||
DEBUG: generating subplan XXX_1 for CTE inserted_table: WITH cte AS MATERIALIZED (SELECT source_table_1.col_1, source_table_1.col_2, source_table_1.col_3 FROM on_conflict.source_table_1), cte_2 AS MATERIALIZED (SELECT cte.col_1, cte.col_2 FROM cte) INSERT INTO on_conflict.target_table (col_1, col_2) SELECT col_1, col_2 FROM cte_2 ON CONFLICT(col_1) DO UPDATE SET col_2 = (excluded.col_2 OPERATOR(pg_catalog.+) 1) RETURNING target_table.col_1, target_table.col_2
|
|
||||||
DEBUG: distributed INSERT ... SELECT can only select from distributed tables
|
|
||||||
DEBUG: generating subplan XXX_1 for CTE cte: SELECT col_1, col_2, col_3 FROM on_conflict.source_table_1
|
|
||||||
DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT col_1, col_2 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2, intermediate_result.col_3 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer, col_3 integer)) cte
|
|
||||||
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT col_1, col_2 FROM (SELECT cte_2.col_1, cte_2.col_2 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2 FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer)) cte_2) citus_insert_select_subquery
|
|
||||||
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT col_1, col_2 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer)) inserted_table ORDER BY col_1
|
|
||||||
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
|
||||||
col_1 | col_2
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
1 | 2
|
|
||||||
2 | 3
|
|
||||||
3 | 4
|
|
||||||
4 | 5
|
|
||||||
5 | 6
|
|
||||||
(5 rows)
|
|
||||||
|
|
||||||
WITH cte AS MATERIALIZED (
|
|
||||||
WITH basic AS MATERIALIZED (
|
|
||||||
SELECT col_1, col_2 FROM source_table_1
|
|
||||||
)
|
|
||||||
INSERT INTO target_table (SELECT * FROM basic) ON CONFLICT DO NOTHING RETURNING *
|
|
||||||
)
|
|
||||||
UPDATE target_table SET col_2 = 4 WHERE col_1 IN (SELECT col_1 FROM cte);
|
|
||||||
DEBUG: generating subplan XXX_1 for CTE cte: WITH basic AS MATERIALIZED (SELECT source_table_1.col_1, source_table_1.col_2 FROM on_conflict.source_table_1) INSERT INTO on_conflict.target_table (col_1, col_2) SELECT col_1, col_2 FROM basic ON CONFLICT DO NOTHING RETURNING target_table.col_1, target_table.col_2
|
|
||||||
DEBUG: distributed INSERT ... SELECT can only select from distributed tables
|
|
||||||
DEBUG: generating subplan XXX_1 for CTE basic: SELECT col_1, col_2 FROM on_conflict.source_table_1
|
|
||||||
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT col_1, col_2 FROM (SELECT basic.col_1, basic.col_2 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer)) basic) citus_insert_select_subquery
|
|
||||||
DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE on_conflict.target_table SET col_2 = 4 WHERE (col_1 OPERATOR(pg_catalog.=) ANY (SELECT cte.col_1 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer)) cte))
|
|
||||||
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
|
||||||
RESET client_min_messages;
|
|
||||||
-- Following query is supported by using repartition join for the insert/select
|
|
||||||
SELECT coordinator_plan($Q$
|
|
||||||
EXPLAIN (costs off)
|
|
||||||
WITH cte AS (
|
|
||||||
SELECT
|
|
||||||
col_1, col_2
|
|
||||||
FROM
|
|
||||||
source_table_1
|
|
||||||
)
|
|
||||||
INSERT INTO target_table
|
|
||||||
SELECT
|
|
||||||
source_table_1.col_1,
|
|
||||||
source_table_1.col_2
|
|
||||||
FROM cte, source_table_1
|
|
||||||
WHERE cte.col_1 = source_table_1.col_1 ON CONFLICT DO NOTHING;
|
|
||||||
$Q$);
|
|
||||||
coordinator_plan
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
Custom Scan (Citus INSERT ... SELECT)
|
|
||||||
INSERT/SELECT method: repartition
|
|
||||||
-> Custom Scan (Citus Adaptive)
|
|
||||||
Task Count: 4
|
|
||||||
(4 rows)
|
|
||||||
|
|
||||||
-- Tests with foreign key to reference table
|
|
||||||
CREATE TABLE test_ref_table (key int PRIMARY KEY);
|
|
||||||
SELECT create_reference_table('test_ref_table');
|
|
||||||
create_reference_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
INSERT INTO test_ref_table VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
|
|
||||||
ALTER TABLE target_table ADD CONSTRAINT fkey FOREIGN KEY (col_1) REFERENCES test_ref_table(key) ON DELETE CASCADE;
|
|
||||||
BEGIN;
|
|
||||||
TRUNCATE test_ref_table CASCADE;
|
|
||||||
NOTICE: truncate cascades to table "target_table"
|
|
||||||
INSERT INTO
|
|
||||||
target_table
|
|
||||||
SELECT
|
|
||||||
col_2,
|
|
||||||
col_1
|
|
||||||
FROM source_table_1 ON CONFLICT (col_1) DO UPDATE SET col_2 = 55 RETURNING *;
|
|
||||||
ERROR: insert or update on table "target_table_xxxxxxx" violates foreign key constraint "fkey_xxxxxxx"
|
|
||||||
DETAIL: Key (col_1)=(X) is not present in table "test_ref_table_xxxxxxx".
|
|
||||||
CONTEXT: while executing command on localhost:xxxxx
|
|
||||||
ROLLBACK;
|
|
||||||
BEGIN;
|
|
||||||
DELETE FROM test_ref_table WHERE key > 10;
|
|
||||||
WITH r AS (
|
|
||||||
INSERT INTO
|
|
||||||
target_table
|
|
||||||
SELECT
|
|
||||||
col_2,
|
|
||||||
col_1
|
|
||||||
FROM source_table_1 ON CONFLICT (col_1) DO UPDATE SET col_2 = 1 RETURNING *)
|
|
||||||
SELECT * FROM r ORDER BY col_1;
|
|
||||||
col_1 | col_2
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
1 | 1
|
|
||||||
2 | 1
|
|
||||||
3 | 1
|
|
||||||
4 | 1
|
|
||||||
5 | 1
|
|
||||||
(5 rows)
|
|
||||||
|
|
||||||
ROLLBACK;
|
|
||||||
-- Following two queries are supported since we no not modify but only select from
|
|
||||||
-- the target_table after modification on test_ref_table.
|
|
||||||
BEGIN;
|
|
||||||
TRUNCATE test_ref_table CASCADE;
|
|
||||||
NOTICE: truncate cascades to table "target_table"
|
|
||||||
INSERT INTO
|
|
||||||
source_table_1
|
|
||||||
SELECT
|
|
||||||
col_2,
|
|
||||||
col_1
|
|
||||||
FROM target_table ON CONFLICT (col_1) DO UPDATE SET col_2 = 55 RETURNING *;
|
|
||||||
col_1 | col_2 | col_3
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
(0 rows)
|
|
||||||
|
|
||||||
ROLLBACK;
|
|
||||||
BEGIN;
|
|
||||||
DELETE FROM test_ref_table;
|
|
||||||
INSERT INTO
|
|
||||||
source_table_1
|
|
||||||
SELECT
|
|
||||||
col_2,
|
|
||||||
col_1
|
|
||||||
FROM target_table ON CONFLICT (col_1) DO UPDATE SET col_2 = 55 RETURNING *;
|
|
||||||
col_1 | col_2 | col_3
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
(0 rows)
|
|
||||||
|
|
||||||
ROLLBACK;
|
|
||||||
-- INSERT .. SELECT with different column types
|
|
||||||
CREATE TABLE source_table_3(col_1 numeric, col_2 numeric, col_3 numeric);
|
|
||||||
SELECT create_distributed_table('source_table_3','col_1');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
INSERT INTO source_table_3 VALUES(1,11,1),(2,22,2),(3,33,3),(4,44,4),(5,55,5);
|
|
||||||
CREATE TABLE source_table_4(id int, arr_val text[]);
|
|
||||||
SELECT create_distributed_table('source_table_4','id');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
INSERT INTO source_table_4 VALUES(1, '{"abc","cde","efg"}'), (2, '{"xyz","tvu"}');
|
|
||||||
CREATE TABLE target_table_2(id int primary key, arr_val char(10)[]);
|
|
||||||
SELECT create_distributed_table('target_table_2','id');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
INSERT INTO target_table_2 VALUES(1, '{"abc","def","gyx"}');
|
|
||||||
SET client_min_messages to debug1;
|
|
||||||
INSERT INTO target_table
|
|
||||||
SELECT
|
|
||||||
col_1, col_2
|
|
||||||
FROM
|
|
||||||
source_table_3
|
|
||||||
ON CONFLICT(col_1) DO UPDATE SET col_2 = EXCLUDED.col_2;
|
|
||||||
DEBUG: cannot perform distributed INSERT INTO ... SELECT because the partition columns in the source table and subquery do not match
|
|
||||||
DETAIL: The data type of the target table's partition column should exactly match the data type of the corresponding simple column reference in the subquery.
|
|
||||||
DEBUG: performing repartitioned INSERT ... SELECT
|
|
||||||
SELECT * FROM target_table ORDER BY 1;
|
|
||||||
col_1 | col_2
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
1 | 11
|
|
||||||
2 | 22
|
|
||||||
3 | 33
|
|
||||||
4 | 44
|
|
||||||
5 | 55
|
|
||||||
6 | 7
|
|
||||||
7 | 8
|
|
||||||
8 | 9
|
|
||||||
9 | 10
|
|
||||||
10 | 11
|
|
||||||
(10 rows)
|
|
||||||
|
|
||||||
INSERT INTO target_table_2
|
|
||||||
SELECT
|
|
||||||
*
|
|
||||||
FROM
|
|
||||||
source_table_4
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
SELECT * FROM target_table_2 ORDER BY 1;
|
|
||||||
id | arr_val
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
1 | {"abc ","def ","gyx "}
|
|
||||||
2 | {"xyz ","tvu "}
|
|
||||||
(2 rows)
|
|
||||||
|
|
||||||
RESET client_min_messages;
|
|
||||||
-- Test with shard_replication_factor = 2
|
|
||||||
SET citus.shard_replication_factor to 2;
|
|
||||||
DROP TABLE target_table, source_table_1, source_table_2;
|
|
||||||
CREATE TABLE target_table(col_1 int primary key, col_2 int);
|
|
||||||
SELECT create_distributed_table('target_table','col_1');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
INSERT INTO target_table VALUES(1,2),(2,3),(3,4),(4,5),(5,6);
|
|
||||||
CREATE TABLE source_table_1(col_1 int, col_2 int, col_3 int);
|
|
||||||
SELECT create_distributed_table('source_table_1','col_1');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
INSERT INTO source_table_1 VALUES(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5);
|
|
||||||
CREATE TABLE source_table_2(col_1 int, col_2 int, col_3 int);
|
|
||||||
SELECT create_distributed_table('source_table_2','col_1');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
INSERT INTO source_table_2 VALUES(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
|
|
||||||
SET client_min_messages to debug1;
|
|
||||||
-- Generate series directly on the coordinator and on conflict do nothing
|
|
||||||
INSERT INTO target_table (col_1, col_2)
|
|
||||||
SELECT
|
|
||||||
s, s
|
|
||||||
FROM
|
|
||||||
generate_series(1,10) s
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
DEBUG: distributed INSERT ... SELECT can only select from distributed tables
|
|
||||||
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
|
||||||
-- Test with multiple subqueries
|
|
||||||
INSERT INTO target_table
|
|
||||||
SELECT
|
|
||||||
col_1, col_2
|
|
||||||
FROM (
|
|
||||||
(SELECT
|
|
||||||
col_1, col_2, col_3
|
|
||||||
FROM
|
|
||||||
source_table_1
|
|
||||||
LIMIT 5)
|
|
||||||
UNION
|
|
||||||
(SELECT
|
|
||||||
col_1, col_2, col_3
|
|
||||||
FROM
|
|
||||||
source_table_2
|
|
||||||
LIMIT 5)
|
|
||||||
) as foo
|
|
||||||
ON CONFLICT(col_1) DO UPDATE SET col_2 = 0;
|
|
||||||
DEBUG: cannot push down this subquery
|
|
||||||
DETAIL: Limit clause is currently unsupported when a subquery references a column from another query
|
|
||||||
DEBUG: push down of limit count: 5
|
|
||||||
DEBUG: generating subplan XXX_1 for subquery SELECT col_1, col_2, col_3 FROM on_conflict.source_table_1 LIMIT 5
|
|
||||||
DEBUG: push down of limit count: 5
|
|
||||||
DEBUG: generating subplan XXX_2 for subquery SELECT col_1, col_2, col_3 FROM on_conflict.source_table_2 LIMIT 5
|
|
||||||
DEBUG: generating subplan XXX_3 for subquery SELECT intermediate_result.col_1, intermediate_result.col_2, intermediate_result.col_3 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer, col_3 integer) UNION SELECT intermediate_result.col_1, intermediate_result.col_2, intermediate_result.col_3 FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer, col_3 integer)
|
|
||||||
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT col_1, col_2 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2, intermediate_result.col_3 FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer, col_3 integer)) foo
|
|
||||||
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
|
||||||
SELECT * FROM target_table ORDER BY 1;
|
|
||||||
col_1 | col_2
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
1 | 0
|
|
||||||
2 | 0
|
|
||||||
3 | 0
|
|
||||||
4 | 0
|
|
||||||
5 | 0
|
|
||||||
6 | 0
|
|
||||||
7 | 0
|
|
||||||
8 | 0
|
|
||||||
9 | 0
|
|
||||||
10 | 0
|
|
||||||
(10 rows)
|
|
||||||
|
|
||||||
WITH cte AS MATERIALIZED(
|
|
||||||
SELECT col_1, col_2, col_3 FROM source_table_1
|
|
||||||
), cte_2 AS MATERIALIZED(
|
|
||||||
SELECT col_1, col_2 FROM cte
|
|
||||||
)
|
|
||||||
INSERT INTO target_table SELECT * FROM cte_2 ON CONFLICT(col_1) DO UPDATE SET col_2 = EXCLUDED.col_2 + 1;
|
|
||||||
DEBUG: distributed INSERT ... SELECT can only select from distributed tables
|
|
||||||
DEBUG: generating subplan XXX_1 for CTE cte: SELECT col_1, col_2, col_3 FROM on_conflict.source_table_1
|
|
||||||
DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT col_1, col_2 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2, intermediate_result.col_3 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer, col_3 integer)) cte
|
|
||||||
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT col_1, col_2 FROM (SELECT cte_2.col_1, cte_2.col_2 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2 FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer)) cte_2) citus_insert_select_subquery
|
|
||||||
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
|
||||||
SELECT * FROM target_table ORDER BY 1;
|
|
||||||
col_1 | col_2
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
1 | 2
|
|
||||||
2 | 3
|
|
||||||
3 | 4
|
|
||||||
4 | 5
|
|
||||||
5 | 6
|
|
||||||
6 | 0
|
|
||||||
7 | 0
|
|
||||||
8 | 0
|
|
||||||
9 | 0
|
|
||||||
10 | 0
|
|
||||||
(10 rows)
|
|
||||||
|
|
||||||
-- make sure that even if COPY switchover happens
|
|
||||||
-- the results are correct
|
|
||||||
SET citus.copy_switchover_threshold TO 1;
|
|
||||||
TRUNCATE target_table;
|
|
||||||
-- load some data to make sure copy commands switch over connections
|
|
||||||
INSERT INTO target_table SELECT i,0 FROM generate_series(0,500)i;
|
|
||||||
DEBUG: distributed INSERT ... SELECT can only select from distributed tables
|
|
||||||
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
|
||||||
-- make sure that SELECT only uses 1 connection 1 node
|
|
||||||
-- yet still COPY commands use 1 connection per co-located
|
|
||||||
-- intermediate result file
|
|
||||||
SET citus.max_adaptive_executor_pool_size TO 1;
|
|
||||||
INSERT INTO target_table SELECT * FROM target_table LIMIT 10000 ON CONFLICT(col_1) DO UPDATE SET col_2 = EXCLUDED.col_2 + 1;
|
|
||||||
DEBUG: cannot push down this subquery
|
|
||||||
DETAIL: Limit clause is currently unsupported when a subquery references a column from another query
|
|
||||||
DEBUG: push down of limit count: 10000
|
|
||||||
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
|
||||||
SELECT DISTINCT col_2 FROM target_table;
|
|
||||||
col_2
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
1
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
WITH cte_1 AS (INSERT INTO target_table SELECT * FROM target_table LIMIT 10000 ON CONFLICT(col_1) DO UPDATE SET col_2 = EXCLUDED.col_2 + 1 RETURNING *)
|
|
||||||
SELECT DISTINCT col_2 FROM cte_1;
|
|
||||||
DEBUG: generating subplan XXX_1 for CTE cte_1: INSERT INTO on_conflict.target_table (col_1, col_2) SELECT col_1, col_2 FROM on_conflict.target_table LIMIT 10000 ON CONFLICT(col_1) DO UPDATE SET col_2 = (excluded.col_2 OPERATOR(pg_catalog.+) 1) RETURNING target_table.col_1, target_table.col_2
|
|
||||||
DEBUG: cannot push down this subquery
|
|
||||||
DETAIL: Limit clause is currently unsupported when a subquery references a column from another query
|
|
||||||
DEBUG: push down of limit count: 10000
|
|
||||||
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT DISTINCT col_2 FROM (SELECT intermediate_result.col_1, intermediate_result.col_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(col_1 integer, col_2 integer)) cte_1
|
|
||||||
DEBUG: Collecting INSERT ... SELECT results on coordinator
|
|
||||||
col_2
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
2
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
RESET client_min_messages;
|
|
||||||
DROP SCHEMA on_conflict CASCADE;
|
|
||||||
NOTICE: drop cascades to 8 other objects
|
|
||||||
DETAIL: drop cascades to table test_ref_table
|
|
||||||
drop cascades to table test_ref_table_1900012
|
|
||||||
drop cascades to table source_table_3
|
|
||||||
drop cascades to table source_table_4
|
|
||||||
drop cascades to table target_table_2
|
|
||||||
drop cascades to table target_table
|
|
||||||
drop cascades to table source_table_1
|
|
||||||
drop cascades to table source_table_2
|
|
|
@ -1,16 +1,6 @@
|
||||||
--
|
--
|
||||||
-- MULTI_METADATA_SYNC
|
-- MULTI_METADATA_SYNC
|
||||||
--
|
--
|
||||||
-- this test has different output for PG14 compared to PG15
|
|
||||||
-- In PG15, public schema is owned by pg_database_owner role
|
|
||||||
-- Relevant PG commit: b073c3ccd06e4cb845e121387a43faa8c68a7b62
|
|
||||||
SHOW server_version \gset
|
|
||||||
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15;
|
|
||||||
server_version_ge_15
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
t
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- Tests for metadata snapshot functions, metadata syncing functions and propagation of
|
-- Tests for metadata snapshot functions, metadata syncing functions and propagation of
|
||||||
-- metadata changes to MX tables.
|
-- metadata changes to MX tables.
|
||||||
-- Turn metadata sync off at first
|
-- Turn metadata sync off at first
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue