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