summaryrefslogtreecommitdiff
path: root/src/backend/nodes
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-09-29 18:21:41 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-09-29 18:21:41 +0000
commit3a94e789f5c9537d804210be3cb26f7fb08e3b9e (patch)
treef1eac12405e3c0ded881d7dd7e59cec35b30c335 /src/backend/nodes
parent6f64c2e54a0b14154a335249f4dca91a39c61c50 (diff)
downloadpostgresql-3a94e789f5c9537d804210be3cb26f7fb08e3b9e.tar.gz
Subselects in FROM clause, per ISO syntax: FROM (SELECT ...) [AS] alias.
(Don't forget that an alias is required.) Views reimplemented as expanding to subselect-in-FROM. Grouping, aggregates, DISTINCT in views actually work now (he says optimistically). No UNION support in subselects/views yet, but I have some ideas about that. Rule-related permissions checking moved out of rewriter and into executor. INITDB REQUIRED!
Diffstat (limited to 'src/backend/nodes')
-rw-r--r--src/backend/nodes/copyfuncs.c71
-rw-r--r--src/backend/nodes/equalfuncs.c46
-rw-r--r--src/backend/nodes/list.c55
-rw-r--r--src/backend/nodes/outfuncs.c130
-rw-r--r--src/backend/nodes/print.c37
-rw-r--r--src/backend/nodes/readfuncs.c172
6 files changed, 297 insertions, 214 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index d6883bb339..808ffbd075 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.122 2000/09/20 15:28:01 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.123 2000/09/29 18:21:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -300,6 +300,31 @@ _copyTidScan(TidScan *from)
return newnode;
}
+/* ----------------
+ * _copySubqueryScan
+ * ----------------
+ */
+static SubqueryScan *
+_copySubqueryScan(SubqueryScan *from)
+{
+ SubqueryScan *newnode = makeNode(SubqueryScan);
+
+ /* ----------------
+ * copy node superclass fields
+ * ----------------
+ */
+ CopyPlanFields((Plan *) from, (Plan *) newnode);
+ CopyScanFields((Scan *) from, (Scan *) newnode);
+
+ /* ----------------
+ * copy remainder of node
+ * ----------------
+ */
+ Node_Copy(from, newnode, subplan);
+
+ return newnode;
+}
+
/* ----------------
* CopyJoinFields
@@ -913,6 +938,17 @@ _copyRangeTblRef(RangeTblRef *from)
return newnode;
}
+static FromExpr *
+_copyFromExpr(FromExpr *from)
+{
+ FromExpr *newnode = makeNode(FromExpr);
+
+ Node_Copy(from, newnode, fromlist);
+ Node_Copy(from, newnode, quals);
+
+ return newnode;
+}
+
static JoinExpr *
_copyJoinExpr(JoinExpr *from)
{
@@ -1025,9 +1061,11 @@ _copyRelOptInfo(RelOptInfo *from)
Node_Copy(from, newnode, cheapest_total_path);
newnode->pruneable = from->pruneable;
+ newnode->issubquery = from->issubquery;
newnode->indexed = from->indexed;
newnode->pages = from->pages;
newnode->tuples = from->tuples;
+ Node_Copy(from, newnode, subplan);
Node_Copy(from, newnode, baserestrictinfo);
newnode->baserestrictcost = from->baserestrictcost;
@@ -1306,7 +1344,7 @@ _copyRestrictInfo(RestrictInfo *from)
* ----------------
*/
Node_Copy(from, newnode, clause);
- newnode->isjoinqual = from->isjoinqual;
+ newnode->ispusheddown = from->ispusheddown;
Node_Copy(from, newnode, subclauseindices);
newnode->mergejoinoperator = from->mergejoinoperator;
newnode->left_sortop = from->left_sortop;
@@ -1392,22 +1430,14 @@ _copyRangeTblEntry(RangeTblEntry *from)
if (from->relname)
newnode->relname = pstrdup(from->relname);
newnode->relid = from->relid;
+ Node_Copy(from, newnode, subquery);
Node_Copy(from, newnode, alias);
Node_Copy(from, newnode, eref);
newnode->inh = from->inh;
newnode->inFromCl = from->inFromCl;
- newnode->skipAcl = from->skipAcl;
-
- return newnode;
-}
-
-static RowMark *
-_copyRowMark(RowMark *from)
-{
- RowMark *newnode = makeNode(RowMark);
-
- newnode->rti = from->rti;
- newnode->info = from->info;
+ newnode->checkForRead = from->checkForRead;
+ newnode->checkForWrite = from->checkForWrite;
+ newnode->checkAsUser = from->checkAsUser;
return newnode;
}
@@ -1674,8 +1704,8 @@ _copyQuery(Query *from)
Node_Copy(from, newnode, jointree);
Node_Copy(from, newnode, targetList);
- Node_Copy(from, newnode, qual);
- Node_Copy(from, newnode, rowMark);
+
+ newnode->rowMarks = listCopy(from->rowMarks);
Node_Copy(from, newnode, distinctClause);
Node_Copy(from, newnode, sortClause);
@@ -2493,6 +2523,9 @@ copyObject(void *from)
case T_TidScan:
retval = _copyTidScan(from);
break;
+ case T_SubqueryScan:
+ retval = _copySubqueryScan(from);
+ break;
case T_Join:
retval = _copyJoin(from);
break;
@@ -2575,6 +2608,9 @@ copyObject(void *from)
case T_RangeTblRef:
retval = _copyRangeTblRef(from);
break;
+ case T_FromExpr:
+ retval = _copyFromExpr(from);
+ break;
case T_JoinExpr:
retval = _copyJoinExpr(from);
break;
@@ -2881,9 +2917,6 @@ copyObject(void *from)
case T_CaseWhen:
retval = _copyCaseWhen(from);
break;
- case T_RowMark:
- retval = _copyRowMark(from);
- break;
case T_FkConstraint:
retval = _copyFkConstraint(from);
break;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 51a7a03fc1..bcb8e396ed 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.73 2000/09/12 21:06:49 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.74 2000/09/29 18:21:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -312,6 +312,17 @@ _equalRangeTblRef(RangeTblRef *a, RangeTblRef *b)
}
static bool
+_equalFromExpr(FromExpr *a, FromExpr *b)
+{
+ if (!equal(a->fromlist, b->fromlist))
+ return false;
+ if (!equal(a->quals, b->quals))
+ return false;
+
+ return true;
+}
+
+static bool
_equalJoinExpr(JoinExpr *a, JoinExpr *b)
{
if (a->jointype != b->jointype)
@@ -346,7 +357,7 @@ _equalRelOptInfo(RelOptInfo *a, RelOptInfo *b)
/*
* We treat RelOptInfos as equal if they refer to the same base rels
- * joined in the same order. Is this sufficient?
+ * joined in the same order. Is this appropriate/sufficient?
*/
return equali(a->relids, b->relids);
}
@@ -495,7 +506,7 @@ _equalRestrictInfo(RestrictInfo *a, RestrictInfo *b)
{
if (!equal(a->clause, b->clause))
return false;
- if (a->isjoinqual != b->isjoinqual)
+ if (a->ispusheddown != b->ispusheddown)
return false;
if (!equal(a->subclauseindices, b->subclauseindices))
return false;
@@ -601,9 +612,7 @@ _equalQuery(Query *a, Query *b)
return false;
if (!equal(a->targetList, b->targetList))
return false;
- if (!equal(a->qual, b->qual))
- return false;
- if (!equal(a->rowMark, b->rowMark))
+ if (!equali(a->rowMarks, b->rowMarks))
return false;
if (!equal(a->distinctClause, b->distinctClause))
return false;
@@ -1651,6 +1660,8 @@ _equalRangeTblEntry(RangeTblEntry *a, RangeTblEntry *b)
return false;
if (a->relid != b->relid)
return false;
+ if (!equal(a->subquery, b->subquery))
+ return false;
if (!equal(a->alias, b->alias))
return false;
if (!equal(a->eref, b->eref))
@@ -1659,7 +1670,11 @@ _equalRangeTblEntry(RangeTblEntry *a, RangeTblEntry *b)
return false;
if (a->inFromCl != b->inFromCl)
return false;
- if (a->skipAcl != b->skipAcl)
+ if (a->checkForRead != b->checkForRead)
+ return false;
+ if (a->checkForWrite != b->checkForWrite)
+ return false;
+ if (a->checkAsUser != b->checkAsUser)
return false;
return true;
@@ -1677,17 +1692,6 @@ _equalSortClause(SortClause *a, SortClause *b)
}
static bool
-_equalRowMark(RowMark *a, RowMark *b)
-{
- if (a->rti != b->rti)
- return false;
- if (a->info != b->info)
- return false;
-
- return true;
-}
-
-static bool
_equalFkConstraint(FkConstraint *a, FkConstraint *b)
{
if (!equalstr(a->constr_name, b->constr_name))
@@ -1835,6 +1839,9 @@ equal(void *a, void *b)
case T_RangeTblRef:
retval = _equalRangeTblRef(a, b);
break;
+ case T_FromExpr:
+ retval = _equalFromExpr(a, b);
+ break;
case T_JoinExpr:
retval = _equalJoinExpr(a, b);
break;
@@ -2140,9 +2147,6 @@ equal(void *a, void *b)
case T_CaseWhen:
retval = _equalCaseWhen(a, b);
break;
- case T_RowMark:
- retval = _equalRowMark(a, b);
- break;
case T_FkConstraint:
retval = _equalFkConstraint(a, b);
break;
diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c
index e94b357d24..358e6a7eb6 100644
--- a/src/backend/nodes/list.c
+++ b/src/backend/nodes/list.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.33 2000/09/12 21:06:49 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.34 2000/09/29 18:21:29 tgl Exp $
*
* NOTES
* XXX a few of the following functions are duplicated to handle
@@ -23,40 +23,9 @@
*-------------------------------------------------------------------------
*/
#include "postgres.h"
-#include "nodes/parsenodes.h"
-
-/*
- * makeList
- *
- * Take varargs, terminated by -1, and make a List
- */
-List *
-makeList(void *elem,...)
-{
- va_list args;
- List *retval = NIL;
- List *temp = NIL;
- List *tempcons = NIL;
-
- va_start(args, elem);
-
- temp = elem;
- while (temp != (void *) -1)
- {
- temp = lcons(temp, NIL);
- if (tempcons == NIL)
- retval = temp;
- else
- lnext(tempcons) = temp;
- tempcons = temp;
- temp = va_arg(args, void *);
- }
-
- va_end(args);
+#include "nodes/parsenodes.h"
- return retval;
-}
/*
* makeInteger
@@ -307,7 +276,7 @@ sameseti(List *list1, List *list2)
* as were in the inputs.
*/
List *
-LispUnion(List *l1, List *l2)
+set_union(List *l1, List *l2)
{
List *retval = listCopy(l1);
List *i;
@@ -321,7 +290,7 @@ LispUnion(List *l1, List *l2)
}
List *
-LispUnioni(List *l1, List *l2)
+set_unioni(List *l1, List *l2)
{
List *retval = listCopy(l1);
List *i;
@@ -385,7 +354,8 @@ intMember(int l1, List *l2)
/*
* lremove
- * Removes 'elem' from the the linked list.
+ * Removes 'elem' from the linked list (destructively changing the list!).
+ *
* This version matches 'elem' using simple pointer comparison.
* See also LispRemove.
*/
@@ -414,7 +384,8 @@ lremove(void *elem, List *list)
/*
* LispRemove
- * Removes 'elem' from the the linked list.
+ * Removes 'elem' from the linked list (destructively changing the list!).
+ *
* This version matches 'elem' using equal().
* (If there is more than one equal list member, the first is removed.)
* See also lremove.
@@ -442,10 +413,12 @@ LispRemove(void *elem, List *list)
return result;
}
-#ifdef NOT_USED
-
+/*
+ * lremovei
+ * lremove() for integer lists.
+ */
List *
-intLispRemove(int elem, List *list)
+lremovei(int elem, List *list)
{
List *l;
List *prev = NIL;
@@ -467,8 +440,6 @@ intLispRemove(int elem, List *list)
return result;
}
-#endif
-
/*
* ltruncate
* Truncate a list to n elements.
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 8b24b82122..39bc497343 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.126 2000/09/12 21:06:49 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.127 2000/09/29 18:21:29 tgl Exp $
*
* NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which
@@ -220,6 +220,9 @@ _outQuery(StringInfo str, Query *node)
if (node->utilityStmt)
{
+ /*
+ * Hack to make up for lack of outfuncs for utility-stmt nodes
+ */
switch (nodeTag(node->utilityStmt))
{
case T_CreateStmt:
@@ -239,7 +242,7 @@ _outQuery(StringInfo str, Query *node)
break;
case T_NotifyStmt:
- appendStringInfo(str, " :utility ");
+ appendStringInfo(str, " :notify ");
_outToken(str, ((NotifyStmt *) (node->utilityStmt))->relname);
break;
@@ -250,32 +253,34 @@ _outQuery(StringInfo str, Query *node)
else
appendStringInfo(str, " :utility <>");
- appendStringInfo(str, " :resultRelation %u :into ",
+ appendStringInfo(str, " :resultRelation %d :into ",
node->resultRelation);
_outToken(str, node->into);
- appendStringInfo(str,
- " :isPortal %s :isBinary %s :isTemp %s :unionall %s :distinctClause ",
+ appendStringInfo(str, " :isPortal %s :isBinary %s :isTemp %s"
+ " :unionall %s :hasAggs %s :hasSubLinks %s :rtable ",
node->isPortal ? "true" : "false",
node->isBinary ? "true" : "false",
node->isTemp ? "true" : "false",
- node->unionall ? "true" : "false");
- _outNode(str, node->distinctClause);
-
- appendStringInfo(str, " :sortClause ");
- _outNode(str, node->sortClause);
-
- appendStringInfo(str, " :rtable ");
+ node->unionall ? "true" : "false",
+ node->hasAggs ? "true" : "false",
+ node->hasSubLinks ? "true" : "false");
_outNode(str, node->rtable);
appendStringInfo(str, " :jointree ");
_outNode(str, node->jointree);
- appendStringInfo(str, " :targetlist ");
+ appendStringInfo(str, " :targetList ");
_outNode(str, node->targetList);
- appendStringInfo(str, " :qual ");
- _outNode(str, node->qual);
+ appendStringInfo(str, " :rowMarks ");
+ _outIntList(str, node->rowMarks);
+
+ appendStringInfo(str, " :distinctClause ");
+ _outNode(str, node->distinctClause);
+
+ appendStringInfo(str, " :sortClause ");
+ _outNode(str, node->sortClause);
appendStringInfo(str, " :groupClause ");
_outNode(str, node->groupClause);
@@ -283,23 +288,17 @@ _outQuery(StringInfo str, Query *node)
appendStringInfo(str, " :havingQual ");
_outNode(str, node->havingQual);
- appendStringInfo(str, " :hasAggs %s :hasSubLinks %s :unionClause ",
- node->hasAggs ? "true" : "false",
- node->hasSubLinks ? "true" : "false");
- _outNode(str, node->unionClause);
-
appendStringInfo(str, " :intersectClause ");
_outNode(str, node->intersectClause);
+ appendStringInfo(str, " :unionClause ");
+ _outNode(str, node->unionClause);
+
appendStringInfo(str, " :limitOffset ");
_outNode(str, node->limitOffset);
appendStringInfo(str, " :limitCount ");
_outNode(str, node->limitCount);
-
- appendStringInfo(str, " :rowMark ");
- _outNode(str, node->rowMark);
-
}
static void
@@ -536,6 +535,19 @@ _outTidScan(StringInfo str, TidScan *node)
}
/*
+ * SubqueryScan is a subclass of Scan
+ */
+static void
+_outSubqueryScan(StringInfo str, SubqueryScan *node)
+{
+ appendStringInfo(str, " SUBQUERYSCAN ");
+ _outPlanInfo(str, (Plan *) node);
+
+ appendStringInfo(str, " :scanrelid %u :subplan ", node->scan.scanrelid);
+ _outNode(str, node->subplan);
+}
+
+/*
* Material is a subclass of Plan
*/
static void
@@ -864,6 +876,18 @@ _outRangeTblRef(StringInfo str, RangeTblRef *node)
}
/*
+ * FromExpr
+ */
+static void
+_outFromExpr(StringInfo str, FromExpr *node)
+{
+ appendStringInfo(str, " FROMEXPR :fromlist ");
+ _outNode(str, node->fromlist);
+ appendStringInfo(str, " :quals ");
+ _outNode(str, node->quals);
+}
+
+/*
* JoinExpr
*/
static void
@@ -916,36 +940,33 @@ _outRelOptInfo(StringInfo str, RelOptInfo *node)
appendStringInfo(str, " RELOPTINFO :relids ");
_outIntList(str, node->relids);
- appendStringInfo(str,
- " :rows %.0f :width %d :indexed %s :pages %ld :tuples %.0f :targetlist ",
+ appendStringInfo(str, " :rows %.0f :width %d :targetlist ",
node->rows,
- node->width,
- node->indexed ? "true" : "false",
- node->pages,
- node->tuples);
+ node->width);
_outNode(str, node->targetlist);
appendStringInfo(str, " :pathlist ");
_outNode(str, node->pathlist);
-
appendStringInfo(str, " :cheapest_startup_path ");
_outNode(str, node->cheapest_startup_path);
appendStringInfo(str, " :cheapest_total_path ");
_outNode(str, node->cheapest_total_path);
- appendStringInfo(str,
- " :pruneable %s :baserestrictinfo ",
- node->pruneable ? "true" : "false");
- _outNode(str, node->baserestrictinfo);
+ appendStringInfo(str, " :pruneable %s :issubquery %s :indexed %s :pages %ld :tuples %.0f :subplan ",
+ node->pruneable ? "true" : "false",
+ node->issubquery ? "true" : "false",
+ node->indexed ? "true" : "false",
+ node->pages,
+ node->tuples);
+ _outNode(str, node->subplan);
- appendStringInfo(str,
- " :baserestrictcost %.2f :outerjoinset ",
+ appendStringInfo(str, " :baserestrictinfo ");
+ _outNode(str, node->baserestrictinfo);
+ appendStringInfo(str, " :baserestrictcost %.2f :outerjoinset ",
node->baserestrictcost);
_outIntList(str, node->outerjoinset);
-
appendStringInfo(str, " :joininfo ");
_outNode(str, node->joininfo);
-
appendStringInfo(str, " :innerjoin ");
_outNode(str, node->innerjoin);
}
@@ -977,21 +998,21 @@ _outRangeTblEntry(StringInfo str, RangeTblEntry *node)
{
appendStringInfo(str, " RTE :relname ");
_outToken(str, node->relname);
- appendStringInfo(str, " :relid %u :alias ",
+ appendStringInfo(str, " :relid %u ",
node->relid);
+ appendStringInfo(str, " :subquery ");
+ _outNode(str, node->subquery);
+ appendStringInfo(str, " :alias ");
_outNode(str, node->alias);
appendStringInfo(str, " :eref ");
_outNode(str, node->eref);
- appendStringInfo(str, " :inh %s :inFromCl %s :skipAcl %s",
+ appendStringInfo(str, " :inh %s :inFromCl %s :checkForRead %s"
+ " :checkForWrite %s :checkAsUser %u",
node->inh ? "true" : "false",
node->inFromCl ? "true" : "false",
- node->skipAcl ? "true" : "false");
-}
-
-static void
-_outRowMark(StringInfo str, RowMark *node)
-{
- appendStringInfo(str, " ROWMARK :rti %u :info %u", node->rti, node->info);
+ node->checkForRead ? "true" : "false",
+ node->checkForWrite ? "true" : "false",
+ node->checkAsUser);
}
/*
@@ -1151,8 +1172,8 @@ _outRestrictInfo(StringInfo str, RestrictInfo *node)
appendStringInfo(str, " RESTRICTINFO :clause ");
_outNode(str, node->clause);
- appendStringInfo(str, " :isjoinqual %s :subclauseindices ",
- node->isjoinqual ? "true" : "false");
+ appendStringInfo(str, " :ispusheddown %s :subclauseindices ",
+ node->ispusheddown ? "true" : "false");
_outNode(str, node->subclauseindices);
appendStringInfo(str, " :mergejoinoperator %u ", node->mergejoinoperator);
@@ -1492,6 +1513,9 @@ _outNode(StringInfo str, void *obj)
case T_TidScan:
_outTidScan(str, obj);
break;
+ case T_SubqueryScan:
+ _outSubqueryScan(str, obj);
+ break;
case T_Material:
_outMaterial(str, obj);
break;
@@ -1555,6 +1579,9 @@ _outNode(StringInfo str, void *obj)
case T_RangeTblRef:
_outRangeTblRef(str, obj);
break;
+ case T_FromExpr:
+ _outFromExpr(str, obj);
+ break;
case T_JoinExpr:
_outJoinExpr(str, obj);
break;
@@ -1573,9 +1600,6 @@ _outNode(StringInfo str, void *obj)
case T_RangeTblEntry:
_outRangeTblEntry(str, obj);
break;
- case T_RowMark:
- _outRowMark(str, obj);
- break;
case T_Path:
_outPath(str, obj);
break;
diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c
index 3f48cb0b9e..a0417f8108 100644
--- a/src/backend/nodes/print.c
+++ b/src/backend/nodes/print.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.41 2000/09/25 18:14:55 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.42 2000/09/29 18:21:29 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -39,7 +39,6 @@ print(void *obj)
s = nodeToString(obj);
printf("%s\n", s);
fflush(stdout);
- return;
}
/*
@@ -132,10 +131,15 @@ print_rt(List *rtable)
{
RangeTblEntry *rte = lfirst(l);
- printf("%d\t%s(%s)\t%u\t%d\t%s\n",
- i, rte->relname, rte->eref->relname, rte->relid,
- rte->inFromCl,
- (rte->inh ? "inh" : ""));
+ if (rte->relname)
+ printf("%d\t%s (%s)\t%u",
+ i, rte->relname, rte->eref->relname, rte->relid);
+ else
+ printf("%d\t[subquery] (%s)\t",
+ i, rte->eref->relname);
+ printf("\t%s\t%s\n",
+ (rte->inh ? "inh" : ""),
+ (rte->inFromCl ? "inFromCl" : ""));
i++;
}
}
@@ -286,7 +290,7 @@ plannode_type(Plan *p)
{
switch (nodeTag(p))
{
- case T_Plan:
+ case T_Plan:
return "PLAN";
break;
case T_Result:
@@ -304,6 +308,12 @@ plannode_type(Plan *p)
case T_IndexScan:
return "INDEXSCAN";
break;
+ case T_TidScan:
+ return "TIDSCAN";
+ break;
+ case T_SubqueryScan:
+ return "SUBQUERYSCAN";
+ break;
case T_Join:
return "JOIN";
break;
@@ -334,9 +344,6 @@ plannode_type(Plan *p)
case T_Group:
return "GROUP";
break;
- case T_TidScan:
- return "TIDSCAN";
- break;
default:
return "UNKNOWN";
break;
@@ -372,10 +379,10 @@ print_plan_recursive(Plan *p, Query *parsetree, int indentLevel, char *label)
}
else if (IsA(p, IndexScan))
{
- StrNCpy(extraInfo,
- ((RangeTblEntry *) (nth(((IndexScan *) p)->scan.scanrelid - 1,
- parsetree->rtable)))->relname,
- NAMEDATALEN);
+ RangeTblEntry *rte;
+
+ rte = rt_fetch(((IndexScan *) p)->scan.scanrelid, parsetree->rtable);
+ StrNCpy(extraInfo, rte->relname, NAMEDATALEN);
}
else
extraInfo[0] = '\0';
@@ -386,7 +393,7 @@ print_plan_recursive(Plan *p, Query *parsetree, int indentLevel, char *label)
print_plan_recursive(p->lefttree, parsetree, indentLevel + 3, "l: ");
print_plan_recursive(p->righttree, parsetree, indentLevel + 3, "r: ");
- if (nodeTag(p) == T_Append)
+ if (IsA(p, Append))
{
List *lst;
int whichplan = 0;
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 00a6407db8..da0ba22684 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.96 2000/09/12 21:06:49 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.97 2000/09/29 18:21:29 tgl Exp $
*
* NOTES
* Most of the read functions for plan nodes are tested. (In fact, they
@@ -70,13 +70,16 @@ _readQuery()
local_node->commandType = atoi(token);
token = lsptok(NULL, &length); /* skip :utility */
- /* we can't get create or index here, can we? */
-
- token = lsptok(NULL, &length); /* get the notify name if any */
+ token = lsptok(NULL, &length);
if (length == 0)
local_node->utilityStmt = NULL;
else
{
+ /*
+ * Hack to make up for lack of readfuncs for utility-stmt nodes
+ *
+ * we can't get create or index here, can we?
+ */
NotifyStmt *n = makeNode(NotifyStmt);
n->relname = debackslash(token, length);
@@ -110,11 +113,13 @@ _readQuery()
token = lsptok(NULL, &length); /* get unionall */
local_node->unionall = (token[0] == 't') ? true : false;
- token = lsptok(NULL, &length); /* skip :distinctClause */
- local_node->distinctClause = nodeRead(true);
+ token = lsptok(NULL, &length); /* skip the :hasAggs */
+ token = lsptok(NULL, &length); /* get hasAggs */
+ local_node->hasAggs = (token[0] == 't') ? true : false;
- token = lsptok(NULL, &length); /* skip :sortClause */
- local_node->sortClause = nodeRead(true);
+ token = lsptok(NULL, &length); /* skip the :hasSubLinks */
+ token = lsptok(NULL, &length); /* get hasSubLinks */
+ local_node->hasSubLinks = (token[0] == 't') ? true : false;
token = lsptok(NULL, &length); /* skip :rtable */
local_node->rtable = nodeRead(true);
@@ -125,8 +130,14 @@ _readQuery()
token = lsptok(NULL, &length); /* skip :targetlist */
local_node->targetList = nodeRead(true);
- token = lsptok(NULL, &length); /* skip :qual */
- local_node->qual = nodeRead(true);
+ token = lsptok(NULL, &length); /* skip :rowMarks */
+ local_node->rowMarks = toIntList(nodeRead(true));
+
+ token = lsptok(NULL, &length); /* skip :distinctClause */
+ local_node->distinctClause = nodeRead(true);
+
+ token = lsptok(NULL, &length); /* skip :sortClause */
+ local_node->sortClause = nodeRead(true);
token = lsptok(NULL, &length); /* skip :groupClause */
local_node->groupClause = nodeRead(true);
@@ -134,20 +145,11 @@ _readQuery()
token = lsptok(NULL, &length); /* skip :havingQual */
local_node->havingQual = nodeRead(true);
- token = lsptok(NULL, &length); /* skip the :hasAggs */
- token = lsptok(NULL, &length); /* get hasAggs */
- local_node->hasAggs = (token[0] == 't') ? true : false;
-
- token = lsptok(NULL, &length); /* skip the :hasSubLinks */
- token = lsptok(NULL, &length); /* get hasSubLinks */
- local_node->hasSubLinks = (token[0] == 't') ? true : false;
-
- token = lsptok(NULL, &length); /* skip :unionClause */
- local_node->unionClause = nodeRead(true);
-
token = lsptok(NULL, &length); /* skip :intersectClause */
local_node->intersectClause = nodeRead(true);
+ token = lsptok(NULL, &length); /* skip :unionClause */
+ local_node->unionClause = nodeRead(true);
token = lsptok(NULL, &length); /* skip :limitOffset */
local_node->limitOffset = nodeRead(true);
@@ -155,9 +157,6 @@ _readQuery()
token = lsptok(NULL, &length); /* skip :limitCount */
local_node->limitCount = nodeRead(true);
- token = lsptok(NULL, &length); /* skip :rowMark */
- local_node->rowMark = nodeRead(true);
-
return local_node;
}
@@ -562,6 +561,29 @@ _readTidScan()
}
/* ----------------
+ * _readSubqueryScan
+ *
+ * SubqueryScan is a subclass of Scan
+ * ----------------
+ */
+static SubqueryScan *
+_readSubqueryScan()
+{
+ SubqueryScan *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(SubqueryScan);
+
+ _getScan((Scan *) local_node);
+
+ token = lsptok(NULL, &length); /* eat :subplan */
+ local_node->subplan = nodeRead(true); /* now read it */
+
+ return local_node;
+}
+
+/* ----------------
* _readSort
*
* Sort is a subclass of Plan
@@ -1182,6 +1204,30 @@ _readRangeTblRef()
}
/* ----------------
+ * _readFromExpr
+ *
+ * FromExpr is a subclass of Node
+ * ----------------
+ */
+static FromExpr *
+_readFromExpr()
+{
+ FromExpr *local_node;
+ char *token;
+ int length;
+
+ local_node = makeNode(FromExpr);
+
+ token = lsptok(NULL, &length); /* eat :fromlist */
+ local_node->fromlist = nodeRead(true); /* now read it */
+
+ token = lsptok(NULL, &length); /* eat :quals */
+ local_node->quals = nodeRead(true); /* now read it */
+
+ return local_node;
+}
+
+/* ----------------
* _readJoinExpr
*
* JoinExpr is a subclass of Node
@@ -1293,22 +1339,6 @@ _readRelOptInfo()
token = lsptok(NULL, &length); /* now read it */
local_node->width = atoi(token);
- token = lsptok(NULL, &length); /* get :indexed */
- token = lsptok(NULL, &length); /* now read it */
-
- if (!strncmp(token, "true", 4))
- local_node->indexed = true;
- else
- local_node->indexed = false;
-
- token = lsptok(NULL, &length); /* get :pages */
- token = lsptok(NULL, &length); /* now read it */
- local_node->pages = atol(token);
-
- token = lsptok(NULL, &length); /* get :tuples */
- token = lsptok(NULL, &length); /* now read it */
- local_node->tuples = atof(token);
-
token = lsptok(NULL, &length); /* get :targetlist */
local_node->targetlist = nodeRead(true); /* now read it */
@@ -1325,6 +1355,25 @@ _readRelOptInfo()
token = lsptok(NULL, &length); /* get :pruneable */
local_node->pruneable = (token[0] == 't') ? true : false;
+ token = lsptok(NULL, &length); /* get :issubquery */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->issubquery = (token[0] == 't') ? true : false;
+
+ token = lsptok(NULL, &length); /* get :indexed */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->indexed = (token[0] == 't') ? true : false;
+
+ token = lsptok(NULL, &length); /* get :pages */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->pages = atol(token);
+
+ token = lsptok(NULL, &length); /* get :tuples */
+ token = lsptok(NULL, &length); /* now read it */
+ local_node->tuples = atof(token);
+
+ token = lsptok(NULL, &length); /* get :subplan */
+ local_node->subplan = nodeRead(true); /* now read it */
+
token = lsptok(NULL, &length); /* get :baserestrictinfo */
local_node->baserestrictinfo = nodeRead(true); /* now read it */
@@ -1409,6 +1458,9 @@ _readRangeTblEntry()
token = lsptok(NULL, &length); /* get :relid */
local_node->relid = strtoul(token, NULL, 10);
+ token = lsptok(NULL, &length); /* eat :subquery */
+ local_node->subquery = nodeRead(true); /* now read it */
+
token = lsptok(NULL, &length); /* eat :alias */
local_node->alias = nodeRead(true); /* now read it */
@@ -1423,27 +1475,17 @@ _readRangeTblEntry()
token = lsptok(NULL, &length); /* get :inFromCl */
local_node->inFromCl = (token[0] == 't') ? true : false;
- token = lsptok(NULL, &length); /* eat :skipAcl */
- token = lsptok(NULL, &length); /* get :skipAcl */
- local_node->skipAcl = (token[0] == 't') ? true : false;
-
- return local_node;
-}
-
-static RowMark *
-_readRowMark()
-{
- RowMark *local_node = makeNode(RowMark);
- char *token;
- int length;
+ token = lsptok(NULL, &length); /* eat :checkForRead */
+ token = lsptok(NULL, &length); /* get :checkForRead */
+ local_node->checkForRead = (token[0] == 't') ? true : false;
- token = lsptok(NULL, &length); /* eat :rti */
- token = lsptok(NULL, &length); /* get :rti */
- local_node->rti = strtoul(token, NULL, 10);
+ token = lsptok(NULL, &length); /* eat :checkForWrite */
+ token = lsptok(NULL, &length); /* get :checkForWrite */
+ local_node->checkForWrite = (token[0] == 't') ? true : false;
- token = lsptok(NULL, &length); /* eat :info */
- token = lsptok(NULL, &length); /* get :info */
- local_node->info = strtoul(token, NULL, 10);
+ token = lsptok(NULL, &length); /* eat :checkAsUser */
+ token = lsptok(NULL, &length); /* get :checkAsUser */
+ local_node->checkAsUser = strtoul(token, NULL, 10);
return local_node;
}
@@ -1768,9 +1810,9 @@ _readRestrictInfo()
token = lsptok(NULL, &length); /* get :clause */
local_node->clause = nodeRead(true); /* now read it */
- token = lsptok(NULL, &length); /* get :isjoinqual */
+ token = lsptok(NULL, &length); /* get :ispusheddown */
token = lsptok(NULL, &length); /* now read it */
- local_node->isjoinqual = (token[0] == 't') ? true : false;
+ local_node->ispusheddown = (token[0] == 't') ? true : false;
token = lsptok(NULL, &length); /* get :subclauseindices */
local_node->subclauseindices = nodeRead(true); /* now read it */
@@ -1879,6 +1921,8 @@ parsePlanString(void)
return_value = _readIndexScan();
else if (length == 7 && strncmp(token, "TIDSCAN", length) == 0)
return_value = _readTidScan();
+ else if (length == 12 && strncmp(token, "SUBQUERYSCAN", length) == 0)
+ return_value = _readSubqueryScan();
else if (length == 4 && strncmp(token, "SORT", length) == 0)
return_value = _readSort();
else if (length == 6 && strncmp(token, "AGGREG", length) == 0)
@@ -1891,6 +1935,8 @@ parsePlanString(void)
return_value = _readRelabelType();
else if (length == 11 && strncmp(token, "RANGETBLREF", length) == 0)
return_value = _readRangeTblRef();
+ else if (length == 8 && strncmp(token, "FROMEXPR", length) == 0)
+ return_value = _readFromExpr();
else if (length == 8 && strncmp(token, "JOINEXPR", length) == 0)
return_value = _readJoinExpr();
else if (length == 3 && strncmp(token, "AGG", length) == 0)
@@ -1953,10 +1999,8 @@ parsePlanString(void)
return_value = _readCaseExpr();
else if (length == 4 && strncmp(token, "WHEN", length) == 0)
return_value = _readCaseWhen();
- else if (length == 7 && strncmp(token, "ROWMARK", length) == 0)
- return_value = _readRowMark();
else
- elog(ERROR, "badly formatted planstring \"%.10s\"...\n", token);
+ elog(ERROR, "badly formatted planstring \"%.10s\"...", token);
return (Node *) return_value;
}