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