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