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