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