pg18 compile work cont

m3hm3t/pg18_rel_oid_2
Mehmet Yilmaz 2025-05-12 20:02:13 +00:00
parent a1dfdca4ed
commit 5f4e571b70
20 changed files with 8161 additions and 1588 deletions

View File

@ -108,6 +108,18 @@ RUN mkdir .pgenv-staging/
RUN cp -r .pgenv/src .pgenv/pgsql-* .pgenv/config .pgenv-staging/ RUN cp -r .pgenv/src .pgenv/pgsql-* .pgenv/config .pgenv-staging/
RUN rm .pgenv-staging/config/default.conf RUN rm .pgenv-staging/config/default.conf
FROM base AS pg18
RUN MAKEFLAGS="-j $(nproc)" pgenv build 18beta1
RUN rm .pgenv/src/*.tar*
RUN make -C .pgenv/src/postgresql-*/ clean
RUN make -C .pgenv/src/postgresql-*/src/include install
# Stage the pgenv artifacts for PG18
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 uncrustify-builder FROM base AS uncrustify-builder
RUN sudo apt update && sudo apt install -y cmake tree RUN sudo apt update && sudo apt install -y cmake tree
@ -201,6 +213,7 @@ COPY --link --from=uncrustify-builder /uncrustify/usr/ /usr/
COPY --link --from=pg15 /home/citus/.pgenv-staging/ /home/citus/.pgenv/ 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=pg16 /home/citus/.pgenv-staging/ /home/citus/.pgenv/
COPY --link --from=pg17 /home/citus/.pgenv-staging/ /home/citus/.pgenv/ COPY --link --from=pg17 /home/citus/.pgenv-staging/ /home/citus/.pgenv/
COPY --link --from=pg18 /home/citus/.pgenv-staging/ /home/citus/.pgenv/
COPY --link --from=pipenv /home/citus/.local/share/virtualenvs/ /home/citus/.local/share/virtualenvs/ COPY --link --from=pipenv /home/citus/.local/share/virtualenvs/ /home/citus/.local/share/virtualenvs/
@ -216,7 +229,7 @@ COPY --chown=citus:citus .psqlrc .
RUN sudo chown --from=root:root citus:citus -R ~ RUN sudo chown --from=root:root citus:citus -R ~
# sets default pg version # sets default pg version
RUN pgenv switch 17.5 RUN pgenv switch 18beta1
# make connecting to the coordinator easy # make connecting to the coordinator easy
ENV PGPORT=9700 ENV PGPORT=9700

3051
configure vendored

File diff suppressed because it is too large Load Diff

6163
configure~ Executable file

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,9 @@
#include "miscadmin.h" #include "miscadmin.h"
#include "nodes/execnodes.h" /* for ExprState, ExprContext, etc. */
#include "executor/executor.h" /* for ExecInitExprWithParams(), ExecEvalExpr() */
#include "commands/explain_format.h" /* for ExplainPropertyInteger() */
#include "access/amapi.h" #include "access/amapi.h"
#include "access/skey.h" #include "access/skey.h"
#include "catalog/pg_am.h" #include "catalog/pg_am.h"

View File

@ -1414,16 +1414,28 @@ UpdateStripeMetadataRow(uint64 storageId, uint64 stripeId, bool *update,
storageId, stripeId))); storageId, stripeId)));
} }
/*
* heap_modify_tuple + heap_inplace_update only exist on PG < 18;
* on PG18 the in-place helper was removed upstream, so we skip the whole block.
*/
#if PG_VERSION_NUM < PG_VERSION_18
/* /*
* heap_inplace_update already doesn't allow changing size of the original * heap_inplace_update already doesn't allow changing size of the original
* tuple, so we don't allow setting any Datum's to NULL values. * tuple, so we don't allow setting any Datum's to NULL values.
*/ */
bool newNulls[Natts_columnar_stripe] = { false }; bool newNulls[Natts_columnar_stripe] = { false };
TupleDesc tupleDescriptor = RelationGetDescr(columnarStripes); TupleDesc tupleDescriptor = RelationGetDescr(columnarStripes);
HeapTuple modifiedTuple = heap_modify_tuple(oldTuple, tupleDescriptor, HeapTuple modifiedTuple = heap_modify_tuple(oldTuple,
newValues, newNulls, update); tupleDescriptor,
newValues,
newNulls,
update);
heap_inplace_update(columnarStripes, modifiedTuple); heap_inplace_update(columnarStripes, modifiedTuple);
#endif
/* /*
* Existing tuple now contains modifications, because we used * Existing tuple now contains modifications, because we used
@ -1727,12 +1739,39 @@ create_estate_for_relation(Relation rel)
rte->relkind = rel->rd_rel->relkind; rte->relkind = rel->rd_rel->relkind;
rte->rellockmode = AccessShareLock; rte->rellockmode = AccessShareLock;
/* Prepare permission info on PG 16+ */
#if PG_VERSION_NUM >= PG_VERSION_16 #if PG_VERSION_NUM >= PG_VERSION_16
List *perminfos = NIL; List *perminfos = NIL;
addRTEPermissionInfo(&perminfos, rte); addRTEPermissionInfo(&perminfos, rte);
ExecInitRangeTable(estate, list_make1(rte), perminfos);
#else #else
ExecInitRangeTable(estate, list_make1(rte)); List *perminfos = NIL; /* not used on PG 15 */
#endif
/* Initialize the range table, with the right signature for each PG version */
#if PG_VERSION_NUM >= PG_VERSION_18
/* PG 18+ needs four arguments (unpruned_relids) */
ExecInitRangeTable(
estate,
list_make1(rte),
perminfos,
NULL /* unpruned_relids: not used by columnar */
);
#elif PG_VERSION_NUM >= PG_VERSION_16
/* PG 1617: three-arg signature (permInfos) */
ExecInitRangeTable(
estate,
list_make1(rte),
perminfos
);
#else
/* PG 15: two-arg signature */
ExecInitRangeTable(
estate,
list_make1(rte)
);
#endif #endif
estate->es_output_cid = GetCurrentCommandId(true); estate->es_output_cid = GetCurrentCommandId(true);

View File

@ -1012,7 +1012,7 @@ NeededColumnsList(TupleDesc tupdesc, Bitmapset *attr_needed)
for (int i = 0; i < tupdesc->natts; i++) for (int i = 0; i < tupdesc->natts; i++)
{ {
if (tupdesc->attrs[i].attisdropped) if (Attr(tupdesc, i)->attisdropped)
{ {
continue; continue;
} }
@ -1121,10 +1121,23 @@ columnar_vacuum_rel(Relation rel, VacuumParams *params,
bool frozenxid_updated; bool frozenxid_updated;
bool minmulti_updated; bool minmulti_updated;
/* for PG 18+, vac_update_relstats gained a new “all_frozen” param */
#if PG_VERSION_NUM >= PG_VERSION_18
vac_update_relstats(rel, new_rel_pages, new_live_tuples,
new_rel_allvisible, /* allvisible */
0, /* all_frozen */
nindexes > 0,
newRelFrozenXid, newRelminMxid,
&frozenxid_updated, &minmulti_updated,
false);
#else
vac_update_relstats(rel, new_rel_pages, new_live_tuples, vac_update_relstats(rel, new_rel_pages, new_live_tuples,
new_rel_allvisible, nindexes > 0, new_rel_allvisible, nindexes > 0,
newRelFrozenXid, newRelminMxid, newRelFrozenXid, newRelminMxid,
&frozenxid_updated, &minmulti_updated, false); &frozenxid_updated, &minmulti_updated,
false);
#endif
#else #else
TransactionId oldestXmin; TransactionId oldestXmin;
TransactionId freezeLimit; TransactionId freezeLimit;
@ -1187,10 +1200,17 @@ columnar_vacuum_rel(Relation rel, VacuumParams *params,
#endif #endif
#endif #endif
#if PG_VERSION_NUM >= PG_VERSION_18
pgstat_report_vacuum(RelationGetRelid(rel), pgstat_report_vacuum(RelationGetRelid(rel),
rel->rd_rel->relisshared, rel->rd_rel->relisshared,
Max(new_live_tuples, 0), Max(new_live_tuples, 0), /* live tuples */
0); 0, /* dead tuples */
GetCurrentTimestamp()); /* start time */
#else
pgstat_report_vacuum(RelationGetRelid(rel),
rel->rd_rel->relisshared);
#endif
pgstat_progress_end_command(); pgstat_progress_end_command();
} }
@ -1225,7 +1245,7 @@ LogRelationStats(Relation rel, int elevel)
GetTransactionSnapshot()); GetTransactionSnapshot());
for (uint32 column = 0; column < skiplist->columnCount; column++) for (uint32 column = 0; column < skiplist->columnCount; column++)
{ {
bool attrDropped = tupdesc->attrs[column].attisdropped; bool attrDropped = Attr(tupdesc, column)->attisdropped;
for (uint32 chunk = 0; chunk < skiplist->chunkCount; chunk++) for (uint32 chunk = 0; chunk < skiplist->chunkCount; chunk++)
{ {
ColumnChunkSkipNode *skipnode = ColumnChunkSkipNode *skipnode =
@ -2564,8 +2584,13 @@ static const TableAmRoutine columnar_am_methods = {
.relation_estimate_size = columnar_estimate_rel_size, .relation_estimate_size = columnar_estimate_rel_size,
#if PG_VERSION_NUM < PG_VERSION_18
/* these two fields were removed in PG18 */
.scan_bitmap_next_block = NULL, .scan_bitmap_next_block = NULL,
.scan_bitmap_next_tuple = NULL, .scan_bitmap_next_tuple = NULL,
#endif
.scan_sample_next_block = columnar_scan_sample_next_block, .scan_sample_next_block = columnar_scan_sample_next_block,
.scan_sample_next_tuple = columnar_scan_sample_next_tuple .scan_sample_next_tuple = columnar_scan_sample_next_tuple
}; };
@ -2603,7 +2628,7 @@ detoast_values(TupleDesc tupleDesc, Datum *orig_values, bool *isnull)
for (int i = 0; i < tupleDesc->natts; i++) for (int i = 0; i < tupleDesc->natts; i++)
{ {
if (!isnull[i] && tupleDesc->attrs[i].attlen == -1 && if (!isnull[i] && Attr(tupleDesc, i)->attlen == -1 &&
VARATT_IS_EXTENDED(values[i])) VARATT_IS_EXTENDED(values[i]))
{ {
/* make a copy */ /* make a copy */

View File

@ -3049,7 +3049,7 @@ CitusCopySelect(CopyStmt *copyStatement)
for (int i = 0; i < tupleDescriptor->natts; i++) for (int i = 0; i < tupleDescriptor->natts; i++)
{ {
Form_pg_attribute attr = &tupleDescriptor->attrs[i]; Form_pg_attribute attr = TupleDescAttr(tupleDescriptor, i);
if (attr->attisdropped || if (attr->attisdropped ||
attr->attgenerated attr->attgenerated

View File

@ -15,6 +15,7 @@
#include "distributed/connection_management.h" #include "distributed/connection_management.h"
#include "distributed/error_codes.h" #include "distributed/error_codes.h"
#include "distributed/errormessage.h" #include "distributed/errormessage.h"
#include "utils/memutils.h" /* for TopTransactionContext */
#include "distributed/log_utils.h" #include "distributed/log_utils.h"
#include "distributed/worker_log_messages.h" #include "distributed/worker_log_messages.h"

View File

@ -1,6 +1,6 @@
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* *
* ruleutils_16.c * ruleutils_17.c
* Functions to convert stored expressions/querytrees back to * Functions to convert stored expressions/querytrees back to
* source text * source text
* *
@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* src/backend/distributed/deparser/ruleutils_16.c * src/backend/distributed/deparser/ruleutils_17.c
* *
* This needs to be closely in sync with the core code. * This needs to be closely in sync with the core code.
*------------------------------------------------------------------------- *-------------------------------------------------------------------------

View File

@ -755,13 +755,48 @@ ExecuteTaskPlan(PlannedStmt *taskPlan, char *queryString,
CreateDestReceiver(DestNone); CreateDestReceiver(DestNone);
/* Create a QueryDesc for the query */ /* Create a QueryDesc for the query */
QueryDesc *queryDesc = CreateQueryDesc(taskPlan, queryString, #if PG_VERSION_NUM >= PG_VERSION_18
GetActiveSnapshot(), InvalidSnapshot,
destReceiver, paramListInfo, /* PG18+: ninearg CreateQueryDesc with a CachedPlan slot */
queryEnv, 0); QueryDesc *queryDesc = CreateQueryDesc(
taskPlan, /* PlannedStmt *plannedstmt */
NULL, /* CachedPlan *cplan (none) */
queryString, /* const char *sourceText */
GetActiveSnapshot(), /* Snapshot snapshot */
InvalidSnapshot, /* Snapshot crosscheck_snapshot */
destReceiver, /* DestReceiver *dest */
paramListInfo, /* ParamListInfo params */
queryEnv, /* QueryEnvironment *queryEnv */
0 /* int instrument_options */
);
#else
/* PG1517: eightarg CreateQueryDesc without CachedPlan */
QueryDesc *queryDesc = CreateQueryDesc(
taskPlan, /* PlannedStmt *plannedstmt */
queryString, /* const char *sourceText */
GetActiveSnapshot(), /* Snapshot snapshot */
InvalidSnapshot, /* Snapshot crosscheck_snapshot */
destReceiver, /* DestReceiver *dest */
paramListInfo, /* ParamListInfo params */
queryEnv, /* QueryEnvironment *queryEnv */
0 /* int instrument_options */
);
#endif
ExecutorStart(queryDesc, eflags); ExecutorStart(queryDesc, eflags);
/* run the plan: count = 0 (all rows) */
#if PG_VERSION_NUM >= PG_VERSION_18
/* PG 18+ dropped the “execute_once” boolean */
ExecutorRun(queryDesc, scanDirection, 0L);
#else
/* PG 17 and prevs still expect the 4th once argument */
ExecutorRun(queryDesc, scanDirection, 0L, true); ExecutorRun(queryDesc, scanDirection, 0L, true);
#endif
/* /*
* We'll set the executorState->es_processed later, for now only remember * We'll set the executorState->es_processed later, for now only remember

View File

@ -235,7 +235,20 @@ CitusExecutorRun(QueryDesc *queryDesc,
/* postgres will switch here again and will restore back on its own */ /* postgres will switch here again and will restore back on its own */
MemoryContextSwitchTo(oldcontext); MemoryContextSwitchTo(oldcontext);
standard_ExecutorRun(queryDesc, direction, count, execute_once); #if PG_VERSION_NUM >= PG_VERSION_18
/* PG18+ drops the “execute_once” argument */
standard_ExecutorRun(queryDesc,
direction,
count);
#else
/* PG17-: original four-arg signature */
standard_ExecutorRun(queryDesc,
direction,
count,
execute_once);
#endif
} }
if (totalTime) if (totalTime)
@ -688,15 +701,55 @@ ExecutePlanIntoDestReceiver(PlannedStmt *queryPlan, ParamListInfo params,
/* don't display the portal in pg_cursors, it is for internal use only */ /* don't display the portal in pg_cursors, it is for internal use only */
portal->visible = false; portal->visible = false;
PortalDefineQuery(portal, #if PG_VERSION_NUM >= PG_VERSION_18
NULL,
"", /* PostgreSQL 18+ adds a seventh “plansource” argument */
CMDTAG_SELECT, PortalDefineQuery(
list_make1(queryPlan), portal,
NULL); NULL, /* no prepared statement name */
"", /* query text */
CMDTAG_SELECT, /* command tag */
list_make1(queryPlan),/* list of PlannedStmt* */
NULL, /* no CachedPlan */
NULL /* no CachedPlanSource */
);
#else
/* PostgreSQL 17-: six-arg signature */
PortalDefineQuery(
portal,
NULL, /* no prepared statement name */
"", /* query text */
CMDTAG_SELECT, /* command tag */
list_make1(queryPlan),/* list of PlannedStmt* */
NULL /* no CachedPlan */
);
#endif
PortalStart(portal, params, eflags, GetActiveSnapshot()); PortalStart(portal, params, eflags, GetActiveSnapshot());
PortalRun(portal, count, false, true, dest, dest, NULL);
#if PG_VERSION_NUM >= PG_VERSION_18
/* PG 18+: six-arg signature (drop the run_once bool) */
PortalRun(portal,
count, /* how many rows to fetch */
false, /* isTopLevel */
dest, /* DestReceiver *dest */
dest, /* DestReceiver *altdest */
NULL); /* QueryCompletion *qc */
#else
/* PG 17-: original seven-arg signature */
PortalRun(portal,
count, /* how many rows to fetch */
false, /* isTopLevel */
true, /* run_once */
dest, /* DestReceiver *dest */
dest, /* DestReceiver *altdest */
NULL); /* QueryCompletion *qc */
#endif
PortalDrop(portal, false); PortalDrop(portal, false);
} }

View File

@ -242,7 +242,27 @@ worker_partition_query_result(PG_FUNCTION_ARGS)
allowNullPartitionColumnValues); allowNullPartitionColumnValues);
/* execute the query */ /* execute the query */
PortalRun(portal, FETCH_ALL, false, true, dest, dest, NULL); #if PG_VERSION_NUM >= PG_VERSION_18
/* PG18+: drop the “run_once” bool */
PortalRun(portal,
FETCH_ALL, /* count */
false, /* isTopLevel */
dest, /* dest receiver */
dest, /* alternative dest */
NULL); /* QueryCompletion *qc */
#else
/* PG1517: original sevenarg signature */
PortalRun(portal,
FETCH_ALL, /* count */
false, /* isTopLevel */
true, /* run_once */
dest, /* dest receiver */
dest, /* alternative dest */
NULL); /* QueryCompletion *qc */
#endif
/* construct the output result */ /* construct the output result */
TupleDesc returnTupleDesc = NULL; TupleDesc returnTupleDesc = NULL;
@ -295,8 +315,31 @@ StartPortalForQueryExecution(const char *queryString)
/* don't display the portal in pg_cursors, it is for internal use only */ /* don't display the portal in pg_cursors, it is for internal use only */
portal->visible = false; portal->visible = false;
PortalDefineQuery(portal, NULL, queryString, CMDTAG_SELECT, #if PG_VERSION_NUM >= PG_VERSION_18
list_make1(queryPlan), NULL);
/* PG 18+: new CachedPlanSource slot */
PortalDefineQuery(
portal,
NULL, /* no preparedstmt name */
queryString, /* the SQL text */
CMDTAG_SELECT, /* were running a SELECT */
list_make1(queryPlan), /* plan trees */
NULL, /* no CachedPlan */
NULL /* no CachedPlanSource */
);
#else
/* PG 1517: sixarg signature */
PortalDefineQuery(
portal,
NULL,
queryString,
CMDTAG_SELECT,
list_make1(queryPlan),
NULL /* no CachedPlan */
);
#endif
int eflags = 0; int eflags = 0;
PortalStart(portal, NULL, eflags, GetActiveSnapshot()); PortalStart(portal, NULL, eflags, GetActiveSnapshot());

View File

@ -2965,8 +2965,18 @@ DeleteNodeRow(char *nodeName, int32 nodePort)
* https://github.com/citusdata/citus/pull/2855#discussion_r313628554 * https://github.com/citusdata/citus/pull/2855#discussion_r313628554
* https://github.com/citusdata/citus/issues/1890 * https://github.com/citusdata/citus/issues/1890
*/ */
Relation replicaIndex = index_open(RelationGetPrimaryKeyIndex(pgDistNode), #if PG_VERSION_NUM >= PG_VERSION_18
AccessShareLock);
/* PG 18+ adds a bool “deferrable_ok” parameter */
Relation replicaIndex =
index_open(RelationGetPrimaryKeyIndex(pgDistNode, false),
RowExclusiveLock);
#else
Relation replicaIndex =
index_open(RelationGetPrimaryKeyIndex(pgDistNode),
RowExclusiveLock);
#endif
ScanKeyInit(&scanKey[0], Anum_pg_dist_node_nodename, ScanKeyInit(&scanKey[0], Anum_pg_dist_node_nodename,
BTEqualStrategyNumber, F_TEXTEQ, CStringGetTextDatum(nodeName)); BTEqualStrategyNumber, F_TEXTEQ, CStringGetTextDatum(nodeName));

View File

@ -746,7 +746,12 @@ GetRelationIdentityOrPK(Relation rel)
if (!OidIsValid(idxoid)) if (!OidIsValid(idxoid))
{ {
/* Determine the index OID of the primary key (PG18 adds a second parameter) */
#if PG_VERSION_NUM >= PG_VERSION_18
idxoid = RelationGetPrimaryKeyIndex(rel, false);
#else
idxoid = RelationGetPrimaryKeyIndex(rel); idxoid = RelationGetPrimaryKeyIndex(rel);
#endif
} }
return idxoid; return idxoid;

View File

@ -23,6 +23,7 @@
#include "commands/createas.h" #include "commands/createas.h"
#include "commands/dbcommands.h" #include "commands/dbcommands.h"
#include "commands/explain.h" #include "commands/explain.h"
#include "commands/explain_format.h"
#include "commands/tablecmds.h" #include "commands/tablecmds.h"
#include "executor/tstoreReceiver.h" #include "executor/tstoreReceiver.h"
#include "lib/stringinfo.h" #include "lib/stringinfo.h"
@ -42,6 +43,10 @@
#include "utils/json.h" #include "utils/json.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/snapmgr.h" #include "utils/snapmgr.h"
#if PG_VERSION_NUM >= PG_VERSION_18
# include "commands/explain_dr.h" /* CreateExplainSerializeDestReceiver() */
#endif
#include "pg_version_constants.h" #include "pg_version_constants.h"
@ -134,7 +139,7 @@ typedef struct ExplainAnalyzeDestination
TupleDesc lastSavedExplainAnalyzeTupDesc; TupleDesc lastSavedExplainAnalyzeTupDesc;
} ExplainAnalyzeDestination; } ExplainAnalyzeDestination;
#if PG_VERSION_NUM >= PG_VERSION_17 #if PG_VERSION_NUM >= PG_VERSION_17 && PG_VERSION_NUM < PG_VERSION_18
/* /*
* Various places within need to convert bytes to kilobytes. Round these up * Various places within need to convert bytes to kilobytes. Round these up
@ -529,19 +534,53 @@ ExplainSubPlans(DistributedPlan *distributedPlan, ExplainState *es)
ExplainOpenGroup("PlannedStmt", "PlannedStmt", false, es); ExplainOpenGroup("PlannedStmt", "PlannedStmt", false, es);
/* Capture memory stats on PG17+ */
#if PG_VERSION_NUM >= PG_VERSION_17 #if PG_VERSION_NUM >= PG_VERSION_17
if (es->memory) if (es->memory)
{ {
MemoryContextSwitchTo(saved_ctx); MemoryContextSwitchTo(saved_ctx);
MemoryContextMemConsumed(planner_ctx, &mem_counters); MemoryContextMemConsumed(planner_ctx, &mem_counters);
} }
#endif
ExplainOnePlan(plan, into, es, queryString, params, NULL, &planduration, #if PG_VERSION_NUM >= PG_VERSION_18
ExplainOnePlan(
plan, /* PlannedStmt *plannedstmt */
NULL, /* CachedPlan *cplan */
NULL, /* CachedPlanSource *plansource */
0, /* query_index */
into, /* IntoClause *into */
es, /* struct ExplainState *es */
queryString, /* const char *queryString */
params, /* ParamListInfo params */
NULL, /* QueryEnvironment *queryEnv */
&planduration, /* const instr_time *planduration */
(es->buffers ? &bufusage : NULL),/* const BufferUsage *bufusage */
(es->memory ? &mem_counters : NULL) /* const MemoryContextCounters *mem_counters */
);
#elif PG_VERSION_NUM >= PG_VERSION_17
ExplainOnePlan(
plan,
into,
es,
queryString,
params,
NULL, /* QueryEnvironment *queryEnv */
&planduration,
(es->buffers ? &bufusage : NULL), (es->buffers ? &bufusage : NULL),
(es->memory ? &mem_counters : NULL)); (es->memory ? &mem_counters : NULL)
);
#else #else
ExplainOnePlan(plan, into, es, queryString, params, NULL, &planduration, ExplainOnePlan(
(es->buffers ? &bufusage : NULL)); plan,
into,
es,
queryString,
params,
NULL, /* QueryEnvironment *queryEnv */
&planduration,
(es->buffers ? &bufusage : NULL)
);
#endif #endif
ExplainCloseGroup("PlannedStmt", "PlannedStmt", false, es); ExplainCloseGroup("PlannedStmt", "PlannedStmt", false, es);
@ -1558,22 +1597,55 @@ CitusExplainOneQuery(Query *query, int cursorOptions, IntoClause *into,
BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start); BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start);
} }
/* capture memory stats on PG17+ */
#if PG_VERSION_NUM >= PG_VERSION_17 #if PG_VERSION_NUM >= PG_VERSION_17
if (es->memory) if (es->memory)
{ {
MemoryContextSwitchTo(saved_ctx); MemoryContextSwitchTo(saved_ctx);
MemoryContextMemConsumed(planner_ctx, &mem_counters); MemoryContextMemConsumed(planner_ctx, &mem_counters);
} }
#endif
/* run it (if needed) and produce output */ #if PG_VERSION_NUM >= PG_VERSION_18
ExplainOnePlan(plan, into, es, queryString, params, queryEnv, ExplainOnePlan(
&planduration, (es->buffers ? &bufusage : NULL), plan, /* PlannedStmt *plannedstmt */
(es->memory ? &mem_counters : NULL)); NULL, /* no CachedPlan */
NULL, /* no CachedPlanSource */
0, /* query_index */
into, /* IntoClause *into */
es, /* struct ExplainState *es */
queryString, /* const char *queryString */
params, /* ParamListInfo params */
queryEnv, /* QueryEnvironment *queryEnv */
&planduration, /* const instr_time *planduration */
(es->buffers ? &bufusage : NULL), /* const BufferUsage *bufusage */
(es->memory ? &mem_counters : NULL) /* const MemoryContextCounters *mem_counters */
);
#elif PG_VERSION_NUM >= PG_VERSION_17
/* PostgreSQL 17 signature (9 args: includes mem_counters) */
ExplainOnePlan(
plan,
into,
es,
queryString,
params,
queryEnv,
&planduration,
(es->buffers ? &bufusage : NULL),
(es->memory ? &mem_counters : NULL)
);
#else #else
ExplainOnePlan(
/* run it (if needed) and produce output */ plan,
ExplainOnePlan(plan, into, es, queryString, params, queryEnv, into,
&planduration, (es->buffers ? &bufusage : NULL)); es,
queryString,
params,
queryEnv,
&planduration,
(es->buffers ? &bufusage : NULL)
);
#endif #endif
} }
@ -1805,7 +1877,7 @@ WrapQueryForExplainAnalyze(const char *queryString, TupleDesc tupleDesc,
appendStringInfoString(columnDef, ", "); appendStringInfoString(columnDef, ", ");
} }
Form_pg_attribute attr = &tupleDesc->attrs[columnIndex]; Form_pg_attribute attr = TupleDescAttr(tupleDesc, columnIndex);
char *attrType = format_type_extended(attr->atttypid, attr->atttypmod, char *attrType = format_type_extended(attr->atttypid, attr->atttypmod,
FORMAT_TYPE_TYPEMOD_GIVEN | FORMAT_TYPE_TYPEMOD_GIVEN |
FORMAT_TYPE_FORCE_QUALIFY); FORMAT_TYPE_FORCE_QUALIFY);
@ -2026,21 +2098,55 @@ ExplainOneQuery(Query *query, int cursorOptions,
BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start); BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start);
} }
/* 1) Capture memory counters on PG17+ only once: */
#if PG_VERSION_NUM >= PG_VERSION_17 #if PG_VERSION_NUM >= PG_VERSION_17
if (es->memory) if (es->memory)
{ {
MemoryContextSwitchTo(saved_ctx); MemoryContextSwitchTo(saved_ctx);
MemoryContextMemConsumed(planner_ctx, &mem_counters); MemoryContextMemConsumed(planner_ctx, &mem_counters);
} }
/* run it (if needed) and produce output */
ExplainOnePlan(plan, into, es, queryString, params, queryEnv,
&planduration, (es->buffers ? &bufusage : NULL),
(es->memory ? &mem_counters : NULL));
#else
/* run it (if needed) and produce output */
ExplainOnePlan(plan, into, es, queryString, params, queryEnv,
&planduration, (es->buffers ? &bufusage : NULL));
#endif #endif
#if PG_VERSION_NUM >= PG_VERSION_18
ExplainOnePlan(
plan, /* PlannedStmt *plannedstmt */
NULL, /* CachedPlan *cplan */
NULL, /* CachedPlanSource *plansource */
0, /* query_index */
into, /* IntoClause *into */
es, /* struct ExplainState *es */
queryString, /* const char *queryString */
params, /* ParamListInfo params */
queryEnv, /* QueryEnvironment *queryEnv */
&planduration, /* const instr_time *planduration */
(es->buffers ? &bufusage : NULL),
(es->memory ? &mem_counters: NULL)
);
#elif PG_VERSION_NUM >= PG_VERSION_17
ExplainOnePlan(
plan,
into,
es,
queryString,
params,
queryEnv,
&planduration,
(es->buffers ? &bufusage : NULL),
(es->memory ? &mem_counters: NULL)
);
#else
ExplainOnePlan(
plan,
into,
es,
queryString,
params,
queryEnv,
&planduration,
(es->buffers ? &bufusage : NULL)
);
#endif
} }
} }
@ -2102,9 +2208,30 @@ ExplainWorkerPlan(PlannedStmt *plannedstmt, DestReceiver *dest, ExplainState *es
UpdateActiveSnapshotCommandId(); UpdateActiveSnapshotCommandId();
/* Create a QueryDesc for the query */ /* Create a QueryDesc for the query */
queryDesc = CreateQueryDesc(plannedstmt, queryString, #if PG_VERSION_NUM >= PG_VERSION_18
GetActiveSnapshot(), InvalidSnapshot, queryDesc = CreateQueryDesc(
dest, params, queryEnv, instrument_option); plannedstmt, /* PlannedStmt *plannedstmt */
NULL, /* CachedPlan *cplan (none) */
queryString, /* const char *sourceText */
GetActiveSnapshot(), /* Snapshot snapshot */
InvalidSnapshot, /* Snapshot crosscheck_snapshot */
dest, /* DestReceiver *dest */
params, /* ParamListInfo params */
queryEnv, /* QueryEnvironment *queryEnv */
instrument_option /* int instrument_options */
);
#else
queryDesc = CreateQueryDesc(
plannedstmt, /* PlannedStmt *plannedstmt */
queryString, /* const char *sourceText */
GetActiveSnapshot(), /* Snapshot snapshot */
InvalidSnapshot, /* Snapshot crosscheck_snapshot */
dest, /* DestReceiver *dest */
params, /* ParamListInfo params */
queryEnv, /* QueryEnvironment *queryEnv */
instrument_option /* int instrument_options */
);
#endif
/* Select execution options */ /* Select execution options */
if (es->analyze) if (es->analyze)
@ -2121,7 +2248,14 @@ ExplainWorkerPlan(PlannedStmt *plannedstmt, DestReceiver *dest, ExplainState *es
ScanDirection dir = ForwardScanDirection; ScanDirection dir = ForwardScanDirection;
/* run the plan */ /* run the plan */
/* run the plan: count = 0 (all rows) */
#if PG_VERSION_NUM >= PG_VERSION_18
/* PG 18+ dropped the “execute_once” boolean */
ExecutorRun(queryDesc, dir, 0L);
#else
/* PG 17- still expect the 4th once argument */
ExecutorRun(queryDesc, dir, 0L, true); ExecutorRun(queryDesc, dir, 0L, true);
#endif
/* run cleanup too */ /* run cleanup too */
ExecutorFinish(queryDesc); ExecutorFinish(queryDesc);
@ -2560,7 +2694,7 @@ ExplainPrintSerialize(ExplainState *es, SerializeMetrics *metrics)
ExplainPropertyFloat("Time", "ms", ExplainPropertyFloat("Time", "ms",
1000.0 * INSTR_TIME_GET_DOUBLE(metrics->timeSpent), 1000.0 * INSTR_TIME_GET_DOUBLE(metrics->timeSpent),
3, es); 3, es);
ExplainPropertyUInteger("Output Volume", "kB", ExplainPropertyInteger("Output Volume", "kB",
BYTES_TO_KILOBYTES(metrics->bytesSent), es); BYTES_TO_KILOBYTES(metrics->bytesSent), es);
ExplainPropertyText("Format", format, es); ExplainPropertyText("Format", format, es);
if (es->buffers) if (es->buffers)

View File

@ -34,6 +34,14 @@
#include "utils/relcache.h" #include "utils/relcache.h"
#include "utils/syscache.h" #include "utils/syscache.h"
/*
* PG18 renamed OpBtreeInterpretation to the more generic OpIndexInterpretation,
* so make the old name an alias.
*/
#if PG_VERSION_NUM >= PG_VERSION_18
typedef OpIndexInterpretation OpBtreeInterpretation;
#endif
#include "pg_version_constants.h" #include "pg_version_constants.h"
#include "distributed/citus_clauses.h" #include "distributed/citus_clauses.h"
@ -61,6 +69,11 @@ typedef struct QualifierWalkerContext
} QualifierWalkerContext; } QualifierWalkerContext;
#if PG_VERSION_NUM >= PG_VERSION_18
#define get_op_btree_interpretation(opno) get_op_index_interpretation(opno)
#endif
/* Function pointer type definition for apply join rule functions */ /* Function pointer type definition for apply join rule functions */
typedef MultiNode *(*RuleApplyFunction) (MultiNode *leftNode, MultiNode *rightNode, typedef MultiNode *(*RuleApplyFunction) (MultiNode *leftNode, MultiNode *rightNode,
List *partitionColumnList, JoinType joinType, List *partitionColumnList, JoinType joinType,
@ -2293,7 +2306,12 @@ OperatorImplementsEquality(Oid opno)
{ {
OpBtreeInterpretation *btreeIntepretation = (OpBtreeInterpretation *) OpBtreeInterpretation *btreeIntepretation = (OpBtreeInterpretation *)
lfirst(btreeInterpretationCell); lfirst(btreeInterpretationCell);
#if PG_VERSION_NUM >= PG_VERSION_18
if (btreeIntepretation->cmptype == BTEqualStrategyNumber)
#else
if (btreeIntepretation->strategy == BTEqualStrategyNumber) if (btreeIntepretation->strategy == BTEqualStrategyNumber)
#endif
{ {
equalityOperator = true; equalityOperator = true;
break; break;

View File

@ -84,6 +84,14 @@
#include "utils/memutils.h" #include "utils/memutils.h"
#include "utils/ruleutils.h" #include "utils/ruleutils.h"
/*
* PG18 renamed OpBtreeInterpretation to the more generic OpIndexInterpretation,
* so make the old name an alias.
*/
#if PG_VERSION_NUM >= PG_VERSION_18
typedef OpIndexInterpretation OpBtreeInterpretation;
#endif
#include "pg_version_constants.h" #include "pg_version_constants.h"
#include "distributed/distributed_planner.h" #include "distributed/distributed_planner.h"
@ -177,6 +185,11 @@ typedef struct PruningInstance
bool isPartial; bool isPartial;
} PruningInstance; } PruningInstance;
#if PG_VERSION_NUM >= PG_VERSION_18
#define get_op_btree_interpretation(opno) get_op_index_interpretation(opno)
#define ROWCOMPARE_NE COMPARE_NE
#endif
/* /*
* Partial instances that need to be finished building. This is used to * Partial instances that need to be finished building. This is used to
@ -1078,7 +1091,11 @@ IsValidPartitionKeyRestriction(OpExpr *opClause)
OpBtreeInterpretation *btreeInterpretation = OpBtreeInterpretation *btreeInterpretation =
(OpBtreeInterpretation *) lfirst(btreeInterpretationCell); (OpBtreeInterpretation *) lfirst(btreeInterpretationCell);
#if PG_VERSION_NUM >= PG_VERSION_18
if (btreeInterpretation->cmptype == ROWCOMPARE_NE)
#else
if (btreeInterpretation->strategy == ROWCOMPARE_NE) if (btreeInterpretation->strategy == ROWCOMPARE_NE)
#endif
{ {
/* TODO: could add support for this, if we feel like it */ /* TODO: could add support for this, if we feel like it */
return false; return false;
@ -1130,7 +1147,11 @@ AddPartitionKeyRestrictionToInstance(ClauseWalkerContext *context, OpExpr *opCla
OpBtreeInterpretation *btreeInterpretation = OpBtreeInterpretation *btreeInterpretation =
(OpBtreeInterpretation *) lfirst(btreeInterpretationCell); (OpBtreeInterpretation *) lfirst(btreeInterpretationCell);
#if PG_VERSION_NUM >= PG_VERSION_18
switch (btreeInterpretation->cmptype)
#else
switch (btreeInterpretation->strategy) switch (btreeInterpretation->strategy)
#endif
{ {
case BTLessStrategyNumber: case BTLessStrategyNumber:
{ {
@ -1299,7 +1320,11 @@ IsValidHashRestriction(OpExpr *opClause)
OpBtreeInterpretation *btreeInterpretation = OpBtreeInterpretation *btreeInterpretation =
(OpBtreeInterpretation *) lfirst(btreeInterpretationCell); (OpBtreeInterpretation *) lfirst(btreeInterpretationCell);
#if PG_VERSION_NUM >= PG_VERSION_18
if (btreeInterpretation->cmptype == BTGreaterEqualStrategyNumber)
#else
if (btreeInterpretation->strategy == BTGreaterEqualStrategyNumber) if (btreeInterpretation->strategy == BTGreaterEqualStrategyNumber)
#endif
{ {
return true; return true;
} }

View File

@ -578,8 +578,13 @@ static const TableAmRoutine fake_methods = {
.relation_estimate_size = fake_estimate_rel_size, .relation_estimate_size = fake_estimate_rel_size,
#if PG_VERSION_NUM < PG_VERSION_18
/* these two fields were removed in PG18 */
.scan_bitmap_next_block = fake_scan_bitmap_next_block, .scan_bitmap_next_block = fake_scan_bitmap_next_block,
.scan_bitmap_next_tuple = fake_scan_bitmap_next_tuple, .scan_bitmap_next_tuple = fake_scan_bitmap_next_tuple,
#endif
.scan_sample_next_block = fake_scan_sample_next_block, .scan_sample_next_block = fake_scan_sample_next_block,
.scan_sample_next_tuple = fake_scan_sample_next_tuple .scan_sample_next_tuple = fake_scan_sample_next_tuple
}; };

View File

@ -26,7 +26,7 @@
/* tuple-descriptor attributes moved in PostgreSQL 18: */ /* tuple-descriptor attributes moved in PostgreSQL 18: */
#if PG_VERSION_NUM >= 180000 #if PG_VERSION_NUM >= PG_VERSION_18
# define Attr(tupdesc, colno) TupleDescAttr((tupdesc), (colno)) # define Attr(tupdesc, colno) TupleDescAttr((tupdesc), (colno))
#else #else
# define Attr(tupdesc, colno) ((tupdesc)->attrs[(colno)]) # define Attr(tupdesc, colno) ((tupdesc)->attrs[(colno)])

View File

@ -169,7 +169,7 @@ IsNodeWideObjectClass(ObjectClass objectClass)
* If new object classes are added and none of them are node-wide, then update * If new object classes are added and none of them are node-wide, then update
* this assertion check based on latest supported major Postgres version. * this assertion check based on latest supported major Postgres version.
*/ */
StaticAssertStmt(PG_MAJORVERSION_NUM <= 17, StaticAssertStmt(PG_MAJORVERSION_NUM <= 18,
"better to check if any of newly added ObjectClass'es are node-wide"); "better to check if any of newly added ObjectClass'es are node-wide");
switch (objectClass) switch (objectClass)