]> granicus.if.org Git - postgresql/blob - src/backend/nodes/outfuncs.c
a1ed403d79bda2e7b5449e7276cb1439967dc2fc
[postgresql] / src / backend / nodes / outfuncs.c
1 /*-------------------------------------------------------------------------
2  *
3  * outfuncs.c
4  *        Output functions for Postgres tree nodes.
5  *
6  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.282 2006/08/12 02:52:04 tgl Exp $
12  *
13  * NOTES
14  *        Every node type that can appear in stored rules' parsetrees *must*
15  *        have an output function defined here (as well as an input function
16  *        in readfuncs.c).      For use in debugging, we also provide output
17  *        functions for nodes that appear in raw parsetrees, path, and plan trees.
18  *        These nodes however need not have input functions.
19  *
20  *-------------------------------------------------------------------------
21  */
22 #include "postgres.h"
23
24 #include <ctype.h>
25
26 #include "lib/stringinfo.h"
27 #include "nodes/plannodes.h"
28 #include "nodes/relation.h"
29 #include "utils/datum.h"
30
31
32 /*
33  * Macros to simplify output of different kinds of fields.      Use these
34  * wherever possible to reduce the chance for silly typos.      Note that these
35  * hard-wire conventions about the names of the local variables in an Out
36  * routine.
37  */
38
39 /* Write the label for the node type */
40 #define WRITE_NODE_TYPE(nodelabel) \
41         appendStringInfoString(str, nodelabel)
42
43 /* Write an integer field (anything written as ":fldname %d") */
44 #define WRITE_INT_FIELD(fldname) \
45         appendStringInfo(str, " :" CppAsString(fldname) " %d", node->fldname)
46
47 /* Write an unsigned integer field (anything written as ":fldname %u") */
48 #define WRITE_UINT_FIELD(fldname) \
49         appendStringInfo(str, " :" CppAsString(fldname) " %u", node->fldname)
50
51 /* Write an OID field (don't hard-wire assumption that OID is same as uint) */
52 #define WRITE_OID_FIELD(fldname) \
53         appendStringInfo(str, " :" CppAsString(fldname) " %u", node->fldname)
54
55 /* Write a long-integer field */
56 #define WRITE_LONG_FIELD(fldname) \
57         appendStringInfo(str, " :" CppAsString(fldname) " %ld", node->fldname)
58
59 /* Write a char field (ie, one ascii character) */
60 #define WRITE_CHAR_FIELD(fldname) \
61         appendStringInfo(str, " :" CppAsString(fldname) " %c", node->fldname)
62
63 /* Write an enumerated-type field as an integer code */
64 #define WRITE_ENUM_FIELD(fldname, enumtype) \
65         appendStringInfo(str, " :" CppAsString(fldname) " %d", \
66                                          (int) node->fldname)
67
68 /* Write a float field --- caller must give format to define precision */
69 #define WRITE_FLOAT_FIELD(fldname,format) \
70         appendStringInfo(str, " :" CppAsString(fldname) " " format, node->fldname)
71
72 /* Write a boolean field */
73 #define WRITE_BOOL_FIELD(fldname) \
74         appendStringInfo(str, " :" CppAsString(fldname) " %s", \
75                                          booltostr(node->fldname))
76
77 /* Write a character-string (possibly NULL) field */
78 #define WRITE_STRING_FIELD(fldname) \
79         (appendStringInfo(str, " :" CppAsString(fldname) " "), \
80          _outToken(str, node->fldname))
81
82 /* Write a Node field */
83 #define WRITE_NODE_FIELD(fldname) \
84         (appendStringInfo(str, " :" CppAsString(fldname) " "), \
85          _outNode(str, node->fldname))
86
87 /* Write a bitmapset field */
88 #define WRITE_BITMAPSET_FIELD(fldname) \
89         (appendStringInfo(str, " :" CppAsString(fldname) " "), \
90          _outBitmapset(str, node->fldname))
91
92
93 #define booltostr(x)  ((x) ? "true" : "false")
94
95 static void _outNode(StringInfo str, void *obj);
96
97
98 /*
99  * _outToken
100  *        Convert an ordinary string (eg, an identifier) into a form that
101  *        will be decoded back to a plain token by read.c's functions.
102  *
103  *        If a null or empty string is given, it is encoded as "<>".
104  */
105 static void
106 _outToken(StringInfo str, char *s)
107 {
108         if (s == NULL || *s == '\0')
109         {
110                 appendStringInfo(str, "<>");
111                 return;
112         }
113
114         /*
115          * Look for characters or patterns that are treated specially by read.c
116          * (either in pg_strtok() or in nodeRead()), and therefore need a
117          * protective backslash.
118          */
119         /* These characters only need to be quoted at the start of the string */
120         if (*s == '<' ||
121                 *s == '\"' ||
122                 isdigit((unsigned char) *s) ||
123                 ((*s == '+' || *s == '-') &&
124                  (isdigit((unsigned char) s[1]) || s[1] == '.')))
125                 appendStringInfoChar(str, '\\');
126         while (*s)
127         {
128                 /* These chars must be backslashed anywhere in the string */
129                 if (*s == ' ' || *s == '\n' || *s == '\t' ||
130                         *s == '(' || *s == ')' || *s == '{' || *s == '}' ||
131                         *s == '\\')
132                         appendStringInfoChar(str, '\\');
133                 appendStringInfoChar(str, *s++);
134         }
135 }
136
137 static void
138 _outList(StringInfo str, List *node)
139 {
140         ListCell   *lc;
141
142         appendStringInfoChar(str, '(');
143
144         if (IsA(node, IntList))
145                 appendStringInfoChar(str, 'i');
146         else if (IsA(node, OidList))
147                 appendStringInfoChar(str, 'o');
148
149         foreach(lc, node)
150         {
151                 /*
152                  * For the sake of backward compatibility, we emit a slightly
153                  * different whitespace format for lists of nodes vs. other types of
154                  * lists. XXX: is this necessary?
155                  */
156                 if (IsA(node, List))
157                 {
158                         _outNode(str, lfirst(lc));
159                         if (lnext(lc))
160                                 appendStringInfoChar(str, ' ');
161                 }
162                 else if (IsA(node, IntList))
163                         appendStringInfo(str, " %d", lfirst_int(lc));
164                 else if (IsA(node, OidList))
165                         appendStringInfo(str, " %u", lfirst_oid(lc));
166                 else
167                         elog(ERROR, "unrecognized list node type: %d",
168                                  (int) node->type);
169         }
170
171         appendStringInfoChar(str, ')');
172 }
173
174 /*
175  * _outBitmapset -
176  *         converts a bitmap set of integers
177  *
178  * Note: the output format is "(b int int ...)", similar to an integer List.
179  * Currently bitmapsets do not appear in any node type that is stored in
180  * rules, so there is no support in readfuncs.c for reading this format.
181  */
182 static void
183 _outBitmapset(StringInfo str, Bitmapset *bms)
184 {
185         Bitmapset  *tmpset;
186         int                     x;
187
188         appendStringInfoChar(str, '(');
189         appendStringInfoChar(str, 'b');
190         tmpset = bms_copy(bms);
191         while ((x = bms_first_member(tmpset)) >= 0)
192                 appendStringInfo(str, " %d", x);
193         bms_free(tmpset);
194         appendStringInfoChar(str, ')');
195 }
196
197 /*
198  * Print the value of a Datum given its type.
199  */
200 static void
201 _outDatum(StringInfo str, Datum value, int typlen, bool typbyval)
202 {
203         Size            length,
204                                 i;
205         char       *s;
206
207         length = datumGetSize(value, typbyval, typlen);
208
209         if (typbyval)
210         {
211                 s = (char *) (&value);
212                 appendStringInfo(str, "%u [ ", (unsigned int) length);
213                 for (i = 0; i < (Size) sizeof(Datum); i++)
214                         appendStringInfo(str, "%d ", (int) (s[i]));
215                 appendStringInfo(str, "]");
216         }
217         else
218         {
219                 s = (char *) DatumGetPointer(value);
220                 if (!PointerIsValid(s))
221                         appendStringInfo(str, "0 [ ]");
222                 else
223                 {
224                         appendStringInfo(str, "%u [ ", (unsigned int) length);
225                         for (i = 0; i < length; i++)
226                                 appendStringInfo(str, "%d ", (int) (s[i]));
227                         appendStringInfo(str, "]");
228                 }
229         }
230 }
231
232
233 /*
234  *      Stuff from plannodes.h
235  */
236
237 /*
238  * print the basic stuff of all nodes that inherit from Plan
239  */
240 static void
241 _outPlanInfo(StringInfo str, Plan *node)
242 {
243         WRITE_FLOAT_FIELD(startup_cost, "%.2f");
244         WRITE_FLOAT_FIELD(total_cost, "%.2f");
245         WRITE_FLOAT_FIELD(plan_rows, "%.0f");
246         WRITE_INT_FIELD(plan_width);
247         WRITE_NODE_FIELD(targetlist);
248         WRITE_NODE_FIELD(qual);
249         WRITE_NODE_FIELD(lefttree);
250         WRITE_NODE_FIELD(righttree);
251         WRITE_NODE_FIELD(initPlan);
252         WRITE_BITMAPSET_FIELD(extParam);
253         WRITE_BITMAPSET_FIELD(allParam);
254         WRITE_INT_FIELD(nParamExec);
255 }
256
257 /*
258  * print the basic stuff of all nodes that inherit from Scan
259  */
260 static void
261 _outScanInfo(StringInfo str, Scan *node)
262 {
263         _outPlanInfo(str, (Plan *) node);
264
265         WRITE_UINT_FIELD(scanrelid);
266 }
267
268 /*
269  * print the basic stuff of all nodes that inherit from Join
270  */
271 static void
272 _outJoinPlanInfo(StringInfo str, Join *node)
273 {
274         _outPlanInfo(str, (Plan *) node);
275
276         WRITE_ENUM_FIELD(jointype, JoinType);
277         WRITE_NODE_FIELD(joinqual);
278 }
279
280
281 static void
282 _outPlan(StringInfo str, Plan *node)
283 {
284         WRITE_NODE_TYPE("PLAN");
285
286         _outPlanInfo(str, (Plan *) node);
287 }
288
289 static void
290 _outResult(StringInfo str, Result *node)
291 {
292         WRITE_NODE_TYPE("RESULT");
293
294         _outPlanInfo(str, (Plan *) node);
295
296         WRITE_NODE_FIELD(resconstantqual);
297 }
298
299 static void
300 _outAppend(StringInfo str, Append *node)
301 {
302         WRITE_NODE_TYPE("APPEND");
303
304         _outPlanInfo(str, (Plan *) node);
305
306         WRITE_NODE_FIELD(appendplans);
307         WRITE_BOOL_FIELD(isTarget);
308 }
309
310 static void
311 _outBitmapAnd(StringInfo str, BitmapAnd *node)
312 {
313         WRITE_NODE_TYPE("BITMAPAND");
314
315         _outPlanInfo(str, (Plan *) node);
316
317         WRITE_NODE_FIELD(bitmapplans);
318 }
319
320 static void
321 _outBitmapOr(StringInfo str, BitmapOr *node)
322 {
323         WRITE_NODE_TYPE("BITMAPOR");
324
325         _outPlanInfo(str, (Plan *) node);
326
327         WRITE_NODE_FIELD(bitmapplans);
328 }
329
330 static void
331 _outScan(StringInfo str, Scan *node)
332 {
333         WRITE_NODE_TYPE("SCAN");
334
335         _outScanInfo(str, (Scan *) node);
336 }
337
338 static void
339 _outSeqScan(StringInfo str, SeqScan *node)
340 {
341         WRITE_NODE_TYPE("SEQSCAN");
342
343         _outScanInfo(str, (Scan *) node);
344 }
345
346 static void
347 _outIndexScan(StringInfo str, IndexScan *node)
348 {
349         WRITE_NODE_TYPE("INDEXSCAN");
350
351         _outScanInfo(str, (Scan *) node);
352
353         WRITE_OID_FIELD(indexid);
354         WRITE_NODE_FIELD(indexqual);
355         WRITE_NODE_FIELD(indexqualorig);
356         WRITE_NODE_FIELD(indexstrategy);
357         WRITE_NODE_FIELD(indexsubtype);
358         WRITE_ENUM_FIELD(indexorderdir, ScanDirection);
359 }
360
361 static void
362 _outBitmapIndexScan(StringInfo str, BitmapIndexScan *node)
363 {
364         WRITE_NODE_TYPE("BITMAPINDEXSCAN");
365
366         _outScanInfo(str, (Scan *) node);
367
368         WRITE_OID_FIELD(indexid);
369         WRITE_NODE_FIELD(indexqual);
370         WRITE_NODE_FIELD(indexqualorig);
371         WRITE_NODE_FIELD(indexstrategy);
372         WRITE_NODE_FIELD(indexsubtype);
373 }
374
375 static void
376 _outBitmapHeapScan(StringInfo str, BitmapHeapScan *node)
377 {
378         WRITE_NODE_TYPE("BITMAPHEAPSCAN");
379
380         _outScanInfo(str, (Scan *) node);
381
382         WRITE_NODE_FIELD(bitmapqualorig);
383 }
384
385 static void
386 _outTidScan(StringInfo str, TidScan *node)
387 {
388         WRITE_NODE_TYPE("TIDSCAN");
389
390         _outScanInfo(str, (Scan *) node);
391
392         WRITE_NODE_FIELD(tidquals);
393 }
394
395 static void
396 _outSubqueryScan(StringInfo str, SubqueryScan *node)
397 {
398         WRITE_NODE_TYPE("SUBQUERYSCAN");
399
400         _outScanInfo(str, (Scan *) node);
401
402         WRITE_NODE_FIELD(subplan);
403 }
404
405 static void
406 _outFunctionScan(StringInfo str, FunctionScan *node)
407 {
408         WRITE_NODE_TYPE("FUNCTIONSCAN");
409
410         _outScanInfo(str, (Scan *) node);
411 }
412
413 static void
414 _outValuesScan(StringInfo str, ValuesScan *node)
415 {
416         WRITE_NODE_TYPE("VALUESSCAN");
417
418         _outScanInfo(str, (Scan *) node);
419 }
420
421 static void
422 _outJoin(StringInfo str, Join *node)
423 {
424         WRITE_NODE_TYPE("JOIN");
425
426         _outJoinPlanInfo(str, (Join *) node);
427 }
428
429 static void
430 _outNestLoop(StringInfo str, NestLoop *node)
431 {
432         WRITE_NODE_TYPE("NESTLOOP");
433
434         _outJoinPlanInfo(str, (Join *) node);
435 }
436
437 static void
438 _outMergeJoin(StringInfo str, MergeJoin *node)
439 {
440         WRITE_NODE_TYPE("MERGEJOIN");
441
442         _outJoinPlanInfo(str, (Join *) node);
443
444         WRITE_NODE_FIELD(mergeclauses);
445 }
446
447 static void
448 _outHashJoin(StringInfo str, HashJoin *node)
449 {
450         WRITE_NODE_TYPE("HASHJOIN");
451
452         _outJoinPlanInfo(str, (Join *) node);
453
454         WRITE_NODE_FIELD(hashclauses);
455 }
456
457 static void
458 _outAgg(StringInfo str, Agg *node)
459 {
460         WRITE_NODE_TYPE("AGG");
461
462         _outPlanInfo(str, (Plan *) node);
463
464         WRITE_ENUM_FIELD(aggstrategy, AggStrategy);
465         WRITE_INT_FIELD(numCols);
466         WRITE_LONG_FIELD(numGroups);
467 }
468
469 static void
470 _outGroup(StringInfo str, Group *node)
471 {
472         int                     i;
473
474         WRITE_NODE_TYPE("GROUP");
475
476         _outPlanInfo(str, (Plan *) node);
477
478         WRITE_INT_FIELD(numCols);
479
480         appendStringInfo(str, " :grpColIdx");
481         for (i = 0; i < node->numCols; i++)
482                 appendStringInfo(str, " %d", node->grpColIdx[i]);
483 }
484
485 static void
486 _outMaterial(StringInfo str, Material *node)
487 {
488         WRITE_NODE_TYPE("MATERIAL");
489
490         _outPlanInfo(str, (Plan *) node);
491 }
492
493 static void
494 _outSort(StringInfo str, Sort *node)
495 {
496         int                     i;
497
498         WRITE_NODE_TYPE("SORT");
499
500         _outPlanInfo(str, (Plan *) node);
501
502         WRITE_INT_FIELD(numCols);
503
504         appendStringInfo(str, " :sortColIdx");
505         for (i = 0; i < node->numCols; i++)
506                 appendStringInfo(str, " %d", node->sortColIdx[i]);
507
508         appendStringInfo(str, " :sortOperators");
509         for (i = 0; i < node->numCols; i++)
510                 appendStringInfo(str, " %u", node->sortOperators[i]);
511 }
512
513 static void
514 _outUnique(StringInfo str, Unique *node)
515 {
516         int                     i;
517
518         WRITE_NODE_TYPE("UNIQUE");
519
520         _outPlanInfo(str, (Plan *) node);
521
522         WRITE_INT_FIELD(numCols);
523
524         appendStringInfo(str, " :uniqColIdx");
525         for (i = 0; i < node->numCols; i++)
526                 appendStringInfo(str, " %d", node->uniqColIdx[i]);
527 }
528
529 static void
530 _outSetOp(StringInfo str, SetOp *node)
531 {
532         int                     i;
533
534         WRITE_NODE_TYPE("SETOP");
535
536         _outPlanInfo(str, (Plan *) node);
537
538         WRITE_ENUM_FIELD(cmd, SetOpCmd);
539         WRITE_INT_FIELD(numCols);
540
541         appendStringInfo(str, " :dupColIdx");
542         for (i = 0; i < node->numCols; i++)
543                 appendStringInfo(str, " %d", node->dupColIdx[i]);
544
545         WRITE_INT_FIELD(flagColIdx);
546 }
547
548 static void
549 _outLimit(StringInfo str, Limit *node)
550 {
551         WRITE_NODE_TYPE("LIMIT");
552
553         _outPlanInfo(str, (Plan *) node);
554
555         WRITE_NODE_FIELD(limitOffset);
556         WRITE_NODE_FIELD(limitCount);
557 }
558
559 static void
560 _outHash(StringInfo str, Hash *node)
561 {
562         WRITE_NODE_TYPE("HASH");
563
564         _outPlanInfo(str, (Plan *) node);
565 }
566
567 /*****************************************************************************
568  *
569  *      Stuff from primnodes.h.
570  *
571  *****************************************************************************/
572
573 static void
574 _outAlias(StringInfo str, Alias *node)
575 {
576         WRITE_NODE_TYPE("ALIAS");
577
578         WRITE_STRING_FIELD(aliasname);
579         WRITE_NODE_FIELD(colnames);
580 }
581
582 static void
583 _outRangeVar(StringInfo str, RangeVar *node)
584 {
585         WRITE_NODE_TYPE("RANGEVAR");
586
587         /*
588          * we deliberately ignore catalogname here, since it is presently not
589          * semantically meaningful
590          */
591         WRITE_STRING_FIELD(schemaname);
592         WRITE_STRING_FIELD(relname);
593         WRITE_ENUM_FIELD(inhOpt, InhOption);
594         WRITE_BOOL_FIELD(istemp);
595         WRITE_NODE_FIELD(alias);
596 }
597
598 static void
599 _outVar(StringInfo str, Var *node)
600 {
601         WRITE_NODE_TYPE("VAR");
602
603         WRITE_UINT_FIELD(varno);
604         WRITE_INT_FIELD(varattno);
605         WRITE_OID_FIELD(vartype);
606         WRITE_INT_FIELD(vartypmod);
607         WRITE_UINT_FIELD(varlevelsup);
608         WRITE_UINT_FIELD(varnoold);
609         WRITE_INT_FIELD(varoattno);
610 }
611
612 static void
613 _outConst(StringInfo str, Const *node)
614 {
615         WRITE_NODE_TYPE("CONST");
616
617         WRITE_OID_FIELD(consttype);
618         WRITE_INT_FIELD(constlen);
619         WRITE_BOOL_FIELD(constbyval);
620         WRITE_BOOL_FIELD(constisnull);
621
622         appendStringInfo(str, " :constvalue ");
623         if (node->constisnull)
624                 appendStringInfo(str, "<>");
625         else
626                 _outDatum(str, node->constvalue, node->constlen, node->constbyval);
627 }
628
629 static void
630 _outParam(StringInfo str, Param *node)
631 {
632         WRITE_NODE_TYPE("PARAM");
633
634         WRITE_ENUM_FIELD(paramkind, ParamKind);
635         WRITE_INT_FIELD(paramid);
636         WRITE_OID_FIELD(paramtype);
637 }
638
639 static void
640 _outAggref(StringInfo str, Aggref *node)
641 {
642         WRITE_NODE_TYPE("AGGREF");
643
644         WRITE_OID_FIELD(aggfnoid);
645         WRITE_OID_FIELD(aggtype);
646         WRITE_NODE_FIELD(args);
647         WRITE_UINT_FIELD(agglevelsup);
648         WRITE_BOOL_FIELD(aggstar);
649         WRITE_BOOL_FIELD(aggdistinct);
650 }
651
652 static void
653 _outArrayRef(StringInfo str, ArrayRef *node)
654 {
655         WRITE_NODE_TYPE("ARRAYREF");
656
657         WRITE_OID_FIELD(refrestype);
658         WRITE_OID_FIELD(refarraytype);
659         WRITE_OID_FIELD(refelemtype);
660         WRITE_NODE_FIELD(refupperindexpr);
661         WRITE_NODE_FIELD(reflowerindexpr);
662         WRITE_NODE_FIELD(refexpr);
663         WRITE_NODE_FIELD(refassgnexpr);
664 }
665
666 static void
667 _outFuncExpr(StringInfo str, FuncExpr *node)
668 {
669         WRITE_NODE_TYPE("FUNCEXPR");
670
671         WRITE_OID_FIELD(funcid);
672         WRITE_OID_FIELD(funcresulttype);
673         WRITE_BOOL_FIELD(funcretset);
674         WRITE_ENUM_FIELD(funcformat, CoercionForm);
675         WRITE_NODE_FIELD(args);
676 }
677
678 static void
679 _outOpExpr(StringInfo str, OpExpr *node)
680 {
681         WRITE_NODE_TYPE("OPEXPR");
682
683         WRITE_OID_FIELD(opno);
684         WRITE_OID_FIELD(opfuncid);
685         WRITE_OID_FIELD(opresulttype);
686         WRITE_BOOL_FIELD(opretset);
687         WRITE_NODE_FIELD(args);
688 }
689
690 static void
691 _outDistinctExpr(StringInfo str, DistinctExpr *node)
692 {
693         WRITE_NODE_TYPE("DISTINCTEXPR");
694
695         WRITE_OID_FIELD(opno);
696         WRITE_OID_FIELD(opfuncid);
697         WRITE_OID_FIELD(opresulttype);
698         WRITE_BOOL_FIELD(opretset);
699         WRITE_NODE_FIELD(args);
700 }
701
702 static void
703 _outScalarArrayOpExpr(StringInfo str, ScalarArrayOpExpr *node)
704 {
705         WRITE_NODE_TYPE("SCALARARRAYOPEXPR");
706
707         WRITE_OID_FIELD(opno);
708         WRITE_OID_FIELD(opfuncid);
709         WRITE_BOOL_FIELD(useOr);
710         WRITE_NODE_FIELD(args);
711 }
712
713 static void
714 _outBoolExpr(StringInfo str, BoolExpr *node)
715 {
716         char       *opstr = NULL;
717
718         WRITE_NODE_TYPE("BOOLEXPR");
719
720         /* do-it-yourself enum representation */
721         switch (node->boolop)
722         {
723                 case AND_EXPR:
724                         opstr = "and";
725                         break;
726                 case OR_EXPR:
727                         opstr = "or";
728                         break;
729                 case NOT_EXPR:
730                         opstr = "not";
731                         break;
732         }
733         appendStringInfo(str, " :boolop ");
734         _outToken(str, opstr);
735
736         WRITE_NODE_FIELD(args);
737 }
738
739 static void
740 _outSubLink(StringInfo str, SubLink *node)
741 {
742         WRITE_NODE_TYPE("SUBLINK");
743
744         WRITE_ENUM_FIELD(subLinkType, SubLinkType);
745         WRITE_NODE_FIELD(testexpr);
746         WRITE_NODE_FIELD(operName);
747         WRITE_NODE_FIELD(subselect);
748 }
749
750 static void
751 _outSubPlan(StringInfo str, SubPlan *node)
752 {
753         WRITE_NODE_TYPE("SUBPLAN");
754
755         WRITE_ENUM_FIELD(subLinkType, SubLinkType);
756         WRITE_NODE_FIELD(testexpr);
757         WRITE_NODE_FIELD(paramIds);
758         WRITE_NODE_FIELD(plan);
759         WRITE_INT_FIELD(plan_id);
760         WRITE_NODE_FIELD(rtable);
761         WRITE_BOOL_FIELD(useHashTable);
762         WRITE_BOOL_FIELD(unknownEqFalse);
763         WRITE_NODE_FIELD(setParam);
764         WRITE_NODE_FIELD(parParam);
765         WRITE_NODE_FIELD(args);
766 }
767
768 static void
769 _outFieldSelect(StringInfo str, FieldSelect *node)
770 {
771         WRITE_NODE_TYPE("FIELDSELECT");
772
773         WRITE_NODE_FIELD(arg);
774         WRITE_INT_FIELD(fieldnum);
775         WRITE_OID_FIELD(resulttype);
776         WRITE_INT_FIELD(resulttypmod);
777 }
778
779 static void
780 _outFieldStore(StringInfo str, FieldStore *node)
781 {
782         WRITE_NODE_TYPE("FIELDSTORE");
783
784         WRITE_NODE_FIELD(arg);
785         WRITE_NODE_FIELD(newvals);
786         WRITE_NODE_FIELD(fieldnums);
787         WRITE_OID_FIELD(resulttype);
788 }
789
790 static void
791 _outRelabelType(StringInfo str, RelabelType *node)
792 {
793         WRITE_NODE_TYPE("RELABELTYPE");
794
795         WRITE_NODE_FIELD(arg);
796         WRITE_OID_FIELD(resulttype);
797         WRITE_INT_FIELD(resulttypmod);
798         WRITE_ENUM_FIELD(relabelformat, CoercionForm);
799 }
800
801 static void
802 _outConvertRowtypeExpr(StringInfo str, ConvertRowtypeExpr *node)
803 {
804         WRITE_NODE_TYPE("CONVERTROWTYPEEXPR");
805
806         WRITE_NODE_FIELD(arg);
807         WRITE_OID_FIELD(resulttype);
808         WRITE_ENUM_FIELD(convertformat, CoercionForm);
809 }
810
811 static void
812 _outCaseExpr(StringInfo str, CaseExpr *node)
813 {
814         WRITE_NODE_TYPE("CASE");
815
816         WRITE_OID_FIELD(casetype);
817         WRITE_NODE_FIELD(arg);
818         WRITE_NODE_FIELD(args);
819         WRITE_NODE_FIELD(defresult);
820 }
821
822 static void
823 _outCaseWhen(StringInfo str, CaseWhen *node)
824 {
825         WRITE_NODE_TYPE("WHEN");
826
827         WRITE_NODE_FIELD(expr);
828         WRITE_NODE_FIELD(result);
829 }
830
831 static void
832 _outCaseTestExpr(StringInfo str, CaseTestExpr *node)
833 {
834         WRITE_NODE_TYPE("CASETESTEXPR");
835
836         WRITE_OID_FIELD(typeId);
837         WRITE_INT_FIELD(typeMod);
838 }
839
840 static void
841 _outArrayExpr(StringInfo str, ArrayExpr *node)
842 {
843         WRITE_NODE_TYPE("ARRAY");
844
845         WRITE_OID_FIELD(array_typeid);
846         WRITE_OID_FIELD(element_typeid);
847         WRITE_NODE_FIELD(elements);
848         WRITE_BOOL_FIELD(multidims);
849 }
850
851 static void
852 _outRowExpr(StringInfo str, RowExpr *node)
853 {
854         WRITE_NODE_TYPE("ROW");
855
856         WRITE_NODE_FIELD(args);
857         WRITE_OID_FIELD(row_typeid);
858         WRITE_ENUM_FIELD(row_format, CoercionForm);
859 }
860
861 static void
862 _outRowCompareExpr(StringInfo str, RowCompareExpr *node)
863 {
864         WRITE_NODE_TYPE("ROWCOMPARE");
865
866         WRITE_ENUM_FIELD(rctype, RowCompareType);
867         WRITE_NODE_FIELD(opnos);
868         WRITE_NODE_FIELD(opclasses);
869         WRITE_NODE_FIELD(largs);
870         WRITE_NODE_FIELD(rargs);
871 }
872
873 static void
874 _outCoalesceExpr(StringInfo str, CoalesceExpr *node)
875 {
876         WRITE_NODE_TYPE("COALESCE");
877
878         WRITE_OID_FIELD(coalescetype);
879         WRITE_NODE_FIELD(args);
880 }
881
882 static void
883 _outMinMaxExpr(StringInfo str, MinMaxExpr *node)
884 {
885         WRITE_NODE_TYPE("MINMAX");
886
887         WRITE_OID_FIELD(minmaxtype);
888         WRITE_ENUM_FIELD(op, MinMaxOp);
889         WRITE_NODE_FIELD(args);
890 }
891
892 static void
893 _outNullIfExpr(StringInfo str, NullIfExpr *node)
894 {
895         WRITE_NODE_TYPE("NULLIFEXPR");
896
897         WRITE_OID_FIELD(opno);
898         WRITE_OID_FIELD(opfuncid);
899         WRITE_OID_FIELD(opresulttype);
900         WRITE_BOOL_FIELD(opretset);
901         WRITE_NODE_FIELD(args);
902 }
903
904 static void
905 _outNullTest(StringInfo str, NullTest *node)
906 {
907         WRITE_NODE_TYPE("NULLTEST");
908
909         WRITE_NODE_FIELD(arg);
910         WRITE_ENUM_FIELD(nulltesttype, NullTestType);
911 }
912
913 static void
914 _outBooleanTest(StringInfo str, BooleanTest *node)
915 {
916         WRITE_NODE_TYPE("BOOLEANTEST");
917
918         WRITE_NODE_FIELD(arg);
919         WRITE_ENUM_FIELD(booltesttype, BoolTestType);
920 }
921
922 static void
923 _outCoerceToDomain(StringInfo str, CoerceToDomain *node)
924 {
925         WRITE_NODE_TYPE("COERCETODOMAIN");
926
927         WRITE_NODE_FIELD(arg);
928         WRITE_OID_FIELD(resulttype);
929         WRITE_INT_FIELD(resulttypmod);
930         WRITE_ENUM_FIELD(coercionformat, CoercionForm);
931 }
932
933 static void
934 _outCoerceToDomainValue(StringInfo str, CoerceToDomainValue *node)
935 {
936         WRITE_NODE_TYPE("COERCETODOMAINVALUE");
937
938         WRITE_OID_FIELD(typeId);
939         WRITE_INT_FIELD(typeMod);
940 }
941
942 static void
943 _outSetToDefault(StringInfo str, SetToDefault *node)
944 {
945         WRITE_NODE_TYPE("SETTODEFAULT");
946
947         WRITE_OID_FIELD(typeId);
948         WRITE_INT_FIELD(typeMod);
949 }
950
951 static void
952 _outTargetEntry(StringInfo str, TargetEntry *node)
953 {
954         WRITE_NODE_TYPE("TARGETENTRY");
955
956         WRITE_NODE_FIELD(expr);
957         WRITE_INT_FIELD(resno);
958         WRITE_STRING_FIELD(resname);
959         WRITE_UINT_FIELD(ressortgroupref);
960         WRITE_OID_FIELD(resorigtbl);
961         WRITE_INT_FIELD(resorigcol);
962         WRITE_BOOL_FIELD(resjunk);
963 }
964
965 static void
966 _outRangeTblRef(StringInfo str, RangeTblRef *node)
967 {
968         WRITE_NODE_TYPE("RANGETBLREF");
969
970         WRITE_INT_FIELD(rtindex);
971 }
972
973 static void
974 _outJoinExpr(StringInfo str, JoinExpr *node)
975 {
976         WRITE_NODE_TYPE("JOINEXPR");
977
978         WRITE_ENUM_FIELD(jointype, JoinType);
979         WRITE_BOOL_FIELD(isNatural);
980         WRITE_NODE_FIELD(larg);
981         WRITE_NODE_FIELD(rarg);
982         WRITE_NODE_FIELD(using);
983         WRITE_NODE_FIELD(quals);
984         WRITE_NODE_FIELD(alias);
985         WRITE_INT_FIELD(rtindex);
986 }
987
988 static void
989 _outFromExpr(StringInfo str, FromExpr *node)
990 {
991         WRITE_NODE_TYPE("FROMEXPR");
992
993         WRITE_NODE_FIELD(fromlist);
994         WRITE_NODE_FIELD(quals);
995 }
996
997 /*****************************************************************************
998  *
999  *      Stuff from relation.h.
1000  *
1001  *****************************************************************************/
1002
1003 /*
1004  * print the basic stuff of all nodes that inherit from Path
1005  *
1006  * Note we do NOT print the parent, else we'd be in infinite recursion
1007  */
1008 static void
1009 _outPathInfo(StringInfo str, Path *node)
1010 {
1011         WRITE_ENUM_FIELD(pathtype, NodeTag);
1012         WRITE_FLOAT_FIELD(startup_cost, "%.2f");
1013         WRITE_FLOAT_FIELD(total_cost, "%.2f");
1014         WRITE_NODE_FIELD(pathkeys);
1015 }
1016
1017 /*
1018  * print the basic stuff of all nodes that inherit from JoinPath
1019  */
1020 static void
1021 _outJoinPathInfo(StringInfo str, JoinPath *node)
1022 {
1023         _outPathInfo(str, (Path *) node);
1024
1025         WRITE_ENUM_FIELD(jointype, JoinType);
1026         WRITE_NODE_FIELD(outerjoinpath);
1027         WRITE_NODE_FIELD(innerjoinpath);
1028         WRITE_NODE_FIELD(joinrestrictinfo);
1029 }
1030
1031 static void
1032 _outPath(StringInfo str, Path *node)
1033 {
1034         WRITE_NODE_TYPE("PATH");
1035
1036         _outPathInfo(str, (Path *) node);
1037 }
1038
1039 static void
1040 _outIndexPath(StringInfo str, IndexPath *node)
1041 {
1042         WRITE_NODE_TYPE("INDEXPATH");
1043
1044         _outPathInfo(str, (Path *) node);
1045
1046         WRITE_NODE_FIELD(indexinfo);
1047         WRITE_NODE_FIELD(indexclauses);
1048         WRITE_NODE_FIELD(indexquals);
1049         WRITE_BOOL_FIELD(isjoininner);
1050         WRITE_ENUM_FIELD(indexscandir, ScanDirection);
1051         WRITE_FLOAT_FIELD(indextotalcost, "%.2f");
1052         WRITE_FLOAT_FIELD(indexselectivity, "%.4f");
1053         WRITE_FLOAT_FIELD(rows, "%.0f");
1054 }
1055
1056 static void
1057 _outBitmapHeapPath(StringInfo str, BitmapHeapPath *node)
1058 {
1059         WRITE_NODE_TYPE("BITMAPHEAPPATH");
1060
1061         _outPathInfo(str, (Path *) node);
1062
1063         WRITE_NODE_FIELD(bitmapqual);
1064         WRITE_BOOL_FIELD(isjoininner);
1065         WRITE_FLOAT_FIELD(rows, "%.0f");
1066 }
1067
1068 static void
1069 _outBitmapAndPath(StringInfo str, BitmapAndPath *node)
1070 {
1071         WRITE_NODE_TYPE("BITMAPANDPATH");
1072
1073         _outPathInfo(str, (Path *) node);
1074
1075         WRITE_NODE_FIELD(bitmapquals);
1076         WRITE_FLOAT_FIELD(bitmapselectivity, "%.4f");
1077 }
1078
1079 static void
1080 _outBitmapOrPath(StringInfo str, BitmapOrPath *node)
1081 {
1082         WRITE_NODE_TYPE("BITMAPORPATH");
1083
1084         _outPathInfo(str, (Path *) node);
1085
1086         WRITE_NODE_FIELD(bitmapquals);
1087         WRITE_FLOAT_FIELD(bitmapselectivity, "%.4f");
1088 }
1089
1090 static void
1091 _outTidPath(StringInfo str, TidPath *node)
1092 {
1093         WRITE_NODE_TYPE("TIDPATH");
1094
1095         _outPathInfo(str, (Path *) node);
1096
1097         WRITE_NODE_FIELD(tidquals);
1098 }
1099
1100 static void
1101 _outAppendPath(StringInfo str, AppendPath *node)
1102 {
1103         WRITE_NODE_TYPE("APPENDPATH");
1104
1105         _outPathInfo(str, (Path *) node);
1106
1107         WRITE_NODE_FIELD(subpaths);
1108 }
1109
1110 static void
1111 _outResultPath(StringInfo str, ResultPath *node)
1112 {
1113         WRITE_NODE_TYPE("RESULTPATH");
1114
1115         _outPathInfo(str, (Path *) node);
1116
1117         WRITE_NODE_FIELD(quals);
1118 }
1119
1120 static void
1121 _outMaterialPath(StringInfo str, MaterialPath *node)
1122 {
1123         WRITE_NODE_TYPE("MATERIALPATH");
1124
1125         _outPathInfo(str, (Path *) node);
1126
1127         WRITE_NODE_FIELD(subpath);
1128 }
1129
1130 static void
1131 _outUniquePath(StringInfo str, UniquePath *node)
1132 {
1133         WRITE_NODE_TYPE("UNIQUEPATH");
1134
1135         _outPathInfo(str, (Path *) node);
1136
1137         WRITE_NODE_FIELD(subpath);
1138         WRITE_ENUM_FIELD(umethod, UniquePathMethod);
1139         WRITE_FLOAT_FIELD(rows, "%.0f");
1140 }
1141
1142 static void
1143 _outNestPath(StringInfo str, NestPath *node)
1144 {
1145         WRITE_NODE_TYPE("NESTPATH");
1146
1147         _outJoinPathInfo(str, (JoinPath *) node);
1148 }
1149
1150 static void
1151 _outMergePath(StringInfo str, MergePath *node)
1152 {
1153         WRITE_NODE_TYPE("MERGEPATH");
1154
1155         _outJoinPathInfo(str, (JoinPath *) node);
1156
1157         WRITE_NODE_FIELD(path_mergeclauses);
1158         WRITE_NODE_FIELD(outersortkeys);
1159         WRITE_NODE_FIELD(innersortkeys);
1160 }
1161
1162 static void
1163 _outHashPath(StringInfo str, HashPath *node)
1164 {
1165         WRITE_NODE_TYPE("HASHPATH");
1166
1167         _outJoinPathInfo(str, (JoinPath *) node);
1168
1169         WRITE_NODE_FIELD(path_hashclauses);
1170 }
1171
1172 static void
1173 _outPlannerInfo(StringInfo str, PlannerInfo *node)
1174 {
1175         WRITE_NODE_TYPE("PLANNERINFO");
1176
1177         /* NB: this isn't a complete set of fields */
1178         WRITE_NODE_FIELD(parse);
1179         WRITE_NODE_FIELD(join_rel_list);
1180         WRITE_NODE_FIELD(equi_key_list);
1181         WRITE_NODE_FIELD(left_join_clauses);
1182         WRITE_NODE_FIELD(right_join_clauses);
1183         WRITE_NODE_FIELD(full_join_clauses);
1184         WRITE_NODE_FIELD(oj_info_list);
1185         WRITE_NODE_FIELD(in_info_list);
1186         WRITE_NODE_FIELD(append_rel_list);
1187         WRITE_NODE_FIELD(query_pathkeys);
1188         WRITE_NODE_FIELD(group_pathkeys);
1189         WRITE_NODE_FIELD(sort_pathkeys);
1190         WRITE_FLOAT_FIELD(tuple_fraction, "%.4f");
1191         WRITE_BOOL_FIELD(hasJoinRTEs);
1192         WRITE_BOOL_FIELD(hasOuterJoins);
1193         WRITE_BOOL_FIELD(hasHavingQual);
1194         WRITE_BOOL_FIELD(hasPseudoConstantQuals);
1195 }
1196
1197 static void
1198 _outRelOptInfo(StringInfo str, RelOptInfo *node)
1199 {
1200         WRITE_NODE_TYPE("RELOPTINFO");
1201
1202         /* NB: this isn't a complete set of fields */
1203         WRITE_ENUM_FIELD(reloptkind, RelOptKind);
1204         WRITE_BITMAPSET_FIELD(relids);
1205         WRITE_FLOAT_FIELD(rows, "%.0f");
1206         WRITE_INT_FIELD(width);
1207         WRITE_NODE_FIELD(reltargetlist);
1208         WRITE_NODE_FIELD(pathlist);
1209         WRITE_NODE_FIELD(cheapest_startup_path);
1210         WRITE_NODE_FIELD(cheapest_total_path);
1211         WRITE_NODE_FIELD(cheapest_unique_path);
1212         WRITE_UINT_FIELD(relid);
1213         WRITE_ENUM_FIELD(rtekind, RTEKind);
1214         WRITE_INT_FIELD(min_attr);
1215         WRITE_INT_FIELD(max_attr);
1216         WRITE_NODE_FIELD(indexlist);
1217         WRITE_UINT_FIELD(pages);
1218         WRITE_FLOAT_FIELD(tuples, "%.0f");
1219         WRITE_NODE_FIELD(subplan);
1220         WRITE_NODE_FIELD(baserestrictinfo);
1221         WRITE_NODE_FIELD(joininfo);
1222         WRITE_BITMAPSET_FIELD(index_outer_relids);
1223         WRITE_NODE_FIELD(index_inner_paths);
1224 }
1225
1226 static void
1227 _outIndexOptInfo(StringInfo str, IndexOptInfo *node)
1228 {
1229         WRITE_NODE_TYPE("INDEXOPTINFO");
1230
1231         /* NB: this isn't a complete set of fields */
1232         WRITE_OID_FIELD(indexoid);
1233         /* Do NOT print rel field, else infinite recursion */
1234         WRITE_UINT_FIELD(pages);
1235         WRITE_FLOAT_FIELD(tuples, "%.0f");
1236         WRITE_INT_FIELD(ncolumns);
1237         WRITE_NODE_FIELD(indexprs);
1238         WRITE_NODE_FIELD(indpred);
1239         WRITE_BOOL_FIELD(predOK);
1240         WRITE_BOOL_FIELD(unique);
1241 }
1242
1243 static void
1244 _outPathKeyItem(StringInfo str, PathKeyItem *node)
1245 {
1246         WRITE_NODE_TYPE("PATHKEYITEM");
1247
1248         WRITE_NODE_FIELD(key);
1249         WRITE_OID_FIELD(sortop);
1250 }
1251
1252 static void
1253 _outRestrictInfo(StringInfo str, RestrictInfo *node)
1254 {
1255         WRITE_NODE_TYPE("RESTRICTINFO");
1256
1257         /* NB: this isn't a complete set of fields */
1258         WRITE_NODE_FIELD(clause);
1259         WRITE_BOOL_FIELD(is_pushed_down);
1260         WRITE_BOOL_FIELD(outerjoin_delayed);
1261         WRITE_BOOL_FIELD(can_join);
1262         WRITE_BOOL_FIELD(pseudoconstant);
1263         WRITE_BITMAPSET_FIELD(clause_relids);
1264         WRITE_BITMAPSET_FIELD(required_relids);
1265         WRITE_BITMAPSET_FIELD(left_relids);
1266         WRITE_BITMAPSET_FIELD(right_relids);
1267         WRITE_NODE_FIELD(orclause);
1268         WRITE_OID_FIELD(mergejoinoperator);
1269         WRITE_OID_FIELD(left_sortop);
1270         WRITE_OID_FIELD(right_sortop);
1271         WRITE_NODE_FIELD(left_pathkey);
1272         WRITE_NODE_FIELD(right_pathkey);
1273         WRITE_OID_FIELD(hashjoinoperator);
1274 }
1275
1276 static void
1277 _outInnerIndexscanInfo(StringInfo str, InnerIndexscanInfo *node)
1278 {
1279         WRITE_NODE_TYPE("INNERINDEXSCANINFO");
1280         WRITE_BITMAPSET_FIELD(other_relids);
1281         WRITE_BOOL_FIELD(isouterjoin);
1282         WRITE_NODE_FIELD(best_innerpath);
1283 }
1284
1285 static void
1286 _outOuterJoinInfo(StringInfo str, OuterJoinInfo *node)
1287 {
1288         WRITE_NODE_TYPE("OUTERJOININFO");
1289
1290         WRITE_BITMAPSET_FIELD(min_lefthand);
1291         WRITE_BITMAPSET_FIELD(min_righthand);
1292         WRITE_BOOL_FIELD(is_full_join);
1293         WRITE_BOOL_FIELD(lhs_strict);
1294 }
1295
1296 static void
1297 _outInClauseInfo(StringInfo str, InClauseInfo *node)
1298 {
1299         WRITE_NODE_TYPE("INCLAUSEINFO");
1300
1301         WRITE_BITMAPSET_FIELD(lefthand);
1302         WRITE_BITMAPSET_FIELD(righthand);
1303         WRITE_NODE_FIELD(sub_targetlist);
1304 }
1305
1306 static void
1307 _outAppendRelInfo(StringInfo str, AppendRelInfo *node)
1308 {
1309         WRITE_NODE_TYPE("APPENDRELINFO");
1310
1311         WRITE_UINT_FIELD(parent_relid);
1312         WRITE_UINT_FIELD(child_relid);
1313         WRITE_OID_FIELD(parent_reltype);
1314         WRITE_OID_FIELD(child_reltype);
1315         WRITE_NODE_FIELD(col_mappings);
1316         WRITE_NODE_FIELD(translated_vars);
1317         WRITE_OID_FIELD(parent_reloid);
1318 }
1319
1320 /*****************************************************************************
1321  *
1322  *      Stuff from parsenodes.h.
1323  *
1324  *****************************************************************************/
1325
1326 static void
1327 _outCreateStmt(StringInfo str, CreateStmt *node)
1328 {
1329         WRITE_NODE_TYPE("CREATESTMT");
1330
1331         WRITE_NODE_FIELD(relation);
1332         WRITE_NODE_FIELD(tableElts);
1333         WRITE_NODE_FIELD(inhRelations);
1334         WRITE_NODE_FIELD(constraints);
1335         WRITE_NODE_FIELD(options);
1336         WRITE_ENUM_FIELD(oncommit, OnCommitAction);
1337         WRITE_STRING_FIELD(tablespacename);
1338 }
1339
1340 static void
1341 _outIndexStmt(StringInfo str, IndexStmt *node)
1342 {
1343         WRITE_NODE_TYPE("INDEXSTMT");
1344
1345         WRITE_STRING_FIELD(idxname);
1346         WRITE_NODE_FIELD(relation);
1347         WRITE_STRING_FIELD(accessMethod);
1348         WRITE_STRING_FIELD(tableSpace);
1349         WRITE_NODE_FIELD(indexParams);
1350         WRITE_NODE_FIELD(options);
1351         WRITE_NODE_FIELD(whereClause);
1352         WRITE_NODE_FIELD(rangetable);
1353         WRITE_BOOL_FIELD(unique);
1354         WRITE_BOOL_FIELD(primary);
1355         WRITE_BOOL_FIELD(isconstraint);
1356 }
1357
1358 static void
1359 _outNotifyStmt(StringInfo str, NotifyStmt *node)
1360 {
1361         WRITE_NODE_TYPE("NOTIFY");
1362
1363         WRITE_NODE_FIELD(relation);
1364 }
1365
1366 static void
1367 _outDeclareCursorStmt(StringInfo str, DeclareCursorStmt *node)
1368 {
1369         WRITE_NODE_TYPE("DECLARECURSOR");
1370
1371         WRITE_STRING_FIELD(portalname);
1372         WRITE_INT_FIELD(options);
1373         WRITE_NODE_FIELD(query);
1374 }
1375
1376 static void
1377 _outSelectStmt(StringInfo str, SelectStmt *node)
1378 {
1379         WRITE_NODE_TYPE("SELECT");
1380
1381         WRITE_NODE_FIELD(distinctClause);
1382         WRITE_NODE_FIELD(into);
1383         WRITE_NODE_FIELD(intoColNames);
1384         WRITE_NODE_FIELD(intoOptions);
1385         WRITE_ENUM_FIELD(intoOnCommit, OnCommitAction);
1386         WRITE_STRING_FIELD(intoTableSpaceName);
1387         WRITE_NODE_FIELD(targetList);
1388         WRITE_NODE_FIELD(fromClause);
1389         WRITE_NODE_FIELD(whereClause);
1390         WRITE_NODE_FIELD(groupClause);
1391         WRITE_NODE_FIELD(havingClause);
1392         WRITE_NODE_FIELD(valuesLists);
1393         WRITE_NODE_FIELD(sortClause);
1394         WRITE_NODE_FIELD(limitOffset);
1395         WRITE_NODE_FIELD(limitCount);
1396         WRITE_NODE_FIELD(lockingClause);
1397         WRITE_ENUM_FIELD(op, SetOperation);
1398         WRITE_BOOL_FIELD(all);
1399         WRITE_NODE_FIELD(larg);
1400         WRITE_NODE_FIELD(rarg);
1401 }
1402
1403 static void
1404 _outFuncCall(StringInfo str, FuncCall *node)
1405 {
1406         WRITE_NODE_TYPE("FUNCCALL");
1407
1408         WRITE_NODE_FIELD(funcname);
1409         WRITE_NODE_FIELD(args);
1410         WRITE_BOOL_FIELD(agg_star);
1411         WRITE_BOOL_FIELD(agg_distinct);
1412         WRITE_INT_FIELD(location);
1413 }
1414
1415 static void
1416 _outDefElem(StringInfo str, DefElem *node)
1417 {
1418         WRITE_NODE_TYPE("DEFELEM");
1419
1420         WRITE_STRING_FIELD(defname);
1421         WRITE_NODE_FIELD(arg);
1422 }
1423
1424 static void
1425 _outLockingClause(StringInfo str, LockingClause *node)
1426 {
1427         WRITE_NODE_TYPE("LOCKINGCLAUSE");
1428
1429         WRITE_NODE_FIELD(lockedRels);
1430         WRITE_BOOL_FIELD(forUpdate);
1431         WRITE_BOOL_FIELD(noWait);
1432 }
1433
1434 static void
1435 _outColumnDef(StringInfo str, ColumnDef *node)
1436 {
1437         WRITE_NODE_TYPE("COLUMNDEF");
1438
1439         WRITE_STRING_FIELD(colname);
1440         WRITE_NODE_FIELD(typename);
1441         WRITE_INT_FIELD(inhcount);
1442         WRITE_BOOL_FIELD(is_local);
1443         WRITE_BOOL_FIELD(is_not_null);
1444         WRITE_NODE_FIELD(raw_default);
1445         WRITE_STRING_FIELD(cooked_default);
1446         WRITE_NODE_FIELD(constraints);
1447         WRITE_NODE_FIELD(support);
1448 }
1449
1450 static void
1451 _outTypeName(StringInfo str, TypeName *node)
1452 {
1453         WRITE_NODE_TYPE("TYPENAME");
1454
1455         WRITE_NODE_FIELD(names);
1456         WRITE_OID_FIELD(typeid);
1457         WRITE_BOOL_FIELD(timezone);
1458         WRITE_BOOL_FIELD(setof);
1459         WRITE_BOOL_FIELD(pct_type);
1460         WRITE_INT_FIELD(typmod);
1461         WRITE_NODE_FIELD(arrayBounds);
1462         WRITE_INT_FIELD(location);
1463 }
1464
1465 static void
1466 _outTypeCast(StringInfo str, TypeCast *node)
1467 {
1468         WRITE_NODE_TYPE("TYPECAST");
1469
1470         WRITE_NODE_FIELD(arg);
1471         WRITE_NODE_FIELD(typename);
1472 }
1473
1474 static void
1475 _outIndexElem(StringInfo str, IndexElem *node)
1476 {
1477         WRITE_NODE_TYPE("INDEXELEM");
1478
1479         WRITE_STRING_FIELD(name);
1480         WRITE_NODE_FIELD(expr);
1481         WRITE_NODE_FIELD(opclass);
1482 }
1483
1484 static void
1485 _outQuery(StringInfo str, Query *node)
1486 {
1487         WRITE_NODE_TYPE("QUERY");
1488
1489         WRITE_ENUM_FIELD(commandType, CmdType);
1490         WRITE_ENUM_FIELD(querySource, QuerySource);
1491         WRITE_BOOL_FIELD(canSetTag);
1492
1493         /*
1494          * Hack to work around missing outfuncs routines for a lot of the
1495          * utility-statement node types.  (The only one we actually *need* for
1496          * rules support is NotifyStmt.)  Someday we ought to support 'em all, but
1497          * for the meantime do this to avoid getting lots of warnings when running
1498          * with debug_print_parse on.
1499          */
1500         if (node->utilityStmt)
1501         {
1502                 switch (nodeTag(node->utilityStmt))
1503                 {
1504                         case T_CreateStmt:
1505                         case T_IndexStmt:
1506                         case T_NotifyStmt:
1507                         case T_DeclareCursorStmt:
1508                                 WRITE_NODE_FIELD(utilityStmt);
1509                                 break;
1510                         default:
1511                                 appendStringInfo(str, " :utilityStmt ?");
1512                                 break;
1513                 }
1514         }
1515         else
1516                 appendStringInfo(str, " :utilityStmt <>");
1517
1518         WRITE_INT_FIELD(resultRelation);
1519         WRITE_NODE_FIELD(into);
1520         WRITE_NODE_FIELD(intoOptions);
1521         WRITE_ENUM_FIELD(intoOnCommit, OnCommitAction);
1522         WRITE_STRING_FIELD(intoTableSpaceName);
1523         WRITE_BOOL_FIELD(hasAggs);
1524         WRITE_BOOL_FIELD(hasSubLinks);
1525         WRITE_NODE_FIELD(rtable);
1526         WRITE_NODE_FIELD(jointree);
1527         WRITE_NODE_FIELD(targetList);
1528         WRITE_NODE_FIELD(returningList);
1529         WRITE_NODE_FIELD(groupClause);
1530         WRITE_NODE_FIELD(havingQual);
1531         WRITE_NODE_FIELD(distinctClause);
1532         WRITE_NODE_FIELD(sortClause);
1533         WRITE_NODE_FIELD(limitOffset);
1534         WRITE_NODE_FIELD(limitCount);
1535         WRITE_NODE_FIELD(rowMarks);
1536         WRITE_NODE_FIELD(setOperations);
1537         WRITE_NODE_FIELD(resultRelations);
1538         WRITE_NODE_FIELD(returningLists);
1539 }
1540
1541 static void
1542 _outSortClause(StringInfo str, SortClause *node)
1543 {
1544         WRITE_NODE_TYPE("SORTCLAUSE");
1545
1546         WRITE_UINT_FIELD(tleSortGroupRef);
1547         WRITE_OID_FIELD(sortop);
1548 }
1549
1550 static void
1551 _outGroupClause(StringInfo str, GroupClause *node)
1552 {
1553         WRITE_NODE_TYPE("GROUPCLAUSE");
1554
1555         WRITE_UINT_FIELD(tleSortGroupRef);
1556         WRITE_OID_FIELD(sortop);
1557 }
1558
1559 static void
1560 _outRowMarkClause(StringInfo str, RowMarkClause *node)
1561 {
1562         WRITE_NODE_TYPE("ROWMARKCLAUSE");
1563
1564         WRITE_UINT_FIELD(rti);
1565         WRITE_BOOL_FIELD(forUpdate);
1566         WRITE_BOOL_FIELD(noWait);
1567 }
1568
1569 static void
1570 _outSetOperationStmt(StringInfo str, SetOperationStmt *node)
1571 {
1572         WRITE_NODE_TYPE("SETOPERATIONSTMT");
1573
1574         WRITE_ENUM_FIELD(op, SetOperation);
1575         WRITE_BOOL_FIELD(all);
1576         WRITE_NODE_FIELD(larg);
1577         WRITE_NODE_FIELD(rarg);
1578         WRITE_NODE_FIELD(colTypes);
1579         WRITE_NODE_FIELD(colTypmods);
1580 }
1581
1582 static void
1583 _outRangeTblEntry(StringInfo str, RangeTblEntry *node)
1584 {
1585         WRITE_NODE_TYPE("RTE");
1586
1587         /* put alias + eref first to make dump more legible */
1588         WRITE_NODE_FIELD(alias);
1589         WRITE_NODE_FIELD(eref);
1590         WRITE_ENUM_FIELD(rtekind, RTEKind);
1591
1592         switch (node->rtekind)
1593         {
1594                 case RTE_RELATION:
1595                 case RTE_SPECIAL:
1596                         WRITE_OID_FIELD(relid);
1597                         break;
1598                 case RTE_SUBQUERY:
1599                         WRITE_NODE_FIELD(subquery);
1600                         break;
1601                 case RTE_FUNCTION:
1602                         WRITE_NODE_FIELD(funcexpr);
1603                         WRITE_NODE_FIELD(funccoltypes);
1604                         WRITE_NODE_FIELD(funccoltypmods);
1605                         break;
1606                 case RTE_VALUES:
1607                         WRITE_NODE_FIELD(values_lists);
1608                         break;
1609                 case RTE_JOIN:
1610                         WRITE_ENUM_FIELD(jointype, JoinType);
1611                         WRITE_NODE_FIELD(joinaliasvars);
1612                         break;
1613                 default:
1614                         elog(ERROR, "unrecognized RTE kind: %d", (int) node->rtekind);
1615                         break;
1616         }
1617
1618         WRITE_BOOL_FIELD(inh);
1619         WRITE_BOOL_FIELD(inFromCl);
1620         WRITE_UINT_FIELD(requiredPerms);
1621         WRITE_OID_FIELD(checkAsUser);
1622 }
1623
1624 static void
1625 _outAExpr(StringInfo str, A_Expr *node)
1626 {
1627         WRITE_NODE_TYPE("AEXPR");
1628
1629         switch (node->kind)
1630         {
1631                 case AEXPR_OP:
1632                         appendStringInfo(str, " ");
1633                         WRITE_NODE_FIELD(name);
1634                         break;
1635                 case AEXPR_AND:
1636                         appendStringInfo(str, " AND");
1637                         break;
1638                 case AEXPR_OR:
1639                         appendStringInfo(str, " OR");
1640                         break;
1641                 case AEXPR_NOT:
1642                         appendStringInfo(str, " NOT");
1643                         break;
1644                 case AEXPR_OP_ANY:
1645                         appendStringInfo(str, " ");
1646                         WRITE_NODE_FIELD(name);
1647                         appendStringInfo(str, " ANY ");
1648                         break;
1649                 case AEXPR_OP_ALL:
1650                         appendStringInfo(str, " ");
1651                         WRITE_NODE_FIELD(name);
1652                         appendStringInfo(str, " ALL ");
1653                         break;
1654                 case AEXPR_DISTINCT:
1655                         appendStringInfo(str, " DISTINCT ");
1656                         WRITE_NODE_FIELD(name);
1657                         break;
1658                 case AEXPR_NULLIF:
1659                         appendStringInfo(str, " NULLIF ");
1660                         WRITE_NODE_FIELD(name);
1661                         break;
1662                 case AEXPR_OF:
1663                         appendStringInfo(str, " OF ");
1664                         WRITE_NODE_FIELD(name);
1665                         break;
1666                 case AEXPR_IN:
1667                         appendStringInfo(str, " IN ");
1668                         WRITE_NODE_FIELD(name);
1669                         break;
1670                 default:
1671                         appendStringInfo(str, " ??");
1672                         break;
1673         }
1674
1675         WRITE_NODE_FIELD(lexpr);
1676         WRITE_NODE_FIELD(rexpr);
1677         WRITE_INT_FIELD(location);
1678 }
1679
1680 static void
1681 _outValue(StringInfo str, Value *value)
1682 {
1683         switch (value->type)
1684         {
1685                 case T_Integer:
1686                         appendStringInfo(str, "%ld", value->val.ival);
1687                         break;
1688                 case T_Float:
1689
1690                         /*
1691                          * We assume the value is a valid numeric literal and so does not
1692                          * need quoting.
1693                          */
1694                         appendStringInfoString(str, value->val.str);
1695                         break;
1696                 case T_String:
1697                         appendStringInfoChar(str, '"');
1698                         _outToken(str, value->val.str);
1699                         appendStringInfoChar(str, '"');
1700                         break;
1701                 case T_BitString:
1702                         /* internal representation already has leading 'b' */
1703                         appendStringInfoString(str, value->val.str);
1704                         break;
1705                 default:
1706                         elog(ERROR, "unrecognized node type: %d", (int) value->type);
1707                         break;
1708         }
1709 }
1710
1711 static void
1712 _outColumnRef(StringInfo str, ColumnRef *node)
1713 {
1714         WRITE_NODE_TYPE("COLUMNREF");
1715
1716         WRITE_NODE_FIELD(fields);
1717         WRITE_INT_FIELD(location);
1718 }
1719
1720 static void
1721 _outParamRef(StringInfo str, ParamRef *node)
1722 {
1723         WRITE_NODE_TYPE("PARAMREF");
1724
1725         WRITE_INT_FIELD(number);
1726 }
1727
1728 static void
1729 _outAConst(StringInfo str, A_Const *node)
1730 {
1731         WRITE_NODE_TYPE("A_CONST");
1732
1733         appendStringInfo(str, " :val ");
1734         _outValue(str, &(node->val));
1735         WRITE_NODE_FIELD(typename);
1736 }
1737
1738 static void
1739 _outA_Indices(StringInfo str, A_Indices *node)
1740 {
1741         WRITE_NODE_TYPE("A_INDICES");
1742
1743         WRITE_NODE_FIELD(lidx);
1744         WRITE_NODE_FIELD(uidx);
1745 }
1746
1747 static void
1748 _outA_Indirection(StringInfo str, A_Indirection *node)
1749 {
1750         WRITE_NODE_TYPE("A_INDIRECTION");
1751
1752         WRITE_NODE_FIELD(arg);
1753         WRITE_NODE_FIELD(indirection);
1754 }
1755
1756 static void
1757 _outResTarget(StringInfo str, ResTarget *node)
1758 {
1759         WRITE_NODE_TYPE("RESTARGET");
1760
1761         WRITE_STRING_FIELD(name);
1762         WRITE_NODE_FIELD(indirection);
1763         WRITE_NODE_FIELD(val);
1764         WRITE_INT_FIELD(location);
1765 }
1766
1767 static void
1768 _outConstraint(StringInfo str, Constraint *node)
1769 {
1770         WRITE_NODE_TYPE("CONSTRAINT");
1771
1772         WRITE_STRING_FIELD(name);
1773
1774         appendStringInfo(str, " :contype ");
1775         switch (node->contype)
1776         {
1777                 case CONSTR_PRIMARY:
1778                         appendStringInfo(str, "PRIMARY_KEY");
1779                         WRITE_NODE_FIELD(keys);
1780                         WRITE_NODE_FIELD(options);
1781                         WRITE_STRING_FIELD(indexspace);
1782                         break;
1783
1784                 case CONSTR_UNIQUE:
1785                         appendStringInfo(str, "UNIQUE");
1786                         WRITE_NODE_FIELD(keys);
1787                         WRITE_NODE_FIELD(options);
1788                         WRITE_STRING_FIELD(indexspace);
1789                         break;
1790
1791                 case CONSTR_CHECK:
1792                         appendStringInfo(str, "CHECK");
1793                         WRITE_NODE_FIELD(raw_expr);
1794                         WRITE_STRING_FIELD(cooked_expr);
1795                         break;
1796
1797                 case CONSTR_DEFAULT:
1798                         appendStringInfo(str, "DEFAULT");
1799                         WRITE_NODE_FIELD(raw_expr);
1800                         WRITE_STRING_FIELD(cooked_expr);
1801                         break;
1802
1803                 case CONSTR_NOTNULL:
1804                         appendStringInfo(str, "NOT_NULL");
1805                         break;
1806
1807                 default:
1808                         appendStringInfo(str, "<unrecognized_constraint>");
1809                         break;
1810         }
1811 }
1812
1813 static void
1814 _outFkConstraint(StringInfo str, FkConstraint *node)
1815 {
1816         WRITE_NODE_TYPE("FKCONSTRAINT");
1817
1818         WRITE_STRING_FIELD(constr_name);
1819         WRITE_NODE_FIELD(pktable);
1820         WRITE_NODE_FIELD(fk_attrs);
1821         WRITE_NODE_FIELD(pk_attrs);
1822         WRITE_CHAR_FIELD(fk_matchtype);
1823         WRITE_CHAR_FIELD(fk_upd_action);
1824         WRITE_CHAR_FIELD(fk_del_action);
1825         WRITE_BOOL_FIELD(deferrable);
1826         WRITE_BOOL_FIELD(initdeferred);
1827         WRITE_BOOL_FIELD(skip_validation);
1828 }
1829
1830
1831 /*
1832  * _outNode -
1833  *        converts a Node into ascii string and append it to 'str'
1834  */
1835 static void
1836 _outNode(StringInfo str, void *obj)
1837 {
1838         if (obj == NULL)
1839                 appendStringInfo(str, "<>");
1840         else if (IsA(obj, List) ||IsA(obj, IntList) || IsA(obj, OidList))
1841                 _outList(str, obj);
1842         else if (IsA(obj, Integer) ||
1843                          IsA(obj, Float) ||
1844                          IsA(obj, String) ||
1845                          IsA(obj, BitString))
1846         {
1847                 /* nodeRead does not want to see { } around these! */
1848                 _outValue(str, obj);
1849         }
1850         else
1851         {
1852                 appendStringInfoChar(str, '{');
1853                 switch (nodeTag(obj))
1854                 {
1855                         case T_Plan:
1856                                 _outPlan(str, obj);
1857                                 break;
1858                         case T_Result:
1859                                 _outResult(str, obj);
1860                                 break;
1861                         case T_Append:
1862                                 _outAppend(str, obj);
1863                                 break;
1864                         case T_BitmapAnd:
1865                                 _outBitmapAnd(str, obj);
1866                                 break;
1867                         case T_BitmapOr:
1868                                 _outBitmapOr(str, obj);
1869                                 break;
1870                         case T_Scan:
1871                                 _outScan(str, obj);
1872                                 break;
1873                         case T_SeqScan:
1874                                 _outSeqScan(str, obj);
1875                                 break;
1876                         case T_IndexScan:
1877                                 _outIndexScan(str, obj);
1878                                 break;
1879                         case T_BitmapIndexScan:
1880                                 _outBitmapIndexScan(str, obj);
1881                                 break;
1882                         case T_BitmapHeapScan:
1883                                 _outBitmapHeapScan(str, obj);
1884                                 break;
1885                         case T_TidScan:
1886                                 _outTidScan(str, obj);
1887                                 break;
1888                         case T_SubqueryScan:
1889                                 _outSubqueryScan(str, obj);
1890                                 break;
1891                         case T_FunctionScan:
1892                                 _outFunctionScan(str, obj);
1893                                 break;
1894                         case T_ValuesScan:
1895                                 _outValuesScan(str, obj);
1896                                 break;
1897                         case T_Join:
1898                                 _outJoin(str, obj);
1899                                 break;
1900                         case T_NestLoop:
1901                                 _outNestLoop(str, obj);
1902                                 break;
1903                         case T_MergeJoin:
1904                                 _outMergeJoin(str, obj);
1905                                 break;
1906                         case T_HashJoin:
1907                                 _outHashJoin(str, obj);
1908                                 break;
1909                         case T_Agg:
1910                                 _outAgg(str, obj);
1911                                 break;
1912                         case T_Group:
1913                                 _outGroup(str, obj);
1914                                 break;
1915                         case T_Material:
1916                                 _outMaterial(str, obj);
1917                                 break;
1918                         case T_Sort:
1919                                 _outSort(str, obj);
1920                                 break;
1921                         case T_Unique:
1922                                 _outUnique(str, obj);
1923                                 break;
1924                         case T_SetOp:
1925                                 _outSetOp(str, obj);
1926                                 break;
1927                         case T_Limit:
1928                                 _outLimit(str, obj);
1929                                 break;
1930                         case T_Hash:
1931                                 _outHash(str, obj);
1932                                 break;
1933                         case T_Alias:
1934                                 _outAlias(str, obj);
1935                                 break;
1936                         case T_RangeVar:
1937                                 _outRangeVar(str, obj);
1938                                 break;
1939                         case T_Var:
1940                                 _outVar(str, obj);
1941                                 break;
1942                         case T_Const:
1943                                 _outConst(str, obj);
1944                                 break;
1945                         case T_Param:
1946                                 _outParam(str, obj);
1947                                 break;
1948                         case T_Aggref:
1949                                 _outAggref(str, obj);
1950                                 break;
1951                         case T_ArrayRef:
1952                                 _outArrayRef(str, obj);
1953                                 break;
1954                         case T_FuncExpr:
1955                                 _outFuncExpr(str, obj);
1956                                 break;
1957                         case T_OpExpr:
1958                                 _outOpExpr(str, obj);
1959                                 break;
1960                         case T_DistinctExpr:
1961                                 _outDistinctExpr(str, obj);
1962                                 break;
1963                         case T_ScalarArrayOpExpr:
1964                                 _outScalarArrayOpExpr(str, obj);
1965                                 break;
1966                         case T_BoolExpr:
1967                                 _outBoolExpr(str, obj);
1968                                 break;
1969                         case T_SubLink:
1970                                 _outSubLink(str, obj);
1971                                 break;
1972                         case T_SubPlan:
1973                                 _outSubPlan(str, obj);
1974                                 break;
1975                         case T_FieldSelect:
1976                                 _outFieldSelect(str, obj);
1977                                 break;
1978                         case T_FieldStore:
1979                                 _outFieldStore(str, obj);
1980                                 break;
1981                         case T_RelabelType:
1982                                 _outRelabelType(str, obj);
1983                                 break;
1984                         case T_ConvertRowtypeExpr:
1985                                 _outConvertRowtypeExpr(str, obj);
1986                                 break;
1987                         case T_CaseExpr:
1988                                 _outCaseExpr(str, obj);
1989                                 break;
1990                         case T_CaseWhen:
1991                                 _outCaseWhen(str, obj);
1992                                 break;
1993                         case T_CaseTestExpr:
1994                                 _outCaseTestExpr(str, obj);
1995                                 break;
1996                         case T_ArrayExpr:
1997                                 _outArrayExpr(str, obj);
1998                                 break;
1999                         case T_RowExpr:
2000                                 _outRowExpr(str, obj);
2001                                 break;
2002                         case T_RowCompareExpr:
2003                                 _outRowCompareExpr(str, obj);
2004                                 break;
2005                         case T_CoalesceExpr:
2006                                 _outCoalesceExpr(str, obj);
2007                                 break;
2008                         case T_MinMaxExpr:
2009                                 _outMinMaxExpr(str, obj);
2010                                 break;
2011                         case T_NullIfExpr:
2012                                 _outNullIfExpr(str, obj);
2013                                 break;
2014                         case T_NullTest:
2015                                 _outNullTest(str, obj);
2016                                 break;
2017                         case T_BooleanTest:
2018                                 _outBooleanTest(str, obj);
2019                                 break;
2020                         case T_CoerceToDomain:
2021                                 _outCoerceToDomain(str, obj);
2022                                 break;
2023                         case T_CoerceToDomainValue:
2024                                 _outCoerceToDomainValue(str, obj);
2025                                 break;
2026                         case T_SetToDefault:
2027                                 _outSetToDefault(str, obj);
2028                                 break;
2029                         case T_TargetEntry:
2030                                 _outTargetEntry(str, obj);
2031                                 break;
2032                         case T_RangeTblRef:
2033                                 _outRangeTblRef(str, obj);
2034                                 break;
2035                         case T_JoinExpr:
2036                                 _outJoinExpr(str, obj);
2037                                 break;
2038                         case T_FromExpr:
2039                                 _outFromExpr(str, obj);
2040                                 break;
2041
2042                         case T_Path:
2043                                 _outPath(str, obj);
2044                                 break;
2045                         case T_IndexPath:
2046                                 _outIndexPath(str, obj);
2047                                 break;
2048                         case T_BitmapHeapPath:
2049                                 _outBitmapHeapPath(str, obj);
2050                                 break;
2051                         case T_BitmapAndPath:
2052                                 _outBitmapAndPath(str, obj);
2053                                 break;
2054                         case T_BitmapOrPath:
2055                                 _outBitmapOrPath(str, obj);
2056                                 break;
2057                         case T_TidPath:
2058                                 _outTidPath(str, obj);
2059                                 break;
2060                         case T_AppendPath:
2061                                 _outAppendPath(str, obj);
2062                                 break;
2063                         case T_ResultPath:
2064                                 _outResultPath(str, obj);
2065                                 break;
2066                         case T_MaterialPath:
2067                                 _outMaterialPath(str, obj);
2068                                 break;
2069                         case T_UniquePath:
2070                                 _outUniquePath(str, obj);
2071                                 break;
2072                         case T_NestPath:
2073                                 _outNestPath(str, obj);
2074                                 break;
2075                         case T_MergePath:
2076                                 _outMergePath(str, obj);
2077                                 break;
2078                         case T_HashPath:
2079                                 _outHashPath(str, obj);
2080                                 break;
2081                         case T_PlannerInfo:
2082                                 _outPlannerInfo(str, obj);
2083                                 break;
2084                         case T_RelOptInfo:
2085                                 _outRelOptInfo(str, obj);
2086                                 break;
2087                         case T_IndexOptInfo:
2088                                 _outIndexOptInfo(str, obj);
2089                                 break;
2090                         case T_PathKeyItem:
2091                                 _outPathKeyItem(str, obj);
2092                                 break;
2093                         case T_RestrictInfo:
2094                                 _outRestrictInfo(str, obj);
2095                                 break;
2096                         case T_InnerIndexscanInfo:
2097                                 _outInnerIndexscanInfo(str, obj);
2098                                 break;
2099                         case T_OuterJoinInfo:
2100                                 _outOuterJoinInfo(str, obj);
2101                                 break;
2102                         case T_InClauseInfo:
2103                                 _outInClauseInfo(str, obj);
2104                                 break;
2105                         case T_AppendRelInfo:
2106                                 _outAppendRelInfo(str, obj);
2107                                 break;
2108
2109                         case T_CreateStmt:
2110                                 _outCreateStmt(str, obj);
2111                                 break;
2112                         case T_IndexStmt:
2113                                 _outIndexStmt(str, obj);
2114                                 break;
2115                         case T_NotifyStmt:
2116                                 _outNotifyStmt(str, obj);
2117                                 break;
2118                         case T_DeclareCursorStmt:
2119                                 _outDeclareCursorStmt(str, obj);
2120                                 break;
2121                         case T_SelectStmt:
2122                                 _outSelectStmt(str, obj);
2123                                 break;
2124                         case T_ColumnDef:
2125                                 _outColumnDef(str, obj);
2126                                 break;
2127                         case T_TypeName:
2128                                 _outTypeName(str, obj);
2129                                 break;
2130                         case T_TypeCast:
2131                                 _outTypeCast(str, obj);
2132                                 break;
2133                         case T_IndexElem:
2134                                 _outIndexElem(str, obj);
2135                                 break;
2136                         case T_Query:
2137                                 _outQuery(str, obj);
2138                                 break;
2139                         case T_SortClause:
2140                                 _outSortClause(str, obj);
2141                                 break;
2142                         case T_GroupClause:
2143                                 _outGroupClause(str, obj);
2144                                 break;
2145                         case T_RowMarkClause:
2146                                 _outRowMarkClause(str, obj);
2147                                 break;
2148                         case T_SetOperationStmt:
2149                                 _outSetOperationStmt(str, obj);
2150                                 break;
2151                         case T_RangeTblEntry:
2152                                 _outRangeTblEntry(str, obj);
2153                                 break;
2154                         case T_A_Expr:
2155                                 _outAExpr(str, obj);
2156                                 break;
2157                         case T_ColumnRef:
2158                                 _outColumnRef(str, obj);
2159                                 break;
2160                         case T_ParamRef:
2161                                 _outParamRef(str, obj);
2162                                 break;
2163                         case T_A_Const:
2164                                 _outAConst(str, obj);
2165                                 break;
2166                         case T_A_Indices:
2167                                 _outA_Indices(str, obj);
2168                                 break;
2169                         case T_A_Indirection:
2170                                 _outA_Indirection(str, obj);
2171                                 break;
2172                         case T_ResTarget:
2173                                 _outResTarget(str, obj);
2174                                 break;
2175                         case T_Constraint:
2176                                 _outConstraint(str, obj);
2177                                 break;
2178                         case T_FkConstraint:
2179                                 _outFkConstraint(str, obj);
2180                                 break;
2181                         case T_FuncCall:
2182                                 _outFuncCall(str, obj);
2183                                 break;
2184                         case T_DefElem:
2185                                 _outDefElem(str, obj);
2186                                 break;
2187                         case T_LockingClause:
2188                                 _outLockingClause(str, obj);
2189                                 break;
2190
2191                         default:
2192
2193                                 /*
2194                                  * This should be an ERROR, but it's too useful to be able to
2195                                  * dump structures that _outNode only understands part of.
2196                                  */
2197                                 elog(WARNING, "could not dump unrecognized node type: %d",
2198                                          (int) nodeTag(obj));
2199                                 break;
2200                 }
2201                 appendStringInfoChar(str, '}');
2202         }
2203 }
2204
2205 /*
2206  * nodeToString -
2207  *         returns the ascii representation of the Node as a palloc'd string
2208  */
2209 char *
2210 nodeToString(void *obj)
2211 {
2212         StringInfoData str;
2213
2214         /* see stringinfo.h for an explanation of this maneuver */
2215         initStringInfo(&str);
2216         _outNode(&str, obj);
2217         return str.data;
2218 }