]> granicus.if.org Git - postgresql/blob - src/backend/nodes/outfuncs.c
Put function expressions and values lists into FunctionScan and ValuesScan
[postgresql] / src / backend / nodes / outfuncs.c
1 /*-------------------------------------------------------------------------
2  *
3  * outfuncs.c
4  *        Output functions for Postgres tree nodes.
5  *
6  * Portions Copyright (c) 1996-2007, 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.298 2007/02/19 02:23:12 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         WRITE_NODE_FIELD(funcexpr);
413         WRITE_NODE_FIELD(funccolnames);
414         WRITE_NODE_FIELD(funccoltypes);
415         WRITE_NODE_FIELD(funccoltypmods);
416 }
417
418 static void
419 _outValuesScan(StringInfo str, ValuesScan *node)
420 {
421         WRITE_NODE_TYPE("VALUESSCAN");
422
423         _outScanInfo(str, (Scan *) node);
424
425         WRITE_NODE_FIELD(values_lists);
426 }
427
428 static void
429 _outJoin(StringInfo str, Join *node)
430 {
431         WRITE_NODE_TYPE("JOIN");
432
433         _outJoinPlanInfo(str, (Join *) node);
434 }
435
436 static void
437 _outNestLoop(StringInfo str, NestLoop *node)
438 {
439         WRITE_NODE_TYPE("NESTLOOP");
440
441         _outJoinPlanInfo(str, (Join *) node);
442 }
443
444 static void
445 _outMergeJoin(StringInfo str, MergeJoin *node)
446 {
447         int                     numCols;
448         int                     i;
449
450         WRITE_NODE_TYPE("MERGEJOIN");
451
452         _outJoinPlanInfo(str, (Join *) node);
453
454         WRITE_NODE_FIELD(mergeclauses);
455
456         numCols = list_length(node->mergeclauses);
457
458         appendStringInfo(str, " :mergeFamilies");
459         for (i = 0; i < numCols; i++)
460                 appendStringInfo(str, " %u", node->mergeFamilies[i]);
461
462         appendStringInfo(str, " :mergeStrategies");
463         for (i = 0; i < numCols; i++)
464                 appendStringInfo(str, " %d", node->mergeStrategies[i]);
465
466         appendStringInfo(str, " :mergeNullsFirst");
467         for (i = 0; i < numCols; i++)
468                 appendStringInfo(str, " %d", (int) node->mergeNullsFirst[i]);
469 }
470
471 static void
472 _outHashJoin(StringInfo str, HashJoin *node)
473 {
474         WRITE_NODE_TYPE("HASHJOIN");
475
476         _outJoinPlanInfo(str, (Join *) node);
477
478         WRITE_NODE_FIELD(hashclauses);
479 }
480
481 static void
482 _outAgg(StringInfo str, Agg *node)
483 {
484         WRITE_NODE_TYPE("AGG");
485
486         _outPlanInfo(str, (Plan *) node);
487
488         WRITE_ENUM_FIELD(aggstrategy, AggStrategy);
489         WRITE_INT_FIELD(numCols);
490         WRITE_LONG_FIELD(numGroups);
491 }
492
493 static void
494 _outGroup(StringInfo str, Group *node)
495 {
496         int                     i;
497
498         WRITE_NODE_TYPE("GROUP");
499
500         _outPlanInfo(str, (Plan *) node);
501
502         WRITE_INT_FIELD(numCols);
503
504         appendStringInfo(str, " :grpColIdx");
505         for (i = 0; i < node->numCols; i++)
506                 appendStringInfo(str, " %d", node->grpColIdx[i]);
507
508         appendStringInfo(str, " :grpOperators");
509         for (i = 0; i < node->numCols; i++)
510                 appendStringInfo(str, " %u", node->grpOperators[i]);
511 }
512
513 static void
514 _outMaterial(StringInfo str, Material *node)
515 {
516         WRITE_NODE_TYPE("MATERIAL");
517
518         _outPlanInfo(str, (Plan *) node);
519 }
520
521 static void
522 _outSort(StringInfo str, Sort *node)
523 {
524         int                     i;
525
526         WRITE_NODE_TYPE("SORT");
527
528         _outPlanInfo(str, (Plan *) node);
529
530         WRITE_INT_FIELD(numCols);
531
532         appendStringInfo(str, " :sortColIdx");
533         for (i = 0; i < node->numCols; i++)
534                 appendStringInfo(str, " %d", node->sortColIdx[i]);
535
536         appendStringInfo(str, " :sortOperators");
537         for (i = 0; i < node->numCols; i++)
538                 appendStringInfo(str, " %u", node->sortOperators[i]);
539
540         appendStringInfo(str, " :nullsFirst");
541         for (i = 0; i < node->numCols; i++)
542                 appendStringInfo(str, " %s", booltostr(node->nullsFirst[i]));
543 }
544
545 static void
546 _outUnique(StringInfo str, Unique *node)
547 {
548         int                     i;
549
550         WRITE_NODE_TYPE("UNIQUE");
551
552         _outPlanInfo(str, (Plan *) node);
553
554         WRITE_INT_FIELD(numCols);
555
556         appendStringInfo(str, " :uniqColIdx");
557         for (i = 0; i < node->numCols; i++)
558                 appendStringInfo(str, " %d", node->uniqColIdx[i]);
559
560         appendStringInfo(str, " :uniqOperators");
561         for (i = 0; i < node->numCols; i++)
562                 appendStringInfo(str, " %u", node->uniqOperators[i]);
563 }
564
565 static void
566 _outSetOp(StringInfo str, SetOp *node)
567 {
568         int                     i;
569
570         WRITE_NODE_TYPE("SETOP");
571
572         _outPlanInfo(str, (Plan *) node);
573
574         WRITE_ENUM_FIELD(cmd, SetOpCmd);
575         WRITE_INT_FIELD(numCols);
576
577         appendStringInfo(str, " :dupColIdx");
578         for (i = 0; i < node->numCols; i++)
579                 appendStringInfo(str, " %d", node->dupColIdx[i]);
580
581         appendStringInfo(str, " :dupOperators");
582         for (i = 0; i < node->numCols; i++)
583                 appendStringInfo(str, " %d", node->dupOperators[i]);
584
585         WRITE_INT_FIELD(flagColIdx);
586 }
587
588 static void
589 _outLimit(StringInfo str, Limit *node)
590 {
591         WRITE_NODE_TYPE("LIMIT");
592
593         _outPlanInfo(str, (Plan *) node);
594
595         WRITE_NODE_FIELD(limitOffset);
596         WRITE_NODE_FIELD(limitCount);
597 }
598
599 static void
600 _outHash(StringInfo str, Hash *node)
601 {
602         WRITE_NODE_TYPE("HASH");
603
604         _outPlanInfo(str, (Plan *) node);
605 }
606
607 /*****************************************************************************
608  *
609  *      Stuff from primnodes.h.
610  *
611  *****************************************************************************/
612
613 static void
614 _outAlias(StringInfo str, Alias *node)
615 {
616         WRITE_NODE_TYPE("ALIAS");
617
618         WRITE_STRING_FIELD(aliasname);
619         WRITE_NODE_FIELD(colnames);
620 }
621
622 static void
623 _outRangeVar(StringInfo str, RangeVar *node)
624 {
625         WRITE_NODE_TYPE("RANGEVAR");
626
627         /*
628          * we deliberately ignore catalogname here, since it is presently not
629          * semantically meaningful
630          */
631         WRITE_STRING_FIELD(schemaname);
632         WRITE_STRING_FIELD(relname);
633         WRITE_ENUM_FIELD(inhOpt, InhOption);
634         WRITE_BOOL_FIELD(istemp);
635         WRITE_NODE_FIELD(alias);
636 }
637
638 static void
639 _outVar(StringInfo str, Var *node)
640 {
641         WRITE_NODE_TYPE("VAR");
642
643         WRITE_UINT_FIELD(varno);
644         WRITE_INT_FIELD(varattno);
645         WRITE_OID_FIELD(vartype);
646         WRITE_INT_FIELD(vartypmod);
647         WRITE_UINT_FIELD(varlevelsup);
648         WRITE_UINT_FIELD(varnoold);
649         WRITE_INT_FIELD(varoattno);
650 }
651
652 static void
653 _outConst(StringInfo str, Const *node)
654 {
655         WRITE_NODE_TYPE("CONST");
656
657         WRITE_OID_FIELD(consttype);
658         WRITE_INT_FIELD(constlen);
659         WRITE_BOOL_FIELD(constbyval);
660         WRITE_BOOL_FIELD(constisnull);
661
662         appendStringInfo(str, " :constvalue ");
663         if (node->constisnull)
664                 appendStringInfo(str, "<>");
665         else
666                 _outDatum(str, node->constvalue, node->constlen, node->constbyval);
667 }
668
669 static void
670 _outParam(StringInfo str, Param *node)
671 {
672         WRITE_NODE_TYPE("PARAM");
673
674         WRITE_ENUM_FIELD(paramkind, ParamKind);
675         WRITE_INT_FIELD(paramid);
676         WRITE_OID_FIELD(paramtype);
677         WRITE_INT_FIELD(paramtypmod);
678 }
679
680 static void
681 _outAggref(StringInfo str, Aggref *node)
682 {
683         WRITE_NODE_TYPE("AGGREF");
684
685         WRITE_OID_FIELD(aggfnoid);
686         WRITE_OID_FIELD(aggtype);
687         WRITE_NODE_FIELD(args);
688         WRITE_UINT_FIELD(agglevelsup);
689         WRITE_BOOL_FIELD(aggstar);
690         WRITE_BOOL_FIELD(aggdistinct);
691 }
692
693 static void
694 _outArrayRef(StringInfo str, ArrayRef *node)
695 {
696         WRITE_NODE_TYPE("ARRAYREF");
697
698         WRITE_OID_FIELD(refrestype);
699         WRITE_OID_FIELD(refarraytype);
700         WRITE_OID_FIELD(refelemtype);
701         WRITE_NODE_FIELD(refupperindexpr);
702         WRITE_NODE_FIELD(reflowerindexpr);
703         WRITE_NODE_FIELD(refexpr);
704         WRITE_NODE_FIELD(refassgnexpr);
705 }
706
707 static void
708 _outFuncExpr(StringInfo str, FuncExpr *node)
709 {
710         WRITE_NODE_TYPE("FUNCEXPR");
711
712         WRITE_OID_FIELD(funcid);
713         WRITE_OID_FIELD(funcresulttype);
714         WRITE_BOOL_FIELD(funcretset);
715         WRITE_ENUM_FIELD(funcformat, CoercionForm);
716         WRITE_NODE_FIELD(args);
717 }
718
719 static void
720 _outOpExpr(StringInfo str, OpExpr *node)
721 {
722         WRITE_NODE_TYPE("OPEXPR");
723
724         WRITE_OID_FIELD(opno);
725         WRITE_OID_FIELD(opfuncid);
726         WRITE_OID_FIELD(opresulttype);
727         WRITE_BOOL_FIELD(opretset);
728         WRITE_NODE_FIELD(args);
729 }
730
731 static void
732 _outDistinctExpr(StringInfo str, DistinctExpr *node)
733 {
734         WRITE_NODE_TYPE("DISTINCTEXPR");
735
736         WRITE_OID_FIELD(opno);
737         WRITE_OID_FIELD(opfuncid);
738         WRITE_OID_FIELD(opresulttype);
739         WRITE_BOOL_FIELD(opretset);
740         WRITE_NODE_FIELD(args);
741 }
742
743 static void
744 _outScalarArrayOpExpr(StringInfo str, ScalarArrayOpExpr *node)
745 {
746         WRITE_NODE_TYPE("SCALARARRAYOPEXPR");
747
748         WRITE_OID_FIELD(opno);
749         WRITE_OID_FIELD(opfuncid);
750         WRITE_BOOL_FIELD(useOr);
751         WRITE_NODE_FIELD(args);
752 }
753
754 static void
755 _outBoolExpr(StringInfo str, BoolExpr *node)
756 {
757         char       *opstr = NULL;
758
759         WRITE_NODE_TYPE("BOOLEXPR");
760
761         /* do-it-yourself enum representation */
762         switch (node->boolop)
763         {
764                 case AND_EXPR:
765                         opstr = "and";
766                         break;
767                 case OR_EXPR:
768                         opstr = "or";
769                         break;
770                 case NOT_EXPR:
771                         opstr = "not";
772                         break;
773         }
774         appendStringInfo(str, " :boolop ");
775         _outToken(str, opstr);
776
777         WRITE_NODE_FIELD(args);
778 }
779
780 static void
781 _outSubLink(StringInfo str, SubLink *node)
782 {
783         WRITE_NODE_TYPE("SUBLINK");
784
785         WRITE_ENUM_FIELD(subLinkType, SubLinkType);
786         WRITE_NODE_FIELD(testexpr);
787         WRITE_NODE_FIELD(operName);
788         WRITE_NODE_FIELD(subselect);
789 }
790
791 static void
792 _outSubPlan(StringInfo str, SubPlan *node)
793 {
794         WRITE_NODE_TYPE("SUBPLAN");
795
796         WRITE_ENUM_FIELD(subLinkType, SubLinkType);
797         WRITE_NODE_FIELD(testexpr);
798         WRITE_NODE_FIELD(paramIds);
799         WRITE_NODE_FIELD(plan);
800         WRITE_INT_FIELD(plan_id);
801         WRITE_NODE_FIELD(rtable);
802         WRITE_BOOL_FIELD(useHashTable);
803         WRITE_BOOL_FIELD(unknownEqFalse);
804         WRITE_NODE_FIELD(setParam);
805         WRITE_NODE_FIELD(parParam);
806         WRITE_NODE_FIELD(args);
807 }
808
809 static void
810 _outFieldSelect(StringInfo str, FieldSelect *node)
811 {
812         WRITE_NODE_TYPE("FIELDSELECT");
813
814         WRITE_NODE_FIELD(arg);
815         WRITE_INT_FIELD(fieldnum);
816         WRITE_OID_FIELD(resulttype);
817         WRITE_INT_FIELD(resulttypmod);
818 }
819
820 static void
821 _outFieldStore(StringInfo str, FieldStore *node)
822 {
823         WRITE_NODE_TYPE("FIELDSTORE");
824
825         WRITE_NODE_FIELD(arg);
826         WRITE_NODE_FIELD(newvals);
827         WRITE_NODE_FIELD(fieldnums);
828         WRITE_OID_FIELD(resulttype);
829 }
830
831 static void
832 _outRelabelType(StringInfo str, RelabelType *node)
833 {
834         WRITE_NODE_TYPE("RELABELTYPE");
835
836         WRITE_NODE_FIELD(arg);
837         WRITE_OID_FIELD(resulttype);
838         WRITE_INT_FIELD(resulttypmod);
839         WRITE_ENUM_FIELD(relabelformat, CoercionForm);
840 }
841
842 static void
843 _outConvertRowtypeExpr(StringInfo str, ConvertRowtypeExpr *node)
844 {
845         WRITE_NODE_TYPE("CONVERTROWTYPEEXPR");
846
847         WRITE_NODE_FIELD(arg);
848         WRITE_OID_FIELD(resulttype);
849         WRITE_ENUM_FIELD(convertformat, CoercionForm);
850 }
851
852 static void
853 _outCaseExpr(StringInfo str, CaseExpr *node)
854 {
855         WRITE_NODE_TYPE("CASE");
856
857         WRITE_OID_FIELD(casetype);
858         WRITE_NODE_FIELD(arg);
859         WRITE_NODE_FIELD(args);
860         WRITE_NODE_FIELD(defresult);
861 }
862
863 static void
864 _outCaseWhen(StringInfo str, CaseWhen *node)
865 {
866         WRITE_NODE_TYPE("WHEN");
867
868         WRITE_NODE_FIELD(expr);
869         WRITE_NODE_FIELD(result);
870 }
871
872 static void
873 _outCaseTestExpr(StringInfo str, CaseTestExpr *node)
874 {
875         WRITE_NODE_TYPE("CASETESTEXPR");
876
877         WRITE_OID_FIELD(typeId);
878         WRITE_INT_FIELD(typeMod);
879 }
880
881 static void
882 _outArrayExpr(StringInfo str, ArrayExpr *node)
883 {
884         WRITE_NODE_TYPE("ARRAY");
885
886         WRITE_OID_FIELD(array_typeid);
887         WRITE_OID_FIELD(element_typeid);
888         WRITE_NODE_FIELD(elements);
889         WRITE_BOOL_FIELD(multidims);
890 }
891
892 static void
893 _outRowExpr(StringInfo str, RowExpr *node)
894 {
895         WRITE_NODE_TYPE("ROW");
896
897         WRITE_NODE_FIELD(args);
898         WRITE_OID_FIELD(row_typeid);
899         WRITE_ENUM_FIELD(row_format, CoercionForm);
900 }
901
902 static void
903 _outRowCompareExpr(StringInfo str, RowCompareExpr *node)
904 {
905         WRITE_NODE_TYPE("ROWCOMPARE");
906
907         WRITE_ENUM_FIELD(rctype, RowCompareType);
908         WRITE_NODE_FIELD(opnos);
909         WRITE_NODE_FIELD(opfamilies);
910         WRITE_NODE_FIELD(largs);
911         WRITE_NODE_FIELD(rargs);
912 }
913
914 static void
915 _outCoalesceExpr(StringInfo str, CoalesceExpr *node)
916 {
917         WRITE_NODE_TYPE("COALESCE");
918
919         WRITE_OID_FIELD(coalescetype);
920         WRITE_NODE_FIELD(args);
921 }
922
923 static void
924 _outMinMaxExpr(StringInfo str, MinMaxExpr *node)
925 {
926         WRITE_NODE_TYPE("MINMAX");
927
928         WRITE_OID_FIELD(minmaxtype);
929         WRITE_ENUM_FIELD(op, MinMaxOp);
930         WRITE_NODE_FIELD(args);
931 }
932
933 static void
934 _outXmlExpr(StringInfo str, XmlExpr *node)
935 {
936         WRITE_NODE_TYPE("XMLEXPR");
937         
938         WRITE_ENUM_FIELD(op, XmlExprOp);
939         WRITE_STRING_FIELD(name);
940         WRITE_NODE_FIELD(named_args);
941         WRITE_NODE_FIELD(arg_names);
942         WRITE_NODE_FIELD(args);
943         WRITE_ENUM_FIELD(xmloption, XmlOptionType);
944         WRITE_OID_FIELD(type);
945         WRITE_INT_FIELD(typmod);
946 }
947
948 static void
949 _outNullIfExpr(StringInfo str, NullIfExpr *node)
950 {
951         WRITE_NODE_TYPE("NULLIFEXPR");
952
953         WRITE_OID_FIELD(opno);
954         WRITE_OID_FIELD(opfuncid);
955         WRITE_OID_FIELD(opresulttype);
956         WRITE_BOOL_FIELD(opretset);
957         WRITE_NODE_FIELD(args);
958 }
959
960 static void
961 _outNullTest(StringInfo str, NullTest *node)
962 {
963         WRITE_NODE_TYPE("NULLTEST");
964
965         WRITE_NODE_FIELD(arg);
966         WRITE_ENUM_FIELD(nulltesttype, NullTestType);
967 }
968
969 static void
970 _outBooleanTest(StringInfo str, BooleanTest *node)
971 {
972         WRITE_NODE_TYPE("BOOLEANTEST");
973
974         WRITE_NODE_FIELD(arg);
975         WRITE_ENUM_FIELD(booltesttype, BoolTestType);
976 }
977
978 static void
979 _outCoerceToDomain(StringInfo str, CoerceToDomain *node)
980 {
981         WRITE_NODE_TYPE("COERCETODOMAIN");
982
983         WRITE_NODE_FIELD(arg);
984         WRITE_OID_FIELD(resulttype);
985         WRITE_INT_FIELD(resulttypmod);
986         WRITE_ENUM_FIELD(coercionformat, CoercionForm);
987 }
988
989 static void
990 _outCoerceToDomainValue(StringInfo str, CoerceToDomainValue *node)
991 {
992         WRITE_NODE_TYPE("COERCETODOMAINVALUE");
993
994         WRITE_OID_FIELD(typeId);
995         WRITE_INT_FIELD(typeMod);
996 }
997
998 static void
999 _outSetToDefault(StringInfo str, SetToDefault *node)
1000 {
1001         WRITE_NODE_TYPE("SETTODEFAULT");
1002
1003         WRITE_OID_FIELD(typeId);
1004         WRITE_INT_FIELD(typeMod);
1005 }
1006
1007 static void
1008 _outTargetEntry(StringInfo str, TargetEntry *node)
1009 {
1010         WRITE_NODE_TYPE("TARGETENTRY");
1011
1012         WRITE_NODE_FIELD(expr);
1013         WRITE_INT_FIELD(resno);
1014         WRITE_STRING_FIELD(resname);
1015         WRITE_UINT_FIELD(ressortgroupref);
1016         WRITE_OID_FIELD(resorigtbl);
1017         WRITE_INT_FIELD(resorigcol);
1018         WRITE_BOOL_FIELD(resjunk);
1019 }
1020
1021 static void
1022 _outRangeTblRef(StringInfo str, RangeTblRef *node)
1023 {
1024         WRITE_NODE_TYPE("RANGETBLREF");
1025
1026         WRITE_INT_FIELD(rtindex);
1027 }
1028
1029 static void
1030 _outJoinExpr(StringInfo str, JoinExpr *node)
1031 {
1032         WRITE_NODE_TYPE("JOINEXPR");
1033
1034         WRITE_ENUM_FIELD(jointype, JoinType);
1035         WRITE_BOOL_FIELD(isNatural);
1036         WRITE_NODE_FIELD(larg);
1037         WRITE_NODE_FIELD(rarg);
1038         WRITE_NODE_FIELD(using);
1039         WRITE_NODE_FIELD(quals);
1040         WRITE_NODE_FIELD(alias);
1041         WRITE_INT_FIELD(rtindex);
1042 }
1043
1044 static void
1045 _outFromExpr(StringInfo str, FromExpr *node)
1046 {
1047         WRITE_NODE_TYPE("FROMEXPR");
1048
1049         WRITE_NODE_FIELD(fromlist);
1050         WRITE_NODE_FIELD(quals);
1051 }
1052
1053 /*****************************************************************************
1054  *
1055  *      Stuff from relation.h.
1056  *
1057  *****************************************************************************/
1058
1059 /*
1060  * print the basic stuff of all nodes that inherit from Path
1061  *
1062  * Note we do NOT print the parent, else we'd be in infinite recursion
1063  */
1064 static void
1065 _outPathInfo(StringInfo str, Path *node)
1066 {
1067         WRITE_ENUM_FIELD(pathtype, NodeTag);
1068         WRITE_FLOAT_FIELD(startup_cost, "%.2f");
1069         WRITE_FLOAT_FIELD(total_cost, "%.2f");
1070         WRITE_NODE_FIELD(pathkeys);
1071 }
1072
1073 /*
1074  * print the basic stuff of all nodes that inherit from JoinPath
1075  */
1076 static void
1077 _outJoinPathInfo(StringInfo str, JoinPath *node)
1078 {
1079         _outPathInfo(str, (Path *) node);
1080
1081         WRITE_ENUM_FIELD(jointype, JoinType);
1082         WRITE_NODE_FIELD(outerjoinpath);
1083         WRITE_NODE_FIELD(innerjoinpath);
1084         WRITE_NODE_FIELD(joinrestrictinfo);
1085 }
1086
1087 static void
1088 _outPath(StringInfo str, Path *node)
1089 {
1090         WRITE_NODE_TYPE("PATH");
1091
1092         _outPathInfo(str, (Path *) node);
1093 }
1094
1095 static void
1096 _outIndexPath(StringInfo str, IndexPath *node)
1097 {
1098         WRITE_NODE_TYPE("INDEXPATH");
1099
1100         _outPathInfo(str, (Path *) node);
1101
1102         WRITE_NODE_FIELD(indexinfo);
1103         WRITE_NODE_FIELD(indexclauses);
1104         WRITE_NODE_FIELD(indexquals);
1105         WRITE_BOOL_FIELD(isjoininner);
1106         WRITE_ENUM_FIELD(indexscandir, ScanDirection);
1107         WRITE_FLOAT_FIELD(indextotalcost, "%.2f");
1108         WRITE_FLOAT_FIELD(indexselectivity, "%.4f");
1109         WRITE_FLOAT_FIELD(rows, "%.0f");
1110 }
1111
1112 static void
1113 _outBitmapHeapPath(StringInfo str, BitmapHeapPath *node)
1114 {
1115         WRITE_NODE_TYPE("BITMAPHEAPPATH");
1116
1117         _outPathInfo(str, (Path *) node);
1118
1119         WRITE_NODE_FIELD(bitmapqual);
1120         WRITE_BOOL_FIELD(isjoininner);
1121         WRITE_FLOAT_FIELD(rows, "%.0f");
1122 }
1123
1124 static void
1125 _outBitmapAndPath(StringInfo str, BitmapAndPath *node)
1126 {
1127         WRITE_NODE_TYPE("BITMAPANDPATH");
1128
1129         _outPathInfo(str, (Path *) node);
1130
1131         WRITE_NODE_FIELD(bitmapquals);
1132         WRITE_FLOAT_FIELD(bitmapselectivity, "%.4f");
1133 }
1134
1135 static void
1136 _outBitmapOrPath(StringInfo str, BitmapOrPath *node)
1137 {
1138         WRITE_NODE_TYPE("BITMAPORPATH");
1139
1140         _outPathInfo(str, (Path *) node);
1141
1142         WRITE_NODE_FIELD(bitmapquals);
1143         WRITE_FLOAT_FIELD(bitmapselectivity, "%.4f");
1144 }
1145
1146 static void
1147 _outTidPath(StringInfo str, TidPath *node)
1148 {
1149         WRITE_NODE_TYPE("TIDPATH");
1150
1151         _outPathInfo(str, (Path *) node);
1152
1153         WRITE_NODE_FIELD(tidquals);
1154 }
1155
1156 static void
1157 _outAppendPath(StringInfo str, AppendPath *node)
1158 {
1159         WRITE_NODE_TYPE("APPENDPATH");
1160
1161         _outPathInfo(str, (Path *) node);
1162
1163         WRITE_NODE_FIELD(subpaths);
1164 }
1165
1166 static void
1167 _outResultPath(StringInfo str, ResultPath *node)
1168 {
1169         WRITE_NODE_TYPE("RESULTPATH");
1170
1171         _outPathInfo(str, (Path *) node);
1172
1173         WRITE_NODE_FIELD(quals);
1174 }
1175
1176 static void
1177 _outMaterialPath(StringInfo str, MaterialPath *node)
1178 {
1179         WRITE_NODE_TYPE("MATERIALPATH");
1180
1181         _outPathInfo(str, (Path *) node);
1182
1183         WRITE_NODE_FIELD(subpath);
1184 }
1185
1186 static void
1187 _outUniquePath(StringInfo str, UniquePath *node)
1188 {
1189         WRITE_NODE_TYPE("UNIQUEPATH");
1190
1191         _outPathInfo(str, (Path *) node);
1192
1193         WRITE_NODE_FIELD(subpath);
1194         WRITE_ENUM_FIELD(umethod, UniquePathMethod);
1195         WRITE_FLOAT_FIELD(rows, "%.0f");
1196 }
1197
1198 static void
1199 _outNestPath(StringInfo str, NestPath *node)
1200 {
1201         WRITE_NODE_TYPE("NESTPATH");
1202
1203         _outJoinPathInfo(str, (JoinPath *) node);
1204 }
1205
1206 static void
1207 _outMergePath(StringInfo str, MergePath *node)
1208 {
1209         WRITE_NODE_TYPE("MERGEPATH");
1210
1211         _outJoinPathInfo(str, (JoinPath *) node);
1212
1213         WRITE_NODE_FIELD(path_mergeclauses);
1214         WRITE_NODE_FIELD(outersortkeys);
1215         WRITE_NODE_FIELD(innersortkeys);
1216 }
1217
1218 static void
1219 _outHashPath(StringInfo str, HashPath *node)
1220 {
1221         WRITE_NODE_TYPE("HASHPATH");
1222
1223         _outJoinPathInfo(str, (JoinPath *) node);
1224
1225         WRITE_NODE_FIELD(path_hashclauses);
1226 }
1227
1228 static void
1229 _outPlannerInfo(StringInfo str, PlannerInfo *node)
1230 {
1231         WRITE_NODE_TYPE("PLANNERINFO");
1232
1233         /* NB: this isn't a complete set of fields */
1234         WRITE_NODE_FIELD(parse);
1235         WRITE_NODE_FIELD(join_rel_list);
1236         WRITE_NODE_FIELD(eq_classes);
1237         WRITE_NODE_FIELD(canon_pathkeys);
1238         WRITE_NODE_FIELD(left_join_clauses);
1239         WRITE_NODE_FIELD(right_join_clauses);
1240         WRITE_NODE_FIELD(full_join_clauses);
1241         WRITE_NODE_FIELD(oj_info_list);
1242         WRITE_NODE_FIELD(in_info_list);
1243         WRITE_NODE_FIELD(append_rel_list);
1244         WRITE_NODE_FIELD(query_pathkeys);
1245         WRITE_NODE_FIELD(group_pathkeys);
1246         WRITE_NODE_FIELD(sort_pathkeys);
1247         WRITE_FLOAT_FIELD(total_table_pages, "%.0f");
1248         WRITE_FLOAT_FIELD(tuple_fraction, "%.4f");
1249         WRITE_BOOL_FIELD(hasJoinRTEs);
1250         WRITE_BOOL_FIELD(hasOuterJoins);
1251         WRITE_BOOL_FIELD(hasHavingQual);
1252         WRITE_BOOL_FIELD(hasPseudoConstantQuals);
1253 }
1254
1255 static void
1256 _outRelOptInfo(StringInfo str, RelOptInfo *node)
1257 {
1258         WRITE_NODE_TYPE("RELOPTINFO");
1259
1260         /* NB: this isn't a complete set of fields */
1261         WRITE_ENUM_FIELD(reloptkind, RelOptKind);
1262         WRITE_BITMAPSET_FIELD(relids);
1263         WRITE_FLOAT_FIELD(rows, "%.0f");
1264         WRITE_INT_FIELD(width);
1265         WRITE_NODE_FIELD(reltargetlist);
1266         WRITE_NODE_FIELD(pathlist);
1267         WRITE_NODE_FIELD(cheapest_startup_path);
1268         WRITE_NODE_FIELD(cheapest_total_path);
1269         WRITE_NODE_FIELD(cheapest_unique_path);
1270         WRITE_UINT_FIELD(relid);
1271         WRITE_ENUM_FIELD(rtekind, RTEKind);
1272         WRITE_INT_FIELD(min_attr);
1273         WRITE_INT_FIELD(max_attr);
1274         WRITE_NODE_FIELD(indexlist);
1275         WRITE_UINT_FIELD(pages);
1276         WRITE_FLOAT_FIELD(tuples, "%.0f");
1277         WRITE_NODE_FIELD(subplan);
1278         WRITE_NODE_FIELD(baserestrictinfo);
1279         WRITE_NODE_FIELD(joininfo);
1280         WRITE_BOOL_FIELD(has_eclass_joins);
1281         WRITE_BITMAPSET_FIELD(index_outer_relids);
1282         WRITE_NODE_FIELD(index_inner_paths);
1283 }
1284
1285 static void
1286 _outIndexOptInfo(StringInfo str, IndexOptInfo *node)
1287 {
1288         WRITE_NODE_TYPE("INDEXOPTINFO");
1289
1290         /* NB: this isn't a complete set of fields */
1291         WRITE_OID_FIELD(indexoid);
1292         /* Do NOT print rel field, else infinite recursion */
1293         WRITE_UINT_FIELD(pages);
1294         WRITE_FLOAT_FIELD(tuples, "%.0f");
1295         WRITE_INT_FIELD(ncolumns);
1296         WRITE_NODE_FIELD(indexprs);
1297         WRITE_NODE_FIELD(indpred);
1298         WRITE_BOOL_FIELD(predOK);
1299         WRITE_BOOL_FIELD(unique);
1300 }
1301
1302 static void
1303 _outEquivalenceClass(StringInfo str, EquivalenceClass *node)
1304 {
1305         /*
1306          * To simplify reading, we just chase up to the topmost merged EC and
1307          * print that, without bothering to show the merge-ees separately.
1308          */
1309         while (node->ec_merged)
1310                 node = node->ec_merged;
1311
1312         WRITE_NODE_TYPE("EQUIVALENCECLASS");
1313
1314         WRITE_NODE_FIELD(ec_opfamilies);
1315         WRITE_NODE_FIELD(ec_members);
1316         WRITE_NODE_FIELD(ec_sources);
1317         WRITE_NODE_FIELD(ec_derives);
1318         WRITE_BITMAPSET_FIELD(ec_relids);
1319         WRITE_BOOL_FIELD(ec_has_const);
1320         WRITE_BOOL_FIELD(ec_has_volatile);
1321         WRITE_BOOL_FIELD(ec_below_outer_join);
1322         WRITE_BOOL_FIELD(ec_broken);
1323 }
1324
1325 static void
1326 _outEquivalenceMember(StringInfo str, EquivalenceMember *node)
1327 {
1328         WRITE_NODE_TYPE("EQUIVALENCEMEMBER");
1329
1330         WRITE_NODE_FIELD(em_expr);
1331         WRITE_BITMAPSET_FIELD(em_relids);
1332         WRITE_BOOL_FIELD(em_is_const);
1333         WRITE_BOOL_FIELD(em_is_child);
1334         WRITE_OID_FIELD(em_datatype);
1335 }
1336
1337 static void
1338 _outPathKey(StringInfo str, PathKey *node)
1339 {
1340         WRITE_NODE_TYPE("PATHKEY");
1341
1342         WRITE_NODE_FIELD(pk_eclass);
1343         WRITE_OID_FIELD(pk_opfamily);
1344         WRITE_INT_FIELD(pk_strategy);
1345         WRITE_BOOL_FIELD(pk_nulls_first);
1346 }
1347
1348 static void
1349 _outRestrictInfo(StringInfo str, RestrictInfo *node)
1350 {
1351         WRITE_NODE_TYPE("RESTRICTINFO");
1352
1353         /* NB: this isn't a complete set of fields */
1354         WRITE_NODE_FIELD(clause);
1355         WRITE_BOOL_FIELD(is_pushed_down);
1356         WRITE_BOOL_FIELD(outerjoin_delayed);
1357         WRITE_BOOL_FIELD(can_join);
1358         WRITE_BOOL_FIELD(pseudoconstant);
1359         WRITE_BITMAPSET_FIELD(clause_relids);
1360         WRITE_BITMAPSET_FIELD(required_relids);
1361         WRITE_BITMAPSET_FIELD(left_relids);
1362         WRITE_BITMAPSET_FIELD(right_relids);
1363         WRITE_NODE_FIELD(orclause);
1364         /* don't write parent_ec, leads to infinite recursion in plan tree dump */
1365         WRITE_NODE_FIELD(mergeopfamilies);
1366         /* don't write left_ec, leads to infinite recursion in plan tree dump */
1367         /* don't write right_ec, leads to infinite recursion in plan tree dump */
1368         WRITE_NODE_FIELD(left_em);
1369         WRITE_NODE_FIELD(right_em);
1370         WRITE_BOOL_FIELD(outer_is_left);
1371         WRITE_OID_FIELD(hashjoinoperator);
1372 }
1373
1374 static void
1375 _outInnerIndexscanInfo(StringInfo str, InnerIndexscanInfo *node)
1376 {
1377         WRITE_NODE_TYPE("INNERINDEXSCANINFO");
1378         WRITE_BITMAPSET_FIELD(other_relids);
1379         WRITE_BOOL_FIELD(isouterjoin);
1380         WRITE_NODE_FIELD(best_innerpath);
1381 }
1382
1383 static void
1384 _outOuterJoinInfo(StringInfo str, OuterJoinInfo *node)
1385 {
1386         WRITE_NODE_TYPE("OUTERJOININFO");
1387
1388         WRITE_BITMAPSET_FIELD(min_lefthand);
1389         WRITE_BITMAPSET_FIELD(min_righthand);
1390         WRITE_BOOL_FIELD(is_full_join);
1391         WRITE_BOOL_FIELD(lhs_strict);
1392 }
1393
1394 static void
1395 _outInClauseInfo(StringInfo str, InClauseInfo *node)
1396 {
1397         WRITE_NODE_TYPE("INCLAUSEINFO");
1398
1399         WRITE_BITMAPSET_FIELD(lefthand);
1400         WRITE_BITMAPSET_FIELD(righthand);
1401         WRITE_NODE_FIELD(sub_targetlist);
1402         WRITE_NODE_FIELD(in_operators);
1403 }
1404
1405 static void
1406 _outAppendRelInfo(StringInfo str, AppendRelInfo *node)
1407 {
1408         WRITE_NODE_TYPE("APPENDRELINFO");
1409
1410         WRITE_UINT_FIELD(parent_relid);
1411         WRITE_UINT_FIELD(child_relid);
1412         WRITE_OID_FIELD(parent_reltype);
1413         WRITE_OID_FIELD(child_reltype);
1414         WRITE_NODE_FIELD(col_mappings);
1415         WRITE_NODE_FIELD(translated_vars);
1416         WRITE_OID_FIELD(parent_reloid);
1417 }
1418
1419 /*****************************************************************************
1420  *
1421  *      Stuff from parsenodes.h.
1422  *
1423  *****************************************************************************/
1424
1425 static void
1426 _outCreateStmt(StringInfo str, CreateStmt *node)
1427 {
1428         WRITE_NODE_TYPE("CREATESTMT");
1429
1430         WRITE_NODE_FIELD(relation);
1431         WRITE_NODE_FIELD(tableElts);
1432         WRITE_NODE_FIELD(inhRelations);
1433         WRITE_NODE_FIELD(constraints);
1434         WRITE_NODE_FIELD(options);
1435         WRITE_ENUM_FIELD(oncommit, OnCommitAction);
1436         WRITE_STRING_FIELD(tablespacename);
1437 }
1438
1439 static void
1440 _outIndexStmt(StringInfo str, IndexStmt *node)
1441 {
1442         WRITE_NODE_TYPE("INDEXSTMT");
1443
1444         WRITE_STRING_FIELD(idxname);
1445         WRITE_NODE_FIELD(relation);
1446         WRITE_STRING_FIELD(accessMethod);
1447         WRITE_STRING_FIELD(tableSpace);
1448         WRITE_NODE_FIELD(indexParams);
1449         WRITE_NODE_FIELD(options);
1450         WRITE_NODE_FIELD(whereClause);
1451         WRITE_NODE_FIELD(rangetable);
1452         WRITE_BOOL_FIELD(unique);
1453         WRITE_BOOL_FIELD(primary);
1454         WRITE_BOOL_FIELD(isconstraint);
1455         WRITE_BOOL_FIELD(concurrent);
1456 }
1457
1458 static void
1459 _outNotifyStmt(StringInfo str, NotifyStmt *node)
1460 {
1461         WRITE_NODE_TYPE("NOTIFY");
1462
1463         WRITE_NODE_FIELD(relation);
1464 }
1465
1466 static void
1467 _outDeclareCursorStmt(StringInfo str, DeclareCursorStmt *node)
1468 {
1469         WRITE_NODE_TYPE("DECLARECURSOR");
1470
1471         WRITE_STRING_FIELD(portalname);
1472         WRITE_INT_FIELD(options);
1473         WRITE_NODE_FIELD(query);
1474 }
1475
1476 static void
1477 _outSelectStmt(StringInfo str, SelectStmt *node)
1478 {
1479         WRITE_NODE_TYPE("SELECT");
1480
1481         WRITE_NODE_FIELD(distinctClause);
1482         WRITE_NODE_FIELD(into);
1483         WRITE_NODE_FIELD(intoColNames);
1484         WRITE_NODE_FIELD(intoOptions);
1485         WRITE_ENUM_FIELD(intoOnCommit, OnCommitAction);
1486         WRITE_STRING_FIELD(intoTableSpaceName);
1487         WRITE_NODE_FIELD(targetList);
1488         WRITE_NODE_FIELD(fromClause);
1489         WRITE_NODE_FIELD(whereClause);
1490         WRITE_NODE_FIELD(groupClause);
1491         WRITE_NODE_FIELD(havingClause);
1492         WRITE_NODE_FIELD(valuesLists);
1493         WRITE_NODE_FIELD(sortClause);
1494         WRITE_NODE_FIELD(limitOffset);
1495         WRITE_NODE_FIELD(limitCount);
1496         WRITE_NODE_FIELD(lockingClause);
1497         WRITE_ENUM_FIELD(op, SetOperation);
1498         WRITE_BOOL_FIELD(all);
1499         WRITE_NODE_FIELD(larg);
1500         WRITE_NODE_FIELD(rarg);
1501 }
1502
1503 static void
1504 _outFuncCall(StringInfo str, FuncCall *node)
1505 {
1506         WRITE_NODE_TYPE("FUNCCALL");
1507
1508         WRITE_NODE_FIELD(funcname);
1509         WRITE_NODE_FIELD(args);
1510         WRITE_BOOL_FIELD(agg_star);
1511         WRITE_BOOL_FIELD(agg_distinct);
1512         WRITE_INT_FIELD(location);
1513 }
1514
1515 static void
1516 _outDefElem(StringInfo str, DefElem *node)
1517 {
1518         WRITE_NODE_TYPE("DEFELEM");
1519
1520         WRITE_STRING_FIELD(defname);
1521         WRITE_NODE_FIELD(arg);
1522 }
1523
1524 static void
1525 _outLockingClause(StringInfo str, LockingClause *node)
1526 {
1527         WRITE_NODE_TYPE("LOCKINGCLAUSE");
1528
1529         WRITE_NODE_FIELD(lockedRels);
1530         WRITE_BOOL_FIELD(forUpdate);
1531         WRITE_BOOL_FIELD(noWait);
1532 }
1533
1534 static void
1535 _outXmlSerialize(StringInfo str, XmlSerialize *node)
1536 {
1537         WRITE_NODE_TYPE("XMLSERIALIZE");
1538
1539         WRITE_ENUM_FIELD(xmloption, XmlOptionType);
1540         WRITE_NODE_FIELD(expr);
1541         WRITE_NODE_FIELD(typename);
1542 }
1543
1544 static void
1545 _outColumnDef(StringInfo str, ColumnDef *node)
1546 {
1547         WRITE_NODE_TYPE("COLUMNDEF");
1548
1549         WRITE_STRING_FIELD(colname);
1550         WRITE_NODE_FIELD(typename);
1551         WRITE_INT_FIELD(inhcount);
1552         WRITE_BOOL_FIELD(is_local);
1553         WRITE_BOOL_FIELD(is_not_null);
1554         WRITE_NODE_FIELD(raw_default);
1555         WRITE_STRING_FIELD(cooked_default);
1556         WRITE_NODE_FIELD(constraints);
1557 }
1558
1559 static void
1560 _outTypeName(StringInfo str, TypeName *node)
1561 {
1562         WRITE_NODE_TYPE("TYPENAME");
1563
1564         WRITE_NODE_FIELD(names);
1565         WRITE_OID_FIELD(typeid);
1566         WRITE_BOOL_FIELD(timezone);
1567         WRITE_BOOL_FIELD(setof);
1568         WRITE_BOOL_FIELD(pct_type);
1569         WRITE_NODE_FIELD(typmods);
1570         WRITE_INT_FIELD(typemod);
1571         WRITE_NODE_FIELD(arrayBounds);
1572         WRITE_INT_FIELD(location);
1573 }
1574
1575 static void
1576 _outTypeCast(StringInfo str, TypeCast *node)
1577 {
1578         WRITE_NODE_TYPE("TYPECAST");
1579
1580         WRITE_NODE_FIELD(arg);
1581         WRITE_NODE_FIELD(typename);
1582 }
1583
1584 static void
1585 _outIndexElem(StringInfo str, IndexElem *node)
1586 {
1587         WRITE_NODE_TYPE("INDEXELEM");
1588
1589         WRITE_STRING_FIELD(name);
1590         WRITE_NODE_FIELD(expr);
1591         WRITE_NODE_FIELD(opclass);
1592         WRITE_ENUM_FIELD(ordering, SortByDir);
1593         WRITE_ENUM_FIELD(nulls_ordering, SortByNulls);
1594 }
1595
1596 static void
1597 _outQuery(StringInfo str, Query *node)
1598 {
1599         WRITE_NODE_TYPE("QUERY");
1600
1601         WRITE_ENUM_FIELD(commandType, CmdType);
1602         WRITE_ENUM_FIELD(querySource, QuerySource);
1603         WRITE_BOOL_FIELD(canSetTag);
1604
1605         /*
1606          * Hack to work around missing outfuncs routines for a lot of the
1607          * utility-statement node types.  (The only one we actually *need* for
1608          * rules support is NotifyStmt.)  Someday we ought to support 'em all, but
1609          * for the meantime do this to avoid getting lots of warnings when running
1610          * with debug_print_parse on.
1611          */
1612         if (node->utilityStmt)
1613         {
1614                 switch (nodeTag(node->utilityStmt))
1615                 {
1616                         case T_CreateStmt:
1617                         case T_IndexStmt:
1618                         case T_NotifyStmt:
1619                         case T_DeclareCursorStmt:
1620                                 WRITE_NODE_FIELD(utilityStmt);
1621                                 break;
1622                         default:
1623                                 appendStringInfo(str, " :utilityStmt ?");
1624                                 break;
1625                 }
1626         }
1627         else
1628                 appendStringInfo(str, " :utilityStmt <>");
1629
1630         WRITE_INT_FIELD(resultRelation);
1631         WRITE_NODE_FIELD(into);
1632         WRITE_NODE_FIELD(intoOptions);
1633         WRITE_ENUM_FIELD(intoOnCommit, OnCommitAction);
1634         WRITE_STRING_FIELD(intoTableSpaceName);
1635         WRITE_BOOL_FIELD(hasAggs);
1636         WRITE_BOOL_FIELD(hasSubLinks);
1637         WRITE_NODE_FIELD(rtable);
1638         WRITE_NODE_FIELD(jointree);
1639         WRITE_NODE_FIELD(targetList);
1640         WRITE_NODE_FIELD(returningList);
1641         WRITE_NODE_FIELD(groupClause);
1642         WRITE_NODE_FIELD(havingQual);
1643         WRITE_NODE_FIELD(distinctClause);
1644         WRITE_NODE_FIELD(sortClause);
1645         WRITE_NODE_FIELD(limitOffset);
1646         WRITE_NODE_FIELD(limitCount);
1647         WRITE_NODE_FIELD(rowMarks);
1648         WRITE_NODE_FIELD(setOperations);
1649         WRITE_NODE_FIELD(resultRelations);
1650         WRITE_NODE_FIELD(returningLists);
1651 }
1652
1653 static void
1654 _outSortClause(StringInfo str, SortClause *node)
1655 {
1656         WRITE_NODE_TYPE("SORTCLAUSE");
1657
1658         WRITE_UINT_FIELD(tleSortGroupRef);
1659         WRITE_OID_FIELD(sortop);
1660         WRITE_BOOL_FIELD(nulls_first);
1661 }
1662
1663 static void
1664 _outGroupClause(StringInfo str, GroupClause *node)
1665 {
1666         WRITE_NODE_TYPE("GROUPCLAUSE");
1667
1668         WRITE_UINT_FIELD(tleSortGroupRef);
1669         WRITE_OID_FIELD(sortop);
1670         WRITE_BOOL_FIELD(nulls_first);
1671 }
1672
1673 static void
1674 _outRowMarkClause(StringInfo str, RowMarkClause *node)
1675 {
1676         WRITE_NODE_TYPE("ROWMARKCLAUSE");
1677
1678         WRITE_UINT_FIELD(rti);
1679         WRITE_BOOL_FIELD(forUpdate);
1680         WRITE_BOOL_FIELD(noWait);
1681 }
1682
1683 static void
1684 _outSetOperationStmt(StringInfo str, SetOperationStmt *node)
1685 {
1686         WRITE_NODE_TYPE("SETOPERATIONSTMT");
1687
1688         WRITE_ENUM_FIELD(op, SetOperation);
1689         WRITE_BOOL_FIELD(all);
1690         WRITE_NODE_FIELD(larg);
1691         WRITE_NODE_FIELD(rarg);
1692         WRITE_NODE_FIELD(colTypes);
1693         WRITE_NODE_FIELD(colTypmods);
1694 }
1695
1696 static void
1697 _outRangeTblEntry(StringInfo str, RangeTblEntry *node)
1698 {
1699         WRITE_NODE_TYPE("RTE");
1700
1701         /* put alias + eref first to make dump more legible */
1702         WRITE_NODE_FIELD(alias);
1703         WRITE_NODE_FIELD(eref);
1704         WRITE_ENUM_FIELD(rtekind, RTEKind);
1705
1706         switch (node->rtekind)
1707         {
1708                 case RTE_RELATION:
1709                 case RTE_SPECIAL:
1710                         WRITE_OID_FIELD(relid);
1711                         break;
1712                 case RTE_SUBQUERY:
1713                         WRITE_NODE_FIELD(subquery);
1714                         break;
1715                 case RTE_FUNCTION:
1716                         WRITE_NODE_FIELD(funcexpr);
1717                         WRITE_NODE_FIELD(funccoltypes);
1718                         WRITE_NODE_FIELD(funccoltypmods);
1719                         break;
1720                 case RTE_VALUES:
1721                         WRITE_NODE_FIELD(values_lists);
1722                         break;
1723                 case RTE_JOIN:
1724                         WRITE_ENUM_FIELD(jointype, JoinType);
1725                         WRITE_NODE_FIELD(joinaliasvars);
1726                         break;
1727                 default:
1728                         elog(ERROR, "unrecognized RTE kind: %d", (int) node->rtekind);
1729                         break;
1730         }
1731
1732         WRITE_BOOL_FIELD(inh);
1733         WRITE_BOOL_FIELD(inFromCl);
1734         WRITE_UINT_FIELD(requiredPerms);
1735         WRITE_OID_FIELD(checkAsUser);
1736 }
1737
1738 static void
1739 _outAExpr(StringInfo str, A_Expr *node)
1740 {
1741         WRITE_NODE_TYPE("AEXPR");
1742
1743         switch (node->kind)
1744         {
1745                 case AEXPR_OP:
1746                         appendStringInfo(str, " ");
1747                         WRITE_NODE_FIELD(name);
1748                         break;
1749                 case AEXPR_AND:
1750                         appendStringInfo(str, " AND");
1751                         break;
1752                 case AEXPR_OR:
1753                         appendStringInfo(str, " OR");
1754                         break;
1755                 case AEXPR_NOT:
1756                         appendStringInfo(str, " NOT");
1757                         break;
1758                 case AEXPR_OP_ANY:
1759                         appendStringInfo(str, " ");
1760                         WRITE_NODE_FIELD(name);
1761                         appendStringInfo(str, " ANY ");
1762                         break;
1763                 case AEXPR_OP_ALL:
1764                         appendStringInfo(str, " ");
1765                         WRITE_NODE_FIELD(name);
1766                         appendStringInfo(str, " ALL ");
1767                         break;
1768                 case AEXPR_DISTINCT:
1769                         appendStringInfo(str, " DISTINCT ");
1770                         WRITE_NODE_FIELD(name);
1771                         break;
1772                 case AEXPR_NULLIF:
1773                         appendStringInfo(str, " NULLIF ");
1774                         WRITE_NODE_FIELD(name);
1775                         break;
1776                 case AEXPR_OF:
1777                         appendStringInfo(str, " OF ");
1778                         WRITE_NODE_FIELD(name);
1779                         break;
1780                 case AEXPR_IN:
1781                         appendStringInfo(str, " IN ");
1782                         WRITE_NODE_FIELD(name);
1783                         break;
1784                 default:
1785                         appendStringInfo(str, " ??");
1786                         break;
1787         }
1788
1789         WRITE_NODE_FIELD(lexpr);
1790         WRITE_NODE_FIELD(rexpr);
1791         WRITE_INT_FIELD(location);
1792 }
1793
1794 static void
1795 _outValue(StringInfo str, Value *value)
1796 {
1797         switch (value->type)
1798         {
1799                 case T_Integer:
1800                         appendStringInfo(str, "%ld", value->val.ival);
1801                         break;
1802                 case T_Float:
1803
1804                         /*
1805                          * We assume the value is a valid numeric literal and so does not
1806                          * need quoting.
1807                          */
1808                         appendStringInfoString(str, value->val.str);
1809                         break;
1810                 case T_String:
1811                         appendStringInfoChar(str, '"');
1812                         _outToken(str, value->val.str);
1813                         appendStringInfoChar(str, '"');
1814                         break;
1815                 case T_BitString:
1816                         /* internal representation already has leading 'b' */
1817                         appendStringInfoString(str, value->val.str);
1818                         break;
1819                 default:
1820                         elog(ERROR, "unrecognized node type: %d", (int) value->type);
1821                         break;
1822         }
1823 }
1824
1825 static void
1826 _outColumnRef(StringInfo str, ColumnRef *node)
1827 {
1828         WRITE_NODE_TYPE("COLUMNREF");
1829
1830         WRITE_NODE_FIELD(fields);
1831         WRITE_INT_FIELD(location);
1832 }
1833
1834 static void
1835 _outParamRef(StringInfo str, ParamRef *node)
1836 {
1837         WRITE_NODE_TYPE("PARAMREF");
1838
1839         WRITE_INT_FIELD(number);
1840 }
1841
1842 static void
1843 _outAConst(StringInfo str, A_Const *node)
1844 {
1845         WRITE_NODE_TYPE("A_CONST");
1846
1847         appendStringInfo(str, " :val ");
1848         _outValue(str, &(node->val));
1849         WRITE_NODE_FIELD(typename);
1850 }
1851
1852 static void
1853 _outA_Indices(StringInfo str, A_Indices *node)
1854 {
1855         WRITE_NODE_TYPE("A_INDICES");
1856
1857         WRITE_NODE_FIELD(lidx);
1858         WRITE_NODE_FIELD(uidx);
1859 }
1860
1861 static void
1862 _outA_Indirection(StringInfo str, A_Indirection *node)
1863 {
1864         WRITE_NODE_TYPE("A_INDIRECTION");
1865
1866         WRITE_NODE_FIELD(arg);
1867         WRITE_NODE_FIELD(indirection);
1868 }
1869
1870 static void
1871 _outResTarget(StringInfo str, ResTarget *node)
1872 {
1873         WRITE_NODE_TYPE("RESTARGET");
1874
1875         WRITE_STRING_FIELD(name);
1876         WRITE_NODE_FIELD(indirection);
1877         WRITE_NODE_FIELD(val);
1878         WRITE_INT_FIELD(location);
1879 }
1880
1881 static void
1882 _outConstraint(StringInfo str, Constraint *node)
1883 {
1884         WRITE_NODE_TYPE("CONSTRAINT");
1885
1886         WRITE_STRING_FIELD(name);
1887
1888         appendStringInfo(str, " :contype ");
1889         switch (node->contype)
1890         {
1891                 case CONSTR_PRIMARY:
1892                         appendStringInfo(str, "PRIMARY_KEY");
1893                         WRITE_NODE_FIELD(keys);
1894                         WRITE_NODE_FIELD(options);
1895                         WRITE_STRING_FIELD(indexspace);
1896                         break;
1897
1898                 case CONSTR_UNIQUE:
1899                         appendStringInfo(str, "UNIQUE");
1900                         WRITE_NODE_FIELD(keys);
1901                         WRITE_NODE_FIELD(options);
1902                         WRITE_STRING_FIELD(indexspace);
1903                         break;
1904
1905                 case CONSTR_CHECK:
1906                         appendStringInfo(str, "CHECK");
1907                         WRITE_NODE_FIELD(raw_expr);
1908                         WRITE_STRING_FIELD(cooked_expr);
1909                         break;
1910
1911                 case CONSTR_DEFAULT:
1912                         appendStringInfo(str, "DEFAULT");
1913                         WRITE_NODE_FIELD(raw_expr);
1914                         WRITE_STRING_FIELD(cooked_expr);
1915                         break;
1916
1917                 case CONSTR_NOTNULL:
1918                         appendStringInfo(str, "NOT_NULL");
1919                         break;
1920
1921                 default:
1922                         appendStringInfo(str, "<unrecognized_constraint>");
1923                         break;
1924         }
1925 }
1926
1927 static void
1928 _outFkConstraint(StringInfo str, FkConstraint *node)
1929 {
1930         WRITE_NODE_TYPE("FKCONSTRAINT");
1931
1932         WRITE_STRING_FIELD(constr_name);
1933         WRITE_NODE_FIELD(pktable);
1934         WRITE_NODE_FIELD(fk_attrs);
1935         WRITE_NODE_FIELD(pk_attrs);
1936         WRITE_CHAR_FIELD(fk_matchtype);
1937         WRITE_CHAR_FIELD(fk_upd_action);
1938         WRITE_CHAR_FIELD(fk_del_action);
1939         WRITE_BOOL_FIELD(deferrable);
1940         WRITE_BOOL_FIELD(initdeferred);
1941         WRITE_BOOL_FIELD(skip_validation);
1942 }
1943
1944
1945 /*
1946  * _outNode -
1947  *        converts a Node into ascii string and append it to 'str'
1948  */
1949 static void
1950 _outNode(StringInfo str, void *obj)
1951 {
1952         if (obj == NULL)
1953                 appendStringInfo(str, "<>");
1954         else if (IsA(obj, List) ||IsA(obj, IntList) || IsA(obj, OidList))
1955                 _outList(str, obj);
1956         else if (IsA(obj, Integer) ||
1957                          IsA(obj, Float) ||
1958                          IsA(obj, String) ||
1959                          IsA(obj, BitString))
1960         {
1961                 /* nodeRead does not want to see { } around these! */
1962                 _outValue(str, obj);
1963         }
1964         else
1965         {
1966                 appendStringInfoChar(str, '{');
1967                 switch (nodeTag(obj))
1968                 {
1969                         case T_Plan:
1970                                 _outPlan(str, obj);
1971                                 break;
1972                         case T_Result:
1973                                 _outResult(str, obj);
1974                                 break;
1975                         case T_Append:
1976                                 _outAppend(str, obj);
1977                                 break;
1978                         case T_BitmapAnd:
1979                                 _outBitmapAnd(str, obj);
1980                                 break;
1981                         case T_BitmapOr:
1982                                 _outBitmapOr(str, obj);
1983                                 break;
1984                         case T_Scan:
1985                                 _outScan(str, obj);
1986                                 break;
1987                         case T_SeqScan:
1988                                 _outSeqScan(str, obj);
1989                                 break;
1990                         case T_IndexScan:
1991                                 _outIndexScan(str, obj);
1992                                 break;
1993                         case T_BitmapIndexScan:
1994                                 _outBitmapIndexScan(str, obj);
1995                                 break;
1996                         case T_BitmapHeapScan:
1997                                 _outBitmapHeapScan(str, obj);
1998                                 break;
1999                         case T_TidScan:
2000                                 _outTidScan(str, obj);
2001                                 break;
2002                         case T_SubqueryScan:
2003                                 _outSubqueryScan(str, obj);
2004                                 break;
2005                         case T_FunctionScan:
2006                                 _outFunctionScan(str, obj);
2007                                 break;
2008                         case T_ValuesScan:
2009                                 _outValuesScan(str, obj);
2010                                 break;
2011                         case T_Join:
2012                                 _outJoin(str, obj);
2013                                 break;
2014                         case T_NestLoop:
2015                                 _outNestLoop(str, obj);
2016                                 break;
2017                         case T_MergeJoin:
2018                                 _outMergeJoin(str, obj);
2019                                 break;
2020                         case T_HashJoin:
2021                                 _outHashJoin(str, obj);
2022                                 break;
2023                         case T_Agg:
2024                                 _outAgg(str, obj);
2025                                 break;
2026                         case T_Group:
2027                                 _outGroup(str, obj);
2028                                 break;
2029                         case T_Material:
2030                                 _outMaterial(str, obj);
2031                                 break;
2032                         case T_Sort:
2033                                 _outSort(str, obj);
2034                                 break;
2035                         case T_Unique:
2036                                 _outUnique(str, obj);
2037                                 break;
2038                         case T_SetOp:
2039                                 _outSetOp(str, obj);
2040                                 break;
2041                         case T_Limit:
2042                                 _outLimit(str, obj);
2043                                 break;
2044                         case T_Hash:
2045                                 _outHash(str, obj);
2046                                 break;
2047                         case T_Alias:
2048                                 _outAlias(str, obj);
2049                                 break;
2050                         case T_RangeVar:
2051                                 _outRangeVar(str, obj);
2052                                 break;
2053                         case T_Var:
2054                                 _outVar(str, obj);
2055                                 break;
2056                         case T_Const:
2057                                 _outConst(str, obj);
2058                                 break;
2059                         case T_Param:
2060                                 _outParam(str, obj);
2061                                 break;
2062                         case T_Aggref:
2063                                 _outAggref(str, obj);
2064                                 break;
2065                         case T_ArrayRef:
2066                                 _outArrayRef(str, obj);
2067                                 break;
2068                         case T_FuncExpr:
2069                                 _outFuncExpr(str, obj);
2070                                 break;
2071                         case T_OpExpr:
2072                                 _outOpExpr(str, obj);
2073                                 break;
2074                         case T_DistinctExpr:
2075                                 _outDistinctExpr(str, obj);
2076                                 break;
2077                         case T_ScalarArrayOpExpr:
2078                                 _outScalarArrayOpExpr(str, obj);
2079                                 break;
2080                         case T_BoolExpr:
2081                                 _outBoolExpr(str, obj);
2082                                 break;
2083                         case T_SubLink:
2084                                 _outSubLink(str, obj);
2085                                 break;
2086                         case T_SubPlan:
2087                                 _outSubPlan(str, obj);
2088                                 break;
2089                         case T_FieldSelect:
2090                                 _outFieldSelect(str, obj);
2091                                 break;
2092                         case T_FieldStore:
2093                                 _outFieldStore(str, obj);
2094                                 break;
2095                         case T_RelabelType:
2096                                 _outRelabelType(str, obj);
2097                                 break;
2098                         case T_ConvertRowtypeExpr:
2099                                 _outConvertRowtypeExpr(str, obj);
2100                                 break;
2101                         case T_CaseExpr:
2102                                 _outCaseExpr(str, obj);
2103                                 break;
2104                         case T_CaseWhen:
2105                                 _outCaseWhen(str, obj);
2106                                 break;
2107                         case T_CaseTestExpr:
2108                                 _outCaseTestExpr(str, obj);
2109                                 break;
2110                         case T_ArrayExpr:
2111                                 _outArrayExpr(str, obj);
2112                                 break;
2113                         case T_RowExpr:
2114                                 _outRowExpr(str, obj);
2115                                 break;
2116                         case T_RowCompareExpr:
2117                                 _outRowCompareExpr(str, obj);
2118                                 break;
2119                         case T_CoalesceExpr:
2120                                 _outCoalesceExpr(str, obj);
2121                                 break;
2122                         case T_MinMaxExpr:
2123                                 _outMinMaxExpr(str, obj);
2124                                 break;
2125                         case T_XmlExpr:
2126                                 _outXmlExpr(str, obj);
2127                                 break;
2128                         case T_NullIfExpr:
2129                                 _outNullIfExpr(str, obj);
2130                                 break;
2131                         case T_NullTest:
2132                                 _outNullTest(str, obj);
2133                                 break;
2134                         case T_BooleanTest:
2135                                 _outBooleanTest(str, obj);
2136                                 break;
2137                         case T_CoerceToDomain:
2138                                 _outCoerceToDomain(str, obj);
2139                                 break;
2140                         case T_CoerceToDomainValue:
2141                                 _outCoerceToDomainValue(str, obj);
2142                                 break;
2143                         case T_SetToDefault:
2144                                 _outSetToDefault(str, obj);
2145                                 break;
2146                         case T_TargetEntry:
2147                                 _outTargetEntry(str, obj);
2148                                 break;
2149                         case T_RangeTblRef:
2150                                 _outRangeTblRef(str, obj);
2151                                 break;
2152                         case T_JoinExpr:
2153                                 _outJoinExpr(str, obj);
2154                                 break;
2155                         case T_FromExpr:
2156                                 _outFromExpr(str, obj);
2157                                 break;
2158
2159                         case T_Path:
2160                                 _outPath(str, obj);
2161                                 break;
2162                         case T_IndexPath:
2163                                 _outIndexPath(str, obj);
2164                                 break;
2165                         case T_BitmapHeapPath:
2166                                 _outBitmapHeapPath(str, obj);
2167                                 break;
2168                         case T_BitmapAndPath:
2169                                 _outBitmapAndPath(str, obj);
2170                                 break;
2171                         case T_BitmapOrPath:
2172                                 _outBitmapOrPath(str, obj);
2173                                 break;
2174                         case T_TidPath:
2175                                 _outTidPath(str, obj);
2176                                 break;
2177                         case T_AppendPath:
2178                                 _outAppendPath(str, obj);
2179                                 break;
2180                         case T_ResultPath:
2181                                 _outResultPath(str, obj);
2182                                 break;
2183                         case T_MaterialPath:
2184                                 _outMaterialPath(str, obj);
2185                                 break;
2186                         case T_UniquePath:
2187                                 _outUniquePath(str, obj);
2188                                 break;
2189                         case T_NestPath:
2190                                 _outNestPath(str, obj);
2191                                 break;
2192                         case T_MergePath:
2193                                 _outMergePath(str, obj);
2194                                 break;
2195                         case T_HashPath:
2196                                 _outHashPath(str, obj);
2197                                 break;
2198                         case T_PlannerInfo:
2199                                 _outPlannerInfo(str, obj);
2200                                 break;
2201                         case T_RelOptInfo:
2202                                 _outRelOptInfo(str, obj);
2203                                 break;
2204                         case T_IndexOptInfo:
2205                                 _outIndexOptInfo(str, obj);
2206                                 break;
2207                         case T_EquivalenceClass:
2208                                 _outEquivalenceClass(str, obj);
2209                                 break;
2210                         case T_EquivalenceMember:
2211                                 _outEquivalenceMember(str, obj);
2212                                 break;
2213                         case T_PathKey:
2214                                 _outPathKey(str, obj);
2215                                 break;
2216                         case T_RestrictInfo:
2217                                 _outRestrictInfo(str, obj);
2218                                 break;
2219                         case T_InnerIndexscanInfo:
2220                                 _outInnerIndexscanInfo(str, obj);
2221                                 break;
2222                         case T_OuterJoinInfo:
2223                                 _outOuterJoinInfo(str, obj);
2224                                 break;
2225                         case T_InClauseInfo:
2226                                 _outInClauseInfo(str, obj);
2227                                 break;
2228                         case T_AppendRelInfo:
2229                                 _outAppendRelInfo(str, obj);
2230                                 break;
2231
2232                         case T_CreateStmt:
2233                                 _outCreateStmt(str, obj);
2234                                 break;
2235                         case T_IndexStmt:
2236                                 _outIndexStmt(str, obj);
2237                                 break;
2238                         case T_NotifyStmt:
2239                                 _outNotifyStmt(str, obj);
2240                                 break;
2241                         case T_DeclareCursorStmt:
2242                                 _outDeclareCursorStmt(str, obj);
2243                                 break;
2244                         case T_SelectStmt:
2245                                 _outSelectStmt(str, obj);
2246                                 break;
2247                         case T_ColumnDef:
2248                                 _outColumnDef(str, obj);
2249                                 break;
2250                         case T_TypeName:
2251                                 _outTypeName(str, obj);
2252                                 break;
2253                         case T_TypeCast:
2254                                 _outTypeCast(str, obj);
2255                                 break;
2256                         case T_IndexElem:
2257                                 _outIndexElem(str, obj);
2258                                 break;
2259                         case T_Query:
2260                                 _outQuery(str, obj);
2261                                 break;
2262                         case T_SortClause:
2263                                 _outSortClause(str, obj);
2264                                 break;
2265                         case T_GroupClause:
2266                                 _outGroupClause(str, obj);
2267                                 break;
2268                         case T_RowMarkClause:
2269                                 _outRowMarkClause(str, obj);
2270                                 break;
2271                         case T_SetOperationStmt:
2272                                 _outSetOperationStmt(str, obj);
2273                                 break;
2274                         case T_RangeTblEntry:
2275                                 _outRangeTblEntry(str, obj);
2276                                 break;
2277                         case T_A_Expr:
2278                                 _outAExpr(str, obj);
2279                                 break;
2280                         case T_ColumnRef:
2281                                 _outColumnRef(str, obj);
2282                                 break;
2283                         case T_ParamRef:
2284                                 _outParamRef(str, obj);
2285                                 break;
2286                         case T_A_Const:
2287                                 _outAConst(str, obj);
2288                                 break;
2289                         case T_A_Indices:
2290                                 _outA_Indices(str, obj);
2291                                 break;
2292                         case T_A_Indirection:
2293                                 _outA_Indirection(str, obj);
2294                                 break;
2295                         case T_ResTarget:
2296                                 _outResTarget(str, obj);
2297                                 break;
2298                         case T_Constraint:
2299                                 _outConstraint(str, obj);
2300                                 break;
2301                         case T_FkConstraint:
2302                                 _outFkConstraint(str, obj);
2303                                 break;
2304                         case T_FuncCall:
2305                                 _outFuncCall(str, obj);
2306                                 break;
2307                         case T_DefElem:
2308                                 _outDefElem(str, obj);
2309                                 break;
2310                         case T_LockingClause:
2311                                 _outLockingClause(str, obj);
2312                                 break;
2313                         case T_XmlSerialize:
2314                                 _outXmlSerialize(str, obj);
2315                                 break;
2316
2317                         default:
2318
2319                                 /*
2320                                  * This should be an ERROR, but it's too useful to be able to
2321                                  * dump structures that _outNode only understands part of.
2322                                  */
2323                                 elog(WARNING, "could not dump unrecognized node type: %d",
2324                                          (int) nodeTag(obj));
2325                                 break;
2326                 }
2327                 appendStringInfoChar(str, '}');
2328         }
2329 }
2330
2331 /*
2332  * nodeToString -
2333  *         returns the ascii representation of the Node as a palloc'd string
2334  */
2335 char *
2336 nodeToString(void *obj)
2337 {
2338         StringInfoData str;
2339
2340         /* see stringinfo.h for an explanation of this maneuver */
2341         initStringInfo(&str);
2342         _outNode(&str, obj);
2343         return str.data;
2344 }