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