Header And Logo

PostgreSQL
| The world's most advanced open source database.

outfuncs.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * outfuncs.c
00004  *    Output functions for Postgres tree nodes.
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/backend/nodes/outfuncs.c
00012  *
00013  * NOTES
00014  *    Every node type that can appear in stored rules' parsetrees *must*
00015  *    have an output function defined here (as well as an input function
00016  *    in readfuncs.c).  For use in debugging, we also provide output
00017  *    functions for nodes that appear in raw parsetrees, path, and plan trees.
00018  *    These nodes however need not have input functions.
00019  *
00020  *-------------------------------------------------------------------------
00021  */
00022 #include "postgres.h"
00023 
00024 #include <ctype.h>
00025 
00026 #include "lib/stringinfo.h"
00027 #include "nodes/plannodes.h"
00028 #include "nodes/relation.h"
00029 #include "utils/datum.h"
00030 
00031 
00032 /*
00033  * Macros to simplify output of different kinds of fields.  Use these
00034  * wherever possible to reduce the chance for silly typos.  Note that these
00035  * hard-wire conventions about the names of the local variables in an Out
00036  * routine.
00037  */
00038 
00039 /* Write the label for the node type */
00040 #define WRITE_NODE_TYPE(nodelabel) \
00041     appendStringInfoString(str, nodelabel)
00042 
00043 /* Write an integer field (anything written as ":fldname %d") */
00044 #define WRITE_INT_FIELD(fldname) \
00045     appendStringInfo(str, " :" CppAsString(fldname) " %d", node->fldname)
00046 
00047 /* Write an unsigned integer field (anything written as ":fldname %u") */
00048 #define WRITE_UINT_FIELD(fldname) \
00049     appendStringInfo(str, " :" CppAsString(fldname) " %u", node->fldname)
00050 
00051 /* Write an OID field (don't hard-wire assumption that OID is same as uint) */
00052 #define WRITE_OID_FIELD(fldname) \
00053     appendStringInfo(str, " :" CppAsString(fldname) " %u", node->fldname)
00054 
00055 /* Write a long-integer field */
00056 #define WRITE_LONG_FIELD(fldname) \
00057     appendStringInfo(str, " :" CppAsString(fldname) " %ld", node->fldname)
00058 
00059 /* Write a char field (ie, one ascii character) */
00060 #define WRITE_CHAR_FIELD(fldname) \
00061     appendStringInfo(str, " :" CppAsString(fldname) " %c", node->fldname)
00062 
00063 /* Write an enumerated-type field as an integer code */
00064 #define WRITE_ENUM_FIELD(fldname, enumtype) \
00065     appendStringInfo(str, " :" CppAsString(fldname) " %d", \
00066                      (int) node->fldname)
00067 
00068 /* Write a float field --- caller must give format to define precision */
00069 #define WRITE_FLOAT_FIELD(fldname,format) \
00070     appendStringInfo(str, " :" CppAsString(fldname) " " format, node->fldname)
00071 
00072 /* Write a boolean field */
00073 #define WRITE_BOOL_FIELD(fldname) \
00074     appendStringInfo(str, " :" CppAsString(fldname) " %s", \
00075                      booltostr(node->fldname))
00076 
00077 /* Write a character-string (possibly NULL) field */
00078 #define WRITE_STRING_FIELD(fldname) \
00079     (appendStringInfo(str, " :" CppAsString(fldname) " "), \
00080      _outToken(str, node->fldname))
00081 
00082 /* Write a parse location field (actually same as INT case) */
00083 #define WRITE_LOCATION_FIELD(fldname) \
00084     appendStringInfo(str, " :" CppAsString(fldname) " %d", node->fldname)
00085 
00086 /* Write a Node field */
00087 #define WRITE_NODE_FIELD(fldname) \
00088     (appendStringInfo(str, " :" CppAsString(fldname) " "), \
00089      _outNode(str, node->fldname))
00090 
00091 /* Write a bitmapset field */
00092 #define WRITE_BITMAPSET_FIELD(fldname) \
00093     (appendStringInfo(str, " :" CppAsString(fldname) " "), \
00094      _outBitmapset(str, node->fldname))
00095 
00096 
00097 #define booltostr(x)  ((x) ? "true" : "false")
00098 
00099 static void _outNode(StringInfo str, const void *obj);
00100 
00101 
00102 /*
00103  * _outToken
00104  *    Convert an ordinary string (eg, an identifier) into a form that
00105  *    will be decoded back to a plain token by read.c's functions.
00106  *
00107  *    If a null or empty string is given, it is encoded as "<>".
00108  */
00109 static void
00110 _outToken(StringInfo str, const char *s)
00111 {
00112     if (s == NULL || *s == '\0')
00113     {
00114         appendStringInfo(str, "<>");
00115         return;
00116     }
00117 
00118     /*
00119      * Look for characters or patterns that are treated specially by read.c
00120      * (either in pg_strtok() or in nodeRead()), and therefore need a
00121      * protective backslash.
00122      */
00123     /* These characters only need to be quoted at the start of the string */
00124     if (*s == '<' ||
00125         *s == '\"' ||
00126         isdigit((unsigned char) *s) ||
00127         ((*s == '+' || *s == '-') &&
00128          (isdigit((unsigned char) s[1]) || s[1] == '.')))
00129         appendStringInfoChar(str, '\\');
00130     while (*s)
00131     {
00132         /* These chars must be backslashed anywhere in the string */
00133         if (*s == ' ' || *s == '\n' || *s == '\t' ||
00134             *s == '(' || *s == ')' || *s == '{' || *s == '}' ||
00135             *s == '\\')
00136             appendStringInfoChar(str, '\\');
00137         appendStringInfoChar(str, *s++);
00138     }
00139 }
00140 
00141 static void
00142 _outList(StringInfo str, const List *node)
00143 {
00144     const ListCell *lc;
00145 
00146     appendStringInfoChar(str, '(');
00147 
00148     if (IsA(node, IntList))
00149         appendStringInfoChar(str, 'i');
00150     else if (IsA(node, OidList))
00151         appendStringInfoChar(str, 'o');
00152 
00153     foreach(lc, node)
00154     {
00155         /*
00156          * For the sake of backward compatibility, we emit a slightly
00157          * different whitespace format for lists of nodes vs. other types of
00158          * lists. XXX: is this necessary?
00159          */
00160         if (IsA(node, List))
00161         {
00162             _outNode(str, lfirst(lc));
00163             if (lnext(lc))
00164                 appendStringInfoChar(str, ' ');
00165         }
00166         else if (IsA(node, IntList))
00167             appendStringInfo(str, " %d", lfirst_int(lc));
00168         else if (IsA(node, OidList))
00169             appendStringInfo(str, " %u", lfirst_oid(lc));
00170         else
00171             elog(ERROR, "unrecognized list node type: %d",
00172                  (int) node->type);
00173     }
00174 
00175     appendStringInfoChar(str, ')');
00176 }
00177 
00178 /*
00179  * _outBitmapset -
00180  *     converts a bitmap set of integers
00181  *
00182  * Note: the output format is "(b int int ...)", similar to an integer List.
00183  */
00184 static void
00185 _outBitmapset(StringInfo str, const Bitmapset *bms)
00186 {
00187     Bitmapset  *tmpset;
00188     int         x;
00189 
00190     appendStringInfoChar(str, '(');
00191     appendStringInfoChar(str, 'b');
00192     tmpset = bms_copy(bms);
00193     while ((x = bms_first_member(tmpset)) >= 0)
00194         appendStringInfo(str, " %d", x);
00195     bms_free(tmpset);
00196     appendStringInfoChar(str, ')');
00197 }
00198 
00199 /*
00200  * Print the value of a Datum given its type.
00201  */
00202 static void
00203 _outDatum(StringInfo str, Datum value, int typlen, bool typbyval)
00204 {
00205     Size        length,
00206                 i;
00207     char       *s;
00208 
00209     length = datumGetSize(value, typbyval, typlen);
00210 
00211     if (typbyval)
00212     {
00213         s = (char *) (&value);
00214         appendStringInfo(str, "%u [ ", (unsigned int) length);
00215         for (i = 0; i < (Size) sizeof(Datum); i++)
00216             appendStringInfo(str, "%d ", (int) (s[i]));
00217         appendStringInfo(str, "]");
00218     }
00219     else
00220     {
00221         s = (char *) DatumGetPointer(value);
00222         if (!PointerIsValid(s))
00223             appendStringInfo(str, "0 [ ]");
00224         else
00225         {
00226             appendStringInfo(str, "%u [ ", (unsigned int) length);
00227             for (i = 0; i < length; i++)
00228                 appendStringInfo(str, "%d ", (int) (s[i]));
00229             appendStringInfo(str, "]");
00230         }
00231     }
00232 }
00233 
00234 
00235 /*
00236  *  Stuff from plannodes.h
00237  */
00238 
00239 static void
00240 _outPlannedStmt(StringInfo str, const PlannedStmt *node)
00241 {
00242     WRITE_NODE_TYPE("PLANNEDSTMT");
00243 
00244     WRITE_ENUM_FIELD(commandType, CmdType);
00245     WRITE_UINT_FIELD(queryId);
00246     WRITE_BOOL_FIELD(hasReturning);
00247     WRITE_BOOL_FIELD(hasModifyingCTE);
00248     WRITE_BOOL_FIELD(canSetTag);
00249     WRITE_BOOL_FIELD(transientPlan);
00250     WRITE_NODE_FIELD(planTree);
00251     WRITE_NODE_FIELD(rtable);
00252     WRITE_NODE_FIELD(resultRelations);
00253     WRITE_NODE_FIELD(utilityStmt);
00254     WRITE_NODE_FIELD(subplans);
00255     WRITE_BITMAPSET_FIELD(rewindPlanIDs);
00256     WRITE_NODE_FIELD(rowMarks);
00257     WRITE_NODE_FIELD(relationOids);
00258     WRITE_NODE_FIELD(invalItems);
00259     WRITE_INT_FIELD(nParamExec);
00260 }
00261 
00262 /*
00263  * print the basic stuff of all nodes that inherit from Plan
00264  */
00265 static void
00266 _outPlanInfo(StringInfo str, const Plan *node)
00267 {
00268     WRITE_FLOAT_FIELD(startup_cost, "%.2f");
00269     WRITE_FLOAT_FIELD(total_cost, "%.2f");
00270     WRITE_FLOAT_FIELD(plan_rows, "%.0f");
00271     WRITE_INT_FIELD(plan_width);
00272     WRITE_NODE_FIELD(targetlist);
00273     WRITE_NODE_FIELD(qual);
00274     WRITE_NODE_FIELD(lefttree);
00275     WRITE_NODE_FIELD(righttree);
00276     WRITE_NODE_FIELD(initPlan);
00277     WRITE_BITMAPSET_FIELD(extParam);
00278     WRITE_BITMAPSET_FIELD(allParam);
00279 }
00280 
00281 /*
00282  * print the basic stuff of all nodes that inherit from Scan
00283  */
00284 static void
00285 _outScanInfo(StringInfo str, const Scan *node)
00286 {
00287     _outPlanInfo(str, (const Plan *) node);
00288 
00289     WRITE_UINT_FIELD(scanrelid);
00290 }
00291 
00292 /*
00293  * print the basic stuff of all nodes that inherit from Join
00294  */
00295 static void
00296 _outJoinPlanInfo(StringInfo str, const Join *node)
00297 {
00298     _outPlanInfo(str, (const Plan *) node);
00299 
00300     WRITE_ENUM_FIELD(jointype, JoinType);
00301     WRITE_NODE_FIELD(joinqual);
00302 }
00303 
00304 
00305 static void
00306 _outPlan(StringInfo str, const Plan *node)
00307 {
00308     WRITE_NODE_TYPE("PLAN");
00309 
00310     _outPlanInfo(str, (const Plan *) node);
00311 }
00312 
00313 static void
00314 _outResult(StringInfo str, const Result *node)
00315 {
00316     WRITE_NODE_TYPE("RESULT");
00317 
00318     _outPlanInfo(str, (const Plan *) node);
00319 
00320     WRITE_NODE_FIELD(resconstantqual);
00321 }
00322 
00323 static void
00324 _outModifyTable(StringInfo str, const ModifyTable *node)
00325 {
00326     WRITE_NODE_TYPE("MODIFYTABLE");
00327 
00328     _outPlanInfo(str, (const Plan *) node);
00329 
00330     WRITE_ENUM_FIELD(operation, CmdType);
00331     WRITE_BOOL_FIELD(canSetTag);
00332     WRITE_NODE_FIELD(resultRelations);
00333     WRITE_INT_FIELD(resultRelIndex);
00334     WRITE_NODE_FIELD(plans);
00335     WRITE_NODE_FIELD(returningLists);
00336     WRITE_NODE_FIELD(fdwPrivLists);
00337     WRITE_NODE_FIELD(rowMarks);
00338     WRITE_INT_FIELD(epqParam);
00339 }
00340 
00341 static void
00342 _outAppend(StringInfo str, const Append *node)
00343 {
00344     WRITE_NODE_TYPE("APPEND");
00345 
00346     _outPlanInfo(str, (const Plan *) node);
00347 
00348     WRITE_NODE_FIELD(appendplans);
00349 }
00350 
00351 static void
00352 _outMergeAppend(StringInfo str, const MergeAppend *node)
00353 {
00354     int         i;
00355 
00356     WRITE_NODE_TYPE("MERGEAPPEND");
00357 
00358     _outPlanInfo(str, (const Plan *) node);
00359 
00360     WRITE_NODE_FIELD(mergeplans);
00361 
00362     WRITE_INT_FIELD(numCols);
00363 
00364     appendStringInfo(str, " :sortColIdx");
00365     for (i = 0; i < node->numCols; i++)
00366         appendStringInfo(str, " %d", node->sortColIdx[i]);
00367 
00368     appendStringInfo(str, " :sortOperators");
00369     for (i = 0; i < node->numCols; i++)
00370         appendStringInfo(str, " %u", node->sortOperators[i]);
00371 
00372     appendStringInfo(str, " :collations");
00373     for (i = 0; i < node->numCols; i++)
00374         appendStringInfo(str, " %u", node->collations[i]);
00375 
00376     appendStringInfo(str, " :nullsFirst");
00377     for (i = 0; i < node->numCols; i++)
00378         appendStringInfo(str, " %s", booltostr(node->nullsFirst[i]));
00379 }
00380 
00381 static void
00382 _outRecursiveUnion(StringInfo str, const RecursiveUnion *node)
00383 {
00384     int         i;
00385 
00386     WRITE_NODE_TYPE("RECURSIVEUNION");
00387 
00388     _outPlanInfo(str, (const Plan *) node);
00389 
00390     WRITE_INT_FIELD(wtParam);
00391     WRITE_INT_FIELD(numCols);
00392 
00393     appendStringInfo(str, " :dupColIdx");
00394     for (i = 0; i < node->numCols; i++)
00395         appendStringInfo(str, " %d", node->dupColIdx[i]);
00396 
00397     appendStringInfo(str, " :dupOperators");
00398     for (i = 0; i < node->numCols; i++)
00399         appendStringInfo(str, " %u", node->dupOperators[i]);
00400 
00401     WRITE_LONG_FIELD(numGroups);
00402 }
00403 
00404 static void
00405 _outBitmapAnd(StringInfo str, const BitmapAnd *node)
00406 {
00407     WRITE_NODE_TYPE("BITMAPAND");
00408 
00409     _outPlanInfo(str, (const Plan *) node);
00410 
00411     WRITE_NODE_FIELD(bitmapplans);
00412 }
00413 
00414 static void
00415 _outBitmapOr(StringInfo str, const BitmapOr *node)
00416 {
00417     WRITE_NODE_TYPE("BITMAPOR");
00418 
00419     _outPlanInfo(str, (const Plan *) node);
00420 
00421     WRITE_NODE_FIELD(bitmapplans);
00422 }
00423 
00424 static void
00425 _outScan(StringInfo str, const Scan *node)
00426 {
00427     WRITE_NODE_TYPE("SCAN");
00428 
00429     _outScanInfo(str, node);
00430 }
00431 
00432 static void
00433 _outSeqScan(StringInfo str, const SeqScan *node)
00434 {
00435     WRITE_NODE_TYPE("SEQSCAN");
00436 
00437     _outScanInfo(str, (const Scan *) node);
00438 }
00439 
00440 static void
00441 _outIndexScan(StringInfo str, const IndexScan *node)
00442 {
00443     WRITE_NODE_TYPE("INDEXSCAN");
00444 
00445     _outScanInfo(str, (const Scan *) node);
00446 
00447     WRITE_OID_FIELD(indexid);
00448     WRITE_NODE_FIELD(indexqual);
00449     WRITE_NODE_FIELD(indexqualorig);
00450     WRITE_NODE_FIELD(indexorderby);
00451     WRITE_NODE_FIELD(indexorderbyorig);
00452     WRITE_ENUM_FIELD(indexorderdir, ScanDirection);
00453 }
00454 
00455 static void
00456 _outIndexOnlyScan(StringInfo str, const IndexOnlyScan *node)
00457 {
00458     WRITE_NODE_TYPE("INDEXONLYSCAN");
00459 
00460     _outScanInfo(str, (const Scan *) node);
00461 
00462     WRITE_OID_FIELD(indexid);
00463     WRITE_NODE_FIELD(indexqual);
00464     WRITE_NODE_FIELD(indexorderby);
00465     WRITE_NODE_FIELD(indextlist);
00466     WRITE_ENUM_FIELD(indexorderdir, ScanDirection);
00467 }
00468 
00469 static void
00470 _outBitmapIndexScan(StringInfo str, const BitmapIndexScan *node)
00471 {
00472     WRITE_NODE_TYPE("BITMAPINDEXSCAN");
00473 
00474     _outScanInfo(str, (const Scan *) node);
00475 
00476     WRITE_OID_FIELD(indexid);
00477     WRITE_NODE_FIELD(indexqual);
00478     WRITE_NODE_FIELD(indexqualorig);
00479 }
00480 
00481 static void
00482 _outBitmapHeapScan(StringInfo str, const BitmapHeapScan *node)
00483 {
00484     WRITE_NODE_TYPE("BITMAPHEAPSCAN");
00485 
00486     _outScanInfo(str, (const Scan *) node);
00487 
00488     WRITE_NODE_FIELD(bitmapqualorig);
00489 }
00490 
00491 static void
00492 _outTidScan(StringInfo str, const TidScan *node)
00493 {
00494     WRITE_NODE_TYPE("TIDSCAN");
00495 
00496     _outScanInfo(str, (const Scan *) node);
00497 
00498     WRITE_NODE_FIELD(tidquals);
00499 }
00500 
00501 static void
00502 _outSubqueryScan(StringInfo str, const SubqueryScan *node)
00503 {
00504     WRITE_NODE_TYPE("SUBQUERYSCAN");
00505 
00506     _outScanInfo(str, (const Scan *) node);
00507 
00508     WRITE_NODE_FIELD(subplan);
00509 }
00510 
00511 static void
00512 _outFunctionScan(StringInfo str, const FunctionScan *node)
00513 {
00514     WRITE_NODE_TYPE("FUNCTIONSCAN");
00515 
00516     _outScanInfo(str, (const Scan *) node);
00517 
00518     WRITE_NODE_FIELD(funcexpr);
00519     WRITE_NODE_FIELD(funccolnames);
00520     WRITE_NODE_FIELD(funccoltypes);
00521     WRITE_NODE_FIELD(funccoltypmods);
00522     WRITE_NODE_FIELD(funccolcollations);
00523 }
00524 
00525 static void
00526 _outValuesScan(StringInfo str, const ValuesScan *node)
00527 {
00528     WRITE_NODE_TYPE("VALUESSCAN");
00529 
00530     _outScanInfo(str, (const Scan *) node);
00531 
00532     WRITE_NODE_FIELD(values_lists);
00533 }
00534 
00535 static void
00536 _outCteScan(StringInfo str, const CteScan *node)
00537 {
00538     WRITE_NODE_TYPE("CTESCAN");
00539 
00540     _outScanInfo(str, (const Scan *) node);
00541 
00542     WRITE_INT_FIELD(ctePlanId);
00543     WRITE_INT_FIELD(cteParam);
00544 }
00545 
00546 static void
00547 _outWorkTableScan(StringInfo str, const WorkTableScan *node)
00548 {
00549     WRITE_NODE_TYPE("WORKTABLESCAN");
00550 
00551     _outScanInfo(str, (const Scan *) node);
00552 
00553     WRITE_INT_FIELD(wtParam);
00554 }
00555 
00556 static void
00557 _outForeignScan(StringInfo str, const ForeignScan *node)
00558 {
00559     WRITE_NODE_TYPE("FOREIGNSCAN");
00560 
00561     _outScanInfo(str, (const Scan *) node);
00562 
00563     WRITE_NODE_FIELD(fdw_exprs);
00564     WRITE_NODE_FIELD(fdw_private);
00565     WRITE_BOOL_FIELD(fsSystemCol);
00566 }
00567 
00568 static void
00569 _outJoin(StringInfo str, const Join *node)
00570 {
00571     WRITE_NODE_TYPE("JOIN");
00572 
00573     _outJoinPlanInfo(str, (const Join *) node);
00574 }
00575 
00576 static void
00577 _outNestLoop(StringInfo str, const NestLoop *node)
00578 {
00579     WRITE_NODE_TYPE("NESTLOOP");
00580 
00581     _outJoinPlanInfo(str, (const Join *) node);
00582 
00583     WRITE_NODE_FIELD(nestParams);
00584 }
00585 
00586 static void
00587 _outMergeJoin(StringInfo str, const MergeJoin *node)
00588 {
00589     int         numCols;
00590     int         i;
00591 
00592     WRITE_NODE_TYPE("MERGEJOIN");
00593 
00594     _outJoinPlanInfo(str, (const Join *) node);
00595 
00596     WRITE_NODE_FIELD(mergeclauses);
00597 
00598     numCols = list_length(node->mergeclauses);
00599 
00600     appendStringInfo(str, " :mergeFamilies");
00601     for (i = 0; i < numCols; i++)
00602         appendStringInfo(str, " %u", node->mergeFamilies[i]);
00603 
00604     appendStringInfo(str, " :mergeCollations");
00605     for (i = 0; i < numCols; i++)
00606         appendStringInfo(str, " %u", node->mergeCollations[i]);
00607 
00608     appendStringInfo(str, " :mergeStrategies");
00609     for (i = 0; i < numCols; i++)
00610         appendStringInfo(str, " %d", node->mergeStrategies[i]);
00611 
00612     appendStringInfo(str, " :mergeNullsFirst");
00613     for (i = 0; i < numCols; i++)
00614         appendStringInfo(str, " %d", (int) node->mergeNullsFirst[i]);
00615 }
00616 
00617 static void
00618 _outHashJoin(StringInfo str, const HashJoin *node)
00619 {
00620     WRITE_NODE_TYPE("HASHJOIN");
00621 
00622     _outJoinPlanInfo(str, (const Join *) node);
00623 
00624     WRITE_NODE_FIELD(hashclauses);
00625 }
00626 
00627 static void
00628 _outAgg(StringInfo str, const Agg *node)
00629 {
00630     int         i;
00631 
00632     WRITE_NODE_TYPE("AGG");
00633 
00634     _outPlanInfo(str, (const Plan *) node);
00635 
00636     WRITE_ENUM_FIELD(aggstrategy, AggStrategy);
00637     WRITE_INT_FIELD(numCols);
00638 
00639     appendStringInfo(str, " :grpColIdx");
00640     for (i = 0; i < node->numCols; i++)
00641         appendStringInfo(str, " %d", node->grpColIdx[i]);
00642 
00643     appendStringInfo(str, " :grpOperators");
00644     for (i = 0; i < node->numCols; i++)
00645         appendStringInfo(str, " %u", node->grpOperators[i]);
00646 
00647     WRITE_LONG_FIELD(numGroups);
00648 }
00649 
00650 static void
00651 _outWindowAgg(StringInfo str, const WindowAgg *node)
00652 {
00653     int         i;
00654 
00655     WRITE_NODE_TYPE("WINDOWAGG");
00656 
00657     _outPlanInfo(str, (const Plan *) node);
00658 
00659     WRITE_UINT_FIELD(winref);
00660     WRITE_INT_FIELD(partNumCols);
00661 
00662     appendStringInfo(str, " :partColIdx");
00663     for (i = 0; i < node->partNumCols; i++)
00664         appendStringInfo(str, " %d", node->partColIdx[i]);
00665 
00666     appendStringInfo(str, " :partOperations");
00667     for (i = 0; i < node->partNumCols; i++)
00668         appendStringInfo(str, " %u", node->partOperators[i]);
00669 
00670     WRITE_INT_FIELD(ordNumCols);
00671 
00672     appendStringInfo(str, " :ordColIdx");
00673     for (i = 0; i < node->ordNumCols; i++)
00674         appendStringInfo(str, " %d", node->ordColIdx[i]);
00675 
00676     appendStringInfo(str, " :ordOperations");
00677     for (i = 0; i < node->ordNumCols; i++)
00678         appendStringInfo(str, " %u", node->ordOperators[i]);
00679 
00680     WRITE_INT_FIELD(frameOptions);
00681     WRITE_NODE_FIELD(startOffset);
00682     WRITE_NODE_FIELD(endOffset);
00683 }
00684 
00685 static void
00686 _outGroup(StringInfo str, const Group *node)
00687 {
00688     int         i;
00689 
00690     WRITE_NODE_TYPE("GROUP");
00691 
00692     _outPlanInfo(str, (const Plan *) node);
00693 
00694     WRITE_INT_FIELD(numCols);
00695 
00696     appendStringInfo(str, " :grpColIdx");
00697     for (i = 0; i < node->numCols; i++)
00698         appendStringInfo(str, " %d", node->grpColIdx[i]);
00699 
00700     appendStringInfo(str, " :grpOperators");
00701     for (i = 0; i < node->numCols; i++)
00702         appendStringInfo(str, " %u", node->grpOperators[i]);
00703 }
00704 
00705 static void
00706 _outMaterial(StringInfo str, const Material *node)
00707 {
00708     WRITE_NODE_TYPE("MATERIAL");
00709 
00710     _outPlanInfo(str, (const Plan *) node);
00711 }
00712 
00713 static void
00714 _outSort(StringInfo str, const Sort *node)
00715 {
00716     int         i;
00717 
00718     WRITE_NODE_TYPE("SORT");
00719 
00720     _outPlanInfo(str, (const Plan *) node);
00721 
00722     WRITE_INT_FIELD(numCols);
00723 
00724     appendStringInfo(str, " :sortColIdx");
00725     for (i = 0; i < node->numCols; i++)
00726         appendStringInfo(str, " %d", node->sortColIdx[i]);
00727 
00728     appendStringInfo(str, " :sortOperators");
00729     for (i = 0; i < node->numCols; i++)
00730         appendStringInfo(str, " %u", node->sortOperators[i]);
00731 
00732     appendStringInfo(str, " :collations");
00733     for (i = 0; i < node->numCols; i++)
00734         appendStringInfo(str, " %u", node->collations[i]);
00735 
00736     appendStringInfo(str, " :nullsFirst");
00737     for (i = 0; i < node->numCols; i++)
00738         appendStringInfo(str, " %s", booltostr(node->nullsFirst[i]));
00739 }
00740 
00741 static void
00742 _outUnique(StringInfo str, const Unique *node)
00743 {
00744     int         i;
00745 
00746     WRITE_NODE_TYPE("UNIQUE");
00747 
00748     _outPlanInfo(str, (const Plan *) node);
00749 
00750     WRITE_INT_FIELD(numCols);
00751 
00752     appendStringInfo(str, " :uniqColIdx");
00753     for (i = 0; i < node->numCols; i++)
00754         appendStringInfo(str, " %d", node->uniqColIdx[i]);
00755 
00756     appendStringInfo(str, " :uniqOperators");
00757     for (i = 0; i < node->numCols; i++)
00758         appendStringInfo(str, " %u", node->uniqOperators[i]);
00759 }
00760 
00761 static void
00762 _outHash(StringInfo str, const Hash *node)
00763 {
00764     WRITE_NODE_TYPE("HASH");
00765 
00766     _outPlanInfo(str, (const Plan *) node);
00767 
00768     WRITE_OID_FIELD(skewTable);
00769     WRITE_INT_FIELD(skewColumn);
00770     WRITE_BOOL_FIELD(skewInherit);
00771     WRITE_OID_FIELD(skewColType);
00772     WRITE_INT_FIELD(skewColTypmod);
00773 }
00774 
00775 static void
00776 _outSetOp(StringInfo str, const SetOp *node)
00777 {
00778     int         i;
00779 
00780     WRITE_NODE_TYPE("SETOP");
00781 
00782     _outPlanInfo(str, (const Plan *) node);
00783 
00784     WRITE_ENUM_FIELD(cmd, SetOpCmd);
00785     WRITE_ENUM_FIELD(strategy, SetOpStrategy);
00786     WRITE_INT_FIELD(numCols);
00787 
00788     appendStringInfo(str, " :dupColIdx");
00789     for (i = 0; i < node->numCols; i++)
00790         appendStringInfo(str, " %d", node->dupColIdx[i]);
00791 
00792     appendStringInfo(str, " :dupOperators");
00793     for (i = 0; i < node->numCols; i++)
00794         appendStringInfo(str, " %u", node->dupOperators[i]);
00795 
00796     WRITE_INT_FIELD(flagColIdx);
00797     WRITE_INT_FIELD(firstFlag);
00798     WRITE_LONG_FIELD(numGroups);
00799 }
00800 
00801 static void
00802 _outLockRows(StringInfo str, const LockRows *node)
00803 {
00804     WRITE_NODE_TYPE("LOCKROWS");
00805 
00806     _outPlanInfo(str, (const Plan *) node);
00807 
00808     WRITE_NODE_FIELD(rowMarks);
00809     WRITE_INT_FIELD(epqParam);
00810 }
00811 
00812 static void
00813 _outLimit(StringInfo str, const Limit *node)
00814 {
00815     WRITE_NODE_TYPE("LIMIT");
00816 
00817     _outPlanInfo(str, (const Plan *) node);
00818 
00819     WRITE_NODE_FIELD(limitOffset);
00820     WRITE_NODE_FIELD(limitCount);
00821 }
00822 
00823 static void
00824 _outNestLoopParam(StringInfo str, const NestLoopParam *node)
00825 {
00826     WRITE_NODE_TYPE("NESTLOOPPARAM");
00827 
00828     WRITE_INT_FIELD(paramno);
00829     WRITE_NODE_FIELD(paramval);
00830 }
00831 
00832 static void
00833 _outPlanRowMark(StringInfo str, const PlanRowMark *node)
00834 {
00835     WRITE_NODE_TYPE("PLANROWMARK");
00836 
00837     WRITE_UINT_FIELD(rti);
00838     WRITE_UINT_FIELD(prti);
00839     WRITE_UINT_FIELD(rowmarkId);
00840     WRITE_ENUM_FIELD(markType, RowMarkType);
00841     WRITE_BOOL_FIELD(noWait);
00842     WRITE_BOOL_FIELD(isParent);
00843 }
00844 
00845 static void
00846 _outPlanInvalItem(StringInfo str, const PlanInvalItem *node)
00847 {
00848     WRITE_NODE_TYPE("PLANINVALITEM");
00849 
00850     WRITE_INT_FIELD(cacheId);
00851     WRITE_UINT_FIELD(hashValue);
00852 }
00853 
00854 /*****************************************************************************
00855  *
00856  *  Stuff from primnodes.h.
00857  *
00858  *****************************************************************************/
00859 
00860 static void
00861 _outAlias(StringInfo str, const Alias *node)
00862 {
00863     WRITE_NODE_TYPE("ALIAS");
00864 
00865     WRITE_STRING_FIELD(aliasname);
00866     WRITE_NODE_FIELD(colnames);
00867 }
00868 
00869 static void
00870 _outRangeVar(StringInfo str, const RangeVar *node)
00871 {
00872     WRITE_NODE_TYPE("RANGEVAR");
00873 
00874     /*
00875      * we deliberately ignore catalogname here, since it is presently not
00876      * semantically meaningful
00877      */
00878     WRITE_STRING_FIELD(schemaname);
00879     WRITE_STRING_FIELD(relname);
00880     WRITE_ENUM_FIELD(inhOpt, InhOption);
00881     WRITE_CHAR_FIELD(relpersistence);
00882     WRITE_NODE_FIELD(alias);
00883     WRITE_LOCATION_FIELD(location);
00884 }
00885 
00886 static void
00887 _outIntoClause(StringInfo str, const IntoClause *node)
00888 {
00889     WRITE_NODE_TYPE("INTOCLAUSE");
00890 
00891     WRITE_NODE_FIELD(rel);
00892     WRITE_NODE_FIELD(colNames);
00893     WRITE_NODE_FIELD(options);
00894     WRITE_ENUM_FIELD(onCommit, OnCommitAction);
00895     WRITE_STRING_FIELD(tableSpaceName);
00896     WRITE_NODE_FIELD(viewQuery);
00897     WRITE_BOOL_FIELD(skipData);
00898 }
00899 
00900 static void
00901 _outVar(StringInfo str, const Var *node)
00902 {
00903     WRITE_NODE_TYPE("VAR");
00904 
00905     WRITE_UINT_FIELD(varno);
00906     WRITE_INT_FIELD(varattno);
00907     WRITE_OID_FIELD(vartype);
00908     WRITE_INT_FIELD(vartypmod);
00909     WRITE_OID_FIELD(varcollid);
00910     WRITE_UINT_FIELD(varlevelsup);
00911     WRITE_UINT_FIELD(varnoold);
00912     WRITE_INT_FIELD(varoattno);
00913     WRITE_LOCATION_FIELD(location);
00914 }
00915 
00916 static void
00917 _outConst(StringInfo str, const Const *node)
00918 {
00919     WRITE_NODE_TYPE("CONST");
00920 
00921     WRITE_OID_FIELD(consttype);
00922     WRITE_INT_FIELD(consttypmod);
00923     WRITE_OID_FIELD(constcollid);
00924     WRITE_INT_FIELD(constlen);
00925     WRITE_BOOL_FIELD(constbyval);
00926     WRITE_BOOL_FIELD(constisnull);
00927     WRITE_LOCATION_FIELD(location);
00928 
00929     appendStringInfo(str, " :constvalue ");
00930     if (node->constisnull)
00931         appendStringInfo(str, "<>");
00932     else
00933         _outDatum(str, node->constvalue, node->constlen, node->constbyval);
00934 }
00935 
00936 static void
00937 _outParam(StringInfo str, const Param *node)
00938 {
00939     WRITE_NODE_TYPE("PARAM");
00940 
00941     WRITE_ENUM_FIELD(paramkind, ParamKind);
00942     WRITE_INT_FIELD(paramid);
00943     WRITE_OID_FIELD(paramtype);
00944     WRITE_INT_FIELD(paramtypmod);
00945     WRITE_OID_FIELD(paramcollid);
00946     WRITE_LOCATION_FIELD(location);
00947 }
00948 
00949 static void
00950 _outAggref(StringInfo str, const Aggref *node)
00951 {
00952     WRITE_NODE_TYPE("AGGREF");
00953 
00954     WRITE_OID_FIELD(aggfnoid);
00955     WRITE_OID_FIELD(aggtype);
00956     WRITE_OID_FIELD(aggcollid);
00957     WRITE_OID_FIELD(inputcollid);
00958     WRITE_NODE_FIELD(args);
00959     WRITE_NODE_FIELD(aggorder);
00960     WRITE_NODE_FIELD(aggdistinct);
00961     WRITE_BOOL_FIELD(aggstar);
00962     WRITE_UINT_FIELD(agglevelsup);
00963     WRITE_LOCATION_FIELD(location);
00964 }
00965 
00966 static void
00967 _outWindowFunc(StringInfo str, const WindowFunc *node)
00968 {
00969     WRITE_NODE_TYPE("WINDOWFUNC");
00970 
00971     WRITE_OID_FIELD(winfnoid);
00972     WRITE_OID_FIELD(wintype);
00973     WRITE_OID_FIELD(wincollid);
00974     WRITE_OID_FIELD(inputcollid);
00975     WRITE_NODE_FIELD(args);
00976     WRITE_UINT_FIELD(winref);
00977     WRITE_BOOL_FIELD(winstar);
00978     WRITE_BOOL_FIELD(winagg);
00979     WRITE_LOCATION_FIELD(location);
00980 }
00981 
00982 static void
00983 _outArrayRef(StringInfo str, const ArrayRef *node)
00984 {
00985     WRITE_NODE_TYPE("ARRAYREF");
00986 
00987     WRITE_OID_FIELD(refarraytype);
00988     WRITE_OID_FIELD(refelemtype);
00989     WRITE_INT_FIELD(reftypmod);
00990     WRITE_OID_FIELD(refcollid);
00991     WRITE_NODE_FIELD(refupperindexpr);
00992     WRITE_NODE_FIELD(reflowerindexpr);
00993     WRITE_NODE_FIELD(refexpr);
00994     WRITE_NODE_FIELD(refassgnexpr);
00995 }
00996 
00997 static void
00998 _outFuncExpr(StringInfo str, const FuncExpr *node)
00999 {
01000     WRITE_NODE_TYPE("FUNCEXPR");
01001 
01002     WRITE_OID_FIELD(funcid);
01003     WRITE_OID_FIELD(funcresulttype);
01004     WRITE_BOOL_FIELD(funcretset);
01005     WRITE_BOOL_FIELD(funcvariadic);
01006     WRITE_ENUM_FIELD(funcformat, CoercionForm);
01007     WRITE_OID_FIELD(funccollid);
01008     WRITE_OID_FIELD(inputcollid);
01009     WRITE_NODE_FIELD(args);
01010     WRITE_LOCATION_FIELD(location);
01011 }
01012 
01013 static void
01014 _outNamedArgExpr(StringInfo str, const NamedArgExpr *node)
01015 {
01016     WRITE_NODE_TYPE("NAMEDARGEXPR");
01017 
01018     WRITE_NODE_FIELD(arg);
01019     WRITE_STRING_FIELD(name);
01020     WRITE_INT_FIELD(argnumber);
01021     WRITE_LOCATION_FIELD(location);
01022 }
01023 
01024 static void
01025 _outOpExpr(StringInfo str, const OpExpr *node)
01026 {
01027     WRITE_NODE_TYPE("OPEXPR");
01028 
01029     WRITE_OID_FIELD(opno);
01030     WRITE_OID_FIELD(opfuncid);
01031     WRITE_OID_FIELD(opresulttype);
01032     WRITE_BOOL_FIELD(opretset);
01033     WRITE_OID_FIELD(opcollid);
01034     WRITE_OID_FIELD(inputcollid);
01035     WRITE_NODE_FIELD(args);
01036     WRITE_LOCATION_FIELD(location);
01037 }
01038 
01039 static void
01040 _outDistinctExpr(StringInfo str, const DistinctExpr *node)
01041 {
01042     WRITE_NODE_TYPE("DISTINCTEXPR");
01043 
01044     WRITE_OID_FIELD(opno);
01045     WRITE_OID_FIELD(opfuncid);
01046     WRITE_OID_FIELD(opresulttype);
01047     WRITE_BOOL_FIELD(opretset);
01048     WRITE_OID_FIELD(opcollid);
01049     WRITE_OID_FIELD(inputcollid);
01050     WRITE_NODE_FIELD(args);
01051     WRITE_LOCATION_FIELD(location);
01052 }
01053 
01054 static void
01055 _outNullIfExpr(StringInfo str, const NullIfExpr *node)
01056 {
01057     WRITE_NODE_TYPE("NULLIFEXPR");
01058 
01059     WRITE_OID_FIELD(opno);
01060     WRITE_OID_FIELD(opfuncid);
01061     WRITE_OID_FIELD(opresulttype);
01062     WRITE_BOOL_FIELD(opretset);
01063     WRITE_OID_FIELD(opcollid);
01064     WRITE_OID_FIELD(inputcollid);
01065     WRITE_NODE_FIELD(args);
01066     WRITE_LOCATION_FIELD(location);
01067 }
01068 
01069 static void
01070 _outScalarArrayOpExpr(StringInfo str, const ScalarArrayOpExpr *node)
01071 {
01072     WRITE_NODE_TYPE("SCALARARRAYOPEXPR");
01073 
01074     WRITE_OID_FIELD(opno);
01075     WRITE_OID_FIELD(opfuncid);
01076     WRITE_BOOL_FIELD(useOr);
01077     WRITE_OID_FIELD(inputcollid);
01078     WRITE_NODE_FIELD(args);
01079     WRITE_LOCATION_FIELD(location);
01080 }
01081 
01082 static void
01083 _outBoolExpr(StringInfo str, const BoolExpr *node)
01084 {
01085     char       *opstr = NULL;
01086 
01087     WRITE_NODE_TYPE("BOOLEXPR");
01088 
01089     /* do-it-yourself enum representation */
01090     switch (node->boolop)
01091     {
01092         case AND_EXPR:
01093             opstr = "and";
01094             break;
01095         case OR_EXPR:
01096             opstr = "or";
01097             break;
01098         case NOT_EXPR:
01099             opstr = "not";
01100             break;
01101     }
01102     appendStringInfo(str, " :boolop ");
01103     _outToken(str, opstr);
01104 
01105     WRITE_NODE_FIELD(args);
01106     WRITE_LOCATION_FIELD(location);
01107 }
01108 
01109 static void
01110 _outSubLink(StringInfo str, const SubLink *node)
01111 {
01112     WRITE_NODE_TYPE("SUBLINK");
01113 
01114     WRITE_ENUM_FIELD(subLinkType, SubLinkType);
01115     WRITE_NODE_FIELD(testexpr);
01116     WRITE_NODE_FIELD(operName);
01117     WRITE_NODE_FIELD(subselect);
01118     WRITE_LOCATION_FIELD(location);
01119 }
01120 
01121 static void
01122 _outSubPlan(StringInfo str, const SubPlan *node)
01123 {
01124     WRITE_NODE_TYPE("SUBPLAN");
01125 
01126     WRITE_ENUM_FIELD(subLinkType, SubLinkType);
01127     WRITE_NODE_FIELD(testexpr);
01128     WRITE_NODE_FIELD(paramIds);
01129     WRITE_INT_FIELD(plan_id);
01130     WRITE_STRING_FIELD(plan_name);
01131     WRITE_OID_FIELD(firstColType);
01132     WRITE_INT_FIELD(firstColTypmod);
01133     WRITE_OID_FIELD(firstColCollation);
01134     WRITE_BOOL_FIELD(useHashTable);
01135     WRITE_BOOL_FIELD(unknownEqFalse);
01136     WRITE_NODE_FIELD(setParam);
01137     WRITE_NODE_FIELD(parParam);
01138     WRITE_NODE_FIELD(args);
01139     WRITE_FLOAT_FIELD(startup_cost, "%.2f");
01140     WRITE_FLOAT_FIELD(per_call_cost, "%.2f");
01141 }
01142 
01143 static void
01144 _outAlternativeSubPlan(StringInfo str, const AlternativeSubPlan *node)
01145 {
01146     WRITE_NODE_TYPE("ALTERNATIVESUBPLAN");
01147 
01148     WRITE_NODE_FIELD(subplans);
01149 }
01150 
01151 static void
01152 _outFieldSelect(StringInfo str, const FieldSelect *node)
01153 {
01154     WRITE_NODE_TYPE("FIELDSELECT");
01155 
01156     WRITE_NODE_FIELD(arg);
01157     WRITE_INT_FIELD(fieldnum);
01158     WRITE_OID_FIELD(resulttype);
01159     WRITE_INT_FIELD(resulttypmod);
01160     WRITE_OID_FIELD(resultcollid);
01161 }
01162 
01163 static void
01164 _outFieldStore(StringInfo str, const FieldStore *node)
01165 {
01166     WRITE_NODE_TYPE("FIELDSTORE");
01167 
01168     WRITE_NODE_FIELD(arg);
01169     WRITE_NODE_FIELD(newvals);
01170     WRITE_NODE_FIELD(fieldnums);
01171     WRITE_OID_FIELD(resulttype);
01172 }
01173 
01174 static void
01175 _outRelabelType(StringInfo str, const RelabelType *node)
01176 {
01177     WRITE_NODE_TYPE("RELABELTYPE");
01178 
01179     WRITE_NODE_FIELD(arg);
01180     WRITE_OID_FIELD(resulttype);
01181     WRITE_INT_FIELD(resulttypmod);
01182     WRITE_OID_FIELD(resultcollid);
01183     WRITE_ENUM_FIELD(relabelformat, CoercionForm);
01184     WRITE_LOCATION_FIELD(location);
01185 }
01186 
01187 static void
01188 _outCoerceViaIO(StringInfo str, const CoerceViaIO *node)
01189 {
01190     WRITE_NODE_TYPE("COERCEVIAIO");
01191 
01192     WRITE_NODE_FIELD(arg);
01193     WRITE_OID_FIELD(resulttype);
01194     WRITE_OID_FIELD(resultcollid);
01195     WRITE_ENUM_FIELD(coerceformat, CoercionForm);
01196     WRITE_LOCATION_FIELD(location);
01197 }
01198 
01199 static void
01200 _outArrayCoerceExpr(StringInfo str, const ArrayCoerceExpr *node)
01201 {
01202     WRITE_NODE_TYPE("ARRAYCOERCEEXPR");
01203 
01204     WRITE_NODE_FIELD(arg);
01205     WRITE_OID_FIELD(elemfuncid);
01206     WRITE_OID_FIELD(resulttype);
01207     WRITE_INT_FIELD(resulttypmod);
01208     WRITE_OID_FIELD(resultcollid);
01209     WRITE_BOOL_FIELD(isExplicit);
01210     WRITE_ENUM_FIELD(coerceformat, CoercionForm);
01211     WRITE_LOCATION_FIELD(location);
01212 }
01213 
01214 static void
01215 _outConvertRowtypeExpr(StringInfo str, const ConvertRowtypeExpr *node)
01216 {
01217     WRITE_NODE_TYPE("CONVERTROWTYPEEXPR");
01218 
01219     WRITE_NODE_FIELD(arg);
01220     WRITE_OID_FIELD(resulttype);
01221     WRITE_ENUM_FIELD(convertformat, CoercionForm);
01222     WRITE_LOCATION_FIELD(location);
01223 }
01224 
01225 static void
01226 _outCollateExpr(StringInfo str, const CollateExpr *node)
01227 {
01228     WRITE_NODE_TYPE("COLLATE");
01229 
01230     WRITE_NODE_FIELD(arg);
01231     WRITE_OID_FIELD(collOid);
01232     WRITE_LOCATION_FIELD(location);
01233 }
01234 
01235 static void
01236 _outCaseExpr(StringInfo str, const CaseExpr *node)
01237 {
01238     WRITE_NODE_TYPE("CASE");
01239 
01240     WRITE_OID_FIELD(casetype);
01241     WRITE_OID_FIELD(casecollid);
01242     WRITE_NODE_FIELD(arg);
01243     WRITE_NODE_FIELD(args);
01244     WRITE_NODE_FIELD(defresult);
01245     WRITE_LOCATION_FIELD(location);
01246 }
01247 
01248 static void
01249 _outCaseWhen(StringInfo str, const CaseWhen *node)
01250 {
01251     WRITE_NODE_TYPE("WHEN");
01252 
01253     WRITE_NODE_FIELD(expr);
01254     WRITE_NODE_FIELD(result);
01255     WRITE_LOCATION_FIELD(location);
01256 }
01257 
01258 static void
01259 _outCaseTestExpr(StringInfo str, const CaseTestExpr *node)
01260 {
01261     WRITE_NODE_TYPE("CASETESTEXPR");
01262 
01263     WRITE_OID_FIELD(typeId);
01264     WRITE_INT_FIELD(typeMod);
01265     WRITE_OID_FIELD(collation);
01266 }
01267 
01268 static void
01269 _outArrayExpr(StringInfo str, const ArrayExpr *node)
01270 {
01271     WRITE_NODE_TYPE("ARRAY");
01272 
01273     WRITE_OID_FIELD(array_typeid);
01274     WRITE_OID_FIELD(array_collid);
01275     WRITE_OID_FIELD(element_typeid);
01276     WRITE_NODE_FIELD(elements);
01277     WRITE_BOOL_FIELD(multidims);
01278     WRITE_LOCATION_FIELD(location);
01279 }
01280 
01281 static void
01282 _outRowExpr(StringInfo str, const RowExpr *node)
01283 {
01284     WRITE_NODE_TYPE("ROW");
01285 
01286     WRITE_NODE_FIELD(args);
01287     WRITE_OID_FIELD(row_typeid);
01288     WRITE_ENUM_FIELD(row_format, CoercionForm);
01289     WRITE_NODE_FIELD(colnames);
01290     WRITE_LOCATION_FIELD(location);
01291 }
01292 
01293 static void
01294 _outRowCompareExpr(StringInfo str, const RowCompareExpr *node)
01295 {
01296     WRITE_NODE_TYPE("ROWCOMPARE");
01297 
01298     WRITE_ENUM_FIELD(rctype, RowCompareType);
01299     WRITE_NODE_FIELD(opnos);
01300     WRITE_NODE_FIELD(opfamilies);
01301     WRITE_NODE_FIELD(inputcollids);
01302     WRITE_NODE_FIELD(largs);
01303     WRITE_NODE_FIELD(rargs);
01304 }
01305 
01306 static void
01307 _outCoalesceExpr(StringInfo str, const CoalesceExpr *node)
01308 {
01309     WRITE_NODE_TYPE("COALESCE");
01310 
01311     WRITE_OID_FIELD(coalescetype);
01312     WRITE_OID_FIELD(coalescecollid);
01313     WRITE_NODE_FIELD(args);
01314     WRITE_LOCATION_FIELD(location);
01315 }
01316 
01317 static void
01318 _outMinMaxExpr(StringInfo str, const MinMaxExpr *node)
01319 {
01320     WRITE_NODE_TYPE("MINMAX");
01321 
01322     WRITE_OID_FIELD(minmaxtype);
01323     WRITE_OID_FIELD(minmaxcollid);
01324     WRITE_OID_FIELD(inputcollid);
01325     WRITE_ENUM_FIELD(op, MinMaxOp);
01326     WRITE_NODE_FIELD(args);
01327     WRITE_LOCATION_FIELD(location);
01328 }
01329 
01330 static void
01331 _outXmlExpr(StringInfo str, const XmlExpr *node)
01332 {
01333     WRITE_NODE_TYPE("XMLEXPR");
01334 
01335     WRITE_ENUM_FIELD(op, XmlExprOp);
01336     WRITE_STRING_FIELD(name);
01337     WRITE_NODE_FIELD(named_args);
01338     WRITE_NODE_FIELD(arg_names);
01339     WRITE_NODE_FIELD(args);
01340     WRITE_ENUM_FIELD(xmloption, XmlOptionType);
01341     WRITE_OID_FIELD(type);
01342     WRITE_INT_FIELD(typmod);
01343     WRITE_LOCATION_FIELD(location);
01344 }
01345 
01346 static void
01347 _outNullTest(StringInfo str, const NullTest *node)
01348 {
01349     WRITE_NODE_TYPE("NULLTEST");
01350 
01351     WRITE_NODE_FIELD(arg);
01352     WRITE_ENUM_FIELD(nulltesttype, NullTestType);
01353     WRITE_BOOL_FIELD(argisrow);
01354 }
01355 
01356 static void
01357 _outBooleanTest(StringInfo str, const BooleanTest *node)
01358 {
01359     WRITE_NODE_TYPE("BOOLEANTEST");
01360 
01361     WRITE_NODE_FIELD(arg);
01362     WRITE_ENUM_FIELD(booltesttype, BoolTestType);
01363 }
01364 
01365 static void
01366 _outCoerceToDomain(StringInfo str, const CoerceToDomain *node)
01367 {
01368     WRITE_NODE_TYPE("COERCETODOMAIN");
01369 
01370     WRITE_NODE_FIELD(arg);
01371     WRITE_OID_FIELD(resulttype);
01372     WRITE_INT_FIELD(resulttypmod);
01373     WRITE_OID_FIELD(resultcollid);
01374     WRITE_ENUM_FIELD(coercionformat, CoercionForm);
01375     WRITE_LOCATION_FIELD(location);
01376 }
01377 
01378 static void
01379 _outCoerceToDomainValue(StringInfo str, const CoerceToDomainValue *node)
01380 {
01381     WRITE_NODE_TYPE("COERCETODOMAINVALUE");
01382 
01383     WRITE_OID_FIELD(typeId);
01384     WRITE_INT_FIELD(typeMod);
01385     WRITE_OID_FIELD(collation);
01386     WRITE_LOCATION_FIELD(location);
01387 }
01388 
01389 static void
01390 _outSetToDefault(StringInfo str, const SetToDefault *node)
01391 {
01392     WRITE_NODE_TYPE("SETTODEFAULT");
01393 
01394     WRITE_OID_FIELD(typeId);
01395     WRITE_INT_FIELD(typeMod);
01396     WRITE_OID_FIELD(collation);
01397     WRITE_LOCATION_FIELD(location);
01398 }
01399 
01400 static void
01401 _outCurrentOfExpr(StringInfo str, const CurrentOfExpr *node)
01402 {
01403     WRITE_NODE_TYPE("CURRENTOFEXPR");
01404 
01405     WRITE_UINT_FIELD(cvarno);
01406     WRITE_STRING_FIELD(cursor_name);
01407     WRITE_INT_FIELD(cursor_param);
01408 }
01409 
01410 static void
01411 _outTargetEntry(StringInfo str, const TargetEntry *node)
01412 {
01413     WRITE_NODE_TYPE("TARGETENTRY");
01414 
01415     WRITE_NODE_FIELD(expr);
01416     WRITE_INT_FIELD(resno);
01417     WRITE_STRING_FIELD(resname);
01418     WRITE_UINT_FIELD(ressortgroupref);
01419     WRITE_OID_FIELD(resorigtbl);
01420     WRITE_INT_FIELD(resorigcol);
01421     WRITE_BOOL_FIELD(resjunk);
01422 }
01423 
01424 static void
01425 _outRangeTblRef(StringInfo str, const RangeTblRef *node)
01426 {
01427     WRITE_NODE_TYPE("RANGETBLREF");
01428 
01429     WRITE_INT_FIELD(rtindex);
01430 }
01431 
01432 static void
01433 _outJoinExpr(StringInfo str, const JoinExpr *node)
01434 {
01435     WRITE_NODE_TYPE("JOINEXPR");
01436 
01437     WRITE_ENUM_FIELD(jointype, JoinType);
01438     WRITE_BOOL_FIELD(isNatural);
01439     WRITE_NODE_FIELD(larg);
01440     WRITE_NODE_FIELD(rarg);
01441     WRITE_NODE_FIELD(usingClause);
01442     WRITE_NODE_FIELD(quals);
01443     WRITE_NODE_FIELD(alias);
01444     WRITE_INT_FIELD(rtindex);
01445 }
01446 
01447 static void
01448 _outFromExpr(StringInfo str, const FromExpr *node)
01449 {
01450     WRITE_NODE_TYPE("FROMEXPR");
01451 
01452     WRITE_NODE_FIELD(fromlist);
01453     WRITE_NODE_FIELD(quals);
01454 }
01455 
01456 /*****************************************************************************
01457  *
01458  *  Stuff from relation.h.
01459  *
01460  *****************************************************************************/
01461 
01462 /*
01463  * print the basic stuff of all nodes that inherit from Path
01464  *
01465  * Note we do NOT print the parent, else we'd be in infinite recursion.
01466  * We can print the parent's relids for identification purposes, though.
01467  * We also do not print the whole of param_info, since it's printed by
01468  * _outRelOptInfo; it's sufficient and less cluttering to print just the
01469  * required outer relids.
01470  */
01471 static void
01472 _outPathInfo(StringInfo str, const Path *node)
01473 {
01474     WRITE_ENUM_FIELD(pathtype, NodeTag);
01475     appendStringInfo(str, " :parent_relids ");
01476     _outBitmapset(str, node->parent->relids);
01477     appendStringInfo(str, " :required_outer ");
01478     if (node->param_info)
01479         _outBitmapset(str, node->param_info->ppi_req_outer);
01480     else
01481         _outBitmapset(str, NULL);
01482     WRITE_FLOAT_FIELD(rows, "%.0f");
01483     WRITE_FLOAT_FIELD(startup_cost, "%.2f");
01484     WRITE_FLOAT_FIELD(total_cost, "%.2f");
01485     WRITE_NODE_FIELD(pathkeys);
01486 }
01487 
01488 /*
01489  * print the basic stuff of all nodes that inherit from JoinPath
01490  */
01491 static void
01492 _outJoinPathInfo(StringInfo str, const JoinPath *node)
01493 {
01494     _outPathInfo(str, (const Path *) node);
01495 
01496     WRITE_ENUM_FIELD(jointype, JoinType);
01497     WRITE_NODE_FIELD(outerjoinpath);
01498     WRITE_NODE_FIELD(innerjoinpath);
01499     WRITE_NODE_FIELD(joinrestrictinfo);
01500 }
01501 
01502 static void
01503 _outPath(StringInfo str, const Path *node)
01504 {
01505     WRITE_NODE_TYPE("PATH");
01506 
01507     _outPathInfo(str, (const Path *) node);
01508 }
01509 
01510 static void
01511 _outIndexPath(StringInfo str, const IndexPath *node)
01512 {
01513     WRITE_NODE_TYPE("INDEXPATH");
01514 
01515     _outPathInfo(str, (const Path *) node);
01516 
01517     WRITE_NODE_FIELD(indexinfo);
01518     WRITE_NODE_FIELD(indexclauses);
01519     WRITE_NODE_FIELD(indexquals);
01520     WRITE_NODE_FIELD(indexqualcols);
01521     WRITE_NODE_FIELD(indexorderbys);
01522     WRITE_NODE_FIELD(indexorderbycols);
01523     WRITE_ENUM_FIELD(indexscandir, ScanDirection);
01524     WRITE_FLOAT_FIELD(indextotalcost, "%.2f");
01525     WRITE_FLOAT_FIELD(indexselectivity, "%.4f");
01526 }
01527 
01528 static void
01529 _outBitmapHeapPath(StringInfo str, const BitmapHeapPath *node)
01530 {
01531     WRITE_NODE_TYPE("BITMAPHEAPPATH");
01532 
01533     _outPathInfo(str, (const Path *) node);
01534 
01535     WRITE_NODE_FIELD(bitmapqual);
01536 }
01537 
01538 static void
01539 _outBitmapAndPath(StringInfo str, const BitmapAndPath *node)
01540 {
01541     WRITE_NODE_TYPE("BITMAPANDPATH");
01542 
01543     _outPathInfo(str, (const Path *) node);
01544 
01545     WRITE_NODE_FIELD(bitmapquals);
01546     WRITE_FLOAT_FIELD(bitmapselectivity, "%.4f");
01547 }
01548 
01549 static void
01550 _outBitmapOrPath(StringInfo str, const BitmapOrPath *node)
01551 {
01552     WRITE_NODE_TYPE("BITMAPORPATH");
01553 
01554     _outPathInfo(str, (const Path *) node);
01555 
01556     WRITE_NODE_FIELD(bitmapquals);
01557     WRITE_FLOAT_FIELD(bitmapselectivity, "%.4f");
01558 }
01559 
01560 static void
01561 _outTidPath(StringInfo str, const TidPath *node)
01562 {
01563     WRITE_NODE_TYPE("TIDPATH");
01564 
01565     _outPathInfo(str, (const Path *) node);
01566 
01567     WRITE_NODE_FIELD(tidquals);
01568 }
01569 
01570 static void
01571 _outForeignPath(StringInfo str, const ForeignPath *node)
01572 {
01573     WRITE_NODE_TYPE("FOREIGNPATH");
01574 
01575     _outPathInfo(str, (const Path *) node);
01576 
01577     WRITE_NODE_FIELD(fdw_private);
01578 }
01579 
01580 static void
01581 _outAppendPath(StringInfo str, const AppendPath *node)
01582 {
01583     WRITE_NODE_TYPE("APPENDPATH");
01584 
01585     _outPathInfo(str, (const Path *) node);
01586 
01587     WRITE_NODE_FIELD(subpaths);
01588 }
01589 
01590 static void
01591 _outMergeAppendPath(StringInfo str, const MergeAppendPath *node)
01592 {
01593     WRITE_NODE_TYPE("MERGEAPPENDPATH");
01594 
01595     _outPathInfo(str, (const Path *) node);
01596 
01597     WRITE_NODE_FIELD(subpaths);
01598     WRITE_FLOAT_FIELD(limit_tuples, "%.0f");
01599 }
01600 
01601 static void
01602 _outResultPath(StringInfo str, const ResultPath *node)
01603 {
01604     WRITE_NODE_TYPE("RESULTPATH");
01605 
01606     _outPathInfo(str, (const Path *) node);
01607 
01608     WRITE_NODE_FIELD(quals);
01609 }
01610 
01611 static void
01612 _outMaterialPath(StringInfo str, const MaterialPath *node)
01613 {
01614     WRITE_NODE_TYPE("MATERIALPATH");
01615 
01616     _outPathInfo(str, (const Path *) node);
01617 
01618     WRITE_NODE_FIELD(subpath);
01619 }
01620 
01621 static void
01622 _outUniquePath(StringInfo str, const UniquePath *node)
01623 {
01624     WRITE_NODE_TYPE("UNIQUEPATH");
01625 
01626     _outPathInfo(str, (const Path *) node);
01627 
01628     WRITE_NODE_FIELD(subpath);
01629     WRITE_ENUM_FIELD(umethod, UniquePathMethod);
01630     WRITE_NODE_FIELD(in_operators);
01631     WRITE_NODE_FIELD(uniq_exprs);
01632 }
01633 
01634 static void
01635 _outNestPath(StringInfo str, const NestPath *node)
01636 {
01637     WRITE_NODE_TYPE("NESTPATH");
01638 
01639     _outJoinPathInfo(str, (const JoinPath *) node);
01640 }
01641 
01642 static void
01643 _outMergePath(StringInfo str, const MergePath *node)
01644 {
01645     WRITE_NODE_TYPE("MERGEPATH");
01646 
01647     _outJoinPathInfo(str, (const JoinPath *) node);
01648 
01649     WRITE_NODE_FIELD(path_mergeclauses);
01650     WRITE_NODE_FIELD(outersortkeys);
01651     WRITE_NODE_FIELD(innersortkeys);
01652     WRITE_BOOL_FIELD(materialize_inner);
01653 }
01654 
01655 static void
01656 _outHashPath(StringInfo str, const HashPath *node)
01657 {
01658     WRITE_NODE_TYPE("HASHPATH");
01659 
01660     _outJoinPathInfo(str, (const JoinPath *) node);
01661 
01662     WRITE_NODE_FIELD(path_hashclauses);
01663     WRITE_INT_FIELD(num_batches);
01664 }
01665 
01666 static void
01667 _outPlannerGlobal(StringInfo str, const PlannerGlobal *node)
01668 {
01669     WRITE_NODE_TYPE("PLANNERGLOBAL");
01670 
01671     /* NB: this isn't a complete set of fields */
01672     WRITE_NODE_FIELD(subplans);
01673     WRITE_BITMAPSET_FIELD(rewindPlanIDs);
01674     WRITE_NODE_FIELD(finalrtable);
01675     WRITE_NODE_FIELD(finalrowmarks);
01676     WRITE_NODE_FIELD(resultRelations);
01677     WRITE_NODE_FIELD(relationOids);
01678     WRITE_NODE_FIELD(invalItems);
01679     WRITE_INT_FIELD(nParamExec);
01680     WRITE_UINT_FIELD(lastPHId);
01681     WRITE_UINT_FIELD(lastRowMarkId);
01682     WRITE_BOOL_FIELD(transientPlan);
01683 }
01684 
01685 static void
01686 _outPlannerInfo(StringInfo str, const PlannerInfo *node)
01687 {
01688     WRITE_NODE_TYPE("PLANNERINFO");
01689 
01690     /* NB: this isn't a complete set of fields */
01691     WRITE_NODE_FIELD(parse);
01692     WRITE_NODE_FIELD(glob);
01693     WRITE_UINT_FIELD(query_level);
01694     WRITE_NODE_FIELD(plan_params);
01695     WRITE_BITMAPSET_FIELD(all_baserels);
01696     WRITE_NODE_FIELD(join_rel_list);
01697     WRITE_INT_FIELD(join_cur_level);
01698     WRITE_NODE_FIELD(init_plans);
01699     WRITE_NODE_FIELD(cte_plan_ids);
01700     WRITE_NODE_FIELD(eq_classes);
01701     WRITE_NODE_FIELD(canon_pathkeys);
01702     WRITE_NODE_FIELD(left_join_clauses);
01703     WRITE_NODE_FIELD(right_join_clauses);
01704     WRITE_NODE_FIELD(full_join_clauses);
01705     WRITE_NODE_FIELD(join_info_list);
01706     WRITE_NODE_FIELD(lateral_info_list);
01707     WRITE_NODE_FIELD(append_rel_list);
01708     WRITE_NODE_FIELD(rowMarks);
01709     WRITE_NODE_FIELD(placeholder_list);
01710     WRITE_NODE_FIELD(query_pathkeys);
01711     WRITE_NODE_FIELD(group_pathkeys);
01712     WRITE_NODE_FIELD(window_pathkeys);
01713     WRITE_NODE_FIELD(distinct_pathkeys);
01714     WRITE_NODE_FIELD(sort_pathkeys);
01715     WRITE_NODE_FIELD(minmax_aggs);
01716     WRITE_FLOAT_FIELD(total_table_pages, "%.0f");
01717     WRITE_FLOAT_FIELD(tuple_fraction, "%.4f");
01718     WRITE_FLOAT_FIELD(limit_tuples, "%.0f");
01719     WRITE_BOOL_FIELD(hasInheritedTarget);
01720     WRITE_BOOL_FIELD(hasJoinRTEs);
01721     WRITE_BOOL_FIELD(hasLateralRTEs);
01722     WRITE_BOOL_FIELD(hasHavingQual);
01723     WRITE_BOOL_FIELD(hasPseudoConstantQuals);
01724     WRITE_BOOL_FIELD(hasRecursion);
01725     WRITE_INT_FIELD(wt_param_id);
01726     WRITE_BITMAPSET_FIELD(curOuterRels);
01727     WRITE_NODE_FIELD(curOuterParams);
01728 }
01729 
01730 static void
01731 _outRelOptInfo(StringInfo str, const RelOptInfo *node)
01732 {
01733     WRITE_NODE_TYPE("RELOPTINFO");
01734 
01735     /* NB: this isn't a complete set of fields */
01736     WRITE_ENUM_FIELD(reloptkind, RelOptKind);
01737     WRITE_BITMAPSET_FIELD(relids);
01738     WRITE_FLOAT_FIELD(rows, "%.0f");
01739     WRITE_INT_FIELD(width);
01740     WRITE_BOOL_FIELD(consider_startup);
01741     WRITE_NODE_FIELD(reltargetlist);
01742     WRITE_NODE_FIELD(pathlist);
01743     WRITE_NODE_FIELD(ppilist);
01744     WRITE_NODE_FIELD(cheapest_startup_path);
01745     WRITE_NODE_FIELD(cheapest_total_path);
01746     WRITE_NODE_FIELD(cheapest_unique_path);
01747     WRITE_NODE_FIELD(cheapest_parameterized_paths);
01748     WRITE_UINT_FIELD(relid);
01749     WRITE_UINT_FIELD(reltablespace);
01750     WRITE_ENUM_FIELD(rtekind, RTEKind);
01751     WRITE_INT_FIELD(min_attr);
01752     WRITE_INT_FIELD(max_attr);
01753     WRITE_NODE_FIELD(lateral_vars);
01754     WRITE_BITMAPSET_FIELD(lateral_relids);
01755     WRITE_NODE_FIELD(indexlist);
01756     WRITE_UINT_FIELD(pages);
01757     WRITE_FLOAT_FIELD(tuples, "%.0f");
01758     WRITE_FLOAT_FIELD(allvisfrac, "%.6f");
01759     WRITE_NODE_FIELD(subplan);
01760     WRITE_NODE_FIELD(subroot);
01761     WRITE_NODE_FIELD(subplan_params);
01762     /* we don't try to print fdwroutine or fdw_private */
01763     WRITE_NODE_FIELD(baserestrictinfo);
01764     WRITE_NODE_FIELD(joininfo);
01765     WRITE_BOOL_FIELD(has_eclass_joins);
01766 }
01767 
01768 static void
01769 _outIndexOptInfo(StringInfo str, const IndexOptInfo *node)
01770 {
01771     WRITE_NODE_TYPE("INDEXOPTINFO");
01772 
01773     /* NB: this isn't a complete set of fields */
01774     WRITE_OID_FIELD(indexoid);
01775     /* Do NOT print rel field, else infinite recursion */
01776     WRITE_UINT_FIELD(pages);
01777     WRITE_FLOAT_FIELD(tuples, "%.0f");
01778     WRITE_INT_FIELD(tree_height);
01779     WRITE_INT_FIELD(ncolumns);
01780     /* array fields aren't really worth the trouble to print */
01781     WRITE_OID_FIELD(relam);
01782     /* indexprs is redundant since we print indextlist */
01783     WRITE_NODE_FIELD(indpred);
01784     WRITE_NODE_FIELD(indextlist);
01785     WRITE_BOOL_FIELD(predOK);
01786     WRITE_BOOL_FIELD(unique);
01787     WRITE_BOOL_FIELD(immediate);
01788     WRITE_BOOL_FIELD(hypothetical);
01789     /* we don't bother with fields copied from the pg_am entry */
01790 }
01791 
01792 static void
01793 _outEquivalenceClass(StringInfo str, const EquivalenceClass *node)
01794 {
01795     /*
01796      * To simplify reading, we just chase up to the topmost merged EC and
01797      * print that, without bothering to show the merge-ees separately.
01798      */
01799     while (node->ec_merged)
01800         node = node->ec_merged;
01801 
01802     WRITE_NODE_TYPE("EQUIVALENCECLASS");
01803 
01804     WRITE_NODE_FIELD(ec_opfamilies);
01805     WRITE_OID_FIELD(ec_collation);
01806     WRITE_NODE_FIELD(ec_members);
01807     WRITE_NODE_FIELD(ec_sources);
01808     WRITE_NODE_FIELD(ec_derives);
01809     WRITE_BITMAPSET_FIELD(ec_relids);
01810     WRITE_BOOL_FIELD(ec_has_const);
01811     WRITE_BOOL_FIELD(ec_has_volatile);
01812     WRITE_BOOL_FIELD(ec_below_outer_join);
01813     WRITE_BOOL_FIELD(ec_broken);
01814     WRITE_UINT_FIELD(ec_sortref);
01815 }
01816 
01817 static void
01818 _outEquivalenceMember(StringInfo str, const EquivalenceMember *node)
01819 {
01820     WRITE_NODE_TYPE("EQUIVALENCEMEMBER");
01821 
01822     WRITE_NODE_FIELD(em_expr);
01823     WRITE_BITMAPSET_FIELD(em_relids);
01824     WRITE_BITMAPSET_FIELD(em_nullable_relids);
01825     WRITE_BOOL_FIELD(em_is_const);
01826     WRITE_BOOL_FIELD(em_is_child);
01827     WRITE_OID_FIELD(em_datatype);
01828 }
01829 
01830 static void
01831 _outPathKey(StringInfo str, const PathKey *node)
01832 {
01833     WRITE_NODE_TYPE("PATHKEY");
01834 
01835     WRITE_NODE_FIELD(pk_eclass);
01836     WRITE_OID_FIELD(pk_opfamily);
01837     WRITE_INT_FIELD(pk_strategy);
01838     WRITE_BOOL_FIELD(pk_nulls_first);
01839 }
01840 
01841 static void
01842 _outParamPathInfo(StringInfo str, const ParamPathInfo *node)
01843 {
01844     WRITE_NODE_TYPE("PARAMPATHINFO");
01845 
01846     WRITE_BITMAPSET_FIELD(ppi_req_outer);
01847     WRITE_FLOAT_FIELD(ppi_rows, "%.0f");
01848     WRITE_NODE_FIELD(ppi_clauses);
01849 }
01850 
01851 static void
01852 _outRestrictInfo(StringInfo str, const RestrictInfo *node)
01853 {
01854     WRITE_NODE_TYPE("RESTRICTINFO");
01855 
01856     /* NB: this isn't a complete set of fields */
01857     WRITE_NODE_FIELD(clause);
01858     WRITE_BOOL_FIELD(is_pushed_down);
01859     WRITE_BOOL_FIELD(outerjoin_delayed);
01860     WRITE_BOOL_FIELD(can_join);
01861     WRITE_BOOL_FIELD(pseudoconstant);
01862     WRITE_BITMAPSET_FIELD(clause_relids);
01863     WRITE_BITMAPSET_FIELD(required_relids);
01864     WRITE_BITMAPSET_FIELD(outer_relids);
01865     WRITE_BITMAPSET_FIELD(nullable_relids);
01866     WRITE_BITMAPSET_FIELD(left_relids);
01867     WRITE_BITMAPSET_FIELD(right_relids);
01868     WRITE_NODE_FIELD(orclause);
01869     /* don't write parent_ec, leads to infinite recursion in plan tree dump */
01870     WRITE_FLOAT_FIELD(norm_selec, "%.4f");
01871     WRITE_FLOAT_FIELD(outer_selec, "%.4f");
01872     WRITE_NODE_FIELD(mergeopfamilies);
01873     /* don't write left_ec, leads to infinite recursion in plan tree dump */
01874     /* don't write right_ec, leads to infinite recursion in plan tree dump */
01875     WRITE_NODE_FIELD(left_em);
01876     WRITE_NODE_FIELD(right_em);
01877     WRITE_BOOL_FIELD(outer_is_left);
01878     WRITE_OID_FIELD(hashjoinoperator);
01879 }
01880 
01881 static void
01882 _outPlaceHolderVar(StringInfo str, const PlaceHolderVar *node)
01883 {
01884     WRITE_NODE_TYPE("PLACEHOLDERVAR");
01885 
01886     WRITE_NODE_FIELD(phexpr);
01887     WRITE_BITMAPSET_FIELD(phrels);
01888     WRITE_UINT_FIELD(phid);
01889     WRITE_UINT_FIELD(phlevelsup);
01890 }
01891 
01892 static void
01893 _outSpecialJoinInfo(StringInfo str, const SpecialJoinInfo *node)
01894 {
01895     WRITE_NODE_TYPE("SPECIALJOININFO");
01896 
01897     WRITE_BITMAPSET_FIELD(min_lefthand);
01898     WRITE_BITMAPSET_FIELD(min_righthand);
01899     WRITE_BITMAPSET_FIELD(syn_lefthand);
01900     WRITE_BITMAPSET_FIELD(syn_righthand);
01901     WRITE_ENUM_FIELD(jointype, JoinType);
01902     WRITE_BOOL_FIELD(lhs_strict);
01903     WRITE_BOOL_FIELD(delay_upper_joins);
01904     WRITE_NODE_FIELD(join_quals);
01905 }
01906 
01907 static void
01908 _outLateralJoinInfo(StringInfo str, const LateralJoinInfo *node)
01909 {
01910     WRITE_NODE_TYPE("LATERALJOININFO");
01911 
01912     WRITE_UINT_FIELD(lateral_rhs);
01913     WRITE_BITMAPSET_FIELD(lateral_lhs);
01914 }
01915 
01916 static void
01917 _outAppendRelInfo(StringInfo str, const AppendRelInfo *node)
01918 {
01919     WRITE_NODE_TYPE("APPENDRELINFO");
01920 
01921     WRITE_UINT_FIELD(parent_relid);
01922     WRITE_UINT_FIELD(child_relid);
01923     WRITE_OID_FIELD(parent_reltype);
01924     WRITE_OID_FIELD(child_reltype);
01925     WRITE_NODE_FIELD(translated_vars);
01926     WRITE_OID_FIELD(parent_reloid);
01927 }
01928 
01929 static void
01930 _outPlaceHolderInfo(StringInfo str, const PlaceHolderInfo *node)
01931 {
01932     WRITE_NODE_TYPE("PLACEHOLDERINFO");
01933 
01934     WRITE_UINT_FIELD(phid);
01935     WRITE_NODE_FIELD(ph_var);
01936     WRITE_BITMAPSET_FIELD(ph_eval_at);
01937     WRITE_BITMAPSET_FIELD(ph_needed);
01938     WRITE_BITMAPSET_FIELD(ph_may_need);
01939     WRITE_INT_FIELD(ph_width);
01940 }
01941 
01942 static void
01943 _outMinMaxAggInfo(StringInfo str, const MinMaxAggInfo *node)
01944 {
01945     WRITE_NODE_TYPE("MINMAXAGGINFO");
01946 
01947     WRITE_OID_FIELD(aggfnoid);
01948     WRITE_OID_FIELD(aggsortop);
01949     WRITE_NODE_FIELD(target);
01950     /* We intentionally omit subroot --- too large, not interesting enough */
01951     WRITE_NODE_FIELD(path);
01952     WRITE_FLOAT_FIELD(pathcost, "%.2f");
01953     WRITE_NODE_FIELD(param);
01954 }
01955 
01956 static void
01957 _outPlannerParamItem(StringInfo str, const PlannerParamItem *node)
01958 {
01959     WRITE_NODE_TYPE("PLANNERPARAMITEM");
01960 
01961     WRITE_NODE_FIELD(item);
01962     WRITE_INT_FIELD(paramId);
01963 }
01964 
01965 /*****************************************************************************
01966  *
01967  *  Stuff from parsenodes.h.
01968  *
01969  *****************************************************************************/
01970 
01971 /*
01972  * print the basic stuff of all nodes that inherit from CreateStmt
01973  */
01974 static void
01975 _outCreateStmtInfo(StringInfo str, const CreateStmt *node)
01976 {
01977     WRITE_NODE_FIELD(relation);
01978     WRITE_NODE_FIELD(tableElts);
01979     WRITE_NODE_FIELD(inhRelations);
01980     WRITE_NODE_FIELD(ofTypename);
01981     WRITE_NODE_FIELD(constraints);
01982     WRITE_NODE_FIELD(options);
01983     WRITE_ENUM_FIELD(oncommit, OnCommitAction);
01984     WRITE_STRING_FIELD(tablespacename);
01985     WRITE_BOOL_FIELD(if_not_exists);
01986 }
01987 
01988 static void
01989 _outCreateStmt(StringInfo str, const CreateStmt *node)
01990 {
01991     WRITE_NODE_TYPE("CREATESTMT");
01992 
01993     _outCreateStmtInfo(str, (const CreateStmt *) node);
01994 }
01995 
01996 static void
01997 _outCreateForeignTableStmt(StringInfo str, const CreateForeignTableStmt *node)
01998 {
01999     WRITE_NODE_TYPE("CREATEFOREIGNTABLESTMT");
02000 
02001     _outCreateStmtInfo(str, (const CreateStmt *) node);
02002 
02003     WRITE_STRING_FIELD(servername);
02004     WRITE_NODE_FIELD(options);
02005 }
02006 
02007 static void
02008 _outIndexStmt(StringInfo str, const IndexStmt *node)
02009 {
02010     WRITE_NODE_TYPE("INDEXSTMT");
02011 
02012     WRITE_STRING_FIELD(idxname);
02013     WRITE_NODE_FIELD(relation);
02014     WRITE_STRING_FIELD(accessMethod);
02015     WRITE_STRING_FIELD(tableSpace);
02016     WRITE_NODE_FIELD(indexParams);
02017     WRITE_NODE_FIELD(options);
02018     WRITE_NODE_FIELD(whereClause);
02019     WRITE_NODE_FIELD(excludeOpNames);
02020     WRITE_STRING_FIELD(idxcomment);
02021     WRITE_OID_FIELD(indexOid);
02022     WRITE_OID_FIELD(oldNode);
02023     WRITE_BOOL_FIELD(unique);
02024     WRITE_BOOL_FIELD(primary);
02025     WRITE_BOOL_FIELD(isconstraint);
02026     WRITE_BOOL_FIELD(deferrable);
02027     WRITE_BOOL_FIELD(initdeferred);
02028     WRITE_BOOL_FIELD(concurrent);
02029 }
02030 
02031 static void
02032 _outNotifyStmt(StringInfo str, const NotifyStmt *node)
02033 {
02034     WRITE_NODE_TYPE("NOTIFY");
02035 
02036     WRITE_STRING_FIELD(conditionname);
02037     WRITE_STRING_FIELD(payload);
02038 }
02039 
02040 static void
02041 _outDeclareCursorStmt(StringInfo str, const DeclareCursorStmt *node)
02042 {
02043     WRITE_NODE_TYPE("DECLARECURSOR");
02044 
02045     WRITE_STRING_FIELD(portalname);
02046     WRITE_INT_FIELD(options);
02047     WRITE_NODE_FIELD(query);
02048 }
02049 
02050 static void
02051 _outSelectStmt(StringInfo str, const SelectStmt *node)
02052 {
02053     WRITE_NODE_TYPE("SELECT");
02054 
02055     WRITE_NODE_FIELD(distinctClause);
02056     WRITE_NODE_FIELD(intoClause);
02057     WRITE_NODE_FIELD(targetList);
02058     WRITE_NODE_FIELD(fromClause);
02059     WRITE_NODE_FIELD(whereClause);
02060     WRITE_NODE_FIELD(groupClause);
02061     WRITE_NODE_FIELD(havingClause);
02062     WRITE_NODE_FIELD(windowClause);
02063     WRITE_NODE_FIELD(valuesLists);
02064     WRITE_NODE_FIELD(sortClause);
02065     WRITE_NODE_FIELD(limitOffset);
02066     WRITE_NODE_FIELD(limitCount);
02067     WRITE_NODE_FIELD(lockingClause);
02068     WRITE_NODE_FIELD(withClause);
02069     WRITE_ENUM_FIELD(op, SetOperation);
02070     WRITE_BOOL_FIELD(all);
02071     WRITE_NODE_FIELD(larg);
02072     WRITE_NODE_FIELD(rarg);
02073 }
02074 
02075 static void
02076 _outFuncCall(StringInfo str, const FuncCall *node)
02077 {
02078     WRITE_NODE_TYPE("FUNCCALL");
02079 
02080     WRITE_NODE_FIELD(funcname);
02081     WRITE_NODE_FIELD(args);
02082     WRITE_NODE_FIELD(agg_order);
02083     WRITE_BOOL_FIELD(agg_star);
02084     WRITE_BOOL_FIELD(agg_distinct);
02085     WRITE_BOOL_FIELD(func_variadic);
02086     WRITE_NODE_FIELD(over);
02087     WRITE_LOCATION_FIELD(location);
02088 }
02089 
02090 static void
02091 _outDefElem(StringInfo str, const DefElem *node)
02092 {
02093     WRITE_NODE_TYPE("DEFELEM");
02094 
02095     WRITE_STRING_FIELD(defnamespace);
02096     WRITE_STRING_FIELD(defname);
02097     WRITE_NODE_FIELD(arg);
02098     WRITE_ENUM_FIELD(defaction, DefElemAction);
02099 }
02100 
02101 static void
02102 _outTableLikeClause(StringInfo str, const TableLikeClause *node)
02103 {
02104     WRITE_NODE_TYPE("TABLELIKECLAUSE");
02105 
02106     WRITE_NODE_FIELD(relation);
02107     WRITE_UINT_FIELD(options);
02108 }
02109 
02110 static void
02111 _outLockingClause(StringInfo str, const LockingClause *node)
02112 {
02113     WRITE_NODE_TYPE("LOCKINGCLAUSE");
02114 
02115     WRITE_NODE_FIELD(lockedRels);
02116     WRITE_ENUM_FIELD(strength, LockClauseStrength);
02117     WRITE_BOOL_FIELD(noWait);
02118 }
02119 
02120 static void
02121 _outXmlSerialize(StringInfo str, const XmlSerialize *node)
02122 {
02123     WRITE_NODE_TYPE("XMLSERIALIZE");
02124 
02125     WRITE_ENUM_FIELD(xmloption, XmlOptionType);
02126     WRITE_NODE_FIELD(expr);
02127     WRITE_NODE_FIELD(typeName);
02128     WRITE_LOCATION_FIELD(location);
02129 }
02130 
02131 static void
02132 _outColumnDef(StringInfo str, const ColumnDef *node)
02133 {
02134     WRITE_NODE_TYPE("COLUMNDEF");
02135 
02136     WRITE_STRING_FIELD(colname);
02137     WRITE_NODE_FIELD(typeName);
02138     WRITE_INT_FIELD(inhcount);
02139     WRITE_BOOL_FIELD(is_local);
02140     WRITE_BOOL_FIELD(is_not_null);
02141     WRITE_BOOL_FIELD(is_from_type);
02142     WRITE_CHAR_FIELD(storage);
02143     WRITE_NODE_FIELD(raw_default);
02144     WRITE_NODE_FIELD(cooked_default);
02145     WRITE_NODE_FIELD(collClause);
02146     WRITE_OID_FIELD(collOid);
02147     WRITE_NODE_FIELD(constraints);
02148     WRITE_NODE_FIELD(fdwoptions);
02149 }
02150 
02151 static void
02152 _outTypeName(StringInfo str, const TypeName *node)
02153 {
02154     WRITE_NODE_TYPE("TYPENAME");
02155 
02156     WRITE_NODE_FIELD(names);
02157     WRITE_OID_FIELD(typeOid);
02158     WRITE_BOOL_FIELD(setof);
02159     WRITE_BOOL_FIELD(pct_type);
02160     WRITE_NODE_FIELD(typmods);
02161     WRITE_INT_FIELD(typemod);
02162     WRITE_NODE_FIELD(arrayBounds);
02163     WRITE_LOCATION_FIELD(location);
02164 }
02165 
02166 static void
02167 _outTypeCast(StringInfo str, const TypeCast *node)
02168 {
02169     WRITE_NODE_TYPE("TYPECAST");
02170 
02171     WRITE_NODE_FIELD(arg);
02172     WRITE_NODE_FIELD(typeName);
02173     WRITE_LOCATION_FIELD(location);
02174 }
02175 
02176 static void
02177 _outCollateClause(StringInfo str, const CollateClause *node)
02178 {
02179     WRITE_NODE_TYPE("COLLATECLAUSE");
02180 
02181     WRITE_NODE_FIELD(arg);
02182     WRITE_NODE_FIELD(collname);
02183     WRITE_LOCATION_FIELD(location);
02184 }
02185 
02186 static void
02187 _outIndexElem(StringInfo str, const IndexElem *node)
02188 {
02189     WRITE_NODE_TYPE("INDEXELEM");
02190 
02191     WRITE_STRING_FIELD(name);
02192     WRITE_NODE_FIELD(expr);
02193     WRITE_STRING_FIELD(indexcolname);
02194     WRITE_NODE_FIELD(collation);
02195     WRITE_NODE_FIELD(opclass);
02196     WRITE_ENUM_FIELD(ordering, SortByDir);
02197     WRITE_ENUM_FIELD(nulls_ordering, SortByNulls);
02198 }
02199 
02200 static void
02201 _outQuery(StringInfo str, const Query *node)
02202 {
02203     WRITE_NODE_TYPE("QUERY");
02204 
02205     WRITE_ENUM_FIELD(commandType, CmdType);
02206     WRITE_ENUM_FIELD(querySource, QuerySource);
02207     /* we intentionally do not print the queryId field */
02208     WRITE_BOOL_FIELD(canSetTag);
02209 
02210     /*
02211      * Hack to work around missing outfuncs routines for a lot of the
02212      * utility-statement node types.  (The only one we actually *need* for
02213      * rules support is NotifyStmt.)  Someday we ought to support 'em all, but
02214      * for the meantime do this to avoid getting lots of warnings when running
02215      * with debug_print_parse on.
02216      */
02217     if (node->utilityStmt)
02218     {
02219         switch (nodeTag(node->utilityStmt))
02220         {
02221             case T_CreateStmt:
02222             case T_IndexStmt:
02223             case T_NotifyStmt:
02224             case T_DeclareCursorStmt:
02225                 WRITE_NODE_FIELD(utilityStmt);
02226                 break;
02227             default:
02228                 appendStringInfo(str, " :utilityStmt ?");
02229                 break;
02230         }
02231     }
02232     else
02233         appendStringInfo(str, " :utilityStmt <>");
02234 
02235     WRITE_INT_FIELD(resultRelation);
02236     WRITE_BOOL_FIELD(hasAggs);
02237     WRITE_BOOL_FIELD(hasWindowFuncs);
02238     WRITE_BOOL_FIELD(hasSubLinks);
02239     WRITE_BOOL_FIELD(hasDistinctOn);
02240     WRITE_BOOL_FIELD(hasRecursive);
02241     WRITE_BOOL_FIELD(hasModifyingCTE);
02242     WRITE_BOOL_FIELD(hasForUpdate);
02243     WRITE_NODE_FIELD(cteList);
02244     WRITE_NODE_FIELD(rtable);
02245     WRITE_NODE_FIELD(jointree);
02246     WRITE_NODE_FIELD(targetList);
02247     WRITE_NODE_FIELD(returningList);
02248     WRITE_NODE_FIELD(groupClause);
02249     WRITE_NODE_FIELD(havingQual);
02250     WRITE_NODE_FIELD(windowClause);
02251     WRITE_NODE_FIELD(distinctClause);
02252     WRITE_NODE_FIELD(sortClause);
02253     WRITE_NODE_FIELD(limitOffset);
02254     WRITE_NODE_FIELD(limitCount);
02255     WRITE_NODE_FIELD(rowMarks);
02256     WRITE_NODE_FIELD(setOperations);
02257     WRITE_NODE_FIELD(constraintDeps);
02258 }
02259 
02260 static void
02261 _outSortGroupClause(StringInfo str, const SortGroupClause *node)
02262 {
02263     WRITE_NODE_TYPE("SORTGROUPCLAUSE");
02264 
02265     WRITE_UINT_FIELD(tleSortGroupRef);
02266     WRITE_OID_FIELD(eqop);
02267     WRITE_OID_FIELD(sortop);
02268     WRITE_BOOL_FIELD(nulls_first);
02269     WRITE_BOOL_FIELD(hashable);
02270 }
02271 
02272 static void
02273 _outWindowClause(StringInfo str, const WindowClause *node)
02274 {
02275     WRITE_NODE_TYPE("WINDOWCLAUSE");
02276 
02277     WRITE_STRING_FIELD(name);
02278     WRITE_STRING_FIELD(refname);
02279     WRITE_NODE_FIELD(partitionClause);
02280     WRITE_NODE_FIELD(orderClause);
02281     WRITE_INT_FIELD(frameOptions);
02282     WRITE_NODE_FIELD(startOffset);
02283     WRITE_NODE_FIELD(endOffset);
02284     WRITE_UINT_FIELD(winref);
02285     WRITE_BOOL_FIELD(copiedOrder);
02286 }
02287 
02288 static void
02289 _outRowMarkClause(StringInfo str, const RowMarkClause *node)
02290 {
02291     WRITE_NODE_TYPE("ROWMARKCLAUSE");
02292 
02293     WRITE_UINT_FIELD(rti);
02294     WRITE_ENUM_FIELD(strength, LockClauseStrength);
02295     WRITE_BOOL_FIELD(noWait);
02296     WRITE_BOOL_FIELD(pushedDown);
02297 }
02298 
02299 static void
02300 _outWithClause(StringInfo str, const WithClause *node)
02301 {
02302     WRITE_NODE_TYPE("WITHCLAUSE");
02303 
02304     WRITE_NODE_FIELD(ctes);
02305     WRITE_BOOL_FIELD(recursive);
02306     WRITE_LOCATION_FIELD(location);
02307 }
02308 
02309 static void
02310 _outCommonTableExpr(StringInfo str, const CommonTableExpr *node)
02311 {
02312     WRITE_NODE_TYPE("COMMONTABLEEXPR");
02313 
02314     WRITE_STRING_FIELD(ctename);
02315     WRITE_NODE_FIELD(aliascolnames);
02316     WRITE_NODE_FIELD(ctequery);
02317     WRITE_LOCATION_FIELD(location);
02318     WRITE_BOOL_FIELD(cterecursive);
02319     WRITE_INT_FIELD(cterefcount);
02320     WRITE_NODE_FIELD(ctecolnames);
02321     WRITE_NODE_FIELD(ctecoltypes);
02322     WRITE_NODE_FIELD(ctecoltypmods);
02323     WRITE_NODE_FIELD(ctecolcollations);
02324 }
02325 
02326 static void
02327 _outSetOperationStmt(StringInfo str, const SetOperationStmt *node)
02328 {
02329     WRITE_NODE_TYPE("SETOPERATIONSTMT");
02330 
02331     WRITE_ENUM_FIELD(op, SetOperation);
02332     WRITE_BOOL_FIELD(all);
02333     WRITE_NODE_FIELD(larg);
02334     WRITE_NODE_FIELD(rarg);
02335     WRITE_NODE_FIELD(colTypes);
02336     WRITE_NODE_FIELD(colTypmods);
02337     WRITE_NODE_FIELD(colCollations);
02338     WRITE_NODE_FIELD(groupClauses);
02339 }
02340 
02341 static void
02342 _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
02343 {
02344     WRITE_NODE_TYPE("RTE");
02345 
02346     /* put alias + eref first to make dump more legible */
02347     WRITE_NODE_FIELD(alias);
02348     WRITE_NODE_FIELD(eref);
02349     WRITE_ENUM_FIELD(rtekind, RTEKind);
02350 
02351     switch (node->rtekind)
02352     {
02353         case RTE_RELATION:
02354             WRITE_OID_FIELD(relid);
02355             WRITE_CHAR_FIELD(relkind);
02356             break;
02357         case RTE_SUBQUERY:
02358             WRITE_NODE_FIELD(subquery);
02359             WRITE_BOOL_FIELD(security_barrier);
02360             break;
02361         case RTE_JOIN:
02362             WRITE_ENUM_FIELD(jointype, JoinType);
02363             WRITE_NODE_FIELD(joinaliasvars);
02364             break;
02365         case RTE_FUNCTION:
02366             WRITE_NODE_FIELD(funcexpr);
02367             WRITE_NODE_FIELD(funccoltypes);
02368             WRITE_NODE_FIELD(funccoltypmods);
02369             WRITE_NODE_FIELD(funccolcollations);
02370             break;
02371         case RTE_VALUES:
02372             WRITE_NODE_FIELD(values_lists);
02373             WRITE_NODE_FIELD(values_collations);
02374             break;
02375         case RTE_CTE:
02376             WRITE_STRING_FIELD(ctename);
02377             WRITE_UINT_FIELD(ctelevelsup);
02378             WRITE_BOOL_FIELD(self_reference);
02379             WRITE_NODE_FIELD(ctecoltypes);
02380             WRITE_NODE_FIELD(ctecoltypmods);
02381             WRITE_NODE_FIELD(ctecolcollations);
02382             break;
02383         default:
02384             elog(ERROR, "unrecognized RTE kind: %d", (int) node->rtekind);
02385             break;
02386     }
02387 
02388     WRITE_BOOL_FIELD(lateral);
02389     WRITE_BOOL_FIELD(inh);
02390     WRITE_BOOL_FIELD(inFromCl);
02391     WRITE_UINT_FIELD(requiredPerms);
02392     WRITE_OID_FIELD(checkAsUser);
02393     WRITE_BITMAPSET_FIELD(selectedCols);
02394     WRITE_BITMAPSET_FIELD(modifiedCols);
02395 }
02396 
02397 static void
02398 _outAExpr(StringInfo str, const A_Expr *node)
02399 {
02400     WRITE_NODE_TYPE("AEXPR");
02401 
02402     switch (node->kind)
02403     {
02404         case AEXPR_OP:
02405             appendStringInfo(str, " ");
02406             WRITE_NODE_FIELD(name);
02407             break;
02408         case AEXPR_AND:
02409             appendStringInfo(str, " AND");
02410             break;
02411         case AEXPR_OR:
02412             appendStringInfo(str, " OR");
02413             break;
02414         case AEXPR_NOT:
02415             appendStringInfo(str, " NOT");
02416             break;
02417         case AEXPR_OP_ANY:
02418             appendStringInfo(str, " ");
02419             WRITE_NODE_FIELD(name);
02420             appendStringInfo(str, " ANY ");
02421             break;
02422         case AEXPR_OP_ALL:
02423             appendStringInfo(str, " ");
02424             WRITE_NODE_FIELD(name);
02425             appendStringInfo(str, " ALL ");
02426             break;
02427         case AEXPR_DISTINCT:
02428             appendStringInfo(str, " DISTINCT ");
02429             WRITE_NODE_FIELD(name);
02430             break;
02431         case AEXPR_NULLIF:
02432             appendStringInfo(str, " NULLIF ");
02433             WRITE_NODE_FIELD(name);
02434             break;
02435         case AEXPR_OF:
02436             appendStringInfo(str, " OF ");
02437             WRITE_NODE_FIELD(name);
02438             break;
02439         case AEXPR_IN:
02440             appendStringInfo(str, " IN ");
02441             WRITE_NODE_FIELD(name);
02442             break;
02443         default:
02444             appendStringInfo(str, " ??");
02445             break;
02446     }
02447 
02448     WRITE_NODE_FIELD(lexpr);
02449     WRITE_NODE_FIELD(rexpr);
02450     WRITE_LOCATION_FIELD(location);
02451 }
02452 
02453 static void
02454 _outValue(StringInfo str, const Value *value)
02455 {
02456     switch (value->type)
02457     {
02458         case T_Integer:
02459             appendStringInfo(str, "%ld", value->val.ival);
02460             break;
02461         case T_Float:
02462 
02463             /*
02464              * We assume the value is a valid numeric literal and so does not
02465              * need quoting.
02466              */
02467             appendStringInfoString(str, value->val.str);
02468             break;
02469         case T_String:
02470             appendStringInfoChar(str, '"');
02471             _outToken(str, value->val.str);
02472             appendStringInfoChar(str, '"');
02473             break;
02474         case T_BitString:
02475             /* internal representation already has leading 'b' */
02476             appendStringInfoString(str, value->val.str);
02477             break;
02478         case T_Null:
02479             /* this is seen only within A_Const, not in transformed trees */
02480             appendStringInfoString(str, "NULL");
02481             break;
02482         default:
02483             elog(ERROR, "unrecognized node type: %d", (int) value->type);
02484             break;
02485     }
02486 }
02487 
02488 static void
02489 _outColumnRef(StringInfo str, const ColumnRef *node)
02490 {
02491     WRITE_NODE_TYPE("COLUMNREF");
02492 
02493     WRITE_NODE_FIELD(fields);
02494     WRITE_LOCATION_FIELD(location);
02495 }
02496 
02497 static void
02498 _outParamRef(StringInfo str, const ParamRef *node)
02499 {
02500     WRITE_NODE_TYPE("PARAMREF");
02501 
02502     WRITE_INT_FIELD(number);
02503     WRITE_LOCATION_FIELD(location);
02504 }
02505 
02506 static void
02507 _outAConst(StringInfo str, const A_Const *node)
02508 {
02509     WRITE_NODE_TYPE("A_CONST");
02510 
02511     appendStringInfo(str, " :val ");
02512     _outValue(str, &(node->val));
02513     WRITE_LOCATION_FIELD(location);
02514 }
02515 
02516 static void
02517 _outA_Star(StringInfo str, const A_Star *node)
02518 {
02519     WRITE_NODE_TYPE("A_STAR");
02520 }
02521 
02522 static void
02523 _outA_Indices(StringInfo str, const A_Indices *node)
02524 {
02525     WRITE_NODE_TYPE("A_INDICES");
02526 
02527     WRITE_NODE_FIELD(lidx);
02528     WRITE_NODE_FIELD(uidx);
02529 }
02530 
02531 static void
02532 _outA_Indirection(StringInfo str, const A_Indirection *node)
02533 {
02534     WRITE_NODE_TYPE("A_INDIRECTION");
02535 
02536     WRITE_NODE_FIELD(arg);
02537     WRITE_NODE_FIELD(indirection);
02538 }
02539 
02540 static void
02541 _outA_ArrayExpr(StringInfo str, const A_ArrayExpr *node)
02542 {
02543     WRITE_NODE_TYPE("A_ARRAYEXPR");
02544 
02545     WRITE_NODE_FIELD(elements);
02546     WRITE_LOCATION_FIELD(location);
02547 }
02548 
02549 static void
02550 _outResTarget(StringInfo str, const ResTarget *node)
02551 {
02552     WRITE_NODE_TYPE("RESTARGET");
02553 
02554     WRITE_STRING_FIELD(name);
02555     WRITE_NODE_FIELD(indirection);
02556     WRITE_NODE_FIELD(val);
02557     WRITE_LOCATION_FIELD(location);
02558 }
02559 
02560 static void
02561 _outSortBy(StringInfo str, const SortBy *node)
02562 {
02563     WRITE_NODE_TYPE("SORTBY");
02564 
02565     WRITE_NODE_FIELD(node);
02566     WRITE_ENUM_FIELD(sortby_dir, SortByDir);
02567     WRITE_ENUM_FIELD(sortby_nulls, SortByNulls);
02568     WRITE_NODE_FIELD(useOp);
02569     WRITE_LOCATION_FIELD(location);
02570 }
02571 
02572 static void
02573 _outWindowDef(StringInfo str, const WindowDef *node)
02574 {
02575     WRITE_NODE_TYPE("WINDOWDEF");
02576 
02577     WRITE_STRING_FIELD(name);
02578     WRITE_STRING_FIELD(refname);
02579     WRITE_NODE_FIELD(partitionClause);
02580     WRITE_NODE_FIELD(orderClause);
02581     WRITE_INT_FIELD(frameOptions);
02582     WRITE_NODE_FIELD(startOffset);
02583     WRITE_NODE_FIELD(endOffset);
02584     WRITE_LOCATION_FIELD(location);
02585 }
02586 
02587 static void
02588 _outRangeSubselect(StringInfo str, const RangeSubselect *node)
02589 {
02590     WRITE_NODE_TYPE("RANGESUBSELECT");
02591 
02592     WRITE_BOOL_FIELD(lateral);
02593     WRITE_NODE_FIELD(subquery);
02594     WRITE_NODE_FIELD(alias);
02595 }
02596 
02597 static void
02598 _outRangeFunction(StringInfo str, const RangeFunction *node)
02599 {
02600     WRITE_NODE_TYPE("RANGEFUNCTION");
02601 
02602     WRITE_BOOL_FIELD(lateral);
02603     WRITE_NODE_FIELD(funccallnode);
02604     WRITE_NODE_FIELD(alias);
02605     WRITE_NODE_FIELD(coldeflist);
02606 }
02607 
02608 static void
02609 _outConstraint(StringInfo str, const Constraint *node)
02610 {
02611     WRITE_NODE_TYPE("CONSTRAINT");
02612 
02613     WRITE_STRING_FIELD(conname);
02614     WRITE_BOOL_FIELD(deferrable);
02615     WRITE_BOOL_FIELD(initdeferred);
02616     WRITE_LOCATION_FIELD(location);
02617 
02618     appendStringInfo(str, " :contype ");
02619     switch (node->contype)
02620     {
02621         case CONSTR_NULL:
02622             appendStringInfo(str, "NULL");
02623             break;
02624 
02625         case CONSTR_NOTNULL:
02626             appendStringInfo(str, "NOT_NULL");
02627             break;
02628 
02629         case CONSTR_DEFAULT:
02630             appendStringInfo(str, "DEFAULT");
02631             WRITE_NODE_FIELD(raw_expr);
02632             WRITE_STRING_FIELD(cooked_expr);
02633             break;
02634 
02635         case CONSTR_CHECK:
02636             appendStringInfo(str, "CHECK");
02637             WRITE_BOOL_FIELD(is_no_inherit);
02638             WRITE_NODE_FIELD(raw_expr);
02639             WRITE_STRING_FIELD(cooked_expr);
02640             break;
02641 
02642         case CONSTR_PRIMARY:
02643             appendStringInfo(str, "PRIMARY_KEY");
02644             WRITE_NODE_FIELD(keys);
02645             WRITE_NODE_FIELD(options);
02646             WRITE_STRING_FIELD(indexname);
02647             WRITE_STRING_FIELD(indexspace);
02648             /* access_method and where_clause not currently used */
02649             break;
02650 
02651         case CONSTR_UNIQUE:
02652             appendStringInfo(str, "UNIQUE");
02653             WRITE_NODE_FIELD(keys);
02654             WRITE_NODE_FIELD(options);
02655             WRITE_STRING_FIELD(indexname);
02656             WRITE_STRING_FIELD(indexspace);
02657             /* access_method and where_clause not currently used */
02658             break;
02659 
02660         case CONSTR_EXCLUSION:
02661             appendStringInfo(str, "EXCLUSION");
02662             WRITE_NODE_FIELD(exclusions);
02663             WRITE_NODE_FIELD(options);
02664             WRITE_STRING_FIELD(indexname);
02665             WRITE_STRING_FIELD(indexspace);
02666             WRITE_STRING_FIELD(access_method);
02667             WRITE_NODE_FIELD(where_clause);
02668             break;
02669 
02670         case CONSTR_FOREIGN:
02671             appendStringInfo(str, "FOREIGN_KEY");
02672             WRITE_NODE_FIELD(pktable);
02673             WRITE_NODE_FIELD(fk_attrs);
02674             WRITE_NODE_FIELD(pk_attrs);
02675             WRITE_CHAR_FIELD(fk_matchtype);
02676             WRITE_CHAR_FIELD(fk_upd_action);
02677             WRITE_CHAR_FIELD(fk_del_action);
02678             WRITE_NODE_FIELD(old_conpfeqop);
02679             WRITE_BOOL_FIELD(skip_validation);
02680             WRITE_BOOL_FIELD(initially_valid);
02681             break;
02682 
02683         case CONSTR_ATTR_DEFERRABLE:
02684             appendStringInfo(str, "ATTR_DEFERRABLE");
02685             break;
02686 
02687         case CONSTR_ATTR_NOT_DEFERRABLE:
02688             appendStringInfo(str, "ATTR_NOT_DEFERRABLE");
02689             break;
02690 
02691         case CONSTR_ATTR_DEFERRED:
02692             appendStringInfo(str, "ATTR_DEFERRED");
02693             break;
02694 
02695         case CONSTR_ATTR_IMMEDIATE:
02696             appendStringInfo(str, "ATTR_IMMEDIATE");
02697             break;
02698 
02699         default:
02700             appendStringInfo(str, "<unrecognized_constraint %d>",
02701                              (int) node->contype);
02702             break;
02703     }
02704 }
02705 
02706 
02707 /*
02708  * _outNode -
02709  *    converts a Node into ascii string and append it to 'str'
02710  */
02711 static void
02712 _outNode(StringInfo str, const void *obj)
02713 {
02714     if (obj == NULL)
02715         appendStringInfo(str, "<>");
02716     else if (IsA(obj, List) ||IsA(obj, IntList) || IsA(obj, OidList))
02717         _outList(str, obj);
02718     else if (IsA(obj, Integer) ||
02719              IsA(obj, Float) ||
02720              IsA(obj, String) ||
02721              IsA(obj, BitString))
02722     {
02723         /* nodeRead does not want to see { } around these! */
02724         _outValue(str, obj);
02725     }
02726     else
02727     {
02728         appendStringInfoChar(str, '{');
02729         switch (nodeTag(obj))
02730         {
02731             case T_PlannedStmt:
02732                 _outPlannedStmt(str, obj);
02733                 break;
02734             case T_Plan:
02735                 _outPlan(str, obj);
02736                 break;
02737             case T_Result:
02738                 _outResult(str, obj);
02739                 break;
02740             case T_ModifyTable:
02741                 _outModifyTable(str, obj);
02742                 break;
02743             case T_Append:
02744                 _outAppend(str, obj);
02745                 break;
02746             case T_MergeAppend:
02747                 _outMergeAppend(str, obj);
02748                 break;
02749             case T_RecursiveUnion:
02750                 _outRecursiveUnion(str, obj);
02751                 break;
02752             case T_BitmapAnd:
02753                 _outBitmapAnd(str, obj);
02754                 break;
02755             case T_BitmapOr:
02756                 _outBitmapOr(str, obj);
02757                 break;
02758             case T_Scan:
02759                 _outScan(str, obj);
02760                 break;
02761             case T_SeqScan:
02762                 _outSeqScan(str, obj);
02763                 break;
02764             case T_IndexScan:
02765                 _outIndexScan(str, obj);
02766                 break;
02767             case T_IndexOnlyScan:
02768                 _outIndexOnlyScan(str, obj);
02769                 break;
02770             case T_BitmapIndexScan:
02771                 _outBitmapIndexScan(str, obj);
02772                 break;
02773             case T_BitmapHeapScan:
02774                 _outBitmapHeapScan(str, obj);
02775                 break;
02776             case T_TidScan:
02777                 _outTidScan(str, obj);
02778                 break;
02779             case T_SubqueryScan:
02780                 _outSubqueryScan(str, obj);
02781                 break;
02782             case T_FunctionScan:
02783                 _outFunctionScan(str, obj);
02784                 break;
02785             case T_ValuesScan:
02786                 _outValuesScan(str, obj);
02787                 break;
02788             case T_CteScan:
02789                 _outCteScan(str, obj);
02790                 break;
02791             case T_WorkTableScan:
02792                 _outWorkTableScan(str, obj);
02793                 break;
02794             case T_ForeignScan:
02795                 _outForeignScan(str, obj);
02796                 break;
02797             case T_Join:
02798                 _outJoin(str, obj);
02799                 break;
02800             case T_NestLoop:
02801                 _outNestLoop(str, obj);
02802                 break;
02803             case T_MergeJoin:
02804                 _outMergeJoin(str, obj);
02805                 break;
02806             case T_HashJoin:
02807                 _outHashJoin(str, obj);
02808                 break;
02809             case T_Agg:
02810                 _outAgg(str, obj);
02811                 break;
02812             case T_WindowAgg:
02813                 _outWindowAgg(str, obj);
02814                 break;
02815             case T_Group:
02816                 _outGroup(str, obj);
02817                 break;
02818             case T_Material:
02819                 _outMaterial(str, obj);
02820                 break;
02821             case T_Sort:
02822                 _outSort(str, obj);
02823                 break;
02824             case T_Unique:
02825                 _outUnique(str, obj);
02826                 break;
02827             case T_Hash:
02828                 _outHash(str, obj);
02829                 break;
02830             case T_SetOp:
02831                 _outSetOp(str, obj);
02832                 break;
02833             case T_LockRows:
02834                 _outLockRows(str, obj);
02835                 break;
02836             case T_Limit:
02837                 _outLimit(str, obj);
02838                 break;
02839             case T_NestLoopParam:
02840                 _outNestLoopParam(str, obj);
02841                 break;
02842             case T_PlanRowMark:
02843                 _outPlanRowMark(str, obj);
02844                 break;
02845             case T_PlanInvalItem:
02846                 _outPlanInvalItem(str, obj);
02847                 break;
02848             case T_Alias:
02849                 _outAlias(str, obj);
02850                 break;
02851             case T_RangeVar:
02852                 _outRangeVar(str, obj);
02853                 break;
02854             case T_IntoClause:
02855                 _outIntoClause(str, obj);
02856                 break;
02857             case T_Var:
02858                 _outVar(str, obj);
02859                 break;
02860             case T_Const:
02861                 _outConst(str, obj);
02862                 break;
02863             case T_Param:
02864                 _outParam(str, obj);
02865                 break;
02866             case T_Aggref:
02867                 _outAggref(str, obj);
02868                 break;
02869             case T_WindowFunc:
02870                 _outWindowFunc(str, obj);
02871                 break;
02872             case T_ArrayRef:
02873                 _outArrayRef(str, obj);
02874                 break;
02875             case T_FuncExpr:
02876                 _outFuncExpr(str, obj);
02877                 break;
02878             case T_NamedArgExpr:
02879                 _outNamedArgExpr(str, obj);
02880                 break;
02881             case T_OpExpr:
02882                 _outOpExpr(str, obj);
02883                 break;
02884             case T_DistinctExpr:
02885                 _outDistinctExpr(str, obj);
02886                 break;
02887             case T_NullIfExpr:
02888                 _outNullIfExpr(str, obj);
02889                 break;
02890             case T_ScalarArrayOpExpr:
02891                 _outScalarArrayOpExpr(str, obj);
02892                 break;
02893             case T_BoolExpr:
02894                 _outBoolExpr(str, obj);
02895                 break;
02896             case T_SubLink:
02897                 _outSubLink(str, obj);
02898                 break;
02899             case T_SubPlan:
02900                 _outSubPlan(str, obj);
02901                 break;
02902             case T_AlternativeSubPlan:
02903                 _outAlternativeSubPlan(str, obj);
02904                 break;
02905             case T_FieldSelect:
02906                 _outFieldSelect(str, obj);
02907                 break;
02908             case T_FieldStore:
02909                 _outFieldStore(str, obj);
02910                 break;
02911             case T_RelabelType:
02912                 _outRelabelType(str, obj);
02913                 break;
02914             case T_CoerceViaIO:
02915                 _outCoerceViaIO(str, obj);
02916                 break;
02917             case T_ArrayCoerceExpr:
02918                 _outArrayCoerceExpr(str, obj);
02919                 break;
02920             case T_ConvertRowtypeExpr:
02921                 _outConvertRowtypeExpr(str, obj);
02922                 break;
02923             case T_CollateExpr:
02924                 _outCollateExpr(str, obj);
02925                 break;
02926             case T_CaseExpr:
02927                 _outCaseExpr(str, obj);
02928                 break;
02929             case T_CaseWhen:
02930                 _outCaseWhen(str, obj);
02931                 break;
02932             case T_CaseTestExpr:
02933                 _outCaseTestExpr(str, obj);
02934                 break;
02935             case T_ArrayExpr:
02936                 _outArrayExpr(str, obj);
02937                 break;
02938             case T_RowExpr:
02939                 _outRowExpr(str, obj);
02940                 break;
02941             case T_RowCompareExpr:
02942                 _outRowCompareExpr(str, obj);
02943                 break;
02944             case T_CoalesceExpr:
02945                 _outCoalesceExpr(str, obj);
02946                 break;
02947             case T_MinMaxExpr:
02948                 _outMinMaxExpr(str, obj);
02949                 break;
02950             case T_XmlExpr:
02951                 _outXmlExpr(str, obj);
02952                 break;
02953             case T_NullTest:
02954                 _outNullTest(str, obj);
02955                 break;
02956             case T_BooleanTest:
02957                 _outBooleanTest(str, obj);
02958                 break;
02959             case T_CoerceToDomain:
02960                 _outCoerceToDomain(str, obj);
02961                 break;
02962             case T_CoerceToDomainValue:
02963                 _outCoerceToDomainValue(str, obj);
02964                 break;
02965             case T_SetToDefault:
02966                 _outSetToDefault(str, obj);
02967                 break;
02968             case T_CurrentOfExpr:
02969                 _outCurrentOfExpr(str, obj);
02970                 break;
02971             case T_TargetEntry:
02972                 _outTargetEntry(str, obj);
02973                 break;
02974             case T_RangeTblRef:
02975                 _outRangeTblRef(str, obj);
02976                 break;
02977             case T_JoinExpr:
02978                 _outJoinExpr(str, obj);
02979                 break;
02980             case T_FromExpr:
02981                 _outFromExpr(str, obj);
02982                 break;
02983 
02984             case T_Path:
02985                 _outPath(str, obj);
02986                 break;
02987             case T_IndexPath:
02988                 _outIndexPath(str, obj);
02989                 break;
02990             case T_BitmapHeapPath:
02991                 _outBitmapHeapPath(str, obj);
02992                 break;
02993             case T_BitmapAndPath:
02994                 _outBitmapAndPath(str, obj);
02995                 break;
02996             case T_BitmapOrPath:
02997                 _outBitmapOrPath(str, obj);
02998                 break;
02999             case T_TidPath:
03000                 _outTidPath(str, obj);
03001                 break;
03002             case T_ForeignPath:
03003                 _outForeignPath(str, obj);
03004                 break;
03005             case T_AppendPath:
03006                 _outAppendPath(str, obj);
03007                 break;
03008             case T_MergeAppendPath:
03009                 _outMergeAppendPath(str, obj);
03010                 break;
03011             case T_ResultPath:
03012                 _outResultPath(str, obj);
03013                 break;
03014             case T_MaterialPath:
03015                 _outMaterialPath(str, obj);
03016                 break;
03017             case T_UniquePath:
03018                 _outUniquePath(str, obj);
03019                 break;
03020             case T_NestPath:
03021                 _outNestPath(str, obj);
03022                 break;
03023             case T_MergePath:
03024                 _outMergePath(str, obj);
03025                 break;
03026             case T_HashPath:
03027                 _outHashPath(str, obj);
03028                 break;
03029             case T_PlannerGlobal:
03030                 _outPlannerGlobal(str, obj);
03031                 break;
03032             case T_PlannerInfo:
03033                 _outPlannerInfo(str, obj);
03034                 break;
03035             case T_RelOptInfo:
03036                 _outRelOptInfo(str, obj);
03037                 break;
03038             case T_IndexOptInfo:
03039                 _outIndexOptInfo(str, obj);
03040                 break;
03041             case T_EquivalenceClass:
03042                 _outEquivalenceClass(str, obj);
03043                 break;
03044             case T_EquivalenceMember:
03045                 _outEquivalenceMember(str, obj);
03046                 break;
03047             case T_PathKey:
03048                 _outPathKey(str, obj);
03049                 break;
03050             case T_ParamPathInfo:
03051                 _outParamPathInfo(str, obj);
03052                 break;
03053             case T_RestrictInfo:
03054                 _outRestrictInfo(str, obj);
03055                 break;
03056             case T_PlaceHolderVar:
03057                 _outPlaceHolderVar(str, obj);
03058                 break;
03059             case T_SpecialJoinInfo:
03060                 _outSpecialJoinInfo(str, obj);
03061                 break;
03062             case T_LateralJoinInfo:
03063                 _outLateralJoinInfo(str, obj);
03064                 break;
03065             case T_AppendRelInfo:
03066                 _outAppendRelInfo(str, obj);
03067                 break;
03068             case T_PlaceHolderInfo:
03069                 _outPlaceHolderInfo(str, obj);
03070                 break;
03071             case T_MinMaxAggInfo:
03072                 _outMinMaxAggInfo(str, obj);
03073                 break;
03074             case T_PlannerParamItem:
03075                 _outPlannerParamItem(str, obj);
03076                 break;
03077 
03078             case T_CreateStmt:
03079                 _outCreateStmt(str, obj);
03080                 break;
03081             case T_CreateForeignTableStmt:
03082                 _outCreateForeignTableStmt(str, obj);
03083                 break;
03084             case T_IndexStmt:
03085                 _outIndexStmt(str, obj);
03086                 break;
03087             case T_NotifyStmt:
03088                 _outNotifyStmt(str, obj);
03089                 break;
03090             case T_DeclareCursorStmt:
03091                 _outDeclareCursorStmt(str, obj);
03092                 break;
03093             case T_SelectStmt:
03094                 _outSelectStmt(str, obj);
03095                 break;
03096             case T_ColumnDef:
03097                 _outColumnDef(str, obj);
03098                 break;
03099             case T_TypeName:
03100                 _outTypeName(str, obj);
03101                 break;
03102             case T_TypeCast:
03103                 _outTypeCast(str, obj);
03104                 break;
03105             case T_CollateClause:
03106                 _outCollateClause(str, obj);
03107                 break;
03108             case T_IndexElem:
03109                 _outIndexElem(str, obj);
03110                 break;
03111             case T_Query:
03112                 _outQuery(str, obj);
03113                 break;
03114             case T_SortGroupClause:
03115                 _outSortGroupClause(str, obj);
03116                 break;
03117             case T_WindowClause:
03118                 _outWindowClause(str, obj);
03119                 break;
03120             case T_RowMarkClause:
03121                 _outRowMarkClause(str, obj);
03122                 break;
03123             case T_WithClause:
03124                 _outWithClause(str, obj);
03125                 break;
03126             case T_CommonTableExpr:
03127                 _outCommonTableExpr(str, obj);
03128                 break;
03129             case T_SetOperationStmt:
03130                 _outSetOperationStmt(str, obj);
03131                 break;
03132             case T_RangeTblEntry:
03133                 _outRangeTblEntry(str, obj);
03134                 break;
03135             case T_A_Expr:
03136                 _outAExpr(str, obj);
03137                 break;
03138             case T_ColumnRef:
03139                 _outColumnRef(str, obj);
03140                 break;
03141             case T_ParamRef:
03142                 _outParamRef(str, obj);
03143                 break;
03144             case T_A_Const:
03145                 _outAConst(str, obj);
03146                 break;
03147             case T_A_Star:
03148                 _outA_Star(str, obj);
03149                 break;
03150             case T_A_Indices:
03151                 _outA_Indices(str, obj);
03152                 break;
03153             case T_A_Indirection:
03154                 _outA_Indirection(str, obj);
03155                 break;
03156             case T_A_ArrayExpr:
03157                 _outA_ArrayExpr(str, obj);
03158                 break;
03159             case T_ResTarget:
03160                 _outResTarget(str, obj);
03161                 break;
03162             case T_SortBy:
03163                 _outSortBy(str, obj);
03164                 break;
03165             case T_WindowDef:
03166                 _outWindowDef(str, obj);
03167                 break;
03168             case T_RangeSubselect:
03169                 _outRangeSubselect(str, obj);
03170                 break;
03171             case T_RangeFunction:
03172                 _outRangeFunction(str, obj);
03173                 break;
03174             case T_Constraint:
03175                 _outConstraint(str, obj);
03176                 break;
03177             case T_FuncCall:
03178                 _outFuncCall(str, obj);
03179                 break;
03180             case T_DefElem:
03181                 _outDefElem(str, obj);
03182                 break;
03183             case T_TableLikeClause:
03184                 _outTableLikeClause(str, obj);
03185                 break;
03186             case T_LockingClause:
03187                 _outLockingClause(str, obj);
03188                 break;
03189             case T_XmlSerialize:
03190                 _outXmlSerialize(str, obj);
03191                 break;
03192 
03193             default:
03194 
03195                 /*
03196                  * This should be an ERROR, but it's too useful to be able to
03197                  * dump structures that _outNode only understands part of.
03198                  */
03199                 elog(WARNING, "could not dump unrecognized node type: %d",
03200                      (int) nodeTag(obj));
03201                 break;
03202         }
03203         appendStringInfoChar(str, '}');
03204     }
03205 }
03206 
03207 /*
03208  * nodeToString -
03209  *     returns the ascii representation of the Node as a palloc'd string
03210  */
03211 char *
03212 nodeToString(const void *obj)
03213 {
03214     StringInfoData str;
03215 
03216     /* see stringinfo.h for an explanation of this maneuver */
03217     initStringInfo(&str);
03218     _outNode(&str, obj);
03219     return str.data;
03220 }