1 /*-------------------------------------------------------------------------
4 * Reader functions for Postgres tree nodes.
6 * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.85 2000/02/20 21:32:05 tgl Exp $
14 * Most of the read functions for plan nodes are tested. (In fact, they
15 * pass the regression test as of 11/8/94.) The rest (for path selection)
16 * are probably never used. No effort has been made to get them to work.
17 * The simplest way to test these functions is by doing the following in
18 * ProcessQuery (before executing the plan):
19 * plan = stringToNode(nodeToString(plan));
20 * Then, run the regression test. Let's just say you'll notice if either
21 * of the above function are not properly done.
24 *-------------------------------------------------------------------------
30 #include "catalog/pg_index.h"
31 #include "nodes/plannodes.h"
32 #include "nodes/readfuncs.h"
33 #include "nodes/relation.h"
34 #include "utils/lsyscache.h"
37 * node creator declarations
41 static Datum readDatum(Oid type);
50 /* ugly manipulation, should probably free the Value node too */
51 lfirst(l) = (void *) intVal(lfirst(l));
67 local_node = makeNode(Query);
69 token = lsptok(NULL, &length); /* skip the :command */
70 token = lsptok(NULL, &length); /* get the commandType */
71 local_node->commandType = atoi(token);
73 token = lsptok(NULL, &length); /* skip :utility */
74 /* we can't get create or index here, can we? */
76 token = lsptok(NULL, &length); /* get the notify name if any */
78 local_node->utilityStmt = NULL;
81 NotifyStmt *n = makeNode(NotifyStmt);
83 n->relname = debackslash(token, length);
84 local_node->utilityStmt = (Node *) n;
87 token = lsptok(NULL, &length); /* skip the :resultRelation */
88 token = lsptok(NULL, &length); /* get the resultRelation */
89 local_node->resultRelation = atoi(token);
91 token = lsptok(NULL, &length); /* skip :into */
92 token = lsptok(NULL, &length); /* get into */
94 local_node->into = NULL;
96 local_node->into = debackslash(token, length);
98 token = lsptok(NULL, &length); /* skip :isPortal */
99 token = lsptok(NULL, &length); /* get isPortal */
100 local_node->isPortal = (token[0] == 't') ? true : false;
102 token = lsptok(NULL, &length); /* skip :isBinary */
103 token = lsptok(NULL, &length); /* get isBinary */
104 local_node->isBinary = (token[0] == 't') ? true : false;
106 token = lsptok(NULL, &length); /* skip :isTemp */
107 token = lsptok(NULL, &length); /* get isTemp */
108 local_node->isTemp = (token[0] == 't') ? true : false;
110 token = lsptok(NULL, &length); /* skip :unionall */
111 token = lsptok(NULL, &length); /* get unionall */
112 local_node->unionall = (token[0] == 't') ? true : false;
114 token = lsptok(NULL, &length); /* skip :distinctClause */
115 local_node->distinctClause = nodeRead(true);
117 token = lsptok(NULL, &length); /* skip :sortClause */
118 local_node->sortClause = nodeRead(true);
120 token = lsptok(NULL, &length); /* skip :rtable */
121 local_node->rtable = nodeRead(true);
123 token = lsptok(NULL, &length); /* skip :targetlist */
124 local_node->targetList = nodeRead(true);
126 token = lsptok(NULL, &length); /* skip :qual */
127 local_node->qual = nodeRead(true);
129 token = lsptok(NULL, &length); /* skip :groupClause */
130 local_node->groupClause = nodeRead(true);
132 token = lsptok(NULL, &length); /* skip :havingQual */
133 local_node->havingQual = nodeRead(true);
135 token = lsptok(NULL, &length); /* skip the :hasAggs */
136 token = lsptok(NULL, &length); /* get hasAggs */
137 local_node->hasAggs = (token[0] == 't') ? true : false;
139 token = lsptok(NULL, &length); /* skip the :hasSubLinks */
140 token = lsptok(NULL, &length); /* get hasSubLinks */
141 local_node->hasSubLinks = (token[0] == 't') ? true : false;
143 token = lsptok(NULL, &length); /* skip :unionClause */
144 local_node->unionClause = nodeRead(true);
146 token = lsptok(NULL, &length); /* skip :intersectClause */
147 local_node->intersectClause = nodeRead(true);
150 token = lsptok(NULL, &length); /* skip :limitOffset */
151 local_node->limitOffset = nodeRead(true);
153 token = lsptok(NULL, &length); /* skip :limitCount */
154 local_node->limitCount = nodeRead(true);
156 token = lsptok(NULL, &length); /* skip :rowMark */
157 local_node->rowMark = nodeRead(true);
169 SortClause *local_node;
173 local_node = makeNode(SortClause);
175 token = lsptok(NULL, &length); /* skip :tleSortGroupRef */
176 token = lsptok(NULL, &length); /* get tleSortGroupRef */
177 local_node->tleSortGroupRef = strtoul(token, NULL, 10);
179 token = lsptok(NULL, &length); /* skip :sortop */
180 token = lsptok(NULL, &length); /* get sortop */
181 local_node->sortop = strtoul(token, NULL, 10);
193 GroupClause *local_node;
197 local_node = makeNode(GroupClause);
199 token = lsptok(NULL, &length); /* skip :tleSortGroupRef */
200 token = lsptok(NULL, &length); /* get tleSortGroupRef */
201 local_node->tleSortGroupRef = strtoul(token, NULL, 10);
203 token = lsptok(NULL, &length); /* skip :sortop */
204 token = lsptok(NULL, &length); /* get sortop */
205 local_node->sortop = strtoul(token, NULL, 10);
220 token = lsptok(NULL, &length); /* first token is :startup_cost */
221 token = lsptok(NULL, &length); /* next is the actual cost */
222 node->startup_cost = (Cost) atof(token);
224 token = lsptok(NULL, &length); /* skip the :total_cost */
225 token = lsptok(NULL, &length); /* next is the actual cost */
226 node->total_cost = (Cost) atof(token);
228 token = lsptok(NULL, &length); /* skip the :rows */
229 token = lsptok(NULL, &length); /* get the plan_rows */
230 node->plan_rows = atof(token);
232 token = lsptok(NULL, &length); /* skip the :width */
233 token = lsptok(NULL, &length); /* get the plan_width */
234 node->plan_width = atoi(token);
236 token = lsptok(NULL, &length); /* eat the :state stuff */
237 token = lsptok(NULL, &length); /* now get the state */
240 node->state = (EState *) NULL;
242 { /* Disgusting hack until I figure out what
244 node->state = (EState *) !NULL;
247 token = lsptok(NULL, &length); /* eat :qptargetlist */
248 node->targetlist = nodeRead(true);
250 token = lsptok(NULL, &length); /* eat :qpqual */
251 node->qual = nodeRead(true);
253 token = lsptok(NULL, &length); /* eat :lefttree */
254 node->lefttree = (Plan *) nodeRead(true);
256 token = lsptok(NULL, &length); /* eat :righttree */
257 node->righttree = (Plan *) nodeRead(true);
263 * Stuff from plannodes.h
275 local_node = makeNode(Plan);
277 _getPlan(local_node);
293 local_node = makeNode(Result);
295 _getPlan((Plan *) local_node);
297 token = lsptok(NULL, &length); /* eat :resconstantqual */
298 local_node->resconstantqual = nodeRead(true); /* now read it */
306 * Append is a subclass of Plan.
317 local_node = makeNode(Append);
319 _getPlan((Plan *) local_node);
321 token = lsptok(NULL, &length); /* eat :appendplans */
322 local_node->appendplans = nodeRead(true); /* now read it */
324 token = lsptok(NULL, &length); /* eat :unionrtables */
325 local_node->unionrtables = nodeRead(true); /* now read it */
327 token = lsptok(NULL, &length); /* eat :inheritrelid */
328 token = lsptok(NULL, &length); /* get inheritrelid */
329 local_node->inheritrelid = strtoul(token, NULL, 10);
331 token = lsptok(NULL, &length); /* eat :inheritrtable */
332 local_node->inheritrtable = nodeRead(true); /* now read it */
340 * In case Join is not the same structure as Plan someday.
346 _getPlan((Plan *) node);
353 * Join is a subclass of Plan
361 local_node = makeNode(Join);
363 _getJoin(local_node);
371 * NestLoop is a subclass of Join
378 NestLoop *local_node;
380 local_node = makeNode(NestLoop);
382 _getJoin((Join *) local_node);
390 * MergeJoin is a subclass of Join
396 MergeJoin *local_node;
400 local_node = makeNode(MergeJoin);
402 _getJoin((Join *) local_node);
403 token = lsptok(NULL, &length); /* eat :mergeclauses */
404 local_node->mergeclauses = nodeRead(true); /* now read it */
412 * HashJoin is a subclass of Join.
418 HashJoin *local_node;
422 local_node = makeNode(HashJoin);
424 _getJoin((Join *) local_node);
426 token = lsptok(NULL, &length); /* eat :hashclauses */
427 local_node->hashclauses = nodeRead(true); /* now read it */
429 token = lsptok(NULL, &length); /* eat :hashjoinop */
430 token = lsptok(NULL, &length); /* get hashjoinop */
431 local_node->hashjoinop = strtoul(token, NULL, 10);
433 token = lsptok(NULL, &length); /* eat :hashdone */
434 token = lsptok(NULL, &length); /* eat hashdone */
435 local_node->hashdone = false;
443 * Scan is a subclass of Node
444 * (Actually, according to the plannodes.h include file, it is a
445 * subclass of Plan. This is why _getPlan is used here.)
447 * Scan gets its own get function since stuff inherits it.
456 _getPlan((Plan *) node);
458 token = lsptok(NULL, &length); /* eat :scanrelid */
459 token = lsptok(NULL, &length); /* get scanrelid */
460 node->scanrelid = strtoul(token, NULL, 10);
466 * Scan is a subclass of Plan (Not Node, see above).
474 local_node = makeNode(Scan);
476 _getScan(local_node);
484 * SeqScan is a subclass of Scan
492 local_node = makeNode(SeqScan);
494 _getScan((Scan *) local_node);
502 * IndexScan is a subclass of Scan
508 IndexScan *local_node;
512 local_node = makeNode(IndexScan);
514 _getScan((Scan *) local_node);
516 token = lsptok(NULL, &length); /* eat :indxid */
517 local_node->indxid = toIntList(nodeRead(true)); /* now read it */
519 token = lsptok(NULL, &length); /* eat :indxqual */
520 local_node->indxqual = nodeRead(true); /* now read it */
522 token = lsptok(NULL, &length); /* eat :indxqualorig */
523 local_node->indxqualorig = nodeRead(true); /* now read it */
525 token = lsptok(NULL, &length); /* eat :indxorderdir */
526 token = lsptok(NULL, &length); /* get indxorderdir */
527 local_node->indxorderdir = atoi(token);
535 * TidScan is a subclass of Scan
545 local_node = makeNode(TidScan);
547 _getScan((Scan *) local_node);
549 token = lsptok(NULL, &length); /* eat :needrescan */
550 token = lsptok(NULL, &length); /* get needrescan */
551 local_node->needRescan = atoi(token);
553 token = lsptok(NULL, &length); /* eat :tideval */
554 local_node->tideval = nodeRead(true); /* now read it */
562 * Noname is a subclass of Plan
572 local_node = makeNode(Noname);
574 _getPlan((Plan *) local_node);
576 token = lsptok(NULL, &length); /* eat :nonameid */
577 token = lsptok(NULL, &length); /* get nonameid */
578 local_node->nonameid = atol(token);
580 token = lsptok(NULL, &length); /* eat :keycount */
581 token = lsptok(NULL, &length); /* get keycount */
582 local_node->keycount = atoi(token);
590 * Sort is a subclass of Noname
600 local_node = makeNode(Sort);
602 _getPlan((Plan *) local_node);
604 token = lsptok(NULL, &length); /* eat :nonameid */
605 token = lsptok(NULL, &length); /* get nonameid */
606 local_node->nonameid = atol(token);
608 token = lsptok(NULL, &length); /* eat :keycount */
609 token = lsptok(NULL, &length); /* get keycount */
610 local_node->keycount = atoi(token);
620 local_node = makeNode(Agg);
621 _getPlan((Plan *) local_node);
629 * Hash is a subclass of Noname
639 local_node = makeNode(Hash);
641 _getPlan((Plan *) local_node);
643 token = lsptok(NULL, &length); /* eat :hashkey */
644 local_node->hashkey = (Var *) nodeRead(true);
650 * Stuff from primnodes.h.
656 * Resdom is a subclass of Node
666 local_node = makeNode(Resdom);
668 token = lsptok(NULL, &length); /* eat :resno */
669 token = lsptok(NULL, &length); /* get resno */
670 local_node->resno = atoi(token);
672 token = lsptok(NULL, &length); /* eat :restype */
673 token = lsptok(NULL, &length); /* get restype */
674 local_node->restype = atol(token);
676 token = lsptok(NULL, &length); /* eat :restypmod */
677 token = lsptok(NULL, &length); /* get restypmod */
678 local_node->restypmod = atoi(token);
680 token = lsptok(NULL, &length); /* eat :resname */
681 token = lsptok(NULL, &length); /* get the name */
683 local_node->resname = NULL;
685 local_node->resname = debackslash(token, length);
687 token = lsptok(NULL, &length); /* eat :reskey */
688 token = lsptok(NULL, &length); /* get reskey */
689 local_node->reskey = strtoul(token, NULL, 10);
691 token = lsptok(NULL, &length); /* eat :reskeyop */
692 token = lsptok(NULL, &length); /* get reskeyop */
693 local_node->reskeyop = (Oid) atol(token);
695 token = lsptok(NULL, &length); /* eat :ressortgroupref */
696 token = lsptok(NULL, &length); /* get ressortgroupref */
697 local_node->ressortgroupref = strtoul(token, NULL, 10);
699 token = lsptok(NULL, &length); /* eat :resjunk */
700 token = lsptok(NULL, &length); /* get resjunk */
701 local_node->resjunk = (token[0] == 't') ? true : false;
709 * Expr is a subclass of Node
719 local_node = makeNode(Expr);
721 token = lsptok(NULL, &length); /* eat :typeOid */
722 token = lsptok(NULL, &length); /* get typeOid */
723 local_node->typeOid = (Oid) atol(token);
725 token = lsptok(NULL, &length); /* eat :opType */
726 token = lsptok(NULL, &length); /* get opType */
727 if (!strncmp(token, "op", 2))
728 local_node->opType = OP_EXPR;
729 else if (!strncmp(token, "func", 4))
730 local_node->opType = FUNC_EXPR;
731 else if (!strncmp(token, "or", 2))
732 local_node->opType = OR_EXPR;
733 else if (!strncmp(token, "and", 3))
734 local_node->opType = AND_EXPR;
735 else if (!strncmp(token, "not", 3))
736 local_node->opType = NOT_EXPR;
737 else if (!strncmp(token, "subp", 4))
738 local_node->opType = SUBPLAN_EXPR;
740 elog(ERROR, "_readExpr: unknown opType \"%.10s\"", token);
742 token = lsptok(NULL, &length); /* eat :oper */
743 local_node->oper = nodeRead(true);
745 token = lsptok(NULL, &length); /* eat :args */
746 local_node->args = nodeRead(true); /* now read it */
754 * CaseExpr is a subclass of Node
760 CaseExpr *local_node;
764 local_node = makeNode(CaseExpr);
766 local_node->args = nodeRead(true);
767 token = lsptok(NULL, &length); /* eat :default */
768 local_node->defresult = nodeRead(true);
776 * CaseWhen is a subclass of Node
782 CaseWhen *local_node;
786 local_node = makeNode(CaseWhen);
788 local_node->expr = nodeRead(true);
789 token = lsptok(NULL, &length); /* eat :then */
790 local_node->result = nodeRead(true);
798 * Var is a subclass of Expr
808 local_node = makeNode(Var);
810 token = lsptok(NULL, &length); /* eat :varno */
811 token = lsptok(NULL, &length); /* get varno */
812 local_node->varno = strtoul(token, NULL, 10);
814 token = lsptok(NULL, &length); /* eat :varattno */
815 token = lsptok(NULL, &length); /* get varattno */
816 local_node->varattno = atoi(token);
818 token = lsptok(NULL, &length); /* eat :vartype */
819 token = lsptok(NULL, &length); /* get vartype */
820 local_node->vartype = (Oid) atol(token);
822 token = lsptok(NULL, &length); /* eat :vartypmod */
823 token = lsptok(NULL, &length); /* get vartypmod */
824 local_node->vartypmod = atoi(token);
826 token = lsptok(NULL, &length); /* eat :varlevelsup */
827 token = lsptok(NULL, &length); /* get varlevelsup */
828 local_node->varlevelsup = (Oid) atol(token);
830 token = lsptok(NULL, &length); /* eat :varnoold */
831 token = lsptok(NULL, &length); /* get varnoold */
832 local_node->varnoold = (Oid) atol(token);
834 token = lsptok(NULL, &length); /* eat :varoattno */
835 token = lsptok(NULL, &length); /* eat :varoattno */
836 local_node->varoattno = (int) atol(token);
844 * Array is a subclass of Expr
854 local_node = makeNode(Array);
856 token = lsptok(NULL, &length); /* eat :arrayelemtype */
857 token = lsptok(NULL, &length); /* get arrayelemtype */
858 local_node->arrayelemtype = strtoul(token, NULL, 10);
860 token = lsptok(NULL, &length); /* eat :arrayelemlength */
861 token = lsptok(NULL, &length); /* get arrayelemlength */
862 local_node->arrayelemlength = atoi(token);
864 token = lsptok(NULL, &length); /* eat :arrayelembyval */
865 token = lsptok(NULL, &length); /* get arrayelembyval */
866 local_node->arrayelembyval = (token[0] == 't') ? true : false;
868 token = lsptok(NULL, &length); /* eat :arraylow */
869 token = lsptok(NULL, &length); /* get arraylow */
870 local_node->arraylow.indx[0] = atoi(token);
872 token = lsptok(NULL, &length); /* eat :arrayhigh */
873 token = lsptok(NULL, &length); /* get arrayhigh */
874 local_node->arrayhigh.indx[0] = atoi(token);
876 token = lsptok(NULL, &length); /* eat :arraylen */
877 token = lsptok(NULL, &length); /* get arraylen */
878 local_node->arraylen = atoi(token);
886 * ArrayRef is a subclass of Expr
892 ArrayRef *local_node;
896 local_node = makeNode(ArrayRef);
898 token = lsptok(NULL, &length); /* eat :refelemtype */
899 token = lsptok(NULL, &length); /* get refelemtype */
900 local_node->refelemtype = strtoul(token, NULL, 10);
902 token = lsptok(NULL, &length); /* eat :refattrlength */
903 token = lsptok(NULL, &length); /* get refattrlength */
904 local_node->refattrlength = atoi(token);
906 token = lsptok(NULL, &length); /* eat :refelemlength */
907 token = lsptok(NULL, &length); /* get refelemlength */
908 local_node->refelemlength = atoi(token);
910 token = lsptok(NULL, &length); /* eat :refelembyval */
911 token = lsptok(NULL, &length); /* get refelembyval */
912 local_node->refelembyval = (token[0] == 't') ? true : false;
914 token = lsptok(NULL, &length); /* eat :refupperindex */
915 local_node->refupperindexpr = nodeRead(true);
917 token = lsptok(NULL, &length); /* eat :reflowerindex */
918 local_node->reflowerindexpr = nodeRead(true);
920 token = lsptok(NULL, &length); /* eat :refexpr */
921 local_node->refexpr = nodeRead(true);
923 token = lsptok(NULL, &length); /* eat :refassgnexpr */
924 local_node->refassgnexpr = nodeRead(true);
932 * Const is a subclass of Expr
942 local_node = makeNode(Const);
944 token = lsptok(NULL, &length); /* get :consttype */
945 token = lsptok(NULL, &length); /* now read it */
946 local_node->consttype = atol(token);
949 token = lsptok(NULL, &length); /* get :constlen */
950 token = lsptok(NULL, &length); /* now read it */
951 local_node->constlen = strtol(token, NULL, 10);
953 token = lsptok(NULL, &length); /* get :constisnull */
954 token = lsptok(NULL, &length); /* now read it */
956 if (!strncmp(token, "true", 4))
957 local_node->constisnull = true;
959 local_node->constisnull = false;
962 token = lsptok(NULL, &length); /* get :constvalue */
964 if (local_node->constisnull)
966 token = lsptok(NULL, &length); /* skip "NIL" */
974 local_node->constvalue = readDatum(local_node->consttype);
977 token = lsptok(NULL, &length); /* get :constbyval */
978 token = lsptok(NULL, &length); /* now read it */
980 if (!strncmp(token, "true", 4))
981 local_node->constbyval = true;
983 local_node->constbyval = false;
991 * Func is a subclass of Expr
1001 local_node = makeNode(Func);
1003 token = lsptok(NULL, &length); /* get :funcid */
1004 token = lsptok(NULL, &length); /* now read it */
1005 local_node->funcid = atol(token);
1007 token = lsptok(NULL, &length); /* get :functype */
1008 token = lsptok(NULL, &length); /* now read it */
1009 local_node->functype = atol(token);
1011 token = lsptok(NULL, &length); /* get :funcisindex */
1012 token = lsptok(NULL, &length); /* now read it */
1014 if (!strncmp(token, "true", 4))
1015 local_node->funcisindex = true;
1017 local_node->funcisindex = false;
1019 token = lsptok(NULL, &length); /* get :funcsize */
1020 token = lsptok(NULL, &length); /* now read it */
1021 local_node->funcsize = atol(token);
1023 token = lsptok(NULL, &length); /* get :func_fcache */
1024 token = lsptok(NULL, &length); /* get @ */
1025 token = lsptok(NULL, &length); /* now read it */
1027 local_node->func_fcache = (FunctionCache *) NULL;
1029 token = lsptok(NULL, &length); /* get :func_tlist */
1030 local_node->func_tlist = nodeRead(true); /* now read it */
1032 token = lsptok(NULL, &length); /* get :func_planlist */
1033 local_node->func_planlist = nodeRead(true); /* now read it */
1041 * Oper is a subclass of Expr
1051 local_node = makeNode(Oper);
1053 token = lsptok(NULL, &length); /* get :opno */
1054 token = lsptok(NULL, &length); /* now read it */
1055 local_node->opno = atol(token);
1057 token = lsptok(NULL, &length); /* get :opid */
1058 token = lsptok(NULL, &length); /* now read it */
1059 local_node->opid = atol(token);
1061 token = lsptok(NULL, &length); /* get :opresulttype */
1062 token = lsptok(NULL, &length); /* now read it */
1063 local_node->opresulttype = atol(token);
1066 * NOTE: Alternatively we can call 'replace_opid' which initializes
1067 * both 'opid' and 'op_fcache'.
1069 local_node->op_fcache = (FunctionCache *) NULL;
1077 * Param is a subclass of Expr
1087 local_node = makeNode(Param);
1089 token = lsptok(NULL, &length); /* get :paramkind */
1090 token = lsptok(NULL, &length); /* now read it */
1091 local_node->paramkind = atoi(token);
1093 token = lsptok(NULL, &length); /* get :paramid */
1094 token = lsptok(NULL, &length); /* now read it */
1095 local_node->paramid = atol(token);
1097 token = lsptok(NULL, &length); /* get :paramname */
1098 token = lsptok(NULL, &length); /* now read it */
1100 local_node->paramname = NULL;
1102 local_node->paramname = debackslash(token, length);
1104 token = lsptok(NULL, &length); /* get :paramtype */
1105 token = lsptok(NULL, &length); /* now read it */
1107 local_node->paramtype = atol(token);
1108 token = lsptok(NULL, &length); /* get :param_tlist */
1109 local_node->param_tlist = nodeRead(true); /* now read it */
1117 * Aggref is a subclass of Node
1127 local_node = makeNode(Aggref);
1129 token = lsptok(NULL, &length); /* eat :aggname */
1130 token = lsptok(NULL, &length); /* get aggname */
1131 local_node->aggname = debackslash(token, length);
1133 token = lsptok(NULL, &length); /* eat :basetype */
1134 token = lsptok(NULL, &length); /* get basetype */
1135 local_node->basetype = (Oid) atol(token);
1137 token = lsptok(NULL, &length); /* eat :aggtype */
1138 token = lsptok(NULL, &length); /* get aggtype */
1139 local_node->aggtype = (Oid) atol(token);
1141 token = lsptok(NULL, &length); /* eat :target */
1142 local_node->target = nodeRead(true); /* now read it */
1144 token = lsptok(NULL, &length); /* eat :usenulls */
1145 token = lsptok(NULL, &length); /* get usenulls */
1146 local_node->usenulls = (token[0] == 't') ? true : false;
1148 token = lsptok(NULL, &length); /* eat :aggstar */
1149 token = lsptok(NULL, &length); /* get aggstar */
1150 local_node->aggstar = (token[0] == 't') ? true : false;
1152 token = lsptok(NULL, &length); /* eat :aggdistinct */
1153 token = lsptok(NULL, &length); /* get aggdistinct */
1154 local_node->aggdistinct = (token[0] == 't') ? true : false;
1162 * SubLink is a subclass of Node
1168 SubLink *local_node;
1172 local_node = makeNode(SubLink);
1174 token = lsptok(NULL, &length); /* eat :subLinkType */
1175 token = lsptok(NULL, &length); /* get subLinkType */
1176 local_node->subLinkType = atoi(token);
1178 token = lsptok(NULL, &length); /* eat :useor */
1179 token = lsptok(NULL, &length); /* get useor */
1180 local_node->useor = (token[0] == 't') ? true : false;
1182 token = lsptok(NULL, &length); /* eat :lefthand */
1183 local_node->lefthand = nodeRead(true); /* now read it */
1185 token = lsptok(NULL, &length); /* eat :oper */
1186 local_node->oper = nodeRead(true); /* now read it */
1188 token = lsptok(NULL, &length); /* eat :subselect */
1189 local_node->subselect = nodeRead(true); /* now read it */
1197 * RelabelType is a subclass of Node
1200 static RelabelType *
1203 RelabelType *local_node;
1207 local_node = makeNode(RelabelType);
1209 token = lsptok(NULL, &length); /* eat :arg */
1210 local_node->arg = nodeRead(true); /* now read it */
1212 token = lsptok(NULL, &length); /* eat :resulttype */
1213 token = lsptok(NULL, &length); /* get resulttype */
1214 local_node->resulttype = (Oid) atol(token);
1216 token = lsptok(NULL, &length); /* eat :resulttypmod */
1217 token = lsptok(NULL, &length); /* get resulttypmod */
1218 local_node->resulttypmod = atoi(token);
1224 * Stuff from execnodes.h
1230 * EState is a subclass of Node.
1240 local_node = makeNode(EState);
1242 token = lsptok(NULL, &length); /* get :direction */
1243 token = lsptok(NULL, &length); /* now read it */
1245 local_node->es_direction = atoi(token);
1247 token = lsptok(NULL, &length); /* get :range_table */
1249 local_node->es_range_table = nodeRead(true); /* now read it */
1251 token = lsptok(NULL, &length); /* get :result_relation_info */
1252 token = lsptok(NULL, &length); /* get @ */
1253 token = lsptok(NULL, &length); /* now read it */
1255 sscanf(token, "%x", (unsigned int *) &local_node->es_result_relation_info);
1261 * Stuff from relation.h
1271 RelOptInfo *local_node;
1275 local_node = makeNode(RelOptInfo);
1277 token = lsptok(NULL, &length); /* get :relids */
1278 local_node->relids = toIntList(nodeRead(true)); /* now read it */
1280 token = lsptok(NULL, &length); /* get :rows */
1281 token = lsptok(NULL, &length); /* now read it */
1282 local_node->rows = atof(token);
1284 token = lsptok(NULL, &length); /* get :width */
1285 token = lsptok(NULL, &length); /* now read it */
1286 local_node->width = atoi(token);
1288 token = lsptok(NULL, &length); /* get :indexed */
1289 token = lsptok(NULL, &length); /* now read it */
1291 if (!strncmp(token, "true", 4))
1292 local_node->indexed = true;
1294 local_node->indexed = false;
1296 token = lsptok(NULL, &length); /* get :pages */
1297 token = lsptok(NULL, &length); /* now read it */
1298 local_node->pages = atol(token);
1300 token = lsptok(NULL, &length); /* get :tuples */
1301 token = lsptok(NULL, &length); /* now read it */
1302 local_node->tuples = atof(token);
1304 token = lsptok(NULL, &length); /* get :targetlist */
1305 local_node->targetlist = nodeRead(true); /* now read it */
1307 token = lsptok(NULL, &length); /* get :pathlist */
1308 local_node->pathlist = nodeRead(true); /* now read it */
1310 token = lsptok(NULL, &length); /* get :cheapest_startup_path */
1311 local_node->cheapest_startup_path = nodeRead(true); /* now read it */
1313 token = lsptok(NULL, &length); /* get :cheapest_total_path */
1314 local_node->cheapest_total_path = nodeRead(true); /* now read it */
1316 token = lsptok(NULL, &length); /* eat :pruneable */
1317 token = lsptok(NULL, &length); /* get :pruneable */
1318 local_node->pruneable = (token[0] == 't') ? true : false;
1320 token = lsptok(NULL, &length); /* get :baserestrictinfo */
1321 local_node->baserestrictinfo = nodeRead(true); /* now read it */
1323 token = lsptok(NULL, &length); /* get :joininfo */
1324 local_node->joininfo = nodeRead(true); /* now read it */
1326 token = lsptok(NULL, &length); /* get :innerjoin */
1327 local_node->innerjoin = nodeRead(true); /* now read it */
1336 static TargetEntry *
1339 TargetEntry *local_node;
1343 local_node = makeNode(TargetEntry);
1345 token = lsptok(NULL, &length); /* get :resdom */
1346 local_node->resdom = nodeRead(true); /* now read it */
1348 token = lsptok(NULL, &length); /* get :expr */
1349 local_node->expr = nodeRead(true); /* now read it */
1361 local_node = makeNode(Attr);
1363 token = lsptok(NULL, &length); /* eat :relname */
1364 token = lsptok(NULL, &length); /* get relname */
1365 local_node->relname = debackslash(token, length);
1367 token = lsptok(NULL, &length); /* eat :attrs */
1368 local_node->attrs = nodeRead(true); /* now read it */
1374 * _readRangeTblEntry
1377 static RangeTblEntry *
1378 _readRangeTblEntry()
1380 RangeTblEntry *local_node;
1384 local_node = makeNode(RangeTblEntry);
1386 token = lsptok(NULL, &length); /* eat :relname */
1387 token = lsptok(NULL, &length); /* get :relname */
1389 local_node->relname = NULL;
1391 local_node->relname = debackslash(token, length);
1393 token = lsptok(NULL, &length); /* eat :ref */
1394 local_node->ref = nodeRead(true); /* now read it */
1396 token = lsptok(NULL, &length); /* eat :relid */
1397 token = lsptok(NULL, &length); /* get :relid */
1398 local_node->relid = strtoul(token, NULL, 10);
1400 token = lsptok(NULL, &length); /* eat :inh */
1401 token = lsptok(NULL, &length); /* get :inh */
1402 local_node->inh = (token[0] == 't') ? true : false;
1404 token = lsptok(NULL, &length); /* eat :inFromCl */
1405 token = lsptok(NULL, &length); /* get :inFromCl */
1406 local_node->inFromCl = (token[0] == 't') ? true : false;
1408 token = lsptok(NULL, &length); /* eat :inJoinSet */
1409 token = lsptok(NULL, &length); /* get :inJoinSet */
1410 local_node->inJoinSet = (token[0] == 't') ? true : false;
1412 token = lsptok(NULL, &length); /* eat :skipAcl */
1413 token = lsptok(NULL, &length); /* get :skipAcl */
1414 local_node->skipAcl = (token[0] == 't') ? true : false;
1422 RowMark *local_node = makeNode(RowMark);
1426 token = lsptok(NULL, &length); /* eat :rti */
1427 token = lsptok(NULL, &length); /* get :rti */
1428 local_node->rti = strtoul(token, NULL, 10);
1430 token = lsptok(NULL, &length); /* eat :info */
1431 token = lsptok(NULL, &length); /* get :info */
1432 local_node->info = strtoul(token, NULL, 10);
1440 * Path is a subclass of Node.
1450 local_node = makeNode(Path);
1452 token = lsptok(NULL, &length); /* get :pathtype */
1453 token = lsptok(NULL, &length); /* now read it */
1454 local_node->pathtype = atol(token);
1456 token = lsptok(NULL, &length); /* get :startup_cost */
1457 token = lsptok(NULL, &length); /* now read it */
1458 local_node->startup_cost = (Cost) atof(token);
1460 token = lsptok(NULL, &length); /* get :total_cost */
1461 token = lsptok(NULL, &length); /* now read it */
1462 local_node->total_cost = (Cost) atof(token);
1464 token = lsptok(NULL, &length); /* get :pathkeys */
1465 local_node->pathkeys = nodeRead(true); /* now read it */
1473 * IndexPath is a subclass of Path.
1479 IndexPath *local_node;
1483 local_node = makeNode(IndexPath);
1485 token = lsptok(NULL, &length); /* get :pathtype */
1486 token = lsptok(NULL, &length); /* now read it */
1487 local_node->path.pathtype = atol(token);
1489 token = lsptok(NULL, &length); /* get :startup_cost */
1490 token = lsptok(NULL, &length); /* now read it */
1491 local_node->path.startup_cost = (Cost) atof(token);
1493 token = lsptok(NULL, &length); /* get :total_cost */
1494 token = lsptok(NULL, &length); /* now read it */
1495 local_node->path.total_cost = (Cost) atof(token);
1497 token = lsptok(NULL, &length); /* get :pathkeys */
1498 local_node->path.pathkeys = nodeRead(true); /* now read it */
1500 token = lsptok(NULL, &length); /* get :indexid */
1501 local_node->indexid = toIntList(nodeRead(true));
1503 token = lsptok(NULL, &length); /* get :indexqual */
1504 local_node->indexqual = nodeRead(true); /* now read it */
1506 token = lsptok(NULL, &length); /* get :indexscandir */
1507 token = lsptok(NULL, &length); /* now read it */
1508 local_node->indexscandir = (ScanDirection) atoi(token);
1510 token = lsptok(NULL, &length); /* get :joinrelids */
1511 local_node->joinrelids = toIntList(nodeRead(true));
1519 * TidPath is a subclass of Path.
1525 TidPath *local_node;
1529 local_node = makeNode(TidPath);
1531 token = lsptok(NULL, &length); /* get :pathtype */
1532 token = lsptok(NULL, &length); /* now read it */
1533 local_node->path.pathtype = atol(token);
1535 token = lsptok(NULL, &length); /* get :startup_cost */
1536 token = lsptok(NULL, &length); /* now read it */
1537 local_node->path.startup_cost = (Cost) atof(token);
1539 token = lsptok(NULL, &length); /* get :total_cost */
1540 token = lsptok(NULL, &length); /* now read it */
1541 local_node->path.total_cost = (Cost) atof(token);
1543 token = lsptok(NULL, &length); /* get :pathkeys */
1544 local_node->path.pathkeys = nodeRead(true); /* now read it */
1546 token = lsptok(NULL, &length); /* get :tideval */
1547 local_node->tideval = nodeRead(true); /* now read it */
1549 token = lsptok(NULL, &length); /* get :unjoined_relids */
1550 local_node->unjoined_relids = toIntList(nodeRead(true));
1558 * NestPath is a subclass of Path
1564 NestPath *local_node;
1568 local_node = makeNode(NestPath);
1570 token = lsptok(NULL, &length); /* get :pathtype */
1571 token = lsptok(NULL, &length); /* now read it */
1572 local_node->path.pathtype = atol(token);
1574 token = lsptok(NULL, &length); /* get :startup_cost */
1575 token = lsptok(NULL, &length); /* now read it */
1576 local_node->path.startup_cost = (Cost) atof(token);
1578 token = lsptok(NULL, &length); /* get :total_cost */
1579 token = lsptok(NULL, &length); /* now read it */
1580 local_node->path.total_cost = (Cost) atof(token);
1582 token = lsptok(NULL, &length); /* get :pathkeys */
1583 local_node->path.pathkeys = nodeRead(true); /* now read it */
1585 token = lsptok(NULL, &length); /* get :outerjoinpath */
1586 local_node->outerjoinpath = nodeRead(true); /* now read it */
1588 token = lsptok(NULL, &length); /* get :innerjoinpath */
1589 local_node->innerjoinpath = nodeRead(true); /* now read it */
1591 token = lsptok(NULL, &length); /* get :joinrestrictinfo */
1592 local_node->joinrestrictinfo = nodeRead(true); /* now read it */
1600 * MergePath is a subclass of NestPath.
1606 MergePath *local_node;
1610 local_node = makeNode(MergePath);
1612 token = lsptok(NULL, &length); /* get :pathtype */
1613 token = lsptok(NULL, &length); /* now read it */
1614 local_node->jpath.path.pathtype = atol(token);
1616 token = lsptok(NULL, &length); /* get :startup_cost */
1617 token = lsptok(NULL, &length); /* now read it */
1618 local_node->jpath.path.startup_cost = (Cost) atof(token);
1620 token = lsptok(NULL, &length); /* get :total_cost */
1621 token = lsptok(NULL, &length); /* now read it */
1622 local_node->jpath.path.total_cost = (Cost) atof(token);
1624 token = lsptok(NULL, &length); /* get :pathkeys */
1625 local_node->jpath.path.pathkeys = nodeRead(true); /* now read it */
1627 token = lsptok(NULL, &length); /* get :outerjoinpath */
1628 local_node->jpath.outerjoinpath = nodeRead(true); /* now read it */
1630 token = lsptok(NULL, &length); /* get :innerjoinpath */
1631 local_node->jpath.innerjoinpath = nodeRead(true); /* now read it */
1633 token = lsptok(NULL, &length); /* get :joinrestrictinfo */
1634 local_node->jpath.joinrestrictinfo = nodeRead(true); /* now read it */
1636 token = lsptok(NULL, &length); /* get :path_mergeclauses */
1637 local_node->path_mergeclauses = nodeRead(true); /* now read it */
1639 token = lsptok(NULL, &length); /* get :outersortkeys */
1640 local_node->outersortkeys = nodeRead(true); /* now read it */
1642 token = lsptok(NULL, &length); /* get :innersortkeys */
1643 local_node->innersortkeys = nodeRead(true); /* now read it */
1651 * HashPath is a subclass of NestPath.
1657 HashPath *local_node;
1661 local_node = makeNode(HashPath);
1663 token = lsptok(NULL, &length); /* get :pathtype */
1664 token = lsptok(NULL, &length); /* now read it */
1665 local_node->jpath.path.pathtype = atol(token);
1667 token = lsptok(NULL, &length); /* get :startup_cost */
1668 token = lsptok(NULL, &length); /* now read it */
1669 local_node->jpath.path.startup_cost = (Cost) atof(token);
1671 token = lsptok(NULL, &length); /* get :total_cost */
1672 token = lsptok(NULL, &length); /* now read it */
1673 local_node->jpath.path.total_cost = (Cost) atof(token);
1675 token = lsptok(NULL, &length); /* get :pathkeys */
1676 local_node->jpath.path.pathkeys = nodeRead(true); /* now read it */
1678 token = lsptok(NULL, &length); /* get :outerjoinpath */
1679 local_node->jpath.outerjoinpath = nodeRead(true); /* now read it */
1681 token = lsptok(NULL, &length); /* get :innerjoinpath */
1682 local_node->jpath.innerjoinpath = nodeRead(true); /* now read it */
1684 token = lsptok(NULL, &length); /* get :joinrestrictinfo */
1685 local_node->jpath.joinrestrictinfo = nodeRead(true); /* now read it */
1687 token = lsptok(NULL, &length); /* get :path_hashclauses */
1688 local_node->path_hashclauses = nodeRead(true); /* now read it */
1696 * PathKeyItem is a subclass of Node.
1699 static PathKeyItem *
1702 PathKeyItem *local_node;
1706 local_node = makeNode(PathKeyItem);
1708 token = lsptok(NULL, &length); /* get :sortop */
1709 token = lsptok(NULL, &length); /* now read it */
1711 local_node->sortop = atol(token);
1713 token = lsptok(NULL, &length); /* get :key */
1714 local_node->key = nodeRead(true); /* now read it */
1722 * RestrictInfo is a subclass of Node.
1725 static RestrictInfo *
1728 RestrictInfo *local_node;
1732 local_node = makeNode(RestrictInfo);
1734 token = lsptok(NULL, &length); /* get :clause */
1735 local_node->clause = nodeRead(true); /* now read it */
1737 token = lsptok(NULL, &length); /* get :subclauseindices */
1738 local_node->subclauseindices = nodeRead(true); /* now read it */
1740 token = lsptok(NULL, &length); /* get :mergejoinoperator */
1741 token = lsptok(NULL, &length); /* now read it */
1742 local_node->mergejoinoperator = atol(token);
1744 token = lsptok(NULL, &length); /* get :left_sortop */
1745 token = lsptok(NULL, &length); /* now read it */
1746 local_node->left_sortop = atol(token);
1748 token = lsptok(NULL, &length); /* get :right_sortop */
1749 token = lsptok(NULL, &length); /* now read it */
1750 local_node->right_sortop = atol(token);
1752 token = lsptok(NULL, &length); /* get :hashjoinoperator */
1753 token = lsptok(NULL, &length); /* now read it */
1754 local_node->hashjoinoperator = atol(token);
1762 * JoinInfo is a subclass of Node.
1768 JoinInfo *local_node;
1772 local_node = makeNode(JoinInfo);
1774 token = lsptok(NULL, &length); /* get :unjoined_relids */
1775 local_node->unjoined_relids = toIntList(nodeRead(true)); /* now read it */
1777 token = lsptok(NULL, &length); /* get :jinfo_restrictinfo */
1778 local_node->jinfo_restrictinfo = nodeRead(true); /* now read it */
1795 local_node = makeNode(Iter);
1797 token = lsptok(NULL, &length); /* eat :iterexpr */
1798 local_node->iterexpr = nodeRead(true); /* now read it */
1807 * Given a character string containing a plan, parsePlanString sets up the
1808 * plan structure representing that plan.
1810 * The string to be read must already have been loaded into lsptok().
1814 parsePlanString(void)
1818 void *return_value = NULL;
1820 token = lsptok(NULL, &length);
1822 if (length == 4 && strncmp(token, "PLAN", length) == 0)
1823 return_value = _readPlan();
1824 else if (length == 6 && strncmp(token, "RESULT", length) == 0)
1825 return_value = _readResult();
1826 else if (length == 6 && strncmp(token, "APPEND", length) == 0)
1827 return_value = _readAppend();
1828 else if (length == 4 && strncmp(token, "JOIN", length) == 0)
1829 return_value = _readJoin();
1830 else if (length == 8 && strncmp(token, "NESTLOOP", length) == 0)
1831 return_value = _readNestLoop();
1832 else if (length == 9 && strncmp(token, "MERGEJOIN", length) == 0)
1833 return_value = _readMergeJoin();
1834 else if (length == 8 && strncmp(token, "HASHJOIN", length) == 0)
1835 return_value = _readHashJoin();
1836 else if (length == 4 && strncmp(token, "SCAN", length) == 0)
1837 return_value = _readScan();
1838 else if (length == 7 && strncmp(token, "SEQSCAN", length) == 0)
1839 return_value = _readSeqScan();
1840 else if (length == 9 && strncmp(token, "INDEXSCAN", length) == 0)
1841 return_value = _readIndexScan();
1842 else if (length == 7 && strncmp(token, "TIDSCAN", length) == 0)
1843 return_value = _readTidScan();
1844 else if (length == 6 && strncmp(token, "NONAME", length) == 0)
1845 return_value = _readNoname();
1846 else if (length == 4 && strncmp(token, "SORT", length) == 0)
1847 return_value = _readSort();
1848 else if (length == 6 && strncmp(token, "AGGREG", length) == 0)
1849 return_value = _readAggref();
1850 else if (length == 7 && strncmp(token, "SUBLINK", length) == 0)
1851 return_value = _readSubLink();
1852 else if (length == 11 && strncmp(token, "RELABELTYPE", length) == 0)
1853 return_value = _readRelabelType();
1854 else if (length == 3 && strncmp(token, "AGG", length) == 0)
1855 return_value = _readAgg();
1856 else if (length == 4 && strncmp(token, "HASH", length) == 0)
1857 return_value = _readHash();
1858 else if (length == 6 && strncmp(token, "RESDOM", length) == 0)
1859 return_value = _readResdom();
1860 else if (length == 4 && strncmp(token, "EXPR", length) == 0)
1861 return_value = _readExpr();
1862 else if (length == 8 && strncmp(token, "ARRAYREF", length) == 0)
1863 return_value = _readArrayRef();
1864 else if (length == 5 && strncmp(token, "ARRAY", length) == 0)
1865 return_value = _readArray();
1866 else if (length == 3 && strncmp(token, "VAR", length) == 0)
1867 return_value = _readVar();
1868 else if (length == 4 && strncmp(token, "ATTR", length) == 0)
1869 return_value = _readAttr();
1870 else if (length == 5 && strncmp(token, "CONST", length) == 0)
1871 return_value = _readConst();
1872 else if (length == 4 && strncmp(token, "FUNC", length) == 0)
1873 return_value = _readFunc();
1874 else if (length == 4 && strncmp(token, "OPER", length) == 0)
1875 return_value = _readOper();
1876 else if (length == 5 && strncmp(token, "PARAM", length) == 0)
1877 return_value = _readParam();
1878 else if (length == 6 && strncmp(token, "ESTATE", length) == 0)
1879 return_value = _readEState();
1880 else if (length == 10 && strncmp(token, "RELOPTINFO", length) == 0)
1881 return_value = _readRelOptInfo();
1882 else if (length == 11 && strncmp(token, "TARGETENTRY", length) == 0)
1883 return_value = _readTargetEntry();
1884 else if (length == 3 && strncmp(token, "RTE", length) == 0)
1885 return_value = _readRangeTblEntry();
1886 else if (length == 4 && strncmp(token, "PATH", length) == 0)
1887 return_value = _readPath();
1888 else if (length == 9 && strncmp(token, "INDEXPATH", length) == 0)
1889 return_value = _readIndexPath();
1890 else if (length == 7 && strncmp(token, "TIDPATH", length) == 0)
1891 return_value = _readTidPath();
1892 else if (length == 8 && strncmp(token, "NESTPATH", length) == 0)
1893 return_value = _readNestPath();
1894 else if (length == 9 && strncmp(token, "MERGEPATH", length) == 0)
1895 return_value = _readMergePath();
1896 else if (length == 8 && strncmp(token, "HASHPATH", length) == 0)
1897 return_value = _readHashPath();
1898 else if (length == 11 && strncmp(token, "PATHKEYITEM", length) == 0)
1899 return_value = _readPathKeyItem();
1900 else if (length == 12 && strncmp(token, "RESTRICTINFO", length) == 0)
1901 return_value = _readRestrictInfo();
1902 else if (length == 8 && strncmp(token, "JOININFO", length) == 0)
1903 return_value = _readJoinInfo();
1904 else if (length == 4 && strncmp(token, "ITER", length) == 0)
1905 return_value = _readIter();
1906 else if (length == 5 && strncmp(token, "QUERY", length) == 0)
1907 return_value = _readQuery();
1908 else if (length == 10 && strncmp(token, "SORTCLAUSE", length) == 0)
1909 return_value = _readSortClause();
1910 else if (length == 11 && strncmp(token, "GROUPCLAUSE", length) == 0)
1911 return_value = _readGroupClause();
1912 else if (length == 4 && strncmp(token, "CASE", length) == 0)
1913 return_value = _readCaseExpr();
1914 else if (length == 4 && strncmp(token, "WHEN", length) == 0)
1915 return_value = _readCaseWhen();
1916 else if (length == 7 && strncmp(token, "ROWMARK", length) == 0)
1917 return_value = _readRowMark();
1919 elog(ERROR, "badly formatted planstring \"%.10s\"...\n", token);
1921 return (Node *) return_value;
1924 /*------------------------------------------------------------*/
1929 * given a string representation of the value of the given type,
1930 * create the appropriate Datum
1944 byValue = get_typbyval(type);
1947 * read the actual length of the value
1949 token = lsptok(NULL, &tokenLength);
1950 length = atoi(token);
1951 token = lsptok(NULL, &tokenLength); /* skip the '[' */
1955 if (length > sizeof(Datum))
1956 elog(ERROR, "readValue: byval & length = %d", length);
1958 s = (char *) (&res);
1959 for (i = 0; i < sizeof(Datum); i++)
1961 token = lsptok(NULL, &tokenLength);
1962 s[i] = (char) atoi(token);
1965 else if (length <= 0)
1969 s = (char *) palloc(length);
1970 for (i = 0; i < length; i++)
1972 token = lsptok(NULL, &tokenLength);
1973 s[i] = (char) atoi(token);
1975 res = PointerGetDatum(s);
1978 token = lsptok(NULL, &tokenLength); /* skip the ']' */
1979 if (token[0] != ']')
1980 elog(ERROR, "readValue: ']' expected, length =%d", length);