summaryrefslogtreecommitdiffstats
path: root/src/backend/nodes/readfuncs.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:19:15 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:19:15 +0000
commit6eb9c5a5657d1fe77b55cc261450f3538d35a94d (patch)
tree657d8194422a5daccecfd42d654b8a245ef7b4c8 /src/backend/nodes/readfuncs.c
parentInitial commit. (diff)
downloadpostgresql-13-6eb9c5a5657d1fe77b55cc261450f3538d35a94d.tar.xz
postgresql-13-6eb9c5a5657d1fe77b55cc261450f3538d35a94d.zip
Adding upstream version 13.4.upstream/13.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/backend/nodes/readfuncs.c')
-rw-r--r--src/backend/nodes/readfuncs.c3048
1 files changed, 3048 insertions, 0 deletions
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
new file mode 100644
index 0000000..42050ab
--- /dev/null
+++ b/src/backend/nodes/readfuncs.c
@@ -0,0 +1,3048 @@
+/*-------------------------------------------------------------------------
+ *
+ * readfuncs.c
+ * Reader functions for Postgres tree nodes.
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * src/backend/nodes/readfuncs.c
+ *
+ * NOTES
+ * Path nodes do not have any readfuncs support, because we never
+ * have occasion to read them in. (There was once code here that
+ * claimed to read them, but it was broken as well as unused.) We
+ * never read executor state trees, either.
+ *
+ * Parse location fields are written out by outfuncs.c, but only for
+ * debugging use. When reading a location field, we normally discard
+ * the stored value and set the location field to -1 (ie, "unknown").
+ * This is because nodes coming from a stored rule should not be thought
+ * to have a known location in the current query's text.
+ * However, if restore_location_fields is true, we do restore location
+ * fields from the string. This is currently intended only for use by the
+ * WRITE_READ_PARSE_PLAN_TREES test code, which doesn't want to cause
+ * any change in the node contents.
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include <math.h>
+
+#include "fmgr.h"
+#include "miscadmin.h"
+#include "nodes/extensible.h"
+#include "nodes/parsenodes.h"
+#include "nodes/plannodes.h"
+#include "nodes/readfuncs.h"
+#include "utils/builtins.h"
+
+
+/*
+ * Macros to simplify reading of different kinds of fields. Use these
+ * wherever possible to reduce the chance for silly typos. Note that these
+ * hard-wire conventions about the names of the local variables in a Read
+ * routine.
+ */
+
+/* Macros for declaring appropriate local variables */
+
+/* A few guys need only local_node */
+#define READ_LOCALS_NO_FIELDS(nodeTypeName) \
+ nodeTypeName *local_node = makeNode(nodeTypeName)
+
+/* And a few guys need only the pg_strtok support fields */
+#define READ_TEMP_LOCALS() \
+ const char *token; \
+ int length
+
+/* ... but most need both */
+#define READ_LOCALS(nodeTypeName) \
+ READ_LOCALS_NO_FIELDS(nodeTypeName); \
+ READ_TEMP_LOCALS()
+
+/* Read an integer field (anything written as ":fldname %d") */
+#define READ_INT_FIELD(fldname) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ token = pg_strtok(&length); /* get field value */ \
+ local_node->fldname = atoi(token)
+
+/* Read an unsigned integer field (anything written as ":fldname %u") */
+#define READ_UINT_FIELD(fldname) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ token = pg_strtok(&length); /* get field value */ \
+ local_node->fldname = atoui(token)
+
+/* Read an unsigned integer field (anything written using UINT64_FORMAT) */
+#define READ_UINT64_FIELD(fldname) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ token = pg_strtok(&length); /* get field value */ \
+ local_node->fldname = pg_strtouint64(token, NULL, 10)
+
+/* Read a long integer field (anything written as ":fldname %ld") */
+#define READ_LONG_FIELD(fldname) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ token = pg_strtok(&length); /* get field value */ \
+ local_node->fldname = atol(token)
+
+/* Read an OID field (don't hard-wire assumption that OID is same as uint) */
+#define READ_OID_FIELD(fldname) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ token = pg_strtok(&length); /* get field value */ \
+ local_node->fldname = atooid(token)
+
+/* Read a char field (ie, one ascii character) */
+#define READ_CHAR_FIELD(fldname) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ token = pg_strtok(&length); /* get field value */ \
+ /* avoid overhead of calling debackslash() for one char */ \
+ local_node->fldname = (length == 0) ? '\0' : (token[0] == '\\' ? token[1] : token[0])
+
+/* Read an enumerated-type field that was written as an integer code */
+#define READ_ENUM_FIELD(fldname, enumtype) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ token = pg_strtok(&length); /* get field value */ \
+ local_node->fldname = (enumtype) atoi(token)
+
+/* Read a float field */
+#define READ_FLOAT_FIELD(fldname) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ token = pg_strtok(&length); /* get field value */ \
+ local_node->fldname = atof(token)
+
+/* Read a boolean field */
+#define READ_BOOL_FIELD(fldname) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ token = pg_strtok(&length); /* get field value */ \
+ local_node->fldname = strtobool(token)
+
+/* Read a character-string field */
+#define READ_STRING_FIELD(fldname) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ token = pg_strtok(&length); /* get field value */ \
+ local_node->fldname = nullable_string(token, length)
+
+/* Read a parse location field (and possibly throw away the value) */
+#ifdef WRITE_READ_PARSE_PLAN_TREES
+#define READ_LOCATION_FIELD(fldname) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ token = pg_strtok(&length); /* get field value */ \
+ local_node->fldname = restore_location_fields ? atoi(token) : -1
+#else
+#define READ_LOCATION_FIELD(fldname) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ token = pg_strtok(&length); /* get field value */ \
+ (void) token; /* in case not used elsewhere */ \
+ local_node->fldname = -1 /* set field to "unknown" */
+#endif
+
+/* Read a Node field */
+#define READ_NODE_FIELD(fldname) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ (void) token; /* in case not used elsewhere */ \
+ local_node->fldname = nodeRead(NULL, 0)
+
+/* Read a bitmapset field */
+#define READ_BITMAPSET_FIELD(fldname) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ (void) token; /* in case not used elsewhere */ \
+ local_node->fldname = _readBitmapset()
+
+/* Read an attribute number array */
+#define READ_ATTRNUMBER_ARRAY(fldname, len) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ local_node->fldname = readAttrNumberCols(len)
+
+/* Read an oid array */
+#define READ_OID_ARRAY(fldname, len) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ local_node->fldname = readOidCols(len)
+
+/* Read an int array */
+#define READ_INT_ARRAY(fldname, len) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ local_node->fldname = readIntCols(len)
+
+/* Read a bool array */
+#define READ_BOOL_ARRAY(fldname, len) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ local_node->fldname = readBoolCols(len)
+
+/* Routine exit */
+#define READ_DONE() \
+ return local_node
+
+
+/*
+ * NOTE: use atoi() to read values written with %d, or atoui() to read
+ * values written with %u in outfuncs.c. An exception is OID values,
+ * for which use atooid(). (As of 7.1, outfuncs.c writes OIDs as %u,
+ * but this will probably change in the future.)
+ */
+#define atoui(x) ((unsigned int) strtoul((x), NULL, 10))
+
+#define strtobool(x) ((*(x) == 't') ? true : false)
+
+#define nullable_string(token,length) \
+ ((length) == 0 ? NULL : debackslash(token, length))
+
+
+/*
+ * _readBitmapset
+ */
+static Bitmapset *
+_readBitmapset(void)
+{
+ Bitmapset *result = NULL;
+
+ READ_TEMP_LOCALS();
+
+ token = pg_strtok(&length);
+ if (token == NULL)
+ elog(ERROR, "incomplete Bitmapset structure");
+ if (length != 1 || token[0] != '(')
+ elog(ERROR, "unrecognized token: \"%.*s\"", length, token);
+
+ token = pg_strtok(&length);
+ if (token == NULL)
+ elog(ERROR, "incomplete Bitmapset structure");
+ if (length != 1 || token[0] != 'b')
+ elog(ERROR, "unrecognized token: \"%.*s\"", length, token);
+
+ for (;;)
+ {
+ int val;
+ char *endptr;
+
+ token = pg_strtok(&length);
+ if (token == NULL)
+ elog(ERROR, "unterminated Bitmapset structure");
+ if (length == 1 && token[0] == ')')
+ break;
+ val = (int) strtol(token, &endptr, 10);
+ if (endptr != token + length)
+ elog(ERROR, "unrecognized integer: \"%.*s\"", length, token);
+ result = bms_add_member(result, val);
+ }
+
+ return result;
+}
+
+/*
+ * for use by extensions which define extensible nodes
+ */
+Bitmapset *
+readBitmapset(void)
+{
+ return _readBitmapset();
+}
+
+/*
+ * _readQuery
+ */
+static Query *
+_readQuery(void)
+{
+ READ_LOCALS(Query);
+
+ READ_ENUM_FIELD(commandType, CmdType);
+ READ_ENUM_FIELD(querySource, QuerySource);
+ local_node->queryId = UINT64CONST(0); /* not saved in output format */
+ READ_BOOL_FIELD(canSetTag);
+ READ_NODE_FIELD(utilityStmt);
+ READ_INT_FIELD(resultRelation);
+ READ_BOOL_FIELD(hasAggs);
+ READ_BOOL_FIELD(hasWindowFuncs);
+ READ_BOOL_FIELD(hasTargetSRFs);
+ READ_BOOL_FIELD(hasSubLinks);
+ READ_BOOL_FIELD(hasDistinctOn);
+ READ_BOOL_FIELD(hasRecursive);
+ READ_BOOL_FIELD(hasModifyingCTE);
+ READ_BOOL_FIELD(hasForUpdate);
+ READ_BOOL_FIELD(hasRowSecurity);
+ READ_NODE_FIELD(cteList);
+ READ_NODE_FIELD(rtable);
+ READ_NODE_FIELD(jointree);
+ READ_NODE_FIELD(targetList);
+ READ_ENUM_FIELD(override, OverridingKind);
+ READ_NODE_FIELD(onConflict);
+ READ_NODE_FIELD(returningList);
+ READ_NODE_FIELD(groupClause);
+ READ_NODE_FIELD(groupingSets);
+ READ_NODE_FIELD(havingQual);
+ READ_NODE_FIELD(windowClause);
+ READ_NODE_FIELD(distinctClause);
+ READ_NODE_FIELD(sortClause);
+ READ_NODE_FIELD(limitOffset);
+ READ_NODE_FIELD(limitCount);
+ READ_ENUM_FIELD(limitOption, LimitOption);
+ READ_NODE_FIELD(rowMarks);
+ READ_NODE_FIELD(setOperations);
+ READ_NODE_FIELD(constraintDeps);
+ READ_NODE_FIELD(withCheckOptions);
+ READ_LOCATION_FIELD(stmt_location);
+ READ_INT_FIELD(stmt_len);
+
+ READ_DONE();
+}
+
+/*
+ * _readNotifyStmt
+ */
+static NotifyStmt *
+_readNotifyStmt(void)
+{
+ READ_LOCALS(NotifyStmt);
+
+ READ_STRING_FIELD(conditionname);
+ READ_STRING_FIELD(payload);
+
+ READ_DONE();
+}
+
+/*
+ * _readDeclareCursorStmt
+ */
+static DeclareCursorStmt *
+_readDeclareCursorStmt(void)
+{
+ READ_LOCALS(DeclareCursorStmt);
+
+ READ_STRING_FIELD(portalname);
+ READ_INT_FIELD(options);
+ READ_NODE_FIELD(query);
+
+ READ_DONE();
+}
+
+/*
+ * _readWithCheckOption
+ */
+static WithCheckOption *
+_readWithCheckOption(void)
+{
+ READ_LOCALS(WithCheckOption);
+
+ READ_ENUM_FIELD(kind, WCOKind);
+ READ_STRING_FIELD(relname);
+ READ_STRING_FIELD(polname);
+ READ_NODE_FIELD(qual);
+ READ_BOOL_FIELD(cascaded);
+
+ READ_DONE();
+}
+
+/*
+ * _readSortGroupClause
+ */
+static SortGroupClause *
+_readSortGroupClause(void)
+{
+ READ_LOCALS(SortGroupClause);
+
+ READ_UINT_FIELD(tleSortGroupRef);
+ READ_OID_FIELD(eqop);
+ READ_OID_FIELD(sortop);
+ READ_BOOL_FIELD(nulls_first);
+ READ_BOOL_FIELD(hashable);
+
+ READ_DONE();
+}
+
+/*
+ * _readGroupingSet
+ */
+static GroupingSet *
+_readGroupingSet(void)
+{
+ READ_LOCALS(GroupingSet);
+
+ READ_ENUM_FIELD(kind, GroupingSetKind);
+ READ_NODE_FIELD(content);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readWindowClause
+ */
+static WindowClause *
+_readWindowClause(void)
+{
+ READ_LOCALS(WindowClause);
+
+ READ_STRING_FIELD(name);
+ READ_STRING_FIELD(refname);
+ READ_NODE_FIELD(partitionClause);
+ READ_NODE_FIELD(orderClause);
+ READ_INT_FIELD(frameOptions);
+ READ_NODE_FIELD(startOffset);
+ READ_NODE_FIELD(endOffset);
+ READ_OID_FIELD(startInRangeFunc);
+ READ_OID_FIELD(endInRangeFunc);
+ READ_OID_FIELD(inRangeColl);
+ READ_BOOL_FIELD(inRangeAsc);
+ READ_BOOL_FIELD(inRangeNullsFirst);
+ READ_UINT_FIELD(winref);
+ READ_BOOL_FIELD(copiedOrder);
+
+ READ_DONE();
+}
+
+/*
+ * _readRowMarkClause
+ */
+static RowMarkClause *
+_readRowMarkClause(void)
+{
+ READ_LOCALS(RowMarkClause);
+
+ READ_UINT_FIELD(rti);
+ READ_ENUM_FIELD(strength, LockClauseStrength);
+ READ_ENUM_FIELD(waitPolicy, LockWaitPolicy);
+ READ_BOOL_FIELD(pushedDown);
+
+ READ_DONE();
+}
+
+/*
+ * _readCommonTableExpr
+ */
+static CommonTableExpr *
+_readCommonTableExpr(void)
+{
+ READ_LOCALS(CommonTableExpr);
+
+ READ_STRING_FIELD(ctename);
+ READ_NODE_FIELD(aliascolnames);
+ READ_ENUM_FIELD(ctematerialized, CTEMaterialize);
+ READ_NODE_FIELD(ctequery);
+ READ_LOCATION_FIELD(location);
+ READ_BOOL_FIELD(cterecursive);
+ READ_INT_FIELD(cterefcount);
+ READ_NODE_FIELD(ctecolnames);
+ READ_NODE_FIELD(ctecoltypes);
+ READ_NODE_FIELD(ctecoltypmods);
+ READ_NODE_FIELD(ctecolcollations);
+
+ READ_DONE();
+}
+
+/*
+ * _readSetOperationStmt
+ */
+static SetOperationStmt *
+_readSetOperationStmt(void)
+{
+ READ_LOCALS(SetOperationStmt);
+
+ READ_ENUM_FIELD(op, SetOperation);
+ READ_BOOL_FIELD(all);
+ READ_NODE_FIELD(larg);
+ READ_NODE_FIELD(rarg);
+ READ_NODE_FIELD(colTypes);
+ READ_NODE_FIELD(colTypmods);
+ READ_NODE_FIELD(colCollations);
+ READ_NODE_FIELD(groupClauses);
+
+ READ_DONE();
+}
+
+
+/*
+ * Stuff from primnodes.h.
+ */
+
+static Alias *
+_readAlias(void)
+{
+ READ_LOCALS(Alias);
+
+ READ_STRING_FIELD(aliasname);
+ READ_NODE_FIELD(colnames);
+
+ READ_DONE();
+}
+
+static RangeVar *
+_readRangeVar(void)
+{
+ READ_LOCALS(RangeVar);
+
+ local_node->catalogname = NULL; /* not currently saved in output format */
+
+ READ_STRING_FIELD(schemaname);
+ READ_STRING_FIELD(relname);
+ READ_BOOL_FIELD(inh);
+ READ_CHAR_FIELD(relpersistence);
+ READ_NODE_FIELD(alias);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readTableFunc
+ */
+static TableFunc *
+_readTableFunc(void)
+{
+ READ_LOCALS(TableFunc);
+
+ READ_NODE_FIELD(ns_uris);
+ READ_NODE_FIELD(ns_names);
+ READ_NODE_FIELD(docexpr);
+ READ_NODE_FIELD(rowexpr);
+ READ_NODE_FIELD(colnames);
+ READ_NODE_FIELD(coltypes);
+ READ_NODE_FIELD(coltypmods);
+ READ_NODE_FIELD(colcollations);
+ READ_NODE_FIELD(colexprs);
+ READ_NODE_FIELD(coldefexprs);
+ READ_BITMAPSET_FIELD(notnulls);
+ READ_INT_FIELD(ordinalitycol);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+static IntoClause *
+_readIntoClause(void)
+{
+ READ_LOCALS(IntoClause);
+
+ READ_NODE_FIELD(rel);
+ READ_NODE_FIELD(colNames);
+ READ_STRING_FIELD(accessMethod);
+ READ_NODE_FIELD(options);
+ READ_ENUM_FIELD(onCommit, OnCommitAction);
+ READ_STRING_FIELD(tableSpaceName);
+ READ_NODE_FIELD(viewQuery);
+ READ_BOOL_FIELD(skipData);
+
+ READ_DONE();
+}
+
+/*
+ * _readVar
+ */
+static Var *
+_readVar(void)
+{
+ READ_LOCALS(Var);
+
+ READ_UINT_FIELD(varno);
+ READ_INT_FIELD(varattno);
+ READ_OID_FIELD(vartype);
+ READ_INT_FIELD(vartypmod);
+ READ_OID_FIELD(varcollid);
+ READ_UINT_FIELD(varlevelsup);
+ READ_UINT_FIELD(varnosyn);
+ READ_INT_FIELD(varattnosyn);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readConst
+ */
+static Const *
+_readConst(void)
+{
+ READ_LOCALS(Const);
+
+ READ_OID_FIELD(consttype);
+ READ_INT_FIELD(consttypmod);
+ READ_OID_FIELD(constcollid);
+ READ_INT_FIELD(constlen);
+ READ_BOOL_FIELD(constbyval);
+ READ_BOOL_FIELD(constisnull);
+ READ_LOCATION_FIELD(location);
+
+ token = pg_strtok(&length); /* skip :constvalue */
+ if (local_node->constisnull)
+ token = pg_strtok(&length); /* skip "<>" */
+ else
+ local_node->constvalue = readDatum(local_node->constbyval);
+
+ READ_DONE();
+}
+
+/*
+ * _readParam
+ */
+static Param *
+_readParam(void)
+{
+ READ_LOCALS(Param);
+
+ READ_ENUM_FIELD(paramkind, ParamKind);
+ READ_INT_FIELD(paramid);
+ READ_OID_FIELD(paramtype);
+ READ_INT_FIELD(paramtypmod);
+ READ_OID_FIELD(paramcollid);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readAggref
+ */
+static Aggref *
+_readAggref(void)
+{
+ READ_LOCALS(Aggref);
+
+ READ_OID_FIELD(aggfnoid);
+ READ_OID_FIELD(aggtype);
+ READ_OID_FIELD(aggcollid);
+ READ_OID_FIELD(inputcollid);
+ READ_OID_FIELD(aggtranstype);
+ READ_NODE_FIELD(aggargtypes);
+ READ_NODE_FIELD(aggdirectargs);
+ READ_NODE_FIELD(args);
+ READ_NODE_FIELD(aggorder);
+ READ_NODE_FIELD(aggdistinct);
+ READ_NODE_FIELD(aggfilter);
+ READ_BOOL_FIELD(aggstar);
+ READ_BOOL_FIELD(aggvariadic);
+ READ_CHAR_FIELD(aggkind);
+ READ_UINT_FIELD(agglevelsup);
+ READ_ENUM_FIELD(aggsplit, AggSplit);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readGroupingFunc
+ */
+static GroupingFunc *
+_readGroupingFunc(void)
+{
+ READ_LOCALS(GroupingFunc);
+
+ READ_NODE_FIELD(args);
+ READ_NODE_FIELD(refs);
+ READ_NODE_FIELD(cols);
+ READ_UINT_FIELD(agglevelsup);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readWindowFunc
+ */
+static WindowFunc *
+_readWindowFunc(void)
+{
+ READ_LOCALS(WindowFunc);
+
+ READ_OID_FIELD(winfnoid);
+ READ_OID_FIELD(wintype);
+ READ_OID_FIELD(wincollid);
+ READ_OID_FIELD(inputcollid);
+ READ_NODE_FIELD(args);
+ READ_NODE_FIELD(aggfilter);
+ READ_UINT_FIELD(winref);
+ READ_BOOL_FIELD(winstar);
+ READ_BOOL_FIELD(winagg);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readSubscriptingRef
+ */
+static SubscriptingRef *
+_readSubscriptingRef(void)
+{
+ READ_LOCALS(SubscriptingRef);
+
+ READ_OID_FIELD(refcontainertype);
+ READ_OID_FIELD(refelemtype);
+ READ_INT_FIELD(reftypmod);
+ READ_OID_FIELD(refcollid);
+ READ_NODE_FIELD(refupperindexpr);
+ READ_NODE_FIELD(reflowerindexpr);
+ READ_NODE_FIELD(refexpr);
+ READ_NODE_FIELD(refassgnexpr);
+
+ READ_DONE();
+}
+
+/*
+ * _readFuncExpr
+ */
+static FuncExpr *
+_readFuncExpr(void)
+{
+ READ_LOCALS(FuncExpr);
+
+ READ_OID_FIELD(funcid);
+ READ_OID_FIELD(funcresulttype);
+ READ_BOOL_FIELD(funcretset);
+ READ_BOOL_FIELD(funcvariadic);
+ READ_ENUM_FIELD(funcformat, CoercionForm);
+ READ_OID_FIELD(funccollid);
+ READ_OID_FIELD(inputcollid);
+ READ_NODE_FIELD(args);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readNamedArgExpr
+ */
+static NamedArgExpr *
+_readNamedArgExpr(void)
+{
+ READ_LOCALS(NamedArgExpr);
+
+ READ_NODE_FIELD(arg);
+ READ_STRING_FIELD(name);
+ READ_INT_FIELD(argnumber);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readOpExpr
+ */
+static OpExpr *
+_readOpExpr(void)
+{
+ READ_LOCALS(OpExpr);
+
+ READ_OID_FIELD(opno);
+ READ_OID_FIELD(opfuncid);
+ READ_OID_FIELD(opresulttype);
+ READ_BOOL_FIELD(opretset);
+ READ_OID_FIELD(opcollid);
+ READ_OID_FIELD(inputcollid);
+ READ_NODE_FIELD(args);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readDistinctExpr
+ */
+static DistinctExpr *
+_readDistinctExpr(void)
+{
+ READ_LOCALS(DistinctExpr);
+
+ READ_OID_FIELD(opno);
+ READ_OID_FIELD(opfuncid);
+ READ_OID_FIELD(opresulttype);
+ READ_BOOL_FIELD(opretset);
+ READ_OID_FIELD(opcollid);
+ READ_OID_FIELD(inputcollid);
+ READ_NODE_FIELD(args);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readNullIfExpr
+ */
+static NullIfExpr *
+_readNullIfExpr(void)
+{
+ READ_LOCALS(NullIfExpr);
+
+ READ_OID_FIELD(opno);
+ READ_OID_FIELD(opfuncid);
+ READ_OID_FIELD(opresulttype);
+ READ_BOOL_FIELD(opretset);
+ READ_OID_FIELD(opcollid);
+ READ_OID_FIELD(inputcollid);
+ READ_NODE_FIELD(args);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readScalarArrayOpExpr
+ */
+static ScalarArrayOpExpr *
+_readScalarArrayOpExpr(void)
+{
+ READ_LOCALS(ScalarArrayOpExpr);
+
+ READ_OID_FIELD(opno);
+ READ_OID_FIELD(opfuncid);
+ READ_BOOL_FIELD(useOr);
+ READ_OID_FIELD(inputcollid);
+ READ_NODE_FIELD(args);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readBoolExpr
+ */
+static BoolExpr *
+_readBoolExpr(void)
+{
+ READ_LOCALS(BoolExpr);
+
+ /* do-it-yourself enum representation */
+ token = pg_strtok(&length); /* skip :boolop */
+ token = pg_strtok(&length); /* get field value */
+ if (strncmp(token, "and", 3) == 0)
+ local_node->boolop = AND_EXPR;
+ else if (strncmp(token, "or", 2) == 0)
+ local_node->boolop = OR_EXPR;
+ else if (strncmp(token, "not", 3) == 0)
+ local_node->boolop = NOT_EXPR;
+ else
+ elog(ERROR, "unrecognized boolop \"%.*s\"", length, token);
+
+ READ_NODE_FIELD(args);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readSubLink
+ */
+static SubLink *
+_readSubLink(void)
+{
+ READ_LOCALS(SubLink);
+
+ READ_ENUM_FIELD(subLinkType, SubLinkType);
+ READ_INT_FIELD(subLinkId);
+ READ_NODE_FIELD(testexpr);
+ READ_NODE_FIELD(operName);
+ READ_NODE_FIELD(subselect);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readSubPlan is not needed since it doesn't appear in stored rules.
+ */
+
+/*
+ * _readFieldSelect
+ */
+static FieldSelect *
+_readFieldSelect(void)
+{
+ READ_LOCALS(FieldSelect);
+
+ READ_NODE_FIELD(arg);
+ READ_INT_FIELD(fieldnum);
+ READ_OID_FIELD(resulttype);
+ READ_INT_FIELD(resulttypmod);
+ READ_OID_FIELD(resultcollid);
+
+ READ_DONE();
+}
+
+/*
+ * _readFieldStore
+ */
+static FieldStore *
+_readFieldStore(void)
+{
+ READ_LOCALS(FieldStore);
+
+ READ_NODE_FIELD(arg);
+ READ_NODE_FIELD(newvals);
+ READ_NODE_FIELD(fieldnums);
+ READ_OID_FIELD(resulttype);
+
+ READ_DONE();
+}
+
+/*
+ * _readRelabelType
+ */
+static RelabelType *
+_readRelabelType(void)
+{
+ READ_LOCALS(RelabelType);
+
+ READ_NODE_FIELD(arg);
+ READ_OID_FIELD(resulttype);
+ READ_INT_FIELD(resulttypmod);
+ READ_OID_FIELD(resultcollid);
+ READ_ENUM_FIELD(relabelformat, CoercionForm);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readCoerceViaIO
+ */
+static CoerceViaIO *
+_readCoerceViaIO(void)
+{
+ READ_LOCALS(CoerceViaIO);
+
+ READ_NODE_FIELD(arg);
+ READ_OID_FIELD(resulttype);
+ READ_OID_FIELD(resultcollid);
+ READ_ENUM_FIELD(coerceformat, CoercionForm);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readArrayCoerceExpr
+ */
+static ArrayCoerceExpr *
+_readArrayCoerceExpr(void)
+{
+ READ_LOCALS(ArrayCoerceExpr);
+
+ READ_NODE_FIELD(arg);
+ READ_NODE_FIELD(elemexpr);
+ READ_OID_FIELD(resulttype);
+ READ_INT_FIELD(resulttypmod);
+ READ_OID_FIELD(resultcollid);
+ READ_ENUM_FIELD(coerceformat, CoercionForm);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readConvertRowtypeExpr
+ */
+static ConvertRowtypeExpr *
+_readConvertRowtypeExpr(void)
+{
+ READ_LOCALS(ConvertRowtypeExpr);
+
+ READ_NODE_FIELD(arg);
+ READ_OID_FIELD(resulttype);
+ READ_ENUM_FIELD(convertformat, CoercionForm);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readCollateExpr
+ */
+static CollateExpr *
+_readCollateExpr(void)
+{
+ READ_LOCALS(CollateExpr);
+
+ READ_NODE_FIELD(arg);
+ READ_OID_FIELD(collOid);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readCaseExpr
+ */
+static CaseExpr *
+_readCaseExpr(void)
+{
+ READ_LOCALS(CaseExpr);
+
+ READ_OID_FIELD(casetype);
+ READ_OID_FIELD(casecollid);
+ READ_NODE_FIELD(arg);
+ READ_NODE_FIELD(args);
+ READ_NODE_FIELD(defresult);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readCaseWhen
+ */
+static CaseWhen *
+_readCaseWhen(void)
+{
+ READ_LOCALS(CaseWhen);
+
+ READ_NODE_FIELD(expr);
+ READ_NODE_FIELD(result);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readCaseTestExpr
+ */
+static CaseTestExpr *
+_readCaseTestExpr(void)
+{
+ READ_LOCALS(CaseTestExpr);
+
+ READ_OID_FIELD(typeId);
+ READ_INT_FIELD(typeMod);
+ READ_OID_FIELD(collation);
+
+ READ_DONE();
+}
+
+/*
+ * _readArrayExpr
+ */
+static ArrayExpr *
+_readArrayExpr(void)
+{
+ READ_LOCALS(ArrayExpr);
+
+ READ_OID_FIELD(array_typeid);
+ READ_OID_FIELD(array_collid);
+ READ_OID_FIELD(element_typeid);
+ READ_NODE_FIELD(elements);
+ READ_BOOL_FIELD(multidims);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readRowExpr
+ */
+static RowExpr *
+_readRowExpr(void)
+{
+ READ_LOCALS(RowExpr);
+
+ READ_NODE_FIELD(args);
+ READ_OID_FIELD(row_typeid);
+ READ_ENUM_FIELD(row_format, CoercionForm);
+ READ_NODE_FIELD(colnames);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readRowCompareExpr
+ */
+static RowCompareExpr *
+_readRowCompareExpr(void)
+{
+ READ_LOCALS(RowCompareExpr);
+
+ READ_ENUM_FIELD(rctype, RowCompareType);
+ READ_NODE_FIELD(opnos);
+ READ_NODE_FIELD(opfamilies);
+ READ_NODE_FIELD(inputcollids);
+ READ_NODE_FIELD(largs);
+ READ_NODE_FIELD(rargs);
+
+ READ_DONE();
+}
+
+/*
+ * _readCoalesceExpr
+ */
+static CoalesceExpr *
+_readCoalesceExpr(void)
+{
+ READ_LOCALS(CoalesceExpr);
+
+ READ_OID_FIELD(coalescetype);
+ READ_OID_FIELD(coalescecollid);
+ READ_NODE_FIELD(args);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readMinMaxExpr
+ */
+static MinMaxExpr *
+_readMinMaxExpr(void)
+{
+ READ_LOCALS(MinMaxExpr);
+
+ READ_OID_FIELD(minmaxtype);
+ READ_OID_FIELD(minmaxcollid);
+ READ_OID_FIELD(inputcollid);
+ READ_ENUM_FIELD(op, MinMaxOp);
+ READ_NODE_FIELD(args);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readSQLValueFunction
+ */
+static SQLValueFunction *
+_readSQLValueFunction(void)
+{
+ READ_LOCALS(SQLValueFunction);
+
+ READ_ENUM_FIELD(op, SQLValueFunctionOp);
+ READ_OID_FIELD(type);
+ READ_INT_FIELD(typmod);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readXmlExpr
+ */
+static XmlExpr *
+_readXmlExpr(void)
+{
+ READ_LOCALS(XmlExpr);
+
+ READ_ENUM_FIELD(op, XmlExprOp);
+ READ_STRING_FIELD(name);
+ READ_NODE_FIELD(named_args);
+ READ_NODE_FIELD(arg_names);
+ READ_NODE_FIELD(args);
+ READ_ENUM_FIELD(xmloption, XmlOptionType);
+ READ_OID_FIELD(type);
+ READ_INT_FIELD(typmod);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readNullTest
+ */
+static NullTest *
+_readNullTest(void)
+{
+ READ_LOCALS(NullTest);
+
+ READ_NODE_FIELD(arg);
+ READ_ENUM_FIELD(nulltesttype, NullTestType);
+ READ_BOOL_FIELD(argisrow);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readBooleanTest
+ */
+static BooleanTest *
+_readBooleanTest(void)
+{
+ READ_LOCALS(BooleanTest);
+
+ READ_NODE_FIELD(arg);
+ READ_ENUM_FIELD(booltesttype, BoolTestType);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readCoerceToDomain
+ */
+static CoerceToDomain *
+_readCoerceToDomain(void)
+{
+ READ_LOCALS(CoerceToDomain);
+
+ READ_NODE_FIELD(arg);
+ READ_OID_FIELD(resulttype);
+ READ_INT_FIELD(resulttypmod);
+ READ_OID_FIELD(resultcollid);
+ READ_ENUM_FIELD(coercionformat, CoercionForm);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readCoerceToDomainValue
+ */
+static CoerceToDomainValue *
+_readCoerceToDomainValue(void)
+{
+ READ_LOCALS(CoerceToDomainValue);
+
+ READ_OID_FIELD(typeId);
+ READ_INT_FIELD(typeMod);
+ READ_OID_FIELD(collation);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readSetToDefault
+ */
+static SetToDefault *
+_readSetToDefault(void)
+{
+ READ_LOCALS(SetToDefault);
+
+ READ_OID_FIELD(typeId);
+ READ_INT_FIELD(typeMod);
+ READ_OID_FIELD(collation);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readCurrentOfExpr
+ */
+static CurrentOfExpr *
+_readCurrentOfExpr(void)
+{
+ READ_LOCALS(CurrentOfExpr);
+
+ READ_UINT_FIELD(cvarno);
+ READ_STRING_FIELD(cursor_name);
+ READ_INT_FIELD(cursor_param);
+
+ READ_DONE();
+}
+
+/*
+ * _readNextValueExpr
+ */
+static NextValueExpr *
+_readNextValueExpr(void)
+{
+ READ_LOCALS(NextValueExpr);
+
+ READ_OID_FIELD(seqid);
+ READ_OID_FIELD(typeId);
+
+ READ_DONE();
+}
+
+/*
+ * _readInferenceElem
+ */
+static InferenceElem *
+_readInferenceElem(void)
+{
+ READ_LOCALS(InferenceElem);
+
+ READ_NODE_FIELD(expr);
+ READ_OID_FIELD(infercollid);
+ READ_OID_FIELD(inferopclass);
+
+ READ_DONE();
+}
+
+/*
+ * _readTargetEntry
+ */
+static TargetEntry *
+_readTargetEntry(void)
+{
+ READ_LOCALS(TargetEntry);
+
+ READ_NODE_FIELD(expr);
+ READ_INT_FIELD(resno);
+ READ_STRING_FIELD(resname);
+ READ_UINT_FIELD(ressortgroupref);
+ READ_OID_FIELD(resorigtbl);
+ READ_INT_FIELD(resorigcol);
+ READ_BOOL_FIELD(resjunk);
+
+ READ_DONE();
+}
+
+/*
+ * _readRangeTblRef
+ */
+static RangeTblRef *
+_readRangeTblRef(void)
+{
+ READ_LOCALS(RangeTblRef);
+
+ READ_INT_FIELD(rtindex);
+
+ READ_DONE();
+}
+
+/*
+ * _readJoinExpr
+ */
+static JoinExpr *
+_readJoinExpr(void)
+{
+ READ_LOCALS(JoinExpr);
+
+ READ_ENUM_FIELD(jointype, JoinType);
+ READ_BOOL_FIELD(isNatural);
+ READ_NODE_FIELD(larg);
+ READ_NODE_FIELD(rarg);
+ READ_NODE_FIELD(usingClause);
+ READ_NODE_FIELD(quals);
+ READ_NODE_FIELD(alias);
+ READ_INT_FIELD(rtindex);
+
+ READ_DONE();
+}
+
+/*
+ * _readFromExpr
+ */
+static FromExpr *
+_readFromExpr(void)
+{
+ READ_LOCALS(FromExpr);
+
+ READ_NODE_FIELD(fromlist);
+ READ_NODE_FIELD(quals);
+
+ READ_DONE();
+}
+
+/*
+ * _readOnConflictExpr
+ */
+static OnConflictExpr *
+_readOnConflictExpr(void)
+{
+ READ_LOCALS(OnConflictExpr);
+
+ READ_ENUM_FIELD(action, OnConflictAction);
+ READ_NODE_FIELD(arbiterElems);
+ READ_NODE_FIELD(arbiterWhere);
+ READ_OID_FIELD(constraint);
+ READ_NODE_FIELD(onConflictSet);
+ READ_NODE_FIELD(onConflictWhere);
+ READ_INT_FIELD(exclRelIndex);
+ READ_NODE_FIELD(exclRelTlist);
+
+ READ_DONE();
+}
+
+/*
+ * Stuff from pathnodes.h.
+ *
+ * Mostly we don't need to read planner nodes back in again, but some
+ * of these also end up in plan trees.
+ */
+
+/*
+ * _readAppendRelInfo
+ */
+static AppendRelInfo *
+_readAppendRelInfo(void)
+{
+ READ_LOCALS(AppendRelInfo);
+
+ READ_UINT_FIELD(parent_relid);
+ READ_UINT_FIELD(child_relid);
+ READ_OID_FIELD(parent_reltype);
+ READ_OID_FIELD(child_reltype);
+ READ_NODE_FIELD(translated_vars);
+ READ_INT_FIELD(num_child_cols);
+ READ_ATTRNUMBER_ARRAY(parent_colnos, local_node->num_child_cols);
+ READ_OID_FIELD(parent_reloid);
+
+ READ_DONE();
+}
+
+/*
+ * Stuff from parsenodes.h.
+ */
+
+/*
+ * _readRangeTblEntry
+ */
+static RangeTblEntry *
+_readRangeTblEntry(void)
+{
+ READ_LOCALS(RangeTblEntry);
+
+ /* put alias + eref first to make dump more legible */
+ READ_NODE_FIELD(alias);
+ READ_NODE_FIELD(eref);
+ READ_ENUM_FIELD(rtekind, RTEKind);
+
+ switch (local_node->rtekind)
+ {
+ case RTE_RELATION:
+ READ_OID_FIELD(relid);
+ READ_CHAR_FIELD(relkind);
+ READ_INT_FIELD(rellockmode);
+ READ_NODE_FIELD(tablesample);
+ break;
+ case RTE_SUBQUERY:
+ READ_NODE_FIELD(subquery);
+ READ_BOOL_FIELD(security_barrier);
+ break;
+ case RTE_JOIN:
+ READ_ENUM_FIELD(jointype, JoinType);
+ READ_INT_FIELD(joinmergedcols);
+ READ_NODE_FIELD(joinaliasvars);
+ READ_NODE_FIELD(joinleftcols);
+ READ_NODE_FIELD(joinrightcols);
+ break;
+ case RTE_FUNCTION:
+ READ_NODE_FIELD(functions);
+ READ_BOOL_FIELD(funcordinality);
+ break;
+ case RTE_TABLEFUNC:
+ READ_NODE_FIELD(tablefunc);
+ /* The RTE must have a copy of the column type info, if any */
+ if (local_node->tablefunc)
+ {
+ TableFunc *tf = local_node->tablefunc;
+
+ local_node->coltypes = tf->coltypes;
+ local_node->coltypmods = tf->coltypmods;
+ local_node->colcollations = tf->colcollations;
+ }
+ break;
+ case RTE_VALUES:
+ READ_NODE_FIELD(values_lists);
+ READ_NODE_FIELD(coltypes);
+ READ_NODE_FIELD(coltypmods);
+ READ_NODE_FIELD(colcollations);
+ break;
+ case RTE_CTE:
+ READ_STRING_FIELD(ctename);
+ READ_UINT_FIELD(ctelevelsup);
+ READ_BOOL_FIELD(self_reference);
+ READ_NODE_FIELD(coltypes);
+ READ_NODE_FIELD(coltypmods);
+ READ_NODE_FIELD(colcollations);
+ break;
+ case RTE_NAMEDTUPLESTORE:
+ READ_STRING_FIELD(enrname);
+ READ_FLOAT_FIELD(enrtuples);
+ READ_OID_FIELD(relid);
+ READ_NODE_FIELD(coltypes);
+ READ_NODE_FIELD(coltypmods);
+ READ_NODE_FIELD(colcollations);
+ break;
+ case RTE_RESULT:
+ /* no extra fields */
+ break;
+ default:
+ elog(ERROR, "unrecognized RTE kind: %d",
+ (int) local_node->rtekind);
+ break;
+ }
+
+ READ_BOOL_FIELD(lateral);
+ READ_BOOL_FIELD(inh);
+ READ_BOOL_FIELD(inFromCl);
+ READ_UINT_FIELD(requiredPerms);
+ READ_OID_FIELD(checkAsUser);
+ READ_BITMAPSET_FIELD(selectedCols);
+ READ_BITMAPSET_FIELD(insertedCols);
+ READ_BITMAPSET_FIELD(updatedCols);
+ READ_BITMAPSET_FIELD(extraUpdatedCols);
+ READ_NODE_FIELD(securityQuals);
+
+ READ_DONE();
+}
+
+/*
+ * _readRangeTblFunction
+ */
+static RangeTblFunction *
+_readRangeTblFunction(void)
+{
+ READ_LOCALS(RangeTblFunction);
+
+ READ_NODE_FIELD(funcexpr);
+ READ_INT_FIELD(funccolcount);
+ READ_NODE_FIELD(funccolnames);
+ READ_NODE_FIELD(funccoltypes);
+ READ_NODE_FIELD(funccoltypmods);
+ READ_NODE_FIELD(funccolcollations);
+ READ_BITMAPSET_FIELD(funcparams);
+
+ READ_DONE();
+}
+
+/*
+ * _readTableSampleClause
+ */
+static TableSampleClause *
+_readTableSampleClause(void)
+{
+ READ_LOCALS(TableSampleClause);
+
+ READ_OID_FIELD(tsmhandler);
+ READ_NODE_FIELD(args);
+ READ_NODE_FIELD(repeatable);
+
+ READ_DONE();
+}
+
+/*
+ * _readDefElem
+ */
+static DefElem *
+_readDefElem(void)
+{
+ READ_LOCALS(DefElem);
+
+ READ_STRING_FIELD(defnamespace);
+ READ_STRING_FIELD(defname);
+ READ_NODE_FIELD(arg);
+ READ_ENUM_FIELD(defaction, DefElemAction);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * Stuff from plannodes.h.
+ */
+
+/*
+ * _readPlannedStmt
+ */
+static PlannedStmt *
+_readPlannedStmt(void)
+{
+ READ_LOCALS(PlannedStmt);
+
+ READ_ENUM_FIELD(commandType, CmdType);
+ READ_UINT64_FIELD(queryId);
+ READ_BOOL_FIELD(hasReturning);
+ READ_BOOL_FIELD(hasModifyingCTE);
+ READ_BOOL_FIELD(canSetTag);
+ READ_BOOL_FIELD(transientPlan);
+ READ_BOOL_FIELD(dependsOnRole);
+ READ_BOOL_FIELD(parallelModeNeeded);
+ READ_INT_FIELD(jitFlags);
+ READ_NODE_FIELD(planTree);
+ READ_NODE_FIELD(rtable);
+ READ_NODE_FIELD(resultRelations);
+ READ_NODE_FIELD(rootResultRelations);
+ READ_NODE_FIELD(appendRelations);
+ READ_NODE_FIELD(subplans);
+ READ_BITMAPSET_FIELD(rewindPlanIDs);
+ READ_NODE_FIELD(rowMarks);
+ READ_NODE_FIELD(relationOids);
+ READ_NODE_FIELD(invalItems);
+ READ_NODE_FIELD(paramExecTypes);
+ READ_NODE_FIELD(utilityStmt);
+ READ_LOCATION_FIELD(stmt_location);
+ READ_INT_FIELD(stmt_len);
+
+ READ_DONE();
+}
+
+/*
+ * ReadCommonPlan
+ * Assign the basic stuff of all nodes that inherit from Plan
+ */
+static void
+ReadCommonPlan(Plan *local_node)
+{
+ READ_TEMP_LOCALS();
+
+ READ_FLOAT_FIELD(startup_cost);
+ READ_FLOAT_FIELD(total_cost);
+ READ_FLOAT_FIELD(plan_rows);
+ READ_INT_FIELD(plan_width);
+ READ_BOOL_FIELD(parallel_aware);
+ READ_BOOL_FIELD(parallel_safe);
+ READ_INT_FIELD(plan_node_id);
+ READ_NODE_FIELD(targetlist);
+ READ_NODE_FIELD(qual);
+ READ_NODE_FIELD(lefttree);
+ READ_NODE_FIELD(righttree);
+ READ_NODE_FIELD(initPlan);
+ READ_BITMAPSET_FIELD(extParam);
+ READ_BITMAPSET_FIELD(allParam);
+}
+
+/*
+ * _readPlan
+ */
+static Plan *
+_readPlan(void)
+{
+ READ_LOCALS_NO_FIELDS(Plan);
+
+ ReadCommonPlan(local_node);
+
+ READ_DONE();
+}
+
+/*
+ * _readResult
+ */
+static Result *
+_readResult(void)
+{
+ READ_LOCALS(Result);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_NODE_FIELD(resconstantqual);
+
+ READ_DONE();
+}
+
+/*
+ * _readProjectSet
+ */
+static ProjectSet *
+_readProjectSet(void)
+{
+ READ_LOCALS_NO_FIELDS(ProjectSet);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_DONE();
+}
+
+/*
+ * _readModifyTable
+ */
+static ModifyTable *
+_readModifyTable(void)
+{
+ READ_LOCALS(ModifyTable);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_ENUM_FIELD(operation, CmdType);
+ READ_BOOL_FIELD(canSetTag);
+ READ_UINT_FIELD(nominalRelation);
+ READ_UINT_FIELD(rootRelation);
+ READ_BOOL_FIELD(partColsUpdated);
+ READ_NODE_FIELD(resultRelations);
+ READ_INT_FIELD(resultRelIndex);
+ READ_INT_FIELD(rootResultRelIndex);
+ READ_NODE_FIELD(plans);
+ READ_NODE_FIELD(withCheckOptionLists);
+ READ_NODE_FIELD(returningLists);
+ READ_NODE_FIELD(fdwPrivLists);
+ READ_BITMAPSET_FIELD(fdwDirectModifyPlans);
+ READ_NODE_FIELD(rowMarks);
+ READ_INT_FIELD(epqParam);
+ READ_ENUM_FIELD(onConflictAction, OnConflictAction);
+ READ_NODE_FIELD(arbiterIndexes);
+ READ_NODE_FIELD(onConflictSet);
+ READ_NODE_FIELD(onConflictWhere);
+ READ_UINT_FIELD(exclRelRTI);
+ READ_NODE_FIELD(exclRelTlist);
+
+ READ_DONE();
+}
+
+/*
+ * _readAppend
+ */
+static Append *
+_readAppend(void)
+{
+ READ_LOCALS(Append);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_BITMAPSET_FIELD(apprelids);
+ READ_NODE_FIELD(appendplans);
+ READ_INT_FIELD(first_partial_plan);
+ READ_NODE_FIELD(part_prune_info);
+
+ READ_DONE();
+}
+
+/*
+ * _readMergeAppend
+ */
+static MergeAppend *
+_readMergeAppend(void)
+{
+ READ_LOCALS(MergeAppend);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_BITMAPSET_FIELD(apprelids);
+ READ_NODE_FIELD(mergeplans);
+ READ_INT_FIELD(numCols);
+ READ_ATTRNUMBER_ARRAY(sortColIdx, local_node->numCols);
+ READ_OID_ARRAY(sortOperators, local_node->numCols);
+ READ_OID_ARRAY(collations, local_node->numCols);
+ READ_BOOL_ARRAY(nullsFirst, local_node->numCols);
+ READ_NODE_FIELD(part_prune_info);
+
+ READ_DONE();
+}
+
+/*
+ * _readRecursiveUnion
+ */
+static RecursiveUnion *
+_readRecursiveUnion(void)
+{
+ READ_LOCALS(RecursiveUnion);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_INT_FIELD(wtParam);
+ READ_INT_FIELD(numCols);
+ READ_ATTRNUMBER_ARRAY(dupColIdx, local_node->numCols);
+ READ_OID_ARRAY(dupOperators, local_node->numCols);
+ READ_OID_ARRAY(dupCollations, local_node->numCols);
+ READ_LONG_FIELD(numGroups);
+
+ READ_DONE();
+}
+
+/*
+ * _readBitmapAnd
+ */
+static BitmapAnd *
+_readBitmapAnd(void)
+{
+ READ_LOCALS(BitmapAnd);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_NODE_FIELD(bitmapplans);
+
+ READ_DONE();
+}
+
+/*
+ * _readBitmapOr
+ */
+static BitmapOr *
+_readBitmapOr(void)
+{
+ READ_LOCALS(BitmapOr);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_BOOL_FIELD(isshared);
+ READ_NODE_FIELD(bitmapplans);
+
+ READ_DONE();
+}
+
+/*
+ * ReadCommonScan
+ * Assign the basic stuff of all nodes that inherit from Scan
+ */
+static void
+ReadCommonScan(Scan *local_node)
+{
+ READ_TEMP_LOCALS();
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_UINT_FIELD(scanrelid);
+}
+
+/*
+ * _readScan
+ */
+static Scan *
+_readScan(void)
+{
+ READ_LOCALS_NO_FIELDS(Scan);
+
+ ReadCommonScan(local_node);
+
+ READ_DONE();
+}
+
+/*
+ * _readSeqScan
+ */
+static SeqScan *
+_readSeqScan(void)
+{
+ READ_LOCALS_NO_FIELDS(SeqScan);
+
+ ReadCommonScan(local_node);
+
+ READ_DONE();
+}
+
+/*
+ * _readSampleScan
+ */
+static SampleScan *
+_readSampleScan(void)
+{
+ READ_LOCALS(SampleScan);
+
+ ReadCommonScan(&local_node->scan);
+
+ READ_NODE_FIELD(tablesample);
+
+ READ_DONE();
+}
+
+/*
+ * _readIndexScan
+ */
+static IndexScan *
+_readIndexScan(void)
+{
+ READ_LOCALS(IndexScan);
+
+ ReadCommonScan(&local_node->scan);
+
+ READ_OID_FIELD(indexid);
+ READ_NODE_FIELD(indexqual);
+ READ_NODE_FIELD(indexqualorig);
+ READ_NODE_FIELD(indexorderby);
+ READ_NODE_FIELD(indexorderbyorig);
+ READ_NODE_FIELD(indexorderbyops);
+ READ_ENUM_FIELD(indexorderdir, ScanDirection);
+
+ READ_DONE();
+}
+
+/*
+ * _readIndexOnlyScan
+ */
+static IndexOnlyScan *
+_readIndexOnlyScan(void)
+{
+ READ_LOCALS(IndexOnlyScan);
+
+ ReadCommonScan(&local_node->scan);
+
+ READ_OID_FIELD(indexid);
+ READ_NODE_FIELD(indexqual);
+ READ_NODE_FIELD(indexorderby);
+ READ_NODE_FIELD(indextlist);
+ READ_ENUM_FIELD(indexorderdir, ScanDirection);
+
+ READ_DONE();
+}
+
+/*
+ * _readBitmapIndexScan
+ */
+static BitmapIndexScan *
+_readBitmapIndexScan(void)
+{
+ READ_LOCALS(BitmapIndexScan);
+
+ ReadCommonScan(&local_node->scan);
+
+ READ_OID_FIELD(indexid);
+ READ_BOOL_FIELD(isshared);
+ READ_NODE_FIELD(indexqual);
+ READ_NODE_FIELD(indexqualorig);
+
+ READ_DONE();
+}
+
+/*
+ * _readBitmapHeapScan
+ */
+static BitmapHeapScan *
+_readBitmapHeapScan(void)
+{
+ READ_LOCALS(BitmapHeapScan);
+
+ ReadCommonScan(&local_node->scan);
+
+ READ_NODE_FIELD(bitmapqualorig);
+
+ READ_DONE();
+}
+
+/*
+ * _readTidScan
+ */
+static TidScan *
+_readTidScan(void)
+{
+ READ_LOCALS(TidScan);
+
+ ReadCommonScan(&local_node->scan);
+
+ READ_NODE_FIELD(tidquals);
+
+ READ_DONE();
+}
+
+/*
+ * _readSubqueryScan
+ */
+static SubqueryScan *
+_readSubqueryScan(void)
+{
+ READ_LOCALS(SubqueryScan);
+
+ ReadCommonScan(&local_node->scan);
+
+ READ_NODE_FIELD(subplan);
+
+ READ_DONE();
+}
+
+/*
+ * _readFunctionScan
+ */
+static FunctionScan *
+_readFunctionScan(void)
+{
+ READ_LOCALS(FunctionScan);
+
+ ReadCommonScan(&local_node->scan);
+
+ READ_NODE_FIELD(functions);
+ READ_BOOL_FIELD(funcordinality);
+
+ READ_DONE();
+}
+
+/*
+ * _readValuesScan
+ */
+static ValuesScan *
+_readValuesScan(void)
+{
+ READ_LOCALS(ValuesScan);
+
+ ReadCommonScan(&local_node->scan);
+
+ READ_NODE_FIELD(values_lists);
+
+ READ_DONE();
+}
+
+/*
+ * _readTableFuncScan
+ */
+static TableFuncScan *
+_readTableFuncScan(void)
+{
+ READ_LOCALS(TableFuncScan);
+
+ ReadCommonScan(&local_node->scan);
+
+ READ_NODE_FIELD(tablefunc);
+
+ READ_DONE();
+}
+
+/*
+ * _readCteScan
+ */
+static CteScan *
+_readCteScan(void)
+{
+ READ_LOCALS(CteScan);
+
+ ReadCommonScan(&local_node->scan);
+
+ READ_INT_FIELD(ctePlanId);
+ READ_INT_FIELD(cteParam);
+
+ READ_DONE();
+}
+
+/*
+ * _readNamedTuplestoreScan
+ */
+static NamedTuplestoreScan *
+_readNamedTuplestoreScan(void)
+{
+ READ_LOCALS(NamedTuplestoreScan);
+
+ ReadCommonScan(&local_node->scan);
+
+ READ_STRING_FIELD(enrname);
+
+ READ_DONE();
+}
+
+/*
+ * _readWorkTableScan
+ */
+static WorkTableScan *
+_readWorkTableScan(void)
+{
+ READ_LOCALS(WorkTableScan);
+
+ ReadCommonScan(&local_node->scan);
+
+ READ_INT_FIELD(wtParam);
+
+ READ_DONE();
+}
+
+/*
+ * _readForeignScan
+ */
+static ForeignScan *
+_readForeignScan(void)
+{
+ READ_LOCALS(ForeignScan);
+
+ ReadCommonScan(&local_node->scan);
+
+ READ_ENUM_FIELD(operation, CmdType);
+ READ_OID_FIELD(fs_server);
+ READ_NODE_FIELD(fdw_exprs);
+ READ_NODE_FIELD(fdw_private);
+ READ_NODE_FIELD(fdw_scan_tlist);
+ READ_NODE_FIELD(fdw_recheck_quals);
+ READ_BITMAPSET_FIELD(fs_relids);
+ READ_BOOL_FIELD(fsSystemCol);
+
+ READ_DONE();
+}
+
+/*
+ * _readCustomScan
+ */
+static CustomScan *
+_readCustomScan(void)
+{
+ READ_LOCALS(CustomScan);
+ char *custom_name;
+ const CustomScanMethods *methods;
+
+ ReadCommonScan(&local_node->scan);
+
+ READ_UINT_FIELD(flags);
+ READ_NODE_FIELD(custom_plans);
+ READ_NODE_FIELD(custom_exprs);
+ READ_NODE_FIELD(custom_private);
+ READ_NODE_FIELD(custom_scan_tlist);
+ READ_BITMAPSET_FIELD(custom_relids);
+
+ /* Lookup CustomScanMethods by CustomName */
+ token = pg_strtok(&length); /* skip methods: */
+ token = pg_strtok(&length); /* CustomName */
+ custom_name = nullable_string(token, length);
+ methods = GetCustomScanMethods(custom_name, false);
+ local_node->methods = methods;
+
+ READ_DONE();
+}
+
+/*
+ * ReadCommonJoin
+ * Assign the basic stuff of all nodes that inherit from Join
+ */
+static void
+ReadCommonJoin(Join *local_node)
+{
+ READ_TEMP_LOCALS();
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_ENUM_FIELD(jointype, JoinType);
+ READ_BOOL_FIELD(inner_unique);
+ READ_NODE_FIELD(joinqual);
+}
+
+/*
+ * _readJoin
+ */
+static Join *
+_readJoin(void)
+{
+ READ_LOCALS_NO_FIELDS(Join);
+
+ ReadCommonJoin(local_node);
+
+ READ_DONE();
+}
+
+/*
+ * _readNestLoop
+ */
+static NestLoop *
+_readNestLoop(void)
+{
+ READ_LOCALS(NestLoop);
+
+ ReadCommonJoin(&local_node->join);
+
+ READ_NODE_FIELD(nestParams);
+
+ READ_DONE();
+}
+
+/*
+ * _readMergeJoin
+ */
+static MergeJoin *
+_readMergeJoin(void)
+{
+ int numCols;
+
+ READ_LOCALS(MergeJoin);
+
+ ReadCommonJoin(&local_node->join);
+
+ READ_BOOL_FIELD(skip_mark_restore);
+ READ_NODE_FIELD(mergeclauses);
+
+ numCols = list_length(local_node->mergeclauses);
+
+ READ_OID_ARRAY(mergeFamilies, numCols);
+ READ_OID_ARRAY(mergeCollations, numCols);
+ READ_INT_ARRAY(mergeStrategies, numCols);
+ READ_BOOL_ARRAY(mergeNullsFirst, numCols);
+
+ READ_DONE();
+}
+
+/*
+ * _readHashJoin
+ */
+static HashJoin *
+_readHashJoin(void)
+{
+ READ_LOCALS(HashJoin);
+
+ ReadCommonJoin(&local_node->join);
+
+ READ_NODE_FIELD(hashclauses);
+ READ_NODE_FIELD(hashoperators);
+ READ_NODE_FIELD(hashcollations);
+ READ_NODE_FIELD(hashkeys);
+
+ READ_DONE();
+}
+
+/*
+ * _readMaterial
+ */
+static Material *
+_readMaterial(void)
+{
+ READ_LOCALS_NO_FIELDS(Material);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_DONE();
+}
+
+/*
+ * ReadCommonSort
+ * Assign the basic stuff of all nodes that inherit from Sort
+ */
+static void
+ReadCommonSort(Sort *local_node)
+{
+ READ_TEMP_LOCALS();
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_INT_FIELD(numCols);
+ READ_ATTRNUMBER_ARRAY(sortColIdx, local_node->numCols);
+ READ_OID_ARRAY(sortOperators, local_node->numCols);
+ READ_OID_ARRAY(collations, local_node->numCols);
+ READ_BOOL_ARRAY(nullsFirst, local_node->numCols);
+}
+
+/*
+ * _readSort
+ */
+static Sort *
+_readSort(void)
+{
+ READ_LOCALS_NO_FIELDS(Sort);
+
+ ReadCommonSort(local_node);
+
+ READ_DONE();
+}
+
+/*
+ * _readIncrementalSort
+ */
+static IncrementalSort *
+_readIncrementalSort(void)
+{
+ READ_LOCALS(IncrementalSort);
+
+ ReadCommonSort(&local_node->sort);
+
+ READ_INT_FIELD(nPresortedCols);
+
+ READ_DONE();
+}
+
+/*
+ * _readGroup
+ */
+static Group *
+_readGroup(void)
+{
+ READ_LOCALS(Group);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_INT_FIELD(numCols);
+ READ_ATTRNUMBER_ARRAY(grpColIdx, local_node->numCols);
+ READ_OID_ARRAY(grpOperators, local_node->numCols);
+ READ_OID_ARRAY(grpCollations, local_node->numCols);
+
+ READ_DONE();
+}
+
+/*
+ * _readAgg
+ */
+static Agg *
+_readAgg(void)
+{
+ READ_LOCALS(Agg);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_ENUM_FIELD(aggstrategy, AggStrategy);
+ READ_ENUM_FIELD(aggsplit, AggSplit);
+ READ_INT_FIELD(numCols);
+ READ_ATTRNUMBER_ARRAY(grpColIdx, local_node->numCols);
+ READ_OID_ARRAY(grpOperators, local_node->numCols);
+ READ_OID_ARRAY(grpCollations, local_node->numCols);
+ READ_LONG_FIELD(numGroups);
+ READ_UINT64_FIELD(transitionSpace);
+ READ_BITMAPSET_FIELD(aggParams);
+ READ_NODE_FIELD(groupingSets);
+ READ_NODE_FIELD(chain);
+
+ READ_DONE();
+}
+
+/*
+ * _readWindowAgg
+ */
+static WindowAgg *
+_readWindowAgg(void)
+{
+ READ_LOCALS(WindowAgg);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_UINT_FIELD(winref);
+ READ_INT_FIELD(partNumCols);
+ READ_ATTRNUMBER_ARRAY(partColIdx, local_node->partNumCols);
+ READ_OID_ARRAY(partOperators, local_node->partNumCols);
+ READ_OID_ARRAY(partCollations, local_node->partNumCols);
+ READ_INT_FIELD(ordNumCols);
+ READ_ATTRNUMBER_ARRAY(ordColIdx, local_node->ordNumCols);
+ READ_OID_ARRAY(ordOperators, local_node->ordNumCols);
+ READ_OID_ARRAY(ordCollations, local_node->ordNumCols);
+ READ_INT_FIELD(frameOptions);
+ READ_NODE_FIELD(startOffset);
+ READ_NODE_FIELD(endOffset);
+ READ_OID_FIELD(startInRangeFunc);
+ READ_OID_FIELD(endInRangeFunc);
+ READ_OID_FIELD(inRangeColl);
+ READ_BOOL_FIELD(inRangeAsc);
+ READ_BOOL_FIELD(inRangeNullsFirst);
+
+ READ_DONE();
+}
+
+/*
+ * _readUnique
+ */
+static Unique *
+_readUnique(void)
+{
+ READ_LOCALS(Unique);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_INT_FIELD(numCols);
+ READ_ATTRNUMBER_ARRAY(uniqColIdx, local_node->numCols);
+ READ_OID_ARRAY(uniqOperators, local_node->numCols);
+ READ_OID_ARRAY(uniqCollations, local_node->numCols);
+
+ READ_DONE();
+}
+
+/*
+ * _readGather
+ */
+static Gather *
+_readGather(void)
+{
+ READ_LOCALS(Gather);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_INT_FIELD(num_workers);
+ READ_INT_FIELD(rescan_param);
+ READ_BOOL_FIELD(single_copy);
+ READ_BOOL_FIELD(invisible);
+ READ_BITMAPSET_FIELD(initParam);
+
+ READ_DONE();
+}
+
+/*
+ * _readGatherMerge
+ */
+static GatherMerge *
+_readGatherMerge(void)
+{
+ READ_LOCALS(GatherMerge);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_INT_FIELD(num_workers);
+ READ_INT_FIELD(rescan_param);
+ READ_INT_FIELD(numCols);
+ READ_ATTRNUMBER_ARRAY(sortColIdx, local_node->numCols);
+ READ_OID_ARRAY(sortOperators, local_node->numCols);
+ READ_OID_ARRAY(collations, local_node->numCols);
+ READ_BOOL_ARRAY(nullsFirst, local_node->numCols);
+ READ_BITMAPSET_FIELD(initParam);
+
+ READ_DONE();
+}
+
+/*
+ * _readHash
+ */
+static Hash *
+_readHash(void)
+{
+ READ_LOCALS(Hash);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_NODE_FIELD(hashkeys);
+ READ_OID_FIELD(skewTable);
+ READ_INT_FIELD(skewColumn);
+ READ_BOOL_FIELD(skewInherit);
+ READ_FLOAT_FIELD(rows_total);
+
+ READ_DONE();
+}
+
+/*
+ * _readSetOp
+ */
+static SetOp *
+_readSetOp(void)
+{
+ READ_LOCALS(SetOp);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_ENUM_FIELD(cmd, SetOpCmd);
+ READ_ENUM_FIELD(strategy, SetOpStrategy);
+ READ_INT_FIELD(numCols);
+ READ_ATTRNUMBER_ARRAY(dupColIdx, local_node->numCols);
+ READ_OID_ARRAY(dupOperators, local_node->numCols);
+ READ_OID_ARRAY(dupCollations, local_node->numCols);
+ READ_INT_FIELD(flagColIdx);
+ READ_INT_FIELD(firstFlag);
+ READ_LONG_FIELD(numGroups);
+
+ READ_DONE();
+}
+
+/*
+ * _readLockRows
+ */
+static LockRows *
+_readLockRows(void)
+{
+ READ_LOCALS(LockRows);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_NODE_FIELD(rowMarks);
+ READ_INT_FIELD(epqParam);
+
+ READ_DONE();
+}
+
+/*
+ * _readLimit
+ */
+static Limit *
+_readLimit(void)
+{
+ READ_LOCALS(Limit);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_NODE_FIELD(limitOffset);
+ READ_NODE_FIELD(limitCount);
+ READ_ENUM_FIELD(limitOption, LimitOption);
+ READ_INT_FIELD(uniqNumCols);
+ READ_ATTRNUMBER_ARRAY(uniqColIdx, local_node->uniqNumCols);
+ READ_OID_ARRAY(uniqOperators, local_node->uniqNumCols);
+ READ_OID_ARRAY(uniqCollations, local_node->uniqNumCols);
+
+ READ_DONE();
+}
+
+/*
+ * _readNestLoopParam
+ */
+static NestLoopParam *
+_readNestLoopParam(void)
+{
+ READ_LOCALS(NestLoopParam);
+
+ READ_INT_FIELD(paramno);
+ READ_NODE_FIELD(paramval);
+
+ READ_DONE();
+}
+
+/*
+ * _readPlanRowMark
+ */
+static PlanRowMark *
+_readPlanRowMark(void)
+{
+ READ_LOCALS(PlanRowMark);
+
+ READ_UINT_FIELD(rti);
+ READ_UINT_FIELD(prti);
+ READ_UINT_FIELD(rowmarkId);
+ READ_ENUM_FIELD(markType, RowMarkType);
+ READ_INT_FIELD(allMarkTypes);
+ READ_ENUM_FIELD(strength, LockClauseStrength);
+ READ_ENUM_FIELD(waitPolicy, LockWaitPolicy);
+ READ_BOOL_FIELD(isParent);
+
+ READ_DONE();
+}
+
+static PartitionPruneInfo *
+_readPartitionPruneInfo(void)
+{
+ READ_LOCALS(PartitionPruneInfo);
+
+ READ_NODE_FIELD(prune_infos);
+ READ_BITMAPSET_FIELD(other_subplans);
+
+ READ_DONE();
+}
+
+static PartitionedRelPruneInfo *
+_readPartitionedRelPruneInfo(void)
+{
+ READ_LOCALS(PartitionedRelPruneInfo);
+
+ READ_UINT_FIELD(rtindex);
+ READ_BITMAPSET_FIELD(present_parts);
+ READ_INT_FIELD(nparts);
+ READ_INT_ARRAY(subplan_map, local_node->nparts);
+ READ_INT_ARRAY(subpart_map, local_node->nparts);
+ READ_OID_ARRAY(relid_map, local_node->nparts);
+ READ_NODE_FIELD(initial_pruning_steps);
+ READ_NODE_FIELD(exec_pruning_steps);
+ READ_BITMAPSET_FIELD(execparamids);
+
+ READ_DONE();
+}
+
+static PartitionPruneStepOp *
+_readPartitionPruneStepOp(void)
+{
+ READ_LOCALS(PartitionPruneStepOp);
+
+ READ_INT_FIELD(step.step_id);
+ READ_INT_FIELD(opstrategy);
+ READ_NODE_FIELD(exprs);
+ READ_NODE_FIELD(cmpfns);
+ READ_BITMAPSET_FIELD(nullkeys);
+
+ READ_DONE();
+}
+
+static PartitionPruneStepCombine *
+_readPartitionPruneStepCombine(void)
+{
+ READ_LOCALS(PartitionPruneStepCombine);
+
+ READ_INT_FIELD(step.step_id);
+ READ_ENUM_FIELD(combineOp, PartitionPruneCombineOp);
+ READ_NODE_FIELD(source_stepids);
+
+ READ_DONE();
+}
+
+/*
+ * _readPlanInvalItem
+ */
+static PlanInvalItem *
+_readPlanInvalItem(void)
+{
+ READ_LOCALS(PlanInvalItem);
+
+ READ_INT_FIELD(cacheId);
+ READ_UINT_FIELD(hashValue);
+
+ READ_DONE();
+}
+
+/*
+ * _readSubPlan
+ */
+static SubPlan *
+_readSubPlan(void)
+{
+ READ_LOCALS(SubPlan);
+
+ READ_ENUM_FIELD(subLinkType, SubLinkType);
+ READ_NODE_FIELD(testexpr);
+ READ_NODE_FIELD(paramIds);
+ READ_INT_FIELD(plan_id);
+ READ_STRING_FIELD(plan_name);
+ READ_OID_FIELD(firstColType);
+ READ_INT_FIELD(firstColTypmod);
+ READ_OID_FIELD(firstColCollation);
+ READ_BOOL_FIELD(useHashTable);
+ READ_BOOL_FIELD(unknownEqFalse);
+ READ_BOOL_FIELD(parallel_safe);
+ READ_NODE_FIELD(setParam);
+ READ_NODE_FIELD(parParam);
+ READ_NODE_FIELD(args);
+ READ_FLOAT_FIELD(startup_cost);
+ READ_FLOAT_FIELD(per_call_cost);
+
+ READ_DONE();
+}
+
+/*
+ * _readAlternativeSubPlan
+ */
+static AlternativeSubPlan *
+_readAlternativeSubPlan(void)
+{
+ READ_LOCALS(AlternativeSubPlan);
+
+ READ_NODE_FIELD(subplans);
+
+ READ_DONE();
+}
+
+/*
+ * _readExtensibleNode
+ */
+static ExtensibleNode *
+_readExtensibleNode(void)
+{
+ const ExtensibleNodeMethods *methods;
+ ExtensibleNode *local_node;
+ const char *extnodename;
+
+ READ_TEMP_LOCALS();
+
+ token = pg_strtok(&length); /* skip :extnodename */
+ token = pg_strtok(&length); /* get extnodename */
+
+ extnodename = nullable_string(token, length);
+ if (!extnodename)
+ elog(ERROR, "extnodename has to be supplied");
+ methods = GetExtensibleNodeMethods(extnodename, false);
+
+ local_node = (ExtensibleNode *) newNode(methods->node_size,
+ T_ExtensibleNode);
+ local_node->extnodename = extnodename;
+
+ /* deserialize the private fields */
+ methods->nodeRead(local_node);
+
+ READ_DONE();
+}
+
+/*
+ * _readPartitionBoundSpec
+ */
+static PartitionBoundSpec *
+_readPartitionBoundSpec(void)
+{
+ READ_LOCALS(PartitionBoundSpec);
+
+ READ_CHAR_FIELD(strategy);
+ READ_BOOL_FIELD(is_default);
+ READ_INT_FIELD(modulus);
+ READ_INT_FIELD(remainder);
+ READ_NODE_FIELD(listdatums);
+ READ_NODE_FIELD(lowerdatums);
+ READ_NODE_FIELD(upperdatums);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * _readPartitionRangeDatum
+ */
+static PartitionRangeDatum *
+_readPartitionRangeDatum(void)
+{
+ READ_LOCALS(PartitionRangeDatum);
+
+ READ_ENUM_FIELD(kind, PartitionRangeDatumKind);
+ READ_NODE_FIELD(value);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
+ * parseNodeString
+ *
+ * Given a character string representing a node tree, parseNodeString creates
+ * the internal node structure.
+ *
+ * The string to be read must already have been loaded into pg_strtok().
+ */
+Node *
+parseNodeString(void)
+{
+ void *return_value;
+
+ READ_TEMP_LOCALS();
+
+ /* Guard against stack overflow due to overly complex expressions */
+ check_stack_depth();
+
+ token = pg_strtok(&length);
+
+#define MATCH(tokname, namelen) \
+ (length == namelen && memcmp(token, tokname, namelen) == 0)
+
+ if (MATCH("QUERY", 5))
+ return_value = _readQuery();
+ else if (MATCH("WITHCHECKOPTION", 15))
+ return_value = _readWithCheckOption();
+ else if (MATCH("SORTGROUPCLAUSE", 15))
+ return_value = _readSortGroupClause();
+ else if (MATCH("GROUPINGSET", 11))
+ return_value = _readGroupingSet();
+ else if (MATCH("WINDOWCLAUSE", 12))
+ return_value = _readWindowClause();
+ else if (MATCH("ROWMARKCLAUSE", 13))
+ return_value = _readRowMarkClause();
+ else if (MATCH("COMMONTABLEEXPR", 15))
+ return_value = _readCommonTableExpr();
+ else if (MATCH("SETOPERATIONSTMT", 16))
+ return_value = _readSetOperationStmt();
+ else if (MATCH("ALIAS", 5))
+ return_value = _readAlias();
+ else if (MATCH("RANGEVAR", 8))
+ return_value = _readRangeVar();
+ else if (MATCH("INTOCLAUSE", 10))
+ return_value = _readIntoClause();
+ else if (MATCH("TABLEFUNC", 9))
+ return_value = _readTableFunc();
+ else if (MATCH("VAR", 3))
+ return_value = _readVar();
+ else if (MATCH("CONST", 5))
+ return_value = _readConst();
+ else if (MATCH("PARAM", 5))
+ return_value = _readParam();
+ else if (MATCH("AGGREF", 6))
+ return_value = _readAggref();
+ else if (MATCH("GROUPINGFUNC", 12))
+ return_value = _readGroupingFunc();
+ else if (MATCH("WINDOWFUNC", 10))
+ return_value = _readWindowFunc();
+ else if (MATCH("SUBSCRIPTINGREF", 15))
+ return_value = _readSubscriptingRef();
+ else if (MATCH("FUNCEXPR", 8))
+ return_value = _readFuncExpr();
+ else if (MATCH("NAMEDARGEXPR", 12))
+ return_value = _readNamedArgExpr();
+ else if (MATCH("OPEXPR", 6))
+ return_value = _readOpExpr();
+ else if (MATCH("DISTINCTEXPR", 12))
+ return_value = _readDistinctExpr();
+ else if (MATCH("NULLIFEXPR", 10))
+ return_value = _readNullIfExpr();
+ else if (MATCH("SCALARARRAYOPEXPR", 17))
+ return_value = _readScalarArrayOpExpr();
+ else if (MATCH("BOOLEXPR", 8))
+ return_value = _readBoolExpr();
+ else if (MATCH("SUBLINK", 7))
+ return_value = _readSubLink();
+ else if (MATCH("FIELDSELECT", 11))
+ return_value = _readFieldSelect();
+ else if (MATCH("FIELDSTORE", 10))
+ return_value = _readFieldStore();
+ else if (MATCH("RELABELTYPE", 11))
+ return_value = _readRelabelType();
+ else if (MATCH("COERCEVIAIO", 11))
+ return_value = _readCoerceViaIO();
+ else if (MATCH("ARRAYCOERCEEXPR", 15))
+ return_value = _readArrayCoerceExpr();
+ else if (MATCH("CONVERTROWTYPEEXPR", 18))
+ return_value = _readConvertRowtypeExpr();
+ else if (MATCH("COLLATE", 7))
+ return_value = _readCollateExpr();
+ else if (MATCH("CASE", 4))
+ return_value = _readCaseExpr();
+ else if (MATCH("WHEN", 4))
+ return_value = _readCaseWhen();
+ else if (MATCH("CASETESTEXPR", 12))
+ return_value = _readCaseTestExpr();
+ else if (MATCH("ARRAY", 5))
+ return_value = _readArrayExpr();
+ else if (MATCH("ROW", 3))
+ return_value = _readRowExpr();
+ else if (MATCH("ROWCOMPARE", 10))
+ return_value = _readRowCompareExpr();
+ else if (MATCH("COALESCE", 8))
+ return_value = _readCoalesceExpr();
+ else if (MATCH("MINMAX", 6))
+ return_value = _readMinMaxExpr();
+ else if (MATCH("SQLVALUEFUNCTION", 16))
+ return_value = _readSQLValueFunction();
+ else if (MATCH("XMLEXPR", 7))
+ return_value = _readXmlExpr();
+ else if (MATCH("NULLTEST", 8))
+ return_value = _readNullTest();
+ else if (MATCH("BOOLEANTEST", 11))
+ return_value = _readBooleanTest();
+ else if (MATCH("COERCETODOMAIN", 14))
+ return_value = _readCoerceToDomain();
+ else if (MATCH("COERCETODOMAINVALUE", 19))
+ return_value = _readCoerceToDomainValue();
+ else if (MATCH("SETTODEFAULT", 12))
+ return_value = _readSetToDefault();
+ else if (MATCH("CURRENTOFEXPR", 13))
+ return_value = _readCurrentOfExpr();
+ else if (MATCH("NEXTVALUEEXPR", 13))
+ return_value = _readNextValueExpr();
+ else if (MATCH("INFERENCEELEM", 13))
+ return_value = _readInferenceElem();
+ else if (MATCH("TARGETENTRY", 11))
+ return_value = _readTargetEntry();
+ else if (MATCH("RANGETBLREF", 11))
+ return_value = _readRangeTblRef();
+ else if (MATCH("JOINEXPR", 8))
+ return_value = _readJoinExpr();
+ else if (MATCH("FROMEXPR", 8))
+ return_value = _readFromExpr();
+ else if (MATCH("ONCONFLICTEXPR", 14))
+ return_value = _readOnConflictExpr();
+ else if (MATCH("APPENDRELINFO", 13))
+ return_value = _readAppendRelInfo();
+ else if (MATCH("RTE", 3))
+ return_value = _readRangeTblEntry();
+ else if (MATCH("RANGETBLFUNCTION", 16))
+ return_value = _readRangeTblFunction();
+ else if (MATCH("TABLESAMPLECLAUSE", 17))
+ return_value = _readTableSampleClause();
+ else if (MATCH("NOTIFY", 6))
+ return_value = _readNotifyStmt();
+ else if (MATCH("DEFELEM", 7))
+ return_value = _readDefElem();
+ else if (MATCH("DECLARECURSOR", 13))
+ return_value = _readDeclareCursorStmt();
+ else if (MATCH("PLANNEDSTMT", 11))
+ return_value = _readPlannedStmt();
+ else if (MATCH("PLAN", 4))
+ return_value = _readPlan();
+ else if (MATCH("RESULT", 6))
+ return_value = _readResult();
+ else if (MATCH("PROJECTSET", 10))
+ return_value = _readProjectSet();
+ else if (MATCH("MODIFYTABLE", 11))
+ return_value = _readModifyTable();
+ else if (MATCH("APPEND", 6))
+ return_value = _readAppend();
+ else if (MATCH("MERGEAPPEND", 11))
+ return_value = _readMergeAppend();
+ else if (MATCH("RECURSIVEUNION", 14))
+ return_value = _readRecursiveUnion();
+ else if (MATCH("BITMAPAND", 9))
+ return_value = _readBitmapAnd();
+ else if (MATCH("BITMAPOR", 8))
+ return_value = _readBitmapOr();
+ else if (MATCH("SCAN", 4))
+ return_value = _readScan();
+ else if (MATCH("SEQSCAN", 7))
+ return_value = _readSeqScan();
+ else if (MATCH("SAMPLESCAN", 10))
+ return_value = _readSampleScan();
+ else if (MATCH("INDEXSCAN", 9))
+ return_value = _readIndexScan();
+ else if (MATCH("INDEXONLYSCAN", 13))
+ return_value = _readIndexOnlyScan();
+ else if (MATCH("BITMAPINDEXSCAN", 15))
+ return_value = _readBitmapIndexScan();
+ else if (MATCH("BITMAPHEAPSCAN", 14))
+ return_value = _readBitmapHeapScan();
+ else if (MATCH("TIDSCAN", 7))
+ return_value = _readTidScan();
+ else if (MATCH("SUBQUERYSCAN", 12))
+ return_value = _readSubqueryScan();
+ else if (MATCH("FUNCTIONSCAN", 12))
+ return_value = _readFunctionScan();
+ else if (MATCH("VALUESSCAN", 10))
+ return_value = _readValuesScan();
+ else if (MATCH("TABLEFUNCSCAN", 13))
+ return_value = _readTableFuncScan();
+ else if (MATCH("CTESCAN", 7))
+ return_value = _readCteScan();
+ else if (MATCH("NAMEDTUPLESTORESCAN", 19))
+ return_value = _readNamedTuplestoreScan();
+ else if (MATCH("WORKTABLESCAN", 13))
+ return_value = _readWorkTableScan();
+ else if (MATCH("FOREIGNSCAN", 11))
+ return_value = _readForeignScan();
+ else if (MATCH("CUSTOMSCAN", 10))
+ return_value = _readCustomScan();
+ else if (MATCH("JOIN", 4))
+ return_value = _readJoin();
+ else if (MATCH("NESTLOOP", 8))
+ return_value = _readNestLoop();
+ else if (MATCH("MERGEJOIN", 9))
+ return_value = _readMergeJoin();
+ else if (MATCH("HASHJOIN", 8))
+ return_value = _readHashJoin();
+ else if (MATCH("MATERIAL", 8))
+ return_value = _readMaterial();
+ else if (MATCH("SORT", 4))
+ return_value = _readSort();
+ else if (MATCH("INCREMENTALSORT", 15))
+ return_value = _readIncrementalSort();
+ else if (MATCH("GROUP", 5))
+ return_value = _readGroup();
+ else if (MATCH("AGG", 3))
+ return_value = _readAgg();
+ else if (MATCH("WINDOWAGG", 9))
+ return_value = _readWindowAgg();
+ else if (MATCH("UNIQUE", 6))
+ return_value = _readUnique();
+ else if (MATCH("GATHER", 6))
+ return_value = _readGather();
+ else if (MATCH("GATHERMERGE", 11))
+ return_value = _readGatherMerge();
+ else if (MATCH("HASH", 4))
+ return_value = _readHash();
+ else if (MATCH("SETOP", 5))
+ return_value = _readSetOp();
+ else if (MATCH("LOCKROWS", 8))
+ return_value = _readLockRows();
+ else if (MATCH("LIMIT", 5))
+ return_value = _readLimit();
+ else if (MATCH("NESTLOOPPARAM", 13))
+ return_value = _readNestLoopParam();
+ else if (MATCH("PLANROWMARK", 11))
+ return_value = _readPlanRowMark();
+ else if (MATCH("PARTITIONPRUNEINFO", 18))
+ return_value = _readPartitionPruneInfo();
+ else if (MATCH("PARTITIONEDRELPRUNEINFO", 23))
+ return_value = _readPartitionedRelPruneInfo();
+ else if (MATCH("PARTITIONPRUNESTEPOP", 20))
+ return_value = _readPartitionPruneStepOp();
+ else if (MATCH("PARTITIONPRUNESTEPCOMBINE", 25))
+ return_value = _readPartitionPruneStepCombine();
+ else if (MATCH("PLANINVALITEM", 13))
+ return_value = _readPlanInvalItem();
+ else if (MATCH("SUBPLAN", 7))
+ return_value = _readSubPlan();
+ else if (MATCH("ALTERNATIVESUBPLAN", 18))
+ return_value = _readAlternativeSubPlan();
+ else if (MATCH("EXTENSIBLENODE", 14))
+ return_value = _readExtensibleNode();
+ else if (MATCH("PARTITIONBOUNDSPEC", 18))
+ return_value = _readPartitionBoundSpec();
+ else if (MATCH("PARTITIONRANGEDATUM", 19))
+ return_value = _readPartitionRangeDatum();
+ else
+ {
+ elog(ERROR, "badly formatted node string \"%.32s\"...", token);
+ return_value = NULL; /* keep compiler quiet */
+ }
+
+ return (Node *) return_value;
+}
+
+
+/*
+ * readDatum
+ *
+ * Given a string representation of a constant, recreate the appropriate
+ * Datum. The string representation embeds length info, but not byValue,
+ * so we must be told that.
+ */
+Datum
+readDatum(bool typbyval)
+{
+ Size length,
+ i;
+ int tokenLength;
+ const char *token;
+ Datum res;
+ char *s;
+
+ /*
+ * read the actual length of the value
+ */
+ token = pg_strtok(&tokenLength);
+ length = atoui(token);
+
+ token = pg_strtok(&tokenLength); /* read the '[' */
+ if (token == NULL || token[0] != '[')
+ elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %zu",
+ token ? token : "[NULL]", length);
+
+ if (typbyval)
+ {
+ if (length > (Size) sizeof(Datum))
+ elog(ERROR, "byval datum but length = %zu", length);
+ res = (Datum) 0;
+ s = (char *) (&res);
+ for (i = 0; i < (Size) sizeof(Datum); i++)
+ {
+ token = pg_strtok(&tokenLength);
+ s[i] = (char) atoi(token);
+ }
+ }
+ else if (length <= 0)
+ res = (Datum) NULL;
+ else
+ {
+ s = (char *) palloc(length);
+ for (i = 0; i < length; i++)
+ {
+ token = pg_strtok(&tokenLength);
+ s[i] = (char) atoi(token);
+ }
+ res = PointerGetDatum(s);
+ }
+
+ token = pg_strtok(&tokenLength); /* read the ']' */
+ if (token == NULL || token[0] != ']')
+ elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %zu",
+ token ? token : "[NULL]", length);
+
+ return res;
+}
+
+/*
+ * readAttrNumberCols
+ */
+AttrNumber *
+readAttrNumberCols(int numCols)
+{
+ int tokenLength,
+ i;
+ const char *token;
+ AttrNumber *attr_vals;
+
+ if (numCols <= 0)
+ return NULL;
+
+ attr_vals = (AttrNumber *) palloc(numCols * sizeof(AttrNumber));
+ for (i = 0; i < numCols; i++)
+ {
+ token = pg_strtok(&tokenLength);
+ attr_vals[i] = atoi(token);
+ }
+
+ return attr_vals;
+}
+
+/*
+ * readOidCols
+ */
+Oid *
+readOidCols(int numCols)
+{
+ int tokenLength,
+ i;
+ const char *token;
+ Oid *oid_vals;
+
+ if (numCols <= 0)
+ return NULL;
+
+ oid_vals = (Oid *) palloc(numCols * sizeof(Oid));
+ for (i = 0; i < numCols; i++)
+ {
+ token = pg_strtok(&tokenLength);
+ oid_vals[i] = atooid(token);
+ }
+
+ return oid_vals;
+}
+
+/*
+ * readIntCols
+ */
+int *
+readIntCols(int numCols)
+{
+ int tokenLength,
+ i;
+ const char *token;
+ int *int_vals;
+
+ if (numCols <= 0)
+ return NULL;
+
+ int_vals = (int *) palloc(numCols * sizeof(int));
+ for (i = 0; i < numCols; i++)
+ {
+ token = pg_strtok(&tokenLength);
+ int_vals[i] = atoi(token);
+ }
+
+ return int_vals;
+}
+
+/*
+ * readBoolCols
+ */
+bool *
+readBoolCols(int numCols)
+{
+ int tokenLength,
+ i;
+ const char *token;
+ bool *bool_vals;
+
+ if (numCols <= 0)
+ return NULL;
+
+ bool_vals = (bool *) palloc(numCols * sizeof(bool));
+ for (i = 0; i < numCols; i++)
+ {
+ token = pg_strtok(&tokenLength);
+ bool_vals[i] = strtobool(token);
+ }
+
+ return bool_vals;
+}