pull/8372/merge
Naisila Puka 2025-12-07 20:30:29 +00:00 committed by GitHub
commit dba6fdb01e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
104 changed files with 80 additions and 20248 deletions

View File

@ -72,18 +72,6 @@ ENV PATH="/home/citus/.pgenv/pgsql/bin:${PATH}"
USER citus
# build postgres versions separately for effective parrallelism and caching of already built versions when changing only certain versions
FROM base AS pg15
RUN MAKEFLAGS="-j $(nproc)" pgenv build 15.14
RUN rm .pgenv/src/*.tar*
RUN make -C .pgenv/src/postgresql-*/ clean
RUN make -C .pgenv/src/postgresql-*/src/include install
# create a staging directory with all files we want to copy from our pgenv build
# we will copy the contents of the staged folder into the final image at once
RUN mkdir .pgenv-staging/
RUN cp -r .pgenv/src .pgenv/pgsql-* .pgenv/config .pgenv-staging/
RUN rm .pgenv-staging/config/default.conf
FROM base AS pg16
RUN MAKEFLAGS="-j $(nproc)" pgenv build 16.10
RUN rm .pgenv/src/*.tar*
@ -198,7 +186,6 @@ RUN git clone https://github.com/so-fancy/diff-so-fancy.git \
COPY --link --from=uncrustify-builder /uncrustify/usr/ /usr/
COPY --link --from=pg15 /home/citus/.pgenv-staging/ /home/citus/.pgenv/
COPY --link --from=pg16 /home/citus/.pgenv-staging/ /home/citus/.pgenv/
COPY --link --from=pg17 /home/citus/.pgenv-staging/ /home/citus/.pgenv/

1
.gitattributes vendored
View File

@ -25,7 +25,6 @@ configure -whitespace
# except these exceptions...
src/backend/distributed/utils/citus_outfuncs.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_17.c -citus-style
src/backend/distributed/deparser/ruleutils_18.c -citus-style

View File

@ -32,11 +32,10 @@ jobs:
style_checker_image_name: "ghcr.io/citusdata/stylechecker"
style_checker_tools_version: "0.8.18"
sql_snapshot_pg_version: "17.6"
image_suffix: "-va20872f"
pg15_version: '{ "major": "15", "full": "15.14" }'
image_suffix: "-dev-76e863d"
pg16_version: '{ "major": "16", "full": "16.10" }'
pg17_version: '{ "major": "17", "full": "17.6" }'
upgrade_pg_versions: "15.14-16.10-17.6"
upgrade_pg_versions: "16.10-17.6"
steps:
# Since GHA jobs need at least one step we use a noop step here.
- name: Set up parameters
@ -110,7 +109,6 @@ jobs:
image_suffix:
- ${{ needs.params.outputs.image_suffix}}
pg_version:
- ${{ needs.params.outputs.pg15_version }}
- ${{ needs.params.outputs.pg16_version }}
- ${{ needs.params.outputs.pg17_version }}
runs-on: ubuntu-latest
@ -141,7 +139,6 @@ jobs:
image_name:
- ${{ needs.params.outputs.test_image_name }}
pg_version:
- ${{ needs.params.outputs.pg15_version }}
- ${{ needs.params.outputs.pg16_version }}
- ${{ needs.params.outputs.pg17_version }}
make:
@ -162,10 +159,6 @@ jobs:
- check-enterprise-isolation-logicalrep-2
- check-enterprise-isolation-logicalrep-3
include:
- make: check-failure
pg_version: ${{ needs.params.outputs.pg15_version }}
suite: regress
image_name: ${{ needs.params.outputs.fail_test_image_name }}
- make: check-failure
pg_version: ${{ needs.params.outputs.pg16_version }}
suite: regress
@ -174,10 +167,6 @@ jobs:
pg_version: ${{ needs.params.outputs.pg17_version }}
suite: regress
image_name: ${{ needs.params.outputs.fail_test_image_name }}
- make: check-enterprise-failure
pg_version: ${{ needs.params.outputs.pg15_version }}
suite: regress
image_name: ${{ needs.params.outputs.fail_test_image_name }}
- make: check-enterprise-failure
pg_version: ${{ needs.params.outputs.pg16_version }}
suite: regress
@ -186,10 +175,6 @@ jobs:
pg_version: ${{ needs.params.outputs.pg17_version }}
suite: regress
image_name: ${{ needs.params.outputs.fail_test_image_name }}
- make: check-pytest
pg_version: ${{ needs.params.outputs.pg15_version }}
suite: regress
image_name: ${{ needs.params.outputs.fail_test_image_name }}
- make: check-pytest
pg_version: ${{ needs.params.outputs.pg16_version }}
suite: regress
@ -198,10 +183,6 @@ jobs:
pg_version: ${{ needs.params.outputs.pg17_version }}
suite: regress
image_name: ${{ needs.params.outputs.fail_test_image_name }}
- make: installcheck
suite: cdc
image_name: ${{ needs.params.outputs.test_image_name }}
pg_version: ${{ needs.params.outputs.pg15_version }}
- make: installcheck
suite: cdc
image_name: ${{ needs.params.outputs.test_image_name }}
@ -210,10 +191,6 @@ jobs:
suite: cdc
image_name: ${{ needs.params.outputs.test_image_name }}
pg_version: ${{ needs.params.outputs.pg17_version }}
- make: check-query-generator
pg_version: ${{ needs.params.outputs.pg15_version }}
suite: regress
image_name: ${{ needs.params.outputs.fail_test_image_name }}
- make: check-query-generator
pg_version: ${{ needs.params.outputs.pg16_version }}
suite: regress
@ -268,7 +245,6 @@ jobs:
image_name:
- ${{ needs.params.outputs.fail_test_image_name }}
pg_version:
- ${{ needs.params.outputs.pg15_version }}
- ${{ needs.params.outputs.pg16_version }}
- ${{ needs.params.outputs.pg17_version }}
parallel: [0,1,2,3,4,5] # workaround for running 6 parallel jobs
@ -315,12 +291,8 @@ jobs:
fail-fast: false
matrix:
include:
- old_pg_major: 15
new_pg_major: 16
- old_pg_major: 16
new_pg_major: 17
- old_pg_major: 15
new_pg_major: 17
env:
old_pg_major: ${{ matrix.old_pg_major }}
new_pg_major: ${{ matrix.new_pg_major }}
@ -376,7 +348,6 @@ jobs:
fail-fast: false
matrix:
pg_version:
- ${{ needs.params.outputs.pg15_version }}
- ${{ needs.params.outputs.pg16_version }}
steps:
- uses: actions/checkout@v4

View File

@ -25,7 +25,7 @@ jobs:
name: Build Citus
runs-on: ubuntu-latest
container:
image: ${{ vars.build_image_name }}:${{ vars.pg15_version }}${{ vars.image_suffix }}
image: ${{ vars.build_image_name }}:${{ vars.pg16_version }}${{ vars.image_suffix }}
options: --user root
steps:
- uses: actions/checkout@v4
@ -55,7 +55,7 @@ jobs:
name: Test flakyness
runs-on: ubuntu-latest
container:
image: ${{ vars.fail_test_image_name }}:${{ vars.pg15_version }}${{ vars.image_suffix }}
image: ${{ vars.fail_test_image_name }}:${{ vars.pg16_version }}${{ vars.image_suffix }}
options: --user root
needs:
[build, prepare_parallelization_matrix]

2
configure vendored
View File

@ -2588,7 +2588,7 @@ fi
if test "$with_pg_version_check" = no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: building against PostgreSQL $version_num (skipped compatibility check)" >&5
$as_echo "$as_me: building against PostgreSQL $version_num (skipped compatibility check)" >&6;}
elif test "$version_num" != '15' -a "$version_num" != '16' -a "$version_num" != '17'; then
elif test "$version_num" != '16' -a "$version_num" != '17'; then
as_fn_error $? "Citus is not compatible with the detected PostgreSQL version ${version_num}." "$LINENO" 5
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: building against PostgreSQL $version_num" >&5

View File

@ -80,7 +80,7 @@ AC_SUBST(with_pg_version_check)
if test "$with_pg_version_check" = no; then
AC_MSG_NOTICE([building against PostgreSQL $version_num (skipped compatibility check)])
elif test "$version_num" != '15' -a "$version_num" != '16' -a "$version_num" != '17'; then
elif test "$version_num" != '16' -a "$version_num" != '17'; then
AC_MSG_ERROR([Citus is not compatible with the detected PostgreSQL version ${version_num}.])
else
AC_MSG_NOTICE([building against PostgreSQL $version_num])

View File

@ -25,9 +25,7 @@
#include <lz4.h>
#endif
#if PG_VERSION_NUM >= PG_VERSION_16
#include "varatt.h"
#endif
#if HAVE_LIBZSTD
#include <zstd.h>

View File

@ -39,11 +39,10 @@
#include "optimizer/paths.h"
#include "optimizer/plancat.h"
#include "optimizer/restrictinfo.h"
#if PG_VERSION_NUM >= PG_VERSION_16
#include "parser/parse_relation.h"
#include "parser/parsetree.h"
#endif
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
#include "utils/relcache.h"
#include "utils/ruleutils.h"
@ -140,9 +139,7 @@ static List * set_deparse_context_planstate(List *dpcontext, Node *node,
/* other helpers */
static List * ColumnarVarNeeded(ColumnarScanState *columnarScanState);
static Bitmapset * ColumnarAttrNeeded(ScanState *ss);
#if PG_VERSION_NUM >= PG_VERSION_16
static Bitmapset * fixup_inherited_columns(Oid parentId, Oid childId, Bitmapset *columns);
#endif
/* saved hook value in case of unload */
static set_rel_pathlist_hook_type PreviousSetRelPathlistHook = NULL;
@ -551,7 +548,7 @@ ColumnarIndexScanAdditionalCost(PlannerInfo *root, RelOptInfo *rel,
* "anti-correlated" (-1) since both help us avoiding from reading the
* same stripe again and again.
*/
double absIndexCorrelation = float_abs(indexCorrelation);
double absIndexCorrelation = fabs(indexCorrelation);
/*
* To estimate the number of stripes that we need to read, we do linear
@ -670,7 +667,7 @@ CheckVarStats(PlannerInfo *root, Var *var, Oid sortop, float4 *absVarCorrelation
* If the Var is not highly correlated, then the chunk's min/max bounds
* will be nearly useless.
*/
if (float_abs(varCorrelation) < ColumnarQualPushdownCorrelationThreshold)
if (fabs(varCorrelation) < ColumnarQualPushdownCorrelationThreshold)
{
if (absVarCorrelation)
{
@ -678,7 +675,7 @@ CheckVarStats(PlannerInfo *root, Var *var, Oid sortop, float4 *absVarCorrelation
* Report absVarCorrelation if caller wants to know why given
* var is rejected.
*/
*absVarCorrelation = float_abs(varCorrelation);
*absVarCorrelation = fabs(varCorrelation);
}
return false;
}
@ -1063,9 +1060,7 @@ FindCandidateRelids(PlannerInfo *root, RelOptInfo *rel, List *joinClauses)
* For the relevant PG16 commit requiring this addition:
* postgres/postgres@2489d76
*/
#if PG_VERSION_NUM >= PG_VERSION_16
candidateRelids = bms_del_members(candidateRelids, root->outer_join_rels);
#endif
return candidateRelids;
}
@ -1394,7 +1389,6 @@ AddColumnarScanPath(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte,
}
int numberOfColumnsRead = 0;
#if PG_VERSION_NUM >= PG_VERSION_16
if (rte->perminfoindex > 0)
{
/*
@ -1426,9 +1420,6 @@ AddColumnarScanPath(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte,
perminfo->
selectedCols));
}
#else
numberOfColumnsRead = bms_num_members(rte->selectedCols);
#endif
int numberOfClausesPushed = list_length(allClauses);
@ -1449,8 +1440,6 @@ AddColumnarScanPath(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte,
}
#if PG_VERSION_NUM >= PG_VERSION_16
/*
* fixup_inherited_columns
*
@ -1509,9 +1498,6 @@ fixup_inherited_columns(Oid parentId, Oid childId, Bitmapset *columns)
}
#endif
/*
* CostColumnarScan calculates the cost of scanning the columnar table. The
* cost is estimated by using all stripe metadata to estimate based on the

View File

@ -62,13 +62,9 @@
#include "distributed/listutils.h"
#if PG_VERSION_NUM >= PG_VERSION_16
#include "parser/parse_relation.h"
#include "storage/relfilelocator.h"
#include "utils/relfilenumbermap.h"
#else
#include "utils/relfilenodemap.h"
#endif
#define COLUMNAR_RELOPTION_NAMESPACE "columnar"
#define SLOW_METADATA_ACCESS_WARNING \
@ -730,7 +726,7 @@ ReadStripeSkipList(Relation rel, uint64 stripe,
ScanKeyData scanKey[2];
uint64 storageId = LookupStorageId(RelationPrecomputeOid(rel),
RelationPhysicalIdentifier_compat(rel));
rel->rd_locator);
Oid columnarChunkOid = ColumnarChunkRelationId();
Relation columnarChunk = table_open(columnarChunkOid, AccessShareLock);
@ -1277,7 +1273,7 @@ List *
StripesForRelfilelocator(Relation rel)
{
uint64 storageId = LookupStorageId(RelationPrecomputeOid(rel),
RelationPhysicalIdentifier_compat(rel));
rel->rd_locator);
/*
* PG18 requires snapshot to be active or registered before it's used
@ -1309,7 +1305,7 @@ uint64
GetHighestUsedAddress(Relation rel)
{
uint64 storageId = LookupStorageId(RelationPrecomputeOid(rel),
RelationPhysicalIdentifier_compat(rel));
rel->rd_locator);
uint64 highestUsedAddress = 0;
uint64 highestUsedId = 0;
@ -1330,10 +1326,8 @@ GetHighestUsedAddress(Relation rel)
Oid
ColumnarRelationId(Oid relid, RelFileLocator relfilelocator)
{
return OidIsValid(relid) ? relid : RelidByRelfilenumber(RelationTablespace_compat(
relfilelocator),
RelationPhysicalIdentifierNumber_compat(
relfilelocator));
return OidIsValid(relid) ? relid : RelidByRelfilenumber(relfilelocator.spcOid,
relfilelocator.relNumber);
}
@ -1624,7 +1618,7 @@ DeleteMetadataRows(Relation rel)
}
uint64 storageId = LookupStorageId(RelationPrecomputeOid(rel),
RelationPhysicalIdentifier_compat(rel));
rel->rd_locator);
DeleteStorageFromColumnarMetadataTable(ColumnarStripeRelationId(),
Anum_columnar_stripe_storageid,
@ -1789,10 +1783,8 @@ create_estate_for_relation(Relation rel)
rte->rellockmode = AccessShareLock;
/* Prepare permission info on PG 16+ */
#if PG_VERSION_NUM >= PG_VERSION_16
List *perminfos = NIL;
addRTEPermissionInfo(&perminfos, rte);
#endif
/* Initialize the range table, with the right signature for each PG version */
#if PG_VERSION_NUM >= PG_VERSION_18
@ -1804,7 +1796,7 @@ create_estate_for_relation(Relation rel)
perminfos,
NULL /* unpruned_relids: not used by columnar */
);
#elif PG_VERSION_NUM >= PG_VERSION_16
#else
/* PG 1617: three-arg signature (permInfos) */
ExecInitRangeTable(
@ -1812,13 +1804,6 @@ create_estate_for_relation(Relation rel)
list_make1(rte),
perminfos
);
#else
/* PG 15: two-arg signature */
ExecInitRangeTable(
estate,
list_make1(rte)
);
#endif
estate->es_output_cid = GetCurrentCommandId(true);

View File

@ -255,8 +255,7 @@ ColumnarReadFlushPendingWrites(ColumnarReadState *readState)
{
Assert(!readState->snapshotRegisteredByUs);
RelFileNumber relfilenumber = RelationPhysicalIdentifierNumber_compat(
RelationPhysicalIdentifier_compat(readState->relation));
RelFileNumber relfilenumber = readState->relation->rd_locator.relNumber;
FlushWriteStateForRelfilenumber(relfilenumber, GetCurrentSubTransactionId());
if (readState->snapshot == InvalidSnapshot || !IsMVCCSnapshot(readState->snapshot))

View File

@ -169,11 +169,7 @@ ColumnarStorageInit(SMgrRelation srel, uint64 storageId)
}
/* create two pages */
#if PG_VERSION_NUM >= PG_VERSION_16
PGIOAlignedBlock block;
#else
PGAlignedBlock block;
#endif
Page page = block.data;
/* write metapage */
@ -192,7 +188,7 @@ ColumnarStorageInit(SMgrRelation srel, uint64 storageId)
(char *) &metapage, sizeof(ColumnarMetapage));
phdr->pd_lower += sizeof(ColumnarMetapage);
log_newpage(RelationPhysicalIdentifierBackend_compat(&srel), MAIN_FORKNUM,
log_newpage(&srel->smgr_rlocator.locator, MAIN_FORKNUM,
COLUMNAR_METAPAGE_BLOCKNO, page, true);
PageSetChecksumInplace(page, COLUMNAR_METAPAGE_BLOCKNO);
smgrextend(srel, MAIN_FORKNUM, COLUMNAR_METAPAGE_BLOCKNO, page, true);
@ -200,7 +196,7 @@ ColumnarStorageInit(SMgrRelation srel, uint64 storageId)
/* write empty page */
PageInit(page, BLCKSZ, 0);
log_newpage(RelationPhysicalIdentifierBackend_compat(&srel), MAIN_FORKNUM,
log_newpage(&srel->smgr_rlocator.locator, MAIN_FORKNUM,
COLUMNAR_EMPTY_BLOCKNO, page, true);
PageSetChecksumInplace(page, COLUMNAR_EMPTY_BLOCKNO);
smgrextend(srel, MAIN_FORKNUM, COLUMNAR_EMPTY_BLOCKNO, page, true);

View File

@ -208,8 +208,7 @@ columnar_beginscan_extended(Relation relation, Snapshot snapshot,
uint32 flags, Bitmapset *attr_needed, List *scanQual)
{
CheckCitusColumnarVersion(ERROR);
RelFileNumber relfilenumber = RelationPhysicalIdentifierNumber_compat(
RelationPhysicalIdentifier_compat(relation));
RelFileNumber relfilenumber = relation->rd_locator.relNumber;
/*
* A memory context to use for scan-wide data, including the lazily
@ -435,8 +434,7 @@ columnar_index_fetch_begin(Relation rel)
{
CheckCitusColumnarVersion(ERROR);
RelFileNumber relfilenumber = RelationPhysicalIdentifierNumber_compat(
RelationPhysicalIdentifier_compat(rel));
RelFileNumber relfilenumber = rel->rd_locator.relNumber;
if (PendingWritesInUpperTransactions(relfilenumber, GetCurrentSubTransactionId()))
{
/* XXX: maybe we can just flush the data and continue */
@ -865,11 +863,9 @@ columnar_relation_set_new_filelocator(Relation rel,
* state. If they are equal, this is a new relation object and we don't
* need to clean anything.
*/
if (RelationPhysicalIdentifierNumber_compat(RelationPhysicalIdentifier_compat(rel)) !=
RelationPhysicalIdentifierNumberPtr_compat(newrlocator))
if (rel->rd_locator.relNumber != newrlocator->relNumber)
{
MarkRelfilenumberDropped(RelationPhysicalIdentifierNumber_compat(
RelationPhysicalIdentifier_compat(rel)),
MarkRelfilenumberDropped(rel->rd_locator.relNumber,
GetCurrentSubTransactionId());
DeleteMetadataRows(rel);
@ -892,9 +888,9 @@ static void
columnar_relation_nontransactional_truncate(Relation rel)
{
CheckCitusColumnarVersion(ERROR);
RelFileLocator relfilelocator = RelationPhysicalIdentifier_compat(rel);
RelFileLocator relfilelocator = rel->rd_locator;
NonTransactionDropWriteState(RelationPhysicalIdentifierNumber_compat(relfilelocator));
NonTransactionDropWriteState(relfilelocator.relNumber);
/* Delete old relfilenode metadata */
DeleteMetadataRows(rel);
@ -1098,7 +1094,6 @@ columnar_vacuum_rel(Relation rel, VacuumParams *params,
List *indexList = RelationGetIndexList(rel);
int nindexes = list_length(indexList);
#if PG_VERSION_NUM >= PG_VERSION_16
struct VacuumCutoffs cutoffs;
vacuum_get_cutoffs(rel, params, &cutoffs);
@ -1140,68 +1135,6 @@ columnar_vacuum_rel(Relation rel, VacuumParams *params,
false);
#endif
#else
TransactionId oldestXmin;
TransactionId freezeLimit;
MultiXactId multiXactCutoff;
/* initialize xids */
#if (PG_VERSION_NUM >= PG_VERSION_15) && (PG_VERSION_NUM < PG_VERSION_16)
MultiXactId oldestMxact;
vacuum_set_xid_limits(rel,
params->freeze_min_age,
params->freeze_table_age,
params->multixact_freeze_min_age,
params->multixact_freeze_table_age,
&oldestXmin, &oldestMxact,
&freezeLimit, &multiXactCutoff);
Assert(MultiXactIdPrecedesOrEquals(multiXactCutoff, oldestMxact));
#else
TransactionId xidFullScanLimit;
MultiXactId mxactFullScanLimit;
vacuum_set_xid_limits(rel,
params->freeze_min_age,
params->freeze_table_age,
params->multixact_freeze_min_age,
params->multixact_freeze_table_age,
&oldestXmin, &freezeLimit, &xidFullScanLimit,
&multiXactCutoff, &mxactFullScanLimit);
#endif
Assert(TransactionIdPrecedesOrEquals(freezeLimit, oldestXmin));
/*
* Columnar storage doesn't hold any transaction IDs, so we can always
* just advance to the most aggressive value.
*/
TransactionId newRelFrozenXid = oldestXmin;
#if (PG_VERSION_NUM >= PG_VERSION_15) && (PG_VERSION_NUM < PG_VERSION_16)
MultiXactId newRelminMxid = oldestMxact;
#else
MultiXactId newRelminMxid = multiXactCutoff;
#endif
double new_live_tuples = ColumnarTableTupleCount(rel);
/* all visible pages are always 0 */
BlockNumber new_rel_allvisible = 0;
#if (PG_VERSION_NUM >= PG_VERSION_15) && (PG_VERSION_NUM < PG_VERSION_16)
bool frozenxid_updated;
bool minmulti_updated;
vac_update_relstats(rel, new_rel_pages, new_live_tuples,
new_rel_allvisible, nindexes > 0,
newRelFrozenXid, newRelminMxid,
&frozenxid_updated, &minmulti_updated, false);
#else
vac_update_relstats(rel, new_rel_pages, new_live_tuples,
new_rel_allvisible, nindexes > 0,
newRelFrozenXid, newRelminMxid, false);
#endif
#endif
#if PG_VERSION_NUM >= PG_VERSION_18
pgstat_report_vacuum(RelationGetRelid(rel),
rel->rd_rel->relisshared,
@ -1906,7 +1839,7 @@ TupleSortSkipSmallerItemPointers(Tuplesortstate *tupleSort, ItemPointer targetIt
Datum *abbrev = NULL;
Datum tsDatum;
bool tsDatumIsNull;
if (!tuplesort_getdatum_compat(tupleSort, forwardDirection, false,
if (!tuplesort_getdatum(tupleSort, forwardDirection, false,
&tsDatum, &tsDatumIsNull, abbrev))
{
ItemPointerSetInvalid(&tsItemPointerData);
@ -2148,12 +2081,12 @@ ColumnarTableDropHook(Oid relid)
* tableam tables storage is managed by postgres.
*/
Relation rel = table_open(relid, AccessExclusiveLock);
RelFileLocator relfilelocator = RelationPhysicalIdentifier_compat(rel);
RelFileLocator relfilelocator = rel->rd_locator;
DeleteMetadataRows(rel);
DeleteColumnarTableOptions(rel->rd_id, true);
MarkRelfilenumberDropped(RelationPhysicalIdentifierNumber_compat(relfilelocator),
MarkRelfilenumberDropped(relfilelocator.relNumber,
GetCurrentSubTransactionId());
/* keep the lock since we did physical changes to the relation */
@ -2571,11 +2504,7 @@ static const TableAmRoutine columnar_am_methods = {
.tuple_lock = columnar_tuple_lock,
.finish_bulk_insert = columnar_finish_bulk_insert,
#if PG_VERSION_NUM >= PG_VERSION_16
.relation_set_new_filelocator = columnar_relation_set_new_filelocator,
#else
.relation_set_new_filenode = columnar_relation_set_new_filelocator,
#endif
.relation_nontransactional_truncate = columnar_relation_nontransactional_truncate,
.relation_copy_data = columnar_relation_copy_data,
.relation_copy_for_cluster = columnar_relation_copy_for_cluster,

View File

@ -35,12 +35,8 @@
#include "columnar/columnar_storage.h"
#include "columnar/columnar_version_compat.h"
#if PG_VERSION_NUM >= PG_VERSION_16
#include "storage/relfilelocator.h"
#include "utils/relfilenumbermap.h"
#else
#include "utils/relfilenodemap.h"
#endif
struct ColumnarWriteState
{
@ -103,7 +99,7 @@ ColumnarBeginWrite(Relation rel,
ColumnarOptions options,
TupleDesc tupleDescriptor)
{
RelFileLocator relfilelocator = RelationPhysicalIdentifier_compat(rel);
RelFileLocator relfilelocator = rel->rd_locator;
/* get comparison function pointers for each of the columns */
uint32 columnCount = tupleDescriptor->natts;

View File

@ -146,9 +146,7 @@ columnar_init_write_state(Relation relation, TupleDesc tupdesc,
}
WriteStateMapEntry *hashEntry = hash_search(WriteStateMap,
&RelationPhysicalIdentifierNumber_compat(
RelationPhysicalIdentifier_compat(
relation)),
&(relation->rd_locator.relNumber),
HASH_ENTER, &found);
if (!found)
{

View File

@ -1476,20 +1476,10 @@ InsertMetadataForCitusLocalTable(Oid citusLocalTableId, uint64 shardId,
static void
FinalizeCitusLocalTableCreation(Oid relationId)
{
#if PG_VERSION_NUM >= PG_VERSION_16
/*
* PG16+ supports truncate triggers on foreign tables
*/
if (RegularTable(relationId) || IsForeignTable(relationId))
#else
/*
* If it is a foreign table, then skip creating citus truncate trigger
* as foreign tables do not support truncate triggers.
*/
if (RegularTable(relationId))
#endif
{
CreateTruncateTrigger(relationId);
}

View File

@ -161,7 +161,6 @@ CreateCollationDDLInternal(Oid collationId, Oid *collowner, char **quotedCollati
pfree(collctype);
}
#if PG_VERSION_NUM >= PG_VERSION_16
char *collicurules = NULL;
datum = SysCacheGetAttr(COLLOID, heapTuple, Anum_pg_collation_collicurules, &isnull);
if (!isnull)
@ -170,7 +169,6 @@ CreateCollationDDLInternal(Oid collationId, Oid *collowner, char **quotedCollati
appendStringInfo(&collationNameDef, ", rules = %s",
quote_literal_cstr(collicurules));
}
#endif
if (!collisdeterministic)
{
appendStringInfoString(&collationNameDef, ", deterministic = false");

View File

@ -1271,17 +1271,10 @@ CreateCitusTable(Oid relationId, CitusTableType tableType,
colocationId, citusTableParams.replicationModel,
autoConverted);
#if PG_VERSION_NUM >= PG_VERSION_16
/*
* PG16+ supports truncate triggers on foreign tables
*/
if (RegularTable(relationId) || IsForeignTable(relationId))
#else
/* foreign tables do not support TRUNCATE trigger */
if (RegularTable(relationId))
#endif
{
CreateTruncateTrigger(relationId);
}

View File

@ -81,10 +81,7 @@ typedef struct DatabaseCollationInfo
char *datctype;
char *daticulocale;
char *datcollversion;
#if PG_VERSION_NUM >= PG_VERSION_16
char *daticurules;
#endif
} DatabaseCollationInfo;
static char * GenerateCreateDatabaseStatementFromPgDatabase(Form_pg_database
@ -853,14 +850,12 @@ GetDatabaseCollation(Oid dbOid)
info.datcollversion = TextDatumGetCString(collverDatum);
}
#if PG_VERSION_NUM >= PG_VERSION_16
Datum icurulesDatum = heap_getattr(tup, Anum_pg_database_daticurules, tupdesc,
&isNull);
if (!isNull)
{
info.daticurules = TextDatumGetCString(icurulesDatum);
}
#endif
table_close(rel, AccessShareLock);
heap_freetuple(tup);
@ -954,13 +949,11 @@ GenerateCreateDatabaseStatementFromPgDatabase(Form_pg_database databaseForm)
quote_identifier(GetLocaleProviderString(
databaseForm->datlocprovider)));
#if PG_VERSION_NUM >= PG_VERSION_16
if (collInfo.daticurules != NULL)
{
appendStringInfo(&str, " ICU_RULES = %s", quote_identifier(
collInfo.daticurules));
}
#endif
return str.data;
}

View File

@ -64,8 +64,7 @@ CreateDomainStmt *
RecreateDomainStmt(Oid domainOid)
{
CreateDomainStmt *stmt = makeNode(CreateDomainStmt);
stmt->domainname = stringToQualifiedNameList_compat(format_type_be_qualified(
domainOid));
stmt->domainname = stringToQualifiedNameList(format_type_be_qualified(domainOid), NULL);
HeapTuple tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(domainOid));
if (!HeapTupleIsValid(tup))

View File

@ -52,10 +52,7 @@
#include "distributed/resource_lock.h"
#include "distributed/version_compat.h"
#include "distributed/worker_manager.h"
#if PG_VERSION_NUM >= PG_VERSION_16
#include "catalog/pg_namespace.h"
#endif
/* Local functions forward declarations for helper functions */

View File

@ -110,10 +110,7 @@
#include "distributed/transmit.h"
#include "distributed/version_compat.h"
#include "distributed/worker_protocol.h"
#if PG_VERSION_NUM >= PG_VERSION_16
#include "distributed/relation_utils.h"
#endif
/* constant used in binary protocol */
@ -3251,12 +3248,8 @@ CheckCopyPermissions(CopyStmt *copyStatement)
RangeTblEntry *rte = (RangeTblEntry*) linitial(range_table);
tupDesc = RelationGetDescr(rel);
#if PG_VERSION_NUM >= PG_VERSION_16
/* create permission info for rte */
RTEPermissionInfo *perminfo = GetFilledPermissionInfo(rel->rd_id, rte->inh, required_access);
#else
rte->requiredPerms = required_access;
#endif
attnums = CopyGetAttnums(tupDesc, rel, copyStatement->attlist);
foreach(cur, attnums)
@ -3265,29 +3258,17 @@ CheckCopyPermissions(CopyStmt *copyStatement)
if (is_from)
{
#if PG_VERSION_NUM >= PG_VERSION_16
perminfo->insertedCols = bms_add_member(perminfo->insertedCols, attno);
#else
rte->insertedCols = bms_add_member(rte->insertedCols, attno);
#endif
}
else
{
#if PG_VERSION_NUM >= PG_VERSION_16
perminfo->selectedCols = bms_add_member(perminfo->selectedCols, attno);
#else
rte->selectedCols = bms_add_member(rte->selectedCols, attno);
#endif
}
}
#if PG_VERSION_NUM >= PG_VERSION_16
/* link rte to its permission info then check permissions */
rte->perminfoindex = 1;
ExecCheckPermissions(list_make1(rte), list_make1(perminfo), true);
#else
ExecCheckRTPerms(range_table, true);
#endif
/* TODO: Perform RLS checks once supported */

View File

@ -734,7 +734,7 @@ MakeSetStatementArguments(char *configurationName, char *configurationValue)
* using this function
*/
int gucCount = 0;
struct config_generic **gucVariables = get_guc_variables_compat(&gucCount);
struct config_generic **gucVariables = get_guc_variables(&gucCount);
struct config_generic **matchingConfig =
(struct config_generic **) SafeBsearch((void *) &key,
@ -851,12 +851,8 @@ GenerateGrantRoleStmtsFromOptions(RoleSpec *roleSpec, List *options)
if (strcmp(option->defname, "adminmembers") == 0)
{
#if PG_VERSION_NUM >= PG_VERSION_16
DefElem *opt = makeDefElem("admin", (Node *) makeBoolean(true), -1);
grantRoleStmt->opt = list_make1(opt);
#else
grantRoleStmt->admin_opt = true;
#endif
}
stmts = lappend(stmts, grantRoleStmt);
@ -916,8 +912,6 @@ GenerateGrantRoleStmtsOfRole(Oid roleid)
grantorRole->rolename = GetUserNameFromId(membership->grantor, false);
grantRoleStmt->grantor = grantorRole;
#if PG_VERSION_NUM >= PG_VERSION_16
/* inherit option is always included */
DefElem *inherit_opt;
if (membership->inherit_option)
@ -943,9 +937,6 @@ GenerateGrantRoleStmtsOfRole(Oid roleid)
DefElem *set_opt = makeDefElem("set", (Node *) makeBoolean(false), -1);
grantRoleStmt->opt = lappend(grantRoleStmt->opt, set_opt);
}
#else
grantRoleStmt->admin_opt = membership->admin_option;
#endif
stmts = lappend(stmts, grantRoleStmt);
}

View File

@ -184,7 +184,7 @@ truncate_local_data_after_distributing_table(PG_FUNCTION_ARGS)
TruncateStmt *truncateStmt = makeNode(TruncateStmt);
char *relationName = generate_qualified_relation_name(relationId);
List *names = stringToQualifiedNameList_compat(relationName);
List *names = stringToQualifiedNameList(relationName, NULL);
truncateStmt->relations = list_make1(makeRangeVarFromNameList(names));
truncateStmt->restart_seqs = false;
truncateStmt->behavior = DROP_CASCADE;

View File

@ -189,7 +189,7 @@ RecreateCompositeTypeStmt(Oid typeOid)
Assert(get_typtype(typeOid) == TYPTYPE_COMPOSITE);
CompositeTypeStmt *stmt = makeNode(CompositeTypeStmt);
List *names = stringToQualifiedNameList_compat(format_type_be_qualified(typeOid));
List *names = stringToQualifiedNameList(format_type_be_qualified(typeOid), NULL);
stmt->typevar = makeRangeVarFromNameList(names);
stmt->coldeflist = CompositeTypeColumnDefList(typeOid);
@ -254,7 +254,7 @@ RecreateEnumStmt(Oid typeOid)
Assert(get_typtype(typeOid) == TYPTYPE_ENUM);
CreateEnumStmt *stmt = makeNode(CreateEnumStmt);
stmt->typeName = stringToQualifiedNameList_compat(format_type_be_qualified(typeOid));
stmt->typeName = stringToQualifiedNameList(format_type_be_qualified(typeOid), NULL);
stmt->vals = EnumValsList(typeOid);
return stmt;
@ -567,8 +567,7 @@ CreateTypeDDLCommandsIdempotent(const ObjectAddress *typeAddress)
char *
GenerateBackupNameForTypeCollision(const ObjectAddress *address)
{
List *names = stringToQualifiedNameList_compat(format_type_be_qualified(
address->objectId));
List *names = stringToQualifiedNameList(format_type_be_qualified(address->objectId), NULL);
RangeVar *rel = makeRangeVarFromNameList(names);
char *newName = palloc0(NAMEDATALEN);

View File

@ -43,9 +43,7 @@ typedef struct CitusVacuumParams
VacOptValue truncate;
VacOptValue index_cleanup;
int nworkers;
#if PG_VERSION_NUM >= PG_VERSION_16
int ring_size;
#endif
} CitusVacuumParams;
/*
@ -353,19 +351,12 @@ DeparseVacuumStmtPrefix(CitusVacuumParams vacuumParams)
}
/* if no flags remain, exit early */
#if PG_VERSION_NUM >= PG_VERSION_16
if (vacuumFlags & VACOPT_PROCESS_TOAST &&
vacuumFlags & VACOPT_PROCESS_MAIN)
{
/* process toast and process main are true by default */
if (((vacuumFlags & ~VACOPT_PROCESS_TOAST) & ~VACOPT_PROCESS_MAIN) == 0 &&
vacuumParams.ring_size == -1 &&
#else
if (vacuumFlags & VACOPT_PROCESS_TOAST)
{
/* process toast is true by default */
if ((vacuumFlags & ~VACOPT_PROCESS_TOAST) == 0 &&
#endif
vacuumParams.truncate == VACOPTVALUE_UNSPECIFIED &&
vacuumParams.index_cleanup == VACOPTVALUE_UNSPECIFIED &&
vacuumParams.nworkers == VACUUM_PARALLEL_NOTSET
@ -413,7 +404,6 @@ DeparseVacuumStmtPrefix(CitusVacuumParams vacuumParams)
appendStringInfoString(vacuumPrefix, "PROCESS_TOAST FALSE,");
}
#if PG_VERSION_NUM >= PG_VERSION_16
if (!(vacuumFlags & VACOPT_PROCESS_MAIN))
{
appendStringInfoString(vacuumPrefix, "PROCESS_MAIN FALSE,");
@ -433,7 +423,6 @@ DeparseVacuumStmtPrefix(CitusVacuumParams vacuumParams)
{
appendStringInfo(vacuumPrefix, "BUFFER_USAGE_LIMIT %d,", vacuumParams.ring_size);
}
#endif
if (vacuumParams.truncate != VACOPTVALUE_UNSPECIFIED)
{
@ -537,13 +526,10 @@ VacuumStmtParams(VacuumStmt *vacstmt)
bool full = false;
bool disable_page_skipping = false;
bool process_toast = true;
#if PG_VERSION_NUM >= PG_VERSION_16
bool process_main = true;
bool skip_database_stats = false;
bool only_database_stats = false;
params.ring_size = -1;
#endif
/* Set default value */
params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
@ -563,13 +549,11 @@ VacuumStmtParams(VacuumStmt *vacstmt)
{
skip_locked = defGetBoolean(opt);
}
#if PG_VERSION_NUM >= PG_VERSION_16
else if (strcmp(opt->defname, "buffer_usage_limit") == 0)
{
char *vac_buffer_size = defGetString(opt);
parse_int(vac_buffer_size, &params.ring_size, GUC_UNIT_KB, NULL);
}
#endif
else if (!vacstmt->is_vacuumcmd)
{
ereport(ERROR,
@ -594,7 +578,6 @@ VacuumStmtParams(VacuumStmt *vacstmt)
{
disable_page_skipping = defGetBoolean(opt);
}
#if PG_VERSION_NUM >= PG_VERSION_16
else if (strcmp(opt->defname, "process_main") == 0)
{
process_main = defGetBoolean(opt);
@ -607,7 +590,6 @@ VacuumStmtParams(VacuumStmt *vacstmt)
{
only_database_stats = defGetBoolean(opt);
}
#endif
else if (strcmp(opt->defname, "process_toast") == 0)
{
process_toast = defGetBoolean(opt);
@ -678,11 +660,9 @@ VacuumStmtParams(VacuumStmt *vacstmt)
(analyze ? VACOPT_ANALYZE : 0) |
(freeze ? VACOPT_FREEZE : 0) |
(full ? VACOPT_FULL : 0) |
#if PG_VERSION_NUM >= PG_VERSION_16
(process_main ? VACOPT_PROCESS_MAIN : 0) |
(skip_database_stats ? VACOPT_SKIP_DATABASE_STATS : 0) |
(only_database_stats ? VACOPT_ONLY_DATABASE_STATS : 0) |
#endif
(process_toast ? VACOPT_PROCESS_TOAST : 0) |
(disable_page_skipping ? VACOPT_DISABLE_PAGE_SKIPPING : 0);
return params;

View File

@ -400,7 +400,6 @@ DeparseGrantRoleStmt(Node *node)
static void
AppendRevokeAdminOptionFor(StringInfo buf, GrantRoleStmt *stmt)
{
#if PG_VERSION_NUM >= PG_VERSION_16
if (!stmt->is_grant)
{
DefElem *opt = NULL;
@ -423,12 +422,6 @@ AppendRevokeAdminOptionFor(StringInfo buf, GrantRoleStmt *stmt)
}
}
}
#else
if (!stmt->is_grant && stmt->admin_opt)
{
appendStringInfo(buf, "ADMIN OPTION FOR ");
}
#endif
}
@ -437,7 +430,6 @@ AppendGrantWithAdminOption(StringInfo buf, GrantRoleStmt *stmt)
{
if (stmt->is_grant)
{
#if PG_VERSION_NUM >= PG_VERSION_16
int opt_count = 0;
DefElem *opt = NULL;
foreach_declared_ptr(opt, stmt->opt)
@ -463,12 +455,6 @@ AppendGrantWithAdminOption(StringInfo buf, GrantRoleStmt *stmt)
}
}
}
#else
if (stmt->admin_opt)
{
appendStringInfo(buf, " WITH ADMIN OPTION");
}
#endif
}
}

File diff suppressed because it is too large Load Diff

View File

@ -88,10 +88,6 @@
#include "distributed/worker_manager.h"
#include "distributed/worker_protocol.h"
#if PG_VERSION_NUM < PG_VERSION_16
#include "utils/relfilenodemap.h"
#endif
/* user configuration */
int ReadFromSecondaries = USE_SECONDARY_NODES_NEVER;

View File

@ -3195,7 +3195,7 @@ SignalMetadataSyncDaemon(Oid database, int sig)
int backendCount = pgstat_fetch_stat_numbackends();
for (int backend = 1; backend <= backendCount; backend++)
{
LocalPgBackendStatus *localBeEntry = pgstat_fetch_stat_local_beentry(backend);
LocalPgBackendStatus *localBeEntry = pgstat_get_local_beentry_by_index(backend);
if (!localBeEntry)
{
continue;

View File

@ -29,6 +29,7 @@
#include "catalog/pg_constraint.h"
#include "catalog/pg_extension.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc_d.h"
#include "catalog/pg_type.h"
#include "commands/extension.h"
#include "commands/sequence.h"
@ -81,10 +82,6 @@
#include "distributed/worker_manager.h"
#include "distributed/worker_protocol.h"
#if PG_VERSION_NUM >= PG_VERSION_16
#include "catalog/pg_proc_d.h"
#endif
#define DISK_SPACE_FIELDS 2
/* Local functions forward declarations */

View File

@ -96,7 +96,7 @@ PgGetObjectAddress(char *ttype, ArrayType *namearr, ArrayType *argsarr)
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("name or argument lists may not contain nulls")));
}
typename = typeStringToTypeName_compat(TextDatumGetCString(elems[0]), NULL);
typename = typeStringToTypeName(TextDatumGetCString(elems[0]), NULL);
}
else if (type == OBJECT_LARGEOBJECT)
{
@ -163,7 +163,7 @@ PgGetObjectAddress(char *ttype, ArrayType *namearr, ArrayType *argsarr)
errmsg("name or argument lists may not contain nulls")));
}
args = lappend(args,
typeStringToTypeName_compat(TextDatumGetCString(elems[i]),
typeStringToTypeName(TextDatumGetCString(elems[i]),
NULL));
}
}

View File

@ -2476,7 +2476,7 @@ GetSetCommandListForNewConnections(void)
List *commandList = NIL;
int gucCount = 0;
struct config_generic **guc_vars = get_guc_variables_compat(&gucCount);
struct config_generic **guc_vars = get_guc_variables(&gucCount);
for (int gucIndex = 0; gucIndex < gucCount; gucIndex++)
{

View File

@ -610,11 +610,10 @@ ConvertRteToSubqueryWithEmptyResult(RangeTblEntry *rte)
subquery->jointree = joinTree;
rte->rtekind = RTE_SUBQUERY;
#if PG_VERSION_NUM >= PG_VERSION_16
/* no permission checking for this RTE */
rte->perminfoindex = 0;
#endif
rte->subquery = subquery;
rte->alias = copyObject(rte->eref);
}

View File

@ -29,6 +29,7 @@
#include "optimizer/plancat.h"
#include "optimizer/planmain.h"
#include "optimizer/planner.h"
#include "parser/parse_relation.h"
#include "parser/parse_type.h"
#include "parser/parsetree.h"
#include "utils/builtins.h"
@ -71,10 +72,6 @@
#include "distributed/version_compat.h"
#include "distributed/worker_shard_visibility.h"
#if PG_VERSION_NUM >= PG_VERSION_16
#include "parser/parse_relation.h"
#endif
static List *plannerRestrictionContextList = NIL;
int MultiTaskQueryLogLevel = CITUS_LOG_LEVEL_OFF; /* multi-task query log level */
@ -1510,7 +1507,6 @@ static void
ConcatenateRTablesAndPerminfos(PlannedStmt *mainPlan, PlannedStmt *concatPlan)
{
mainPlan->rtable = list_concat(mainPlan->rtable, concatPlan->rtable);
#if PG_VERSION_NUM >= PG_VERSION_16
/*
* concatPlan's range table list is concatenated to mainPlan's range table list
@ -1532,7 +1528,6 @@ ConcatenateRTablesAndPerminfos(PlannedStmt *mainPlan, PlannedStmt *concatPlan)
/* finally, concatenate perminfos as well */
mainPlan->permInfos = list_concat(mainPlan->permInfos, concatPlan->permInfos);
#endif
}
@ -2018,18 +2013,6 @@ multi_relation_restriction_hook(PlannerInfo *root, RelOptInfo *relOptInfo,
{
cacheEntry = GetCitusTableCacheEntry(rte->relid);
#if PG_VERSION_NUM == PG_VERSION_15
/*
* Postgres 15.0 had a bug regarding inherited statistics expressions,
* which is fixed in 15.1 via Postgres commit
* 1f1865e9083625239769c26f68b9c2861b8d4b1c.
*
* Hence, we only set this value on exactly PG15.0
*/
relOptInfo->statlist = NIL;
#endif
relationRestrictionContext->allReferenceTables &=
IsCitusTableTypeCacheEntry(cacheEntry, REFERENCE_TABLE);
}

View File

@ -116,24 +116,15 @@ PlannedStmt *
GeneratePlaceHolderPlannedStmt(Query *parse)
{
PlannedStmt *result = makeNode(PlannedStmt);
#if PG_VERSION_NUM >= PG_VERSION_16
SeqScan *scanNode = makeNode(SeqScan);
Plan *plan = &(scanNode->scan.plan);
#else
Scan *scanNode = makeNode(Scan);
Plan *plan = &scanNode->plan;
#endif
FastPathRestrictionContext fprCtxt PG_USED_FOR_ASSERTS_ONLY = { 0 };
Assert(FastPathRouterQuery(parse, &fprCtxt));
/* there is only a single relation rte */
#if PG_VERSION_NUM >= PG_VERSION_16
scanNode->scan.scanrelid = 1;
#else
scanNode->scanrelid = 1;
#endif
plan->targetlist =
copyObject(FetchStatementTargetList((Node *) parse));
@ -149,9 +140,7 @@ GeneratePlaceHolderPlannedStmt(Query *parse)
result->stmt_len = parse->stmt_len;
result->rtable = copyObject(parse->rtable);
#if PG_VERSION_NUM >= PG_VERSION_16
result->permInfos = copyObject(parse->rteperminfos);
#endif
result->planTree = (Plan *) plan;
result->hasReturning = (parse->returningList != NIL);

View File

@ -623,8 +623,6 @@ CreateCombineQueryForRouterPlan(DistributedPlan *distPlan)
combineQuery->canSetTag = true;
combineQuery->rtable = list_make1(rangeTableEntry);
#if PG_VERSION_NUM >= PG_VERSION_16
/*
* This part of the code is more of a sanity check for readability,
* it doesn't really do anything.
@ -636,7 +634,6 @@ CreateCombineQueryForRouterPlan(DistributedPlan *distPlan)
Assert(rangeTableEntry->rtekind == RTE_FUNCTION &&
rangeTableEntry->perminfoindex == 0);
combineQuery->rteperminfos = NIL;
#endif
combineQuery->targetList = targetList;
combineQuery->jointree = joinTree;
@ -1599,13 +1596,10 @@ WrapSubquery(Query *subquery)
outerQuery->rtable = list_make1(rte_subq);
#if PG_VERSION_NUM >= PG_VERSION_16
/* Ensure RTE_SUBQUERY has proper permission handling */
Assert(rte_subq->rtekind == RTE_SUBQUERY &&
rte_subq->perminfoindex == 0);
outerQuery->rteperminfos = NIL;
#endif
RangeTblRef *rtref = makeNode(RangeTblRef);
rtref->rtindex = 1; /* Only one RTE, so index is 1 */

View File

@ -135,9 +135,7 @@ typedef struct RangeTableEntryDetails
RangeTblEntry *rangeTableEntry;
List *requiredAttributeNumbers;
bool hasConstantFilterOnUniqueColumn;
#if PG_VERSION_NUM >= PG_VERSION_16
RTEPermissionInfo *perminfo;
#endif
} RangeTableEntryDetails;
/*
@ -208,17 +206,11 @@ RecursivelyPlanLocalTableJoins(Query *query,
GetPlannerRestrictionContext(context);
List *rangeTableList = query->rtable;
#if PG_VERSION_NUM >= PG_VERSION_16
List *rteperminfos = query->rteperminfos;
#endif
int resultRTEIdentity = ResultRTEIdentity(query);
ConversionCandidates *conversionCandidates =
CreateConversionCandidates(plannerRestrictionContext,
#if PG_VERSION_NUM >= PG_VERSION_16
rangeTableList, resultRTEIdentity, rteperminfos);
#else
rangeTableList, resultRTEIdentity, NIL);
#endif
ConversionChoice conversionChoise =
GetConversionChoice(conversionCandidates, plannerRestrictionContext);
@ -333,12 +325,8 @@ ConvertRTEsToSubquery(List *rangeTableEntryDetailsList, RecursivePlanningContext
RangeTblEntry *rangeTableEntry = rangeTableEntryDetails->rangeTableEntry;
List *requiredAttributeNumbers = rangeTableEntryDetails->requiredAttributeNumbers;
ReplaceRTERelationWithRteSubquery(rangeTableEntry,
#if PG_VERSION_NUM >= PG_VERSION_16
requiredAttributeNumbers, context,
rangeTableEntryDetails->perminfo);
#else
requiredAttributeNumbers, context, NULL);
#endif
}
}
@ -581,14 +569,12 @@ CreateConversionCandidates(PlannerRestrictionContext *plannerRestrictionContext,
RequiredAttrNumbersForRelation(rangeTableEntry, plannerRestrictionContext);
rangeTableEntryDetails->hasConstantFilterOnUniqueColumn =
HasConstantFilterOnUniqueColumn(rangeTableEntry, relationRestriction);
#if PG_VERSION_NUM >= PG_VERSION_16
rangeTableEntryDetails->perminfo = NULL;
if (rangeTableEntry->perminfoindex)
{
rangeTableEntryDetails->perminfo = getRTEPermissionInfo(rteperminfos,
rangeTableEntry);
}
#endif
bool referenceOrDistributedTable =
IsCitusTableType(rangeTableEntry->relid, REFERENCE_TABLE) ||

View File

@ -835,11 +835,9 @@ ConvertCteRTEIntoSubquery(Query *mergeQuery, RangeTblEntry *sourceRte)
Query *cteQuery = (Query *) copyObject(sourceCte->ctequery);
sourceRte->rtekind = RTE_SUBQUERY;
#if PG_VERSION_NUM >= PG_VERSION_16
/* sanity check - sourceRte was RTE_CTE previously so it should have no perminfo */
Assert(sourceRte->perminfoindex == 0);
#endif
/*
* As we are delinking the CTE from main query, we have to walk through the
@ -889,8 +887,6 @@ ConvertRelationRTEIntoSubquery(Query *mergeQuery, RangeTblEntry *sourceRte,
/* we copy the input rteRelation to preserve the rteIdentity */
RangeTblEntry *newRangeTableEntry = copyObject(sourceRte);
sourceResultsQuery->rtable = list_make1(newRangeTableEntry);
#if PG_VERSION_NUM >= PG_VERSION_16
sourceResultsQuery->rteperminfos = NIL;
if (sourceRte->perminfoindex)
{
@ -902,7 +898,6 @@ ConvertRelationRTEIntoSubquery(Query *mergeQuery, RangeTblEntry *sourceRte,
newRangeTableEntry->perminfoindex = 1;
sourceResultsQuery->rteperminfos = list_make1(perminfo);
}
#endif
/* set the FROM expression to the subquery */
newRangeTableRef->rtindex = SINGLE_RTE_INDEX;
@ -929,9 +924,7 @@ ConvertRelationRTEIntoSubquery(Query *mergeQuery, RangeTblEntry *sourceRte,
/* replace the function with the constructed subquery */
sourceRte->rtekind = RTE_SUBQUERY;
#if PG_VERSION_NUM >= PG_VERSION_16
sourceRte->perminfoindex = 0;
#endif
sourceRte->subquery = sourceResultsQuery;
sourceRte->inh = false;
}

View File

@ -287,13 +287,11 @@ PG_FUNCTION_INFO_V1(worker_save_query_explain_analyze);
void
CitusExplainScan(CustomScanState *node, List *ancestors, struct ExplainState *es)
{
#if PG_VERSION_NUM >= PG_VERSION_16
if (es->generic)
{
ereport(ERROR, (errmsg(
"EXPLAIN GENERIC_PLAN is currently not supported for Citus tables")));
}
#endif
CitusScanState *scanState = (CitusScanState *) node;
DistributedPlan *distributedPlan = scanState->distributedPlan;

View File

@ -2259,13 +2259,10 @@ ConvertToQueryOnShard(Query *query, Oid citusTableOid, Oid shardId)
Assert(shardRelationId != InvalidOid);
citusTableRte->relid = shardRelationId;
#if PG_VERSION_NUM >= PG_VERSION_16
/* Change the range table permission oid to that of the shard's (PG16+) */
Assert(list_length(query->rteperminfos) == 1);
RTEPermissionInfo *rtePermInfo = (RTEPermissionInfo *) linitial(query->rteperminfos);
rtePermInfo->relid = shardRelationId;
#endif
return true;
}
@ -2573,18 +2570,6 @@ SelectsFromDistributedTable(List *rangeTableList, Query *query)
continue;
}
#if PG_VERSION_NUM >= 150013 && PG_VERSION_NUM < PG_VERSION_16
if (rangeTableEntry->rtekind == RTE_SUBQUERY && rangeTableEntry->relkind == 0)
{
/*
* In PG15.13 commit https://github.com/postgres/postgres/commit/317aba70e
* relid is retained when converting views to subqueries,
* so we need an extra check identifying those views
*/
continue;
}
#endif
if (rangeTableEntry->relkind == RELKIND_VIEW ||
rangeTableEntry->relkind == RELKIND_MATVIEW)
{

View File

@ -81,16 +81,12 @@ CreateColocatedJoinChecker(Query *subquery, PlannerRestrictionContext *restricti
* functions (i.e., FilterPlannerRestrictionForQuery()) rely on queries
* not relations.
*/
#if PG_VERSION_NUM >= PG_VERSION_16
RTEPermissionInfo *perminfo = NULL;
if (anchorRangeTblEntry->perminfoindex)
{
perminfo = getRTEPermissionInfo(subquery->rteperminfos, anchorRangeTblEntry);
}
anchorSubquery = WrapRteRelationIntoSubquery(anchorRangeTblEntry, NIL, perminfo);
#else
anchorSubquery = WrapRteRelationIntoSubquery(anchorRangeTblEntry, NIL, NULL);
#endif
}
else if (anchorRangeTblEntry->rtekind == RTE_SUBQUERY)
{
@ -133,7 +129,7 @@ static RangeTblEntry *
AnchorRte(Query *subquery)
{
FromExpr *joinTree = subquery->jointree;
Relids joinRelIds = get_relids_in_jointree_compat((Node *) joinTree, false, false);
Relids joinRelIds = get_relids_in_jointree((Node *) joinTree, false, false);
int currentRTEIndex = -1;
RangeTblEntry *anchorRangeTblEntry = NULL;
@ -286,13 +282,11 @@ WrapRteRelationIntoSubquery(RangeTblEntry *rteRelation,
RangeTblEntry *newRangeTableEntry = copyObject(rteRelation);
subquery->rtable = list_make1(newRangeTableEntry);
#if PG_VERSION_NUM >= PG_VERSION_16
if (perminfo)
{
newRangeTableEntry->perminfoindex = 1;
subquery->rteperminfos = list_make1(perminfo);
}
#endif
/* set the FROM expression to the subquery */
newRangeTableRef = makeNode(RangeTblRef);

View File

@ -2054,9 +2054,7 @@ SubqueryPushdownMultiNodeTree(Query *originalQuery)
pushedDownQuery->targetList = subqueryTargetEntryList;
pushedDownQuery->jointree = copyObject(queryTree->jointree);
pushedDownQuery->rtable = copyObject(queryTree->rtable);
#if PG_VERSION_NUM >= PG_VERSION_16
pushedDownQuery->rteperminfos = copyObject(queryTree->rteperminfos);
#endif
pushedDownQuery->setOperations = copyObject(queryTree->setOperations);
pushedDownQuery->querySource = queryTree->querySource;
pushedDownQuery->hasSubLinks = queryTree->hasSubLinks;
@ -2190,9 +2188,7 @@ CreateSubqueryTargetListAndAdjustVars(List *columnList)
* the var - is empty. Otherwise, when given the query, the Postgres planner
* may attempt to access a non-existent range table and segfault, as in #7787.
*/
#if PG_VERSION_NUM >= PG_VERSION_16
column->varnullingrels = NULL;
#endif
}
return subqueryTargetEntryList;

View File

@ -973,7 +973,6 @@ RecursivelyPlanDistributedJoinNode(Node *node, Query *query,
List *requiredAttributes =
RequiredAttrNumbersForRelation(distributedRte, restrictionContext);
#if PG_VERSION_NUM >= PG_VERSION_16
RTEPermissionInfo *perminfo = NULL;
if (distributedRte->perminfoindex)
{
@ -982,10 +981,6 @@ RecursivelyPlanDistributedJoinNode(Node *node, Query *query,
ReplaceRTERelationWithRteSubquery(distributedRte, requiredAttributes,
recursivePlanningContext, perminfo);
#else
ReplaceRTERelationWithRteSubquery(distributedRte, requiredAttributes,
recursivePlanningContext, NULL);
#endif
}
else if (distributedRte->rtekind == RTE_SUBQUERY)
{
@ -1874,9 +1869,7 @@ ReplaceRTERelationWithRteSubquery(RangeTblEntry *rangeTableEntry,
/* replace the function with the constructed subquery */
rangeTableEntry->rtekind = RTE_SUBQUERY;
#if PG_VERSION_NUM >= PG_VERSION_16
rangeTableEntry->perminfoindex = 0;
#endif
rangeTableEntry->subquery = subquery;
/*
@ -1949,13 +1942,10 @@ CreateOuterSubquery(RangeTblEntry *rangeTableEntry, List *outerSubqueryTargetLis
innerSubqueryRTE->eref->colnames = innerSubqueryColNames;
outerSubquery->rtable = list_make1(innerSubqueryRTE);
#if PG_VERSION_NUM >= PG_VERSION_16
/* sanity check */
Assert(innerSubqueryRTE->rtekind == RTE_SUBQUERY &&
innerSubqueryRTE->perminfoindex == 0);
outerSubquery->rteperminfos = NIL;
#endif
/* set the FROM expression to the subquery */
@ -2131,13 +2121,10 @@ TransformFunctionRTE(RangeTblEntry *rangeTblEntry)
/* set the FROM expression to the subquery */
subquery->rtable = list_make1(newRangeTableEntry);
#if PG_VERSION_NUM >= PG_VERSION_16
/* sanity check */
Assert(newRangeTableEntry->rtekind == RTE_FUNCTION &&
newRangeTableEntry->perminfoindex == 0);
subquery->rteperminfos = NIL;
#endif
newRangeTableRef->rtindex = 1;
subquery->jointree = makeFromExpr(list_make1(newRangeTableRef), NULL);
@ -2459,9 +2446,7 @@ BuildEmptyResultQuery(List *targetEntryList, char *resultId)
valuesQuery->canSetTag = true;
valuesQuery->commandType = CMD_SELECT;
valuesQuery->rtable = list_make1(valuesRangeTable);
#if PG_VERSION_NUM >= PG_VERSION_16
valuesQuery->rteperminfos = NIL;
#endif
valuesQuery->jointree = valuesJoinTree;
valuesQuery->targetList = valueTargetList;
@ -2478,9 +2463,7 @@ BuildEmptyResultQuery(List *targetEntryList, char *resultId)
resultQuery->commandType = CMD_SELECT;
resultQuery->canSetTag = true;
resultQuery->rtable = list_make1(emptyRangeTable);
#if PG_VERSION_NUM >= PG_VERSION_16
resultQuery->rteperminfos = NIL;
#endif
RangeTblRef *rangeTableRef = makeNode(RangeTblRef);
rangeTableRef->rtindex = 1;
@ -2630,9 +2613,7 @@ BuildReadIntermediateResultsQuery(List *targetEntryList, List *columnAliasList,
Query *resultQuery = makeNode(Query);
resultQuery->commandType = CMD_SELECT;
resultQuery->rtable = list_make1(rangeTableEntry);
#if PG_VERSION_NUM >= PG_VERSION_16
resultQuery->rteperminfos = NIL;
#endif
resultQuery->jointree = joinTree;
resultQuery->targetList = targetList;

View File

@ -1508,7 +1508,6 @@ GetTargetSubquery(PlannerInfo *root, RangeTblEntry *rangeTableEntry, Var *varToB
bool
IsRelOptOuterJoin(PlannerInfo *root, int varNo)
{
#if PG_VERSION_NUM >= PG_VERSION_16
if (root->simple_rel_array_size <= varNo)
{
return true;
@ -1520,7 +1519,6 @@ IsRelOptOuterJoin(PlannerInfo *root, int varNo)
/* must be an outer join */
return true;
}
#endif
return false;
}

View File

@ -1515,8 +1515,6 @@ CreateSubscriptions(MultiConnection *sourceConnection,
appendStringInfo(createSubscriptionCommand,
"CREATE SUBSCRIPTION %s CONNECTION %s PUBLICATION %s "
"WITH (citus_use_authinfo=true, create_slot=false, "
#if PG_VERSION_NUM >= PG_VERSION_16
/*
* password_required specifies whether connections to the publisher
* made as a result of this subscription must use password authentication.
@ -1529,9 +1527,6 @@ CreateSubscriptions(MultiConnection *sourceConnection,
* it will be ignored anyway
*/
"copy_data=false, enabled=false, slot_name=%s, password_required=false",
#else
"copy_data=false, enabled=false, slot_name=%s",
#endif
quote_identifier(target->subscriptionName),
quote_literal_cstr(conninfo->data),
quote_identifier(target->publication->name),

View File

@ -94,42 +94,6 @@ replication_origin_filter_cb(LogicalDecodingContext *ctx, RepOriginId origin_id)
}
/*
* update_replication_progress is copied from Postgres 15. We use it to send keepalive
* messages when we are filtering out the wal changes resulting from the initial copy.
* If we do not send out messages long enough, wal reciever will time out.
* Postgres 16 has refactored this code such that keepalive messages are sent during
* reordering phase which is above change_cb. So we do not need to send keepalive in
* change_cb.
*/
#if (PG_VERSION_NUM < PG_VERSION_16)
static void
update_replication_progress(LogicalDecodingContext *ctx, bool skipped_xact)
{
static int changes_count = 0;
/*
* We don't want to try sending a keepalive message after processing each
* change as that can have overhead. Tests revealed that there is no
* noticeable overhead in doing it after continuously processing 100 or so
* changes.
*/
#define CHANGES_THRESHOLD 100
/*
* After continuously processing CHANGES_THRESHOLD changes, we
* try to send a keepalive message if required.
*/
if (ctx->end_xact || ++changes_count >= CHANGES_THRESHOLD)
{
OutputPluginUpdateProgress(ctx, skipped_xact);
changes_count = 0;
}
}
#endif
/*
* shard_split_change_cb function emits the incoming tuple change
* to the appropriate destination shard.
@ -148,12 +112,6 @@ shard_split_change_cb(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
return;
}
#if (PG_VERSION_NUM < PG_VERSION_16)
/* Send replication keepalive. */
update_replication_progress(ctx, false);
#endif
/* check if the relation is publishable.*/
if (!is_publishable_relation(relation))
{

View File

@ -2803,7 +2803,7 @@ static void
OverridePostgresConfigProperties(void)
{
int gucCount = 0;
struct config_generic **guc_vars = get_guc_variables_compat(&gucCount);
struct config_generic **guc_vars = get_guc_variables(&gucCount);
for (int gucIndex = 0; gucIndex < gucCount; gucIndex++)
{
@ -2982,7 +2982,7 @@ ShowShardsForAppNamePrefixesCheckHook(char **newval, void **extra, GucSource sou
}
char *prefixAscii = pstrdup(appNamePrefix);
pg_clean_ascii_compat(prefixAscii, 0);
pg_clean_ascii(prefixAscii, 0);
if (strcmp(prefixAscii, appNamePrefix) != 0)
{

View File

@ -562,11 +562,7 @@ static const TableAmRoutine fake_methods = {
.tuple_satisfies_snapshot = fake_tuple_satisfies_snapshot,
.index_delete_tuples = fake_index_delete_tuples,
#if PG_VERSION_NUM >= PG_VERSION_16
.relation_set_new_filelocator = fake_relation_set_new_filenode,
#else
.relation_set_new_filenode = fake_relation_set_new_filenode,
#endif
.relation_nontransactional_truncate = fake_relation_nontransactional_truncate,
.relation_copy_data = fake_copy_data,
.relation_copy_for_cluster = fake_copy_for_cluster,

View File

@ -740,8 +740,6 @@ UnlockLockData(void)
* We have separate blocks for PG16 and <PG16 because SHM_QUEUE is completely
* removed from PG16
*/
#if PG_VERSION_NUM >= PG_VERSION_16
static void
AddEdgesForLockWaits(WaitGraph *waitGraph, PGPROC *waitingProc, PROCStack *remaining)
{
@ -820,86 +818,6 @@ AddEdgesForWaitQueue(WaitGraph *waitGraph, PGPROC *waitingProc, PROCStack *remai
}
#else
static void
AddEdgesForLockWaits(WaitGraph *waitGraph, PGPROC *waitingProc, PROCStack *remaining)
{
/* the lock for which this process is waiting */
LOCK *waitLock = waitingProc->waitLock;
/* determine the conflict mask for the lock level used by the process */
LockMethod lockMethodTable = GetLocksMethodTable(waitLock);
int conflictMask = lockMethodTable->conflictTab[waitingProc->waitLockMode];
/* iterate through the queue of processes holding the lock */
SHM_QUEUE *procLocks = &waitLock->procLocks;
PROCLOCK *procLock = (PROCLOCK *) SHMQueueNext(procLocks, procLocks,
offsetof(PROCLOCK, lockLink));
while (procLock != NULL)
{
PGPROC *currentProc = procLock->tag.myProc;
/*
* Skip processes from the same lock group, processes that don't conflict,
* and processes that are waiting on safe operations.
*/
if (!IsSameLockGroup(waitingProc, currentProc) &&
IsConflictingLockMask(procLock->holdMask, conflictMask) &&
!IsProcessWaitingForSafeOperations(currentProc))
{
AddWaitEdge(waitGraph, waitingProc, currentProc, remaining);
}
procLock = (PROCLOCK *) SHMQueueNext(procLocks, &procLock->lockLink,
offsetof(PROCLOCK, lockLink));
}
}
static void
AddEdgesForWaitQueue(WaitGraph *waitGraph, PGPROC *waitingProc, PROCStack *remaining)
{
/* the lock for which this process is waiting */
LOCK *waitLock = waitingProc->waitLock;
/* determine the conflict mask for the lock level used by the process */
LockMethod lockMethodTable = GetLocksMethodTable(waitLock);
int conflictMask = lockMethodTable->conflictTab[waitingProc->waitLockMode];
/* iterate through the wait queue */
PROC_QUEUE *waitQueue = &(waitLock->waitProcs);
int queueSize = waitQueue->size;
PGPROC *currentProc = (PGPROC *) waitQueue->links.next;
/*
* Iterate through the queue from the start until we encounter waitingProc,
* since we only care about processes in front of waitingProc in the queue.
*/
while (queueSize-- > 0 && currentProc != waitingProc)
{
int awaitMask = LOCKBIT_ON(currentProc->waitLockMode);
/*
* Skip processes from the same lock group, processes that don't conflict,
* and processes that are waiting on safe operations.
*/
if (!IsSameLockGroup(waitingProc, currentProc) &&
IsConflictingLockMask(awaitMask, conflictMask) &&
!IsProcessWaitingForSafeOperations(currentProc))
{
AddWaitEdge(waitGraph, waitingProc, currentProc, remaining);
}
currentProc = (PGPROC *) currentProc->links.next;
}
}
#endif
/*
* AddWaitEdge adds a new wait edge to a wait graph. The nodes in the graph are
* transactions and an edge indicates the "waiting" process is blocked on a lock

View File

@ -25,6 +25,7 @@
#include "storage/fd.h"
#include "utils/datum.h"
#include "utils/guc.h"
#include "utils/guc_tables.h"
#include "utils/hsearch.h"
#include "utils/memutils.h"
@ -807,13 +808,9 @@ AdjustMaxPreparedTransactions(void)
* really check if max_prepared_xacts is configured by the user explicitly,
* so check if it's value is default.
*/
#if PG_VERSION_NUM >= PG_VERSION_16
struct config_generic *gconf = find_option("max_prepared_transactions",
false, false, ERROR);
if (gconf->source == PGC_S_DEFAULT)
#else
if (max_prepared_xacts == 0)
#endif
{
char newvalue[12];

View File

@ -42,8 +42,7 @@ FunctionOidExtended(const char *schemaName, const char *functionName, int argume
bool missingOK)
{
char *qualifiedFunctionName = quote_qualified_identifier(schemaName, functionName);
List *qualifiedFunctionNameList = stringToQualifiedNameList_compat(
qualifiedFunctionName);
List *qualifiedFunctionNameList = stringToQualifiedNameList(qualifiedFunctionName, NULL);
List *argumentList = NIL;
const bool findVariadics = false;
const bool findDefaults = false;

View File

@ -14,9 +14,7 @@
#include "distributed/relation_utils.h"
#if PG_VERSION_NUM >= PG_VERSION_16
#include "miscadmin.h"
#endif
#include "utils/lsyscache.h"
#include "utils/rel.h"
@ -33,8 +31,6 @@ RelationGetNamespaceName(Relation relation)
}
#if PG_VERSION_NUM >= PG_VERSION_16
/*
* GetFilledPermissionInfo creates RTEPermissionInfo for a given RTE
* and fills it with given data and returns this RTEPermissionInfo object.
@ -56,6 +52,3 @@ GetFilledPermissionInfo(Oid relid, bool inh, AclMode requiredPerms)
perminfo->checkAsUser = GetUserId();
return perminfo;
}
#endif

View File

@ -526,8 +526,7 @@ CreateRenameTypeStmt(const ObjectAddress *address, char *newName)
RenameStmt *stmt = makeNode(RenameStmt);
stmt->renameType = OBJECT_TYPE;
stmt->object = (Node *) stringToQualifiedNameList_compat(format_type_be_qualified(
address->objectId));
stmt->object = (Node *) stringToQualifiedNameList(format_type_be_qualified(address->objectId), NULL);
stmt->newname = newName;

View File

@ -27,11 +27,7 @@
#include "columnar/columnar_compression.h"
#include "columnar/columnar_metadata.h"
#if PG_VERSION_NUM >= PG_VERSION_16
#include "storage/relfilelocator.h"
#else
#include "storage/relfilenode.h"
#endif
#define COLUMNAR_AM_NAME "columnar"
#define COLUMNAR_MODULE_NAME "citus_columnar"

View File

@ -17,11 +17,7 @@
#include "pg_version_compat.h"
#include "pg_version_constants.h"
#if PG_VERSION_NUM >= PG_VERSION_16
#include "storage/relfilelocator.h"
#else
#include "storage/relfilenode.h"
#endif
/*

View File

@ -38,7 +38,7 @@ typedef struct DeferredErrorMessage
*/
#define DeferredError(code, message, detail, hint) \
DeferredErrorInternal(code, message, detail, hint, __FILE__, __LINE__, \
PG_FUNCNAME_MACRO)
__func__)
DeferredErrorMessage * DeferredErrorInternal(int code, const char *message,
const char *detail, const char *hint,

View File

@ -14,15 +14,11 @@
#include "postgres.h"
#include "pg_version_constants.h"
#if PG_VERSION_NUM >= PG_VERSION_16
#include "parser/parse_relation.h"
#endif
#include "utils/relcache.h"
extern char * RelationGetNamespaceName(Relation relation);
#if PG_VERSION_NUM >= PG_VERSION_16
extern RTEPermissionInfo * GetFilledPermissionInfo(Oid relid, bool inh,
AclMode requiredPerms);
#endif
#endif /* RELATION_UTILS_H */

View File

@ -179,9 +179,7 @@ IsNodeWideObjectClass(ObjectClass objectClass)
case OCLASS_DATABASE:
case OCLASS_TBLSPACE:
case OCLASS_PARAMETER_ACL:
#if PG_VERSION_NUM >= PG_VERSION_16
case OCLASS_ROLE_MEMBERSHIP:
#endif
{
return true;
}

View File

@ -461,178 +461,6 @@ getStxstattarget_compat(HeapTuple tup)
#endif
#if PG_VERSION_NUM >= PG_VERSION_16
#include "utils/guc_tables.h"
#define pg_clean_ascii_compat(a, b) pg_clean_ascii(a, b)
#define RelationPhysicalIdentifier_compat(a) ((a)->rd_locator)
#define RelationTablespace_compat(a) (a.spcOid)
#define RelationPhysicalIdentifierNumber_compat(a) (a.relNumber)
#define RelationPhysicalIdentifierNumberPtr_compat(a) (a->relNumber)
#define RelationPhysicalIdentifierBackend_compat(a) (a->smgr_rlocator.locator)
#define float_abs(a) fabs(a)
#define tuplesort_getdatum_compat(a, b, c, d, e, f) tuplesort_getdatum(a, b, c, d, e, f)
static inline struct config_generic **
get_guc_variables_compat(int *gucCount)
{
return get_guc_variables(gucCount);
}
#define PG_FUNCNAME_MACRO __func__
#define stringToQualifiedNameList_compat(a) stringToQualifiedNameList(a, NULL)
#define typeStringToTypeName_compat(a, b) typeStringToTypeName(a, b)
#define get_relids_in_jointree_compat(a, b, c) get_relids_in_jointree(a, b, c)
#define object_ownercheck(a, b, c) object_ownercheck(a, b, c)
#define object_aclcheck(a, b, c, d) object_aclcheck(a, b, c, d)
#define pgstat_fetch_stat_local_beentry(a) pgstat_get_local_beentry_by_index(a)
#define have_createdb_privilege() have_createdb_privilege()
#else
#include "miscadmin.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_class_d.h"
#include "catalog/pg_database_d.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc_d.h"
#include "storage/relfilenode.h"
#include "utils/guc.h"
#include "utils/guc_tables.h"
#include "utils/syscache.h"
#define pg_clean_ascii_compat(a, b) pg_clean_ascii(a)
#define RelationPhysicalIdentifier_compat(a) ((a)->rd_node)
#define RelationTablespace_compat(a) (a.spcNode)
#define RelationPhysicalIdentifierNumber_compat(a) (a.relNode)
#define RelationPhysicalIdentifierNumberPtr_compat(a) (a->relNode)
#define RelationPhysicalIdentifierBackend_compat(a) (a->smgr_rnode.node)
typedef RelFileNode RelFileLocator;
typedef Oid RelFileNumber;
#define RelidByRelfilenumber(a, b) RelidByRelfilenode(a, b)
#define float_abs(a) Abs(a)
#define tuplesort_getdatum_compat(a, b, c, d, e, f) tuplesort_getdatum(a, b, d, e, f)
static inline struct config_generic **
get_guc_variables_compat(int *gucCount)
{
*gucCount = GetNumConfigOptions();
return get_guc_variables();
}
#define stringToQualifiedNameList_compat(a) stringToQualifiedNameList(a)
#define typeStringToTypeName_compat(a, b) typeStringToTypeName(a)
#define get_relids_in_jointree_compat(a, b, c) get_relids_in_jointree(a, b)
static inline bool
object_ownercheck(Oid classid, Oid objectid, Oid roleid)
{
switch (classid)
{
case RelationRelationId:
{
return pg_class_ownercheck(objectid, roleid);
}
case NamespaceRelationId:
{
return pg_namespace_ownercheck(objectid, roleid);
}
case ProcedureRelationId:
{
return pg_proc_ownercheck(objectid, roleid);
}
case DatabaseRelationId:
{
return pg_database_ownercheck(objectid, roleid);
}
default:
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("Missing classid:%d",
classid)));
}
}
}
static inline AclResult
object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
{
switch (classid)
{
case NamespaceRelationId:
{
return pg_namespace_aclcheck(objectid, roleid, mode);
}
case ProcedureRelationId:
{
return pg_proc_aclcheck(objectid, roleid, mode);
}
default:
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("Missing classid:%d",
classid)));
}
}
}
static inline bool
have_createdb_privilege(void)
{
bool result = false;
HeapTuple utup;
/* Superusers can always do everything */
if (superuser())
{
return true;
}
utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(GetUserId()));
if (HeapTupleIsValid(utup))
{
result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreatedb;
ReleaseSysCache(utup);
}
return result;
}
typedef bool TU_UpdateIndexes;
/*
* we define RTEPermissionInfo for PG16 compatibility
* There are some functions that need to include RTEPermissionInfo in their signature
* for PG14/PG15 we pass a NULL argument in these functions
*/
typedef RangeTblEntry RTEPermissionInfo;
#endif
#define SetListCellPtr(a, b) ((a)->ptr_value = (b))
#define RangeTableEntryFromNSItem(a) ((a)->p_rte)
#define fcGetArgValue(fc, n) ((fc)->args[n].value)

View File

@ -11,7 +11,6 @@
#ifndef PG_VERSION_CONSTANTS
#define PG_VERSION_CONSTANTS
#define PG_VERSION_15 150000
#define PG_VERSION_16 160000
#define PG_VERSION_17 170000
#define PG_VERSION_18 180000

View File

@ -776,15 +776,8 @@ RESET client_min_messages;
create table events (event_id bigserial, event_time timestamptz default now(), payload text);
create index on events (event_id);
insert into events (payload) select 'hello-'||s from generate_series(1,10) s;
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
BEGIN;
\if :server_version_ge_16
SET LOCAL debug_parallel_query = regress;
\else
SET LOCAL force_parallel_mode = regress;
\endif
SET LOCAL min_parallel_table_scan_size = 1;
SET LOCAL parallel_tuple_cost = 0;
SET LOCAL max_parallel_workers = 4;

View File

@ -21,14 +21,7 @@ select count(*), min(i), max(i), avg(i) from fallback_scan;
-- Negative test: try to force a parallel plan with at least two
-- workers, but columnar should reject it and use a non-parallel scan.
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
\if :server_version_ge_16
set debug_parallel_query = regress;
\else
set force_parallel_mode = regress;
\endif
set min_parallel_table_scan_size = 1;
set parallel_tuple_cost = 0;
set max_parallel_workers = 4;
@ -46,11 +39,7 @@ select count(*), min(i), max(i), avg(i) from fallback_scan;
150000 | 1 | 150000 | 75000.500000000000
(1 row)
\if :server_version_ge_16
set debug_parallel_query = default;
\else
set force_parallel_mode = default;
\endif
set min_parallel_table_scan_size to default;
set parallel_tuple_cost to default;
set max_parallel_workers to default;

View File

@ -556,9 +556,6 @@ create table events (event_id bigserial, event_time timestamptz default now(), p
BEGIN;
-- this wouldn't flush any data
insert into events (payload) select 'hello-'||s from generate_series(1, 10) s;
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
-- Since table is large enough, normally postgres would prefer using
-- parallel workers when building the index.
--
@ -570,11 +567,7 @@ BEGIN;
-- by postgres and throws an error. For this reason, here we don't expect
-- following commnad to fail since we prevent using parallel workers for
-- columnar tables.
\if :server_version_ge_16
SET LOCAL debug_parallel_query = regress;
\else
SET LOCAL force_parallel_mode = regress;
\endif
SET LOCAL min_parallel_table_scan_size = 1;
SET LOCAL parallel_tuple_cost = 0;
SET LOCAL max_parallel_workers = 4;

View File

@ -20,15 +20,8 @@ INSERT INTO parent SELECT '2020-03-15', 30, 300, 'three thousand'
FROM generate_series(1,100000);
INSERT INTO parent SELECT '2020-04-15', 30, 300, 'three thousand'
FROM generate_series(1,100000);
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
-- run parallel plans
\if :server_version_ge_16
SET debug_parallel_query = regress;
\else
SET force_parallel_mode = regress;
\endif
SET min_parallel_table_scan_size = 1;
SET parallel_tuple_cost = 0;
SET max_parallel_workers = 4;
@ -104,11 +97,7 @@ SELECT count(*), sum(i), min(i), max(i) FROM parent;
(1 row)
SET columnar.enable_custom_scan TO DEFAULT;
\if :server_version_ge_16
SET debug_parallel_query TO DEFAULT;
\else
SET force_parallel_mode TO DEFAULT;
\endif
SET min_parallel_table_scan_size TO DEFAULT;
SET parallel_tuple_cost TO DEFAULT;
SET max_parallel_workers TO DEFAULT;

View File

@ -1,13 +1,3 @@
--
-- 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/drop database for pg >= 15
set citus.enable_create_database_propagation=on;
CREATE DATABASE mydatabase

View File

@ -1,9 +0,0 @@
--
-- 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

View File

@ -1,13 +1,3 @@
--
-- PG16
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
\if :server_version_ge_16
\else
\q
\endif
-- create/drop database for pg >= 16
set citus.enable_create_database_propagation=on;
-- test icu_rules

View File

@ -1,9 +0,0 @@
--
-- PG16
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
\if :server_version_ge_16
\else
\q

View File

@ -2,7 +2,6 @@ SHOW server_version \gset
SELECT CASE
WHEN substring(current_setting('server_version'), '\d+')::int >= 17 THEN '17+'
WHEN substring(current_setting('server_version'), '\d+')::int IN (15, 16) THEN '15_16'
WHEN substring(current_setting('server_version'), '\d+')::int = 14 THEN '14'
ELSE 'Unsupported version'
END AS version_category;
version_category
@ -10,12 +9,6 @@ SELECT CASE
17+
(1 row)
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
\gset
\if :server_version_ge_15
\else
\q
\endif
--
-- MERGE test from PG community (adapted to Citus by converting all tables to Citus local)
--

View File

@ -2,7 +2,6 @@ SHOW server_version \gset
SELECT CASE
WHEN substring(current_setting('server_version'), '\d+')::int >= 17 THEN '17+'
WHEN substring(current_setting('server_version'), '\d+')::int IN (15, 16) THEN '15_16'
WHEN substring(current_setting('server_version'), '\d+')::int = 14 THEN '14'
ELSE 'Unsupported version'
END AS version_category;
version_category
@ -10,12 +9,6 @@ SELECT CASE
15_16
(1 row)
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
\gset
\if :server_version_ge_15
\else
\q
\endif
--
-- MERGE test from PG community (adapted to Citus by converting all tables to Citus local)
--

View File

@ -1,17 +0,0 @@
SHOW server_version \gset
SELECT CASE
WHEN substring(current_setting('server_version'), '\d+')::int >= 17 THEN '17+'
WHEN substring(current_setting('server_version'), '\d+')::int IN (15, 16) THEN '15_16'
WHEN substring(current_setting('server_version'), '\d+')::int = 14 THEN '14'
ELSE 'Unsupported version'
END AS version_category;
version_category
---------------------------------------------------------------------
14
(1 row)
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
\gset
\if :server_version_ge_15
\else
\q

View File

@ -1287,21 +1287,14 @@ BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET application_name to 'citus_internal gpid=10000000001';
-- with an ugly trick, update the vartype of table from int to bigint
-- so that making two tables colocated fails
-- include varnullingrels for PG16+
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
-- include varreturningtype for PG18+
SELECT substring(:'server_version', '\d+')::int >= 18 AS server_version_ge_18
\gset
\if :server_version_ge_18
UPDATE pg_dist_partition SET partkey = '{VAR :varno 1 :varattno 1 :vartype 20 :vartypmod -1 :varcollid 0 :varnullingrels (b) :varlevelsup 1 :varreturningtype 0 :varnoold 1 :varoattno 1 :location -1}'
WHERE logicalrelid = 'test_2'::regclass;
\elif :server_version_ge_16
UPDATE pg_dist_partition SET partkey = '{VAR :varno 1 :varattno 1 :vartype 20 :vartypmod -1 :varcollid 0 :varnullingrels (b) :varlevelsup 1 :varnoold 1 :varoattno 1 :location -1}'
WHERE logicalrelid = 'test_2'::regclass;
\else
UPDATE pg_dist_partition SET partkey = '{VAR :varno 1 :varattno 1 :vartype 20 :vartypmod -1 :varcollid 0 :varlevelsup 1 :varnoold 1 :varoattno 1 :location -1}'
UPDATE pg_dist_partition SET partkey = '{VAR :varno 1 :varattno 1 :vartype 20 :vartypmod -1 :varcollid 0 :varnullingrels (b) :varlevelsup 1 :varnoold 1 :varoattno 1 :location -1}'
WHERE logicalrelid = 'test_2'::regclass;
\endif
SELECT citus_internal.update_relation_colocation('test_2'::regclass, 251);

View File

@ -1,18 +1,6 @@
--
-- COMPLEX_COUNT_DISTINCT
--
-- This test file has an alternative output because of the following in PG16:
-- https://github.com/postgres/postgres/commit/1349d2790bf48a4de072931c722f39337e72055e
-- https://github.com/postgres/postgres/commit/f4c7c410ee4a7baa06f51ebb8d5333c169691dd3
-- The alternative output can be deleted when we drop support for PG15
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16;
server_version_ge_16
---------------------------------------------------------------------
t
(1 row)
SET citus.next_shard_id TO 240000;
SET citus.shard_count TO 8;
SET citus.shard_replication_factor TO 1;

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +1,11 @@
--
-- MULTI_EXPLAIN
--
-- This test file has an alternative output because of the following in PG16:
-- https://github.com/postgres/postgres/commit/1349d2790bf48a4de072931c722f39337e72055e
-- https://github.com/postgres/postgres/commit/f4c7c410ee4a7baa06f51ebb8d5333c169691dd3
-- The alternative output can be deleted when we drop support for PG15
--
-- This test file has an alternative output because of the following in PG18:
-- https://github.com/postgres/postgres/commit/161320b4b960ee4fe918959be6529ae9b106ea5a
-- The alternative output can be deleted when we drop support for PG17
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16;
server_version_ge_16
---------------------------------------------------------------------
t
(1 row)
SELECT substring(:'server_version', '\d+')::int >= 18 AS server_version_ge_18;
server_version_ge_18
---------------------------------------------------------------------

View File

@ -1,22 +1,11 @@
--
-- MULTI_EXPLAIN
--
-- This test file has an alternative output because of the following in PG16:
-- https://github.com/postgres/postgres/commit/1349d2790bf48a4de072931c722f39337e72055e
-- https://github.com/postgres/postgres/commit/f4c7c410ee4a7baa06f51ebb8d5333c169691dd3
-- The alternative output can be deleted when we drop support for PG15
--
-- This test file has an alternative output because of the following in PG18:
-- https://github.com/postgres/postgres/commit/161320b4b960ee4fe918959be6529ae9b106ea5a
-- The alternative output can be deleted when we drop support for PG17
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16;
server_version_ge_16
---------------------------------------------------------------------
t
(1 row)
SELECT substring(:'server_version', '\d+')::int >= 18 AS server_version_ge_18;
server_version_ge_18
---------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -58,8 +58,6 @@ CREATE OPERATOR citus_mx_test_schema.=== (
);
SET search_path TO public;
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
SELECT substring(:'server_version', '\d+')::int >= 17 AS server_version_ge_17
\gset
\if :server_version_ge_17
@ -67,12 +65,10 @@ SELECT substring(:'server_version', '\d+')::int >= 17 AS server_version_ge_17
-- Relevant PG commit:
-- https://github.com/postgres/postgres/commit/f696c0cd5f299f1b51e214efc55a22a782cc175d
SELECT quote_ident((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) as current_locale \gset
\elif :server_version_ge_16
\else
-- In PG16, read-only server settings lc_collate and lc_ctype are removed
-- Relevant PG commit: b0f6c437160db640d4ea3e49398ebc3ba39d1982
SELECT quote_ident((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) as current_locale \gset
\else
SELECT quote_ident(current_setting('lc_collate')) as current_locale \gset
\endif
CREATE COLLATION citus_mx_test_schema.english (LOCALE=:current_locale);
CREATE TYPE citus_mx_test_schema.new_composite_type as (key1 text, key2 text);

View File

@ -1,6 +1,12 @@
--
-- Hide shard names on MX worker nodes
--
-- PostgreSQL 18 planner changes (probably AIO and updated cost model) make
-- sequential scans cheaper, so the psql `\d table`-style query that uses a
-- regex on `pg_class.relname` no longer chooses an index scan. This causes
-- a plan difference.
-- Alternative test output can be removed when we drop PG17 support
--
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1130000;
-- make sure that the signature of the citus_table_is_visible
-- and pg_table_is_visible are the same since the logic
@ -471,10 +477,6 @@ SELECT relname FROM pg_catalog.pg_class WHERE relnamespace = 'mx_hide_shard_name
test_table_2_1130000
(4 rows)
-- PG16 added one more backend type B_STANDALONE_BACKEND
-- and also alphabetized the backend types, hence the orders changed
-- Relevant PG16 commit:
-- https://github.com/postgres/postgres/commit/0c679464a837079acc75ff1d45eaa83f79e05690
-- Relevant Pg17 commit:
-- https://github.com/postgres/postgres/commit/067701f57758f9baed5bd9d868539738d77bfa92
-- Relevant PG18 commit:
@ -482,7 +484,6 @@ SELECT relname FROM pg_catalog.pg_class WHERE relnamespace = 'mx_hide_shard_name
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 18 AS server_version_ge_18 \gset
SELECT substring(:'server_version', '\d+')::int >= 17 AS server_version_ge_17 \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16 \gset
\if :server_version_ge_18
SELECT 1 AS client_backend \gset
SELECT 5 AS bgworker \gset
@ -491,14 +492,10 @@ SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16 \g
SELECT 1 AS client_backend \gset
SELECT 4 AS bgworker \gset
SELECT 5 AS walsender \gset
\elif :server_version_ge_16
\else
SELECT 4 AS client_backend \gset
SELECT 5 AS bgworker \gset
SELECT 12 AS walsender \gset
\else
SELECT 3 AS client_backend \gset
SELECT 4 AS bgworker \gset
SELECT 9 AS walsender \gset
\endif
-- say, we set it to bgworker
-- the shards and indexes do not show up

View File

@ -1,6 +1,12 @@
--
-- Hide shard names on MX worker nodes
--
-- PostgreSQL 18 planner changes (probably AIO and updated cost model) make
-- sequential scans cheaper, so the psql `\d table`-style query that uses a
-- regex on `pg_class.relname` no longer chooses an index scan. This causes
-- a plan difference.
-- Alternative test output can be removed when we drop PG17 support
--
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1130000;
-- make sure that the signature of the citus_table_is_visible
-- and pg_table_is_visible are the same since the logic
@ -472,10 +478,6 @@ SELECT relname FROM pg_catalog.pg_class WHERE relnamespace = 'mx_hide_shard_name
test_table_2_1130000
(4 rows)
-- PG16 added one more backend type B_STANDALONE_BACKEND
-- and also alphabetized the backend types, hence the orders changed
-- Relevant PG16 commit:
-- https://github.com/postgres/postgres/commit/0c679464a837079acc75ff1d45eaa83f79e05690
-- Relevant Pg17 commit:
-- https://github.com/postgres/postgres/commit/067701f57758f9baed5bd9d868539738d77bfa92
-- Relevant PG18 commit:
@ -483,7 +485,6 @@ SELECT relname FROM pg_catalog.pg_class WHERE relnamespace = 'mx_hide_shard_name
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 18 AS server_version_ge_18 \gset
SELECT substring(:'server_version', '\d+')::int >= 17 AS server_version_ge_17 \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16 \gset
\if :server_version_ge_18
SELECT 1 AS client_backend \gset
SELECT 5 AS bgworker \gset
@ -492,14 +493,10 @@ SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16 \g
SELECT 1 AS client_backend \gset
SELECT 4 AS bgworker \gset
SELECT 5 AS walsender \gset
\elif :server_version_ge_16
\else
SELECT 4 AS client_backend \gset
SELECT 5 AS bgworker \gset
SELECT 12 AS walsender \gset
\else
SELECT 3 AS client_backend \gset
SELECT 4 AS bgworker \gset
SELECT 9 AS walsender \gset
\endif
-- say, we set it to bgworker
-- the shards and indexes do not show up

View File

@ -1,167 +0,0 @@
--
-- MULTI_MX_INSERT_SELECT_REPARTITION
--
-- Test behaviour of repartitioned INSERT ... SELECT in MX setup
--
-- 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_mx_insert_select_repartition;
SET search_path TO multi_mx_insert_select_repartition;
SET citus.next_shard_id TO 4213581;
SET citus.shard_replication_factor TO 1;
SET citus.shard_count TO 4;
CREATE TABLE source_table(a int, b int);
SELECT create_distributed_table('source_table', 'a');
create_distributed_table
---------------------------------------------------------------------
(1 row)
INSERT INTO source_table SELECT floor(i/4), i*i FROM generate_series(1, 20) i;
SET citus.shard_count TO 3;
CREATE TABLE target_table(a int, b int);
SELECT create_distributed_table('target_table', 'a');
create_distributed_table
---------------------------------------------------------------------
(1 row)
CREATE FUNCTION square(int) RETURNS INT
AS $$ SELECT $1 * $1 $$
LANGUAGE SQL;
select create_distributed_function('square(int)');
NOTICE: procedure multi_mx_insert_select_repartition.square is already distributed
DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands
create_distributed_function
---------------------------------------------------------------------
(1 row)
select public.colocate_proc_with_table('square', 'source_table'::regclass, 0);
colocate_proc_with_table
---------------------------------------------------------------------
(1 row)
-- Test along with function delegation
-- function delegation only happens for "SELECT f()", and we don't use
-- repartitioned INSERT/SELECT when task count is 1, so the following
-- should go via coordinator
EXPLAIN (costs off) INSERT INTO target_table(a) SELECT square(4);
QUERY PLAN
---------------------------------------------------------------------
Custom Scan (Citus INSERT ... SELECT)
INSERT/SELECT method: pull to coordinator
-> Result
(3 rows)
INSERT INTO target_table(a) SELECT square(4);
SELECT * FROM target_table;
a | b
---------------------------------------------------------------------
16 |
(1 row)
TRUNCATE target_table;
--
-- Test repartitioned INSERT/SELECT from MX worker
--
\c - - - :worker_1_port
SET search_path TO multi_mx_insert_select_repartition;
EXPLAIN (costs off) INSERT INTO target_table SELECT a, max(b) FROM source_table GROUP BY a;
QUERY PLAN
---------------------------------------------------------------------
Custom Scan (Citus INSERT ... SELECT)
INSERT/SELECT method: repartition
-> Custom Scan (Citus Adaptive)
Task Count: 4
Tasks Shown: One of 4
-> Task
Node: host=localhost port=xxxxx dbname=regression
-> HashAggregate
Group Key: a
-> Seq Scan on source_table_4213581 source_table
(10 rows)
INSERT INTO target_table SELECT a, max(b) FROM source_table GROUP BY a;
SET citus.log_local_commands to on;
-- INSERT .. SELECT via repartitioning with local execution
BEGIN;
select count(*) from source_table WHERE a = 1;
NOTICE: executing the command locally: SELECT count(*) AS count FROM multi_mx_insert_select_repartition.source_table_4213581 source_table WHERE (a OPERATOR(pg_catalog.=) 1)
count
---------------------------------------------------------------------
4
(1 row)
-- we omit the "SELECT bytes FROM fetch_intermediate_results..." line since it is flaky
SET LOCAL citus.grep_remote_commands TO '%multi_mx_insert_select_repartition%';
insert into target_table SELECT a*2 FROM source_table RETURNING a;
NOTICE: executing the command locally: SELECT partition_index, 'repartitioned_results_xxxxx_from_4213581_to' || '_' || partition_index::text , rows_written FROM worker_partition_query_result('repartitioned_results_xxxxx_from_4213581_to','SELECT (a OPERATOR(pg_catalog.*) 2) AS a FROM multi_mx_insert_select_repartition.source_table_4213581 source_table WHERE true',0,'hash','{-2147483648,-715827883,715827882}'::text[],'{-715827884,715827881,2147483647}'::text[],true) WHERE rows_written > 0
NOTICE: executing the command locally: SELECT partition_index, 'repartitioned_results_xxxxx_from_4213583_to' || '_' || partition_index::text , rows_written FROM worker_partition_query_result('repartitioned_results_xxxxx_from_4213583_to','SELECT (a OPERATOR(pg_catalog.*) 2) AS a FROM multi_mx_insert_select_repartition.source_table_4213583 source_table WHERE true',0,'hash','{-2147483648,-715827883,715827882}'::text[],'{-715827884,715827881,2147483647}'::text[],true) WHERE rows_written > 0
NOTICE: executing the command locally: INSERT INTO multi_mx_insert_select_repartition.target_table_4213585 AS citus_table_alias (a) SELECT a FROM read_intermediate_results('{repartitioned_results_xxxxx_from_4213581_to_0,repartitioned_results_xxxxx_from_4213582_to_0,repartitioned_results_xxxxx_from_4213584_to_0}'::text[], 'binary'::citus_copy_format) intermediate_result(a integer) RETURNING citus_table_alias.a
NOTICE: executing the command locally: INSERT INTO multi_mx_insert_select_repartition.target_table_4213587 AS citus_table_alias (a) SELECT a FROM read_intermediate_results('{repartitioned_results_xxxxx_from_4213581_to_2}'::text[], 'binary'::citus_copy_format) intermediate_result(a integer) RETURNING citus_table_alias.a
a
---------------------------------------------------------------------
0
0
0
2
2
2
2
4
4
4
4
6
6
6
6
8
8
8
8
10
(20 rows)
ROLLBACK;
BEGIN;
select count(*) from source_table WHERE a = 1;
NOTICE: executing the command locally: SELECT count(*) AS count FROM multi_mx_insert_select_repartition.source_table_4213581 source_table WHERE (a OPERATOR(pg_catalog.=) 1)
count
---------------------------------------------------------------------
4
(1 row)
insert into target_table SELECT a FROM source_table LIMIT 10;
NOTICE: executing the command locally: SELECT a FROM multi_mx_insert_select_repartition.source_table_4213581 source_table WHERE true LIMIT '10'::bigint
NOTICE: executing the command locally: SELECT a FROM multi_mx_insert_select_repartition.source_table_4213583 source_table WHERE true LIMIT '10'::bigint
NOTICE: executing the copy locally for shard xxxxx
ROLLBACK;
\c - - - :master_port
SET search_path TO multi_mx_insert_select_repartition;
SELECT * FROM target_table ORDER BY a;
a | b
---------------------------------------------------------------------
0 | 9
1 | 49
2 | 121
3 | 225
4 | 361
5 | 400
(6 rows)
RESET client_min_messages;
\set VERBOSITY terse
DROP SCHEMA multi_mx_insert_select_repartition CASCADE;
NOTICE: drop cascades to 3 other objects

View File

@ -2,16 +2,6 @@
--- do not cause issues for the postgres planner, in particular postgres versions 16+, where the
--- varnullingrels field of a VAR node may contain relids of join relations that can make the var
--- NULL; in a rewritten distributed query without a join such relids do not have a meaning.
-- This test has an alternative goldfile because of the following feature in Postgres 16:
-- https://github.com/postgres/postgres/commit/1349d2790bf48a4de072931c722f39337e72055e
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16;
server_version_ge_16
---------------------------------------------------------------------
t
(1 row)
CREATE SCHEMA outer_join_columns_testing;
SET search_path to 'outer_join_columns_testing';
SET citus.next_shard_id TO 30070000;

View File

@ -1,422 +0,0 @@
--- Test for verifying that column references (var nodes) in targets that cannot be pushed down
--- do not cause issues for the postgres planner, in particular postgres versions 16+, where the
--- varnullingrels field of a VAR node may contain relids of join relations that can make the var
--- NULL; in a rewritten distributed query without a join such relids do not have a meaning.
-- This test has an alternative goldfile because of the following feature in Postgres 16:
-- https://github.com/postgres/postgres/commit/1349d2790bf48a4de072931c722f39337e72055e
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16;
server_version_ge_16
---------------------------------------------------------------------
f
(1 row)
CREATE SCHEMA outer_join_columns_testing;
SET search_path to 'outer_join_columns_testing';
SET citus.next_shard_id TO 30070000;
SET citus.shard_replication_factor TO 1;
SET citus.enable_local_execution TO ON;
CREATE TABLE t1 (id INT PRIMARY KEY);
INSERT INTO t1 VALUES (1), (2);
CREATE TABLE t2 (id INT, account_id INT, a2 INT, PRIMARY KEY(id, account_id));
INSERT INTO t2 VALUES (3, 1, 10), (4, 2, 20), (5, 1, NULL);
SELECT create_distributed_table('t1', 'id');
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($$outer_join_columns_testing.t1$$)
create_distributed_table
---------------------------------------------------------------------
(1 row)
SELECT create_distributed_table('t2', 'account_id');
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($$outer_join_columns_testing.t2$$)
create_distributed_table
---------------------------------------------------------------------
(1 row)
-- Test the issue seen in #7705; a target expression with
-- a window function that cannot be pushed down because the
-- partion by is not on the distribution column also includes
-- a column from the inner side of a left outer join, which
-- produces a non-empty varnullingrels set in PG 16 (and higher)
SELECT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
id | max
---------------------------------------------------------------------
1 | 10
2 | 20
1 |
(3 rows)
select public.explain_filter('
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
', true);
explain_filter
---------------------------------------------------------------------
WindowAgg
Output: remote_scan.id, max(remote_scan.max) OVER (?), remote_scan.worker_column_3
-> Sort
Output: remote_scan.worker_column_3, remote_scan.id, remote_scan.max
Sort Key: remote_scan.worker_column_3
-> Custom Scan (Citus Adaptive)
Output: remote_scan.worker_column_3, remote_scan.id, remote_scan.max
Task Count: 4
Tasks Shown: One of 4
-> Task
Query: SELECT worker_column_1 AS id, worker_column_2 AS max, worker_column_3 FROM (SELECT t1.id AS worker_column_1, t2.a2 AS worker_column_2, t2.id AS worker_column_3 FROM (outer_join_columns_testing.t1_30070000 t1 LEFT JOIN outer_join_columns_testing.t2_30070004 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery
Node: host=localhost port=xxxxx dbname=regression
-> Hash Right Join
Output: t1.id, t2.a2, t2.id
Inner Unique: true
Hash Cond: (t2.account_id = t1.id)
-> Seq Scan on outer_join_columns_testing.t2_30070004 t2
Output: t2.id, t2.account_id, t2.a2
-> Hash
Output: t1.id
-> Seq Scan on outer_join_columns_testing.t1_30070000 t1
Output: t1.id
(22 rows)
SELECT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t2 RIGHT OUTER JOIN t1 ON t1.id = t2.account_id;
id | max
---------------------------------------------------------------------
1 | 10
2 | 20
1 |
(3 rows)
select public.explain_filter('
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t2 RIGHT OUTER JOIN t1 ON t1.id = t2.account_id
', true);
explain_filter
---------------------------------------------------------------------
WindowAgg
Output: remote_scan.id, max(remote_scan.max) OVER (?), remote_scan.worker_column_3
-> Sort
Output: remote_scan.worker_column_3, remote_scan.id, remote_scan.max
Sort Key: remote_scan.worker_column_3
-> Custom Scan (Citus Adaptive)
Output: remote_scan.worker_column_3, remote_scan.id, remote_scan.max
Task Count: 4
Tasks Shown: One of 4
-> Task
Query: SELECT worker_column_1 AS id, worker_column_2 AS max, worker_column_3 FROM (SELECT t1.id AS worker_column_1, t2.a2 AS worker_column_2, t2.id AS worker_column_3 FROM (outer_join_columns_testing.t2_30070004 t2 RIGHT JOIN outer_join_columns_testing.t1_30070000 t1 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery
Node: host=localhost port=xxxxx dbname=regression
-> Hash Right Join
Output: t1.id, t2.a2, t2.id
Inner Unique: true
Hash Cond: (t2.account_id = t1.id)
-> Seq Scan on outer_join_columns_testing.t2_30070004 t2
Output: t2.id, t2.account_id, t2.a2
-> Hash
Output: t1.id
-> Seq Scan on outer_join_columns_testing.t1_30070000 t1
Output: t1.id
(22 rows)
SELECT DISTINCT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
id | max
---------------------------------------------------------------------
1 |
1 | 10
2 | 20
(3 rows)
select public.explain_filter('
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT DISTINCT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
', true);
explain_filter
---------------------------------------------------------------------
HashAggregate
Output: remote_scan.id, (max(remote_scan.max) OVER (?)), remote_scan.worker_column_3
Group Key: remote_scan.id, max(remote_scan.max) OVER (?)
-> WindowAgg
Output: remote_scan.id, max(remote_scan.max) OVER (?), remote_scan.worker_column_3
-> Sort
Output: remote_scan.worker_column_3, remote_scan.id, remote_scan.max
Sort Key: remote_scan.worker_column_3
-> Custom Scan (Citus Adaptive)
Output: remote_scan.worker_column_3, remote_scan.id, remote_scan.max
Task Count: 4
Tasks Shown: One of 4
-> Task
Query: SELECT worker_column_1 AS id, worker_column_2 AS max, worker_column_3 FROM (SELECT t1.id AS worker_column_1, t2.a2 AS worker_column_2, t2.id AS worker_column_3 FROM (outer_join_columns_testing.t1_30070000 t1 LEFT JOIN outer_join_columns_testing.t2_30070004 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery
Node: host=localhost port=xxxxx dbname=regression
-> Hash Right Join
Output: t1.id, t2.a2, t2.id
Inner Unique: true
Hash Cond: (t2.account_id = t1.id)
-> Seq Scan on outer_join_columns_testing.t2_30070004 t2
Output: t2.id, t2.account_id, t2.a2
-> Hash
Output: t1.id
-> Seq Scan on outer_join_columns_testing.t1_30070000 t1
Output: t1.id
(25 rows)
CREATE SEQUENCE test_seq START 101;
CREATE OR REPLACE FUNCTION TEST_F(int) returns INT language sql stable as $$ select $1 + 42; $$ ;
-- Issue #7705 also occurs if a target expression includes a column
-- of a distributed table that is on the inner side of a left outer
-- join and a call to nextval(), because nextval() cannot be pushed
-- down, and must be run on the coordinator
SELECT t1.id, TEST_F(t2.a2 + nextval('test_seq') :: int)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
ORDER BY t1.id;
id | test_f
---------------------------------------------------------------------
1 | 153
1 |
2 | 165
(3 rows)
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT t1.id, TEST_F(t2.a2 + nextval('test_seq') :: int)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
ORDER BY t1.id;
QUERY PLAN
---------------------------------------------------------------------
Result
Output: remote_scan.id, ((remote_scan.test_f + (nextval('test_seq'::regclass))::integer) + 42)
-> Sort
Output: remote_scan.id, remote_scan.test_f
Sort Key: remote_scan.id
-> Custom Scan (Citus Adaptive)
Output: remote_scan.id, remote_scan.test_f
Task Count: 4
Tasks Shown: One of 4
-> Task
Query: SELECT worker_column_1 AS id, worker_column_2 AS test_f FROM (SELECT t1.id AS worker_column_1, t2.a2 AS worker_column_2 FROM (outer_join_columns_testing.t1_30070000 t1 LEFT JOIN outer_join_columns_testing.t2_30070004 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery
Node: host=localhost port=xxxxx dbname=regression
-> Hash Right Join
Output: t1.id, t2.a2
Inner Unique: true
Hash Cond: (t2.account_id = t1.id)
-> Seq Scan on outer_join_columns_testing.t2_30070004 t2
Output: t2.id, t2.account_id, t2.a2
-> Hash
Output: t1.id
-> Seq Scan on outer_join_columns_testing.t1_30070000 t1
Output: t1.id
(22 rows)
SELECT t1.id, CASE nextval('test_seq') % 2 = 0 WHEN true THEN t2.a2 ELSE 1 END
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
ORDER BY t1.id;
id | case
---------------------------------------------------------------------
1 | 10
1 | 1
2 | 20
(3 rows)
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT t1.id, CASE nextval('test_seq') %2 = 0 WHEN true THEN t2.a2 ELSE 1 END
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
ORDER BY t1.id;
QUERY PLAN
---------------------------------------------------------------------
Result
Output: remote_scan.id, CASE ((nextval('test_seq'::regclass) % '2'::bigint) = 0) WHEN CASE_TEST_EXPR THEN remote_scan."case" ELSE 1 END
-> Sort
Output: remote_scan.id, remote_scan."case"
Sort Key: remote_scan.id
-> Custom Scan (Citus Adaptive)
Output: remote_scan.id, remote_scan."case"
Task Count: 4
Tasks Shown: One of 4
-> Task
Query: SELECT worker_column_1 AS id, worker_column_2 AS "case" FROM (SELECT t1.id AS worker_column_1, t2.a2 AS worker_column_2 FROM (outer_join_columns_testing.t1_30070000 t1 LEFT JOIN outer_join_columns_testing.t2_30070004 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery
Node: host=localhost port=xxxxx dbname=regression
-> Hash Right Join
Output: t1.id, t2.a2
Inner Unique: true
Hash Cond: (t2.account_id = t1.id)
-> Seq Scan on outer_join_columns_testing.t2_30070004 t2
Output: t2.id, t2.account_id, t2.a2
-> Hash
Output: t1.id
-> Seq Scan on outer_join_columns_testing.t1_30070000 t1
Output: t1.id
(22 rows)
-- Issue #7787: count distinct of a column from the inner side of a
-- left outer join will have a non-empty varnullingrels in the query
-- tree returned by Postgres 16+, so ensure this is not reflected in
-- the worker subquery constructed by Citus; it has just one relation,
-- for the pushed down subquery.
SELECT COUNT(DISTINCT a2)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
count
---------------------------------------------------------------------
2
(1 row)
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT COUNT(DISTINCT a2)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
QUERY PLAN
---------------------------------------------------------------------
Aggregate
Output: count(DISTINCT remote_scan.count)
-> Custom Scan (Citus Adaptive)
Output: remote_scan.count
Task Count: 4
Tasks Shown: One of 4
-> Task
Query: SELECT worker_column_1 AS count FROM (SELECT t2.a2 AS worker_column_1 FROM (outer_join_columns_testing.t1_30070000 t1 LEFT JOIN outer_join_columns_testing.t2_30070004 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery GROUP BY worker_column_1
Node: host=localhost port=xxxxx dbname=regression
-> HashAggregate
Output: t2.a2
Group Key: t2.a2
-> Hash Right Join
Output: t2.a2
Inner Unique: true
Hash Cond: (t2.account_id = t1.id)
-> Seq Scan on outer_join_columns_testing.t2_30070004 t2
Output: t2.id, t2.account_id, t2.a2
-> Hash
Output: t1.id
-> Seq Scan on outer_join_columns_testing.t1_30070000 t1
Output: t1.id
(22 rows)
-- Issue #7787 also occurs with a HAVING clause
SELECT 1
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
HAVING COUNT(DISTINCT a2) > 1;
?column?
---------------------------------------------------------------------
1
(1 row)
select public.explain_filter('
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT 1
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
HAVING COUNT(DISTINCT a2) > 1;
', true);
explain_filter
---------------------------------------------------------------------
Aggregate
Output: remote_scan."?column?"
Filter: (count(DISTINCT remote_scan.worker_column_2) > 1)
-> Custom Scan (Citus Adaptive)
Output: remote_scan."?column?", remote_scan.worker_column_2
Task Count: 4
Tasks Shown: One of 4
-> Task
Query: SELECT 1, worker_column_1 AS worker_column_2 FROM (SELECT t2.a2 AS worker_column_1 FROM (outer_join_columns_testing.t1_30070000 t1 LEFT JOIN outer_join_columns_testing.t2_30070004 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery GROUP BY worker_column_1
Node: host=localhost port=xxxxx dbname=regression
-> HashAggregate
Output: 1, t2.a2
Group Key: t2.a2
-> Hash Right Join
Output: t2.a2
Inner Unique: true
Hash Cond: (t2.account_id = t1.id)
-> Seq Scan on outer_join_columns_testing.t2_30070004 t2
Output: t2.id, t2.account_id, t2.a2
-> Hash
Output: t1.id
-> Seq Scan on outer_join_columns_testing.t1_30070000 t1
Output: t1.id
(23 rows)
-- Check right outer join
SELECT COUNT(DISTINCT a2)
FROM t2 RIGHT OUTER JOIN t1 ON t2.account_id = t1.id;
count
---------------------------------------------------------------------
2
(1 row)
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT COUNT(DISTINCT a2)
FROM t2 RIGHT OUTER JOIN t1 ON t2.account_id = t1.id;
QUERY PLAN
---------------------------------------------------------------------
Aggregate
Output: count(DISTINCT remote_scan.count)
-> Custom Scan (Citus Adaptive)
Output: remote_scan.count
Task Count: 4
Tasks Shown: One of 4
-> Task
Query: SELECT worker_column_1 AS count FROM (SELECT t2.a2 AS worker_column_1 FROM (outer_join_columns_testing.t2_30070004 t2 RIGHT JOIN outer_join_columns_testing.t1_30070000 t1 ON ((t2.account_id OPERATOR(pg_catalog.=) t1.id)))) worker_subquery GROUP BY worker_column_1
Node: host=localhost port=xxxxx dbname=regression
-> HashAggregate
Output: t2.a2
Group Key: t2.a2
-> Hash Right Join
Output: t2.a2
Inner Unique: true
Hash Cond: (t2.account_id = t1.id)
-> Seq Scan on outer_join_columns_testing.t2_30070004 t2
Output: t2.id, t2.account_id, t2.a2
-> Hash
Output: t1.id
-> Seq Scan on outer_join_columns_testing.t1_30070000 t1
Output: t1.id
(22 rows)
-- Check both count distinct and having clause
SELECT COUNT(DISTINCT a2)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
HAVING COUNT(DISTINCT t2.id) > 1;
count
---------------------------------------------------------------------
2
(1 row)
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT COUNT(DISTINCT a2)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
HAVING COUNT(DISTINCT t2.id) > 1;
QUERY PLAN
---------------------------------------------------------------------
Aggregate
Output: count(DISTINCT remote_scan.count)
Filter: (count(DISTINCT remote_scan.worker_column_2) > 1)
-> Custom Scan (Citus Adaptive)
Output: remote_scan.count, remote_scan.worker_column_2
Task Count: 4
Tasks Shown: One of 4
-> Task
Query: SELECT worker_column_1 AS count, worker_column_2 FROM (SELECT t2.a2 AS worker_column_1, t2.id AS worker_column_2 FROM (outer_join_columns_testing.t1_30070000 t1 LEFT JOIN outer_join_columns_testing.t2_30070004 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery GROUP BY worker_column_1, worker_column_2
Node: host=localhost port=xxxxx dbname=regression
-> HashAggregate
Output: t2.a2, t2.id
Group Key: t2.a2, t2.id
-> Hash Right Join
Output: t2.a2, t2.id
Inner Unique: true
Hash Cond: (t2.account_id = t1.id)
-> Seq Scan on outer_join_columns_testing.t2_30070004 t2
Output: t2.id, t2.account_id, t2.a2
-> Hash
Output: t1.id
-> Seq Scan on outer_join_columns_testing.t1_30070000 t1
Output: t1.id
(23 rows)
--- cleanup
\set VERBOSITY TERSE
DROP SCHEMA outer_join_columns_testing CASCADE;
NOTICE: drop cascades to 4 other objects
RESET all;

View File

@ -348,8 +348,6 @@ SELECT * FROM nation_hash ORDER BY 1,2,3,4;
--test COLLATION with schema
SET search_path TO public;
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
SELECT substring(:'server_version', '\d+')::int >= 17 AS server_version_ge_17
\gset
\if :server_version_ge_17
@ -357,12 +355,10 @@ SELECT substring(:'server_version', '\d+')::int >= 17 AS server_version_ge_17
-- Relevant PG commit:
-- https://github.com/postgres/postgres/commit/f696c0cd5f299f1b51e214efc55a22a782cc175d
SELECT quote_ident((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) as current_locale \gset
\elif :server_version_ge_16
\else
-- In PG16, read-only server settings lc_collate and lc_ctype are removed
-- Relevant PG commit: b0f6c437160db640d4ea3e49398ebc3ba39d1982
SELECT quote_ident((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) as current_locale \gset
\else
SELECT quote_ident(current_setting('lc_collate')) as current_locale \gset
\endif
CREATE COLLATION test_schema_support.english (LOCALE = :current_locale);
\c - - - :master_port

View File

@ -1,13 +1,6 @@
--
-- PG16
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
\if :server_version_ge_16
\else
\q
\endif
CREATE SCHEMA pg16;
SET search_path TO pg16;
SET citus.next_shard_id TO 950000;

View File

@ -1,9 +0,0 @@
--
-- PG16
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
\if :server_version_ge_16
\else
\q

View File

@ -1,276 +0,0 @@
CREATE SCHEMA publication;
CREATE SCHEMA "publication-1";
SET search_path TO publication;
SET citus.shard_replication_factor TO 1;
CREATE OR REPLACE FUNCTION activate_node_snapshot()
RETURNS text[]
LANGUAGE C STRICT
AS 'citus';
COMMENT ON FUNCTION activate_node_snapshot()
IS 'commands to activate node snapshot';
\c - - - :worker_1_port
SET citus.enable_ddl_propagation TO off;
CREATE OR REPLACE FUNCTION activate_node_snapshot()
RETURNS text[]
LANGUAGE C STRICT
AS 'citus';
COMMENT ON FUNCTION activate_node_snapshot()
IS 'commands to activate node snapshot';
\c - - - :worker_2_port
SET citus.enable_ddl_propagation TO off;
CREATE OR REPLACE FUNCTION activate_node_snapshot()
RETURNS text[]
LANGUAGE C STRICT
AS 'citus';
COMMENT ON FUNCTION activate_node_snapshot()
IS 'commands to activate node snapshot';
-- create some publications with conflicting names on worker node
-- publication will be different from coordinator
CREATE PUBLICATION "pub-all";
-- publication will be same as coordinator
CREATE PUBLICATION "pub-all-insertupdateonly" FOR ALL TABLES WITH (publish = 'insert, update');;
\c - - - :master_port
SET search_path TO publication;
SET citus.shard_replication_factor TO 1;
-- do not create publications on worker 2 initially
SELECT citus_remove_node('localhost', :worker_2_port);
citus_remove_node
---------------------------------------------------------------------
(1 row)
-- create a non-distributed publication
SET citus.enable_ddl_propagation TO off;
CREATE PUBLICATION pubnotdistributed WITH (publish = 'delete');
RESET citus.enable_ddl_propagation;
ALTER PUBLICATION pubnotdistributed SET (publish = 'truncate');
-- create regular, distributed publications
CREATE PUBLICATION pubempty;
CREATE PUBLICATION pubinsertonly WITH (publish = 'insert');
CREATE PUBLICATION "pub-all" FOR ALL TABLES;
CREATE PUBLICATION "pub-all-insertupdateonly" FOR ALL TABLES WITH (publish = 'insert, update');
-- add worker 2 with publications
SELECT 1 FROM citus_add_node('localhost', :worker_2_port);
?column?
---------------------------------------------------------------------
1
(1 row)
-- Check publications on all the nodes, if we see the same publication name twice then its definition differs
-- Note that publications are special in the sense that the coordinator object might differ from
-- worker objects due to the presence of regular tables.
SELECT DISTINCT c FROM (
SELECT unnest(result::text[]) c
FROM run_command_on_workers($$
SELECT array_agg(c) FROM (SELECT c FROM unnest(activate_node_snapshot()) c WHERE c LIKE '%CREATE PUBLICATION%' ORDER BY 1) s$$)
ORDER BY c) s;
c
---------------------------------------------------------------------
SELECT worker_create_or_replace_object('CREATE PUBLICATION "pub-all" FOR ALL TABLES WITH (publish_via_partition_root = ''false'', publish = ''insert, update, delete, truncate'')');
SELECT worker_create_or_replace_object('CREATE PUBLICATION "pub-all-insertupdateonly" FOR ALL TABLES WITH (publish_via_partition_root = ''false'', publish = ''insert, update'')');
SELECT worker_create_or_replace_object('CREATE PUBLICATION pubempty WITH (publish_via_partition_root = ''false'', publish = ''insert, update, delete, truncate'')');
SELECT worker_create_or_replace_object('CREATE PUBLICATION pubinsertonly WITH (publish_via_partition_root = ''false'', publish = ''insert'')');
(4 rows)
CREATE TABLE test (x int primary key, y int, "column-1" int, doc xml);
CREATE TABLE "test-pubs" (x int primary key, y int, "column-1" int);
CREATE TABLE "publication-1"."test-pubs" (x int primary key, y int, "column-1" int);
-- various operations on a publication with only local tables
CREATE PUBLICATION pubtables_orig FOR TABLE test, "test-pubs", "publication-1"."test-pubs" WITH (publish = 'insert, truncate');
ALTER PUBLICATION pubtables_orig DROP TABLE test;
ALTER PUBLICATION pubtables_orig ADD TABLE test;
-- publication will be empty on worker nodes, since all tables are local
SELECT DISTINCT c FROM (
SELECT unnest(result::text[]) c
FROM run_command_on_workers($$
SELECT array_agg(c) FROM (SELECT c FROM unnest(activate_node_snapshot()) c WHERE c LIKE '%CREATE PUBLICATION%' AND c LIKE '%pubtables%' ORDER BY 1) s$$)
ORDER BY c) s;
c
---------------------------------------------------------------------
SELECT worker_create_or_replace_object('CREATE PUBLICATION pubtables_orig WITH (publish_via_partition_root = ''false'', publish = ''insert, truncate'')');
(1 row)
-- distribute a table and create a tenant schema, creating a mixed publication
SELECT create_distributed_table('test','x', colocate_with := 'none');
create_distributed_table
---------------------------------------------------------------------
(1 row)
SET citus.enable_schema_based_sharding TO ON;
CREATE SCHEMA citus_schema_1;
CREATE TABLE citus_schema_1.test (x int primary key, y int, "column-1" int, doc xml);
SET citus.enable_schema_based_sharding TO OFF;
ALTER PUBLICATION pubtables_orig ADD TABLE citus_schema_1.test;
-- some generic operations
ALTER PUBLICATION pubtables_orig RENAME TO pubtables;
ALTER PUBLICATION pubtables SET (publish = 'insert, update, delete');
ALTER PUBLICATION pubtables OWNER TO postgres;
ALTER PUBLICATION pubtables SET (publish = 'inert, update, delete');
ERROR: unrecognized "publish" value: "inert"
ALTER PUBLICATION pubtables ADD TABLE notexist;
ERROR: relation "notexist" does not exist
-- operations with a distributed table
ALTER PUBLICATION pubtables DROP TABLE test;
ALTER PUBLICATION pubtables ADD TABLE test;
ALTER PUBLICATION pubtables SET TABLE test, "test-pubs", "publication-1"."test-pubs", citus_schema_1.test;
-- operations with a tenant schema table
ALTER PUBLICATION pubtables DROP TABLE citus_schema_1.test;
ALTER PUBLICATION pubtables ADD TABLE citus_schema_1.test;
ALTER PUBLICATION pubtables SET TABLE test, "test-pubs", "publication-1"."test-pubs", citus_schema_1.test;
-- operations with a local table in a mixed publication
ALTER PUBLICATION pubtables DROP TABLE "test-pubs";
ALTER PUBLICATION pubtables ADD TABLE "test-pubs";
SELECT create_distributed_table('"test-pubs"', 'x');
create_distributed_table
---------------------------------------------------------------------
(1 row)
-- test and test-pubs will show up in worker nodes
SELECT DISTINCT c FROM (
SELECT unnest(result::text[]) c
FROM run_command_on_workers($$
SELECT array_agg(c) FROM (SELECT c FROM unnest(activate_node_snapshot()) c WHERE c LIKE '%CREATE PUBLICATION%' AND c LIKE '%pubtables%' ORDER BY 1) s$$)
ORDER BY c) s;
c
---------------------------------------------------------------------
SELECT worker_create_or_replace_object('CREATE PUBLICATION pubtables FOR TABLE publication.test, citus_schema_1.test, publication."test-pubs" WITH (publish_via_partition_root = ''false'', publish = ''insert, update, delete'')');
(1 row)
-- operations with a strangely named distributed table in a mixed publication
ALTER PUBLICATION pubtables DROP TABLE "test-pubs";
ALTER PUBLICATION pubtables ADD TABLE "test-pubs";
-- create a publication with distributed and local tables
DROP PUBLICATION pubtables;
CREATE PUBLICATION pubtables FOR TABLE test, "test-pubs", "publication-1"."test-pubs", citus_schema_1.test;
-- change distributed tables
SELECT alter_distributed_table('test', shard_count := 5, cascade_to_colocated := true);
NOTICE: creating a new table for publication.test
NOTICE: moving the data of publication.test
NOTICE: dropping the old publication.test
NOTICE: renaming the new table to publication.test
NOTICE: creating a new table for publication."test-pubs"
NOTICE: moving the data of publication."test-pubs"
NOTICE: dropping the old publication."test-pubs"
NOTICE: renaming the new table to publication."test-pubs"
alter_distributed_table
---------------------------------------------------------------------
(1 row)
SELECT undistribute_table('test');
NOTICE: creating a new table for publication.test
NOTICE: moving the data of publication.test
NOTICE: dropping the old publication.test
NOTICE: renaming the new table to publication.test
undistribute_table
---------------------------------------------------------------------
(1 row)
SELECT citus_add_local_table_to_metadata('test');
citus_add_local_table_to_metadata
---------------------------------------------------------------------
(1 row)
SELECT create_distributed_table_concurrently('test', 'x');
create_distributed_table_concurrently
---------------------------------------------------------------------
(1 row)
SELECT undistribute_table('"test-pubs"');
NOTICE: creating a new table for publication."test-pubs"
NOTICE: moving the data of publication."test-pubs"
NOTICE: dropping the old publication."test-pubs"
NOTICE: renaming the new table to publication."test-pubs"
undistribute_table
---------------------------------------------------------------------
(1 row)
SELECT create_reference_table('"test-pubs"');
create_reference_table
---------------------------------------------------------------------
(1 row)
-- publications are unchanged despite various tranformations
SELECT DISTINCT c FROM (
SELECT unnest(result::text[]) c
FROM run_command_on_workers($$
SELECT array_agg(c) FROM (SELECT c FROM unnest(activate_node_snapshot()) c WHERE c LIKE '%CREATE PUBLICATION%' AND c LIKE '%pubtables%' ORDER BY 1) s$$)
ORDER BY c) s;
c
---------------------------------------------------------------------
SELECT worker_create_or_replace_object('CREATE PUBLICATION pubtables FOR TABLE citus_schema_1.test, publication.test, publication."test-pubs" WITH (publish_via_partition_root = ''false'', publish = ''insert, update, delete, truncate'')');
(1 row)
-- partitioned table
CREATE TABLE testpub_partitioned (a int, b text, c text) PARTITION BY RANGE (a);
CREATE TABLE testpub_partitioned_0 PARTITION OF testpub_partitioned FOR VALUES FROM (1) TO (10);
ALTER TABLE testpub_partitioned_0 ADD PRIMARY KEY (a);
ALTER TABLE testpub_partitioned_0 REPLICA IDENTITY USING INDEX testpub_partitioned_0_pkey;
CREATE TABLE testpub_partitioned_1 PARTITION OF testpub_partitioned FOR VALUES FROM (11) TO (20);
ALTER TABLE testpub_partitioned_1 ADD PRIMARY KEY (a);
ALTER TABLE testpub_partitioned_1 REPLICA IDENTITY USING INDEX testpub_partitioned_1_pkey;
CREATE PUBLICATION pubpartitioned FOR TABLE testpub_partitioned WITH (publish_via_partition_root = 'true');
SELECT create_distributed_table('testpub_partitioned', 'a');
create_distributed_table
---------------------------------------------------------------------
(1 row)
SELECT DISTINCT c FROM (
SELECT unnest(result::text[]) c
FROM run_command_on_workers($$
SELECT array_agg(c) FROM (SELECT c FROM unnest(activate_node_snapshot()) c WHERE c LIKE '%CREATE PUBLICATION%' AND c LIKE '%pubpartitioned%' ORDER BY 1) s$$)
ORDER BY c) s;
c
---------------------------------------------------------------------
SELECT worker_create_or_replace_object('CREATE PUBLICATION pubpartitioned FOR TABLE publication.testpub_partitioned WITH (publish_via_partition_root = ''true'', publish = ''insert, update, delete, truncate'')');
(1 row)
DROP PUBLICATION pubpartitioned;
CREATE PUBLICATION pubpartitioned FOR TABLE testpub_partitioned WITH (publish_via_partition_root = 'true');
-- add a partition
ALTER PUBLICATION pubpartitioned ADD TABLE testpub_partitioned_1;
SELECT DISTINCT c FROM (
SELECT unnest(result::text[]) c
FROM run_command_on_workers($$
SELECT array_agg(c) FROM (SELECT c FROM unnest(activate_node_snapshot()) c WHERE c LIKE '%CREATE PUBLIATION%' AND c LIKE '%pubpartitioned%' ORDER BY 1) s$$)
ORDER BY c) s;
ERROR: malformed array literal: ""
DETAIL: Array value must start with "{" or dimension information.
-- make sure we can sync all the publication metadata
SELECT start_metadata_sync_to_all_nodes();
start_metadata_sync_to_all_nodes
---------------------------------------------------------------------
t
(1 row)
DROP PUBLICATION pubempty;
DROP PUBLICATION pubtables;
DROP PUBLICATION pubinsertonly;
DROP PUBLICATION "pub-all-insertupdateonly";
DROP PUBLICATION "pub-all";
DROP PUBLICATION pubpartitioned;
DROP PUBLICATION pubnotdistributed;
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
\gset
\if :server_version_ge_15
\else
SET client_min_messages TO ERROR;
DROP SCHEMA publication CASCADE;
DROP SCHEMA "publication-1" CASCADE;
DROP SCHEMA citus_schema_1 CASCADE;
SELECT public.wait_for_resource_cleanup();
wait_for_resource_cleanup
---------------------------------------------------------------------
(1 row)
\q

File diff suppressed because it is too large Load Diff

View File

@ -266,16 +266,8 @@ create table events (event_id bigserial, event_time timestamptz default now(), p
create index on events (event_id);
insert into events (payload) select 'hello-'||s from generate_series(1,10) s;
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
BEGIN;
\if :server_version_ge_16
SET LOCAL debug_parallel_query = regress;
\else
SET LOCAL force_parallel_mode = regress;
\endif
SET LOCAL min_parallel_table_scan_size = 1;
SET LOCAL parallel_tuple_cost = 0;
SET LOCAL max_parallel_workers = 4;

View File

@ -20,16 +20,7 @@ select count(*), min(i), max(i), avg(i) from fallback_scan;
-- Negative test: try to force a parallel plan with at least two
-- workers, but columnar should reject it and use a non-parallel scan.
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
\if :server_version_ge_16
set debug_parallel_query = regress;
\else
set force_parallel_mode = regress;
\endif
set min_parallel_table_scan_size = 1;
set parallel_tuple_cost = 0;
set max_parallel_workers = 4;
@ -37,11 +28,7 @@ set max_parallel_workers_per_gather = 4;
explain (costs off) select count(*), min(i), max(i), avg(i) from fallback_scan;
select count(*), min(i), max(i), avg(i) from fallback_scan;
\if :server_version_ge_16
set debug_parallel_query = default;
\else
set force_parallel_mode = default;
\endif
set min_parallel_table_scan_size to default;
set parallel_tuple_cost to default;
set max_parallel_workers to default;

View File

@ -414,10 +414,6 @@ BEGIN;
-- this wouldn't flush any data
insert into events (payload) select 'hello-'||s from generate_series(1, 10) s;
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
-- Since table is large enough, normally postgres would prefer using
-- parallel workers when building the index.
--
@ -430,11 +426,7 @@ BEGIN;
-- following commnad to fail since we prevent using parallel workers for
-- columnar tables.
\if :server_version_ge_16
SET LOCAL debug_parallel_query = regress;
\else
SET LOCAL force_parallel_mode = regress;
\endif
SET LOCAL min_parallel_table_scan_size = 1;
SET LOCAL parallel_tuple_cost = 0;
SET LOCAL max_parallel_workers = 4;

View File

@ -24,16 +24,9 @@ INSERT INTO parent SELECT '2020-03-15', 30, 300, 'three thousand'
INSERT INTO parent SELECT '2020-04-15', 30, 300, 'three thousand'
FROM generate_series(1,100000);
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
-- run parallel plans
\if :server_version_ge_16
SET debug_parallel_query = regress;
\else
SET force_parallel_mode = regress;
\endif
SET min_parallel_table_scan_size = 1;
SET parallel_tuple_cost = 0;
SET max_parallel_workers = 4;
@ -57,11 +50,8 @@ EXPLAIN (costs off) SELECT count(*), sum(i), min(i), max(i) FROM parent;
SELECT count(*), sum(i), min(i), max(i) FROM parent;
SET columnar.enable_custom_scan TO DEFAULT;
\if :server_version_ge_16
SET debug_parallel_query TO DEFAULT;
\else
SET force_parallel_mode TO DEFAULT;
\endif
SET min_parallel_table_scan_size TO DEFAULT;
SET parallel_tuple_cost TO DEFAULT;
SET max_parallel_workers TO DEFAULT;

View File

@ -1,14 +1,3 @@
--
-- 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/drop database for pg >= 15
set citus.enable_create_database_propagation=on;

View File

@ -1,14 +1,3 @@
--
-- PG16
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
\if :server_version_ge_16
\else
\q
\endif
-- create/drop database for pg >= 16
set citus.enable_create_database_propagation=on;

View File

@ -1,18 +1,9 @@
SHOW server_version \gset
SELECT CASE
WHEN substring(current_setting('server_version'), '\d+')::int >= 17 THEN '17+'
WHEN substring(current_setting('server_version'), '\d+')::int IN (15, 16) THEN '15_16'
WHEN substring(current_setting('server_version'), '\d+')::int = 14 THEN '14'
ELSE 'Unsupported version'
END AS version_category;
SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15
\gset
\if :server_version_ge_15
\else
\q
\endif
--
-- MERGE test from PG community (adapted to Citus by converting all tables to Citus local)

View File

@ -798,21 +798,14 @@ BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- with an ugly trick, update the vartype of table from int to bigint
-- so that making two tables colocated fails
-- include varnullingrels for PG16+
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
-- include varreturningtype for PG18+
SELECT substring(:'server_version', '\d+')::int >= 18 AS server_version_ge_18
\gset
\if :server_version_ge_18
UPDATE pg_dist_partition SET partkey = '{VAR :varno 1 :varattno 1 :vartype 20 :vartypmod -1 :varcollid 0 :varnullingrels (b) :varlevelsup 1 :varreturningtype 0 :varnoold 1 :varoattno 1 :location -1}'
WHERE logicalrelid = 'test_2'::regclass;
\elif :server_version_ge_16
UPDATE pg_dist_partition SET partkey = '{VAR :varno 1 :varattno 1 :vartype 20 :vartypmod -1 :varcollid 0 :varnullingrels (b) :varlevelsup 1 :varnoold 1 :varoattno 1 :location -1}'
WHERE logicalrelid = 'test_2'::regclass;
\else
UPDATE pg_dist_partition SET partkey = '{VAR :varno 1 :varattno 1 :vartype 20 :vartypmod -1 :varcollid 0 :varlevelsup 1 :varnoold 1 :varoattno 1 :location -1}'
UPDATE pg_dist_partition SET partkey = '{VAR :varno 1 :varattno 1 :vartype 20 :vartypmod -1 :varcollid 0 :varnullingrels (b) :varlevelsup 1 :varnoold 1 :varoattno 1 :location -1}'
WHERE logicalrelid = 'test_2'::regclass;
\endif

View File

@ -1,14 +1,6 @@
--
-- COMPLEX_COUNT_DISTINCT
--
-- This test file has an alternative output because of the following in PG16:
-- https://github.com/postgres/postgres/commit/1349d2790bf48a4de072931c722f39337e72055e
-- https://github.com/postgres/postgres/commit/f4c7c410ee4a7baa06f51ebb8d5333c169691dd3
-- The alternative output can be deleted when we drop support for PG15
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16;
SET citus.next_shard_id TO 240000;
SET citus.shard_count TO 8;
SET citus.shard_replication_factor TO 1;

View File

@ -1,17 +1,11 @@
--
-- MULTI_EXPLAIN
--
-- This test file has an alternative output because of the following in PG16:
-- https://github.com/postgres/postgres/commit/1349d2790bf48a4de072931c722f39337e72055e
-- https://github.com/postgres/postgres/commit/f4c7c410ee4a7baa06f51ebb8d5333c169691dd3
-- The alternative output can be deleted when we drop support for PG15
--
-- This test file has an alternative output because of the following in PG18:
-- https://github.com/postgres/postgres/commit/161320b4b960ee4fe918959be6529ae9b106ea5a
-- The alternative output can be deleted when we drop support for PG17
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16;
SELECT substring(:'server_version', '\d+')::int >= 18 AS server_version_ge_18;
SET citus.next_shard_id TO 570000;

View File

@ -59,8 +59,6 @@ CREATE OPERATOR citus_mx_test_schema.=== (
SET search_path TO public;
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int >= 16 AS server_version_ge_16
\gset
SELECT substring(:'server_version', '\d+')::int >= 17 AS server_version_ge_17
\gset
@ -69,12 +67,10 @@ SELECT substring(:'server_version', '\d+')::int >= 17 AS server_version_ge_17
-- Relevant PG commit:
-- https://github.com/postgres/postgres/commit/f696c0cd5f299f1b51e214efc55a22a782cc175d
SELECT quote_ident((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) as current_locale \gset
\elif :server_version_ge_16
\else
-- In PG16, read-only server settings lc_collate and lc_ctype are removed
-- Relevant PG commit: b0f6c437160db640d4ea3e49398ebc3ba39d1982
SELECT quote_ident((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) as current_locale \gset
\else
SELECT quote_ident(current_setting('lc_collate')) as current_locale \gset
\endif
CREATE COLLATION citus_mx_test_schema.english (LOCALE=:current_locale);

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