提交 e18e8f87 编写于 作者: T Tom Lane

Change expandRTE() and ResolveNew() back to taking just the single

RTE of interest, rather than the whole rangetable list.  This makes
the API more understandable and avoids duplicate RTE lookups.  This
patch reverts no-longer-needed portions of my patch of 2004-08-19.
上级 fb91a83e
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.129 2005/04/28 21:47:13 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.130 2005/06/04 19:19:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -58,10 +58,10 @@ static void compare_tlist_datatypes(List *tlist, List *colTypes,
bool *differentTypes);
static bool qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
bool *differentTypes);
static void subquery_push_qual(Query *subquery, List *rtable,
Index rti, Node *qual);
static void subquery_push_qual(Query *subquery,
RangeTblEntry *rte, Index rti, Node *qual);
static void recurse_push_qual(Node *setOp, Query *topquery,
List *rtable, Index rti, Node *qual);
RangeTblEntry *rte, Index rti, Node *qual);
/*
......@@ -365,7 +365,7 @@ set_subquery_pathlist(Query *root, RelOptInfo *rel,
if (qual_is_pushdown_safe(subquery, rti, clause, differentTypes))
{
/* Push it down */
subquery_push_qual(subquery, root->rtable, rti, clause);
subquery_push_qual(subquery, rte, rti, clause);
}
else
{
......@@ -769,13 +769,13 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
* subquery_push_qual - push down a qual that we have determined is safe
*/
static void
subquery_push_qual(Query *subquery, List *rtable, Index rti, Node *qual)
subquery_push_qual(Query *subquery, RangeTblEntry *rte, Index rti, Node *qual)
{
if (subquery->setOperations != NULL)
{
/* Recurse to push it separately to each component query */
recurse_push_qual(subquery->setOperations, subquery,
rtable, rti, qual);
rte, rti, qual);
}
else
{
......@@ -789,7 +789,7 @@ subquery_push_qual(Query *subquery, List *rtable, Index rti, Node *qual)
* This step also ensures that when we are pushing into a setop tree,
* each component query gets its own copy of the qual.
*/
qual = ResolveNew(qual, rti, 0, rtable,
qual = ResolveNew(qual, rti, 0, rte,
subquery->targetList,
CMD_SELECT, 0);
......@@ -817,7 +817,7 @@ subquery_push_qual(Query *subquery, List *rtable, Index rti, Node *qual)
*/
static void
recurse_push_qual(Node *setOp, Query *topquery,
List *rtable, Index rti, Node *qual)
RangeTblEntry *rte, Index rti, Node *qual)
{
if (IsA(setOp, RangeTblRef))
{
......@@ -826,14 +826,14 @@ recurse_push_qual(Node *setOp, Query *topquery,
Query *subquery = subrte->subquery;
Assert(subquery != NULL);
subquery_push_qual(subquery, rtable, rti, qual);
subquery_push_qual(subquery, rte, rti, qual);
}
else if (IsA(setOp, SetOperationStmt))
{
SetOperationStmt *op = (SetOperationStmt *) setOp;
recurse_push_qual(op->larg, topquery, rtable, rti, qual);
recurse_push_qual(op->rarg, topquery, rtable, rti, qual);
recurse_push_qual(op->larg, topquery, rte, rti, qual);
recurse_push_qual(op->rarg, topquery, rte, rti, qual);
}
else
{
......
......@@ -16,7 +16,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.27 2005/04/28 21:47:14 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.28 2005/06/04 19:19:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -46,7 +46,7 @@ typedef struct reduce_outer_joins_state
static bool is_simple_subquery(Query *subquery);
static bool has_nullable_targetlist(Query *subquery);
static void resolvenew_in_jointree(Node *jtnode, int varno,
List *rtable, List *subtlist);
RangeTblEntry *rte, List *subtlist);
static reduce_outer_joins_state *reduce_outer_joins_pass1(Node *jtnode);
static void reduce_outer_joins_pass2(Node *jtnode,
reduce_outer_joins_state *state,
......@@ -243,18 +243,18 @@ pull_up_subqueries(Query *parse, Node *jtnode, bool below_outer_join)
subtlist = subquery->targetList;
parse->targetList = (List *)
ResolveNew((Node *) parse->targetList,
varno, 0, parse->rtable,
varno, 0, rte,
subtlist, CMD_SELECT, 0);
resolvenew_in_jointree((Node *) parse->jointree, varno,
parse->rtable, subtlist);
rte, subtlist);
Assert(parse->setOperations == NULL);
parse->havingQual =
ResolveNew(parse->havingQual,
varno, 0, parse->rtable,
varno, 0, rte,
subtlist, CMD_SELECT, 0);
parse->in_info_list = (List *)
ResolveNew((Node *) parse->in_info_list,
varno, 0, parse->rtable,
varno, 0, rte,
subtlist, CMD_SELECT, 0);
foreach(rt, parse->rtable)
......@@ -264,7 +264,7 @@ pull_up_subqueries(Query *parse, Node *jtnode, bool below_outer_join)
if (otherrte->rtekind == RTE_JOIN)
otherrte->joinaliasvars = (List *)
ResolveNew((Node *) otherrte->joinaliasvars,
varno, 0, parse->rtable,
varno, 0, rte,
subtlist, CMD_SELECT, 0);
}
......@@ -492,7 +492,7 @@ has_nullable_targetlist(Query *subquery)
*/
static void
resolvenew_in_jointree(Node *jtnode, int varno,
List *rtable, List *subtlist)
RangeTblEntry *rte, List *subtlist)
{
if (jtnode == NULL)
return;
......@@ -506,19 +506,19 @@ resolvenew_in_jointree(Node *jtnode, int varno,
ListCell *l;
foreach(l, f->fromlist)
resolvenew_in_jointree(lfirst(l), varno, rtable, subtlist);
resolvenew_in_jointree(lfirst(l), varno, rte, subtlist);
f->quals = ResolveNew(f->quals,
varno, 0, rtable,
varno, 0, rte,
subtlist, CMD_SELECT, 0);
}
else if (IsA(jtnode, JoinExpr))
{
JoinExpr *j = (JoinExpr *) jtnode;
resolvenew_in_jointree(j->larg, varno, rtable, subtlist);
resolvenew_in_jointree(j->rarg, varno, rtable, subtlist);
resolvenew_in_jointree(j->larg, varno, rte, subtlist);
resolvenew_in_jointree(j->rarg, varno, rte, subtlist);
j->quals = ResolveNew(j->quals,
varno, 0, rtable,
varno, 0, rte,
subtlist, CMD_SELECT, 0);
/*
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.109 2005/05/30 18:55:49 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.110 2005/06/04 19:19:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -451,7 +451,7 @@ build_physical_tlist(Query *root, RelOptInfo *rel)
break;
case RTE_FUNCTION:
expandRTE(root->rtable, varno, 0, true /* include dropped */,
expandRTE(rte, varno, 0, true /* include dropped */,
NULL, &colvars);
foreach(l, colvars)
{
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.140 2005/04/13 16:50:55 tgl Exp $
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.141 2005/06/04 19:19:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -663,7 +663,8 @@ transformFromClauseItem(ParseState *pstate, Node *n, List **containedRels)
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(j->larg));
leftrti = 0; /* keep compiler quiet */
}
expandRTE(pstate->p_rtable, leftrti, 0, false,
rte = rt_fetch(leftrti, pstate->p_rtable);
expandRTE(rte, leftrti, 0, false,
&l_colnames, &l_colvars);
if (IsA(j->rarg, RangeTblRef))
......@@ -675,7 +676,8 @@ transformFromClauseItem(ParseState *pstate, Node *n, List **containedRels)
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(j->rarg));
rightrti = 0; /* keep compiler quiet */
}
expandRTE(pstate->p_rtable, rightrti, 0, false,
rte = rt_fetch(rightrti, pstate->p_rtable);
expandRTE(rte, rightrti, 0, false,
&r_colnames, &r_colvars);
/*
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.130 2005/05/30 01:20:49 tgl Exp $
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.131 2005/06/04 19:19:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -695,10 +695,11 @@ coerce_record_to_complex(ParseState *pstate, Node *node,
{
int rtindex = ((Var *) node)->varno;
int sublevels_up = ((Var *) node)->varlevelsup;
List *rtable;
RangeTblEntry *rte;
rtable = GetLevelNRangeTable(pstate, sublevels_up);
expandRTE(rtable, rtindex, sublevels_up, false, NULL, &args);
rte = GetRTEByRangeTablePosn(pstate, rtindex, sublevels_up);
expandRTE(rte, rtindex, sublevels_up, false,
NULL, &args);
}
else
ereport(ERROR,
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.109 2005/06/03 23:05:28 tgl Exp $
* $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.110 2005/06/04 19:19:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -445,27 +445,6 @@ GetRTEByRangeTablePosn(ParseState *pstate,
return rt_fetch(varno, pstate->p_rtable);
}
/*
* GetLevelNRangeTable
* Get the rangetable list for the N'th query level up from current.
*/
List *
GetLevelNRangeTable(ParseState *pstate, int sublevels_up)
{
int index = 0;
while (pstate != NULL)
{
if (index == sublevels_up)
return pstate->p_rtable;
index++;
pstate = pstate->parentParseState;
}
elog(ERROR, "rangetable not found (internal error)");
return NIL; /* keep compiler quiet */
}
/*
* scanRTEForColumn
* Search the column names of a single RTE for the given name.
......@@ -1202,19 +1181,19 @@ addImplicitRTE(ParseState *pstate, RangeVar *relation)
* results. If include_dropped is TRUE then empty strings and NULL constants
* (not Vars!) are returned for dropped columns.
*
* The target RTE is the rtindex'th entry of rtable.
* sublevels_up is the varlevelsup value to use in the created Vars.
* rtindex and sublevels_up are the varno and varlevelsup values to use
* in the created Vars. Ordinarily rtindex should match the actual position
* of the RTE in its rangetable.
*
* The output lists go into *colnames and *colvars.
* If only one of the two kinds of output list is needed, pass NULL for the
* output pointer for the unwanted one.
*/
void
expandRTE(List *rtable, int rtindex, int sublevels_up,
expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
bool include_dropped,
List **colnames, List **colvars)
{
RangeTblEntry *rte = rt_fetch(rtindex, rtable);
int varattno;
if (colnames)
......@@ -1490,9 +1469,14 @@ expandTupleDesc(TupleDesc tupdesc, Alias *eref,
* expandRelAttrs -
* Workhorse for "*" expansion: produce a list of targetentries
* for the attributes of the rte
*
* As with expandRTE, rtindex/sublevels_up determine the varno/varlevelsup
* fields of the Vars produced. pstate->p_next_resno determines the resnos
* assigned to the TLEs.
*/
List *
expandRelAttrs(ParseState *pstate, List *rtable, int rtindex, int sublevels_up)
expandRelAttrs(ParseState *pstate, RangeTblEntry *rte,
int rtindex, int sublevels_up)
{
List *names,
*vars;
......@@ -1500,7 +1484,8 @@ expandRelAttrs(ParseState *pstate, List *rtable, int rtindex, int sublevels_up)
*var;
List *te_list = NIL;
expandRTE(rtable, rtindex, sublevels_up, false, &names, &vars);
expandRTE(rte, rtindex, sublevels_up, false,
&names, &vars);
forboth(name, names, var, vars)
{
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.134 2005/05/31 01:03:23 tgl Exp $
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.135 2005/06/04 19:19:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -697,7 +697,6 @@ ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref)
RangeTblEntry *rte;
int sublevels_up;
int rtindex;
List *rtable;
switch (numnames)
{
......@@ -742,9 +741,8 @@ ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref)
relname));
rtindex = RTERangeTablePosn(pstate, rte, &sublevels_up);
rtable = GetLevelNRangeTable(pstate, sublevels_up);
return expandRelAttrs(pstate, rtable, rtindex, sublevels_up);
return expandRelAttrs(pstate, rte, rtindex, sublevels_up);
}
}
......@@ -789,8 +787,7 @@ ExpandAllTables(ParseState *pstate)
found_table = true;
target = list_concat(target,
expandRelAttrs(pstate, pstate->p_rtable,
rtindex, 0));
expandRelAttrs(pstate, rte, rtindex, 0));
}
/* Check for SELECT *; */
......@@ -929,8 +926,8 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
*lvar;
int i;
expandRTE(GetLevelNRangeTable(pstate, netlevelsup),
var->varno, 0, false, &names, &vars);
expandRTE(rte, var->varno, 0, false,
&names, &vars);
tupleDesc = CreateTemplateTupleDesc(list_length(vars), false);
i = 1;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.153 2005/06/03 23:05:28 tgl Exp $
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.154 2005/06/04 19:19:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -106,6 +106,8 @@ AcquireRewriteLocks(Query *parsetree)
Relation rel;
LOCKMODE lockmode;
List *newaliasvars;
Index curinputvarno;
RangeTblEntry *curinputrte;
ListCell *ll;
++rt_index;
......@@ -140,8 +142,14 @@ AcquireRewriteLocks(Query *parsetree)
* Scan the join's alias var list to see if any columns
* have been dropped, and if so replace those Vars with
* NULL Consts.
*
* Since a join has only two inputs, we can expect to
* see multiple references to the same input RTE; optimize
* away multiple fetches.
*/
newaliasvars = NIL;
curinputvarno = 0;
curinputrte = NULL;
foreach(ll, rte->joinaliasvars)
{
Var *aliasvar = (Var *) lfirst(ll);
......@@ -165,12 +173,17 @@ AcquireRewriteLocks(Query *parsetree)
* but it's OK to assume here.)
*/
Assert(aliasvar->varlevelsup == 0);
if (aliasvar->varno >= rt_index)
elog(ERROR, "unexpected varno %d in JOIN RTE %d",
aliasvar->varno, rt_index);
if (get_rte_attribute_is_dropped(
rt_fetch(aliasvar->varno, parsetree->rtable),
aliasvar->varattno))
if (aliasvar->varno != curinputvarno)
{
curinputvarno = aliasvar->varno;
if (curinputvarno >= rt_index)
elog(ERROR, "unexpected varno %d in JOIN RTE %d",
curinputvarno, rt_index);
curinputrte = rt_fetch(curinputvarno,
parsetree->rtable);
}
if (get_rte_attribute_is_dropped(curinputrte,
aliasvar->varattno))
{
/*
* can't use vartype here, since that might be a
......@@ -386,7 +399,8 @@ rewriteRuleAction(Query *parsetree,
sub_action = (Query *) ResolveNew((Node *) sub_action,
new_varno,
0,
sub_action->rtable,
rt_fetch(new_varno,
sub_action->rtable),
parsetree->targetList,
event,
current_varno);
......@@ -1206,7 +1220,7 @@ CopyAndAddInvertedQual(Query *parsetree,
new_qual = ResolveNew(new_qual,
PRS2_NEW_VARNO,
0,
parsetree->rtable,
rt_fetch(rt_index, parsetree->rtable),
parsetree->targetList,
event,
rt_index);
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteManip.c,v 1.90 2005/03/10 23:21:24 tgl Exp $
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteManip.c,v 1.91 2005/06/04 19:19:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -797,10 +797,9 @@ AddInvertedQual(Query *parsetree, Node *qual)
* If not, we either change the unmatched Var's varno to update_varno
* (when event == CMD_UPDATE) or replace it with a constant NULL.
*
* The caller must also provide target_rtable, the rangetable containing
* the target relation (which must be described by the target_varno'th
* RTE in that list). This is needed to handle whole-row Vars referencing
* the target. We expand such Vars into RowExpr constructs.
* The caller must also provide target_rte, the RTE describing the target
* relation. This is needed to handle whole-row Vars referencing the target.
* We expand such Vars into RowExpr constructs.
*
* Note: the business with inserted_sublink is needed to update hasSubLinks
* in subqueries when the replacement adds a subquery inside a subquery.
......@@ -813,7 +812,7 @@ typedef struct
{
int target_varno;
int sublevels_up;
List *target_rtable;
RangeTblEntry *target_rte;
List *targetlist;
int event;
int update_varno;
......@@ -885,7 +884,8 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context)
* include dummy items for dropped columns. If the var is
* RECORD (ie, this is a JOIN), then omit dropped columns.
*/
expandRTE(context->target_rtable, this_varno, this_varlevelsup,
expandRTE(context->target_rte,
this_varno, this_varlevelsup,
(var->vartype != RECORDOID),
NULL, &fields);
/* Adjust the generated per-field Vars... */
......@@ -929,14 +929,14 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context)
Node *
ResolveNew(Node *node, int target_varno, int sublevels_up,
List *target_rtable,
RangeTblEntry *target_rte,
List *targetlist, int event, int update_varno)
{
ResolveNew_context context;
context.target_varno = target_varno;
context.sublevels_up = sublevels_up;
context.target_rtable = target_rtable;
context.target_rte = target_rte;
context.targetlist = targetlist;
context.event = event;
context.update_varno = update_varno;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/parser/parse_relation.h,v 1.49 2005/04/13 16:50:55 tgl Exp $
* $PostgreSQL: pgsql/src/include/parser/parse_relation.h,v 1.50 2005/06/04 19:19:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -30,7 +30,6 @@ extern int RTERangeTablePosn(ParseState *pstate,
extern RangeTblEntry *GetRTEByRangeTablePosn(ParseState *pstate,
int varno,
int sublevels_up);
extern List *GetLevelNRangeTable(ParseState *pstate, int sublevels_up);
extern Node *scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte,
char *colname);
extern Node *colNameToVar(ParseState *pstate, char *colname, bool localonly);
......@@ -67,10 +66,10 @@ extern RangeTblEntry *addRangeTableEntryForJoin(ParseState *pstate,
extern void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
bool addToJoinList, bool addToNameSpace);
extern RangeTblEntry *addImplicitRTE(ParseState *pstate, RangeVar *relation);
extern void expandRTE(List *rtable, int rtindex, int sublevels_up,
extern void expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
bool include_dropped,
List **colnames, List **colvars);
extern List *expandRelAttrs(ParseState *pstate, List *rtable,
extern List *expandRelAttrs(ParseState *pstate, RangeTblEntry *rte,
int rtindex, int sublevels_up);
extern int attnameAttNum(Relation rd, const char *attname, bool sysColOK);
extern Name attnumAttName(Relation rd, int attid);
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/rewrite/rewriteManip.h,v 1.40 2005/03/10 23:21:25 tgl Exp $
* $PostgreSQL: pgsql/src/include/rewrite/rewriteManip.h,v 1.41 2005/06/04 19:19:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -37,7 +37,7 @@ extern bool checkExprHasAggs(Node *node);
extern bool checkExprHasSubLink(Node *node);
extern Node *ResolveNew(Node *node, int target_varno, int sublevels_up,
List *target_rtable,
RangeTblEntry *target_rte,
List *targetlist, int event, int update_varno);
#endif /* REWRITEMANIP_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册