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