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