]> granicus.if.org Git - postgresql/blobdiff - src/backend/nodes/outfuncs.c
Change representation of statement lists, and add statement location info.
[postgresql] / src / backend / nodes / outfuncs.c
index bc891d391f56943030cfa27c20b77eed6da005f4..cf0a6059e91f280499946bfe51872423d09d5245 100644 (file)
@@ -3,7 +3,7 @@
  * outfuncs.c
  *       Output functions for Postgres tree nodes.
  *
- * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
  * NOTES
  *       Every node type that can appear in stored rules' parsetrees *must*
  *       have an output function defined here (as well as an input function
- *       in readfuncs.c).  For use in debugging, we also provide output
- *       functions for nodes that appear in raw parsetrees, path, and plan trees.
- *       These nodes however need not have input functions.
+ *       in readfuncs.c).  In addition, plan nodes should have input and
+ *       output functions so that they can be sent to parallel workers.
+ *       For use in debugging, we also provide output functions for nodes
+ *       that appear in raw parsetrees and path.  These nodes however need
+ *       not have input functions.
  *
  *-------------------------------------------------------------------------
  */
 #include <ctype.h>
 
 #include "lib/stringinfo.h"
+#include "nodes/extensible.h"
 #include "nodes/plannodes.h"
 #include "nodes/relation.h"
 #include "utils/datum.h"
+#include "utils/rel.h"
 
 
 /*
@@ -77,7 +81,7 @@
 /* Write a character-string (possibly NULL) field */
 #define WRITE_STRING_FIELD(fldname) \
        (appendStringInfo(str, " :" CppAsString(fldname) " "), \
-        _outToken(str, node->fldname))
+        outToken(str, node->fldname))
 
 /* Write a parse location field (actually same as INT case) */
 #define WRITE_LOCATION_FIELD(fldname) \
 /* Write a Node field */
 #define WRITE_NODE_FIELD(fldname) \
        (appendStringInfo(str, " :" CppAsString(fldname) " "), \
-        _outNode(str, node->fldname))
+        outNode(str, node->fldname))
 
 /* Write a bitmapset field */
 #define WRITE_BITMAPSET_FIELD(fldname) \
        (appendStringInfo(str, " :" CppAsString(fldname) " "), \
-        _outBitmapset(str, node->fldname))
+        outBitmapset(str, node->fldname))
 
 
 #define booltostr(x)  ((x) ? "true" : "false")
 
-static void _outNode(StringInfo str, const void *obj);
-
 
 /*
- * _outToken
+ * outToken
  *       Convert an ordinary string (eg, an identifier) into a form that
  *       will be decoded back to a plain token by read.c's functions.
  *
  *       If a null or empty string is given, it is encoded as "<>".
  */
-static void
-_outToken(StringInfo str, const char *s)
+void
+outToken(StringInfo str, const char *s)
 {
        if (s == NULL || *s == '\0')
        {
@@ -122,7 +124,7 @@ _outToken(StringInfo str, const char *s)
         */
        /* These characters only need to be quoted at the start of the string */
        if (*s == '<' ||
-               *s == '\"' ||
+               *s == '"' ||
                isdigit((unsigned char) *s) ||
                ((*s == '+' || *s == '-') &&
                 (isdigit((unsigned char) s[1]) || s[1] == '.')))
@@ -159,7 +161,7 @@ _outList(StringInfo str, const List *node)
                 */
                if (IsA(node, List))
                {
-                       _outNode(str, lfirst(lc));
+                       outNode(str, lfirst(lc));
                        if (lnext(lc))
                                appendStringInfoChar(str, ' ');
                }
@@ -176,13 +178,13 @@ _outList(StringInfo str, const List *node)
 }
 
 /*
- * _outBitmapset -
+ * outBitmapset -
  *        converts a bitmap set of integers
  *
  * Note: the output format is "(b int int ...)", similar to an integer List.
  */
-static void
-_outBitmapset(StringInfo str, const Bitmapset *bms)
+void
+outBitmapset(StringInfo str, const Bitmapset *bms)
 {
        int                     x;
 
@@ -197,8 +199,8 @@ _outBitmapset(StringInfo str, const Bitmapset *bms)
 /*
  * Print the value of a Datum given its type.
  */
-static void
-_outDatum(StringInfo str, Datum value, int typlen, bool typbyval)
+void
+outDatum(StringInfo str, Datum value, int typlen, bool typbyval)
 {
        Size            length,
                                i;
@@ -243,20 +245,22 @@ _outPlannedStmt(StringInfo str, const PlannedStmt *node)
        WRITE_UINT_FIELD(queryId);
        WRITE_BOOL_FIELD(hasReturning);
        WRITE_BOOL_FIELD(hasModifyingCTE);
-       WRITE_BOOL_FIELD(isUpsert);
        WRITE_BOOL_FIELD(canSetTag);
        WRITE_BOOL_FIELD(transientPlan);
+       WRITE_BOOL_FIELD(dependsOnRole);
+       WRITE_BOOL_FIELD(parallelModeNeeded);
        WRITE_NODE_FIELD(planTree);
        WRITE_NODE_FIELD(rtable);
        WRITE_NODE_FIELD(resultRelations);
-       WRITE_NODE_FIELD(utilityStmt);
        WRITE_NODE_FIELD(subplans);
        WRITE_BITMAPSET_FIELD(rewindPlanIDs);
        WRITE_NODE_FIELD(rowMarks);
        WRITE_NODE_FIELD(relationOids);
        WRITE_NODE_FIELD(invalItems);
        WRITE_INT_FIELD(nParamExec);
-       WRITE_BOOL_FIELD(hasRowSecurity);
+       WRITE_NODE_FIELD(utilityStmt);
+       WRITE_LOCATION_FIELD(stmt_location);
+       WRITE_LOCATION_FIELD(stmt_len);
 }
 
 /*
@@ -269,6 +273,8 @@ _outPlanInfo(StringInfo str, const Plan *node)
        WRITE_FLOAT_FIELD(total_cost, "%.2f");
        WRITE_FLOAT_FIELD(plan_rows, "%.0f");
        WRITE_INT_FIELD(plan_width);
+       WRITE_BOOL_FIELD(parallel_aware);
+       WRITE_INT_FIELD(plan_node_id);
        WRITE_NODE_FIELD(targetlist);
        WRITE_NODE_FIELD(qual);
        WRITE_NODE_FIELD(lefttree);
@@ -336,13 +342,14 @@ _outModifyTable(StringInfo str, const ModifyTable *node)
        WRITE_NODE_FIELD(withCheckOptionLists);
        WRITE_NODE_FIELD(returningLists);
        WRITE_NODE_FIELD(fdwPrivLists);
+       WRITE_BITMAPSET_FIELD(fdwDirectModifyPlans);
        WRITE_NODE_FIELD(rowMarks);
        WRITE_INT_FIELD(epqParam);
        WRITE_ENUM_FIELD(onConflictAction, OnConflictAction);
        WRITE_NODE_FIELD(arbiterIndexes);
        WRITE_NODE_FIELD(onConflictSet);
        WRITE_NODE_FIELD(onConflictWhere);
-       WRITE_INT_FIELD(exclRelRTI);
+       WRITE_UINT_FIELD(exclRelRTI);
        WRITE_NODE_FIELD(exclRelTlist);
 }
 
@@ -429,6 +436,18 @@ _outBitmapOr(StringInfo str, const BitmapOr *node)
        WRITE_NODE_FIELD(bitmapplans);
 }
 
+static void
+_outGather(StringInfo str, const Gather *node)
+{
+       WRITE_NODE_TYPE("GATHER");
+
+       _outPlanInfo(str, (const Plan *) node);
+
+       WRITE_INT_FIELD(num_workers);
+       WRITE_BOOL_FIELD(single_copy);
+       WRITE_BOOL_FIELD(invisible);
+}
+
 static void
 _outScan(StringInfo str, const Scan *node)
 {
@@ -445,6 +464,16 @@ _outSeqScan(StringInfo str, const SeqScan *node)
        _outScanInfo(str, (const Scan *) node);
 }
 
+static void
+_outSampleScan(StringInfo str, const SampleScan *node)
+{
+       WRITE_NODE_TYPE("SAMPLESCAN");
+
+       _outScanInfo(str, (const Scan *) node);
+
+       WRITE_NODE_FIELD(tablesample);
+}
+
 static void
 _outIndexScan(StringInfo str, const IndexScan *node)
 {
@@ -457,6 +486,7 @@ _outIndexScan(StringInfo str, const IndexScan *node)
        WRITE_NODE_FIELD(indexqualorig);
        WRITE_NODE_FIELD(indexorderby);
        WRITE_NODE_FIELD(indexorderbyorig);
+       WRITE_NODE_FIELD(indexorderbyops);
        WRITE_ENUM_FIELD(indexorderdir, ScanDirection);
 }
 
@@ -565,11 +595,13 @@ _outForeignScan(StringInfo str, const ForeignScan *node)
 
        _outScanInfo(str, (const Scan *) node);
 
-       WRITE_OID_FIELD(fdw_handler);
+       WRITE_ENUM_FIELD(operation, CmdType);
+       WRITE_OID_FIELD(fs_server);
        WRITE_NODE_FIELD(fdw_exprs);
-       WRITE_NODE_FIELD(fdw_ps_tlist);
        WRITE_NODE_FIELD(fdw_private);
-       WRITE_BITMAPSET_FIELD(fdw_relids);
+       WRITE_NODE_FIELD(fdw_scan_tlist);
+       WRITE_NODE_FIELD(fdw_recheck_quals);
+       WRITE_BITMAPSET_FIELD(fs_relids);
        WRITE_BOOL_FIELD(fsSystemCol);
 }
 
@@ -581,14 +613,14 @@ _outCustomScan(StringInfo str, const CustomScan *node)
        _outScanInfo(str, (const Scan *) node);
 
        WRITE_UINT_FIELD(flags);
+       WRITE_NODE_FIELD(custom_plans);
        WRITE_NODE_FIELD(custom_exprs);
-       WRITE_NODE_FIELD(custom_ps_tlist);
        WRITE_NODE_FIELD(custom_private);
+       WRITE_NODE_FIELD(custom_scan_tlist);
        WRITE_BITMAPSET_FIELD(custom_relids);
+       /* CustomName is a key to lookup CustomScanMethods */
        appendStringInfoString(str, " :methods ");
-       _outToken(str, node->methods->CustomName);
-       if (node->methods->TextOutCustomScan)
-               node->methods->TextOutCustomScan(str, node);
+       outToken(str, node->methods->CustomName);
 }
 
 static void
@@ -637,7 +669,7 @@ _outMergeJoin(StringInfo str, const MergeJoin *node)
 
        appendStringInfoString(str, " :mergeNullsFirst");
        for (i = 0; i < numCols; i++)
-               appendStringInfo(str, " %d", (int) node->mergeNullsFirst[i]);
+               appendStringInfo(str, " %s", booltostr(node->mergeNullsFirst[i]));
 }
 
 static void
@@ -660,6 +692,7 @@ _outAgg(StringInfo str, const Agg *node)
        _outPlanInfo(str, (const Plan *) node);
 
        WRITE_ENUM_FIELD(aggstrategy, AggStrategy);
+       WRITE_ENUM_FIELD(aggsplit, AggSplit);
        WRITE_INT_FIELD(numCols);
 
        appendStringInfoString(str, " :grpColIdx");
@@ -671,6 +704,9 @@ _outAgg(StringInfo str, const Agg *node)
                appendStringInfo(str, " %u", node->grpOperators[i]);
 
        WRITE_LONG_FIELD(numGroups);
+       WRITE_BITMAPSET_FIELD(aggParams);
+       WRITE_NODE_FIELD(groupingSets);
+       WRITE_NODE_FIELD(chain);
 }
 
 static void
@@ -905,7 +941,7 @@ _outRangeVar(StringInfo str, const RangeVar *node)
         */
        WRITE_STRING_FIELD(schemaname);
        WRITE_STRING_FIELD(relname);
-       WRITE_ENUM_FIELD(inhOpt, InhOption);
+       WRITE_BOOL_FIELD(inh);
        WRITE_CHAR_FIELD(relpersistence);
        WRITE_NODE_FIELD(alias);
        WRITE_LOCATION_FIELD(location);
@@ -958,7 +994,7 @@ _outConst(StringInfo str, const Const *node)
        if (node->constisnull)
                appendStringInfoString(str, "<>");
        else
-               _outDatum(str, node->constvalue, node->constlen, node->constbyval);
+               outDatum(str, node->constvalue, node->constlen, node->constbyval);
 }
 
 static void
@@ -983,6 +1019,8 @@ _outAggref(StringInfo str, const Aggref *node)
        WRITE_OID_FIELD(aggtype);
        WRITE_OID_FIELD(aggcollid);
        WRITE_OID_FIELD(inputcollid);
+       WRITE_OID_FIELD(aggtranstype);
+       WRITE_NODE_FIELD(aggargtypes);
        WRITE_NODE_FIELD(aggdirectargs);
        WRITE_NODE_FIELD(args);
        WRITE_NODE_FIELD(aggorder);
@@ -992,6 +1030,19 @@ _outAggref(StringInfo str, const Aggref *node)
        WRITE_BOOL_FIELD(aggvariadic);
        WRITE_CHAR_FIELD(aggkind);
        WRITE_UINT_FIELD(agglevelsup);
+       WRITE_ENUM_FIELD(aggsplit, AggSplit);
+       WRITE_LOCATION_FIELD(location);
+}
+
+static void
+_outGroupingFunc(StringInfo str, const GroupingFunc *node)
+{
+       WRITE_NODE_TYPE("GROUPINGFUNC");
+
+       WRITE_NODE_FIELD(args);
+       WRITE_NODE_FIELD(refs);
+       WRITE_NODE_FIELD(cols);
+       WRITE_UINT_FIELD(agglevelsup);
        WRITE_LOCATION_FIELD(location);
 }
 
@@ -1133,7 +1184,7 @@ _outBoolExpr(StringInfo str, const BoolExpr *node)
                        break;
        }
        appendStringInfoString(str, " :boolop ");
-       _outToken(str, opstr);
+       outToken(str, opstr);
 
        WRITE_NODE_FIELD(args);
        WRITE_LOCATION_FIELD(location);
@@ -1361,6 +1412,17 @@ _outMinMaxExpr(StringInfo str, const MinMaxExpr *node)
        WRITE_LOCATION_FIELD(location);
 }
 
+static void
+_outSQLValueFunction(StringInfo str, const SQLValueFunction *node)
+{
+       WRITE_NODE_TYPE("SQLVALUEFUNCTION");
+
+       WRITE_ENUM_FIELD(op, SQLValueFunctionOp);
+       WRITE_OID_FIELD(type);
+       WRITE_INT_FIELD(typmod);
+       WRITE_LOCATION_FIELD(location);
+}
+
 static void
 _outXmlExpr(StringInfo str, const XmlExpr *node)
 {
@@ -1450,8 +1512,7 @@ _outInferenceElem(StringInfo str, const InferenceElem *node)
 
        WRITE_NODE_FIELD(expr);
        WRITE_OID_FIELD(infercollid);
-       WRITE_OID_FIELD(inferopfamily);
-       WRITE_OID_FIELD(inferopcinputtype);
+       WRITE_OID_FIELD(inferopclass);
 }
 
 static void
@@ -1508,9 +1569,9 @@ _outOnConflictExpr(StringInfo str, const OnConflictExpr *node)
        WRITE_ENUM_FIELD(action, OnConflictAction);
        WRITE_NODE_FIELD(arbiterElems);
        WRITE_NODE_FIELD(arbiterWhere);
+       WRITE_OID_FIELD(constraint);
        WRITE_NODE_FIELD(onConflictSet);
        WRITE_NODE_FIELD(onConflictWhere);
-       WRITE_OID_FIELD(constraint);
        WRITE_INT_FIELD(exclRelIndex);
        WRITE_NODE_FIELD(exclRelTlist);
 }
@@ -1526,6 +1587,7 @@ _outOnConflictExpr(StringInfo str, const OnConflictExpr *node)
  *
  * Note we do NOT print the parent, else we'd be in infinite recursion.
  * We can print the parent's relids for identification purposes, though.
+ * We print the pathtarget only if it's not the default one for the rel.
  * We also do not print the whole of param_info, since it's printed by
  * _outRelOptInfo; it's sufficient and less cluttering to print just the
  * required outer relids.
@@ -1535,15 +1597,17 @@ _outPathInfo(StringInfo str, const Path *node)
 {
        WRITE_ENUM_FIELD(pathtype, NodeTag);
        appendStringInfoString(str, " :parent_relids ");
-       if (node->parent)
-               _outBitmapset(str, node->parent->relids);
-       else
-               _outBitmapset(str, NULL);
+       outBitmapset(str, node->parent->relids);
+       if (node->pathtarget != node->parent->reltarget)
+               WRITE_NODE_FIELD(pathtarget);
        appendStringInfoString(str, " :required_outer ");
        if (node->param_info)
-               _outBitmapset(str, node->param_info->ppi_req_outer);
+               outBitmapset(str, node->param_info->ppi_req_outer);
        else
-               _outBitmapset(str, NULL);
+               outBitmapset(str, NULL);
+       WRITE_BOOL_FIELD(parallel_aware);
+       WRITE_BOOL_FIELD(parallel_safe);
+       WRITE_INT_FIELD(parallel_workers);
        WRITE_FLOAT_FIELD(rows, "%.0f");
        WRITE_FLOAT_FIELD(startup_cost, "%.2f");
        WRITE_FLOAT_FIELD(total_cost, "%.2f");
@@ -1632,6 +1696,16 @@ _outTidPath(StringInfo str, const TidPath *node)
        WRITE_NODE_FIELD(tidquals);
 }
 
+static void
+_outSubqueryScanPath(StringInfo str, const SubqueryScanPath *node)
+{
+       WRITE_NODE_TYPE("SUBQUERYSCANPATH");
+
+       _outPathInfo(str, (const Path *) node);
+
+       WRITE_NODE_FIELD(subpath);
+}
+
 static void
 _outForeignPath(StringInfo str, const ForeignPath *node)
 {
@@ -1639,6 +1713,7 @@ _outForeignPath(StringInfo str, const ForeignPath *node)
 
        _outPathInfo(str, (const Path *) node);
 
+       WRITE_NODE_FIELD(fdw_outerpath);
        WRITE_NODE_FIELD(fdw_private);
 }
 
@@ -1650,11 +1725,10 @@ _outCustomPath(StringInfo str, const CustomPath *node)
        _outPathInfo(str, (const Path *) node);
 
        WRITE_UINT_FIELD(flags);
+       WRITE_NODE_FIELD(custom_paths);
        WRITE_NODE_FIELD(custom_private);
        appendStringInfoString(str, " :methods ");
-       _outToken(str, node->methods->CustomName);
-       if (node->methods->TextOutCustomPath)
-               node->methods->TextOutCustomPath(str, node);
+       outToken(str, node->methods->CustomName);
 }
 
 static void
@@ -1711,6 +1785,186 @@ _outUniquePath(StringInfo str, const UniquePath *node)
        WRITE_NODE_FIELD(uniq_exprs);
 }
 
+static void
+_outGatherPath(StringInfo str, const GatherPath *node)
+{
+       WRITE_NODE_TYPE("GATHERPATH");
+
+       _outPathInfo(str, (const Path *) node);
+
+       WRITE_NODE_FIELD(subpath);
+       WRITE_BOOL_FIELD(single_copy);
+}
+
+static void
+_outProjectionPath(StringInfo str, const ProjectionPath *node)
+{
+       WRITE_NODE_TYPE("PROJECTIONPATH");
+
+       _outPathInfo(str, (const Path *) node);
+
+       WRITE_NODE_FIELD(subpath);
+       WRITE_BOOL_FIELD(dummypp);
+}
+
+static void
+_outSortPath(StringInfo str, const SortPath *node)
+{
+       WRITE_NODE_TYPE("SORTPATH");
+
+       _outPathInfo(str, (const Path *) node);
+
+       WRITE_NODE_FIELD(subpath);
+}
+
+static void
+_outGroupPath(StringInfo str, const GroupPath *node)
+{
+       WRITE_NODE_TYPE("GROUPPATH");
+
+       _outPathInfo(str, (const Path *) node);
+
+       WRITE_NODE_FIELD(subpath);
+       WRITE_NODE_FIELD(groupClause);
+       WRITE_NODE_FIELD(qual);
+}
+
+static void
+_outUpperUniquePath(StringInfo str, const UpperUniquePath *node)
+{
+       WRITE_NODE_TYPE("UPPERUNIQUEPATH");
+
+       _outPathInfo(str, (const Path *) node);
+
+       WRITE_NODE_FIELD(subpath);
+       WRITE_INT_FIELD(numkeys);
+}
+
+static void
+_outAggPath(StringInfo str, const AggPath *node)
+{
+       WRITE_NODE_TYPE("AGGPATH");
+
+       _outPathInfo(str, (const Path *) node);
+
+       WRITE_NODE_FIELD(subpath);
+       WRITE_ENUM_FIELD(aggstrategy, AggStrategy);
+       WRITE_ENUM_FIELD(aggsplit, AggSplit);
+       WRITE_FLOAT_FIELD(numGroups, "%.0f");
+       WRITE_NODE_FIELD(groupClause);
+       WRITE_NODE_FIELD(qual);
+}
+
+static void
+_outGroupingSetsPath(StringInfo str, const GroupingSetsPath *node)
+{
+       WRITE_NODE_TYPE("GROUPINGSETSPATH");
+
+       _outPathInfo(str, (const Path *) node);
+
+       WRITE_NODE_FIELD(subpath);
+       WRITE_NODE_FIELD(rollup_groupclauses);
+       WRITE_NODE_FIELD(rollup_lists);
+       WRITE_NODE_FIELD(qual);
+}
+
+static void
+_outMinMaxAggPath(StringInfo str, const MinMaxAggPath *node)
+{
+       WRITE_NODE_TYPE("MINMAXAGGPATH");
+
+       _outPathInfo(str, (const Path *) node);
+
+       WRITE_NODE_FIELD(mmaggregates);
+       WRITE_NODE_FIELD(quals);
+}
+
+static void
+_outWindowAggPath(StringInfo str, const WindowAggPath *node)
+{
+       WRITE_NODE_TYPE("WINDOWAGGPATH");
+
+       _outPathInfo(str, (const Path *) node);
+
+       WRITE_NODE_FIELD(subpath);
+       WRITE_NODE_FIELD(winclause);
+       WRITE_NODE_FIELD(winpathkeys);
+}
+
+static void
+_outSetOpPath(StringInfo str, const SetOpPath *node)
+{
+       WRITE_NODE_TYPE("SETOPPATH");
+
+       _outPathInfo(str, (const Path *) node);
+
+       WRITE_NODE_FIELD(subpath);
+       WRITE_ENUM_FIELD(cmd, SetOpCmd);
+       WRITE_ENUM_FIELD(strategy, SetOpStrategy);
+       WRITE_NODE_FIELD(distinctList);
+       WRITE_INT_FIELD(flagColIdx);
+       WRITE_INT_FIELD(firstFlag);
+       WRITE_FLOAT_FIELD(numGroups, "%.0f");
+}
+
+static void
+_outRecursiveUnionPath(StringInfo str, const RecursiveUnionPath *node)
+{
+       WRITE_NODE_TYPE("RECURSIVEUNIONPATH");
+
+       _outPathInfo(str, (const Path *) node);
+
+       WRITE_NODE_FIELD(leftpath);
+       WRITE_NODE_FIELD(rightpath);
+       WRITE_NODE_FIELD(distinctList);
+       WRITE_INT_FIELD(wtParam);
+       WRITE_FLOAT_FIELD(numGroups, "%.0f");
+}
+
+static void
+_outLockRowsPath(StringInfo str, const LockRowsPath *node)
+{
+       WRITE_NODE_TYPE("LOCKROWSPATH");
+
+       _outPathInfo(str, (const Path *) node);
+
+       WRITE_NODE_FIELD(subpath);
+       WRITE_NODE_FIELD(rowMarks);
+       WRITE_INT_FIELD(epqParam);
+}
+
+static void
+_outModifyTablePath(StringInfo str, const ModifyTablePath *node)
+{
+       WRITE_NODE_TYPE("MODIFYTABLEPATH");
+
+       _outPathInfo(str, (const Path *) node);
+
+       WRITE_ENUM_FIELD(operation, CmdType);
+       WRITE_BOOL_FIELD(canSetTag);
+       WRITE_UINT_FIELD(nominalRelation);
+       WRITE_NODE_FIELD(resultRelations);
+       WRITE_NODE_FIELD(subpaths);
+       WRITE_NODE_FIELD(subroots);
+       WRITE_NODE_FIELD(withCheckOptionLists);
+       WRITE_NODE_FIELD(returningLists);
+       WRITE_NODE_FIELD(rowMarks);
+       WRITE_NODE_FIELD(onconflict);
+       WRITE_INT_FIELD(epqParam);
+}
+
+static void
+_outLimitPath(StringInfo str, const LimitPath *node)
+{
+       WRITE_NODE_TYPE("LIMITPATH");
+
+       _outPathInfo(str, (const Path *) node);
+
+       WRITE_NODE_FIELD(subpath);
+       WRITE_NODE_FIELD(limitOffset);
+       WRITE_NODE_FIELD(limitCount);
+}
+
 static void
 _outNestPath(StringInfo str, const NestPath *node)
 {
@@ -1759,8 +2013,12 @@ _outPlannerGlobal(StringInfo str, const PlannerGlobal *node)
        WRITE_INT_FIELD(nParamExec);
        WRITE_UINT_FIELD(lastPHId);
        WRITE_UINT_FIELD(lastRowMarkId);
+       WRITE_INT_FIELD(lastPlanNodeId);
        WRITE_BOOL_FIELD(transientPlan);
-       WRITE_BOOL_FIELD(hasRowSecurity);
+       WRITE_BOOL_FIELD(dependsOnRole);
+       WRITE_BOOL_FIELD(parallelModeOK);
+       WRITE_BOOL_FIELD(parallelModeNeeded);
+       WRITE_CHAR_FIELD(maxParallelHazard);
 }
 
 static void
@@ -1773,6 +2031,7 @@ _outPlannerInfo(StringInfo str, const PlannerInfo *node)
        WRITE_NODE_FIELD(glob);
        WRITE_UINT_FIELD(query_level);
        WRITE_NODE_FIELD(plan_params);
+       WRITE_BITMAPSET_FIELD(outer_params);
        WRITE_BITMAPSET_FIELD(all_baserels);
        WRITE_BITMAPSET_FIELD(nullable_baserels);
        WRITE_NODE_FIELD(join_rel_list);
@@ -1786,15 +2045,16 @@ _outPlannerInfo(StringInfo str, const PlannerInfo *node)
        WRITE_NODE_FIELD(right_join_clauses);
        WRITE_NODE_FIELD(full_join_clauses);
        WRITE_NODE_FIELD(join_info_list);
-       WRITE_NODE_FIELD(lateral_info_list);
        WRITE_NODE_FIELD(append_rel_list);
        WRITE_NODE_FIELD(rowMarks);
        WRITE_NODE_FIELD(placeholder_list);
+       WRITE_NODE_FIELD(fkey_list);
        WRITE_NODE_FIELD(query_pathkeys);
        WRITE_NODE_FIELD(group_pathkeys);
        WRITE_NODE_FIELD(window_pathkeys);
        WRITE_NODE_FIELD(distinct_pathkeys);
        WRITE_NODE_FIELD(sort_pathkeys);
+       WRITE_NODE_FIELD(processed_tlist);
        WRITE_NODE_FIELD(minmax_aggs);
        WRITE_FLOAT_FIELD(total_table_pages, "%.0f");
        WRITE_FLOAT_FIELD(tuple_fraction, "%.4f");
@@ -1820,30 +2080,36 @@ _outRelOptInfo(StringInfo str, const RelOptInfo *node)
        WRITE_ENUM_FIELD(reloptkind, RelOptKind);
        WRITE_BITMAPSET_FIELD(relids);
        WRITE_FLOAT_FIELD(rows, "%.0f");
-       WRITE_INT_FIELD(width);
        WRITE_BOOL_FIELD(consider_startup);
-       WRITE_NODE_FIELD(reltargetlist);
+       WRITE_BOOL_FIELD(consider_param_startup);
+       WRITE_BOOL_FIELD(consider_parallel);
+       WRITE_NODE_FIELD(reltarget);
        WRITE_NODE_FIELD(pathlist);
        WRITE_NODE_FIELD(ppilist);
+       WRITE_NODE_FIELD(partial_pathlist);
        WRITE_NODE_FIELD(cheapest_startup_path);
        WRITE_NODE_FIELD(cheapest_total_path);
        WRITE_NODE_FIELD(cheapest_unique_path);
        WRITE_NODE_FIELD(cheapest_parameterized_paths);
+       WRITE_BITMAPSET_FIELD(direct_lateral_relids);
+       WRITE_BITMAPSET_FIELD(lateral_relids);
        WRITE_UINT_FIELD(relid);
        WRITE_OID_FIELD(reltablespace);
        WRITE_ENUM_FIELD(rtekind, RTEKind);
        WRITE_INT_FIELD(min_attr);
        WRITE_INT_FIELD(max_attr);
        WRITE_NODE_FIELD(lateral_vars);
-       WRITE_BITMAPSET_FIELD(lateral_relids);
        WRITE_BITMAPSET_FIELD(lateral_referencers);
        WRITE_NODE_FIELD(indexlist);
        WRITE_UINT_FIELD(pages);
        WRITE_FLOAT_FIELD(tuples, "%.0f");
        WRITE_FLOAT_FIELD(allvisfrac, "%.6f");
-       WRITE_NODE_FIELD(subplan);
        WRITE_NODE_FIELD(subroot);
        WRITE_NODE_FIELD(subplan_params);
+       WRITE_INT_FIELD(rel_parallel_workers);
+       WRITE_OID_FIELD(serverid);
+       WRITE_OID_FIELD(userid);
+       WRITE_BOOL_FIELD(useridiscurrent);
        /* we don't try to print fdwroutine or fdw_private */
        WRITE_NODE_FIELD(baserestrictinfo);
        WRITE_NODE_FIELD(joininfo);
@@ -1867,11 +2133,43 @@ _outIndexOptInfo(StringInfo str, const IndexOptInfo *node)
        /* indexprs is redundant since we print indextlist */
        WRITE_NODE_FIELD(indpred);
        WRITE_NODE_FIELD(indextlist);
+       WRITE_NODE_FIELD(indrestrictinfo);
        WRITE_BOOL_FIELD(predOK);
        WRITE_BOOL_FIELD(unique);
        WRITE_BOOL_FIELD(immediate);
        WRITE_BOOL_FIELD(hypothetical);
-       /* we don't bother with fields copied from the pg_am entry */
+       /* we don't bother with fields copied from the index AM's API struct */
+}
+
+static void
+_outForeignKeyOptInfo(StringInfo str, const ForeignKeyOptInfo *node)
+{
+       int                     i;
+
+       WRITE_NODE_TYPE("FOREIGNKEYOPTINFO");
+
+       WRITE_UINT_FIELD(con_relid);
+       WRITE_UINT_FIELD(ref_relid);
+       WRITE_INT_FIELD(nkeys);
+       appendStringInfoString(str, " :conkey");
+       for (i = 0; i < node->nkeys; i++)
+               appendStringInfo(str, " %d", node->conkey[i]);
+       appendStringInfoString(str, " :confkey");
+       for (i = 0; i < node->nkeys; i++)
+               appendStringInfo(str, " %d", node->confkey[i]);
+       appendStringInfoString(str, " :conpfeqop");
+       for (i = 0; i < node->nkeys; i++)
+               appendStringInfo(str, " %u", node->conpfeqop[i]);
+       WRITE_INT_FIELD(nmatched_ec);
+       WRITE_INT_FIELD(nmatched_rcols);
+       WRITE_INT_FIELD(nmatched_ri);
+       /* for compactness, just print the number of matches per column: */
+       appendStringInfoString(str, " :eclass");
+       for (i = 0; i < node->nkeys; i++)
+               appendStringInfo(str, " %d", (node->eclass[i] != NULL));
+       appendStringInfoString(str, " :rinfos");
+       for (i = 0; i < node->nkeys; i++)
+               appendStringInfo(str, " %d", list_length(node->rinfos[i]));
 }
 
 static void
@@ -1923,6 +2221,25 @@ _outPathKey(StringInfo str, const PathKey *node)
        WRITE_BOOL_FIELD(pk_nulls_first);
 }
 
+static void
+_outPathTarget(StringInfo str, const PathTarget *node)
+{
+       WRITE_NODE_TYPE("PATHTARGET");
+
+       WRITE_NODE_FIELD(exprs);
+       if (node->sortgrouprefs)
+       {
+               int                     i;
+
+               appendStringInfoString(str, " :sortgrouprefs");
+               for (i = 0; i < list_length(node->exprs); i++)
+                       appendStringInfo(str, " %u", node->sortgrouprefs[i]);
+       }
+       WRITE_FLOAT_FIELD(cost.startup, "%.2f");
+       WRITE_FLOAT_FIELD(cost.per_tuple, "%.2f");
+       WRITE_INT_FIELD(width);
+}
+
 static void
 _outParamPathInfo(StringInfo str, const ParamPathInfo *node)
 {
@@ -1992,15 +2309,6 @@ _outSpecialJoinInfo(StringInfo str, const SpecialJoinInfo *node)
        WRITE_NODE_FIELD(semi_rhs_exprs);
 }
 
-static void
-_outLateralJoinInfo(StringInfo str, const LateralJoinInfo *node)
-{
-       WRITE_NODE_TYPE("LATERALJOININFO");
-
-       WRITE_BITMAPSET_FIELD(lateral_lhs);
-       WRITE_BITMAPSET_FIELD(lateral_rhs);
-}
-
 static void
 _outAppendRelInfo(StringInfo str, const AppendRelInfo *node)
 {
@@ -2050,6 +2358,27 @@ _outPlannerParamItem(StringInfo str, const PlannerParamItem *node)
        WRITE_INT_FIELD(paramId);
 }
 
+/*****************************************************************************
+ *
+ *     Stuff from extensible.h
+ *
+ *****************************************************************************/
+
+static void
+_outExtensibleNode(StringInfo str, const ExtensibleNode *node)
+{
+       const ExtensibleNodeMethods *methods;
+
+       methods = GetExtensibleNodeMethods(node->extnodename, false);
+
+       WRITE_NODE_TYPE("EXTENSIBLENODE");
+
+       WRITE_STRING_FIELD(extnodename);
+
+       /* serialize the private fields */
+       methods->nodeOut(str, node);
+}
+
 /*****************************************************************************
  *
  *     Stuff from parsenodes.h.
@@ -2065,6 +2394,8 @@ _outCreateStmtInfo(StringInfo str, const CreateStmt *node)
        WRITE_NODE_FIELD(relation);
        WRITE_NODE_FIELD(tableElts);
        WRITE_NODE_FIELD(inhRelations);
+       WRITE_NODE_FIELD(partspec);
+       WRITE_NODE_FIELD(partbound);
        WRITE_NODE_FIELD(ofTypename);
        WRITE_NODE_FIELD(constraints);
        WRITE_NODE_FIELD(options);
@@ -2201,6 +2532,7 @@ _outDefElem(StringInfo str, const DefElem *node)
        WRITE_STRING_FIELD(defname);
        WRITE_NODE_FIELD(arg);
        WRITE_ENUM_FIELD(defaction, DefElemAction);
+       WRITE_LOCATION_FIELD(location);
 }
 
 static void
@@ -2233,6 +2565,16 @@ _outXmlSerialize(StringInfo str, const XmlSerialize *node)
        WRITE_LOCATION_FIELD(location);
 }
 
+static void
+_outTriggerTransition(StringInfo str, const TriggerTransition *node)
+{
+       WRITE_NODE_TYPE("TRIGGERTRANSITION");
+
+       WRITE_STRING_FIELD(name);
+       WRITE_BOOL_FIELD(isNew);
+       WRITE_BOOL_FIELD(isTable);
+}
+
 static void
 _outColumnDef(StringInfo str, const ColumnDef *node)
 {
@@ -2341,6 +2683,7 @@ _outQuery(StringInfo str, const Query *node)
        WRITE_INT_FIELD(resultRelation);
        WRITE_BOOL_FIELD(hasAggs);
        WRITE_BOOL_FIELD(hasWindowFuncs);
+       WRITE_BOOL_FIELD(hasTargetSRFs);
        WRITE_BOOL_FIELD(hasSubLinks);
        WRITE_BOOL_FIELD(hasDistinctOn);
        WRITE_BOOL_FIELD(hasRecursive);
@@ -2351,10 +2694,10 @@ _outQuery(StringInfo str, const Query *node)
        WRITE_NODE_FIELD(rtable);
        WRITE_NODE_FIELD(jointree);
        WRITE_NODE_FIELD(targetList);
-       WRITE_NODE_FIELD(withCheckOptions);
        WRITE_NODE_FIELD(onConflict);
        WRITE_NODE_FIELD(returningList);
        WRITE_NODE_FIELD(groupClause);
+       WRITE_NODE_FIELD(groupingSets);
        WRITE_NODE_FIELD(havingQual);
        WRITE_NODE_FIELD(windowClause);
        WRITE_NODE_FIELD(distinctClause);
@@ -2364,6 +2707,9 @@ _outQuery(StringInfo str, const Query *node)
        WRITE_NODE_FIELD(rowMarks);
        WRITE_NODE_FIELD(setOperations);
        WRITE_NODE_FIELD(constraintDeps);
+       /* withCheckOptions intentionally omitted, see comment in parsenodes.h */
+       WRITE_LOCATION_FIELD(stmt_location);
+       WRITE_LOCATION_FIELD(stmt_len);
 }
 
 static void
@@ -2373,6 +2719,7 @@ _outWithCheckOption(StringInfo str, const WithCheckOption *node)
 
        WRITE_ENUM_FIELD(kind, WCOKind);
        WRITE_STRING_FIELD(relname);
+       WRITE_STRING_FIELD(polname);
        WRITE_NODE_FIELD(qual);
        WRITE_BOOL_FIELD(cascaded);
 }
@@ -2389,6 +2736,16 @@ _outSortGroupClause(StringInfo str, const SortGroupClause *node)
        WRITE_BOOL_FIELD(hashable);
 }
 
+static void
+_outGroupingSet(StringInfo str, const GroupingSet *node)
+{
+       WRITE_NODE_TYPE("GROUPINGSET");
+
+       WRITE_ENUM_FIELD(kind, GroupingSetKind);
+       WRITE_NODE_FIELD(content);
+       WRITE_LOCATION_FIELD(location);
+}
+
 static void
 _outWindowClause(StringInfo str, const WindowClause *node)
 {
@@ -2473,6 +2830,7 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
                case RTE_RELATION:
                        WRITE_OID_FIELD(relid);
                        WRITE_CHAR_FIELD(relkind);
+                       WRITE_NODE_FIELD(tablesample);
                        break;
                case RTE_SUBQUERY:
                        WRITE_NODE_FIELD(subquery);
@@ -2488,15 +2846,17 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
                        break;
                case RTE_VALUES:
                        WRITE_NODE_FIELD(values_lists);
-                       WRITE_NODE_FIELD(values_collations);
+                       WRITE_NODE_FIELD(coltypes);
+                       WRITE_NODE_FIELD(coltypmods);
+                       WRITE_NODE_FIELD(colcollations);
                        break;
                case RTE_CTE:
                        WRITE_STRING_FIELD(ctename);
                        WRITE_UINT_FIELD(ctelevelsup);
                        WRITE_BOOL_FIELD(self_reference);
-                       WRITE_NODE_FIELD(ctecoltypes);
-                       WRITE_NODE_FIELD(ctecoltypmods);
-                       WRITE_NODE_FIELD(ctecolcollations);
+                       WRITE_NODE_FIELD(coltypes);
+                       WRITE_NODE_FIELD(coltypmods);
+                       WRITE_NODE_FIELD(colcollations);
                        break;
                default:
                        elog(ERROR, "unrecognized RTE kind: %d", (int) node->rtekind);
@@ -2528,6 +2888,16 @@ _outRangeTblFunction(StringInfo str, const RangeTblFunction *node)
        WRITE_BITMAPSET_FIELD(funcparams);
 }
 
+static void
+_outTableSampleClause(StringInfo str, const TableSampleClause *node)
+{
+       WRITE_NODE_TYPE("TABLESAMPLECLAUSE");
+
+       WRITE_OID_FIELD(tsmhandler);
+       WRITE_NODE_FIELD(args);
+       WRITE_NODE_FIELD(repeatable);
+}
+
 static void
 _outAExpr(StringInfo str, const A_Expr *node)
 {
@@ -2553,6 +2923,10 @@ _outAExpr(StringInfo str, const A_Expr *node)
                        appendStringInfoString(str, " DISTINCT ");
                        WRITE_NODE_FIELD(name);
                        break;
+               case AEXPR_NOT_DISTINCT:
+                       appendStringInfoString(str, " NOT_DISTINCT ");
+                       WRITE_NODE_FIELD(name);
+                       break;
                case AEXPR_NULLIF:
                        appendStringInfoString(str, " NULLIF ");
                        WRITE_NODE_FIELD(name);
@@ -2625,12 +2999,12 @@ _outValue(StringInfo str, const Value *value)
                case T_String:
 
                        /*
-                        * We use _outToken to provide escaping of the string's content,
+                        * We use outToken to provide escaping of the string's content,
                         * but we don't want it to do anything with an empty string.
                         */
                        appendStringInfoChar(str, '"');
                        if (value->val.str[0] != '\0')
-                               _outToken(str, value->val.str);
+                               outToken(str, value->val.str);
                        appendStringInfoChar(str, '"');
                        break;
                case T_BitString:
@@ -2686,6 +3060,7 @@ _outA_Indices(StringInfo str, const A_Indices *node)
 {
        WRITE_NODE_TYPE("A_INDICES");
 
+       WRITE_BOOL_FIELD(is_slice);
        WRITE_NODE_FIELD(lidx);
        WRITE_NODE_FIELD(uidx);
 }
@@ -2779,6 +3154,18 @@ _outRangeFunction(StringInfo str, const RangeFunction *node)
        WRITE_NODE_FIELD(coldeflist);
 }
 
+static void
+_outRangeTableSample(StringInfo str, const RangeTableSample *node)
+{
+       WRITE_NODE_TYPE("RANGETABLESAMPLE");
+
+       WRITE_NODE_FIELD(relation);
+       WRITE_NODE_FIELD(method);
+       WRITE_NODE_FIELD(args);
+       WRITE_NODE_FIELD(repeatable);
+       WRITE_LOCATION_FIELD(location);
+}
+
 static void
 _outConstraint(StringInfo str, const Constraint *node)
 {
@@ -2878,13 +3265,75 @@ _outConstraint(StringInfo str, const Constraint *node)
        }
 }
 
+static void
+_outForeignKeyCacheInfo(StringInfo str, const ForeignKeyCacheInfo *node)
+{
+       int                     i;
+
+       WRITE_NODE_TYPE("FOREIGNKEYCACHEINFO");
+
+       WRITE_OID_FIELD(conrelid);
+       WRITE_OID_FIELD(confrelid);
+       WRITE_INT_FIELD(nkeys);
+       appendStringInfoString(str, " :conkey");
+       for (i = 0; i < node->nkeys; i++)
+               appendStringInfo(str, " %d", node->conkey[i]);
+       appendStringInfoString(str, " :confkey");
+       for (i = 0; i < node->nkeys; i++)
+               appendStringInfo(str, " %d", node->confkey[i]);
+       appendStringInfoString(str, " :conpfeqop");
+       for (i = 0; i < node->nkeys; i++)
+               appendStringInfo(str, " %u", node->conpfeqop[i]);
+}
+
+static void
+_outPartitionSpec(StringInfo str, const PartitionSpec *node)
+{
+       WRITE_NODE_TYPE("PARTITIONBY");
+
+       WRITE_STRING_FIELD(strategy);
+       WRITE_NODE_FIELD(partParams);
+       WRITE_LOCATION_FIELD(location);
+}
+
+static void
+_outPartitionElem(StringInfo str, const PartitionElem *node)
+{
+       WRITE_NODE_TYPE("PARTITIONELEM");
+
+       WRITE_STRING_FIELD(name);
+       WRITE_NODE_FIELD(expr);
+       WRITE_NODE_FIELD(collation);
+       WRITE_NODE_FIELD(opclass);
+       WRITE_LOCATION_FIELD(location);
+}
+
+static void
+_outPartitionBoundSpec(StringInfo str, const PartitionBoundSpec *node)
+{
+       WRITE_NODE_TYPE("PARTITIONBOUND");
+
+       WRITE_CHAR_FIELD(strategy);
+       WRITE_NODE_FIELD(listdatums);
+       WRITE_NODE_FIELD(lowerdatums);
+       WRITE_NODE_FIELD(upperdatums);
+}
+
+static void
+_outPartitionRangeDatum(StringInfo str, const PartitionRangeDatum *node)
+{
+       WRITE_NODE_TYPE("PARTRANGEDATUM");
+
+       WRITE_BOOL_FIELD(infinite);
+       WRITE_NODE_FIELD(value);
+}
 
 /*
- * _outNode -
+ * outNode -
  *       converts a Node into ascii string and append it to 'str'
  */
-static void
-_outNode(StringInfo str, const void *obj)
+void
+outNode(StringInfo str, const void *obj)
 {
        if (obj == NULL)
                appendStringInfoString(str, "<>");
@@ -2930,12 +3379,18 @@ _outNode(StringInfo str, const void *obj)
                        case T_BitmapOr:
                                _outBitmapOr(str, obj);
                                break;
+                       case T_Gather:
+                               _outGather(str, obj);
+                               break;
                        case T_Scan:
                                _outScan(str, obj);
                                break;
                        case T_SeqScan:
                                _outSeqScan(str, obj);
                                break;
+                       case T_SampleScan:
+                               _outSampleScan(str, obj);
+                               break;
                        case T_IndexScan:
                                _outIndexScan(str, obj);
                                break;
@@ -3044,6 +3499,9 @@ _outNode(StringInfo str, const void *obj)
                        case T_Aggref:
                                _outAggref(str, obj);
                                break;
+                       case T_GroupingFunc:
+                               _outGroupingFunc(str, obj);
+                               break;
                        case T_WindowFunc:
                                _outWindowFunc(str, obj);
                                break;
@@ -3125,6 +3583,9 @@ _outNode(StringInfo str, const void *obj)
                        case T_MinMaxExpr:
                                _outMinMaxExpr(str, obj);
                                break;
+                       case T_SQLValueFunction:
+                               _outSQLValueFunction(str, obj);
+                               break;
                        case T_XmlExpr:
                                _outXmlExpr(str, obj);
                                break;
@@ -3182,6 +3643,9 @@ _outNode(StringInfo str, const void *obj)
                        case T_TidPath:
                                _outTidPath(str, obj);
                                break;
+                       case T_SubqueryScanPath:
+                               _outSubqueryScanPath(str, obj);
+                               break;
                        case T_ForeignPath:
                                _outForeignPath(str, obj);
                                break;
@@ -3203,6 +3667,48 @@ _outNode(StringInfo str, const void *obj)
                        case T_UniquePath:
                                _outUniquePath(str, obj);
                                break;
+                       case T_GatherPath:
+                               _outGatherPath(str, obj);
+                               break;
+                       case T_ProjectionPath:
+                               _outProjectionPath(str, obj);
+                               break;
+                       case T_SortPath:
+                               _outSortPath(str, obj);
+                               break;
+                       case T_GroupPath:
+                               _outGroupPath(str, obj);
+                               break;
+                       case T_UpperUniquePath:
+                               _outUpperUniquePath(str, obj);
+                               break;
+                       case T_AggPath:
+                               _outAggPath(str, obj);
+                               break;
+                       case T_GroupingSetsPath:
+                               _outGroupingSetsPath(str, obj);
+                               break;
+                       case T_MinMaxAggPath:
+                               _outMinMaxAggPath(str, obj);
+                               break;
+                       case T_WindowAggPath:
+                               _outWindowAggPath(str, obj);
+                               break;
+                       case T_SetOpPath:
+                               _outSetOpPath(str, obj);
+                               break;
+                       case T_RecursiveUnionPath:
+                               _outRecursiveUnionPath(str, obj);
+                               break;
+                       case T_LockRowsPath:
+                               _outLockRowsPath(str, obj);
+                               break;
+                       case T_ModifyTablePath:
+                               _outModifyTablePath(str, obj);
+                               break;
+                       case T_LimitPath:
+                               _outLimitPath(str, obj);
+                               break;
                        case T_NestPath:
                                _outNestPath(str, obj);
                                break;
@@ -3224,6 +3730,9 @@ _outNode(StringInfo str, const void *obj)
                        case T_IndexOptInfo:
                                _outIndexOptInfo(str, obj);
                                break;
+                       case T_ForeignKeyOptInfo:
+                               _outForeignKeyOptInfo(str, obj);
+                               break;
                        case T_EquivalenceClass:
                                _outEquivalenceClass(str, obj);
                                break;
@@ -3233,6 +3742,9 @@ _outNode(StringInfo str, const void *obj)
                        case T_PathKey:
                                _outPathKey(str, obj);
                                break;
+                       case T_PathTarget:
+                               _outPathTarget(str, obj);
+                               break;
                        case T_ParamPathInfo:
                                _outParamPathInfo(str, obj);
                                break;
@@ -3245,9 +3757,6 @@ _outNode(StringInfo str, const void *obj)
                        case T_SpecialJoinInfo:
                                _outSpecialJoinInfo(str, obj);
                                break;
-                       case T_LateralJoinInfo:
-                               _outLateralJoinInfo(str, obj);
-                               break;
                        case T_AppendRelInfo:
                                _outAppendRelInfo(str, obj);
                                break;
@@ -3261,6 +3770,10 @@ _outNode(StringInfo str, const void *obj)
                                _outPlannerParamItem(str, obj);
                                break;
 
+                       case T_ExtensibleNode:
+                               _outExtensibleNode(str, obj);
+                               break;
+
                        case T_CreateStmt:
                                _outCreateStmt(str, obj);
                                break;
@@ -3306,6 +3819,9 @@ _outNode(StringInfo str, const void *obj)
                        case T_SortGroupClause:
                                _outSortGroupClause(str, obj);
                                break;
+                       case T_GroupingSet:
+                               _outGroupingSet(str, obj);
+                               break;
                        case T_WindowClause:
                                _outWindowClause(str, obj);
                                break;
@@ -3327,6 +3843,9 @@ _outNode(StringInfo str, const void *obj)
                        case T_RangeTblFunction:
                                _outRangeTblFunction(str, obj);
                                break;
+                       case T_TableSampleClause:
+                               _outTableSampleClause(str, obj);
+                               break;
                        case T_A_Expr:
                                _outAExpr(str, obj);
                                break;
@@ -3369,6 +3888,9 @@ _outNode(StringInfo str, const void *obj)
                        case T_RangeFunction:
                                _outRangeFunction(str, obj);
                                break;
+                       case T_RangeTableSample:
+                               _outRangeTableSample(str, obj);
+                               break;
                        case T_Constraint:
                                _outConstraint(str, obj);
                                break;
@@ -3387,12 +3909,30 @@ _outNode(StringInfo str, const void *obj)
                        case T_XmlSerialize:
                                _outXmlSerialize(str, obj);
                                break;
+                       case T_ForeignKeyCacheInfo:
+                               _outForeignKeyCacheInfo(str, obj);
+                               break;
+                       case T_TriggerTransition:
+                               _outTriggerTransition(str, obj);
+                               break;
+                       case T_PartitionSpec:
+                               _outPartitionSpec(str, obj);
+                               break;
+                       case T_PartitionElem:
+                               _outPartitionElem(str, obj);
+                               break;
+                       case T_PartitionBoundSpec:
+                               _outPartitionBoundSpec(str, obj);
+                               break;
+                       case T_PartitionRangeDatum:
+                               _outPartitionRangeDatum(str, obj);
+                               break;
 
                        default:
 
                                /*
                                 * This should be an ERROR, but it's too useful to be able to
-                                * dump structures that _outNode only understands part of.
+                                * dump structures that outNode only understands part of.
                                 */
                                elog(WARNING, "could not dump unrecognized node type: %d",
                                         (int) nodeTag(obj));
@@ -3413,6 +3953,21 @@ nodeToString(const void *obj)
 
        /* see stringinfo.h for an explanation of this maneuver */
        initStringInfo(&str);
-       _outNode(&str, obj);
+       outNode(&str, obj);
+       return str.data;
+}
+
+/*
+ * bmsToString -
+ *        returns the ascii representation of the Bitmapset as a palloc'd string
+ */
+char *
+bmsToString(const Bitmapset *bms)
+{
+       StringInfoData str;
+
+       /* see stringinfo.h for an explanation of this maneuver */
+       initStringInfo(&str);
+       outBitmapset(&str, bms);
        return str.data;
 }