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