]> granicus.if.org Git - postgresql/blob - src/backend/nodes/outfuncs.c
Update copyright for 2016
[postgresql] / src / backend / nodes / outfuncs.c
1 /*-------------------------------------------------------------------------
2  *
3  * outfuncs.c
4  *        Output functions for Postgres tree nodes.
5  *
6  * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        src/backend/nodes/outfuncs.c
12  *
13  * NOTES
14  *        Every node type that can appear in stored rules' parsetrees *must*
15  *        have an output function defined here (as well as an input function
16  *        in readfuncs.c).  In addition, plan nodes should have input and
17  *        output functions so that they can be sent to parallel workers.
18  *        For use in debugging, we also provide output functions for nodes
19  *        that appear in raw parsetrees and path.  These nodes however need
20  *        not have input functions.
21  *
22  *-------------------------------------------------------------------------
23  */
24 #include "postgres.h"
25
26 #include <ctype.h>
27
28 #include "lib/stringinfo.h"
29 #include "nodes/plannodes.h"
30 #include "nodes/relation.h"
31 #include "utils/datum.h"
32
33
34 /*
35  * Macros to simplify output of different kinds of fields.  Use these
36  * wherever possible to reduce the chance for silly typos.  Note that these
37  * hard-wire conventions about the names of the local variables in an Out
38  * routine.
39  */
40
41 /* Write the label for the node type */
42 #define WRITE_NODE_TYPE(nodelabel) \
43         appendStringInfoString(str, nodelabel)
44
45 /* Write an integer field (anything written as ":fldname %d") */
46 #define WRITE_INT_FIELD(fldname) \
47         appendStringInfo(str, " :" CppAsString(fldname) " %d", node->fldname)
48
49 /* Write an unsigned integer field (anything written as ":fldname %u") */
50 #define WRITE_UINT_FIELD(fldname) \
51         appendStringInfo(str, " :" CppAsString(fldname) " %u", node->fldname)
52
53 /* Write an OID field (don't hard-wire assumption that OID is same as uint) */
54 #define WRITE_OID_FIELD(fldname) \
55         appendStringInfo(str, " :" CppAsString(fldname) " %u", node->fldname)
56
57 /* Write a long-integer field */
58 #define WRITE_LONG_FIELD(fldname) \
59         appendStringInfo(str, " :" CppAsString(fldname) " %ld", node->fldname)
60
61 /* Write a char field (ie, one ascii character) */
62 #define WRITE_CHAR_FIELD(fldname) \
63         appendStringInfo(str, " :" CppAsString(fldname) " %c", node->fldname)
64
65 /* Write an enumerated-type field as an integer code */
66 #define WRITE_ENUM_FIELD(fldname, enumtype) \
67         appendStringInfo(str, " :" CppAsString(fldname) " %d", \
68                                          (int) node->fldname)
69
70 /* Write a float field --- caller must give format to define precision */
71 #define WRITE_FLOAT_FIELD(fldname,format) \
72         appendStringInfo(str, " :" CppAsString(fldname) " " format, node->fldname)
73
74 /* Write a boolean field */
75 #define WRITE_BOOL_FIELD(fldname) \
76         appendStringInfo(str, " :" CppAsString(fldname) " %s", \
77                                          booltostr(node->fldname))
78
79 /* Write a character-string (possibly NULL) field */
80 #define WRITE_STRING_FIELD(fldname) \
81         (appendStringInfo(str, " :" CppAsString(fldname) " "), \
82          _outToken(str, node->fldname))
83
84 /* Write a parse location field (actually same as INT case) */
85 #define WRITE_LOCATION_FIELD(fldname) \
86         appendStringInfo(str, " :" CppAsString(fldname) " %d", node->fldname)
87
88 /* Write a Node field */
89 #define WRITE_NODE_FIELD(fldname) \
90         (appendStringInfo(str, " :" CppAsString(fldname) " "), \
91          _outNode(str, node->fldname))
92
93 /* Write a bitmapset field */
94 #define WRITE_BITMAPSET_FIELD(fldname) \
95         (appendStringInfo(str, " :" CppAsString(fldname) " "), \
96          _outBitmapset(str, node->fldname))
97
98
99 #define booltostr(x)  ((x) ? "true" : "false")
100
101 static void _outNode(StringInfo str, const void *obj);
102
103
104 /*
105  * _outToken
106  *        Convert an ordinary string (eg, an identifier) into a form that
107  *        will be decoded back to a plain token by read.c's functions.
108  *
109  *        If a null or empty string is given, it is encoded as "<>".
110  */
111 static void
112 _outToken(StringInfo str, const char *s)
113 {
114         if (s == NULL || *s == '\0')
115         {
116                 appendStringInfoString(str, "<>");
117                 return;
118         }
119
120         /*
121          * Look for characters or patterns that are treated specially by read.c
122          * (either in pg_strtok() or in nodeRead()), and therefore need a
123          * protective backslash.
124          */
125         /* These characters only need to be quoted at the start of the string */
126         if (*s == '<' ||
127                 *s == '"' ||
128                 isdigit((unsigned char) *s) ||
129                 ((*s == '+' || *s == '-') &&
130                  (isdigit((unsigned char) s[1]) || s[1] == '.')))
131                 appendStringInfoChar(str, '\\');
132         while (*s)
133         {
134                 /* These chars must be backslashed anywhere in the string */
135                 if (*s == ' ' || *s == '\n' || *s == '\t' ||
136                         *s == '(' || *s == ')' || *s == '{' || *s == '}' ||
137                         *s == '\\')
138                         appendStringInfoChar(str, '\\');
139                 appendStringInfoChar(str, *s++);
140         }
141 }
142
143 static void
144 _outList(StringInfo str, const List *node)
145 {
146         const ListCell *lc;
147
148         appendStringInfoChar(str, '(');
149
150         if (IsA(node, IntList))
151                 appendStringInfoChar(str, 'i');
152         else if (IsA(node, OidList))
153                 appendStringInfoChar(str, 'o');
154
155         foreach(lc, node)
156         {
157                 /*
158                  * For the sake of backward compatibility, we emit a slightly
159                  * different whitespace format for lists of nodes vs. other types of
160                  * lists. XXX: is this necessary?
161                  */
162                 if (IsA(node, List))
163                 {
164                         _outNode(str, lfirst(lc));
165                         if (lnext(lc))
166                                 appendStringInfoChar(str, ' ');
167                 }
168                 else if (IsA(node, IntList))
169                         appendStringInfo(str, " %d", lfirst_int(lc));
170                 else if (IsA(node, OidList))
171                         appendStringInfo(str, " %u", lfirst_oid(lc));
172                 else
173                         elog(ERROR, "unrecognized list node type: %d",
174                                  (int) node->type);
175         }
176
177         appendStringInfoChar(str, ')');
178 }
179
180 /*
181  * _outBitmapset -
182  *         converts a bitmap set of integers
183  *
184  * Note: the output format is "(b int int ...)", similar to an integer List.
185  */
186 static void
187 _outBitmapset(StringInfo str, const Bitmapset *bms)
188 {
189         int                     x;
190
191         appendStringInfoChar(str, '(');
192         appendStringInfoChar(str, 'b');
193         x = -1;
194         while ((x = bms_next_member(bms, x)) >= 0)
195                 appendStringInfo(str, " %d", x);
196         appendStringInfoChar(str, ')');
197 }
198
199 /*
200  * Print the value of a Datum given its type.
201  */
202 static void
203 _outDatum(StringInfo str, Datum value, int typlen, bool typbyval)
204 {
205         Size            length,
206                                 i;
207         char       *s;
208
209         length = datumGetSize(value, typbyval, typlen);
210
211         if (typbyval)
212         {
213                 s = (char *) (&value);
214                 appendStringInfo(str, "%u [ ", (unsigned int) length);
215                 for (i = 0; i < (Size) sizeof(Datum); i++)
216                         appendStringInfo(str, "%d ", (int) (s[i]));
217                 appendStringInfoChar(str, ']');
218         }
219         else
220         {
221                 s = (char *) DatumGetPointer(value);
222                 if (!PointerIsValid(s))
223                         appendStringInfoString(str, "0 [ ]");
224                 else
225                 {
226                         appendStringInfo(str, "%u [ ", (unsigned int) length);
227                         for (i = 0; i < length; i++)
228                                 appendStringInfo(str, "%d ", (int) (s[i]));
229                         appendStringInfoChar(str, ']');
230                 }
231         }
232 }
233
234
235 /*
236  *      Stuff from plannodes.h
237  */
238
239 static void
240 _outPlannedStmt(StringInfo str, const PlannedStmt *node)
241 {
242         WRITE_NODE_TYPE("PLANNEDSTMT");
243
244         WRITE_ENUM_FIELD(commandType, CmdType);
245         WRITE_UINT_FIELD(queryId);
246         WRITE_BOOL_FIELD(hasReturning);
247         WRITE_BOOL_FIELD(hasModifyingCTE);
248         WRITE_BOOL_FIELD(canSetTag);
249         WRITE_BOOL_FIELD(transientPlan);
250         WRITE_NODE_FIELD(planTree);
251         WRITE_NODE_FIELD(rtable);
252         WRITE_NODE_FIELD(resultRelations);
253         WRITE_NODE_FIELD(utilityStmt);
254         WRITE_NODE_FIELD(subplans);
255         WRITE_BITMAPSET_FIELD(rewindPlanIDs);
256         WRITE_NODE_FIELD(rowMarks);
257         WRITE_NODE_FIELD(relationOids);
258         WRITE_NODE_FIELD(invalItems);
259         WRITE_INT_FIELD(nParamExec);
260         WRITE_BOOL_FIELD(hasRowSecurity);
261         WRITE_BOOL_FIELD(parallelModeNeeded);
262 }
263
264 /*
265  * print the basic stuff of all nodes that inherit from Plan
266  */
267 static void
268 _outPlanInfo(StringInfo str, const Plan *node)
269 {
270         WRITE_FLOAT_FIELD(startup_cost, "%.2f");
271         WRITE_FLOAT_FIELD(total_cost, "%.2f");
272         WRITE_FLOAT_FIELD(plan_rows, "%.0f");
273         WRITE_INT_FIELD(plan_width);
274         WRITE_BOOL_FIELD(parallel_aware);
275         WRITE_INT_FIELD(plan_node_id);
276         WRITE_NODE_FIELD(targetlist);
277         WRITE_NODE_FIELD(qual);
278         WRITE_NODE_FIELD(lefttree);
279         WRITE_NODE_FIELD(righttree);
280         WRITE_NODE_FIELD(initPlan);
281         WRITE_BITMAPSET_FIELD(extParam);
282         WRITE_BITMAPSET_FIELD(allParam);
283 }
284
285 /*
286  * print the basic stuff of all nodes that inherit from Scan
287  */
288 static void
289 _outScanInfo(StringInfo str, const Scan *node)
290 {
291         _outPlanInfo(str, (const Plan *) node);
292
293         WRITE_UINT_FIELD(scanrelid);
294 }
295
296 /*
297  * print the basic stuff of all nodes that inherit from Join
298  */
299 static void
300 _outJoinPlanInfo(StringInfo str, const Join *node)
301 {
302         _outPlanInfo(str, (const Plan *) node);
303
304         WRITE_ENUM_FIELD(jointype, JoinType);
305         WRITE_NODE_FIELD(joinqual);
306 }
307
308
309 static void
310 _outPlan(StringInfo str, const Plan *node)
311 {
312         WRITE_NODE_TYPE("PLAN");
313
314         _outPlanInfo(str, (const Plan *) node);
315 }
316
317 static void
318 _outResult(StringInfo str, const Result *node)
319 {
320         WRITE_NODE_TYPE("RESULT");
321
322         _outPlanInfo(str, (const Plan *) node);
323
324         WRITE_NODE_FIELD(resconstantqual);
325 }
326
327 static void
328 _outModifyTable(StringInfo str, const ModifyTable *node)
329 {
330         WRITE_NODE_TYPE("MODIFYTABLE");
331
332         _outPlanInfo(str, (const Plan *) node);
333
334         WRITE_ENUM_FIELD(operation, CmdType);
335         WRITE_BOOL_FIELD(canSetTag);
336         WRITE_UINT_FIELD(nominalRelation);
337         WRITE_NODE_FIELD(resultRelations);
338         WRITE_INT_FIELD(resultRelIndex);
339         WRITE_NODE_FIELD(plans);
340         WRITE_NODE_FIELD(withCheckOptionLists);
341         WRITE_NODE_FIELD(returningLists);
342         WRITE_NODE_FIELD(fdwPrivLists);
343         WRITE_NODE_FIELD(rowMarks);
344         WRITE_INT_FIELD(epqParam);
345         WRITE_ENUM_FIELD(onConflictAction, OnConflictAction);
346         WRITE_NODE_FIELD(arbiterIndexes);
347         WRITE_NODE_FIELD(onConflictSet);
348         WRITE_NODE_FIELD(onConflictWhere);
349         WRITE_UINT_FIELD(exclRelRTI);
350         WRITE_NODE_FIELD(exclRelTlist);
351 }
352
353 static void
354 _outAppend(StringInfo str, const Append *node)
355 {
356         WRITE_NODE_TYPE("APPEND");
357
358         _outPlanInfo(str, (const Plan *) node);
359
360         WRITE_NODE_FIELD(appendplans);
361 }
362
363 static void
364 _outMergeAppend(StringInfo str, const MergeAppend *node)
365 {
366         int                     i;
367
368         WRITE_NODE_TYPE("MERGEAPPEND");
369
370         _outPlanInfo(str, (const Plan *) node);
371
372         WRITE_NODE_FIELD(mergeplans);
373
374         WRITE_INT_FIELD(numCols);
375
376         appendStringInfoString(str, " :sortColIdx");
377         for (i = 0; i < node->numCols; i++)
378                 appendStringInfo(str, " %d", node->sortColIdx[i]);
379
380         appendStringInfoString(str, " :sortOperators");
381         for (i = 0; i < node->numCols; i++)
382                 appendStringInfo(str, " %u", node->sortOperators[i]);
383
384         appendStringInfoString(str, " :collations");
385         for (i = 0; i < node->numCols; i++)
386                 appendStringInfo(str, " %u", node->collations[i]);
387
388         appendStringInfoString(str, " :nullsFirst");
389         for (i = 0; i < node->numCols; i++)
390                 appendStringInfo(str, " %s", booltostr(node->nullsFirst[i]));
391 }
392
393 static void
394 _outRecursiveUnion(StringInfo str, const RecursiveUnion *node)
395 {
396         int                     i;
397
398         WRITE_NODE_TYPE("RECURSIVEUNION");
399
400         _outPlanInfo(str, (const Plan *) node);
401
402         WRITE_INT_FIELD(wtParam);
403         WRITE_INT_FIELD(numCols);
404
405         appendStringInfoString(str, " :dupColIdx");
406         for (i = 0; i < node->numCols; i++)
407                 appendStringInfo(str, " %d", node->dupColIdx[i]);
408
409         appendStringInfoString(str, " :dupOperators");
410         for (i = 0; i < node->numCols; i++)
411                 appendStringInfo(str, " %u", node->dupOperators[i]);
412
413         WRITE_LONG_FIELD(numGroups);
414 }
415
416 static void
417 _outBitmapAnd(StringInfo str, const BitmapAnd *node)
418 {
419         WRITE_NODE_TYPE("BITMAPAND");
420
421         _outPlanInfo(str, (const Plan *) node);
422
423         WRITE_NODE_FIELD(bitmapplans);
424 }
425
426 static void
427 _outBitmapOr(StringInfo str, const BitmapOr *node)
428 {
429         WRITE_NODE_TYPE("BITMAPOR");
430
431         _outPlanInfo(str, (const Plan *) node);
432
433         WRITE_NODE_FIELD(bitmapplans);
434 }
435
436 static void
437 _outGather(StringInfo str, const Gather *node)
438 {
439         WRITE_NODE_TYPE("GATHER");
440
441         _outPlanInfo(str, (const Plan *) node);
442
443         WRITE_INT_FIELD(num_workers);
444         WRITE_BOOL_FIELD(single_copy);
445 }
446
447 static void
448 _outScan(StringInfo str, const Scan *node)
449 {
450         WRITE_NODE_TYPE("SCAN");
451
452         _outScanInfo(str, node);
453 }
454
455 static void
456 _outSeqScan(StringInfo str, const SeqScan *node)
457 {
458         WRITE_NODE_TYPE("SEQSCAN");
459
460         _outScanInfo(str, (const Scan *) node);
461 }
462
463 static void
464 _outSampleScan(StringInfo str, const SampleScan *node)
465 {
466         WRITE_NODE_TYPE("SAMPLESCAN");
467
468         _outScanInfo(str, (const Scan *) node);
469
470         WRITE_NODE_FIELD(tablesample);
471 }
472
473 static void
474 _outIndexScan(StringInfo str, const IndexScan *node)
475 {
476         WRITE_NODE_TYPE("INDEXSCAN");
477
478         _outScanInfo(str, (const Scan *) node);
479
480         WRITE_OID_FIELD(indexid);
481         WRITE_NODE_FIELD(indexqual);
482         WRITE_NODE_FIELD(indexqualorig);
483         WRITE_NODE_FIELD(indexorderby);
484         WRITE_NODE_FIELD(indexorderbyorig);
485         WRITE_NODE_FIELD(indexorderbyops);
486         WRITE_ENUM_FIELD(indexorderdir, ScanDirection);
487 }
488
489 static void
490 _outIndexOnlyScan(StringInfo str, const IndexOnlyScan *node)
491 {
492         WRITE_NODE_TYPE("INDEXONLYSCAN");
493
494         _outScanInfo(str, (const Scan *) node);
495
496         WRITE_OID_FIELD(indexid);
497         WRITE_NODE_FIELD(indexqual);
498         WRITE_NODE_FIELD(indexorderby);
499         WRITE_NODE_FIELD(indextlist);
500         WRITE_ENUM_FIELD(indexorderdir, ScanDirection);
501 }
502
503 static void
504 _outBitmapIndexScan(StringInfo str, const BitmapIndexScan *node)
505 {
506         WRITE_NODE_TYPE("BITMAPINDEXSCAN");
507
508         _outScanInfo(str, (const Scan *) node);
509
510         WRITE_OID_FIELD(indexid);
511         WRITE_NODE_FIELD(indexqual);
512         WRITE_NODE_FIELD(indexqualorig);
513 }
514
515 static void
516 _outBitmapHeapScan(StringInfo str, const BitmapHeapScan *node)
517 {
518         WRITE_NODE_TYPE("BITMAPHEAPSCAN");
519
520         _outScanInfo(str, (const Scan *) node);
521
522         WRITE_NODE_FIELD(bitmapqualorig);
523 }
524
525 static void
526 _outTidScan(StringInfo str, const TidScan *node)
527 {
528         WRITE_NODE_TYPE("TIDSCAN");
529
530         _outScanInfo(str, (const Scan *) node);
531
532         WRITE_NODE_FIELD(tidquals);
533 }
534
535 static void
536 _outSubqueryScan(StringInfo str, const SubqueryScan *node)
537 {
538         WRITE_NODE_TYPE("SUBQUERYSCAN");
539
540         _outScanInfo(str, (const Scan *) node);
541
542         WRITE_NODE_FIELD(subplan);
543 }
544
545 static void
546 _outFunctionScan(StringInfo str, const FunctionScan *node)
547 {
548         WRITE_NODE_TYPE("FUNCTIONSCAN");
549
550         _outScanInfo(str, (const Scan *) node);
551
552         WRITE_NODE_FIELD(functions);
553         WRITE_BOOL_FIELD(funcordinality);
554 }
555
556 static void
557 _outValuesScan(StringInfo str, const ValuesScan *node)
558 {
559         WRITE_NODE_TYPE("VALUESSCAN");
560
561         _outScanInfo(str, (const Scan *) node);
562
563         WRITE_NODE_FIELD(values_lists);
564 }
565
566 static void
567 _outCteScan(StringInfo str, const CteScan *node)
568 {
569         WRITE_NODE_TYPE("CTESCAN");
570
571         _outScanInfo(str, (const Scan *) node);
572
573         WRITE_INT_FIELD(ctePlanId);
574         WRITE_INT_FIELD(cteParam);
575 }
576
577 static void
578 _outWorkTableScan(StringInfo str, const WorkTableScan *node)
579 {
580         WRITE_NODE_TYPE("WORKTABLESCAN");
581
582         _outScanInfo(str, (const Scan *) node);
583
584         WRITE_INT_FIELD(wtParam);
585 }
586
587 static void
588 _outForeignScan(StringInfo str, const ForeignScan *node)
589 {
590         WRITE_NODE_TYPE("FOREIGNSCAN");
591
592         _outScanInfo(str, (const Scan *) node);
593
594         WRITE_OID_FIELD(fs_server);
595         WRITE_NODE_FIELD(fdw_exprs);
596         WRITE_NODE_FIELD(fdw_private);
597         WRITE_NODE_FIELD(fdw_scan_tlist);
598         WRITE_NODE_FIELD(fdw_recheck_quals);
599         WRITE_BITMAPSET_FIELD(fs_relids);
600         WRITE_BOOL_FIELD(fsSystemCol);
601 }
602
603 static void
604 _outCustomScan(StringInfo str, const CustomScan *node)
605 {
606         WRITE_NODE_TYPE("CUSTOMSCAN");
607
608         _outScanInfo(str, (const Scan *) node);
609
610         WRITE_UINT_FIELD(flags);
611         WRITE_NODE_FIELD(custom_plans);
612         WRITE_NODE_FIELD(custom_exprs);
613         WRITE_NODE_FIELD(custom_private);
614         WRITE_NODE_FIELD(custom_scan_tlist);
615         WRITE_BITMAPSET_FIELD(custom_relids);
616         /* Dump library and symbol name instead of raw pointer */
617         appendStringInfoString(str, " :methods ");
618         _outToken(str, node->methods->LibraryName);
619         appendStringInfoChar(str, ' ');
620         _outToken(str, node->methods->SymbolName);
621 }
622
623 static void
624 _outJoin(StringInfo str, const Join *node)
625 {
626         WRITE_NODE_TYPE("JOIN");
627
628         _outJoinPlanInfo(str, (const Join *) node);
629 }
630
631 static void
632 _outNestLoop(StringInfo str, const NestLoop *node)
633 {
634         WRITE_NODE_TYPE("NESTLOOP");
635
636         _outJoinPlanInfo(str, (const Join *) node);
637
638         WRITE_NODE_FIELD(nestParams);
639 }
640
641 static void
642 _outMergeJoin(StringInfo str, const MergeJoin *node)
643 {
644         int                     numCols;
645         int                     i;
646
647         WRITE_NODE_TYPE("MERGEJOIN");
648
649         _outJoinPlanInfo(str, (const Join *) node);
650
651         WRITE_NODE_FIELD(mergeclauses);
652
653         numCols = list_length(node->mergeclauses);
654
655         appendStringInfoString(str, " :mergeFamilies");
656         for (i = 0; i < numCols; i++)
657                 appendStringInfo(str, " %u", node->mergeFamilies[i]);
658
659         appendStringInfoString(str, " :mergeCollations");
660         for (i = 0; i < numCols; i++)
661                 appendStringInfo(str, " %u", node->mergeCollations[i]);
662
663         appendStringInfoString(str, " :mergeStrategies");
664         for (i = 0; i < numCols; i++)
665                 appendStringInfo(str, " %d", node->mergeStrategies[i]);
666
667         appendStringInfoString(str, " :mergeNullsFirst");
668         for (i = 0; i < numCols; i++)
669                 appendStringInfo(str, " %s", booltostr(node->mergeNullsFirst[i]));
670 }
671
672 static void
673 _outHashJoin(StringInfo str, const HashJoin *node)
674 {
675         WRITE_NODE_TYPE("HASHJOIN");
676
677         _outJoinPlanInfo(str, (const Join *) node);
678
679         WRITE_NODE_FIELD(hashclauses);
680 }
681
682 static void
683 _outAgg(StringInfo str, const Agg *node)
684 {
685         int                     i;
686
687         WRITE_NODE_TYPE("AGG");
688
689         _outPlanInfo(str, (const Plan *) node);
690
691         WRITE_ENUM_FIELD(aggstrategy, AggStrategy);
692         WRITE_INT_FIELD(numCols);
693
694         appendStringInfoString(str, " :grpColIdx");
695         for (i = 0; i < node->numCols; i++)
696                 appendStringInfo(str, " %d", node->grpColIdx[i]);
697
698         appendStringInfoString(str, " :grpOperators");
699         for (i = 0; i < node->numCols; i++)
700                 appendStringInfo(str, " %u", node->grpOperators[i]);
701
702         WRITE_LONG_FIELD(numGroups);
703
704         WRITE_NODE_FIELD(groupingSets);
705         WRITE_NODE_FIELD(chain);
706 }
707
708 static void
709 _outWindowAgg(StringInfo str, const WindowAgg *node)
710 {
711         int                     i;
712
713         WRITE_NODE_TYPE("WINDOWAGG");
714
715         _outPlanInfo(str, (const Plan *) node);
716
717         WRITE_UINT_FIELD(winref);
718         WRITE_INT_FIELD(partNumCols);
719
720         appendStringInfoString(str, " :partColIdx");
721         for (i = 0; i < node->partNumCols; i++)
722                 appendStringInfo(str, " %d", node->partColIdx[i]);
723
724         appendStringInfoString(str, " :partOperations");
725         for (i = 0; i < node->partNumCols; i++)
726                 appendStringInfo(str, " %u", node->partOperators[i]);
727
728         WRITE_INT_FIELD(ordNumCols);
729
730         appendStringInfoString(str, " :ordColIdx");
731         for (i = 0; i < node->ordNumCols; i++)
732                 appendStringInfo(str, " %d", node->ordColIdx[i]);
733
734         appendStringInfoString(str, " :ordOperations");
735         for (i = 0; i < node->ordNumCols; i++)
736                 appendStringInfo(str, " %u", node->ordOperators[i]);
737
738         WRITE_INT_FIELD(frameOptions);
739         WRITE_NODE_FIELD(startOffset);
740         WRITE_NODE_FIELD(endOffset);
741 }
742
743 static void
744 _outGroup(StringInfo str, const Group *node)
745 {
746         int                     i;
747
748         WRITE_NODE_TYPE("GROUP");
749
750         _outPlanInfo(str, (const Plan *) node);
751
752         WRITE_INT_FIELD(numCols);
753
754         appendStringInfoString(str, " :grpColIdx");
755         for (i = 0; i < node->numCols; i++)
756                 appendStringInfo(str, " %d", node->grpColIdx[i]);
757
758         appendStringInfoString(str, " :grpOperators");
759         for (i = 0; i < node->numCols; i++)
760                 appendStringInfo(str, " %u", node->grpOperators[i]);
761 }
762
763 static void
764 _outMaterial(StringInfo str, const Material *node)
765 {
766         WRITE_NODE_TYPE("MATERIAL");
767
768         _outPlanInfo(str, (const Plan *) node);
769 }
770
771 static void
772 _outSort(StringInfo str, const Sort *node)
773 {
774         int                     i;
775
776         WRITE_NODE_TYPE("SORT");
777
778         _outPlanInfo(str, (const Plan *) node);
779
780         WRITE_INT_FIELD(numCols);
781
782         appendStringInfoString(str, " :sortColIdx");
783         for (i = 0; i < node->numCols; i++)
784                 appendStringInfo(str, " %d", node->sortColIdx[i]);
785
786         appendStringInfoString(str, " :sortOperators");
787         for (i = 0; i < node->numCols; i++)
788                 appendStringInfo(str, " %u", node->sortOperators[i]);
789
790         appendStringInfoString(str, " :collations");
791         for (i = 0; i < node->numCols; i++)
792                 appendStringInfo(str, " %u", node->collations[i]);
793
794         appendStringInfoString(str, " :nullsFirst");
795         for (i = 0; i < node->numCols; i++)
796                 appendStringInfo(str, " %s", booltostr(node->nullsFirst[i]));
797 }
798
799 static void
800 _outUnique(StringInfo str, const Unique *node)
801 {
802         int                     i;
803
804         WRITE_NODE_TYPE("UNIQUE");
805
806         _outPlanInfo(str, (const Plan *) node);
807
808         WRITE_INT_FIELD(numCols);
809
810         appendStringInfoString(str, " :uniqColIdx");
811         for (i = 0; i < node->numCols; i++)
812                 appendStringInfo(str, " %d", node->uniqColIdx[i]);
813
814         appendStringInfoString(str, " :uniqOperators");
815         for (i = 0; i < node->numCols; i++)
816                 appendStringInfo(str, " %u", node->uniqOperators[i]);
817 }
818
819 static void
820 _outHash(StringInfo str, const Hash *node)
821 {
822         WRITE_NODE_TYPE("HASH");
823
824         _outPlanInfo(str, (const Plan *) node);
825
826         WRITE_OID_FIELD(skewTable);
827         WRITE_INT_FIELD(skewColumn);
828         WRITE_BOOL_FIELD(skewInherit);
829         WRITE_OID_FIELD(skewColType);
830         WRITE_INT_FIELD(skewColTypmod);
831 }
832
833 static void
834 _outSetOp(StringInfo str, const SetOp *node)
835 {
836         int                     i;
837
838         WRITE_NODE_TYPE("SETOP");
839
840         _outPlanInfo(str, (const Plan *) node);
841
842         WRITE_ENUM_FIELD(cmd, SetOpCmd);
843         WRITE_ENUM_FIELD(strategy, SetOpStrategy);
844         WRITE_INT_FIELD(numCols);
845
846         appendStringInfoString(str, " :dupColIdx");
847         for (i = 0; i < node->numCols; i++)
848                 appendStringInfo(str, " %d", node->dupColIdx[i]);
849
850         appendStringInfoString(str, " :dupOperators");
851         for (i = 0; i < node->numCols; i++)
852                 appendStringInfo(str, " %u", node->dupOperators[i]);
853
854         WRITE_INT_FIELD(flagColIdx);
855         WRITE_INT_FIELD(firstFlag);
856         WRITE_LONG_FIELD(numGroups);
857 }
858
859 static void
860 _outLockRows(StringInfo str, const LockRows *node)
861 {
862         WRITE_NODE_TYPE("LOCKROWS");
863
864         _outPlanInfo(str, (const Plan *) node);
865
866         WRITE_NODE_FIELD(rowMarks);
867         WRITE_INT_FIELD(epqParam);
868 }
869
870 static void
871 _outLimit(StringInfo str, const Limit *node)
872 {
873         WRITE_NODE_TYPE("LIMIT");
874
875         _outPlanInfo(str, (const Plan *) node);
876
877         WRITE_NODE_FIELD(limitOffset);
878         WRITE_NODE_FIELD(limitCount);
879 }
880
881 static void
882 _outNestLoopParam(StringInfo str, const NestLoopParam *node)
883 {
884         WRITE_NODE_TYPE("NESTLOOPPARAM");
885
886         WRITE_INT_FIELD(paramno);
887         WRITE_NODE_FIELD(paramval);
888 }
889
890 static void
891 _outPlanRowMark(StringInfo str, const PlanRowMark *node)
892 {
893         WRITE_NODE_TYPE("PLANROWMARK");
894
895         WRITE_UINT_FIELD(rti);
896         WRITE_UINT_FIELD(prti);
897         WRITE_UINT_FIELD(rowmarkId);
898         WRITE_ENUM_FIELD(markType, RowMarkType);
899         WRITE_INT_FIELD(allMarkTypes);
900         WRITE_ENUM_FIELD(strength, LockClauseStrength);
901         WRITE_ENUM_FIELD(waitPolicy, LockWaitPolicy);
902         WRITE_BOOL_FIELD(isParent);
903 }
904
905 static void
906 _outPlanInvalItem(StringInfo str, const PlanInvalItem *node)
907 {
908         WRITE_NODE_TYPE("PLANINVALITEM");
909
910         WRITE_INT_FIELD(cacheId);
911         WRITE_UINT_FIELD(hashValue);
912 }
913
914 /*****************************************************************************
915  *
916  *      Stuff from primnodes.h.
917  *
918  *****************************************************************************/
919
920 static void
921 _outAlias(StringInfo str, const Alias *node)
922 {
923         WRITE_NODE_TYPE("ALIAS");
924
925         WRITE_STRING_FIELD(aliasname);
926         WRITE_NODE_FIELD(colnames);
927 }
928
929 static void
930 _outRangeVar(StringInfo str, const RangeVar *node)
931 {
932         WRITE_NODE_TYPE("RANGEVAR");
933
934         /*
935          * we deliberately ignore catalogname here, since it is presently not
936          * semantically meaningful
937          */
938         WRITE_STRING_FIELD(schemaname);
939         WRITE_STRING_FIELD(relname);
940         WRITE_ENUM_FIELD(inhOpt, InhOption);
941         WRITE_CHAR_FIELD(relpersistence);
942         WRITE_NODE_FIELD(alias);
943         WRITE_LOCATION_FIELD(location);
944 }
945
946 static void
947 _outIntoClause(StringInfo str, const IntoClause *node)
948 {
949         WRITE_NODE_TYPE("INTOCLAUSE");
950
951         WRITE_NODE_FIELD(rel);
952         WRITE_NODE_FIELD(colNames);
953         WRITE_NODE_FIELD(options);
954         WRITE_ENUM_FIELD(onCommit, OnCommitAction);
955         WRITE_STRING_FIELD(tableSpaceName);
956         WRITE_NODE_FIELD(viewQuery);
957         WRITE_BOOL_FIELD(skipData);
958 }
959
960 static void
961 _outVar(StringInfo str, const Var *node)
962 {
963         WRITE_NODE_TYPE("VAR");
964
965         WRITE_UINT_FIELD(varno);
966         WRITE_INT_FIELD(varattno);
967         WRITE_OID_FIELD(vartype);
968         WRITE_INT_FIELD(vartypmod);
969         WRITE_OID_FIELD(varcollid);
970         WRITE_UINT_FIELD(varlevelsup);
971         WRITE_UINT_FIELD(varnoold);
972         WRITE_INT_FIELD(varoattno);
973         WRITE_LOCATION_FIELD(location);
974 }
975
976 static void
977 _outConst(StringInfo str, const Const *node)
978 {
979         WRITE_NODE_TYPE("CONST");
980
981         WRITE_OID_FIELD(consttype);
982         WRITE_INT_FIELD(consttypmod);
983         WRITE_OID_FIELD(constcollid);
984         WRITE_INT_FIELD(constlen);
985         WRITE_BOOL_FIELD(constbyval);
986         WRITE_BOOL_FIELD(constisnull);
987         WRITE_LOCATION_FIELD(location);
988
989         appendStringInfoString(str, " :constvalue ");
990         if (node->constisnull)
991                 appendStringInfoString(str, "<>");
992         else
993                 _outDatum(str, node->constvalue, node->constlen, node->constbyval);
994 }
995
996 static void
997 _outParam(StringInfo str, const Param *node)
998 {
999         WRITE_NODE_TYPE("PARAM");
1000
1001         WRITE_ENUM_FIELD(paramkind, ParamKind);
1002         WRITE_INT_FIELD(paramid);
1003         WRITE_OID_FIELD(paramtype);
1004         WRITE_INT_FIELD(paramtypmod);
1005         WRITE_OID_FIELD(paramcollid);
1006         WRITE_LOCATION_FIELD(location);
1007 }
1008
1009 static void
1010 _outAggref(StringInfo str, const Aggref *node)
1011 {
1012         WRITE_NODE_TYPE("AGGREF");
1013
1014         WRITE_OID_FIELD(aggfnoid);
1015         WRITE_OID_FIELD(aggtype);
1016         WRITE_OID_FIELD(aggcollid);
1017         WRITE_OID_FIELD(inputcollid);
1018         WRITE_NODE_FIELD(aggdirectargs);
1019         WRITE_NODE_FIELD(args);
1020         WRITE_NODE_FIELD(aggorder);
1021         WRITE_NODE_FIELD(aggdistinct);
1022         WRITE_NODE_FIELD(aggfilter);
1023         WRITE_BOOL_FIELD(aggstar);
1024         WRITE_BOOL_FIELD(aggvariadic);
1025         WRITE_CHAR_FIELD(aggkind);
1026         WRITE_UINT_FIELD(agglevelsup);
1027         WRITE_LOCATION_FIELD(location);
1028 }
1029
1030 static void
1031 _outGroupingFunc(StringInfo str, const GroupingFunc *node)
1032 {
1033         WRITE_NODE_TYPE("GROUPINGFUNC");
1034
1035         WRITE_NODE_FIELD(args);
1036         WRITE_NODE_FIELD(refs);
1037         WRITE_NODE_FIELD(cols);
1038         WRITE_UINT_FIELD(agglevelsup);
1039         WRITE_LOCATION_FIELD(location);
1040 }
1041
1042 static void
1043 _outWindowFunc(StringInfo str, const WindowFunc *node)
1044 {
1045         WRITE_NODE_TYPE("WINDOWFUNC");
1046
1047         WRITE_OID_FIELD(winfnoid);
1048         WRITE_OID_FIELD(wintype);
1049         WRITE_OID_FIELD(wincollid);
1050         WRITE_OID_FIELD(inputcollid);
1051         WRITE_NODE_FIELD(args);
1052         WRITE_NODE_FIELD(aggfilter);
1053         WRITE_UINT_FIELD(winref);
1054         WRITE_BOOL_FIELD(winstar);
1055         WRITE_BOOL_FIELD(winagg);
1056         WRITE_LOCATION_FIELD(location);
1057 }
1058
1059 static void
1060 _outArrayRef(StringInfo str, const ArrayRef *node)
1061 {
1062         WRITE_NODE_TYPE("ARRAYREF");
1063
1064         WRITE_OID_FIELD(refarraytype);
1065         WRITE_OID_FIELD(refelemtype);
1066         WRITE_INT_FIELD(reftypmod);
1067         WRITE_OID_FIELD(refcollid);
1068         WRITE_NODE_FIELD(refupperindexpr);
1069         WRITE_NODE_FIELD(reflowerindexpr);
1070         WRITE_NODE_FIELD(refexpr);
1071         WRITE_NODE_FIELD(refassgnexpr);
1072 }
1073
1074 static void
1075 _outFuncExpr(StringInfo str, const FuncExpr *node)
1076 {
1077         WRITE_NODE_TYPE("FUNCEXPR");
1078
1079         WRITE_OID_FIELD(funcid);
1080         WRITE_OID_FIELD(funcresulttype);
1081         WRITE_BOOL_FIELD(funcretset);
1082         WRITE_BOOL_FIELD(funcvariadic);
1083         WRITE_ENUM_FIELD(funcformat, CoercionForm);
1084         WRITE_OID_FIELD(funccollid);
1085         WRITE_OID_FIELD(inputcollid);
1086         WRITE_NODE_FIELD(args);
1087         WRITE_LOCATION_FIELD(location);
1088 }
1089
1090 static void
1091 _outNamedArgExpr(StringInfo str, const NamedArgExpr *node)
1092 {
1093         WRITE_NODE_TYPE("NAMEDARGEXPR");
1094
1095         WRITE_NODE_FIELD(arg);
1096         WRITE_STRING_FIELD(name);
1097         WRITE_INT_FIELD(argnumber);
1098         WRITE_LOCATION_FIELD(location);
1099 }
1100
1101 static void
1102 _outOpExpr(StringInfo str, const OpExpr *node)
1103 {
1104         WRITE_NODE_TYPE("OPEXPR");
1105
1106         WRITE_OID_FIELD(opno);
1107         WRITE_OID_FIELD(opfuncid);
1108         WRITE_OID_FIELD(opresulttype);
1109         WRITE_BOOL_FIELD(opretset);
1110         WRITE_OID_FIELD(opcollid);
1111         WRITE_OID_FIELD(inputcollid);
1112         WRITE_NODE_FIELD(args);
1113         WRITE_LOCATION_FIELD(location);
1114 }
1115
1116 static void
1117 _outDistinctExpr(StringInfo str, const DistinctExpr *node)
1118 {
1119         WRITE_NODE_TYPE("DISTINCTEXPR");
1120
1121         WRITE_OID_FIELD(opno);
1122         WRITE_OID_FIELD(opfuncid);
1123         WRITE_OID_FIELD(opresulttype);
1124         WRITE_BOOL_FIELD(opretset);
1125         WRITE_OID_FIELD(opcollid);
1126         WRITE_OID_FIELD(inputcollid);
1127         WRITE_NODE_FIELD(args);
1128         WRITE_LOCATION_FIELD(location);
1129 }
1130
1131 static void
1132 _outNullIfExpr(StringInfo str, const NullIfExpr *node)
1133 {
1134         WRITE_NODE_TYPE("NULLIFEXPR");
1135
1136         WRITE_OID_FIELD(opno);
1137         WRITE_OID_FIELD(opfuncid);
1138         WRITE_OID_FIELD(opresulttype);
1139         WRITE_BOOL_FIELD(opretset);
1140         WRITE_OID_FIELD(opcollid);
1141         WRITE_OID_FIELD(inputcollid);
1142         WRITE_NODE_FIELD(args);
1143         WRITE_LOCATION_FIELD(location);
1144 }
1145
1146 static void
1147 _outScalarArrayOpExpr(StringInfo str, const ScalarArrayOpExpr *node)
1148 {
1149         WRITE_NODE_TYPE("SCALARARRAYOPEXPR");
1150
1151         WRITE_OID_FIELD(opno);
1152         WRITE_OID_FIELD(opfuncid);
1153         WRITE_BOOL_FIELD(useOr);
1154         WRITE_OID_FIELD(inputcollid);
1155         WRITE_NODE_FIELD(args);
1156         WRITE_LOCATION_FIELD(location);
1157 }
1158
1159 static void
1160 _outBoolExpr(StringInfo str, const BoolExpr *node)
1161 {
1162         char       *opstr = NULL;
1163
1164         WRITE_NODE_TYPE("BOOLEXPR");
1165
1166         /* do-it-yourself enum representation */
1167         switch (node->boolop)
1168         {
1169                 case AND_EXPR:
1170                         opstr = "and";
1171                         break;
1172                 case OR_EXPR:
1173                         opstr = "or";
1174                         break;
1175                 case NOT_EXPR:
1176                         opstr = "not";
1177                         break;
1178         }
1179         appendStringInfoString(str, " :boolop ");
1180         _outToken(str, opstr);
1181
1182         WRITE_NODE_FIELD(args);
1183         WRITE_LOCATION_FIELD(location);
1184 }
1185
1186 static void
1187 _outSubLink(StringInfo str, const SubLink *node)
1188 {
1189         WRITE_NODE_TYPE("SUBLINK");
1190
1191         WRITE_ENUM_FIELD(subLinkType, SubLinkType);
1192         WRITE_INT_FIELD(subLinkId);
1193         WRITE_NODE_FIELD(testexpr);
1194         WRITE_NODE_FIELD(operName);
1195         WRITE_NODE_FIELD(subselect);
1196         WRITE_LOCATION_FIELD(location);
1197 }
1198
1199 static void
1200 _outSubPlan(StringInfo str, const SubPlan *node)
1201 {
1202         WRITE_NODE_TYPE("SUBPLAN");
1203
1204         WRITE_ENUM_FIELD(subLinkType, SubLinkType);
1205         WRITE_NODE_FIELD(testexpr);
1206         WRITE_NODE_FIELD(paramIds);
1207         WRITE_INT_FIELD(plan_id);
1208         WRITE_STRING_FIELD(plan_name);
1209         WRITE_OID_FIELD(firstColType);
1210         WRITE_INT_FIELD(firstColTypmod);
1211         WRITE_OID_FIELD(firstColCollation);
1212         WRITE_BOOL_FIELD(useHashTable);
1213         WRITE_BOOL_FIELD(unknownEqFalse);
1214         WRITE_NODE_FIELD(setParam);
1215         WRITE_NODE_FIELD(parParam);
1216         WRITE_NODE_FIELD(args);
1217         WRITE_FLOAT_FIELD(startup_cost, "%.2f");
1218         WRITE_FLOAT_FIELD(per_call_cost, "%.2f");
1219 }
1220
1221 static void
1222 _outAlternativeSubPlan(StringInfo str, const AlternativeSubPlan *node)
1223 {
1224         WRITE_NODE_TYPE("ALTERNATIVESUBPLAN");
1225
1226         WRITE_NODE_FIELD(subplans);
1227 }
1228
1229 static void
1230 _outFieldSelect(StringInfo str, const FieldSelect *node)
1231 {
1232         WRITE_NODE_TYPE("FIELDSELECT");
1233
1234         WRITE_NODE_FIELD(arg);
1235         WRITE_INT_FIELD(fieldnum);
1236         WRITE_OID_FIELD(resulttype);
1237         WRITE_INT_FIELD(resulttypmod);
1238         WRITE_OID_FIELD(resultcollid);
1239 }
1240
1241 static void
1242 _outFieldStore(StringInfo str, const FieldStore *node)
1243 {
1244         WRITE_NODE_TYPE("FIELDSTORE");
1245
1246         WRITE_NODE_FIELD(arg);
1247         WRITE_NODE_FIELD(newvals);
1248         WRITE_NODE_FIELD(fieldnums);
1249         WRITE_OID_FIELD(resulttype);
1250 }
1251
1252 static void
1253 _outRelabelType(StringInfo str, const RelabelType *node)
1254 {
1255         WRITE_NODE_TYPE("RELABELTYPE");
1256
1257         WRITE_NODE_FIELD(arg);
1258         WRITE_OID_FIELD(resulttype);
1259         WRITE_INT_FIELD(resulttypmod);
1260         WRITE_OID_FIELD(resultcollid);
1261         WRITE_ENUM_FIELD(relabelformat, CoercionForm);
1262         WRITE_LOCATION_FIELD(location);
1263 }
1264
1265 static void
1266 _outCoerceViaIO(StringInfo str, const CoerceViaIO *node)
1267 {
1268         WRITE_NODE_TYPE("COERCEVIAIO");
1269
1270         WRITE_NODE_FIELD(arg);
1271         WRITE_OID_FIELD(resulttype);
1272         WRITE_OID_FIELD(resultcollid);
1273         WRITE_ENUM_FIELD(coerceformat, CoercionForm);
1274         WRITE_LOCATION_FIELD(location);
1275 }
1276
1277 static void
1278 _outArrayCoerceExpr(StringInfo str, const ArrayCoerceExpr *node)
1279 {
1280         WRITE_NODE_TYPE("ARRAYCOERCEEXPR");
1281
1282         WRITE_NODE_FIELD(arg);
1283         WRITE_OID_FIELD(elemfuncid);
1284         WRITE_OID_FIELD(resulttype);
1285         WRITE_INT_FIELD(resulttypmod);
1286         WRITE_OID_FIELD(resultcollid);
1287         WRITE_BOOL_FIELD(isExplicit);
1288         WRITE_ENUM_FIELD(coerceformat, CoercionForm);
1289         WRITE_LOCATION_FIELD(location);
1290 }
1291
1292 static void
1293 _outConvertRowtypeExpr(StringInfo str, const ConvertRowtypeExpr *node)
1294 {
1295         WRITE_NODE_TYPE("CONVERTROWTYPEEXPR");
1296
1297         WRITE_NODE_FIELD(arg);
1298         WRITE_OID_FIELD(resulttype);
1299         WRITE_ENUM_FIELD(convertformat, CoercionForm);
1300         WRITE_LOCATION_FIELD(location);
1301 }
1302
1303 static void
1304 _outCollateExpr(StringInfo str, const CollateExpr *node)
1305 {
1306         WRITE_NODE_TYPE("COLLATE");
1307
1308         WRITE_NODE_FIELD(arg);
1309         WRITE_OID_FIELD(collOid);
1310         WRITE_LOCATION_FIELD(location);
1311 }
1312
1313 static void
1314 _outCaseExpr(StringInfo str, const CaseExpr *node)
1315 {
1316         WRITE_NODE_TYPE("CASE");
1317
1318         WRITE_OID_FIELD(casetype);
1319         WRITE_OID_FIELD(casecollid);
1320         WRITE_NODE_FIELD(arg);
1321         WRITE_NODE_FIELD(args);
1322         WRITE_NODE_FIELD(defresult);
1323         WRITE_LOCATION_FIELD(location);
1324 }
1325
1326 static void
1327 _outCaseWhen(StringInfo str, const CaseWhen *node)
1328 {
1329         WRITE_NODE_TYPE("WHEN");
1330
1331         WRITE_NODE_FIELD(expr);
1332         WRITE_NODE_FIELD(result);
1333         WRITE_LOCATION_FIELD(location);
1334 }
1335
1336 static void
1337 _outCaseTestExpr(StringInfo str, const CaseTestExpr *node)
1338 {
1339         WRITE_NODE_TYPE("CASETESTEXPR");
1340
1341         WRITE_OID_FIELD(typeId);
1342         WRITE_INT_FIELD(typeMod);
1343         WRITE_OID_FIELD(collation);
1344 }
1345
1346 static void
1347 _outArrayExpr(StringInfo str, const ArrayExpr *node)
1348 {
1349         WRITE_NODE_TYPE("ARRAY");
1350
1351         WRITE_OID_FIELD(array_typeid);
1352         WRITE_OID_FIELD(array_collid);
1353         WRITE_OID_FIELD(element_typeid);
1354         WRITE_NODE_FIELD(elements);
1355         WRITE_BOOL_FIELD(multidims);
1356         WRITE_LOCATION_FIELD(location);
1357 }
1358
1359 static void
1360 _outRowExpr(StringInfo str, const RowExpr *node)
1361 {
1362         WRITE_NODE_TYPE("ROW");
1363
1364         WRITE_NODE_FIELD(args);
1365         WRITE_OID_FIELD(row_typeid);
1366         WRITE_ENUM_FIELD(row_format, CoercionForm);
1367         WRITE_NODE_FIELD(colnames);
1368         WRITE_LOCATION_FIELD(location);
1369 }
1370
1371 static void
1372 _outRowCompareExpr(StringInfo str, const RowCompareExpr *node)
1373 {
1374         WRITE_NODE_TYPE("ROWCOMPARE");
1375
1376         WRITE_ENUM_FIELD(rctype, RowCompareType);
1377         WRITE_NODE_FIELD(opnos);
1378         WRITE_NODE_FIELD(opfamilies);
1379         WRITE_NODE_FIELD(inputcollids);
1380         WRITE_NODE_FIELD(largs);
1381         WRITE_NODE_FIELD(rargs);
1382 }
1383
1384 static void
1385 _outCoalesceExpr(StringInfo str, const CoalesceExpr *node)
1386 {
1387         WRITE_NODE_TYPE("COALESCE");
1388
1389         WRITE_OID_FIELD(coalescetype);
1390         WRITE_OID_FIELD(coalescecollid);
1391         WRITE_NODE_FIELD(args);
1392         WRITE_LOCATION_FIELD(location);
1393 }
1394
1395 static void
1396 _outMinMaxExpr(StringInfo str, const MinMaxExpr *node)
1397 {
1398         WRITE_NODE_TYPE("MINMAX");
1399
1400         WRITE_OID_FIELD(minmaxtype);
1401         WRITE_OID_FIELD(minmaxcollid);
1402         WRITE_OID_FIELD(inputcollid);
1403         WRITE_ENUM_FIELD(op, MinMaxOp);
1404         WRITE_NODE_FIELD(args);
1405         WRITE_LOCATION_FIELD(location);
1406 }
1407
1408 static void
1409 _outXmlExpr(StringInfo str, const XmlExpr *node)
1410 {
1411         WRITE_NODE_TYPE("XMLEXPR");
1412
1413         WRITE_ENUM_FIELD(op, XmlExprOp);
1414         WRITE_STRING_FIELD(name);
1415         WRITE_NODE_FIELD(named_args);
1416         WRITE_NODE_FIELD(arg_names);
1417         WRITE_NODE_FIELD(args);
1418         WRITE_ENUM_FIELD(xmloption, XmlOptionType);
1419         WRITE_OID_FIELD(type);
1420         WRITE_INT_FIELD(typmod);
1421         WRITE_LOCATION_FIELD(location);
1422 }
1423
1424 static void
1425 _outNullTest(StringInfo str, const NullTest *node)
1426 {
1427         WRITE_NODE_TYPE("NULLTEST");
1428
1429         WRITE_NODE_FIELD(arg);
1430         WRITE_ENUM_FIELD(nulltesttype, NullTestType);
1431         WRITE_BOOL_FIELD(argisrow);
1432         WRITE_LOCATION_FIELD(location);
1433 }
1434
1435 static void
1436 _outBooleanTest(StringInfo str, const BooleanTest *node)
1437 {
1438         WRITE_NODE_TYPE("BOOLEANTEST");
1439
1440         WRITE_NODE_FIELD(arg);
1441         WRITE_ENUM_FIELD(booltesttype, BoolTestType);
1442         WRITE_LOCATION_FIELD(location);
1443 }
1444
1445 static void
1446 _outCoerceToDomain(StringInfo str, const CoerceToDomain *node)
1447 {
1448         WRITE_NODE_TYPE("COERCETODOMAIN");
1449
1450         WRITE_NODE_FIELD(arg);
1451         WRITE_OID_FIELD(resulttype);
1452         WRITE_INT_FIELD(resulttypmod);
1453         WRITE_OID_FIELD(resultcollid);
1454         WRITE_ENUM_FIELD(coercionformat, CoercionForm);
1455         WRITE_LOCATION_FIELD(location);
1456 }
1457
1458 static void
1459 _outCoerceToDomainValue(StringInfo str, const CoerceToDomainValue *node)
1460 {
1461         WRITE_NODE_TYPE("COERCETODOMAINVALUE");
1462
1463         WRITE_OID_FIELD(typeId);
1464         WRITE_INT_FIELD(typeMod);
1465         WRITE_OID_FIELD(collation);
1466         WRITE_LOCATION_FIELD(location);
1467 }
1468
1469 static void
1470 _outSetToDefault(StringInfo str, const SetToDefault *node)
1471 {
1472         WRITE_NODE_TYPE("SETTODEFAULT");
1473
1474         WRITE_OID_FIELD(typeId);
1475         WRITE_INT_FIELD(typeMod);
1476         WRITE_OID_FIELD(collation);
1477         WRITE_LOCATION_FIELD(location);
1478 }
1479
1480 static void
1481 _outCurrentOfExpr(StringInfo str, const CurrentOfExpr *node)
1482 {
1483         WRITE_NODE_TYPE("CURRENTOFEXPR");
1484
1485         WRITE_UINT_FIELD(cvarno);
1486         WRITE_STRING_FIELD(cursor_name);
1487         WRITE_INT_FIELD(cursor_param);
1488 }
1489
1490 static void
1491 _outInferenceElem(StringInfo str, const InferenceElem *node)
1492 {
1493         WRITE_NODE_TYPE("INFERENCEELEM");
1494
1495         WRITE_NODE_FIELD(expr);
1496         WRITE_OID_FIELD(infercollid);
1497         WRITE_OID_FIELD(inferopclass);
1498 }
1499
1500 static void
1501 _outTargetEntry(StringInfo str, const TargetEntry *node)
1502 {
1503         WRITE_NODE_TYPE("TARGETENTRY");
1504
1505         WRITE_NODE_FIELD(expr);
1506         WRITE_INT_FIELD(resno);
1507         WRITE_STRING_FIELD(resname);
1508         WRITE_UINT_FIELD(ressortgroupref);
1509         WRITE_OID_FIELD(resorigtbl);
1510         WRITE_INT_FIELD(resorigcol);
1511         WRITE_BOOL_FIELD(resjunk);
1512 }
1513
1514 static void
1515 _outRangeTblRef(StringInfo str, const RangeTblRef *node)
1516 {
1517         WRITE_NODE_TYPE("RANGETBLREF");
1518
1519         WRITE_INT_FIELD(rtindex);
1520 }
1521
1522 static void
1523 _outJoinExpr(StringInfo str, const JoinExpr *node)
1524 {
1525         WRITE_NODE_TYPE("JOINEXPR");
1526
1527         WRITE_ENUM_FIELD(jointype, JoinType);
1528         WRITE_BOOL_FIELD(isNatural);
1529         WRITE_NODE_FIELD(larg);
1530         WRITE_NODE_FIELD(rarg);
1531         WRITE_NODE_FIELD(usingClause);
1532         WRITE_NODE_FIELD(quals);
1533         WRITE_NODE_FIELD(alias);
1534         WRITE_INT_FIELD(rtindex);
1535 }
1536
1537 static void
1538 _outFromExpr(StringInfo str, const FromExpr *node)
1539 {
1540         WRITE_NODE_TYPE("FROMEXPR");
1541
1542         WRITE_NODE_FIELD(fromlist);
1543         WRITE_NODE_FIELD(quals);
1544 }
1545
1546 static void
1547 _outOnConflictExpr(StringInfo str, const OnConflictExpr *node)
1548 {
1549         WRITE_NODE_TYPE("ONCONFLICTEXPR");
1550
1551         WRITE_ENUM_FIELD(action, OnConflictAction);
1552         WRITE_NODE_FIELD(arbiterElems);
1553         WRITE_NODE_FIELD(arbiterWhere);
1554         WRITE_OID_FIELD(constraint);
1555         WRITE_NODE_FIELD(onConflictSet);
1556         WRITE_NODE_FIELD(onConflictWhere);
1557         WRITE_INT_FIELD(exclRelIndex);
1558         WRITE_NODE_FIELD(exclRelTlist);
1559 }
1560
1561 /*****************************************************************************
1562  *
1563  *      Stuff from relation.h.
1564  *
1565  *****************************************************************************/
1566
1567 /*
1568  * print the basic stuff of all nodes that inherit from Path
1569  *
1570  * Note we do NOT print the parent, else we'd be in infinite recursion.
1571  * We can print the parent's relids for identification purposes, though.
1572  * We also do not print the whole of param_info, since it's printed by
1573  * _outRelOptInfo; it's sufficient and less cluttering to print just the
1574  * required outer relids.
1575  */
1576 static void
1577 _outPathInfo(StringInfo str, const Path *node)
1578 {
1579         WRITE_ENUM_FIELD(pathtype, NodeTag);
1580         appendStringInfoString(str, " :parent_relids ");
1581         if (node->parent)
1582                 _outBitmapset(str, node->parent->relids);
1583         else
1584                 _outBitmapset(str, NULL);
1585         appendStringInfoString(str, " :required_outer ");
1586         if (node->param_info)
1587                 _outBitmapset(str, node->param_info->ppi_req_outer);
1588         else
1589                 _outBitmapset(str, NULL);
1590         WRITE_BOOL_FIELD(parallel_aware);
1591         WRITE_FLOAT_FIELD(rows, "%.0f");
1592         WRITE_FLOAT_FIELD(startup_cost, "%.2f");
1593         WRITE_FLOAT_FIELD(total_cost, "%.2f");
1594         WRITE_NODE_FIELD(pathkeys);
1595 }
1596
1597 /*
1598  * print the basic stuff of all nodes that inherit from JoinPath
1599  */
1600 static void
1601 _outJoinPathInfo(StringInfo str, const JoinPath *node)
1602 {
1603         _outPathInfo(str, (const Path *) node);
1604
1605         WRITE_ENUM_FIELD(jointype, JoinType);
1606         WRITE_NODE_FIELD(outerjoinpath);
1607         WRITE_NODE_FIELD(innerjoinpath);
1608         WRITE_NODE_FIELD(joinrestrictinfo);
1609 }
1610
1611 static void
1612 _outPath(StringInfo str, const Path *node)
1613 {
1614         WRITE_NODE_TYPE("PATH");
1615
1616         _outPathInfo(str, (const Path *) node);
1617 }
1618
1619 static void
1620 _outIndexPath(StringInfo str, const IndexPath *node)
1621 {
1622         WRITE_NODE_TYPE("INDEXPATH");
1623
1624         _outPathInfo(str, (const Path *) node);
1625
1626         WRITE_NODE_FIELD(indexinfo);
1627         WRITE_NODE_FIELD(indexclauses);
1628         WRITE_NODE_FIELD(indexquals);
1629         WRITE_NODE_FIELD(indexqualcols);
1630         WRITE_NODE_FIELD(indexorderbys);
1631         WRITE_NODE_FIELD(indexorderbycols);
1632         WRITE_ENUM_FIELD(indexscandir, ScanDirection);
1633         WRITE_FLOAT_FIELD(indextotalcost, "%.2f");
1634         WRITE_FLOAT_FIELD(indexselectivity, "%.4f");
1635 }
1636
1637 static void
1638 _outBitmapHeapPath(StringInfo str, const BitmapHeapPath *node)
1639 {
1640         WRITE_NODE_TYPE("BITMAPHEAPPATH");
1641
1642         _outPathInfo(str, (const Path *) node);
1643
1644         WRITE_NODE_FIELD(bitmapqual);
1645 }
1646
1647 static void
1648 _outBitmapAndPath(StringInfo str, const BitmapAndPath *node)
1649 {
1650         WRITE_NODE_TYPE("BITMAPANDPATH");
1651
1652         _outPathInfo(str, (const Path *) node);
1653
1654         WRITE_NODE_FIELD(bitmapquals);
1655         WRITE_FLOAT_FIELD(bitmapselectivity, "%.4f");
1656 }
1657
1658 static void
1659 _outBitmapOrPath(StringInfo str, const BitmapOrPath *node)
1660 {
1661         WRITE_NODE_TYPE("BITMAPORPATH");
1662
1663         _outPathInfo(str, (const Path *) node);
1664
1665         WRITE_NODE_FIELD(bitmapquals);
1666         WRITE_FLOAT_FIELD(bitmapselectivity, "%.4f");
1667 }
1668
1669 static void
1670 _outTidPath(StringInfo str, const TidPath *node)
1671 {
1672         WRITE_NODE_TYPE("TIDPATH");
1673
1674         _outPathInfo(str, (const Path *) node);
1675
1676         WRITE_NODE_FIELD(tidquals);
1677 }
1678
1679 static void
1680 _outForeignPath(StringInfo str, const ForeignPath *node)
1681 {
1682         WRITE_NODE_TYPE("FOREIGNPATH");
1683
1684         _outPathInfo(str, (const Path *) node);
1685
1686         WRITE_NODE_FIELD(fdw_outerpath);
1687         WRITE_NODE_FIELD(fdw_private);
1688 }
1689
1690 static void
1691 _outCustomPath(StringInfo str, const CustomPath *node)
1692 {
1693         WRITE_NODE_TYPE("CUSTOMPATH");
1694
1695         _outPathInfo(str, (const Path *) node);
1696
1697         WRITE_UINT_FIELD(flags);
1698         WRITE_NODE_FIELD(custom_paths);
1699         WRITE_NODE_FIELD(custom_private);
1700         appendStringInfoString(str, " :methods ");
1701         _outToken(str, node->methods->CustomName);
1702         if (node->methods->TextOutCustomPath)
1703                 node->methods->TextOutCustomPath(str, node);
1704 }
1705
1706 static void
1707 _outAppendPath(StringInfo str, const AppendPath *node)
1708 {
1709         WRITE_NODE_TYPE("APPENDPATH");
1710
1711         _outPathInfo(str, (const Path *) node);
1712
1713         WRITE_NODE_FIELD(subpaths);
1714 }
1715
1716 static void
1717 _outMergeAppendPath(StringInfo str, const MergeAppendPath *node)
1718 {
1719         WRITE_NODE_TYPE("MERGEAPPENDPATH");
1720
1721         _outPathInfo(str, (const Path *) node);
1722
1723         WRITE_NODE_FIELD(subpaths);
1724         WRITE_FLOAT_FIELD(limit_tuples, "%.0f");
1725 }
1726
1727 static void
1728 _outResultPath(StringInfo str, const ResultPath *node)
1729 {
1730         WRITE_NODE_TYPE("RESULTPATH");
1731
1732         _outPathInfo(str, (const Path *) node);
1733
1734         WRITE_NODE_FIELD(quals);
1735 }
1736
1737 static void
1738 _outMaterialPath(StringInfo str, const MaterialPath *node)
1739 {
1740         WRITE_NODE_TYPE("MATERIALPATH");
1741
1742         _outPathInfo(str, (const Path *) node);
1743
1744         WRITE_NODE_FIELD(subpath);
1745 }
1746
1747 static void
1748 _outUniquePath(StringInfo str, const UniquePath *node)
1749 {
1750         WRITE_NODE_TYPE("UNIQUEPATH");
1751
1752         _outPathInfo(str, (const Path *) node);
1753
1754         WRITE_NODE_FIELD(subpath);
1755         WRITE_ENUM_FIELD(umethod, UniquePathMethod);
1756         WRITE_NODE_FIELD(in_operators);
1757         WRITE_NODE_FIELD(uniq_exprs);
1758 }
1759
1760 static void
1761 _outGatherPath(StringInfo str, const GatherPath *node)
1762 {
1763         WRITE_NODE_TYPE("GATHERPATH");
1764
1765         _outPathInfo(str, (const Path *) node);
1766
1767         WRITE_NODE_FIELD(subpath);
1768         WRITE_INT_FIELD(num_workers);
1769         WRITE_BOOL_FIELD(single_copy);
1770 }
1771
1772 static void
1773 _outNestPath(StringInfo str, const NestPath *node)
1774 {
1775         WRITE_NODE_TYPE("NESTPATH");
1776
1777         _outJoinPathInfo(str, (const JoinPath *) node);
1778 }
1779
1780 static void
1781 _outMergePath(StringInfo str, const MergePath *node)
1782 {
1783         WRITE_NODE_TYPE("MERGEPATH");
1784
1785         _outJoinPathInfo(str, (const JoinPath *) node);
1786
1787         WRITE_NODE_FIELD(path_mergeclauses);
1788         WRITE_NODE_FIELD(outersortkeys);
1789         WRITE_NODE_FIELD(innersortkeys);
1790         WRITE_BOOL_FIELD(materialize_inner);
1791 }
1792
1793 static void
1794 _outHashPath(StringInfo str, const HashPath *node)
1795 {
1796         WRITE_NODE_TYPE("HASHPATH");
1797
1798         _outJoinPathInfo(str, (const JoinPath *) node);
1799
1800         WRITE_NODE_FIELD(path_hashclauses);
1801         WRITE_INT_FIELD(num_batches);
1802 }
1803
1804 static void
1805 _outPlannerGlobal(StringInfo str, const PlannerGlobal *node)
1806 {
1807         WRITE_NODE_TYPE("PLANNERGLOBAL");
1808
1809         /* NB: this isn't a complete set of fields */
1810         WRITE_NODE_FIELD(subplans);
1811         WRITE_BITMAPSET_FIELD(rewindPlanIDs);
1812         WRITE_NODE_FIELD(finalrtable);
1813         WRITE_NODE_FIELD(finalrowmarks);
1814         WRITE_NODE_FIELD(resultRelations);
1815         WRITE_NODE_FIELD(relationOids);
1816         WRITE_NODE_FIELD(invalItems);
1817         WRITE_INT_FIELD(nParamExec);
1818         WRITE_UINT_FIELD(lastPHId);
1819         WRITE_UINT_FIELD(lastRowMarkId);
1820         WRITE_BOOL_FIELD(transientPlan);
1821         WRITE_BOOL_FIELD(hasRowSecurity);
1822         WRITE_BOOL_FIELD(parallelModeOK);
1823         WRITE_BOOL_FIELD(parallelModeNeeded);
1824 }
1825
1826 static void
1827 _outPlannerInfo(StringInfo str, const PlannerInfo *node)
1828 {
1829         WRITE_NODE_TYPE("PLANNERINFO");
1830
1831         /* NB: this isn't a complete set of fields */
1832         WRITE_NODE_FIELD(parse);
1833         WRITE_NODE_FIELD(glob);
1834         WRITE_UINT_FIELD(query_level);
1835         WRITE_NODE_FIELD(plan_params);
1836         WRITE_BITMAPSET_FIELD(outer_params);
1837         WRITE_BITMAPSET_FIELD(all_baserels);
1838         WRITE_BITMAPSET_FIELD(nullable_baserels);
1839         WRITE_NODE_FIELD(join_rel_list);
1840         WRITE_INT_FIELD(join_cur_level);
1841         WRITE_NODE_FIELD(init_plans);
1842         WRITE_NODE_FIELD(cte_plan_ids);
1843         WRITE_NODE_FIELD(multiexpr_params);
1844         WRITE_NODE_FIELD(eq_classes);
1845         WRITE_NODE_FIELD(canon_pathkeys);
1846         WRITE_NODE_FIELD(left_join_clauses);
1847         WRITE_NODE_FIELD(right_join_clauses);
1848         WRITE_NODE_FIELD(full_join_clauses);
1849         WRITE_NODE_FIELD(join_info_list);
1850         WRITE_NODE_FIELD(append_rel_list);
1851         WRITE_NODE_FIELD(rowMarks);
1852         WRITE_NODE_FIELD(placeholder_list);
1853         WRITE_NODE_FIELD(query_pathkeys);
1854         WRITE_NODE_FIELD(group_pathkeys);
1855         WRITE_NODE_FIELD(window_pathkeys);
1856         WRITE_NODE_FIELD(distinct_pathkeys);
1857         WRITE_NODE_FIELD(sort_pathkeys);
1858         WRITE_NODE_FIELD(minmax_aggs);
1859         WRITE_FLOAT_FIELD(total_table_pages, "%.0f");
1860         WRITE_FLOAT_FIELD(tuple_fraction, "%.4f");
1861         WRITE_FLOAT_FIELD(limit_tuples, "%.0f");
1862         WRITE_BOOL_FIELD(hasInheritedTarget);
1863         WRITE_BOOL_FIELD(hasJoinRTEs);
1864         WRITE_BOOL_FIELD(hasLateralRTEs);
1865         WRITE_BOOL_FIELD(hasDeletedRTEs);
1866         WRITE_BOOL_FIELD(hasHavingQual);
1867         WRITE_BOOL_FIELD(hasPseudoConstantQuals);
1868         WRITE_BOOL_FIELD(hasRecursion);
1869         WRITE_INT_FIELD(wt_param_id);
1870         WRITE_BITMAPSET_FIELD(curOuterRels);
1871         WRITE_NODE_FIELD(curOuterParams);
1872 }
1873
1874 static void
1875 _outRelOptInfo(StringInfo str, const RelOptInfo *node)
1876 {
1877         WRITE_NODE_TYPE("RELOPTINFO");
1878
1879         /* NB: this isn't a complete set of fields */
1880         WRITE_ENUM_FIELD(reloptkind, RelOptKind);
1881         WRITE_BITMAPSET_FIELD(relids);
1882         WRITE_FLOAT_FIELD(rows, "%.0f");
1883         WRITE_INT_FIELD(width);
1884         WRITE_BOOL_FIELD(consider_startup);
1885         WRITE_BOOL_FIELD(consider_param_startup);
1886         WRITE_BOOL_FIELD(consider_parallel);
1887         WRITE_NODE_FIELD(reltargetlist);
1888         WRITE_NODE_FIELD(pathlist);
1889         WRITE_NODE_FIELD(ppilist);
1890         WRITE_NODE_FIELD(cheapest_startup_path);
1891         WRITE_NODE_FIELD(cheapest_total_path);
1892         WRITE_NODE_FIELD(cheapest_unique_path);
1893         WRITE_NODE_FIELD(cheapest_parameterized_paths);
1894         WRITE_BITMAPSET_FIELD(direct_lateral_relids);
1895         WRITE_BITMAPSET_FIELD(lateral_relids);
1896         WRITE_UINT_FIELD(relid);
1897         WRITE_OID_FIELD(reltablespace);
1898         WRITE_ENUM_FIELD(rtekind, RTEKind);
1899         WRITE_INT_FIELD(min_attr);
1900         WRITE_INT_FIELD(max_attr);
1901         WRITE_NODE_FIELD(lateral_vars);
1902         WRITE_BITMAPSET_FIELD(lateral_referencers);
1903         WRITE_NODE_FIELD(indexlist);
1904         WRITE_UINT_FIELD(pages);
1905         WRITE_FLOAT_FIELD(tuples, "%.0f");
1906         WRITE_FLOAT_FIELD(allvisfrac, "%.6f");
1907         WRITE_NODE_FIELD(subplan);
1908         WRITE_NODE_FIELD(subroot);
1909         WRITE_NODE_FIELD(subplan_params);
1910         WRITE_OID_FIELD(serverid);
1911         /* we don't try to print fdwroutine or fdw_private */
1912         WRITE_NODE_FIELD(baserestrictinfo);
1913         WRITE_NODE_FIELD(joininfo);
1914         WRITE_BOOL_FIELD(has_eclass_joins);
1915 }
1916
1917 static void
1918 _outIndexOptInfo(StringInfo str, const IndexOptInfo *node)
1919 {
1920         WRITE_NODE_TYPE("INDEXOPTINFO");
1921
1922         /* NB: this isn't a complete set of fields */
1923         WRITE_OID_FIELD(indexoid);
1924         /* Do NOT print rel field, else infinite recursion */
1925         WRITE_UINT_FIELD(pages);
1926         WRITE_FLOAT_FIELD(tuples, "%.0f");
1927         WRITE_INT_FIELD(tree_height);
1928         WRITE_INT_FIELD(ncolumns);
1929         /* array fields aren't really worth the trouble to print */
1930         WRITE_OID_FIELD(relam);
1931         /* indexprs is redundant since we print indextlist */
1932         WRITE_NODE_FIELD(indpred);
1933         WRITE_NODE_FIELD(indextlist);
1934         WRITE_BOOL_FIELD(predOK);
1935         WRITE_BOOL_FIELD(unique);
1936         WRITE_BOOL_FIELD(immediate);
1937         WRITE_BOOL_FIELD(hypothetical);
1938         /* we don't bother with fields copied from the pg_am entry */
1939 }
1940
1941 static void
1942 _outEquivalenceClass(StringInfo str, const EquivalenceClass *node)
1943 {
1944         /*
1945          * To simplify reading, we just chase up to the topmost merged EC and
1946          * print that, without bothering to show the merge-ees separately.
1947          */
1948         while (node->ec_merged)
1949                 node = node->ec_merged;
1950
1951         WRITE_NODE_TYPE("EQUIVALENCECLASS");
1952
1953         WRITE_NODE_FIELD(ec_opfamilies);
1954         WRITE_OID_FIELD(ec_collation);
1955         WRITE_NODE_FIELD(ec_members);
1956         WRITE_NODE_FIELD(ec_sources);
1957         WRITE_NODE_FIELD(ec_derives);
1958         WRITE_BITMAPSET_FIELD(ec_relids);
1959         WRITE_BOOL_FIELD(ec_has_const);
1960         WRITE_BOOL_FIELD(ec_has_volatile);
1961         WRITE_BOOL_FIELD(ec_below_outer_join);
1962         WRITE_BOOL_FIELD(ec_broken);
1963         WRITE_UINT_FIELD(ec_sortref);
1964 }
1965
1966 static void
1967 _outEquivalenceMember(StringInfo str, const EquivalenceMember *node)
1968 {
1969         WRITE_NODE_TYPE("EQUIVALENCEMEMBER");
1970
1971         WRITE_NODE_FIELD(em_expr);
1972         WRITE_BITMAPSET_FIELD(em_relids);
1973         WRITE_BITMAPSET_FIELD(em_nullable_relids);
1974         WRITE_BOOL_FIELD(em_is_const);
1975         WRITE_BOOL_FIELD(em_is_child);
1976         WRITE_OID_FIELD(em_datatype);
1977 }
1978
1979 static void
1980 _outPathKey(StringInfo str, const PathKey *node)
1981 {
1982         WRITE_NODE_TYPE("PATHKEY");
1983
1984         WRITE_NODE_FIELD(pk_eclass);
1985         WRITE_OID_FIELD(pk_opfamily);
1986         WRITE_INT_FIELD(pk_strategy);
1987         WRITE_BOOL_FIELD(pk_nulls_first);
1988 }
1989
1990 static void
1991 _outParamPathInfo(StringInfo str, const ParamPathInfo *node)
1992 {
1993         WRITE_NODE_TYPE("PARAMPATHINFO");
1994
1995         WRITE_BITMAPSET_FIELD(ppi_req_outer);
1996         WRITE_FLOAT_FIELD(ppi_rows, "%.0f");
1997         WRITE_NODE_FIELD(ppi_clauses);
1998 }
1999
2000 static void
2001 _outRestrictInfo(StringInfo str, const RestrictInfo *node)
2002 {
2003         WRITE_NODE_TYPE("RESTRICTINFO");
2004
2005         /* NB: this isn't a complete set of fields */
2006         WRITE_NODE_FIELD(clause);
2007         WRITE_BOOL_FIELD(is_pushed_down);
2008         WRITE_BOOL_FIELD(outerjoin_delayed);
2009         WRITE_BOOL_FIELD(can_join);
2010         WRITE_BOOL_FIELD(pseudoconstant);
2011         WRITE_BITMAPSET_FIELD(clause_relids);
2012         WRITE_BITMAPSET_FIELD(required_relids);
2013         WRITE_BITMAPSET_FIELD(outer_relids);
2014         WRITE_BITMAPSET_FIELD(nullable_relids);
2015         WRITE_BITMAPSET_FIELD(left_relids);
2016         WRITE_BITMAPSET_FIELD(right_relids);
2017         WRITE_NODE_FIELD(orclause);
2018         /* don't write parent_ec, leads to infinite recursion in plan tree dump */
2019         WRITE_FLOAT_FIELD(norm_selec, "%.4f");
2020         WRITE_FLOAT_FIELD(outer_selec, "%.4f");
2021         WRITE_NODE_FIELD(mergeopfamilies);
2022         /* don't write left_ec, leads to infinite recursion in plan tree dump */
2023         /* don't write right_ec, leads to infinite recursion in plan tree dump */
2024         WRITE_NODE_FIELD(left_em);
2025         WRITE_NODE_FIELD(right_em);
2026         WRITE_BOOL_FIELD(outer_is_left);
2027         WRITE_OID_FIELD(hashjoinoperator);
2028 }
2029
2030 static void
2031 _outPlaceHolderVar(StringInfo str, const PlaceHolderVar *node)
2032 {
2033         WRITE_NODE_TYPE("PLACEHOLDERVAR");
2034
2035         WRITE_NODE_FIELD(phexpr);
2036         WRITE_BITMAPSET_FIELD(phrels);
2037         WRITE_UINT_FIELD(phid);
2038         WRITE_UINT_FIELD(phlevelsup);
2039 }
2040
2041 static void
2042 _outSpecialJoinInfo(StringInfo str, const SpecialJoinInfo *node)
2043 {
2044         WRITE_NODE_TYPE("SPECIALJOININFO");
2045
2046         WRITE_BITMAPSET_FIELD(min_lefthand);
2047         WRITE_BITMAPSET_FIELD(min_righthand);
2048         WRITE_BITMAPSET_FIELD(syn_lefthand);
2049         WRITE_BITMAPSET_FIELD(syn_righthand);
2050         WRITE_ENUM_FIELD(jointype, JoinType);
2051         WRITE_BOOL_FIELD(lhs_strict);
2052         WRITE_BOOL_FIELD(delay_upper_joins);
2053         WRITE_BOOL_FIELD(semi_can_btree);
2054         WRITE_BOOL_FIELD(semi_can_hash);
2055         WRITE_NODE_FIELD(semi_operators);
2056         WRITE_NODE_FIELD(semi_rhs_exprs);
2057 }
2058
2059 static void
2060 _outAppendRelInfo(StringInfo str, const AppendRelInfo *node)
2061 {
2062         WRITE_NODE_TYPE("APPENDRELINFO");
2063
2064         WRITE_UINT_FIELD(parent_relid);
2065         WRITE_UINT_FIELD(child_relid);
2066         WRITE_OID_FIELD(parent_reltype);
2067         WRITE_OID_FIELD(child_reltype);
2068         WRITE_NODE_FIELD(translated_vars);
2069         WRITE_OID_FIELD(parent_reloid);
2070 }
2071
2072 static void
2073 _outPlaceHolderInfo(StringInfo str, const PlaceHolderInfo *node)
2074 {
2075         WRITE_NODE_TYPE("PLACEHOLDERINFO");
2076
2077         WRITE_UINT_FIELD(phid);
2078         WRITE_NODE_FIELD(ph_var);
2079         WRITE_BITMAPSET_FIELD(ph_eval_at);
2080         WRITE_BITMAPSET_FIELD(ph_lateral);
2081         WRITE_BITMAPSET_FIELD(ph_needed);
2082         WRITE_INT_FIELD(ph_width);
2083 }
2084
2085 static void
2086 _outMinMaxAggInfo(StringInfo str, const MinMaxAggInfo *node)
2087 {
2088         WRITE_NODE_TYPE("MINMAXAGGINFO");
2089
2090         WRITE_OID_FIELD(aggfnoid);
2091         WRITE_OID_FIELD(aggsortop);
2092         WRITE_NODE_FIELD(target);
2093         /* We intentionally omit subroot --- too large, not interesting enough */
2094         WRITE_NODE_FIELD(path);
2095         WRITE_FLOAT_FIELD(pathcost, "%.2f");
2096         WRITE_NODE_FIELD(param);
2097 }
2098
2099 static void
2100 _outPlannerParamItem(StringInfo str, const PlannerParamItem *node)
2101 {
2102         WRITE_NODE_TYPE("PLANNERPARAMITEM");
2103
2104         WRITE_NODE_FIELD(item);
2105         WRITE_INT_FIELD(paramId);
2106 }
2107
2108 /*****************************************************************************
2109  *
2110  *      Stuff from parsenodes.h.
2111  *
2112  *****************************************************************************/
2113
2114 /*
2115  * print the basic stuff of all nodes that inherit from CreateStmt
2116  */
2117 static void
2118 _outCreateStmtInfo(StringInfo str, const CreateStmt *node)
2119 {
2120         WRITE_NODE_FIELD(relation);
2121         WRITE_NODE_FIELD(tableElts);
2122         WRITE_NODE_FIELD(inhRelations);
2123         WRITE_NODE_FIELD(ofTypename);
2124         WRITE_NODE_FIELD(constraints);
2125         WRITE_NODE_FIELD(options);
2126         WRITE_ENUM_FIELD(oncommit, OnCommitAction);
2127         WRITE_STRING_FIELD(tablespacename);
2128         WRITE_BOOL_FIELD(if_not_exists);
2129 }
2130
2131 static void
2132 _outCreateStmt(StringInfo str, const CreateStmt *node)
2133 {
2134         WRITE_NODE_TYPE("CREATESTMT");
2135
2136         _outCreateStmtInfo(str, (const CreateStmt *) node);
2137 }
2138
2139 static void
2140 _outCreateForeignTableStmt(StringInfo str, const CreateForeignTableStmt *node)
2141 {
2142         WRITE_NODE_TYPE("CREATEFOREIGNTABLESTMT");
2143
2144         _outCreateStmtInfo(str, (const CreateStmt *) node);
2145
2146         WRITE_STRING_FIELD(servername);
2147         WRITE_NODE_FIELD(options);
2148 }
2149
2150 static void
2151 _outImportForeignSchemaStmt(StringInfo str, const ImportForeignSchemaStmt *node)
2152 {
2153         WRITE_NODE_TYPE("IMPORTFOREIGNSCHEMASTMT");
2154
2155         WRITE_STRING_FIELD(server_name);
2156         WRITE_STRING_FIELD(remote_schema);
2157         WRITE_STRING_FIELD(local_schema);
2158         WRITE_ENUM_FIELD(list_type, ImportForeignSchemaType);
2159         WRITE_NODE_FIELD(table_list);
2160         WRITE_NODE_FIELD(options);
2161 }
2162
2163 static void
2164 _outIndexStmt(StringInfo str, const IndexStmt *node)
2165 {
2166         WRITE_NODE_TYPE("INDEXSTMT");
2167
2168         WRITE_STRING_FIELD(idxname);
2169         WRITE_NODE_FIELD(relation);
2170         WRITE_STRING_FIELD(accessMethod);
2171         WRITE_STRING_FIELD(tableSpace);
2172         WRITE_NODE_FIELD(indexParams);
2173         WRITE_NODE_FIELD(options);
2174         WRITE_NODE_FIELD(whereClause);
2175         WRITE_NODE_FIELD(excludeOpNames);
2176         WRITE_STRING_FIELD(idxcomment);
2177         WRITE_OID_FIELD(indexOid);
2178         WRITE_OID_FIELD(oldNode);
2179         WRITE_BOOL_FIELD(unique);
2180         WRITE_BOOL_FIELD(primary);
2181         WRITE_BOOL_FIELD(isconstraint);
2182         WRITE_BOOL_FIELD(deferrable);
2183         WRITE_BOOL_FIELD(initdeferred);
2184         WRITE_BOOL_FIELD(transformed);
2185         WRITE_BOOL_FIELD(concurrent);
2186         WRITE_BOOL_FIELD(if_not_exists);
2187 }
2188
2189 static void
2190 _outNotifyStmt(StringInfo str, const NotifyStmt *node)
2191 {
2192         WRITE_NODE_TYPE("NOTIFY");
2193
2194         WRITE_STRING_FIELD(conditionname);
2195         WRITE_STRING_FIELD(payload);
2196 }
2197
2198 static void
2199 _outDeclareCursorStmt(StringInfo str, const DeclareCursorStmt *node)
2200 {
2201         WRITE_NODE_TYPE("DECLARECURSOR");
2202
2203         WRITE_STRING_FIELD(portalname);
2204         WRITE_INT_FIELD(options);
2205         WRITE_NODE_FIELD(query);
2206 }
2207
2208 static void
2209 _outSelectStmt(StringInfo str, const SelectStmt *node)
2210 {
2211         WRITE_NODE_TYPE("SELECT");
2212
2213         WRITE_NODE_FIELD(distinctClause);
2214         WRITE_NODE_FIELD(intoClause);
2215         WRITE_NODE_FIELD(targetList);
2216         WRITE_NODE_FIELD(fromClause);
2217         WRITE_NODE_FIELD(whereClause);
2218         WRITE_NODE_FIELD(groupClause);
2219         WRITE_NODE_FIELD(havingClause);
2220         WRITE_NODE_FIELD(windowClause);
2221         WRITE_NODE_FIELD(valuesLists);
2222         WRITE_NODE_FIELD(sortClause);
2223         WRITE_NODE_FIELD(limitOffset);
2224         WRITE_NODE_FIELD(limitCount);
2225         WRITE_NODE_FIELD(lockingClause);
2226         WRITE_NODE_FIELD(withClause);
2227         WRITE_ENUM_FIELD(op, SetOperation);
2228         WRITE_BOOL_FIELD(all);
2229         WRITE_NODE_FIELD(larg);
2230         WRITE_NODE_FIELD(rarg);
2231 }
2232
2233 static void
2234 _outFuncCall(StringInfo str, const FuncCall *node)
2235 {
2236         WRITE_NODE_TYPE("FUNCCALL");
2237
2238         WRITE_NODE_FIELD(funcname);
2239         WRITE_NODE_FIELD(args);
2240         WRITE_NODE_FIELD(agg_order);
2241         WRITE_NODE_FIELD(agg_filter);
2242         WRITE_BOOL_FIELD(agg_within_group);
2243         WRITE_BOOL_FIELD(agg_star);
2244         WRITE_BOOL_FIELD(agg_distinct);
2245         WRITE_BOOL_FIELD(func_variadic);
2246         WRITE_NODE_FIELD(over);
2247         WRITE_LOCATION_FIELD(location);
2248 }
2249
2250 static void
2251 _outDefElem(StringInfo str, const DefElem *node)
2252 {
2253         WRITE_NODE_TYPE("DEFELEM");
2254
2255         WRITE_STRING_FIELD(defnamespace);
2256         WRITE_STRING_FIELD(defname);
2257         WRITE_NODE_FIELD(arg);
2258         WRITE_ENUM_FIELD(defaction, DefElemAction);
2259 }
2260
2261 static void
2262 _outTableLikeClause(StringInfo str, const TableLikeClause *node)
2263 {
2264         WRITE_NODE_TYPE("TABLELIKECLAUSE");
2265
2266         WRITE_NODE_FIELD(relation);
2267         WRITE_UINT_FIELD(options);
2268 }
2269
2270 static void
2271 _outLockingClause(StringInfo str, const LockingClause *node)
2272 {
2273         WRITE_NODE_TYPE("LOCKINGCLAUSE");
2274
2275         WRITE_NODE_FIELD(lockedRels);
2276         WRITE_ENUM_FIELD(strength, LockClauseStrength);
2277         WRITE_ENUM_FIELD(waitPolicy, LockWaitPolicy);
2278 }
2279
2280 static void
2281 _outXmlSerialize(StringInfo str, const XmlSerialize *node)
2282 {
2283         WRITE_NODE_TYPE("XMLSERIALIZE");
2284
2285         WRITE_ENUM_FIELD(xmloption, XmlOptionType);
2286         WRITE_NODE_FIELD(expr);
2287         WRITE_NODE_FIELD(typeName);
2288         WRITE_LOCATION_FIELD(location);
2289 }
2290
2291 static void
2292 _outColumnDef(StringInfo str, const ColumnDef *node)
2293 {
2294         WRITE_NODE_TYPE("COLUMNDEF");
2295
2296         WRITE_STRING_FIELD(colname);
2297         WRITE_NODE_FIELD(typeName);
2298         WRITE_INT_FIELD(inhcount);
2299         WRITE_BOOL_FIELD(is_local);
2300         WRITE_BOOL_FIELD(is_not_null);
2301         WRITE_BOOL_FIELD(is_from_type);
2302         WRITE_CHAR_FIELD(storage);
2303         WRITE_NODE_FIELD(raw_default);
2304         WRITE_NODE_FIELD(cooked_default);
2305         WRITE_NODE_FIELD(collClause);
2306         WRITE_OID_FIELD(collOid);
2307         WRITE_NODE_FIELD(constraints);
2308         WRITE_NODE_FIELD(fdwoptions);
2309         WRITE_LOCATION_FIELD(location);
2310 }
2311
2312 static void
2313 _outTypeName(StringInfo str, const TypeName *node)
2314 {
2315         WRITE_NODE_TYPE("TYPENAME");
2316
2317         WRITE_NODE_FIELD(names);
2318         WRITE_OID_FIELD(typeOid);
2319         WRITE_BOOL_FIELD(setof);
2320         WRITE_BOOL_FIELD(pct_type);
2321         WRITE_NODE_FIELD(typmods);
2322         WRITE_INT_FIELD(typemod);
2323         WRITE_NODE_FIELD(arrayBounds);
2324         WRITE_LOCATION_FIELD(location);
2325 }
2326
2327 static void
2328 _outTypeCast(StringInfo str, const TypeCast *node)
2329 {
2330         WRITE_NODE_TYPE("TYPECAST");
2331
2332         WRITE_NODE_FIELD(arg);
2333         WRITE_NODE_FIELD(typeName);
2334         WRITE_LOCATION_FIELD(location);
2335 }
2336
2337 static void
2338 _outCollateClause(StringInfo str, const CollateClause *node)
2339 {
2340         WRITE_NODE_TYPE("COLLATECLAUSE");
2341
2342         WRITE_NODE_FIELD(arg);
2343         WRITE_NODE_FIELD(collname);
2344         WRITE_LOCATION_FIELD(location);
2345 }
2346
2347 static void
2348 _outIndexElem(StringInfo str, const IndexElem *node)
2349 {
2350         WRITE_NODE_TYPE("INDEXELEM");
2351
2352         WRITE_STRING_FIELD(name);
2353         WRITE_NODE_FIELD(expr);
2354         WRITE_STRING_FIELD(indexcolname);
2355         WRITE_NODE_FIELD(collation);
2356         WRITE_NODE_FIELD(opclass);
2357         WRITE_ENUM_FIELD(ordering, SortByDir);
2358         WRITE_ENUM_FIELD(nulls_ordering, SortByNulls);
2359 }
2360
2361 static void
2362 _outQuery(StringInfo str, const Query *node)
2363 {
2364         WRITE_NODE_TYPE("QUERY");
2365
2366         WRITE_ENUM_FIELD(commandType, CmdType);
2367         WRITE_ENUM_FIELD(querySource, QuerySource);
2368         /* we intentionally do not print the queryId field */
2369         WRITE_BOOL_FIELD(canSetTag);
2370
2371         /*
2372          * Hack to work around missing outfuncs routines for a lot of the
2373          * utility-statement node types.  (The only one we actually *need* for
2374          * rules support is NotifyStmt.)  Someday we ought to support 'em all, but
2375          * for the meantime do this to avoid getting lots of warnings when running
2376          * with debug_print_parse on.
2377          */
2378         if (node->utilityStmt)
2379         {
2380                 switch (nodeTag(node->utilityStmt))
2381                 {
2382                         case T_CreateStmt:
2383                         case T_IndexStmt:
2384                         case T_NotifyStmt:
2385                         case T_DeclareCursorStmt:
2386                                 WRITE_NODE_FIELD(utilityStmt);
2387                                 break;
2388                         default:
2389                                 appendStringInfoString(str, " :utilityStmt ?");
2390                                 break;
2391                 }
2392         }
2393         else
2394                 appendStringInfoString(str, " :utilityStmt <>");
2395
2396         WRITE_INT_FIELD(resultRelation);
2397         WRITE_BOOL_FIELD(hasAggs);
2398         WRITE_BOOL_FIELD(hasWindowFuncs);
2399         WRITE_BOOL_FIELD(hasSubLinks);
2400         WRITE_BOOL_FIELD(hasDistinctOn);
2401         WRITE_BOOL_FIELD(hasRecursive);
2402         WRITE_BOOL_FIELD(hasModifyingCTE);
2403         WRITE_BOOL_FIELD(hasForUpdate);
2404         WRITE_BOOL_FIELD(hasRowSecurity);
2405         WRITE_NODE_FIELD(cteList);
2406         WRITE_NODE_FIELD(rtable);
2407         WRITE_NODE_FIELD(jointree);
2408         WRITE_NODE_FIELD(targetList);
2409         WRITE_NODE_FIELD(onConflict);
2410         WRITE_NODE_FIELD(returningList);
2411         WRITE_NODE_FIELD(groupClause);
2412         WRITE_NODE_FIELD(groupingSets);
2413         WRITE_NODE_FIELD(havingQual);
2414         WRITE_NODE_FIELD(windowClause);
2415         WRITE_NODE_FIELD(distinctClause);
2416         WRITE_NODE_FIELD(sortClause);
2417         WRITE_NODE_FIELD(limitOffset);
2418         WRITE_NODE_FIELD(limitCount);
2419         WRITE_NODE_FIELD(rowMarks);
2420         WRITE_NODE_FIELD(setOperations);
2421         WRITE_NODE_FIELD(constraintDeps);
2422 }
2423
2424 static void
2425 _outWithCheckOption(StringInfo str, const WithCheckOption *node)
2426 {
2427         WRITE_NODE_TYPE("WITHCHECKOPTION");
2428
2429         WRITE_ENUM_FIELD(kind, WCOKind);
2430         WRITE_STRING_FIELD(relname);
2431         WRITE_STRING_FIELD(polname);
2432         WRITE_NODE_FIELD(qual);
2433         WRITE_BOOL_FIELD(cascaded);
2434 }
2435
2436 static void
2437 _outSortGroupClause(StringInfo str, const SortGroupClause *node)
2438 {
2439         WRITE_NODE_TYPE("SORTGROUPCLAUSE");
2440
2441         WRITE_UINT_FIELD(tleSortGroupRef);
2442         WRITE_OID_FIELD(eqop);
2443         WRITE_OID_FIELD(sortop);
2444         WRITE_BOOL_FIELD(nulls_first);
2445         WRITE_BOOL_FIELD(hashable);
2446 }
2447
2448 static void
2449 _outGroupingSet(StringInfo str, const GroupingSet *node)
2450 {
2451         WRITE_NODE_TYPE("GROUPINGSET");
2452
2453         WRITE_ENUM_FIELD(kind, GroupingSetKind);
2454         WRITE_NODE_FIELD(content);
2455         WRITE_LOCATION_FIELD(location);
2456 }
2457
2458 static void
2459 _outWindowClause(StringInfo str, const WindowClause *node)
2460 {
2461         WRITE_NODE_TYPE("WINDOWCLAUSE");
2462
2463         WRITE_STRING_FIELD(name);
2464         WRITE_STRING_FIELD(refname);
2465         WRITE_NODE_FIELD(partitionClause);
2466         WRITE_NODE_FIELD(orderClause);
2467         WRITE_INT_FIELD(frameOptions);
2468         WRITE_NODE_FIELD(startOffset);
2469         WRITE_NODE_FIELD(endOffset);
2470         WRITE_UINT_FIELD(winref);
2471         WRITE_BOOL_FIELD(copiedOrder);
2472 }
2473
2474 static void
2475 _outRowMarkClause(StringInfo str, const RowMarkClause *node)
2476 {
2477         WRITE_NODE_TYPE("ROWMARKCLAUSE");
2478
2479         WRITE_UINT_FIELD(rti);
2480         WRITE_ENUM_FIELD(strength, LockClauseStrength);
2481         WRITE_ENUM_FIELD(waitPolicy, LockWaitPolicy);
2482         WRITE_BOOL_FIELD(pushedDown);
2483 }
2484
2485 static void
2486 _outWithClause(StringInfo str, const WithClause *node)
2487 {
2488         WRITE_NODE_TYPE("WITHCLAUSE");
2489
2490         WRITE_NODE_FIELD(ctes);
2491         WRITE_BOOL_FIELD(recursive);
2492         WRITE_LOCATION_FIELD(location);
2493 }
2494
2495 static void
2496 _outCommonTableExpr(StringInfo str, const CommonTableExpr *node)
2497 {
2498         WRITE_NODE_TYPE("COMMONTABLEEXPR");
2499
2500         WRITE_STRING_FIELD(ctename);
2501         WRITE_NODE_FIELD(aliascolnames);
2502         WRITE_NODE_FIELD(ctequery);
2503         WRITE_LOCATION_FIELD(location);
2504         WRITE_BOOL_FIELD(cterecursive);
2505         WRITE_INT_FIELD(cterefcount);
2506         WRITE_NODE_FIELD(ctecolnames);
2507         WRITE_NODE_FIELD(ctecoltypes);
2508         WRITE_NODE_FIELD(ctecoltypmods);
2509         WRITE_NODE_FIELD(ctecolcollations);
2510 }
2511
2512 static void
2513 _outSetOperationStmt(StringInfo str, const SetOperationStmt *node)
2514 {
2515         WRITE_NODE_TYPE("SETOPERATIONSTMT");
2516
2517         WRITE_ENUM_FIELD(op, SetOperation);
2518         WRITE_BOOL_FIELD(all);
2519         WRITE_NODE_FIELD(larg);
2520         WRITE_NODE_FIELD(rarg);
2521         WRITE_NODE_FIELD(colTypes);
2522         WRITE_NODE_FIELD(colTypmods);
2523         WRITE_NODE_FIELD(colCollations);
2524         WRITE_NODE_FIELD(groupClauses);
2525 }
2526
2527 static void
2528 _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
2529 {
2530         WRITE_NODE_TYPE("RTE");
2531
2532         /* put alias + eref first to make dump more legible */
2533         WRITE_NODE_FIELD(alias);
2534         WRITE_NODE_FIELD(eref);
2535         WRITE_ENUM_FIELD(rtekind, RTEKind);
2536
2537         switch (node->rtekind)
2538         {
2539                 case RTE_RELATION:
2540                         WRITE_OID_FIELD(relid);
2541                         WRITE_CHAR_FIELD(relkind);
2542                         WRITE_NODE_FIELD(tablesample);
2543                         break;
2544                 case RTE_SUBQUERY:
2545                         WRITE_NODE_FIELD(subquery);
2546                         WRITE_BOOL_FIELD(security_barrier);
2547                         break;
2548                 case RTE_JOIN:
2549                         WRITE_ENUM_FIELD(jointype, JoinType);
2550                         WRITE_NODE_FIELD(joinaliasvars);
2551                         break;
2552                 case RTE_FUNCTION:
2553                         WRITE_NODE_FIELD(functions);
2554                         WRITE_BOOL_FIELD(funcordinality);
2555                         break;
2556                 case RTE_VALUES:
2557                         WRITE_NODE_FIELD(values_lists);
2558                         WRITE_NODE_FIELD(values_collations);
2559                         break;
2560                 case RTE_CTE:
2561                         WRITE_STRING_FIELD(ctename);
2562                         WRITE_UINT_FIELD(ctelevelsup);
2563                         WRITE_BOOL_FIELD(self_reference);
2564                         WRITE_NODE_FIELD(ctecoltypes);
2565                         WRITE_NODE_FIELD(ctecoltypmods);
2566                         WRITE_NODE_FIELD(ctecolcollations);
2567                         break;
2568                 default:
2569                         elog(ERROR, "unrecognized RTE kind: %d", (int) node->rtekind);
2570                         break;
2571         }
2572
2573         WRITE_BOOL_FIELD(lateral);
2574         WRITE_BOOL_FIELD(inh);
2575         WRITE_BOOL_FIELD(inFromCl);
2576         WRITE_UINT_FIELD(requiredPerms);
2577         WRITE_OID_FIELD(checkAsUser);
2578         WRITE_BITMAPSET_FIELD(selectedCols);
2579         WRITE_BITMAPSET_FIELD(insertedCols);
2580         WRITE_BITMAPSET_FIELD(updatedCols);
2581         WRITE_NODE_FIELD(securityQuals);
2582 }
2583
2584 static void
2585 _outRangeTblFunction(StringInfo str, const RangeTblFunction *node)
2586 {
2587         WRITE_NODE_TYPE("RANGETBLFUNCTION");
2588
2589         WRITE_NODE_FIELD(funcexpr);
2590         WRITE_INT_FIELD(funccolcount);
2591         WRITE_NODE_FIELD(funccolnames);
2592         WRITE_NODE_FIELD(funccoltypes);
2593         WRITE_NODE_FIELD(funccoltypmods);
2594         WRITE_NODE_FIELD(funccolcollations);
2595         WRITE_BITMAPSET_FIELD(funcparams);
2596 }
2597
2598 static void
2599 _outTableSampleClause(StringInfo str, const TableSampleClause *node)
2600 {
2601         WRITE_NODE_TYPE("TABLESAMPLECLAUSE");
2602
2603         WRITE_OID_FIELD(tsmhandler);
2604         WRITE_NODE_FIELD(args);
2605         WRITE_NODE_FIELD(repeatable);
2606 }
2607
2608 static void
2609 _outAExpr(StringInfo str, const A_Expr *node)
2610 {
2611         WRITE_NODE_TYPE("AEXPR");
2612
2613         switch (node->kind)
2614         {
2615                 case AEXPR_OP:
2616                         appendStringInfoChar(str, ' ');
2617                         WRITE_NODE_FIELD(name);
2618                         break;
2619                 case AEXPR_OP_ANY:
2620                         appendStringInfoChar(str, ' ');
2621                         WRITE_NODE_FIELD(name);
2622                         appendStringInfoString(str, " ANY ");
2623                         break;
2624                 case AEXPR_OP_ALL:
2625                         appendStringInfoChar(str, ' ');
2626                         WRITE_NODE_FIELD(name);
2627                         appendStringInfoString(str, " ALL ");
2628                         break;
2629                 case AEXPR_DISTINCT:
2630                         appendStringInfoString(str, " DISTINCT ");
2631                         WRITE_NODE_FIELD(name);
2632                         break;
2633                 case AEXPR_NULLIF:
2634                         appendStringInfoString(str, " NULLIF ");
2635                         WRITE_NODE_FIELD(name);
2636                         break;
2637                 case AEXPR_OF:
2638                         appendStringInfoString(str, " OF ");
2639                         WRITE_NODE_FIELD(name);
2640                         break;
2641                 case AEXPR_IN:
2642                         appendStringInfoString(str, " IN ");
2643                         WRITE_NODE_FIELD(name);
2644                         break;
2645                 case AEXPR_LIKE:
2646                         appendStringInfoString(str, " LIKE ");
2647                         WRITE_NODE_FIELD(name);
2648                         break;
2649                 case AEXPR_ILIKE:
2650                         appendStringInfoString(str, " ILIKE ");
2651                         WRITE_NODE_FIELD(name);
2652                         break;
2653                 case AEXPR_SIMILAR:
2654                         appendStringInfoString(str, " SIMILAR ");
2655                         WRITE_NODE_FIELD(name);
2656                         break;
2657                 case AEXPR_BETWEEN:
2658                         appendStringInfoString(str, " BETWEEN ");
2659                         WRITE_NODE_FIELD(name);
2660                         break;
2661                 case AEXPR_NOT_BETWEEN:
2662                         appendStringInfoString(str, " NOT_BETWEEN ");
2663                         WRITE_NODE_FIELD(name);
2664                         break;
2665                 case AEXPR_BETWEEN_SYM:
2666                         appendStringInfoString(str, " BETWEEN_SYM ");
2667                         WRITE_NODE_FIELD(name);
2668                         break;
2669                 case AEXPR_NOT_BETWEEN_SYM:
2670                         appendStringInfoString(str, " NOT_BETWEEN_SYM ");
2671                         WRITE_NODE_FIELD(name);
2672                         break;
2673                 case AEXPR_PAREN:
2674                         appendStringInfoString(str, " PAREN");
2675                         break;
2676                 default:
2677                         appendStringInfoString(str, " ??");
2678                         break;
2679         }
2680
2681         WRITE_NODE_FIELD(lexpr);
2682         WRITE_NODE_FIELD(rexpr);
2683         WRITE_LOCATION_FIELD(location);
2684 }
2685
2686 static void
2687 _outValue(StringInfo str, const Value *value)
2688 {
2689         switch (value->type)
2690         {
2691                 case T_Integer:
2692                         appendStringInfo(str, "%ld", value->val.ival);
2693                         break;
2694                 case T_Float:
2695
2696                         /*
2697                          * We assume the value is a valid numeric literal and so does not
2698                          * need quoting.
2699                          */
2700                         appendStringInfoString(str, value->val.str);
2701                         break;
2702                 case T_String:
2703
2704                         /*
2705                          * We use _outToken to provide escaping of the string's content,
2706                          * but we don't want it to do anything with an empty string.
2707                          */
2708                         appendStringInfoChar(str, '"');
2709                         if (value->val.str[0] != '\0')
2710                                 _outToken(str, value->val.str);
2711                         appendStringInfoChar(str, '"');
2712                         break;
2713                 case T_BitString:
2714                         /* internal representation already has leading 'b' */
2715                         appendStringInfoString(str, value->val.str);
2716                         break;
2717                 case T_Null:
2718                         /* this is seen only within A_Const, not in transformed trees */
2719                         appendStringInfoString(str, "NULL");
2720                         break;
2721                 default:
2722                         elog(ERROR, "unrecognized node type: %d", (int) value->type);
2723                         break;
2724         }
2725 }
2726
2727 static void
2728 _outColumnRef(StringInfo str, const ColumnRef *node)
2729 {
2730         WRITE_NODE_TYPE("COLUMNREF");
2731
2732         WRITE_NODE_FIELD(fields);
2733         WRITE_LOCATION_FIELD(location);
2734 }
2735
2736 static void
2737 _outParamRef(StringInfo str, const ParamRef *node)
2738 {
2739         WRITE_NODE_TYPE("PARAMREF");
2740
2741         WRITE_INT_FIELD(number);
2742         WRITE_LOCATION_FIELD(location);
2743 }
2744
2745 static void
2746 _outAConst(StringInfo str, const A_Const *node)
2747 {
2748         WRITE_NODE_TYPE("A_CONST");
2749
2750         appendStringInfoString(str, " :val ");
2751         _outValue(str, &(node->val));
2752         WRITE_LOCATION_FIELD(location);
2753 }
2754
2755 static void
2756 _outA_Star(StringInfo str, const A_Star *node)
2757 {
2758         WRITE_NODE_TYPE("A_STAR");
2759 }
2760
2761 static void
2762 _outA_Indices(StringInfo str, const A_Indices *node)
2763 {
2764         WRITE_NODE_TYPE("A_INDICES");
2765
2766         WRITE_BOOL_FIELD(is_slice);
2767         WRITE_NODE_FIELD(lidx);
2768         WRITE_NODE_FIELD(uidx);
2769 }
2770
2771 static void
2772 _outA_Indirection(StringInfo str, const A_Indirection *node)
2773 {
2774         WRITE_NODE_TYPE("A_INDIRECTION");
2775
2776         WRITE_NODE_FIELD(arg);
2777         WRITE_NODE_FIELD(indirection);
2778 }
2779
2780 static void
2781 _outA_ArrayExpr(StringInfo str, const A_ArrayExpr *node)
2782 {
2783         WRITE_NODE_TYPE("A_ARRAYEXPR");
2784
2785         WRITE_NODE_FIELD(elements);
2786         WRITE_LOCATION_FIELD(location);
2787 }
2788
2789 static void
2790 _outResTarget(StringInfo str, const ResTarget *node)
2791 {
2792         WRITE_NODE_TYPE("RESTARGET");
2793
2794         WRITE_STRING_FIELD(name);
2795         WRITE_NODE_FIELD(indirection);
2796         WRITE_NODE_FIELD(val);
2797         WRITE_LOCATION_FIELD(location);
2798 }
2799
2800 static void
2801 _outMultiAssignRef(StringInfo str, const MultiAssignRef *node)
2802 {
2803         WRITE_NODE_TYPE("MULTIASSIGNREF");
2804
2805         WRITE_NODE_FIELD(source);
2806         WRITE_INT_FIELD(colno);
2807         WRITE_INT_FIELD(ncolumns);
2808 }
2809
2810 static void
2811 _outSortBy(StringInfo str, const SortBy *node)
2812 {
2813         WRITE_NODE_TYPE("SORTBY");
2814
2815         WRITE_NODE_FIELD(node);
2816         WRITE_ENUM_FIELD(sortby_dir, SortByDir);
2817         WRITE_ENUM_FIELD(sortby_nulls, SortByNulls);
2818         WRITE_NODE_FIELD(useOp);
2819         WRITE_LOCATION_FIELD(location);
2820 }
2821
2822 static void
2823 _outWindowDef(StringInfo str, const WindowDef *node)
2824 {
2825         WRITE_NODE_TYPE("WINDOWDEF");
2826
2827         WRITE_STRING_FIELD(name);
2828         WRITE_STRING_FIELD(refname);
2829         WRITE_NODE_FIELD(partitionClause);
2830         WRITE_NODE_FIELD(orderClause);
2831         WRITE_INT_FIELD(frameOptions);
2832         WRITE_NODE_FIELD(startOffset);
2833         WRITE_NODE_FIELD(endOffset);
2834         WRITE_LOCATION_FIELD(location);
2835 }
2836
2837 static void
2838 _outRangeSubselect(StringInfo str, const RangeSubselect *node)
2839 {
2840         WRITE_NODE_TYPE("RANGESUBSELECT");
2841
2842         WRITE_BOOL_FIELD(lateral);
2843         WRITE_NODE_FIELD(subquery);
2844         WRITE_NODE_FIELD(alias);
2845 }
2846
2847 static void
2848 _outRangeFunction(StringInfo str, const RangeFunction *node)
2849 {
2850         WRITE_NODE_TYPE("RANGEFUNCTION");
2851
2852         WRITE_BOOL_FIELD(lateral);
2853         WRITE_BOOL_FIELD(ordinality);
2854         WRITE_BOOL_FIELD(is_rowsfrom);
2855         WRITE_NODE_FIELD(functions);
2856         WRITE_NODE_FIELD(alias);
2857         WRITE_NODE_FIELD(coldeflist);
2858 }
2859
2860 static void
2861 _outRangeTableSample(StringInfo str, const RangeTableSample *node)
2862 {
2863         WRITE_NODE_TYPE("RANGETABLESAMPLE");
2864
2865         WRITE_NODE_FIELD(relation);
2866         WRITE_NODE_FIELD(method);
2867         WRITE_NODE_FIELD(args);
2868         WRITE_NODE_FIELD(repeatable);
2869         WRITE_LOCATION_FIELD(location);
2870 }
2871
2872 static void
2873 _outConstraint(StringInfo str, const Constraint *node)
2874 {
2875         WRITE_NODE_TYPE("CONSTRAINT");
2876
2877         WRITE_STRING_FIELD(conname);
2878         WRITE_BOOL_FIELD(deferrable);
2879         WRITE_BOOL_FIELD(initdeferred);
2880         WRITE_LOCATION_FIELD(location);
2881
2882         appendStringInfoString(str, " :contype ");
2883         switch (node->contype)
2884         {
2885                 case CONSTR_NULL:
2886                         appendStringInfoString(str, "NULL");
2887                         break;
2888
2889                 case CONSTR_NOTNULL:
2890                         appendStringInfoString(str, "NOT_NULL");
2891                         break;
2892
2893                 case CONSTR_DEFAULT:
2894                         appendStringInfoString(str, "DEFAULT");
2895                         WRITE_NODE_FIELD(raw_expr);
2896                         WRITE_STRING_FIELD(cooked_expr);
2897                         break;
2898
2899                 case CONSTR_CHECK:
2900                         appendStringInfoString(str, "CHECK");
2901                         WRITE_BOOL_FIELD(is_no_inherit);
2902                         WRITE_NODE_FIELD(raw_expr);
2903                         WRITE_STRING_FIELD(cooked_expr);
2904                         break;
2905
2906                 case CONSTR_PRIMARY:
2907                         appendStringInfoString(str, "PRIMARY_KEY");
2908                         WRITE_NODE_FIELD(keys);
2909                         WRITE_NODE_FIELD(options);
2910                         WRITE_STRING_FIELD(indexname);
2911                         WRITE_STRING_FIELD(indexspace);
2912                         /* access_method and where_clause not currently used */
2913                         break;
2914
2915                 case CONSTR_UNIQUE:
2916                         appendStringInfoString(str, "UNIQUE");
2917                         WRITE_NODE_FIELD(keys);
2918                         WRITE_NODE_FIELD(options);
2919                         WRITE_STRING_FIELD(indexname);
2920                         WRITE_STRING_FIELD(indexspace);
2921                         /* access_method and where_clause not currently used */
2922                         break;
2923
2924                 case CONSTR_EXCLUSION:
2925                         appendStringInfoString(str, "EXCLUSION");
2926                         WRITE_NODE_FIELD(exclusions);
2927                         WRITE_NODE_FIELD(options);
2928                         WRITE_STRING_FIELD(indexname);
2929                         WRITE_STRING_FIELD(indexspace);
2930                         WRITE_STRING_FIELD(access_method);
2931                         WRITE_NODE_FIELD(where_clause);
2932                         break;
2933
2934                 case CONSTR_FOREIGN:
2935                         appendStringInfoString(str, "FOREIGN_KEY");
2936                         WRITE_NODE_FIELD(pktable);
2937                         WRITE_NODE_FIELD(fk_attrs);
2938                         WRITE_NODE_FIELD(pk_attrs);
2939                         WRITE_CHAR_FIELD(fk_matchtype);
2940                         WRITE_CHAR_FIELD(fk_upd_action);
2941                         WRITE_CHAR_FIELD(fk_del_action);
2942                         WRITE_NODE_FIELD(old_conpfeqop);
2943                         WRITE_OID_FIELD(old_pktable_oid);
2944                         WRITE_BOOL_FIELD(skip_validation);
2945                         WRITE_BOOL_FIELD(initially_valid);
2946                         break;
2947
2948                 case CONSTR_ATTR_DEFERRABLE:
2949                         appendStringInfoString(str, "ATTR_DEFERRABLE");
2950                         break;
2951
2952                 case CONSTR_ATTR_NOT_DEFERRABLE:
2953                         appendStringInfoString(str, "ATTR_NOT_DEFERRABLE");
2954                         break;
2955
2956                 case CONSTR_ATTR_DEFERRED:
2957                         appendStringInfoString(str, "ATTR_DEFERRED");
2958                         break;
2959
2960                 case CONSTR_ATTR_IMMEDIATE:
2961                         appendStringInfoString(str, "ATTR_IMMEDIATE");
2962                         break;
2963
2964                 default:
2965                         appendStringInfo(str, "<unrecognized_constraint %d>",
2966                                                          (int) node->contype);
2967                         break;
2968         }
2969 }
2970
2971
2972 /*
2973  * _outNode -
2974  *        converts a Node into ascii string and append it to 'str'
2975  */
2976 static void
2977 _outNode(StringInfo str, const void *obj)
2978 {
2979         if (obj == NULL)
2980                 appendStringInfoString(str, "<>");
2981         else if (IsA(obj, List) ||IsA(obj, IntList) || IsA(obj, OidList))
2982                 _outList(str, obj);
2983         else if (IsA(obj, Integer) ||
2984                          IsA(obj, Float) ||
2985                          IsA(obj, String) ||
2986                          IsA(obj, BitString))
2987         {
2988                 /* nodeRead does not want to see { } around these! */
2989                 _outValue(str, obj);
2990         }
2991         else
2992         {
2993                 appendStringInfoChar(str, '{');
2994                 switch (nodeTag(obj))
2995                 {
2996                         case T_PlannedStmt:
2997                                 _outPlannedStmt(str, obj);
2998                                 break;
2999                         case T_Plan:
3000                                 _outPlan(str, obj);
3001                                 break;
3002                         case T_Result:
3003                                 _outResult(str, obj);
3004                                 break;
3005                         case T_ModifyTable:
3006                                 _outModifyTable(str, obj);
3007                                 break;
3008                         case T_Append:
3009                                 _outAppend(str, obj);
3010                                 break;
3011                         case T_MergeAppend:
3012                                 _outMergeAppend(str, obj);
3013                                 break;
3014                         case T_RecursiveUnion:
3015                                 _outRecursiveUnion(str, obj);
3016                                 break;
3017                         case T_BitmapAnd:
3018                                 _outBitmapAnd(str, obj);
3019                                 break;
3020                         case T_BitmapOr:
3021                                 _outBitmapOr(str, obj);
3022                                 break;
3023                         case T_Gather:
3024                                 _outGather(str, obj);
3025                                 break;
3026                         case T_Scan:
3027                                 _outScan(str, obj);
3028                                 break;
3029                         case T_SeqScan:
3030                                 _outSeqScan(str, obj);
3031                                 break;
3032                         case T_SampleScan:
3033                                 _outSampleScan(str, obj);
3034                                 break;
3035                         case T_IndexScan:
3036                                 _outIndexScan(str, obj);
3037                                 break;
3038                         case T_IndexOnlyScan:
3039                                 _outIndexOnlyScan(str, obj);
3040                                 break;
3041                         case T_BitmapIndexScan:
3042                                 _outBitmapIndexScan(str, obj);
3043                                 break;
3044                         case T_BitmapHeapScan:
3045                                 _outBitmapHeapScan(str, obj);
3046                                 break;
3047                         case T_TidScan:
3048                                 _outTidScan(str, obj);
3049                                 break;
3050                         case T_SubqueryScan:
3051                                 _outSubqueryScan(str, obj);
3052                                 break;
3053                         case T_FunctionScan:
3054                                 _outFunctionScan(str, obj);
3055                                 break;
3056                         case T_ValuesScan:
3057                                 _outValuesScan(str, obj);
3058                                 break;
3059                         case T_CteScan:
3060                                 _outCteScan(str, obj);
3061                                 break;
3062                         case T_WorkTableScan:
3063                                 _outWorkTableScan(str, obj);
3064                                 break;
3065                         case T_ForeignScan:
3066                                 _outForeignScan(str, obj);
3067                                 break;
3068                         case T_CustomScan:
3069                                 _outCustomScan(str, obj);
3070                                 break;
3071                         case T_Join:
3072                                 _outJoin(str, obj);
3073                                 break;
3074                         case T_NestLoop:
3075                                 _outNestLoop(str, obj);
3076                                 break;
3077                         case T_MergeJoin:
3078                                 _outMergeJoin(str, obj);
3079                                 break;
3080                         case T_HashJoin:
3081                                 _outHashJoin(str, obj);
3082                                 break;
3083                         case T_Agg:
3084                                 _outAgg(str, obj);
3085                                 break;
3086                         case T_WindowAgg:
3087                                 _outWindowAgg(str, obj);
3088                                 break;
3089                         case T_Group:
3090                                 _outGroup(str, obj);
3091                                 break;
3092                         case T_Material:
3093                                 _outMaterial(str, obj);
3094                                 break;
3095                         case T_Sort:
3096                                 _outSort(str, obj);
3097                                 break;
3098                         case T_Unique:
3099                                 _outUnique(str, obj);
3100                                 break;
3101                         case T_Hash:
3102                                 _outHash(str, obj);
3103                                 break;
3104                         case T_SetOp:
3105                                 _outSetOp(str, obj);
3106                                 break;
3107                         case T_LockRows:
3108                                 _outLockRows(str, obj);
3109                                 break;
3110                         case T_Limit:
3111                                 _outLimit(str, obj);
3112                                 break;
3113                         case T_NestLoopParam:
3114                                 _outNestLoopParam(str, obj);
3115                                 break;
3116                         case T_PlanRowMark:
3117                                 _outPlanRowMark(str, obj);
3118                                 break;
3119                         case T_PlanInvalItem:
3120                                 _outPlanInvalItem(str, obj);
3121                                 break;
3122                         case T_Alias:
3123                                 _outAlias(str, obj);
3124                                 break;
3125                         case T_RangeVar:
3126                                 _outRangeVar(str, obj);
3127                                 break;
3128                         case T_IntoClause:
3129                                 _outIntoClause(str, obj);
3130                                 break;
3131                         case T_Var:
3132                                 _outVar(str, obj);
3133                                 break;
3134                         case T_Const:
3135                                 _outConst(str, obj);
3136                                 break;
3137                         case T_Param:
3138                                 _outParam(str, obj);
3139                                 break;
3140                         case T_Aggref:
3141                                 _outAggref(str, obj);
3142                                 break;
3143                         case T_GroupingFunc:
3144                                 _outGroupingFunc(str, obj);
3145                                 break;
3146                         case T_WindowFunc:
3147                                 _outWindowFunc(str, obj);
3148                                 break;
3149                         case T_ArrayRef:
3150                                 _outArrayRef(str, obj);
3151                                 break;
3152                         case T_FuncExpr:
3153                                 _outFuncExpr(str, obj);
3154                                 break;
3155                         case T_NamedArgExpr:
3156                                 _outNamedArgExpr(str, obj);
3157                                 break;
3158                         case T_OpExpr:
3159                                 _outOpExpr(str, obj);
3160                                 break;
3161                         case T_DistinctExpr:
3162                                 _outDistinctExpr(str, obj);
3163                                 break;
3164                         case T_NullIfExpr:
3165                                 _outNullIfExpr(str, obj);
3166                                 break;
3167                         case T_ScalarArrayOpExpr:
3168                                 _outScalarArrayOpExpr(str, obj);
3169                                 break;
3170                         case T_BoolExpr:
3171                                 _outBoolExpr(str, obj);
3172                                 break;
3173                         case T_SubLink:
3174                                 _outSubLink(str, obj);
3175                                 break;
3176                         case T_SubPlan:
3177                                 _outSubPlan(str, obj);
3178                                 break;
3179                         case T_AlternativeSubPlan:
3180                                 _outAlternativeSubPlan(str, obj);
3181                                 break;
3182                         case T_FieldSelect:
3183                                 _outFieldSelect(str, obj);
3184                                 break;
3185                         case T_FieldStore:
3186                                 _outFieldStore(str, obj);
3187                                 break;
3188                         case T_RelabelType:
3189                                 _outRelabelType(str, obj);
3190                                 break;
3191                         case T_CoerceViaIO:
3192                                 _outCoerceViaIO(str, obj);
3193                                 break;
3194                         case T_ArrayCoerceExpr:
3195                                 _outArrayCoerceExpr(str, obj);
3196                                 break;
3197                         case T_ConvertRowtypeExpr:
3198                                 _outConvertRowtypeExpr(str, obj);
3199                                 break;
3200                         case T_CollateExpr:
3201                                 _outCollateExpr(str, obj);
3202                                 break;
3203                         case T_CaseExpr:
3204                                 _outCaseExpr(str, obj);
3205                                 break;
3206                         case T_CaseWhen:
3207                                 _outCaseWhen(str, obj);
3208                                 break;
3209                         case T_CaseTestExpr:
3210                                 _outCaseTestExpr(str, obj);
3211                                 break;
3212                         case T_ArrayExpr:
3213                                 _outArrayExpr(str, obj);
3214                                 break;
3215                         case T_RowExpr:
3216                                 _outRowExpr(str, obj);
3217                                 break;
3218                         case T_RowCompareExpr:
3219                                 _outRowCompareExpr(str, obj);
3220                                 break;
3221                         case T_CoalesceExpr:
3222                                 _outCoalesceExpr(str, obj);
3223                                 break;
3224                         case T_MinMaxExpr:
3225                                 _outMinMaxExpr(str, obj);
3226                                 break;
3227                         case T_XmlExpr:
3228                                 _outXmlExpr(str, obj);
3229                                 break;
3230                         case T_NullTest:
3231                                 _outNullTest(str, obj);
3232                                 break;
3233                         case T_BooleanTest:
3234                                 _outBooleanTest(str, obj);
3235                                 break;
3236                         case T_CoerceToDomain:
3237                                 _outCoerceToDomain(str, obj);
3238                                 break;
3239                         case T_CoerceToDomainValue:
3240                                 _outCoerceToDomainValue(str, obj);
3241                                 break;
3242                         case T_SetToDefault:
3243                                 _outSetToDefault(str, obj);
3244                                 break;
3245                         case T_CurrentOfExpr:
3246                                 _outCurrentOfExpr(str, obj);
3247                                 break;
3248                         case T_InferenceElem:
3249                                 _outInferenceElem(str, obj);
3250                                 break;
3251                         case T_TargetEntry:
3252                                 _outTargetEntry(str, obj);
3253                                 break;
3254                         case T_RangeTblRef:
3255                                 _outRangeTblRef(str, obj);
3256                                 break;
3257                         case T_JoinExpr:
3258                                 _outJoinExpr(str, obj);
3259                                 break;
3260                         case T_FromExpr:
3261                                 _outFromExpr(str, obj);
3262                                 break;
3263                         case T_OnConflictExpr:
3264                                 _outOnConflictExpr(str, obj);
3265                                 break;
3266                         case T_Path:
3267                                 _outPath(str, obj);
3268                                 break;
3269                         case T_IndexPath:
3270                                 _outIndexPath(str, obj);
3271                                 break;
3272                         case T_BitmapHeapPath:
3273                                 _outBitmapHeapPath(str, obj);
3274                                 break;
3275                         case T_BitmapAndPath:
3276                                 _outBitmapAndPath(str, obj);
3277                                 break;
3278                         case T_BitmapOrPath:
3279                                 _outBitmapOrPath(str, obj);
3280                                 break;
3281                         case T_TidPath:
3282                                 _outTidPath(str, obj);
3283                                 break;
3284                         case T_ForeignPath:
3285                                 _outForeignPath(str, obj);
3286                                 break;
3287                         case T_CustomPath:
3288                                 _outCustomPath(str, obj);
3289                                 break;
3290                         case T_AppendPath:
3291                                 _outAppendPath(str, obj);
3292                                 break;
3293                         case T_MergeAppendPath:
3294                                 _outMergeAppendPath(str, obj);
3295                                 break;
3296                         case T_ResultPath:
3297                                 _outResultPath(str, obj);
3298                                 break;
3299                         case T_MaterialPath:
3300                                 _outMaterialPath(str, obj);
3301                                 break;
3302                         case T_UniquePath:
3303                                 _outUniquePath(str, obj);
3304                                 break;
3305                         case T_GatherPath:
3306                                 _outGatherPath(str, obj);
3307                                 break;
3308                         case T_NestPath:
3309                                 _outNestPath(str, obj);
3310                                 break;
3311                         case T_MergePath:
3312                                 _outMergePath(str, obj);
3313                                 break;
3314                         case T_HashPath:
3315                                 _outHashPath(str, obj);
3316                                 break;
3317                         case T_PlannerGlobal:
3318                                 _outPlannerGlobal(str, obj);
3319                                 break;
3320                         case T_PlannerInfo:
3321                                 _outPlannerInfo(str, obj);
3322                                 break;
3323                         case T_RelOptInfo:
3324                                 _outRelOptInfo(str, obj);
3325                                 break;
3326                         case T_IndexOptInfo:
3327                                 _outIndexOptInfo(str, obj);
3328                                 break;
3329                         case T_EquivalenceClass:
3330                                 _outEquivalenceClass(str, obj);
3331                                 break;
3332                         case T_EquivalenceMember:
3333                                 _outEquivalenceMember(str, obj);
3334                                 break;
3335                         case T_PathKey:
3336                                 _outPathKey(str, obj);
3337                                 break;
3338                         case T_ParamPathInfo:
3339                                 _outParamPathInfo(str, obj);
3340                                 break;
3341                         case T_RestrictInfo:
3342                                 _outRestrictInfo(str, obj);
3343                                 break;
3344                         case T_PlaceHolderVar:
3345                                 _outPlaceHolderVar(str, obj);
3346                                 break;
3347                         case T_SpecialJoinInfo:
3348                                 _outSpecialJoinInfo(str, obj);
3349                                 break;
3350                         case T_AppendRelInfo:
3351                                 _outAppendRelInfo(str, obj);
3352                                 break;
3353                         case T_PlaceHolderInfo:
3354                                 _outPlaceHolderInfo(str, obj);
3355                                 break;
3356                         case T_MinMaxAggInfo:
3357                                 _outMinMaxAggInfo(str, obj);
3358                                 break;
3359                         case T_PlannerParamItem:
3360                                 _outPlannerParamItem(str, obj);
3361                                 break;
3362
3363                         case T_CreateStmt:
3364                                 _outCreateStmt(str, obj);
3365                                 break;
3366                         case T_CreateForeignTableStmt:
3367                                 _outCreateForeignTableStmt(str, obj);
3368                                 break;
3369                         case T_ImportForeignSchemaStmt:
3370                                 _outImportForeignSchemaStmt(str, obj);
3371                                 break;
3372                         case T_IndexStmt:
3373                                 _outIndexStmt(str, obj);
3374                                 break;
3375                         case T_NotifyStmt:
3376                                 _outNotifyStmt(str, obj);
3377                                 break;
3378                         case T_DeclareCursorStmt:
3379                                 _outDeclareCursorStmt(str, obj);
3380                                 break;
3381                         case T_SelectStmt:
3382                                 _outSelectStmt(str, obj);
3383                                 break;
3384                         case T_ColumnDef:
3385                                 _outColumnDef(str, obj);
3386                                 break;
3387                         case T_TypeName:
3388                                 _outTypeName(str, obj);
3389                                 break;
3390                         case T_TypeCast:
3391                                 _outTypeCast(str, obj);
3392                                 break;
3393                         case T_CollateClause:
3394                                 _outCollateClause(str, obj);
3395                                 break;
3396                         case T_IndexElem:
3397                                 _outIndexElem(str, obj);
3398                                 break;
3399                         case T_Query:
3400                                 _outQuery(str, obj);
3401                                 break;
3402                         case T_WithCheckOption:
3403                                 _outWithCheckOption(str, obj);
3404                                 break;
3405                         case T_SortGroupClause:
3406                                 _outSortGroupClause(str, obj);
3407                                 break;
3408                         case T_GroupingSet:
3409                                 _outGroupingSet(str, obj);
3410                                 break;
3411                         case T_WindowClause:
3412                                 _outWindowClause(str, obj);
3413                                 break;
3414                         case T_RowMarkClause:
3415                                 _outRowMarkClause(str, obj);
3416                                 break;
3417                         case T_WithClause:
3418                                 _outWithClause(str, obj);
3419                                 break;
3420                         case T_CommonTableExpr:
3421                                 _outCommonTableExpr(str, obj);
3422                                 break;
3423                         case T_SetOperationStmt:
3424                                 _outSetOperationStmt(str, obj);
3425                                 break;
3426                         case T_RangeTblEntry:
3427                                 _outRangeTblEntry(str, obj);
3428                                 break;
3429                         case T_RangeTblFunction:
3430                                 _outRangeTblFunction(str, obj);
3431                                 break;
3432                         case T_TableSampleClause:
3433                                 _outTableSampleClause(str, obj);
3434                                 break;
3435                         case T_A_Expr:
3436                                 _outAExpr(str, obj);
3437                                 break;
3438                         case T_ColumnRef:
3439                                 _outColumnRef(str, obj);
3440                                 break;
3441                         case T_ParamRef:
3442                                 _outParamRef(str, obj);
3443                                 break;
3444                         case T_A_Const:
3445                                 _outAConst(str, obj);
3446                                 break;
3447                         case T_A_Star:
3448                                 _outA_Star(str, obj);
3449                                 break;
3450                         case T_A_Indices:
3451                                 _outA_Indices(str, obj);
3452                                 break;
3453                         case T_A_Indirection:
3454                                 _outA_Indirection(str, obj);
3455                                 break;
3456                         case T_A_ArrayExpr:
3457                                 _outA_ArrayExpr(str, obj);
3458                                 break;
3459                         case T_ResTarget:
3460                                 _outResTarget(str, obj);
3461                                 break;
3462                         case T_MultiAssignRef:
3463                                 _outMultiAssignRef(str, obj);
3464                                 break;
3465                         case T_SortBy:
3466                                 _outSortBy(str, obj);
3467                                 break;
3468                         case T_WindowDef:
3469                                 _outWindowDef(str, obj);
3470                                 break;
3471                         case T_RangeSubselect:
3472                                 _outRangeSubselect(str, obj);
3473                                 break;
3474                         case T_RangeFunction:
3475                                 _outRangeFunction(str, obj);
3476                                 break;
3477                         case T_RangeTableSample:
3478                                 _outRangeTableSample(str, obj);
3479                                 break;
3480                         case T_Constraint:
3481                                 _outConstraint(str, obj);
3482                                 break;
3483                         case T_FuncCall:
3484                                 _outFuncCall(str, obj);
3485                                 break;
3486                         case T_DefElem:
3487                                 _outDefElem(str, obj);
3488                                 break;
3489                         case T_TableLikeClause:
3490                                 _outTableLikeClause(str, obj);
3491                                 break;
3492                         case T_LockingClause:
3493                                 _outLockingClause(str, obj);
3494                                 break;
3495                         case T_XmlSerialize:
3496                                 _outXmlSerialize(str, obj);
3497                                 break;
3498
3499                         default:
3500
3501                                 /*
3502                                  * This should be an ERROR, but it's too useful to be able to
3503                                  * dump structures that _outNode only understands part of.
3504                                  */
3505                                 elog(WARNING, "could not dump unrecognized node type: %d",
3506                                          (int) nodeTag(obj));
3507                                 break;
3508                 }
3509                 appendStringInfoChar(str, '}');
3510         }
3511 }
3512
3513 /*
3514  * nodeToString -
3515  *         returns the ascii representation of the Node as a palloc'd string
3516  */
3517 char *
3518 nodeToString(const void *obj)
3519 {
3520         StringInfoData str;
3521
3522         /* see stringinfo.h for an explanation of this maneuver */
3523         initStringInfo(&str);
3524         _outNode(&str, obj);
3525         return str.data;
3526 }