mirror of
https://github.com/postgres/postgres.git
synced 2025-07-26 01:22:12 +03:00
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!
This commit is contained in:
@ -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
|
||||
@ -535,6 +534,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
|
||||
*/
|
||||
@ -863,6 +875,18 @@ _outRangeTblRef(StringInfo str, RangeTblRef *node)
|
||||
node->rtindex);
|
||||
}
|
||||
|
||||
/*
|
||||
* FromExpr
|
||||
*/
|
||||
static void
|
||||
_outFromExpr(StringInfo str, FromExpr *node)
|
||||
{
|
||||
appendStringInfo(str, " FROMEXPR :fromlist ");
|
||||
_outNode(str, node->fromlist);
|
||||
appendStringInfo(str, " :quals ");
|
||||
_outNode(str, node->quals);
|
||||
}
|
||||
|
||||
/*
|
||||
* JoinExpr
|
||||
*/
|
||||
@ -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;
|
||||
|
Reference in New Issue
Block a user