Commit cc77005d authored by Tom Lane's avatar Tom Lane

Change Agg and Group nodes so that Vars contained in their targetlists

and quals have varno OUTER, rather than zero, to indicate a reference to
an output of their lefttree subplan.  This is consistent with the way
that every other upper-level node type does it, and allows some simplifications
in setrefs.c and EXPLAIN.
parent 3c5985b4
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994-5, Regents of the University of California * Portions Copyright (c) 1994-5, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.157 2007/02/22 22:00:22 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.158 2007/02/22 23:44:24 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -52,8 +52,8 @@ static void show_scan_qual(List *qual, const char *qlabel, ...@@ -52,8 +52,8 @@ static void show_scan_qual(List *qual, const char *qlabel,
int scanrelid, Plan *outer_plan, int scanrelid, Plan *outer_plan,
StringInfo str, int indent, ExplainState *es); StringInfo str, int indent, ExplainState *es);
static void show_upper_qual(List *qual, const char *qlabel, static void show_upper_qual(List *qual, const char *qlabel,
const char *outer_name, int outer_varno, Plan *outer_plan, const char *outer_name, Plan *outer_plan,
const char *inner_name, int inner_varno, Plan *inner_plan, const char *inner_name, Plan *inner_plan,
StringInfo str, int indent, ExplainState *es); StringInfo str, int indent, ExplainState *es);
static void show_sort_keys(Plan *sortplan, int nkeys, AttrNumber *keycols, static void show_sort_keys(Plan *sortplan, int nkeys, AttrNumber *keycols,
const char *qlabel, const char *qlabel,
...@@ -783,55 +783,55 @@ explain_outNode(StringInfo str, ...@@ -783,55 +783,55 @@ explain_outNode(StringInfo str,
case T_NestLoop: case T_NestLoop:
show_upper_qual(((NestLoop *) plan)->join.joinqual, show_upper_qual(((NestLoop *) plan)->join.joinqual,
"Join Filter", "Join Filter",
"outer", OUTER, outerPlan(plan), "outer", outerPlan(plan),
"inner", INNER, innerPlan(plan), "inner", innerPlan(plan),
str, indent, es); str, indent, es);
show_upper_qual(plan->qual, show_upper_qual(plan->qual,
"Filter", "Filter",
"outer", OUTER, outerPlan(plan), "outer", outerPlan(plan),
"inner", INNER, innerPlan(plan), "inner", innerPlan(plan),
str, indent, es); str, indent, es);
break; break;
case T_MergeJoin: case T_MergeJoin:
show_upper_qual(((MergeJoin *) plan)->mergeclauses, show_upper_qual(((MergeJoin *) plan)->mergeclauses,
"Merge Cond", "Merge Cond",
"outer", OUTER, outerPlan(plan), "outer", outerPlan(plan),
"inner", INNER, innerPlan(plan), "inner", innerPlan(plan),
str, indent, es); str, indent, es);
show_upper_qual(((MergeJoin *) plan)->join.joinqual, show_upper_qual(((MergeJoin *) plan)->join.joinqual,
"Join Filter", "Join Filter",
"outer", OUTER, outerPlan(plan), "outer", outerPlan(plan),
"inner", INNER, innerPlan(plan), "inner", innerPlan(plan),
str, indent, es); str, indent, es);
show_upper_qual(plan->qual, show_upper_qual(plan->qual,
"Filter", "Filter",
"outer", OUTER, outerPlan(plan), "outer", outerPlan(plan),
"inner", INNER, innerPlan(plan), "inner", innerPlan(plan),
str, indent, es); str, indent, es);
break; break;
case T_HashJoin: case T_HashJoin:
show_upper_qual(((HashJoin *) plan)->hashclauses, show_upper_qual(((HashJoin *) plan)->hashclauses,
"Hash Cond", "Hash Cond",
"outer", OUTER, outerPlan(plan), "outer", outerPlan(plan),
"inner", INNER, innerPlan(plan), "inner", innerPlan(plan),
str, indent, es); str, indent, es);
show_upper_qual(((HashJoin *) plan)->join.joinqual, show_upper_qual(((HashJoin *) plan)->join.joinqual,
"Join Filter", "Join Filter",
"outer", OUTER, outerPlan(plan), "outer", outerPlan(plan),
"inner", INNER, innerPlan(plan), "inner", innerPlan(plan),
str, indent, es); str, indent, es);
show_upper_qual(plan->qual, show_upper_qual(plan->qual,
"Filter", "Filter",
"outer", OUTER, outerPlan(plan), "outer", outerPlan(plan),
"inner", INNER, innerPlan(plan), "inner", innerPlan(plan),
str, indent, es); str, indent, es);
break; break;
case T_Agg: case T_Agg:
case T_Group: case T_Group:
show_upper_qual(plan->qual, show_upper_qual(plan->qual,
"Filter", "Filter",
"subplan", 0, outerPlan(plan), "subplan", outerPlan(plan),
"", 0, NULL, "", NULL,
str, indent, es); str, indent, es);
break; break;
case T_Sort: case T_Sort:
...@@ -844,13 +844,13 @@ explain_outNode(StringInfo str, ...@@ -844,13 +844,13 @@ explain_outNode(StringInfo str,
case T_Result: case T_Result:
show_upper_qual((List *) ((Result *) plan)->resconstantqual, show_upper_qual((List *) ((Result *) plan)->resconstantqual,
"One-Time Filter", "One-Time Filter",
"subplan", OUTER, outerPlan(plan), "subplan", outerPlan(plan),
"", 0, NULL, "", NULL,
str, indent, es); str, indent, es);
show_upper_qual(plan->qual, show_upper_qual(plan->qual,
"Filter", "Filter",
"subplan", OUTER, outerPlan(plan), "subplan", outerPlan(plan),
"", 0, NULL, "", NULL,
str, indent, es); str, indent, es);
break; break;
default: default:
...@@ -1088,13 +1088,15 @@ show_scan_qual(List *qual, const char *qlabel, ...@@ -1088,13 +1088,15 @@ show_scan_qual(List *qual, const char *qlabel,
*/ */
static void static void
show_upper_qual(List *qual, const char *qlabel, show_upper_qual(List *qual, const char *qlabel,
const char *outer_name, int outer_varno, Plan *outer_plan, const char *outer_name, Plan *outer_plan,
const char *inner_name, int inner_varno, Plan *inner_plan, const char *inner_name, Plan *inner_plan,
StringInfo str, int indent, ExplainState *es) StringInfo str, int indent, ExplainState *es)
{ {
List *context; List *context;
Node *outercontext; Node *outercontext;
Node *innercontext; Node *innercontext;
int outer_varno;
int inner_varno;
Node *node; Node *node;
char *exprstr; char *exprstr;
int i; int i;
...@@ -1105,15 +1107,27 @@ show_upper_qual(List *qual, const char *qlabel, ...@@ -1105,15 +1107,27 @@ show_upper_qual(List *qual, const char *qlabel,
/* Generate deparse context */ /* Generate deparse context */
if (outer_plan) if (outer_plan)
{
outercontext = deparse_context_for_subplan(outer_name, outercontext = deparse_context_for_subplan(outer_name,
(Node *) outer_plan); (Node *) outer_plan);
outer_varno = OUTER;
}
else else
{
outercontext = NULL; outercontext = NULL;
outer_varno = 0;
}
if (inner_plan) if (inner_plan)
{
innercontext = deparse_context_for_subplan(inner_name, innercontext = deparse_context_for_subplan(inner_name,
(Node *) inner_plan); (Node *) inner_plan);
inner_varno = INNER;
}
else else
{
innercontext = NULL; innercontext = NULL;
inner_varno = 0;
}
context = deparse_context_for_plan(outer_varno, outercontext, context = deparse_context_for_plan(outer_varno, outercontext,
inner_varno, innercontext, inner_varno, innercontext,
es->rtable); es->rtable);
......
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.150 2007/02/02 00:07:03 tgl Exp $ * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.151 2007/02/22 23:44:24 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -420,7 +420,7 @@ advance_transition_function(AggState *aggstate, ...@@ -420,7 +420,7 @@ advance_transition_function(AggState *aggstate,
/* /*
* Advance all the aggregates for one input tuple. The input tuple * Advance all the aggregates for one input tuple. The input tuple
* has been stored in tmpcontext->ecxt_scantuple, so that it is accessible * has been stored in tmpcontext->ecxt_outertuple, so that it is accessible
* to ExecEvalExpr. pergroup is the array of per-group structs to use * to ExecEvalExpr. pergroup is the array of per-group structs to use
* (this might be in a hashtable entry). * (this might be in a hashtable entry).
* *
...@@ -643,8 +643,8 @@ find_unaggregated_cols_walker(Node *node, Bitmapset **colnos) ...@@ -643,8 +643,8 @@ find_unaggregated_cols_walker(Node *node, Bitmapset **colnos)
{ {
Var *var = (Var *) node; Var *var = (Var *) node;
/* setrefs.c should have set the varno to 0 */ /* setrefs.c should have set the varno to OUTER */
Assert(var->varno == 0); Assert(var->varno == OUTER);
Assert(var->varlevelsup == 0); Assert(var->varlevelsup == 0);
*colnos = bms_add_member(*colnos, var->varattno); *colnos = bms_add_member(*colnos, var->varattno);
return false; return false;
...@@ -905,7 +905,7 @@ agg_retrieve_direct(AggState *aggstate) ...@@ -905,7 +905,7 @@ agg_retrieve_direct(AggState *aggstate)
aggstate->grp_firstTuple = NULL; /* don't keep two pointers */ aggstate->grp_firstTuple = NULL; /* don't keep two pointers */
/* set up for first advance_aggregates call */ /* set up for first advance_aggregates call */
tmpcontext->ecxt_scantuple = firstSlot; tmpcontext->ecxt_outertuple = firstSlot;
/* /*
* Process each outer-plan tuple, and then fetch the next one, * Process each outer-plan tuple, and then fetch the next one,
...@@ -926,7 +926,7 @@ agg_retrieve_direct(AggState *aggstate) ...@@ -926,7 +926,7 @@ agg_retrieve_direct(AggState *aggstate)
break; break;
} }
/* set up for next advance_aggregates call */ /* set up for next advance_aggregates call */
tmpcontext->ecxt_scantuple = outerslot; tmpcontext->ecxt_outertuple = outerslot;
/* /*
* If we are grouping, check whether we've crossed a group * If we are grouping, check whether we've crossed a group
...@@ -973,7 +973,7 @@ agg_retrieve_direct(AggState *aggstate) ...@@ -973,7 +973,7 @@ agg_retrieve_direct(AggState *aggstate)
* with an empty firstSlot ... but if not grouping, there can't be any * with an empty firstSlot ... but if not grouping, there can't be any
* references to non-aggregated input columns, so no problem.) * references to non-aggregated input columns, so no problem.)
*/ */
econtext->ecxt_scantuple = firstSlot; econtext->ecxt_outertuple = firstSlot;
/* /*
* Check the qual (HAVING clause); if the group does not match, ignore * Check the qual (HAVING clause); if the group does not match, ignore
...@@ -1022,7 +1022,7 @@ agg_fill_hash_table(AggState *aggstate) ...@@ -1022,7 +1022,7 @@ agg_fill_hash_table(AggState *aggstate)
if (TupIsNull(outerslot)) if (TupIsNull(outerslot))
break; break;
/* set up for advance_aggregates call */ /* set up for advance_aggregates call */
tmpcontext->ecxt_scantuple = outerslot; tmpcontext->ecxt_outertuple = outerslot;
/* Find or build hashtable entry for this tuple's group */ /* Find or build hashtable entry for this tuple's group */
entry = lookup_hash_entry(aggstate, outerslot); entry = lookup_hash_entry(aggstate, outerslot);
...@@ -1116,7 +1116,7 @@ agg_retrieve_hash_table(AggState *aggstate) ...@@ -1116,7 +1116,7 @@ agg_retrieve_hash_table(AggState *aggstate)
* Use the representative input tuple for any references to * Use the representative input tuple for any references to
* non-aggregated input columns in the qual and tlist. * non-aggregated input columns in the qual and tlist.
*/ */
econtext->ecxt_scantuple = firstSlot; econtext->ecxt_outertuple = firstSlot;
/* /*
* Check the qual (HAVING clause); if the group does not match, ignore * Check the qual (HAVING clause); if the group does not match, ignore
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* locate group boundaries. * locate group boundaries.
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/nodeGroup.c,v 1.68 2007/02/02 00:07:03 tgl Exp $ * $PostgreSQL: pgsql/src/backend/executor/nodeGroup.c,v 1.69 2007/02/22 23:44:24 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -72,9 +72,14 @@ ExecGroup(GroupState *node) ...@@ -72,9 +72,14 @@ ExecGroup(GroupState *node)
node->grp_done = TRUE; node->grp_done = TRUE;
return NULL; return NULL;
} }
/* Copy tuple, set up as input for qual test and projection */ /* Copy tuple into firsttupleslot */
ExecCopySlot(firsttupleslot, outerslot); ExecCopySlot(firsttupleslot, outerslot);
econtext->ecxt_scantuple = firsttupleslot;
/*
* Set it up as input for qual test and projection. The expressions
* will access the input tuple as varno OUTER.
*/
econtext->ecxt_outertuple = firsttupleslot;
/* /*
* Check the qual (HAVING clause); if the group does not match, ignore * Check the qual (HAVING clause); if the group does not match, ignore
...@@ -126,7 +131,7 @@ ExecGroup(GroupState *node) ...@@ -126,7 +131,7 @@ ExecGroup(GroupState *node)
*/ */
/* Copy tuple, set up as input for qual test and projection */ /* Copy tuple, set up as input for qual test and projection */
ExecCopySlot(firsttupleslot, outerslot); ExecCopySlot(firsttupleslot, outerslot);
econtext->ecxt_scantuple = firsttupleslot; econtext->ecxt_outertuple = firsttupleslot;
/* /*
* Check the qual (HAVING clause); if the group does not match, ignore * Check the qual (HAVING clause); if the group does not match, ignore
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/nodeResult.c,v 1.39 2007/02/16 03:49:04 tgl Exp $ * $PostgreSQL: pgsql/src/backend/executor/nodeResult.c,v 1.40 2007/02/22 23:44:25 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -132,13 +132,11 @@ ExecResult(ResultState *node) ...@@ -132,13 +132,11 @@ ExecResult(ResultState *node)
if (TupIsNull(outerTupleSlot)) if (TupIsNull(outerTupleSlot))
return NULL; return NULL;
node->ps.ps_OuterTupleSlot = outerTupleSlot;
/* /*
* XXX gross hack. use outer tuple as scan tuple for projection * prepare to compute projection expressions, which will expect
* to access the input tuples as varno OUTER.
*/ */
econtext->ecxt_outertuple = outerTupleSlot; econtext->ecxt_outertuple = outerTupleSlot;
econtext->ecxt_scantuple = outerTupleSlot;
} }
else else
{ {
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.131 2007/02/22 22:00:24 tgl Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.132 2007/02/22 23:44:25 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -56,7 +56,6 @@ typedef struct ...@@ -56,7 +56,6 @@ typedef struct
typedef struct typedef struct
{ {
indexed_tlist *subplan_itlist; indexed_tlist *subplan_itlist;
Index subvarno;
int rtoffset; int rtoffset;
} fix_upper_expr_context; } fix_upper_expr_context;
...@@ -73,7 +72,7 @@ static Node *fix_scan_expr_mutator(Node *node, fix_scan_expr_context *context); ...@@ -73,7 +72,7 @@ static Node *fix_scan_expr_mutator(Node *node, fix_scan_expr_context *context);
static void set_join_references(Join *join, int rtoffset); static void set_join_references(Join *join, int rtoffset);
static void set_inner_join_references(Plan *inner_plan, static void set_inner_join_references(Plan *inner_plan,
indexed_tlist *outer_itlist); indexed_tlist *outer_itlist);
static void set_upper_references(Plan *plan, Index subvarno, int rtoffset); static void set_upper_references(Plan *plan, int rtoffset);
static indexed_tlist *build_tlist_index(List *tlist); static indexed_tlist *build_tlist_index(List *tlist);
static Var *search_indexed_tlist_for_var(Var *var, static Var *search_indexed_tlist_for_var(Var *var,
indexed_tlist *itlist, indexed_tlist *itlist,
...@@ -90,7 +89,6 @@ static Node *fix_join_expr_mutator(Node *node, ...@@ -90,7 +89,6 @@ static Node *fix_join_expr_mutator(Node *node,
fix_join_expr_context *context); fix_join_expr_context *context);
static Node *fix_upper_expr(Node *node, static Node *fix_upper_expr(Node *node,
indexed_tlist *subplan_itlist, indexed_tlist *subplan_itlist,
Index subvarno,
int rtoffset); int rtoffset);
static Node *fix_upper_expr_mutator(Node *node, static Node *fix_upper_expr_mutator(Node *node,
fix_upper_expr_context *context); fix_upper_expr_context *context);
...@@ -345,7 +343,7 @@ set_plan_refs(PlannerGlobal *glob, Plan *plan, int rtoffset) ...@@ -345,7 +343,7 @@ set_plan_refs(PlannerGlobal *glob, Plan *plan, int rtoffset)
break; break;
case T_Agg: case T_Agg:
case T_Group: case T_Group:
set_upper_references(plan, (Index) 0, rtoffset); set_upper_references(plan, rtoffset);
break; break;
case T_Result: case T_Result:
{ {
...@@ -354,11 +352,9 @@ set_plan_refs(PlannerGlobal *glob, Plan *plan, int rtoffset) ...@@ -354,11 +352,9 @@ set_plan_refs(PlannerGlobal *glob, Plan *plan, int rtoffset)
/* /*
* Result may or may not have a subplan; if not, it's more * Result may or may not have a subplan; if not, it's more
* like a scan node than an upper node. * like a scan node than an upper node.
*
* XXX why does Result use a different subvarno from Agg/Group?
*/ */
if (splan->plan.lefttree != NULL) if (splan->plan.lefttree != NULL)
set_upper_references(plan, (Index) OUTER, rtoffset); set_upper_references(plan, rtoffset);
else else
{ {
splan->plan.targetlist = splan->plan.targetlist =
...@@ -889,7 +885,7 @@ set_inner_join_references(Plan *inner_plan, indexed_tlist *outer_itlist) ...@@ -889,7 +885,7 @@ set_inner_join_references(Plan *inner_plan, indexed_tlist *outer_itlist)
* the expression. * the expression.
*/ */
static void static void
set_upper_references(Plan *plan, Index subvarno, int rtoffset) set_upper_references(Plan *plan, int rtoffset)
{ {
Plan *subplan = plan->lefttree; Plan *subplan = plan->lefttree;
indexed_tlist *subplan_itlist; indexed_tlist *subplan_itlist;
...@@ -909,7 +905,6 @@ set_upper_references(Plan *plan, Index subvarno, int rtoffset) ...@@ -909,7 +905,6 @@ set_upper_references(Plan *plan, Index subvarno, int rtoffset)
newexpr = fix_upper_expr((Node *) tle->expr, newexpr = fix_upper_expr((Node *) tle->expr,
subplan_itlist, subplan_itlist,
subvarno,
rtoffset); rtoffset);
tle = flatCopyTargetEntry(tle); tle = flatCopyTargetEntry(tle);
tle->expr = (Expr *) newexpr; tle->expr = (Expr *) newexpr;
...@@ -920,7 +915,6 @@ set_upper_references(Plan *plan, Index subvarno, int rtoffset) ...@@ -920,7 +915,6 @@ set_upper_references(Plan *plan, Index subvarno, int rtoffset)
plan->qual = (List *) plan->qual = (List *)
fix_upper_expr((Node *) plan->qual, fix_upper_expr((Node *) plan->qual,
subplan_itlist, subplan_itlist,
subvarno,
rtoffset); rtoffset);
pfree(subplan_itlist); pfree(subplan_itlist);
...@@ -1233,23 +1227,20 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context) ...@@ -1233,23 +1227,20 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context)
* *
* 'node': the tree to be fixed (a target item or qual) * 'node': the tree to be fixed (a target item or qual)
* 'subplan_itlist': indexed target list for subplan * 'subplan_itlist': indexed target list for subplan
* 'subvarno': varno to be assigned to all Vars
* 'rtoffset': how much to increment varnoold by * 'rtoffset': how much to increment varnoold by
* *
* The resulting tree is a copy of the original in which all Var nodes have * The resulting tree is a copy of the original in which all Var nodes have
* varno = subvarno, varattno = resno of corresponding subplan target. * varno = OUTER, varattno = resno of corresponding subplan target.
* The original tree is not modified. * The original tree is not modified.
*/ */
static Node * static Node *
fix_upper_expr(Node *node, fix_upper_expr(Node *node,
indexed_tlist *subplan_itlist, indexed_tlist *subplan_itlist,
Index subvarno,
int rtoffset) int rtoffset)
{ {
fix_upper_expr_context context; fix_upper_expr_context context;
context.subplan_itlist = subplan_itlist; context.subplan_itlist = subplan_itlist;
context.subvarno = subvarno;
context.rtoffset = rtoffset; context.rtoffset = rtoffset;
return fix_upper_expr_mutator(node, &context); return fix_upper_expr_mutator(node, &context);
} }
...@@ -1267,7 +1258,7 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context) ...@@ -1267,7 +1258,7 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context)
newvar = search_indexed_tlist_for_var(var, newvar = search_indexed_tlist_for_var(var,
context->subplan_itlist, context->subplan_itlist,
context->subvarno, OUTER,
context->rtoffset); context->rtoffset);
if (!newvar) if (!newvar)
elog(ERROR, "variable not found in subplan target list"); elog(ERROR, "variable not found in subplan target list");
...@@ -1278,7 +1269,7 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context) ...@@ -1278,7 +1269,7 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context)
{ {
newvar = search_indexed_tlist_for_non_var(node, newvar = search_indexed_tlist_for_non_var(node,
context->subplan_itlist, context->subplan_itlist,
context->subvarno); OUTER);
if (newvar) if (newvar)
return (Node *) newvar; return (Node *) newvar;
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.249 2007/02/14 01:58:57 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.250 2007/02/22 23:44:25 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2626,7 +2626,7 @@ get_rte_for_var(Var *var, int levelsup, deparse_context *context, ...@@ -2626,7 +2626,7 @@ get_rte_for_var(Var *var, int levelsup, deparse_context *context,
/* /*
* Try to find the relevant RTE in this rtable. In a plan tree, it's * Try to find the relevant RTE in this rtable. In a plan tree, it's
* likely that varno is OUTER, INNER, or 0, in which case we try to use * likely that varno is OUTER or INNER, in which case we try to use
* varnoold instead. If the Var references an expression computed by a * varnoold instead. If the Var references an expression computed by a
* subplan, varnoold will be 0, and we fall back to looking at the special * subplan, varnoold will be 0, and we fall back to looking at the special
* subplan RTEs. * subplan RTEs.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment