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