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