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