]> granicus.if.org Git - postgresql/blob - src/backend/nodes/readfuncs.c
Remove unnecessary #include references, per pgrminclude script.
[postgresql] / src / backend / nodes / readfuncs.c
1 /*-------------------------------------------------------------------------
2  *
3  * readfuncs.c
4  *        Reader functions for Postgres tree nodes.
5  *
6  * Portions Copyright (c) 1996-2011, 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         (void) token /* possibly unused */
53
54 /* ... but most need both */
55 #define READ_LOCALS(nodeTypeName)                       \
56         READ_LOCALS_NO_FIELDS(nodeTypeName);    \
57         READ_TEMP_LOCALS()
58
59 /* Read an integer field (anything written as ":fldname %d") */
60 #define READ_INT_FIELD(fldname) \
61         token = pg_strtok(&length);             /* skip :fldname */ \
62         token = pg_strtok(&length);             /* get field value */ \
63         local_node->fldname = atoi(token)
64
65 /* Read an unsigned integer field (anything written as ":fldname %u") */
66 #define READ_UINT_FIELD(fldname) \
67         token = pg_strtok(&length);             /* skip :fldname */ \
68         token = pg_strtok(&length);             /* get field value */ \
69         local_node->fldname = atoui(token)
70
71 /* Read an OID field (don't hard-wire assumption that OID is same as uint) */
72 #define READ_OID_FIELD(fldname) \
73         token = pg_strtok(&length);             /* skip :fldname */ \
74         token = pg_strtok(&length);             /* get field value */ \
75         local_node->fldname = atooid(token)
76
77 /* Read a char field (ie, one ascii character) */
78 #define READ_CHAR_FIELD(fldname) \
79         token = pg_strtok(&length);             /* skip :fldname */ \
80         token = pg_strtok(&length);             /* get field value */ \
81         local_node->fldname = token[0]
82
83 /* Read an enumerated-type field that was written as an integer code */
84 #define READ_ENUM_FIELD(fldname, enumtype) \
85         token = pg_strtok(&length);             /* skip :fldname */ \
86         token = pg_strtok(&length);             /* get field value */ \
87         local_node->fldname = (enumtype) atoi(token)
88
89 /* Read a float field */
90 #define READ_FLOAT_FIELD(fldname) \
91         token = pg_strtok(&length);             /* skip :fldname */ \
92         token = pg_strtok(&length);             /* get field value */ \
93         local_node->fldname = atof(token)
94
95 /* Read a boolean field */
96 #define READ_BOOL_FIELD(fldname) \
97         token = pg_strtok(&length);             /* skip :fldname */ \
98         token = pg_strtok(&length);             /* get field value */ \
99         local_node->fldname = strtobool(token)
100
101 /* Read a character-string field */
102 #define READ_STRING_FIELD(fldname) \
103         token = pg_strtok(&length);             /* skip :fldname */ \
104         token = pg_strtok(&length);             /* get field value */ \
105         local_node->fldname = nullable_string(token, length)
106
107 /* Read a parse location field (and throw away the value, per notes above) */
108 #define READ_LOCATION_FIELD(fldname) \
109         token = pg_strtok(&length);             /* skip :fldname */ \
110         token = pg_strtok(&length);             /* get field value */ \
111         local_node->fldname = -1        /* set field to "unknown" */
112
113 /* Read a Node field */
114 #define READ_NODE_FIELD(fldname) \
115         token = pg_strtok(&length);             /* skip :fldname */ \
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         READ_BOOL_FIELD(canSetTag);
199         READ_NODE_FIELD(utilityStmt);
200         READ_INT_FIELD(resultRelation);
201         READ_NODE_FIELD(intoClause);
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_BOOL_FIELD(forUpdate);
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
398         READ_DONE();
399 }
400
401 /*
402  * _readVar
403  */
404 static Var *
405 _readVar(void)
406 {
407         READ_LOCALS(Var);
408
409         READ_UINT_FIELD(varno);
410         READ_INT_FIELD(varattno);
411         READ_OID_FIELD(vartype);
412         READ_INT_FIELD(vartypmod);
413         READ_OID_FIELD(varcollid);
414         READ_UINT_FIELD(varlevelsup);
415         READ_UINT_FIELD(varnoold);
416         READ_INT_FIELD(varoattno);
417         READ_LOCATION_FIELD(location);
418
419         READ_DONE();
420 }
421
422 /*
423  * _readConst
424  */
425 static Const *
426 _readConst(void)
427 {
428         READ_LOCALS(Const);
429
430         READ_OID_FIELD(consttype);
431         READ_INT_FIELD(consttypmod);
432         READ_OID_FIELD(constcollid);
433         READ_INT_FIELD(constlen);
434         READ_BOOL_FIELD(constbyval);
435         READ_BOOL_FIELD(constisnull);
436         READ_LOCATION_FIELD(location);
437
438         token = pg_strtok(&length); /* skip :constvalue */
439         if (local_node->constisnull)
440                 token = pg_strtok(&length);             /* skip "<>" */
441         else
442                 local_node->constvalue = readDatum(local_node->constbyval);
443
444         READ_DONE();
445 }
446
447 /*
448  * _readParam
449  */
450 static Param *
451 _readParam(void)
452 {
453         READ_LOCALS(Param);
454
455         READ_ENUM_FIELD(paramkind, ParamKind);
456         READ_INT_FIELD(paramid);
457         READ_OID_FIELD(paramtype);
458         READ_INT_FIELD(paramtypmod);
459         READ_OID_FIELD(paramcollid);
460         READ_LOCATION_FIELD(location);
461
462         READ_DONE();
463 }
464
465 /*
466  * _readAggref
467  */
468 static Aggref *
469 _readAggref(void)
470 {
471         READ_LOCALS(Aggref);
472
473         READ_OID_FIELD(aggfnoid);
474         READ_OID_FIELD(aggtype);
475         READ_OID_FIELD(aggcollid);
476         READ_OID_FIELD(inputcollid);
477         READ_NODE_FIELD(args);
478         READ_NODE_FIELD(aggorder);
479         READ_NODE_FIELD(aggdistinct);
480         READ_BOOL_FIELD(aggstar);
481         READ_UINT_FIELD(agglevelsup);
482         READ_LOCATION_FIELD(location);
483
484         READ_DONE();
485 }
486
487 /*
488  * _readWindowFunc
489  */
490 static WindowFunc *
491 _readWindowFunc(void)
492 {
493         READ_LOCALS(WindowFunc);
494
495         READ_OID_FIELD(winfnoid);
496         READ_OID_FIELD(wintype);
497         READ_OID_FIELD(wincollid);
498         READ_OID_FIELD(inputcollid);
499         READ_NODE_FIELD(args);
500         READ_UINT_FIELD(winref);
501         READ_BOOL_FIELD(winstar);
502         READ_BOOL_FIELD(winagg);
503         READ_LOCATION_FIELD(location);
504
505         READ_DONE();
506 }
507
508 /*
509  * _readArrayRef
510  */
511 static ArrayRef *
512 _readArrayRef(void)
513 {
514         READ_LOCALS(ArrayRef);
515
516         READ_OID_FIELD(refarraytype);
517         READ_OID_FIELD(refelemtype);
518         READ_INT_FIELD(reftypmod);
519         READ_OID_FIELD(refcollid);
520         READ_NODE_FIELD(refupperindexpr);
521         READ_NODE_FIELD(reflowerindexpr);
522         READ_NODE_FIELD(refexpr);
523         READ_NODE_FIELD(refassgnexpr);
524
525         READ_DONE();
526 }
527
528 /*
529  * _readFuncExpr
530  */
531 static FuncExpr *
532 _readFuncExpr(void)
533 {
534         READ_LOCALS(FuncExpr);
535
536         READ_OID_FIELD(funcid);
537         READ_OID_FIELD(funcresulttype);
538         READ_BOOL_FIELD(funcretset);
539         READ_ENUM_FIELD(funcformat, CoercionForm);
540         READ_OID_FIELD(funccollid);
541         READ_OID_FIELD(inputcollid);
542         READ_NODE_FIELD(args);
543         READ_LOCATION_FIELD(location);
544
545         READ_DONE();
546 }
547
548 /*
549  * _readNamedArgExpr
550  */
551 static NamedArgExpr *
552 _readNamedArgExpr(void)
553 {
554         READ_LOCALS(NamedArgExpr);
555
556         READ_NODE_FIELD(arg);
557         READ_STRING_FIELD(name);
558         READ_INT_FIELD(argnumber);
559         READ_LOCATION_FIELD(location);
560
561         READ_DONE();
562 }
563
564 /*
565  * _readOpExpr
566  */
567 static OpExpr *
568 _readOpExpr(void)
569 {
570         READ_LOCALS(OpExpr);
571
572         READ_OID_FIELD(opno);
573         READ_OID_FIELD(opfuncid);
574
575         /*
576          * The opfuncid is stored in the textual format primarily for debugging
577          * and documentation reasons.  We want to always read it as zero to force
578          * it to be re-looked-up in the pg_operator entry.      This ensures that
579          * stored rules don't have hidden dependencies on operators' functions.
580          * (We don't currently support an ALTER OPERATOR command, but might
581          * someday.)
582          */
583         local_node->opfuncid = InvalidOid;
584
585         READ_OID_FIELD(opresulttype);
586         READ_BOOL_FIELD(opretset);
587         READ_OID_FIELD(opcollid);
588         READ_OID_FIELD(inputcollid);
589         READ_NODE_FIELD(args);
590         READ_LOCATION_FIELD(location);
591
592         READ_DONE();
593 }
594
595 /*
596  * _readDistinctExpr
597  */
598 static DistinctExpr *
599 _readDistinctExpr(void)
600 {
601         READ_LOCALS(DistinctExpr);
602
603         READ_OID_FIELD(opno);
604         READ_OID_FIELD(opfuncid);
605
606         /*
607          * The opfuncid is stored in the textual format primarily for debugging
608          * and documentation reasons.  We want to always read it as zero to force
609          * it to be re-looked-up in the pg_operator entry.      This ensures that
610          * stored rules don't have hidden dependencies on operators' functions.
611          * (We don't currently support an ALTER OPERATOR command, but might
612          * someday.)
613          */
614         local_node->opfuncid = InvalidOid;
615
616         READ_OID_FIELD(opresulttype);
617         READ_BOOL_FIELD(opretset);
618         READ_OID_FIELD(opcollid);
619         READ_OID_FIELD(inputcollid);
620         READ_NODE_FIELD(args);
621         READ_LOCATION_FIELD(location);
622
623         READ_DONE();
624 }
625
626 /*
627  * _readNullIfExpr
628  */
629 static NullIfExpr *
630 _readNullIfExpr(void)
631 {
632         READ_LOCALS(NullIfExpr);
633
634         READ_OID_FIELD(opno);
635         READ_OID_FIELD(opfuncid);
636
637         /*
638          * The opfuncid is stored in the textual format primarily for debugging
639          * and documentation reasons.  We want to always read it as zero to force
640          * it to be re-looked-up in the pg_operator entry.      This ensures that
641          * stored rules don't have hidden dependencies on operators' functions.
642          * (We don't currently support an ALTER OPERATOR command, but might
643          * someday.)
644          */
645         local_node->opfuncid = InvalidOid;
646
647         READ_OID_FIELD(opresulttype);
648         READ_BOOL_FIELD(opretset);
649         READ_OID_FIELD(opcollid);
650         READ_OID_FIELD(inputcollid);
651         READ_NODE_FIELD(args);
652         READ_LOCATION_FIELD(location);
653
654         READ_DONE();
655 }
656
657 /*
658  * _readScalarArrayOpExpr
659  */
660 static ScalarArrayOpExpr *
661 _readScalarArrayOpExpr(void)
662 {
663         READ_LOCALS(ScalarArrayOpExpr);
664
665         READ_OID_FIELD(opno);
666         READ_OID_FIELD(opfuncid);
667
668         /*
669          * The opfuncid is stored in the textual format primarily for debugging
670          * and documentation reasons.  We want to always read it as zero to force
671          * it to be re-looked-up in the pg_operator entry.      This ensures that
672          * stored rules don't have hidden dependencies on operators' functions.
673          * (We don't currently support an ALTER OPERATOR command, but might
674          * someday.)
675          */
676         local_node->opfuncid = InvalidOid;
677
678         READ_BOOL_FIELD(useOr);
679         READ_OID_FIELD(inputcollid);
680         READ_NODE_FIELD(args);
681         READ_LOCATION_FIELD(location);
682
683         READ_DONE();
684 }
685
686 /*
687  * _readBoolExpr
688  */
689 static BoolExpr *
690 _readBoolExpr(void)
691 {
692         READ_LOCALS(BoolExpr);
693
694         /* do-it-yourself enum representation */
695         token = pg_strtok(&length); /* skip :boolop */
696         token = pg_strtok(&length); /* get field value */
697         if (strncmp(token, "and", 3) == 0)
698                 local_node->boolop = AND_EXPR;
699         else if (strncmp(token, "or", 2) == 0)
700                 local_node->boolop = OR_EXPR;
701         else if (strncmp(token, "not", 3) == 0)
702                 local_node->boolop = NOT_EXPR;
703         else
704                 elog(ERROR, "unrecognized boolop \"%.*s\"", length, token);
705
706         READ_NODE_FIELD(args);
707         READ_LOCATION_FIELD(location);
708
709         READ_DONE();
710 }
711
712 /*
713  * _readSubLink
714  */
715 static SubLink *
716 _readSubLink(void)
717 {
718         READ_LOCALS(SubLink);
719
720         READ_ENUM_FIELD(subLinkType, SubLinkType);
721         READ_NODE_FIELD(testexpr);
722         READ_NODE_FIELD(operName);
723         READ_NODE_FIELD(subselect);
724         READ_LOCATION_FIELD(location);
725
726         READ_DONE();
727 }
728
729 /*
730  * _readSubPlan is not needed since it doesn't appear in stored rules.
731  */
732
733 /*
734  * _readFieldSelect
735  */
736 static FieldSelect *
737 _readFieldSelect(void)
738 {
739         READ_LOCALS(FieldSelect);
740
741         READ_NODE_FIELD(arg);
742         READ_INT_FIELD(fieldnum);
743         READ_OID_FIELD(resulttype);
744         READ_INT_FIELD(resulttypmod);
745         READ_OID_FIELD(resultcollid);
746
747         READ_DONE();
748 }
749
750 /*
751  * _readFieldStore
752  */
753 static FieldStore *
754 _readFieldStore(void)
755 {
756         READ_LOCALS(FieldStore);
757
758         READ_NODE_FIELD(arg);
759         READ_NODE_FIELD(newvals);
760         READ_NODE_FIELD(fieldnums);
761         READ_OID_FIELD(resulttype);
762
763         READ_DONE();
764 }
765
766 /*
767  * _readRelabelType
768  */
769 static RelabelType *
770 _readRelabelType(void)
771 {
772         READ_LOCALS(RelabelType);
773
774         READ_NODE_FIELD(arg);
775         READ_OID_FIELD(resulttype);
776         READ_INT_FIELD(resulttypmod);
777         READ_OID_FIELD(resultcollid);
778         READ_ENUM_FIELD(relabelformat, CoercionForm);
779         READ_LOCATION_FIELD(location);
780
781         READ_DONE();
782 }
783
784 /*
785  * _readCoerceViaIO
786  */
787 static CoerceViaIO *
788 _readCoerceViaIO(void)
789 {
790         READ_LOCALS(CoerceViaIO);
791
792         READ_NODE_FIELD(arg);
793         READ_OID_FIELD(resulttype);
794         READ_OID_FIELD(resultcollid);
795         READ_ENUM_FIELD(coerceformat, CoercionForm);
796         READ_LOCATION_FIELD(location);
797
798         READ_DONE();
799 }
800
801 /*
802  * _readArrayCoerceExpr
803  */
804 static ArrayCoerceExpr *
805 _readArrayCoerceExpr(void)
806 {
807         READ_LOCALS(ArrayCoerceExpr);
808
809         READ_NODE_FIELD(arg);
810         READ_OID_FIELD(elemfuncid);
811         READ_OID_FIELD(resulttype);
812         READ_INT_FIELD(resulttypmod);
813         READ_OID_FIELD(resultcollid);
814         READ_BOOL_FIELD(isExplicit);
815         READ_ENUM_FIELD(coerceformat, CoercionForm);
816         READ_LOCATION_FIELD(location);
817
818         READ_DONE();
819 }
820
821 /*
822  * _readConvertRowtypeExpr
823  */
824 static ConvertRowtypeExpr *
825 _readConvertRowtypeExpr(void)
826 {
827         READ_LOCALS(ConvertRowtypeExpr);
828
829         READ_NODE_FIELD(arg);
830         READ_OID_FIELD(resulttype);
831         READ_ENUM_FIELD(convertformat, CoercionForm);
832         READ_LOCATION_FIELD(location);
833
834         READ_DONE();
835 }
836
837 /*
838  * _readCollateExpr
839  */
840 static CollateExpr *
841 _readCollateExpr(void)
842 {
843         READ_LOCALS(CollateExpr);
844
845         READ_NODE_FIELD(arg);
846         READ_OID_FIELD(collOid);
847         READ_LOCATION_FIELD(location);
848
849         READ_DONE();
850 }
851
852 /*
853  * _readCaseExpr
854  */
855 static CaseExpr *
856 _readCaseExpr(void)
857 {
858         READ_LOCALS(CaseExpr);
859
860         READ_OID_FIELD(casetype);
861         READ_OID_FIELD(casecollid);
862         READ_NODE_FIELD(arg);
863         READ_NODE_FIELD(args);
864         READ_NODE_FIELD(defresult);
865         READ_LOCATION_FIELD(location);
866
867         READ_DONE();
868 }
869
870 /*
871  * _readCaseWhen
872  */
873 static CaseWhen *
874 _readCaseWhen(void)
875 {
876         READ_LOCALS(CaseWhen);
877
878         READ_NODE_FIELD(expr);
879         READ_NODE_FIELD(result);
880         READ_LOCATION_FIELD(location);
881
882         READ_DONE();
883 }
884
885 /*
886  * _readCaseTestExpr
887  */
888 static CaseTestExpr *
889 _readCaseTestExpr(void)
890 {
891         READ_LOCALS(CaseTestExpr);
892
893         READ_OID_FIELD(typeId);
894         READ_INT_FIELD(typeMod);
895         READ_OID_FIELD(collation);
896
897         READ_DONE();
898 }
899
900 /*
901  * _readArrayExpr
902  */
903 static ArrayExpr *
904 _readArrayExpr(void)
905 {
906         READ_LOCALS(ArrayExpr);
907
908         READ_OID_FIELD(array_typeid);
909         READ_OID_FIELD(array_collid);
910         READ_OID_FIELD(element_typeid);
911         READ_NODE_FIELD(elements);
912         READ_BOOL_FIELD(multidims);
913         READ_LOCATION_FIELD(location);
914
915         READ_DONE();
916 }
917
918 /*
919  * _readRowExpr
920  */
921 static RowExpr *
922 _readRowExpr(void)
923 {
924         READ_LOCALS(RowExpr);
925
926         READ_NODE_FIELD(args);
927         READ_OID_FIELD(row_typeid);
928         READ_ENUM_FIELD(row_format, CoercionForm);
929         READ_NODE_FIELD(colnames);
930         READ_LOCATION_FIELD(location);
931
932         READ_DONE();
933 }
934
935 /*
936  * _readRowCompareExpr
937  */
938 static RowCompareExpr *
939 _readRowCompareExpr(void)
940 {
941         READ_LOCALS(RowCompareExpr);
942
943         READ_ENUM_FIELD(rctype, RowCompareType);
944         READ_NODE_FIELD(opnos);
945         READ_NODE_FIELD(opfamilies);
946         READ_NODE_FIELD(inputcollids);
947         READ_NODE_FIELD(largs);
948         READ_NODE_FIELD(rargs);
949
950         READ_DONE();
951 }
952
953 /*
954  * _readCoalesceExpr
955  */
956 static CoalesceExpr *
957 _readCoalesceExpr(void)
958 {
959         READ_LOCALS(CoalesceExpr);
960
961         READ_OID_FIELD(coalescetype);
962         READ_OID_FIELD(coalescecollid);
963         READ_NODE_FIELD(args);
964         READ_LOCATION_FIELD(location);
965
966         READ_DONE();
967 }
968
969 /*
970  * _readMinMaxExpr
971  */
972 static MinMaxExpr *
973 _readMinMaxExpr(void)
974 {
975         READ_LOCALS(MinMaxExpr);
976
977         READ_OID_FIELD(minmaxtype);
978         READ_OID_FIELD(minmaxcollid);
979         READ_OID_FIELD(inputcollid);
980         READ_ENUM_FIELD(op, MinMaxOp);
981         READ_NODE_FIELD(args);
982         READ_LOCATION_FIELD(location);
983
984         READ_DONE();
985 }
986
987 /*
988  * _readXmlExpr
989  */
990 static XmlExpr *
991 _readXmlExpr(void)
992 {
993         READ_LOCALS(XmlExpr);
994
995         READ_ENUM_FIELD(op, XmlExprOp);
996         READ_STRING_FIELD(name);
997         READ_NODE_FIELD(named_args);
998         READ_NODE_FIELD(arg_names);
999         READ_NODE_FIELD(args);
1000         READ_ENUM_FIELD(xmloption, XmlOptionType);
1001         READ_OID_FIELD(type);
1002         READ_INT_FIELD(typmod);
1003         READ_LOCATION_FIELD(location);
1004
1005         READ_DONE();
1006 }
1007
1008 /*
1009  * _readNullTest
1010  */
1011 static NullTest *
1012 _readNullTest(void)
1013 {
1014         READ_LOCALS(NullTest);
1015
1016         READ_NODE_FIELD(arg);
1017         READ_ENUM_FIELD(nulltesttype, NullTestType);
1018         READ_BOOL_FIELD(argisrow);
1019
1020         READ_DONE();
1021 }
1022
1023 /*
1024  * _readBooleanTest
1025  */
1026 static BooleanTest *
1027 _readBooleanTest(void)
1028 {
1029         READ_LOCALS(BooleanTest);
1030
1031         READ_NODE_FIELD(arg);
1032         READ_ENUM_FIELD(booltesttype, BoolTestType);
1033
1034         READ_DONE();
1035 }
1036
1037 /*
1038  * _readCoerceToDomain
1039  */
1040 static CoerceToDomain *
1041 _readCoerceToDomain(void)
1042 {
1043         READ_LOCALS(CoerceToDomain);
1044
1045         READ_NODE_FIELD(arg);
1046         READ_OID_FIELD(resulttype);
1047         READ_INT_FIELD(resulttypmod);
1048         READ_OID_FIELD(resultcollid);
1049         READ_ENUM_FIELD(coercionformat, CoercionForm);
1050         READ_LOCATION_FIELD(location);
1051
1052         READ_DONE();
1053 }
1054
1055 /*
1056  * _readCoerceToDomainValue
1057  */
1058 static CoerceToDomainValue *
1059 _readCoerceToDomainValue(void)
1060 {
1061         READ_LOCALS(CoerceToDomainValue);
1062
1063         READ_OID_FIELD(typeId);
1064         READ_INT_FIELD(typeMod);
1065         READ_OID_FIELD(collation);
1066         READ_LOCATION_FIELD(location);
1067
1068         READ_DONE();
1069 }
1070
1071 /*
1072  * _readSetToDefault
1073  */
1074 static SetToDefault *
1075 _readSetToDefault(void)
1076 {
1077         READ_LOCALS(SetToDefault);
1078
1079         READ_OID_FIELD(typeId);
1080         READ_INT_FIELD(typeMod);
1081         READ_OID_FIELD(collation);
1082         READ_LOCATION_FIELD(location);
1083
1084         READ_DONE();
1085 }
1086
1087 /*
1088  * _readCurrentOfExpr
1089  */
1090 static CurrentOfExpr *
1091 _readCurrentOfExpr(void)
1092 {
1093         READ_LOCALS(CurrentOfExpr);
1094
1095         READ_UINT_FIELD(cvarno);
1096         READ_STRING_FIELD(cursor_name);
1097         READ_INT_FIELD(cursor_param);
1098
1099         READ_DONE();
1100 }
1101
1102 /*
1103  * _readTargetEntry
1104  */
1105 static TargetEntry *
1106 _readTargetEntry(void)
1107 {
1108         READ_LOCALS(TargetEntry);
1109
1110         READ_NODE_FIELD(expr);
1111         READ_INT_FIELD(resno);
1112         READ_STRING_FIELD(resname);
1113         READ_UINT_FIELD(ressortgroupref);
1114         READ_OID_FIELD(resorigtbl);
1115         READ_INT_FIELD(resorigcol);
1116         READ_BOOL_FIELD(resjunk);
1117
1118         READ_DONE();
1119 }
1120
1121 /*
1122  * _readRangeTblRef
1123  */
1124 static RangeTblRef *
1125 _readRangeTblRef(void)
1126 {
1127         READ_LOCALS(RangeTblRef);
1128
1129         READ_INT_FIELD(rtindex);
1130
1131         READ_DONE();
1132 }
1133
1134 /*
1135  * _readJoinExpr
1136  */
1137 static JoinExpr *
1138 _readJoinExpr(void)
1139 {
1140         READ_LOCALS(JoinExpr);
1141
1142         READ_ENUM_FIELD(jointype, JoinType);
1143         READ_BOOL_FIELD(isNatural);
1144         READ_NODE_FIELD(larg);
1145         READ_NODE_FIELD(rarg);
1146         READ_NODE_FIELD(usingClause);
1147         READ_NODE_FIELD(quals);
1148         READ_NODE_FIELD(alias);
1149         READ_INT_FIELD(rtindex);
1150
1151         READ_DONE();
1152 }
1153
1154 /*
1155  * _readFromExpr
1156  */
1157 static FromExpr *
1158 _readFromExpr(void)
1159 {
1160         READ_LOCALS(FromExpr);
1161
1162         READ_NODE_FIELD(fromlist);
1163         READ_NODE_FIELD(quals);
1164
1165         READ_DONE();
1166 }
1167
1168
1169 /*
1170  *      Stuff from parsenodes.h.
1171  */
1172
1173 /*
1174  * _readRangeTblEntry
1175  */
1176 static RangeTblEntry *
1177 _readRangeTblEntry(void)
1178 {
1179         READ_LOCALS(RangeTblEntry);
1180
1181         /* put alias + eref first to make dump more legible */
1182         READ_NODE_FIELD(alias);
1183         READ_NODE_FIELD(eref);
1184         READ_ENUM_FIELD(rtekind, RTEKind);
1185
1186         switch (local_node->rtekind)
1187         {
1188                 case RTE_RELATION:
1189                         READ_OID_FIELD(relid);
1190                         READ_CHAR_FIELD(relkind);
1191                         break;
1192                 case RTE_SUBQUERY:
1193                         READ_NODE_FIELD(subquery);
1194                         break;
1195                 case RTE_JOIN:
1196                         READ_ENUM_FIELD(jointype, JoinType);
1197                         READ_NODE_FIELD(joinaliasvars);
1198                         break;
1199                 case RTE_FUNCTION:
1200                         READ_NODE_FIELD(funcexpr);
1201                         READ_NODE_FIELD(funccoltypes);
1202                         READ_NODE_FIELD(funccoltypmods);
1203                         READ_NODE_FIELD(funccolcollations);
1204                         break;
1205                 case RTE_VALUES:
1206                         READ_NODE_FIELD(values_lists);
1207                         READ_NODE_FIELD(values_collations);
1208                         break;
1209                 case RTE_CTE:
1210                         READ_STRING_FIELD(ctename);
1211                         READ_UINT_FIELD(ctelevelsup);
1212                         READ_BOOL_FIELD(self_reference);
1213                         READ_NODE_FIELD(ctecoltypes);
1214                         READ_NODE_FIELD(ctecoltypmods);
1215                         READ_NODE_FIELD(ctecolcollations);
1216                         break;
1217                 default:
1218                         elog(ERROR, "unrecognized RTE kind: %d",
1219                                  (int) local_node->rtekind);
1220                         break;
1221         }
1222
1223         READ_BOOL_FIELD(inh);
1224         READ_BOOL_FIELD(inFromCl);
1225         READ_UINT_FIELD(requiredPerms);
1226         READ_OID_FIELD(checkAsUser);
1227         READ_BITMAPSET_FIELD(selectedCols);
1228         READ_BITMAPSET_FIELD(modifiedCols);
1229
1230         READ_DONE();
1231 }
1232
1233
1234 /*
1235  * parseNodeString
1236  *
1237  * Given a character string representing a node tree, parseNodeString creates
1238  * the internal node structure.
1239  *
1240  * The string to be read must already have been loaded into pg_strtok().
1241  */
1242 Node *
1243 parseNodeString(void)
1244 {
1245         void       *return_value;
1246
1247         READ_TEMP_LOCALS();
1248
1249         token = pg_strtok(&length);
1250
1251 #define MATCH(tokname, namelen) \
1252         (length == namelen && memcmp(token, tokname, namelen) == 0)
1253
1254         if (MATCH("QUERY", 5))
1255                 return_value = _readQuery();
1256         else if (MATCH("SORTGROUPCLAUSE", 15))
1257                 return_value = _readSortGroupClause();
1258         else if (MATCH("WINDOWCLAUSE", 12))
1259                 return_value = _readWindowClause();
1260         else if (MATCH("ROWMARKCLAUSE", 13))
1261                 return_value = _readRowMarkClause();
1262         else if (MATCH("COMMONTABLEEXPR", 15))
1263                 return_value = _readCommonTableExpr();
1264         else if (MATCH("SETOPERATIONSTMT", 16))
1265                 return_value = _readSetOperationStmt();
1266         else if (MATCH("ALIAS", 5))
1267                 return_value = _readAlias();
1268         else if (MATCH("RANGEVAR", 8))
1269                 return_value = _readRangeVar();
1270         else if (MATCH("INTOCLAUSE", 10))
1271                 return_value = _readIntoClause();
1272         else if (MATCH("VAR", 3))
1273                 return_value = _readVar();
1274         else if (MATCH("CONST", 5))
1275                 return_value = _readConst();
1276         else if (MATCH("PARAM", 5))
1277                 return_value = _readParam();
1278         else if (MATCH("AGGREF", 6))
1279                 return_value = _readAggref();
1280         else if (MATCH("WINDOWFUNC", 10))
1281                 return_value = _readWindowFunc();
1282         else if (MATCH("ARRAYREF", 8))
1283                 return_value = _readArrayRef();
1284         else if (MATCH("FUNCEXPR", 8))
1285                 return_value = _readFuncExpr();
1286         else if (MATCH("NAMEDARGEXPR", 12))
1287                 return_value = _readNamedArgExpr();
1288         else if (MATCH("OPEXPR", 6))
1289                 return_value = _readOpExpr();
1290         else if (MATCH("DISTINCTEXPR", 12))
1291                 return_value = _readDistinctExpr();
1292         else if (MATCH("NULLIFEXPR", 10))
1293                 return_value = _readNullIfExpr();
1294         else if (MATCH("SCALARARRAYOPEXPR", 17))
1295                 return_value = _readScalarArrayOpExpr();
1296         else if (MATCH("BOOLEXPR", 8))
1297                 return_value = _readBoolExpr();
1298         else if (MATCH("SUBLINK", 7))
1299                 return_value = _readSubLink();
1300         else if (MATCH("FIELDSELECT", 11))
1301                 return_value = _readFieldSelect();
1302         else if (MATCH("FIELDSTORE", 10))
1303                 return_value = _readFieldStore();
1304         else if (MATCH("RELABELTYPE", 11))
1305                 return_value = _readRelabelType();
1306         else if (MATCH("COERCEVIAIO", 11))
1307                 return_value = _readCoerceViaIO();
1308         else if (MATCH("ARRAYCOERCEEXPR", 15))
1309                 return_value = _readArrayCoerceExpr();
1310         else if (MATCH("CONVERTROWTYPEEXPR", 18))
1311                 return_value = _readConvertRowtypeExpr();
1312         else if (MATCH("COLLATE", 7))
1313                 return_value = _readCollateExpr();
1314         else if (MATCH("CASE", 4))
1315                 return_value = _readCaseExpr();
1316         else if (MATCH("WHEN", 4))
1317                 return_value = _readCaseWhen();
1318         else if (MATCH("CASETESTEXPR", 12))
1319                 return_value = _readCaseTestExpr();
1320         else if (MATCH("ARRAY", 5))
1321                 return_value = _readArrayExpr();
1322         else if (MATCH("ROW", 3))
1323                 return_value = _readRowExpr();
1324         else if (MATCH("ROWCOMPARE", 10))
1325                 return_value = _readRowCompareExpr();
1326         else if (MATCH("COALESCE", 8))
1327                 return_value = _readCoalesceExpr();
1328         else if (MATCH("MINMAX", 6))
1329                 return_value = _readMinMaxExpr();
1330         else if (MATCH("XMLEXPR", 7))
1331                 return_value = _readXmlExpr();
1332         else if (MATCH("NULLTEST", 8))
1333                 return_value = _readNullTest();
1334         else if (MATCH("BOOLEANTEST", 11))
1335                 return_value = _readBooleanTest();
1336         else if (MATCH("COERCETODOMAIN", 14))
1337                 return_value = _readCoerceToDomain();
1338         else if (MATCH("COERCETODOMAINVALUE", 19))
1339                 return_value = _readCoerceToDomainValue();
1340         else if (MATCH("SETTODEFAULT", 12))
1341                 return_value = _readSetToDefault();
1342         else if (MATCH("CURRENTOFEXPR", 13))
1343                 return_value = _readCurrentOfExpr();
1344         else if (MATCH("TARGETENTRY", 11))
1345                 return_value = _readTargetEntry();
1346         else if (MATCH("RANGETBLREF", 11))
1347                 return_value = _readRangeTblRef();
1348         else if (MATCH("JOINEXPR", 8))
1349                 return_value = _readJoinExpr();
1350         else if (MATCH("FROMEXPR", 8))
1351                 return_value = _readFromExpr();
1352         else if (MATCH("RTE", 3))
1353                 return_value = _readRangeTblEntry();
1354         else if (MATCH("NOTIFY", 6))
1355                 return_value = _readNotifyStmt();
1356         else if (MATCH("DECLARECURSOR", 13))
1357                 return_value = _readDeclareCursorStmt();
1358         else
1359         {
1360                 elog(ERROR, "badly formatted node string \"%.32s\"...", token);
1361                 return_value = NULL;    /* keep compiler quiet */
1362         }
1363
1364         return (Node *) return_value;
1365 }
1366
1367
1368 /*
1369  * readDatum
1370  *
1371  * Given a string representation of a constant, recreate the appropriate
1372  * Datum.  The string representation embeds length info, but not byValue,
1373  * so we must be told that.
1374  */
1375 static Datum
1376 readDatum(bool typbyval)
1377 {
1378         Size            length,
1379                                 i;
1380         int                     tokenLength;
1381         char       *token;
1382         Datum           res;
1383         char       *s;
1384
1385         /*
1386          * read the actual length of the value
1387          */
1388         token = pg_strtok(&tokenLength);
1389         length = atoui(token);
1390
1391         token = pg_strtok(&tokenLength);        /* read the '[' */
1392         if (token == NULL || token[0] != '[')
1393                 elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %lu",
1394                          token ? (const char *) token : "[NULL]",
1395                          (unsigned long) length);
1396
1397         if (typbyval)
1398         {
1399                 if (length > (Size) sizeof(Datum))
1400                         elog(ERROR, "byval datum but length = %lu",
1401                                  (unsigned long) length);
1402                 res = (Datum) 0;
1403                 s = (char *) (&res);
1404                 for (i = 0; i < (Size) sizeof(Datum); i++)
1405                 {
1406                         token = pg_strtok(&tokenLength);
1407                         s[i] = (char) atoi(token);
1408                 }
1409         }
1410         else if (length <= 0)
1411                 res = (Datum) NULL;
1412         else
1413         {
1414                 s = (char *) palloc(length);
1415                 for (i = 0; i < length; i++)
1416                 {
1417                         token = pg_strtok(&tokenLength);
1418                         s[i] = (char) atoi(token);
1419                 }
1420                 res = PointerGetDatum(s);
1421         }
1422
1423         token = pg_strtok(&tokenLength);        /* read the ']' */
1424         if (token == NULL || token[0] != ']')
1425                 elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %lu",
1426                          token ? (const char *) token : "[NULL]",
1427                          (unsigned long) length);
1428
1429         return res;
1430 }