]> granicus.if.org Git - postgresql/blob - src/backend/nodes/readfuncs.c
Incidental cleanup of matviews code.
[postgresql] / src / backend / nodes / readfuncs.c
1 /*-------------------------------------------------------------------------
2  *
3  * readfuncs.c
4  *        Reader functions for Postgres tree nodes.
5  *
6  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        src/backend/nodes/readfuncs.c
12  *
13  * NOTES
14  *        Path and Plan nodes do not have any readfuncs support, because we
15  *        never have occasion to read them in.  (There was once code here that
16  *        claimed to read them, but it was broken as well as unused.)  We
17  *        never read executor state trees, either.
18  *
19  *        Parse location fields are written out by outfuncs.c, but only for
20  *        possible debugging use.  When reading a location field, we discard
21  *        the stored value and set the location field to -1 (ie, "unknown").
22  *        This is because nodes coming from a stored rule should not be thought
23  *        to have a known location in the current query's text.
24  *
25  *-------------------------------------------------------------------------
26  */
27 #include "postgres.h"
28
29 #include <math.h>
30
31 #include "nodes/parsenodes.h"
32 #include "nodes/readfuncs.h"
33
34
35 /*
36  * Macros to simplify reading of different kinds of fields.  Use these
37  * wherever possible to reduce the chance for silly typos.      Note that these
38  * hard-wire conventions about the names of the local variables in a Read
39  * routine.
40  */
41
42 /* Macros for declaring appropriate local variables */
43
44 /* A few guys need only local_node */
45 #define READ_LOCALS_NO_FIELDS(nodeTypeName) \
46         nodeTypeName *local_node = makeNode(nodeTypeName)
47
48 /* And a few guys need only the pg_strtok support fields */
49 #define READ_TEMP_LOCALS()      \
50         char       *token;              \
51         int                     length
52
53 /* ... but most need both */
54 #define READ_LOCALS(nodeTypeName)                       \
55         READ_LOCALS_NO_FIELDS(nodeTypeName);    \
56         READ_TEMP_LOCALS()
57
58 /* Read an integer field (anything written as ":fldname %d") */
59 #define READ_INT_FIELD(fldname) \
60         token = pg_strtok(&length);             /* skip :fldname */ \
61         token = pg_strtok(&length);             /* get field value */ \
62         local_node->fldname = atoi(token)
63
64 /* Read an unsigned integer field (anything written as ":fldname %u") */
65 #define READ_UINT_FIELD(fldname) \
66         token = pg_strtok(&length);             /* skip :fldname */ \
67         token = pg_strtok(&length);             /* get field value */ \
68         local_node->fldname = atoui(token)
69
70 /* Read an OID field (don't hard-wire assumption that OID is same as uint) */
71 #define READ_OID_FIELD(fldname) \
72         token = pg_strtok(&length);             /* skip :fldname */ \
73         token = pg_strtok(&length);             /* get field value */ \
74         local_node->fldname = atooid(token)
75
76 /* Read a char field (ie, one ascii character) */
77 #define READ_CHAR_FIELD(fldname) \
78         token = pg_strtok(&length);             /* skip :fldname */ \
79         token = pg_strtok(&length);             /* get field value */ \
80         local_node->fldname = token[0]
81
82 /* Read an enumerated-type field that was written as an integer code */
83 #define READ_ENUM_FIELD(fldname, enumtype) \
84         token = pg_strtok(&length);             /* skip :fldname */ \
85         token = pg_strtok(&length);             /* get field value */ \
86         local_node->fldname = (enumtype) atoi(token)
87
88 /* Read a float field */
89 #define READ_FLOAT_FIELD(fldname) \
90         token = pg_strtok(&length);             /* skip :fldname */ \
91         token = pg_strtok(&length);             /* get field value */ \
92         local_node->fldname = atof(token)
93
94 /* Read a boolean field */
95 #define READ_BOOL_FIELD(fldname) \
96         token = pg_strtok(&length);             /* skip :fldname */ \
97         token = pg_strtok(&length);             /* get field value */ \
98         local_node->fldname = strtobool(token)
99
100 /* Read a character-string field */
101 #define READ_STRING_FIELD(fldname) \
102         token = pg_strtok(&length);             /* skip :fldname */ \
103         token = pg_strtok(&length);             /* get field value */ \
104         local_node->fldname = nullable_string(token, length)
105
106 /* Read a parse location field (and throw away the value, per notes above) */
107 #define READ_LOCATION_FIELD(fldname) \
108         token = pg_strtok(&length);             /* skip :fldname */ \
109         token = pg_strtok(&length);             /* get field value */ \
110         local_node->fldname = -1        /* set field to "unknown" */
111
112 /* Read a Node field */
113 #define READ_NODE_FIELD(fldname) \
114         token = pg_strtok(&length);             /* skip :fldname */ \
115         (void) token;                           /* in case not used elsewhere */ \
116         local_node->fldname = nodeRead(NULL, 0)
117
118 /* Read a bitmapset field */
119 #define READ_BITMAPSET_FIELD(fldname) \
120         token = pg_strtok(&length);             /* skip :fldname */ \
121         local_node->fldname = _readBitmapset()
122
123 /* Routine exit */
124 #define READ_DONE() \
125         return local_node
126
127
128 /*
129  * NOTE: use atoi() to read values written with %d, or atoui() to read
130  * values written with %u in outfuncs.c.  An exception is OID values,
131  * for which use atooid().      (As of 7.1, outfuncs.c writes OIDs as %u,
132  * but this will probably change in the future.)
133  */
134 #define atoui(x)  ((unsigned int) strtoul((x), NULL, 10))
135
136 #define atooid(x)  ((Oid) strtoul((x), NULL, 10))
137
138 #define strtobool(x)  ((*(x) == 't') ? true : false)
139
140 #define nullable_string(token,length)  \
141         ((length) == 0 ? NULL : debackslash(token, length))
142
143
144 static Datum readDatum(bool typbyval);
145
146 /*
147  * _readBitmapset
148  */
149 static Bitmapset *
150 _readBitmapset(void)
151 {
152         Bitmapset  *result = NULL;
153
154         READ_TEMP_LOCALS();
155
156         token = pg_strtok(&length);
157         if (token == NULL)
158                 elog(ERROR, "incomplete Bitmapset structure");
159         if (length != 1 || token[0] != '(')
160                 elog(ERROR, "unrecognized token: \"%.*s\"", length, token);
161
162         token = pg_strtok(&length);
163         if (token == NULL)
164                 elog(ERROR, "incomplete Bitmapset structure");
165         if (length != 1 || token[0] != 'b')
166                 elog(ERROR, "unrecognized token: \"%.*s\"", length, token);
167
168         for (;;)
169         {
170                 int                     val;
171                 char       *endptr;
172
173                 token = pg_strtok(&length);
174                 if (token == NULL)
175                         elog(ERROR, "unterminated Bitmapset structure");
176                 if (length == 1 && token[0] == ')')
177                         break;
178                 val = (int) strtol(token, &endptr, 10);
179                 if (endptr != token + length)
180                         elog(ERROR, "unrecognized integer: \"%.*s\"", length, token);
181                 result = bms_add_member(result, val);
182         }
183
184         return result;
185 }
186
187
188 /*
189  * _readQuery
190  */
191 static Query *
192 _readQuery(void)
193 {
194         READ_LOCALS(Query);
195
196         READ_ENUM_FIELD(commandType, CmdType);
197         READ_ENUM_FIELD(querySource, QuerySource);
198         local_node->queryId = 0;        /* not saved in output format */
199         READ_BOOL_FIELD(canSetTag);
200         READ_NODE_FIELD(utilityStmt);
201         READ_INT_FIELD(resultRelation);
202         READ_BOOL_FIELD(hasAggs);
203         READ_BOOL_FIELD(hasWindowFuncs);
204         READ_BOOL_FIELD(hasSubLinks);
205         READ_BOOL_FIELD(hasDistinctOn);
206         READ_BOOL_FIELD(hasRecursive);
207         READ_BOOL_FIELD(hasModifyingCTE);
208         READ_BOOL_FIELD(hasForUpdate);
209         READ_NODE_FIELD(cteList);
210         READ_NODE_FIELD(rtable);
211         READ_NODE_FIELD(jointree);
212         READ_NODE_FIELD(targetList);
213         READ_NODE_FIELD(returningList);
214         READ_NODE_FIELD(groupClause);
215         READ_NODE_FIELD(havingQual);
216         READ_NODE_FIELD(windowClause);
217         READ_NODE_FIELD(distinctClause);
218         READ_NODE_FIELD(sortClause);
219         READ_NODE_FIELD(limitOffset);
220         READ_NODE_FIELD(limitCount);
221         READ_NODE_FIELD(rowMarks);
222         READ_NODE_FIELD(setOperations);
223         READ_NODE_FIELD(constraintDeps);
224
225         READ_DONE();
226 }
227
228 /*
229  * _readNotifyStmt
230  */
231 static NotifyStmt *
232 _readNotifyStmt(void)
233 {
234         READ_LOCALS(NotifyStmt);
235
236         READ_STRING_FIELD(conditionname);
237         READ_STRING_FIELD(payload);
238
239         READ_DONE();
240 }
241
242 /*
243  * _readDeclareCursorStmt
244  */
245 static DeclareCursorStmt *
246 _readDeclareCursorStmt(void)
247 {
248         READ_LOCALS(DeclareCursorStmt);
249
250         READ_STRING_FIELD(portalname);
251         READ_INT_FIELD(options);
252         READ_NODE_FIELD(query);
253
254         READ_DONE();
255 }
256
257 /*
258  * _readSortGroupClause
259  */
260 static SortGroupClause *
261 _readSortGroupClause(void)
262 {
263         READ_LOCALS(SortGroupClause);
264
265         READ_UINT_FIELD(tleSortGroupRef);
266         READ_OID_FIELD(eqop);
267         READ_OID_FIELD(sortop);
268         READ_BOOL_FIELD(nulls_first);
269         READ_BOOL_FIELD(hashable);
270
271         READ_DONE();
272 }
273
274 /*
275  * _readWindowClause
276  */
277 static WindowClause *
278 _readWindowClause(void)
279 {
280         READ_LOCALS(WindowClause);
281
282         READ_STRING_FIELD(name);
283         READ_STRING_FIELD(refname);
284         READ_NODE_FIELD(partitionClause);
285         READ_NODE_FIELD(orderClause);
286         READ_INT_FIELD(frameOptions);
287         READ_NODE_FIELD(startOffset);
288         READ_NODE_FIELD(endOffset);
289         READ_UINT_FIELD(winref);
290         READ_BOOL_FIELD(copiedOrder);
291
292         READ_DONE();
293 }
294
295 /*
296  * _readRowMarkClause
297  */
298 static RowMarkClause *
299 _readRowMarkClause(void)
300 {
301         READ_LOCALS(RowMarkClause);
302
303         READ_UINT_FIELD(rti);
304         READ_ENUM_FIELD(strength, LockClauseStrength);
305         READ_BOOL_FIELD(noWait);
306         READ_BOOL_FIELD(pushedDown);
307
308         READ_DONE();
309 }
310
311 /*
312  * _readCommonTableExpr
313  */
314 static CommonTableExpr *
315 _readCommonTableExpr(void)
316 {
317         READ_LOCALS(CommonTableExpr);
318
319         READ_STRING_FIELD(ctename);
320         READ_NODE_FIELD(aliascolnames);
321         READ_NODE_FIELD(ctequery);
322         READ_LOCATION_FIELD(location);
323         READ_BOOL_FIELD(cterecursive);
324         READ_INT_FIELD(cterefcount);
325         READ_NODE_FIELD(ctecolnames);
326         READ_NODE_FIELD(ctecoltypes);
327         READ_NODE_FIELD(ctecoltypmods);
328         READ_NODE_FIELD(ctecolcollations);
329
330         READ_DONE();
331 }
332
333 /*
334  * _readSetOperationStmt
335  */
336 static SetOperationStmt *
337 _readSetOperationStmt(void)
338 {
339         READ_LOCALS(SetOperationStmt);
340
341         READ_ENUM_FIELD(op, SetOperation);
342         READ_BOOL_FIELD(all);
343         READ_NODE_FIELD(larg);
344         READ_NODE_FIELD(rarg);
345         READ_NODE_FIELD(colTypes);
346         READ_NODE_FIELD(colTypmods);
347         READ_NODE_FIELD(colCollations);
348         READ_NODE_FIELD(groupClauses);
349
350         READ_DONE();
351 }
352
353
354 /*
355  *      Stuff from primnodes.h.
356  */
357
358 static Alias *
359 _readAlias(void)
360 {
361         READ_LOCALS(Alias);
362
363         READ_STRING_FIELD(aliasname);
364         READ_NODE_FIELD(colnames);
365
366         READ_DONE();
367 }
368
369 static RangeVar *
370 _readRangeVar(void)
371 {
372         READ_LOCALS(RangeVar);
373
374         local_node->catalogname = NULL;         /* not currently saved in output
375                                                                                  * format */
376
377         READ_STRING_FIELD(schemaname);
378         READ_STRING_FIELD(relname);
379         READ_ENUM_FIELD(inhOpt, InhOption);
380         READ_CHAR_FIELD(relpersistence);
381         READ_NODE_FIELD(alias);
382         READ_LOCATION_FIELD(location);
383
384         READ_DONE();
385 }
386
387 static IntoClause *
388 _readIntoClause(void)
389 {
390         READ_LOCALS(IntoClause);
391
392         READ_NODE_FIELD(rel);
393         READ_NODE_FIELD(colNames);
394         READ_NODE_FIELD(options);
395         READ_ENUM_FIELD(onCommit, OnCommitAction);
396         READ_STRING_FIELD(tableSpaceName);
397         READ_NODE_FIELD(viewQuery);
398         READ_BOOL_FIELD(skipData);
399
400         READ_DONE();
401 }
402
403 /*
404  * _readVar
405  */
406 static Var *
407 _readVar(void)
408 {
409         READ_LOCALS(Var);
410
411         READ_UINT_FIELD(varno);
412         READ_INT_FIELD(varattno);
413         READ_OID_FIELD(vartype);
414         READ_INT_FIELD(vartypmod);
415         READ_OID_FIELD(varcollid);
416         READ_UINT_FIELD(varlevelsup);
417         READ_UINT_FIELD(varnoold);
418         READ_INT_FIELD(varoattno);
419         READ_LOCATION_FIELD(location);
420
421         READ_DONE();
422 }
423
424 /*
425  * _readConst
426  */
427 static Const *
428 _readConst(void)
429 {
430         READ_LOCALS(Const);
431
432         READ_OID_FIELD(consttype);
433         READ_INT_FIELD(consttypmod);
434         READ_OID_FIELD(constcollid);
435         READ_INT_FIELD(constlen);
436         READ_BOOL_FIELD(constbyval);
437         READ_BOOL_FIELD(constisnull);
438         READ_LOCATION_FIELD(location);
439
440         token = pg_strtok(&length); /* skip :constvalue */
441         if (local_node->constisnull)
442                 token = pg_strtok(&length);             /* skip "<>" */
443         else
444                 local_node->constvalue = readDatum(local_node->constbyval);
445
446         READ_DONE();
447 }
448
449 /*
450  * _readParam
451  */
452 static Param *
453 _readParam(void)
454 {
455         READ_LOCALS(Param);
456
457         READ_ENUM_FIELD(paramkind, ParamKind);
458         READ_INT_FIELD(paramid);
459         READ_OID_FIELD(paramtype);
460         READ_INT_FIELD(paramtypmod);
461         READ_OID_FIELD(paramcollid);
462         READ_LOCATION_FIELD(location);
463
464         READ_DONE();
465 }
466
467 /*
468  * _readAggref
469  */
470 static Aggref *
471 _readAggref(void)
472 {
473         READ_LOCALS(Aggref);
474
475         READ_OID_FIELD(aggfnoid);
476         READ_OID_FIELD(aggtype);
477         READ_OID_FIELD(aggcollid);
478         READ_OID_FIELD(inputcollid);
479         READ_NODE_FIELD(args);
480         READ_NODE_FIELD(aggorder);
481         READ_NODE_FIELD(aggdistinct);
482         READ_BOOL_FIELD(aggstar);
483         READ_UINT_FIELD(agglevelsup);
484         READ_LOCATION_FIELD(location);
485
486         READ_DONE();
487 }
488
489 /*
490  * _readWindowFunc
491  */
492 static WindowFunc *
493 _readWindowFunc(void)
494 {
495         READ_LOCALS(WindowFunc);
496
497         READ_OID_FIELD(winfnoid);
498         READ_OID_FIELD(wintype);
499         READ_OID_FIELD(wincollid);
500         READ_OID_FIELD(inputcollid);
501         READ_NODE_FIELD(args);
502         READ_UINT_FIELD(winref);
503         READ_BOOL_FIELD(winstar);
504         READ_BOOL_FIELD(winagg);
505         READ_LOCATION_FIELD(location);
506
507         READ_DONE();
508 }
509
510 /*
511  * _readArrayRef
512  */
513 static ArrayRef *
514 _readArrayRef(void)
515 {
516         READ_LOCALS(ArrayRef);
517
518         READ_OID_FIELD(refarraytype);
519         READ_OID_FIELD(refelemtype);
520         READ_INT_FIELD(reftypmod);
521         READ_OID_FIELD(refcollid);
522         READ_NODE_FIELD(refupperindexpr);
523         READ_NODE_FIELD(reflowerindexpr);
524         READ_NODE_FIELD(refexpr);
525         READ_NODE_FIELD(refassgnexpr);
526
527         READ_DONE();
528 }
529
530 /*
531  * _readFuncExpr
532  */
533 static FuncExpr *
534 _readFuncExpr(void)
535 {
536         READ_LOCALS(FuncExpr);
537
538         READ_OID_FIELD(funcid);
539         READ_OID_FIELD(funcresulttype);
540         READ_BOOL_FIELD(funcretset);
541         READ_BOOL_FIELD(funcvariadic);
542         READ_ENUM_FIELD(funcformat, CoercionForm);
543         READ_OID_FIELD(funccollid);
544         READ_OID_FIELD(inputcollid);
545         READ_NODE_FIELD(args);
546         READ_LOCATION_FIELD(location);
547
548         READ_DONE();
549 }
550
551 /*
552  * _readNamedArgExpr
553  */
554 static NamedArgExpr *
555 _readNamedArgExpr(void)
556 {
557         READ_LOCALS(NamedArgExpr);
558
559         READ_NODE_FIELD(arg);
560         READ_STRING_FIELD(name);
561         READ_INT_FIELD(argnumber);
562         READ_LOCATION_FIELD(location);
563
564         READ_DONE();
565 }
566
567 /*
568  * _readOpExpr
569  */
570 static OpExpr *
571 _readOpExpr(void)
572 {
573         READ_LOCALS(OpExpr);
574
575         READ_OID_FIELD(opno);
576         READ_OID_FIELD(opfuncid);
577
578         /*
579          * The opfuncid is stored in the textual format primarily for debugging
580          * and documentation reasons.  We want to always read it as zero to force
581          * it to be re-looked-up in the pg_operator entry.      This ensures that
582          * stored rules don't have hidden dependencies on operators' functions.
583          * (We don't currently support an ALTER OPERATOR command, but might
584          * someday.)
585          */
586         local_node->opfuncid = InvalidOid;
587
588         READ_OID_FIELD(opresulttype);
589         READ_BOOL_FIELD(opretset);
590         READ_OID_FIELD(opcollid);
591         READ_OID_FIELD(inputcollid);
592         READ_NODE_FIELD(args);
593         READ_LOCATION_FIELD(location);
594
595         READ_DONE();
596 }
597
598 /*
599  * _readDistinctExpr
600  */
601 static DistinctExpr *
602 _readDistinctExpr(void)
603 {
604         READ_LOCALS(DistinctExpr);
605
606         READ_OID_FIELD(opno);
607         READ_OID_FIELD(opfuncid);
608
609         /*
610          * The opfuncid is stored in the textual format primarily for debugging
611          * and documentation reasons.  We want to always read it as zero to force
612          * it to be re-looked-up in the pg_operator entry.      This ensures that
613          * stored rules don't have hidden dependencies on operators' functions.
614          * (We don't currently support an ALTER OPERATOR command, but might
615          * someday.)
616          */
617         local_node->opfuncid = InvalidOid;
618
619         READ_OID_FIELD(opresulttype);
620         READ_BOOL_FIELD(opretset);
621         READ_OID_FIELD(opcollid);
622         READ_OID_FIELD(inputcollid);
623         READ_NODE_FIELD(args);
624         READ_LOCATION_FIELD(location);
625
626         READ_DONE();
627 }
628
629 /*
630  * _readNullIfExpr
631  */
632 static NullIfExpr *
633 _readNullIfExpr(void)
634 {
635         READ_LOCALS(NullIfExpr);
636
637         READ_OID_FIELD(opno);
638         READ_OID_FIELD(opfuncid);
639
640         /*
641          * The opfuncid is stored in the textual format primarily for debugging
642          * and documentation reasons.  We want to always read it as zero to force
643          * it to be re-looked-up in the pg_operator entry.      This ensures that
644          * stored rules don't have hidden dependencies on operators' functions.
645          * (We don't currently support an ALTER OPERATOR command, but might
646          * someday.)
647          */
648         local_node->opfuncid = InvalidOid;
649
650         READ_OID_FIELD(opresulttype);
651         READ_BOOL_FIELD(opretset);
652         READ_OID_FIELD(opcollid);
653         READ_OID_FIELD(inputcollid);
654         READ_NODE_FIELD(args);
655         READ_LOCATION_FIELD(location);
656
657         READ_DONE();
658 }
659
660 /*
661  * _readScalarArrayOpExpr
662  */
663 static ScalarArrayOpExpr *
664 _readScalarArrayOpExpr(void)
665 {
666         READ_LOCALS(ScalarArrayOpExpr);
667
668         READ_OID_FIELD(opno);
669         READ_OID_FIELD(opfuncid);
670
671         /*
672          * The opfuncid is stored in the textual format primarily for debugging
673          * and documentation reasons.  We want to always read it as zero to force
674          * it to be re-looked-up in the pg_operator entry.      This ensures that
675          * stored rules don't have hidden dependencies on operators' functions.
676          * (We don't currently support an ALTER OPERATOR command, but might
677          * someday.)
678          */
679         local_node->opfuncid = InvalidOid;
680
681         READ_BOOL_FIELD(useOr);
682         READ_OID_FIELD(inputcollid);
683         READ_NODE_FIELD(args);
684         READ_LOCATION_FIELD(location);
685
686         READ_DONE();
687 }
688
689 /*
690  * _readBoolExpr
691  */
692 static BoolExpr *
693 _readBoolExpr(void)
694 {
695         READ_LOCALS(BoolExpr);
696
697         /* do-it-yourself enum representation */
698         token = pg_strtok(&length); /* skip :boolop */
699         token = pg_strtok(&length); /* get field value */
700         if (strncmp(token, "and", 3) == 0)
701                 local_node->boolop = AND_EXPR;
702         else if (strncmp(token, "or", 2) == 0)
703                 local_node->boolop = OR_EXPR;
704         else if (strncmp(token, "not", 3) == 0)
705                 local_node->boolop = NOT_EXPR;
706         else
707                 elog(ERROR, "unrecognized boolop \"%.*s\"", length, token);
708
709         READ_NODE_FIELD(args);
710         READ_LOCATION_FIELD(location);
711
712         READ_DONE();
713 }
714
715 /*
716  * _readSubLink
717  */
718 static SubLink *
719 _readSubLink(void)
720 {
721         READ_LOCALS(SubLink);
722
723         READ_ENUM_FIELD(subLinkType, SubLinkType);
724         READ_NODE_FIELD(testexpr);
725         READ_NODE_FIELD(operName);
726         READ_NODE_FIELD(subselect);
727         READ_LOCATION_FIELD(location);
728
729         READ_DONE();
730 }
731
732 /*
733  * _readSubPlan is not needed since it doesn't appear in stored rules.
734  */
735
736 /*
737  * _readFieldSelect
738  */
739 static FieldSelect *
740 _readFieldSelect(void)
741 {
742         READ_LOCALS(FieldSelect);
743
744         READ_NODE_FIELD(arg);
745         READ_INT_FIELD(fieldnum);
746         READ_OID_FIELD(resulttype);
747         READ_INT_FIELD(resulttypmod);
748         READ_OID_FIELD(resultcollid);
749
750         READ_DONE();
751 }
752
753 /*
754  * _readFieldStore
755  */
756 static FieldStore *
757 _readFieldStore(void)
758 {
759         READ_LOCALS(FieldStore);
760
761         READ_NODE_FIELD(arg);
762         READ_NODE_FIELD(newvals);
763         READ_NODE_FIELD(fieldnums);
764         READ_OID_FIELD(resulttype);
765
766         READ_DONE();
767 }
768
769 /*
770  * _readRelabelType
771  */
772 static RelabelType *
773 _readRelabelType(void)
774 {
775         READ_LOCALS(RelabelType);
776
777         READ_NODE_FIELD(arg);
778         READ_OID_FIELD(resulttype);
779         READ_INT_FIELD(resulttypmod);
780         READ_OID_FIELD(resultcollid);
781         READ_ENUM_FIELD(relabelformat, CoercionForm);
782         READ_LOCATION_FIELD(location);
783
784         READ_DONE();
785 }
786
787 /*
788  * _readCoerceViaIO
789  */
790 static CoerceViaIO *
791 _readCoerceViaIO(void)
792 {
793         READ_LOCALS(CoerceViaIO);
794
795         READ_NODE_FIELD(arg);
796         READ_OID_FIELD(resulttype);
797         READ_OID_FIELD(resultcollid);
798         READ_ENUM_FIELD(coerceformat, CoercionForm);
799         READ_LOCATION_FIELD(location);
800
801         READ_DONE();
802 }
803
804 /*
805  * _readArrayCoerceExpr
806  */
807 static ArrayCoerceExpr *
808 _readArrayCoerceExpr(void)
809 {
810         READ_LOCALS(ArrayCoerceExpr);
811
812         READ_NODE_FIELD(arg);
813         READ_OID_FIELD(elemfuncid);
814         READ_OID_FIELD(resulttype);
815         READ_INT_FIELD(resulttypmod);
816         READ_OID_FIELD(resultcollid);
817         READ_BOOL_FIELD(isExplicit);
818         READ_ENUM_FIELD(coerceformat, CoercionForm);
819         READ_LOCATION_FIELD(location);
820
821         READ_DONE();
822 }
823
824 /*
825  * _readConvertRowtypeExpr
826  */
827 static ConvertRowtypeExpr *
828 _readConvertRowtypeExpr(void)
829 {
830         READ_LOCALS(ConvertRowtypeExpr);
831
832         READ_NODE_FIELD(arg);
833         READ_OID_FIELD(resulttype);
834         READ_ENUM_FIELD(convertformat, CoercionForm);
835         READ_LOCATION_FIELD(location);
836
837         READ_DONE();
838 }
839
840 /*
841  * _readCollateExpr
842  */
843 static CollateExpr *
844 _readCollateExpr(void)
845 {
846         READ_LOCALS(CollateExpr);
847
848         READ_NODE_FIELD(arg);
849         READ_OID_FIELD(collOid);
850         READ_LOCATION_FIELD(location);
851
852         READ_DONE();
853 }
854
855 /*
856  * _readCaseExpr
857  */
858 static CaseExpr *
859 _readCaseExpr(void)
860 {
861         READ_LOCALS(CaseExpr);
862
863         READ_OID_FIELD(casetype);
864         READ_OID_FIELD(casecollid);
865         READ_NODE_FIELD(arg);
866         READ_NODE_FIELD(args);
867         READ_NODE_FIELD(defresult);
868         READ_LOCATION_FIELD(location);
869
870         READ_DONE();
871 }
872
873 /*
874  * _readCaseWhen
875  */
876 static CaseWhen *
877 _readCaseWhen(void)
878 {
879         READ_LOCALS(CaseWhen);
880
881         READ_NODE_FIELD(expr);
882         READ_NODE_FIELD(result);
883         READ_LOCATION_FIELD(location);
884
885         READ_DONE();
886 }
887
888 /*
889  * _readCaseTestExpr
890  */
891 static CaseTestExpr *
892 _readCaseTestExpr(void)
893 {
894         READ_LOCALS(CaseTestExpr);
895
896         READ_OID_FIELD(typeId);
897         READ_INT_FIELD(typeMod);
898         READ_OID_FIELD(collation);
899
900         READ_DONE();
901 }
902
903 /*
904  * _readArrayExpr
905  */
906 static ArrayExpr *
907 _readArrayExpr(void)
908 {
909         READ_LOCALS(ArrayExpr);
910
911         READ_OID_FIELD(array_typeid);
912         READ_OID_FIELD(array_collid);
913         READ_OID_FIELD(element_typeid);
914         READ_NODE_FIELD(elements);
915         READ_BOOL_FIELD(multidims);
916         READ_LOCATION_FIELD(location);
917
918         READ_DONE();
919 }
920
921 /*
922  * _readRowExpr
923  */
924 static RowExpr *
925 _readRowExpr(void)
926 {
927         READ_LOCALS(RowExpr);
928
929         READ_NODE_FIELD(args);
930         READ_OID_FIELD(row_typeid);
931         READ_ENUM_FIELD(row_format, CoercionForm);
932         READ_NODE_FIELD(colnames);
933         READ_LOCATION_FIELD(location);
934
935         READ_DONE();
936 }
937
938 /*
939  * _readRowCompareExpr
940  */
941 static RowCompareExpr *
942 _readRowCompareExpr(void)
943 {
944         READ_LOCALS(RowCompareExpr);
945
946         READ_ENUM_FIELD(rctype, RowCompareType);
947         READ_NODE_FIELD(opnos);
948         READ_NODE_FIELD(opfamilies);
949         READ_NODE_FIELD(inputcollids);
950         READ_NODE_FIELD(largs);
951         READ_NODE_FIELD(rargs);
952
953         READ_DONE();
954 }
955
956 /*
957  * _readCoalesceExpr
958  */
959 static CoalesceExpr *
960 _readCoalesceExpr(void)
961 {
962         READ_LOCALS(CoalesceExpr);
963
964         READ_OID_FIELD(coalescetype);
965         READ_OID_FIELD(coalescecollid);
966         READ_NODE_FIELD(args);
967         READ_LOCATION_FIELD(location);
968
969         READ_DONE();
970 }
971
972 /*
973  * _readMinMaxExpr
974  */
975 static MinMaxExpr *
976 _readMinMaxExpr(void)
977 {
978         READ_LOCALS(MinMaxExpr);
979
980         READ_OID_FIELD(minmaxtype);
981         READ_OID_FIELD(minmaxcollid);
982         READ_OID_FIELD(inputcollid);
983         READ_ENUM_FIELD(op, MinMaxOp);
984         READ_NODE_FIELD(args);
985         READ_LOCATION_FIELD(location);
986
987         READ_DONE();
988 }
989
990 /*
991  * _readXmlExpr
992  */
993 static XmlExpr *
994 _readXmlExpr(void)
995 {
996         READ_LOCALS(XmlExpr);
997
998         READ_ENUM_FIELD(op, XmlExprOp);
999         READ_STRING_FIELD(name);
1000         READ_NODE_FIELD(named_args);
1001         READ_NODE_FIELD(arg_names);
1002         READ_NODE_FIELD(args);
1003         READ_ENUM_FIELD(xmloption, XmlOptionType);
1004         READ_OID_FIELD(type);
1005         READ_INT_FIELD(typmod);
1006         READ_LOCATION_FIELD(location);
1007
1008         READ_DONE();
1009 }
1010
1011 /*
1012  * _readNullTest
1013  */
1014 static NullTest *
1015 _readNullTest(void)
1016 {
1017         READ_LOCALS(NullTest);
1018
1019         READ_NODE_FIELD(arg);
1020         READ_ENUM_FIELD(nulltesttype, NullTestType);
1021         READ_BOOL_FIELD(argisrow);
1022
1023         READ_DONE();
1024 }
1025
1026 /*
1027  * _readBooleanTest
1028  */
1029 static BooleanTest *
1030 _readBooleanTest(void)
1031 {
1032         READ_LOCALS(BooleanTest);
1033
1034         READ_NODE_FIELD(arg);
1035         READ_ENUM_FIELD(booltesttype, BoolTestType);
1036
1037         READ_DONE();
1038 }
1039
1040 /*
1041  * _readCoerceToDomain
1042  */
1043 static CoerceToDomain *
1044 _readCoerceToDomain(void)
1045 {
1046         READ_LOCALS(CoerceToDomain);
1047
1048         READ_NODE_FIELD(arg);
1049         READ_OID_FIELD(resulttype);
1050         READ_INT_FIELD(resulttypmod);
1051         READ_OID_FIELD(resultcollid);
1052         READ_ENUM_FIELD(coercionformat, CoercionForm);
1053         READ_LOCATION_FIELD(location);
1054
1055         READ_DONE();
1056 }
1057
1058 /*
1059  * _readCoerceToDomainValue
1060  */
1061 static CoerceToDomainValue *
1062 _readCoerceToDomainValue(void)
1063 {
1064         READ_LOCALS(CoerceToDomainValue);
1065
1066         READ_OID_FIELD(typeId);
1067         READ_INT_FIELD(typeMod);
1068         READ_OID_FIELD(collation);
1069         READ_LOCATION_FIELD(location);
1070
1071         READ_DONE();
1072 }
1073
1074 /*
1075  * _readSetToDefault
1076  */
1077 static SetToDefault *
1078 _readSetToDefault(void)
1079 {
1080         READ_LOCALS(SetToDefault);
1081
1082         READ_OID_FIELD(typeId);
1083         READ_INT_FIELD(typeMod);
1084         READ_OID_FIELD(collation);
1085         READ_LOCATION_FIELD(location);
1086
1087         READ_DONE();
1088 }
1089
1090 /*
1091  * _readCurrentOfExpr
1092  */
1093 static CurrentOfExpr *
1094 _readCurrentOfExpr(void)
1095 {
1096         READ_LOCALS(CurrentOfExpr);
1097
1098         READ_UINT_FIELD(cvarno);
1099         READ_STRING_FIELD(cursor_name);
1100         READ_INT_FIELD(cursor_param);
1101
1102         READ_DONE();
1103 }
1104
1105 /*
1106  * _readTargetEntry
1107  */
1108 static TargetEntry *
1109 _readTargetEntry(void)
1110 {
1111         READ_LOCALS(TargetEntry);
1112
1113         READ_NODE_FIELD(expr);
1114         READ_INT_FIELD(resno);
1115         READ_STRING_FIELD(resname);
1116         READ_UINT_FIELD(ressortgroupref);
1117         READ_OID_FIELD(resorigtbl);
1118         READ_INT_FIELD(resorigcol);
1119         READ_BOOL_FIELD(resjunk);
1120
1121         READ_DONE();
1122 }
1123
1124 /*
1125  * _readRangeTblRef
1126  */
1127 static RangeTblRef *
1128 _readRangeTblRef(void)
1129 {
1130         READ_LOCALS(RangeTblRef);
1131
1132         READ_INT_FIELD(rtindex);
1133
1134         READ_DONE();
1135 }
1136
1137 /*
1138  * _readJoinExpr
1139  */
1140 static JoinExpr *
1141 _readJoinExpr(void)
1142 {
1143         READ_LOCALS(JoinExpr);
1144
1145         READ_ENUM_FIELD(jointype, JoinType);
1146         READ_BOOL_FIELD(isNatural);
1147         READ_NODE_FIELD(larg);
1148         READ_NODE_FIELD(rarg);
1149         READ_NODE_FIELD(usingClause);
1150         READ_NODE_FIELD(quals);
1151         READ_NODE_FIELD(alias);
1152         READ_INT_FIELD(rtindex);
1153
1154         READ_DONE();
1155 }
1156
1157 /*
1158  * _readFromExpr
1159  */
1160 static FromExpr *
1161 _readFromExpr(void)
1162 {
1163         READ_LOCALS(FromExpr);
1164
1165         READ_NODE_FIELD(fromlist);
1166         READ_NODE_FIELD(quals);
1167
1168         READ_DONE();
1169 }
1170
1171
1172 /*
1173  *      Stuff from parsenodes.h.
1174  */
1175
1176 /*
1177  * _readRangeTblEntry
1178  */
1179 static RangeTblEntry *
1180 _readRangeTblEntry(void)
1181 {
1182         READ_LOCALS(RangeTblEntry);
1183
1184         /* put alias + eref first to make dump more legible */
1185         READ_NODE_FIELD(alias);
1186         READ_NODE_FIELD(eref);
1187         READ_ENUM_FIELD(rtekind, RTEKind);
1188
1189         switch (local_node->rtekind)
1190         {
1191                 case RTE_RELATION:
1192                         READ_OID_FIELD(relid);
1193                         READ_CHAR_FIELD(relkind);
1194                         break;
1195                 case RTE_SUBQUERY:
1196                         READ_NODE_FIELD(subquery);
1197                         READ_BOOL_FIELD(security_barrier);
1198                         break;
1199                 case RTE_JOIN:
1200                         READ_ENUM_FIELD(jointype, JoinType);
1201                         READ_NODE_FIELD(joinaliasvars);
1202                         break;
1203                 case RTE_FUNCTION:
1204                         READ_NODE_FIELD(funcexpr);
1205                         READ_NODE_FIELD(funccoltypes);
1206                         READ_NODE_FIELD(funccoltypmods);
1207                         READ_NODE_FIELD(funccolcollations);
1208                         break;
1209                 case RTE_VALUES:
1210                         READ_NODE_FIELD(values_lists);
1211                         READ_NODE_FIELD(values_collations);
1212                         break;
1213                 case RTE_CTE:
1214                         READ_STRING_FIELD(ctename);
1215                         READ_UINT_FIELD(ctelevelsup);
1216                         READ_BOOL_FIELD(self_reference);
1217                         READ_NODE_FIELD(ctecoltypes);
1218                         READ_NODE_FIELD(ctecoltypmods);
1219                         READ_NODE_FIELD(ctecolcollations);
1220                         break;
1221                 default:
1222                         elog(ERROR, "unrecognized RTE kind: %d",
1223                                  (int) local_node->rtekind);
1224                         break;
1225         }
1226
1227         READ_BOOL_FIELD(lateral);
1228         READ_BOOL_FIELD(inh);
1229         READ_BOOL_FIELD(inFromCl);
1230         READ_UINT_FIELD(requiredPerms);
1231         READ_OID_FIELD(checkAsUser);
1232         READ_BITMAPSET_FIELD(selectedCols);
1233         READ_BITMAPSET_FIELD(modifiedCols);
1234
1235         READ_DONE();
1236 }
1237
1238
1239 /*
1240  * parseNodeString
1241  *
1242  * Given a character string representing a node tree, parseNodeString creates
1243  * the internal node structure.
1244  *
1245  * The string to be read must already have been loaded into pg_strtok().
1246  */
1247 Node *
1248 parseNodeString(void)
1249 {
1250         void       *return_value;
1251
1252         READ_TEMP_LOCALS();
1253
1254         token = pg_strtok(&length);
1255
1256 #define MATCH(tokname, namelen) \
1257         (length == namelen && memcmp(token, tokname, namelen) == 0)
1258
1259         if (MATCH("QUERY", 5))
1260                 return_value = _readQuery();
1261         else if (MATCH("SORTGROUPCLAUSE", 15))
1262                 return_value = _readSortGroupClause();
1263         else if (MATCH("WINDOWCLAUSE", 12))
1264                 return_value = _readWindowClause();
1265         else if (MATCH("ROWMARKCLAUSE", 13))
1266                 return_value = _readRowMarkClause();
1267         else if (MATCH("COMMONTABLEEXPR", 15))
1268                 return_value = _readCommonTableExpr();
1269         else if (MATCH("SETOPERATIONSTMT", 16))
1270                 return_value = _readSetOperationStmt();
1271         else if (MATCH("ALIAS", 5))
1272                 return_value = _readAlias();
1273         else if (MATCH("RANGEVAR", 8))
1274                 return_value = _readRangeVar();
1275         else if (MATCH("INTOCLAUSE", 10))
1276                 return_value = _readIntoClause();
1277         else if (MATCH("VAR", 3))
1278                 return_value = _readVar();
1279         else if (MATCH("CONST", 5))
1280                 return_value = _readConst();
1281         else if (MATCH("PARAM", 5))
1282                 return_value = _readParam();
1283         else if (MATCH("AGGREF", 6))
1284                 return_value = _readAggref();
1285         else if (MATCH("WINDOWFUNC", 10))
1286                 return_value = _readWindowFunc();
1287         else if (MATCH("ARRAYREF", 8))
1288                 return_value = _readArrayRef();
1289         else if (MATCH("FUNCEXPR", 8))
1290                 return_value = _readFuncExpr();
1291         else if (MATCH("NAMEDARGEXPR", 12))
1292                 return_value = _readNamedArgExpr();
1293         else if (MATCH("OPEXPR", 6))
1294                 return_value = _readOpExpr();
1295         else if (MATCH("DISTINCTEXPR", 12))
1296                 return_value = _readDistinctExpr();
1297         else if (MATCH("NULLIFEXPR", 10))
1298                 return_value = _readNullIfExpr();
1299         else if (MATCH("SCALARARRAYOPEXPR", 17))
1300                 return_value = _readScalarArrayOpExpr();
1301         else if (MATCH("BOOLEXPR", 8))
1302                 return_value = _readBoolExpr();
1303         else if (MATCH("SUBLINK", 7))
1304                 return_value = _readSubLink();
1305         else if (MATCH("FIELDSELECT", 11))
1306                 return_value = _readFieldSelect();
1307         else if (MATCH("FIELDSTORE", 10))
1308                 return_value = _readFieldStore();
1309         else if (MATCH("RELABELTYPE", 11))
1310                 return_value = _readRelabelType();
1311         else if (MATCH("COERCEVIAIO", 11))
1312                 return_value = _readCoerceViaIO();
1313         else if (MATCH("ARRAYCOERCEEXPR", 15))
1314                 return_value = _readArrayCoerceExpr();
1315         else if (MATCH("CONVERTROWTYPEEXPR", 18))
1316                 return_value = _readConvertRowtypeExpr();
1317         else if (MATCH("COLLATE", 7))
1318                 return_value = _readCollateExpr();
1319         else if (MATCH("CASE", 4))
1320                 return_value = _readCaseExpr();
1321         else if (MATCH("WHEN", 4))
1322                 return_value = _readCaseWhen();
1323         else if (MATCH("CASETESTEXPR", 12))
1324                 return_value = _readCaseTestExpr();
1325         else if (MATCH("ARRAY", 5))
1326                 return_value = _readArrayExpr();
1327         else if (MATCH("ROW", 3))
1328                 return_value = _readRowExpr();
1329         else if (MATCH("ROWCOMPARE", 10))
1330                 return_value = _readRowCompareExpr();
1331         else if (MATCH("COALESCE", 8))
1332                 return_value = _readCoalesceExpr();
1333         else if (MATCH("MINMAX", 6))
1334                 return_value = _readMinMaxExpr();
1335         else if (MATCH("XMLEXPR", 7))
1336                 return_value = _readXmlExpr();
1337         else if (MATCH("NULLTEST", 8))
1338                 return_value = _readNullTest();
1339         else if (MATCH("BOOLEANTEST", 11))
1340                 return_value = _readBooleanTest();
1341         else if (MATCH("COERCETODOMAIN", 14))
1342                 return_value = _readCoerceToDomain();
1343         else if (MATCH("COERCETODOMAINVALUE", 19))
1344                 return_value = _readCoerceToDomainValue();
1345         else if (MATCH("SETTODEFAULT", 12))
1346                 return_value = _readSetToDefault();
1347         else if (MATCH("CURRENTOFEXPR", 13))
1348                 return_value = _readCurrentOfExpr();
1349         else if (MATCH("TARGETENTRY", 11))
1350                 return_value = _readTargetEntry();
1351         else if (MATCH("RANGETBLREF", 11))
1352                 return_value = _readRangeTblRef();
1353         else if (MATCH("JOINEXPR", 8))
1354                 return_value = _readJoinExpr();
1355         else if (MATCH("FROMEXPR", 8))
1356                 return_value = _readFromExpr();
1357         else if (MATCH("RTE", 3))
1358                 return_value = _readRangeTblEntry();
1359         else if (MATCH("NOTIFY", 6))
1360                 return_value = _readNotifyStmt();
1361         else if (MATCH("DECLARECURSOR", 13))
1362                 return_value = _readDeclareCursorStmt();
1363         else
1364         {
1365                 elog(ERROR, "badly formatted node string \"%.32s\"...", token);
1366                 return_value = NULL;    /* keep compiler quiet */
1367         }
1368
1369         return (Node *) return_value;
1370 }
1371
1372
1373 /*
1374  * readDatum
1375  *
1376  * Given a string representation of a constant, recreate the appropriate
1377  * Datum.  The string representation embeds length info, but not byValue,
1378  * so we must be told that.
1379  */
1380 static Datum
1381 readDatum(bool typbyval)
1382 {
1383         Size            length,
1384                                 i;
1385         int                     tokenLength;
1386         char       *token;
1387         Datum           res;
1388         char       *s;
1389
1390         /*
1391          * read the actual length of the value
1392          */
1393         token = pg_strtok(&tokenLength);
1394         length = atoui(token);
1395
1396         token = pg_strtok(&tokenLength);        /* read the '[' */
1397         if (token == NULL || token[0] != '[')
1398                 elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %lu",
1399                          token ? (const char *) token : "[NULL]",
1400                          (unsigned long) length);
1401
1402         if (typbyval)
1403         {
1404                 if (length > (Size) sizeof(Datum))
1405                         elog(ERROR, "byval datum but length = %lu",
1406                                  (unsigned long) length);
1407                 res = (Datum) 0;
1408                 s = (char *) (&res);
1409                 for (i = 0; i < (Size) sizeof(Datum); i++)
1410                 {
1411                         token = pg_strtok(&tokenLength);
1412                         s[i] = (char) atoi(token);
1413                 }
1414         }
1415         else if (length <= 0)
1416                 res = (Datum) NULL;
1417         else
1418         {
1419                 s = (char *) palloc(length);
1420                 for (i = 0; i < length; i++)
1421                 {
1422                         token = pg_strtok(&tokenLength);
1423                         s[i] = (char) atoi(token);
1424                 }
1425                 res = PointerGetDatum(s);
1426         }
1427
1428         token = pg_strtok(&tokenLength);        /* read the ']' */
1429         if (token == NULL || token[0] != ']')
1430                 elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %lu",
1431                          token ? (const char *) token : "[NULL]",
1432                          (unsigned long) length);
1433
1434         return res;
1435 }