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