]> granicus.if.org Git - postgresql/blob - src/backend/nodes/readfuncs.c
1f3b81e275f335b1117bee7d4be8c3b975db574f
[postgresql] / src / backend / nodes / readfuncs.c
1 /*-------------------------------------------------------------------------
2  *
3  * readfuncs.c
4  *        Reader functions for Postgres tree nodes.
5  *
6  * Portions Copyright (c) 1996-2007, 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.205 2007/03/27 23:21:09 tgl 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(into);
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  * _readArrayCoerceExpr
589  */
590 static ArrayCoerceExpr *
591 _readArrayCoerceExpr(void)
592 {
593         READ_LOCALS(ArrayCoerceExpr);
594
595         READ_NODE_FIELD(arg);
596         READ_OID_FIELD(elemfuncid);
597         READ_OID_FIELD(resulttype);
598         READ_INT_FIELD(resulttypmod);
599         READ_BOOL_FIELD(isExplicit);
600         READ_ENUM_FIELD(coerceformat, CoercionForm);
601
602         READ_DONE();
603 }
604
605 /*
606  * _readConvertRowtypeExpr
607  */
608 static ConvertRowtypeExpr *
609 _readConvertRowtypeExpr(void)
610 {
611         READ_LOCALS(ConvertRowtypeExpr);
612
613         READ_NODE_FIELD(arg);
614         READ_OID_FIELD(resulttype);
615         READ_ENUM_FIELD(convertformat, CoercionForm);
616
617         READ_DONE();
618 }
619
620 /*
621  * _readCaseExpr
622  */
623 static CaseExpr *
624 _readCaseExpr(void)
625 {
626         READ_LOCALS(CaseExpr);
627
628         READ_OID_FIELD(casetype);
629         READ_NODE_FIELD(arg);
630         READ_NODE_FIELD(args);
631         READ_NODE_FIELD(defresult);
632
633         READ_DONE();
634 }
635
636 /*
637  * _readCaseWhen
638  */
639 static CaseWhen *
640 _readCaseWhen(void)
641 {
642         READ_LOCALS(CaseWhen);
643
644         READ_NODE_FIELD(expr);
645         READ_NODE_FIELD(result);
646
647         READ_DONE();
648 }
649
650 /*
651  * _readCaseTestExpr
652  */
653 static CaseTestExpr *
654 _readCaseTestExpr(void)
655 {
656         READ_LOCALS(CaseTestExpr);
657
658         READ_OID_FIELD(typeId);
659         READ_INT_FIELD(typeMod);
660
661         READ_DONE();
662 }
663
664 /*
665  * _readArrayExpr
666  */
667 static ArrayExpr *
668 _readArrayExpr(void)
669 {
670         READ_LOCALS(ArrayExpr);
671
672         READ_OID_FIELD(array_typeid);
673         READ_OID_FIELD(element_typeid);
674         READ_NODE_FIELD(elements);
675         READ_BOOL_FIELD(multidims);
676
677         READ_DONE();
678 }
679
680 /*
681  * _readRowExpr
682  */
683 static RowExpr *
684 _readRowExpr(void)
685 {
686         READ_LOCALS(RowExpr);
687
688         READ_NODE_FIELD(args);
689         READ_OID_FIELD(row_typeid);
690         READ_ENUM_FIELD(row_format, CoercionForm);
691
692         READ_DONE();
693 }
694
695 /*
696  * _readRowCompareExpr
697  */
698 static RowCompareExpr *
699 _readRowCompareExpr(void)
700 {
701         READ_LOCALS(RowCompareExpr);
702
703         READ_ENUM_FIELD(rctype, RowCompareType);
704         READ_NODE_FIELD(opnos);
705         READ_NODE_FIELD(opfamilies);
706         READ_NODE_FIELD(largs);
707         READ_NODE_FIELD(rargs);
708
709         READ_DONE();
710 }
711
712 /*
713  * _readCoalesceExpr
714  */
715 static CoalesceExpr *
716 _readCoalesceExpr(void)
717 {
718         READ_LOCALS(CoalesceExpr);
719
720         READ_OID_FIELD(coalescetype);
721         READ_NODE_FIELD(args);
722
723         READ_DONE();
724 }
725
726 /*
727  * _readMinMaxExpr
728  */
729 static MinMaxExpr *
730 _readMinMaxExpr(void)
731 {
732         READ_LOCALS(MinMaxExpr);
733
734         READ_OID_FIELD(minmaxtype);
735         READ_ENUM_FIELD(op, MinMaxOp);
736         READ_NODE_FIELD(args);
737
738         READ_DONE();
739 }
740
741 /*
742  * _readXmlExpr
743  */
744 static XmlExpr *
745 _readXmlExpr(void)
746 {
747         READ_LOCALS(XmlExpr);
748
749         READ_ENUM_FIELD(op, XmlExprOp);
750         READ_STRING_FIELD(name);
751         READ_NODE_FIELD(named_args);
752         READ_NODE_FIELD(arg_names);
753         READ_NODE_FIELD(args);
754         READ_ENUM_FIELD(xmloption, XmlOptionType);
755         READ_OID_FIELD(type);
756         READ_INT_FIELD(typmod);
757
758         READ_DONE();
759 }
760
761 /*
762  * _readNullIfExpr
763  */
764 static NullIfExpr *
765 _readNullIfExpr(void)
766 {
767         READ_LOCALS(NullIfExpr);
768
769         READ_OID_FIELD(opno);
770         READ_OID_FIELD(opfuncid);
771
772         /*
773          * The opfuncid is stored in the textual format primarily for debugging
774          * and documentation reasons.  We want to always read it as zero to force
775          * it to be re-looked-up in the pg_operator entry.      This ensures that
776          * stored rules don't have hidden dependencies on operators' functions.
777          * (We don't currently support an ALTER OPERATOR command, but might
778          * someday.)
779          */
780         local_node->opfuncid = InvalidOid;
781
782         READ_OID_FIELD(opresulttype);
783         READ_BOOL_FIELD(opretset);
784         READ_NODE_FIELD(args);
785
786         READ_DONE();
787 }
788
789 /*
790  * _readNullTest
791  */
792 static NullTest *
793 _readNullTest(void)
794 {
795         READ_LOCALS(NullTest);
796
797         READ_NODE_FIELD(arg);
798         READ_ENUM_FIELD(nulltesttype, NullTestType);
799
800         READ_DONE();
801 }
802
803 /*
804  * _readBooleanTest
805  */
806 static BooleanTest *
807 _readBooleanTest(void)
808 {
809         READ_LOCALS(BooleanTest);
810
811         READ_NODE_FIELD(arg);
812         READ_ENUM_FIELD(booltesttype, BoolTestType);
813
814         READ_DONE();
815 }
816
817 /*
818  * _readCoerceToDomain
819  */
820 static CoerceToDomain *
821 _readCoerceToDomain(void)
822 {
823         READ_LOCALS(CoerceToDomain);
824
825         READ_NODE_FIELD(arg);
826         READ_OID_FIELD(resulttype);
827         READ_INT_FIELD(resulttypmod);
828         READ_ENUM_FIELD(coercionformat, CoercionForm);
829
830         READ_DONE();
831 }
832
833 /*
834  * _readCoerceToDomainValue
835  */
836 static CoerceToDomainValue *
837 _readCoerceToDomainValue(void)
838 {
839         READ_LOCALS(CoerceToDomainValue);
840
841         READ_OID_FIELD(typeId);
842         READ_INT_FIELD(typeMod);
843
844         READ_DONE();
845 }
846
847 /*
848  * _readSetToDefault
849  */
850 static SetToDefault *
851 _readSetToDefault(void)
852 {
853         READ_LOCALS(SetToDefault);
854
855         READ_OID_FIELD(typeId);
856         READ_INT_FIELD(typeMod);
857
858         READ_DONE();
859 }
860
861 /*
862  * _readTargetEntry
863  */
864 static TargetEntry *
865 _readTargetEntry(void)
866 {
867         READ_LOCALS(TargetEntry);
868
869         READ_NODE_FIELD(expr);
870         READ_INT_FIELD(resno);
871         READ_STRING_FIELD(resname);
872         READ_UINT_FIELD(ressortgroupref);
873         READ_OID_FIELD(resorigtbl);
874         READ_INT_FIELD(resorigcol);
875         READ_BOOL_FIELD(resjunk);
876
877         READ_DONE();
878 }
879
880 /*
881  * _readRangeTblRef
882  */
883 static RangeTblRef *
884 _readRangeTblRef(void)
885 {
886         READ_LOCALS(RangeTblRef);
887
888         READ_INT_FIELD(rtindex);
889
890         READ_DONE();
891 }
892
893 /*
894  * _readJoinExpr
895  */
896 static JoinExpr *
897 _readJoinExpr(void)
898 {
899         READ_LOCALS(JoinExpr);
900
901         READ_ENUM_FIELD(jointype, JoinType);
902         READ_BOOL_FIELD(isNatural);
903         READ_NODE_FIELD(larg);
904         READ_NODE_FIELD(rarg);
905         READ_NODE_FIELD(using);
906         READ_NODE_FIELD(quals);
907         READ_NODE_FIELD(alias);
908         READ_INT_FIELD(rtindex);
909
910         READ_DONE();
911 }
912
913 /*
914  * _readFromExpr
915  */
916 static FromExpr *
917 _readFromExpr(void)
918 {
919         READ_LOCALS(FromExpr);
920
921         READ_NODE_FIELD(fromlist);
922         READ_NODE_FIELD(quals);
923
924         READ_DONE();
925 }
926
927
928 /*
929  *      Stuff from parsenodes.h.
930  */
931
932 /*
933  * _readRangeTblEntry
934  */
935 static RangeTblEntry *
936 _readRangeTblEntry(void)
937 {
938         READ_LOCALS(RangeTblEntry);
939
940         /* put alias + eref first to make dump more legible */
941         READ_NODE_FIELD(alias);
942         READ_NODE_FIELD(eref);
943         READ_ENUM_FIELD(rtekind, RTEKind);
944
945         switch (local_node->rtekind)
946         {
947                 case RTE_RELATION:
948                 case RTE_SPECIAL:
949                         READ_OID_FIELD(relid);
950                         break;
951                 case RTE_SUBQUERY:
952                         READ_NODE_FIELD(subquery);
953                         break;
954                 case RTE_FUNCTION:
955                         READ_NODE_FIELD(funcexpr);
956                         READ_NODE_FIELD(funccoltypes);
957                         READ_NODE_FIELD(funccoltypmods);
958                         break;
959                 case RTE_VALUES:
960                         READ_NODE_FIELD(values_lists);
961                         break;
962                 case RTE_JOIN:
963                         READ_ENUM_FIELD(jointype, JoinType);
964                         READ_NODE_FIELD(joinaliasvars);
965                         break;
966                 default:
967                         elog(ERROR, "unrecognized RTE kind: %d",
968                                  (int) local_node->rtekind);
969                         break;
970         }
971
972         READ_BOOL_FIELD(inh);
973         READ_BOOL_FIELD(inFromCl);
974         READ_UINT_FIELD(requiredPerms);
975         READ_OID_FIELD(checkAsUser);
976
977         READ_DONE();
978 }
979
980
981 /*
982  * parseNodeString
983  *
984  * Given a character string representing a node tree, parseNodeString creates
985  * the internal node structure.
986  *
987  * The string to be read must already have been loaded into pg_strtok().
988  */
989 Node *
990 parseNodeString(void)
991 {
992         void       *return_value;
993
994         READ_TEMP_LOCALS();
995
996         token = pg_strtok(&length);
997
998 #define MATCH(tokname, namelen) \
999         (length == namelen && strncmp(token, tokname, namelen) == 0)
1000
1001         if (MATCH("QUERY", 5))
1002                 return_value = _readQuery();
1003         else if (MATCH("SORTCLAUSE", 10))
1004                 return_value = _readSortClause();
1005         else if (MATCH("GROUPCLAUSE", 11))
1006                 return_value = _readGroupClause();
1007         else if (MATCH("ROWMARKCLAUSE", 13))
1008                 return_value = _readRowMarkClause();
1009         else if (MATCH("SETOPERATIONSTMT", 16))
1010                 return_value = _readSetOperationStmt();
1011         else if (MATCH("ALIAS", 5))
1012                 return_value = _readAlias();
1013         else if (MATCH("RANGEVAR", 8))
1014                 return_value = _readRangeVar();
1015         else if (MATCH("INTOCLAUSE", 10))
1016                 return_value = _readIntoClause();
1017         else if (MATCH("VAR", 3))
1018                 return_value = _readVar();
1019         else if (MATCH("CONST", 5))
1020                 return_value = _readConst();
1021         else if (MATCH("PARAM", 5))
1022                 return_value = _readParam();
1023         else if (MATCH("AGGREF", 6))
1024                 return_value = _readAggref();
1025         else if (MATCH("ARRAYREF", 8))
1026                 return_value = _readArrayRef();
1027         else if (MATCH("FUNCEXPR", 8))
1028                 return_value = _readFuncExpr();
1029         else if (MATCH("OPEXPR", 6))
1030                 return_value = _readOpExpr();
1031         else if (MATCH("DISTINCTEXPR", 12))
1032                 return_value = _readDistinctExpr();
1033         else if (MATCH("SCALARARRAYOPEXPR", 17))
1034                 return_value = _readScalarArrayOpExpr();
1035         else if (MATCH("BOOLEXPR", 8))
1036                 return_value = _readBoolExpr();
1037         else if (MATCH("SUBLINK", 7))
1038                 return_value = _readSubLink();
1039         else if (MATCH("FIELDSELECT", 11))
1040                 return_value = _readFieldSelect();
1041         else if (MATCH("FIELDSTORE", 10))
1042                 return_value = _readFieldStore();
1043         else if (MATCH("RELABELTYPE", 11))
1044                 return_value = _readRelabelType();
1045         else if (MATCH("ARRAYCOERCEEXPR", 15))
1046                 return_value = _readArrayCoerceExpr();
1047         else if (MATCH("CONVERTROWTYPEEXPR", 18))
1048                 return_value = _readConvertRowtypeExpr();
1049         else if (MATCH("CASE", 4))
1050                 return_value = _readCaseExpr();
1051         else if (MATCH("WHEN", 4))
1052                 return_value = _readCaseWhen();
1053         else if (MATCH("CASETESTEXPR", 12))
1054                 return_value = _readCaseTestExpr();
1055         else if (MATCH("ARRAY", 5))
1056                 return_value = _readArrayExpr();
1057         else if (MATCH("ROW", 3))
1058                 return_value = _readRowExpr();
1059         else if (MATCH("ROWCOMPARE", 10))
1060                 return_value = _readRowCompareExpr();
1061         else if (MATCH("COALESCE", 8))
1062                 return_value = _readCoalesceExpr();
1063         else if (MATCH("MINMAX", 6))
1064                 return_value = _readMinMaxExpr();
1065         else if (MATCH("XMLEXPR", 7))
1066                 return_value = _readXmlExpr();
1067         else if (MATCH("NULLIFEXPR", 10))
1068                 return_value = _readNullIfExpr();
1069         else if (MATCH("NULLTEST", 8))
1070                 return_value = _readNullTest();
1071         else if (MATCH("BOOLEANTEST", 11))
1072                 return_value = _readBooleanTest();
1073         else if (MATCH("COERCETODOMAIN", 14))
1074                 return_value = _readCoerceToDomain();
1075         else if (MATCH("COERCETODOMAINVALUE", 19))
1076                 return_value = _readCoerceToDomainValue();
1077         else if (MATCH("SETTODEFAULT", 12))
1078                 return_value = _readSetToDefault();
1079         else if (MATCH("TARGETENTRY", 11))
1080                 return_value = _readTargetEntry();
1081         else if (MATCH("RANGETBLREF", 11))
1082                 return_value = _readRangeTblRef();
1083         else if (MATCH("JOINEXPR", 8))
1084                 return_value = _readJoinExpr();
1085         else if (MATCH("FROMEXPR", 8))
1086                 return_value = _readFromExpr();
1087         else if (MATCH("RTE", 3))
1088                 return_value = _readRangeTblEntry();
1089         else if (MATCH("NOTIFY", 6))
1090                 return_value = _readNotifyStmt();
1091         else if (MATCH("DECLARECURSOR", 13))
1092                 return_value = _readDeclareCursorStmt();
1093         else
1094         {
1095                 elog(ERROR, "badly formatted node string \"%.32s\"...", token);
1096                 return_value = NULL;    /* keep compiler quiet */
1097         }
1098
1099         return (Node *) return_value;
1100 }
1101
1102
1103 /*
1104  * readDatum
1105  *
1106  * Given a string representation of a constant, recreate the appropriate
1107  * Datum.  The string representation embeds length info, but not byValue,
1108  * so we must be told that.
1109  */
1110 static Datum
1111 readDatum(bool typbyval)
1112 {
1113         Size            length,
1114                                 i;
1115         int                     tokenLength;
1116         char       *token;
1117         Datum           res;
1118         char       *s;
1119
1120         /*
1121          * read the actual length of the value
1122          */
1123         token = pg_strtok(&tokenLength);
1124         length = atoui(token);
1125
1126         token = pg_strtok(&tokenLength);        /* read the '[' */
1127         if (token == NULL || token[0] != '[')
1128                 elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %lu",
1129                          token ? (const char *) token : "[NULL]",
1130                          (unsigned long) length);
1131
1132         if (typbyval)
1133         {
1134                 if (length > (Size) sizeof(Datum))
1135                         elog(ERROR, "byval datum but length = %lu",
1136                                  (unsigned long) length);
1137                 res = (Datum) 0;
1138                 s = (char *) (&res);
1139                 for (i = 0; i < (Size) sizeof(Datum); i++)
1140                 {
1141                         token = pg_strtok(&tokenLength);
1142                         s[i] = (char) atoi(token);
1143                 }
1144         }
1145         else if (length <= 0)
1146                 res = (Datum) NULL;
1147         else
1148         {
1149                 s = (char *) palloc(length);
1150                 for (i = 0; i < length; i++)
1151                 {
1152                         token = pg_strtok(&tokenLength);
1153                         s[i] = (char) atoi(token);
1154                 }
1155                 res = PointerGetDatum(s);
1156         }
1157
1158         token = pg_strtok(&tokenLength);        /* read the ']' */
1159         if (token == NULL || token[0] != ']')
1160                 elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %lu",
1161                          token ? (const char *) token : "[NULL]",
1162                          (unsigned long) length);
1163
1164         return res;
1165 }