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