mirror of https://github.com/citusdata/citus.git
Add compatibility for PostgreSQL 18 in various source files
parent
5f4e571b70
commit
be6e79baea
|
@ -16,14 +16,14 @@
|
||||||
|
|
||||||
#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"
|
||||||
#include "catalog/pg_statistic.h"
|
#include "catalog/pg_statistic.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
|
#include "commands/explain_format.h" /* for ExplainPropertyInteger() */
|
||||||
|
#include "executor/executor.h" /* for ExecInitExprWithParams(), ExecEvalExpr() */
|
||||||
|
#include "nodes/execnodes.h" /* for ExprState, ExprContext, etc. */
|
||||||
#include "nodes/extensible.h"
|
#include "nodes/extensible.h"
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "nodes/nodeFuncs.h"
|
#include "nodes/nodeFuncs.h"
|
||||||
|
|
|
@ -11,11 +11,11 @@
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "utils/elog.h"
|
#include "utils/elog.h"
|
||||||
|
#include "utils/memutils.h" /* for TopTransactionContext */
|
||||||
|
|
||||||
#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"
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "executor/executor.h" /* for CreateExecutorState(), FreeExecutorState(), CreateExprContext(), etc. */
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
|
|
|
@ -2269,7 +2269,7 @@ ExplainWorkerPlan(PlannedStmt *plannedstmt, DestReceiver *dest, ExplainState *es
|
||||||
/* Create textual dump of plan tree */
|
/* Create textual dump of plan tree */
|
||||||
ExplainPrintPlan(es, queryDesc);
|
ExplainPrintPlan(es, queryDesc);
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_17
|
#if PG_VERSION_NUM >= PG_VERSION_17 && PG_VERSION_NUM < PG_VERSION_18
|
||||||
/* Show buffer and/or memory usage in planning */
|
/* Show buffer and/or memory usage in planning */
|
||||||
if (peek_buffer_usage(es, bufusage) || mem_counters)
|
if (peek_buffer_usage(es, bufusage) || mem_counters)
|
||||||
{
|
{
|
||||||
|
@ -2315,7 +2315,7 @@ ExplainWorkerPlan(PlannedStmt *plannedstmt, DestReceiver *dest, ExplainState *es
|
||||||
if (es->costs)
|
if (es->costs)
|
||||||
ExplainPrintJITSummary(es, queryDesc);
|
ExplainPrintJITSummary(es, queryDesc);
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_17
|
#if PG_VERSION_NUM >= PG_VERSION_17 && PG_VERSION_NUM < PG_VERSION_1
|
||||||
if (es->serialize != EXPLAIN_SERIALIZE_NONE)
|
if (es->serialize != EXPLAIN_SERIALIZE_NONE)
|
||||||
{
|
{
|
||||||
/* the SERIALIZE option requires its own tuple receiver */
|
/* the SERIALIZE option requires its own tuple receiver */
|
||||||
|
@ -2382,7 +2382,7 @@ elapsed_time(instr_time *starttime)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_17
|
#if PG_VERSION_NUM >= PG_VERSION_17 && PG_VERSION_NUM < PG_VERSION_18
|
||||||
/*
|
/*
|
||||||
* Return whether show_buffer_usage would have anything to print, if given
|
* Return whether show_buffer_usage would have anything to print, if given
|
||||||
* the same 'usage' data. Note that when the format is anything other than
|
* the same 'usage' data. Note that when the format is anything other than
|
||||||
|
|
|
@ -1418,8 +1418,24 @@ ExtractColumns(RangeTblEntry *callingRTE, int rangeTableId,
|
||||||
int subLevelsUp = 0;
|
int subLevelsUp = 0;
|
||||||
int location = -1;
|
int location = -1;
|
||||||
bool includeDroppedColumns = false;
|
bool includeDroppedColumns = false;
|
||||||
expandRTE(callingRTE, rangeTableId, subLevelsUp, location, includeDroppedColumns,
|
#if PG_VERSION_NUM >= PG_VERSION_18
|
||||||
columnNames, columnVars);
|
expandRTE(callingRTE,
|
||||||
|
rangeTableId,
|
||||||
|
subLevelsUp,
|
||||||
|
VAR_RETURNING_DEFAULT, /* new argument on PG 18+ */
|
||||||
|
location,
|
||||||
|
includeDroppedColumns,
|
||||||
|
columnNames,
|
||||||
|
columnVars);
|
||||||
|
#else
|
||||||
|
expandRTE(callingRTE,
|
||||||
|
rangeTableId,
|
||||||
|
subLevelsUp,
|
||||||
|
location,
|
||||||
|
includeDroppedColumns,
|
||||||
|
columnNames,
|
||||||
|
columnVars);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -383,6 +383,33 @@ static const struct config_enum_entry metadata_sync_mode_options[] = {
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------*
|
||||||
|
* On PG 18+ the hook signatures changed; we wrap the old Citus handlers
|
||||||
|
* in fresh functions that match the new typedefs exactly.
|
||||||
|
*----------------------------------------------------------------------*/
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_18
|
||||||
|
static bool
|
||||||
|
citus_executor_start_adapter(QueryDesc *queryDesc, int eflags)
|
||||||
|
{
|
||||||
|
/* call the original Citus hook (void) and always return “true” */
|
||||||
|
CitusExecutorStart(queryDesc, eflags);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
citus_executor_run_adapter(QueryDesc *queryDesc,
|
||||||
|
ScanDirection direction,
|
||||||
|
uint64 count)
|
||||||
|
{
|
||||||
|
/* call the original Citus hook (which still expects the old 4-arg form) */
|
||||||
|
CitusExecutorRun(queryDesc, direction, count, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* shared library initialization function */
|
/* shared library initialization function */
|
||||||
void
|
void
|
||||||
_PG_init(void)
|
_PG_init(void)
|
||||||
|
@ -457,8 +484,13 @@ _PG_init(void)
|
||||||
set_rel_pathlist_hook = multi_relation_restriction_hook;
|
set_rel_pathlist_hook = multi_relation_restriction_hook;
|
||||||
get_relation_info_hook = multi_get_relation_info_hook;
|
get_relation_info_hook = multi_get_relation_info_hook;
|
||||||
set_join_pathlist_hook = multi_join_restriction_hook;
|
set_join_pathlist_hook = multi_join_restriction_hook;
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_18
|
||||||
|
ExecutorStart_hook = citus_executor_start_adapter;
|
||||||
|
ExecutorRun_hook = citus_executor_run_adapter;
|
||||||
|
#else
|
||||||
ExecutorStart_hook = CitusExecutorStart;
|
ExecutorStart_hook = CitusExecutorStart;
|
||||||
ExecutorRun_hook = CitusExecutorRun;
|
ExecutorRun_hook = CitusExecutorRun;
|
||||||
|
#endif
|
||||||
ExplainOneQuery_hook = CitusExplainOneQuery;
|
ExplainOneQuery_hook = CitusExplainOneQuery;
|
||||||
prev_ExecutorEnd = ExecutorEnd_hook;
|
prev_ExecutorEnd = ExecutorEnd_hook;
|
||||||
ExecutorEnd_hook = CitusAttributeToEnd;
|
ExecutorEnd_hook = CitusAttributeToEnd;
|
||||||
|
|
|
@ -485,6 +485,7 @@ fake_estimate_rel_size(Relation rel, int32 *attr_widths,
|
||||||
* Executor related callbacks for the fake AM
|
* Executor related callbacks for the fake AM
|
||||||
* ------------------------------------------------------------------------
|
* ------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
#if PG_VERSION_NUM < PG_VERSION_18
|
||||||
static bool
|
static bool
|
||||||
fake_scan_bitmap_next_block(TableScanDesc scan,
|
fake_scan_bitmap_next_block(TableScanDesc scan,
|
||||||
TBMIterateResult *tbmres)
|
TBMIterateResult *tbmres)
|
||||||
|
@ -502,6 +503,8 @@ fake_scan_bitmap_next_tuple(TableScanDesc scan,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
fake_scan_sample_next_block(TableScanDesc scan,
|
fake_scan_sample_next_block(TableScanDesc scan,
|
||||||
SampleScanState *scanstate)
|
SampleScanState *scanstate)
|
||||||
|
|
|
@ -91,11 +91,23 @@ FakeGetForeignPaths(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid)
|
||||||
Cost startup_cost = 0;
|
Cost startup_cost = 0;
|
||||||
Cost total_cost = startup_cost + baserel->rows;
|
Cost total_cost = startup_cost + baserel->rows;
|
||||||
|
|
||||||
add_path(baserel, (Path *) create_foreignscan_path_compat(root, baserel, NULL,
|
add_path(baserel,
|
||||||
|
(Path *) create_foreignscan_path_compat(
|
||||||
|
root,
|
||||||
|
baserel,
|
||||||
|
baserel->reltarget, /* ← PathTarget* is the rel’s reltarget */
|
||||||
baserel->rows,
|
baserel->rows,
|
||||||
startup_cost, total_cost,
|
0, /* ← disabled_nodes (only used in PG18+) */
|
||||||
NIL,
|
startup_cost,
|
||||||
NULL, NULL, NIL, NIL));
|
total_cost,
|
||||||
|
NIL, /* pathkeys */
|
||||||
|
NULL, /* required_outer */
|
||||||
|
NULL, /* fdw_outerpath */
|
||||||
|
NIL, /* fdw_restrictinfo (PG18+) */
|
||||||
|
NIL, /* fdw_private */
|
||||||
|
NIL /* fdw_scan_tlist (PG15–17) */
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "common/hashfn.h"
|
#include "common/hashfn.h"
|
||||||
#include "utils/hsearch.h"
|
#include "utils/hsearch.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/memutils.h" /* for ALLOCSET_DEFAULT_MINSIZE, _INITSIZE, _MAXSIZE */
|
||||||
|
|
||||||
#include "pg_version_constants.h"
|
#include "pg_version_constants.h"
|
||||||
|
|
||||||
|
|
|
@ -918,7 +918,7 @@ TypecheckWorkerPartialAggArgType(FunctionCallInfo fcinfo, StypeBox *box)
|
||||||
true, 'i', &argtypesNull);
|
true, 'i', &argtypesNull);
|
||||||
Assert(!argtypesNull);
|
Assert(!argtypesNull);
|
||||||
TupleDesc tupleDesc = box->aggregationArgumentContext->tupleDesc;
|
TupleDesc tupleDesc = box->aggregationArgumentContext->tupleDesc;
|
||||||
if (argType != tupleDesc->attrs[aggregateArgIndex].atttypid)
|
if (argType != TupleDescAttr(tupleDesc, aggregateArgIndex)->atttypid)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1906,7 +1906,32 @@ ExecuteSqlString(const char *sql)
|
||||||
|
|
||||||
/* Don't display the portal in pg_cursors */
|
/* Don't display the portal in pg_cursors */
|
||||||
portal->visible = false;
|
portal->visible = false;
|
||||||
PortalDefineQuery(portal, NULL, sql, commandTag, plantree_list, NULL);
|
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_18
|
||||||
|
|
||||||
|
/* PG18+ added a seventh “plansource” argument */
|
||||||
|
PortalDefineQuery(
|
||||||
|
portal,
|
||||||
|
NULL, /* no prepared‐stmt name */
|
||||||
|
sql, /* the query text */
|
||||||
|
commandTag, /* the CommandTag */
|
||||||
|
plantree_list, /* List of PlannedStmt* */
|
||||||
|
NULL, /* no CachedPlan */
|
||||||
|
NULL /* no CachedPlanSource */
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* PG17-: six‐arg signature */
|
||||||
|
PortalDefineQuery(
|
||||||
|
portal,
|
||||||
|
NULL, /* no prepared‐stmt name */
|
||||||
|
sql, /* the query text */
|
||||||
|
commandTag, /* the CommandTag */
|
||||||
|
plantree_list, /* List of PlannedStmt* */
|
||||||
|
NULL /* no CachedPlan */
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
PortalStart(portal, NULL, 0, InvalidSnapshot);
|
PortalStart(portal, NULL, 0, InvalidSnapshot);
|
||||||
int16 format[] = { 1 };
|
int16 format[] = { 1 };
|
||||||
PortalSetResultFormat(portal, lengthof(format), format); /* binary format */
|
PortalSetResultFormat(portal, lengthof(format), format); /* binary format */
|
||||||
|
@ -1923,7 +1948,28 @@ ExecuteSqlString(const char *sql)
|
||||||
|
|
||||||
/* Here's where we actually execute the command. */
|
/* Here's where we actually execute the command. */
|
||||||
QueryCompletion qc = { 0 };
|
QueryCompletion qc = { 0 };
|
||||||
(void) PortalRun(portal, FETCH_ALL, isTopLevel, true, receiver, receiver, &qc);
|
|
||||||
|
/* Execute the portal, dropping the `run_once` arg on PG18+ */
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_18
|
||||||
|
(void) PortalRun(
|
||||||
|
portal,
|
||||||
|
FETCH_ALL, /* count */
|
||||||
|
isTopLevel, /* isTopLevel */
|
||||||
|
receiver, /* DestReceiver *dest */
|
||||||
|
receiver, /* DestReceiver *altdest */
|
||||||
|
&qc /* QueryCompletion *qc */
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
(void) PortalRun(
|
||||||
|
portal,
|
||||||
|
FETCH_ALL, /* count */
|
||||||
|
isTopLevel, /* isTopLevel */
|
||||||
|
true, /* run_once */
|
||||||
|
receiver, /* DestReceiver *dest */
|
||||||
|
receiver, /* DestReceiver *altdest */
|
||||||
|
&qc /* QueryCompletion *qc */
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Clean up the receiver. */
|
/* Clean up the receiver. */
|
||||||
(*receiver->rDestroy)(receiver);
|
(*receiver->rDestroy)(receiver);
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "parser/parse_type.h"
|
#include "parser/parse_type.h"
|
||||||
#include "storage/large_object.h"
|
#include "storage/large_object.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/memutils.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
#include "distributed/citus_depended_object.h"
|
#include "distributed/citus_depended_object.h"
|
||||||
|
|
|
@ -324,6 +324,16 @@ GetRangeTblKind(RangeTblEntry *rte)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_18
|
||||||
|
|
||||||
|
/* new in PG18: GROUP RTE, just map it straight through */
|
||||||
|
case RTE_GROUP:
|
||||||
|
{
|
||||||
|
rteKind = (CitusRTEKind) rte->rtekind;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
case RTE_FUNCTION:
|
case RTE_FUNCTION:
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1362,9 +1362,21 @@ DeleteColocationGroupLocally(uint32 colocationId)
|
||||||
* 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 =
|
#if PG_VERSION_NUM >= PG_VERSION_18
|
||||||
index_open(RelationGetPrimaryKeyIndex(pgDistColocation),
|
|
||||||
AccessShareLock);
|
/* PG 18+ expects a second “deferrable_ok” flag */
|
||||||
|
Relation replicaIndex = index_open(
|
||||||
|
RelationGetPrimaryKeyIndex(pgDistColocation, false),
|
||||||
|
AccessShareLock
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* PG 17- had a single-arg signature */
|
||||||
|
Relation replicaIndex = index_open(
|
||||||
|
RelationGetPrimaryKeyIndex(pgDistColocation),
|
||||||
|
AccessShareLock
|
||||||
|
);
|
||||||
|
#endif
|
||||||
simple_heap_delete(pgDistColocation, &(heapTuple->t_self));
|
simple_heap_delete(pgDistColocation, &(heapTuple->t_self));
|
||||||
|
|
||||||
CitusInvalidateRelcacheByRelid(DistColocationRelationId());
|
CitusInvalidateRelcacheByRelid(DistColocationRelationId());
|
||||||
|
|
|
@ -384,9 +384,71 @@ getStxstattarget_compat(HeapTuple tup)
|
||||||
|
|
||||||
#define matched_compat(a) (a->matchKind == MERGE_WHEN_MATCHED)
|
#define matched_compat(a) (a->matchKind == MERGE_WHEN_MATCHED)
|
||||||
|
|
||||||
#define create_foreignscan_path_compat(a, b, c, d, e, f, g, h, i, j, \
|
#include "nodes/pg_list.h" /* for List */
|
||||||
k) create_foreignscan_path(a, b, c, d, e, f, g, h, \
|
#include "nodes/plannodes.h" /* for ForeignScan */
|
||||||
i, j, k)
|
#include "optimizer/pathnode.h" /* for create_foreignscan_path, ForeignPath */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A single entry point for Citus code to build ForeignPath
|
||||||
|
* using the *full* superset of parameters:
|
||||||
|
*
|
||||||
|
* root, rel, target, rows,
|
||||||
|
* disabled_nodes, startup_cost, total_cost,
|
||||||
|
* pathkeys, required_outer,
|
||||||
|
* fdw_outerpath, fdw_restrictinfo,
|
||||||
|
* fdw_private, fdw_scan_tlist
|
||||||
|
*/
|
||||||
|
static inline ForeignPath *
|
||||||
|
create_foreignscan_path_compat(PlannerInfo *root,
|
||||||
|
RelOptInfo *rel,
|
||||||
|
PathTarget *target,
|
||||||
|
double rows,
|
||||||
|
int disabled_nodes,
|
||||||
|
Cost startup_cost,
|
||||||
|
Cost total_cost,
|
||||||
|
List *pathkeys,
|
||||||
|
Relids required_outer,
|
||||||
|
Path *fdw_outerpath,
|
||||||
|
List *fdw_restrictinfo,
|
||||||
|
List *fdw_private,
|
||||||
|
List *fdw_scan_tlist)
|
||||||
|
{
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_18
|
||||||
|
|
||||||
|
/* PG 18+ signature: 12 args */
|
||||||
|
return create_foreignscan_path(
|
||||||
|
root,
|
||||||
|
rel,
|
||||||
|
target,
|
||||||
|
rows,
|
||||||
|
disabled_nodes,
|
||||||
|
startup_cost,
|
||||||
|
total_cost,
|
||||||
|
pathkeys,
|
||||||
|
required_outer,
|
||||||
|
fdw_outerpath,
|
||||||
|
fdw_restrictinfo,
|
||||||
|
fdw_private
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* PG 17- signature: 11 args */
|
||||||
|
return create_foreignscan_path(
|
||||||
|
root,
|
||||||
|
rel,
|
||||||
|
target,
|
||||||
|
rows,
|
||||||
|
startup_cost,
|
||||||
|
total_cost,
|
||||||
|
pathkeys,
|
||||||
|
required_outer,
|
||||||
|
fdw_outerpath,
|
||||||
|
fdw_private,
|
||||||
|
fdw_scan_tlist
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define getProcNo_compat(a) (a->vxid.procNumber)
|
#define getProcNo_compat(a) (a->vxid.procNumber)
|
||||||
#define getLxid_compat(a) (a->vxid.lxid)
|
#define getLxid_compat(a) (a->vxid.lxid)
|
||||||
|
@ -421,10 +483,6 @@ getStxstattarget_compat(HeapTuple tup)
|
||||||
|
|
||||||
#define matched_compat(a) (a->matched)
|
#define matched_compat(a) (a->matched)
|
||||||
|
|
||||||
#define create_foreignscan_path_compat(a, b, c, d, e, f, g, h, i, j, \
|
|
||||||
k) create_foreignscan_path(a, b, c, d, e, f, g, h, \
|
|
||||||
i, k)
|
|
||||||
|
|
||||||
#define getProcNo_compat(a) (a->pgprocno)
|
#define getProcNo_compat(a) (a->pgprocno)
|
||||||
#define getLxid_compat(a) (a->lxid)
|
#define getLxid_compat(a) (a->lxid)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue