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