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