]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Change Agg and Group nodes so that Vars contained in their targetlists
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 22 Feb 2007 23:44:25 +0000 (23:44 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 22 Feb 2007 23:44:25 +0000 (23:44 +0000)
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.

src/backend/commands/explain.c
src/backend/executor/nodeAgg.c
src/backend/executor/nodeGroup.c
src/backend/executor/nodeResult.c
src/backend/optimizer/plan/setrefs.c
src/backend/utils/adt/ruleutils.c

index 34784eb078e8d47306d0ea21247b729df52ca7bb..6a97b01ec3c43cf37b789ad1a214ef0cf20ea51c 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994-5, Regents of the University of California
  *
  * 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,
                           int scanrelid, Plan *outer_plan,
                           StringInfo str, int indent, ExplainState *es);
 static void show_upper_qual(List *qual, const char *qlabel,
-                               const char *outer_name, int outer_varno, Plan *outer_plan,
-                               const char *inner_name, int inner_varno, Plan *inner_plan,
+                               const char *outer_name, Plan *outer_plan,
+                               const char *inner_name, Plan *inner_plan,
                                StringInfo str, int indent, ExplainState *es);
 static void show_sort_keys(Plan *sortplan, int nkeys, AttrNumber *keycols,
                           const char *qlabel,
@@ -783,55 +783,55 @@ explain_outNode(StringInfo str,
                case T_NestLoop:
                        show_upper_qual(((NestLoop *) plan)->join.joinqual,
                                                        "Join Filter",
-                                                       "outer", OUTER, outerPlan(plan),
-                                                       "inner", INNER, innerPlan(plan),
+                                                       "outer", outerPlan(plan),
+                                                       "inner", innerPlan(plan),
                                                        str, indent, es);
                        show_upper_qual(plan->qual,
                                                        "Filter",
-                                                       "outer", OUTER, outerPlan(plan),
-                                                       "inner", INNER, innerPlan(plan),
+                                                       "outer", outerPlan(plan),
+                                                       "inner", innerPlan(plan),
                                                        str, indent, es);
                        break;
                case T_MergeJoin:
                        show_upper_qual(((MergeJoin *) plan)->mergeclauses,
                                                        "Merge Cond",
-                                                       "outer", OUTER, outerPlan(plan),
-                                                       "inner", INNER, innerPlan(plan),
+                                                       "outer", outerPlan(plan),
+                                                       "inner", innerPlan(plan),
                                                        str, indent, es);
                        show_upper_qual(((MergeJoin *) plan)->join.joinqual,
                                                        "Join Filter",
-                                                       "outer", OUTER, outerPlan(plan),
-                                                       "inner", INNER, innerPlan(plan),
+                                                       "outer", outerPlan(plan),
+                                                       "inner", innerPlan(plan),
                                                        str, indent, es);
                        show_upper_qual(plan->qual,
                                                        "Filter",
-                                                       "outer", OUTER, outerPlan(plan),
-                                                       "inner", INNER, innerPlan(plan),
+                                                       "outer", outerPlan(plan),
+                                                       "inner", innerPlan(plan),
                                                        str, indent, es);
                        break;
                case T_HashJoin:
                        show_upper_qual(((HashJoin *) plan)->hashclauses,
                                                        "Hash Cond",
-                                                       "outer", OUTER, outerPlan(plan),
-                                                       "inner", INNER, innerPlan(plan),
+                                                       "outer", outerPlan(plan),
+                                                       "inner", innerPlan(plan),
                                                        str, indent, es);
                        show_upper_qual(((HashJoin *) plan)->join.joinqual,
                                                        "Join Filter",
-                                                       "outer", OUTER, outerPlan(plan),
-                                                       "inner", INNER, innerPlan(plan),
+                                                       "outer", outerPlan(plan),
+                                                       "inner", innerPlan(plan),
                                                        str, indent, es);
                        show_upper_qual(plan->qual,
                                                        "Filter",
-                                                       "outer", OUTER, outerPlan(plan),
-                                                       "inner", INNER, innerPlan(plan),
+                                                       "outer", outerPlan(plan),
+                                                       "inner", innerPlan(plan),
                                                        str, indent, es);
                        break;
                case T_Agg:
                case T_Group:
                        show_upper_qual(plan->qual,
                                                        "Filter",
-                                                       "subplan", 0, outerPlan(plan),
-                                                       "", 0, NULL,
+                                                       "subplan", outerPlan(plan),
+                                                       "", NULL,
                                                        str, indent, es);
                        break;
                case T_Sort:
@@ -844,13 +844,13 @@ explain_outNode(StringInfo str,
                case T_Result:
                        show_upper_qual((List *) ((Result *) plan)->resconstantqual,
                                                        "One-Time Filter",
-                                                       "subplan", OUTER, outerPlan(plan),
-                                                       "", 0, NULL,
+                                                       "subplan", outerPlan(plan),
+                                                       "", NULL,
                                                        str, indent, es);
                        show_upper_qual(plan->qual,
                                                        "Filter",
-                                                       "subplan", OUTER, outerPlan(plan),
-                                                       "", 0, NULL,
+                                                       "subplan", outerPlan(plan),
+                                                       "", NULL,
                                                        str, indent, es);
                        break;
                default:
@@ -1088,13 +1088,15 @@ show_scan_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 *inner_name, int inner_varno, Plan *inner_plan,
+                               const char *outer_name, Plan *outer_plan,
+                               const char *inner_name, Plan *inner_plan,
                                StringInfo str, int indent, ExplainState *es)
 {
        List       *context;
        Node       *outercontext;
        Node       *innercontext;
+       int                     outer_varno;
+       int                     inner_varno;
        Node       *node;
        char       *exprstr;
        int                     i;
@@ -1105,15 +1107,27 @@ show_upper_qual(List *qual, const char *qlabel,
 
        /* Generate deparse context */
        if (outer_plan)
+       {
                outercontext = deparse_context_for_subplan(outer_name,
                                                                                                   (Node *) outer_plan);
+               outer_varno = OUTER;
+       }
        else
+       {
                outercontext = NULL;
+               outer_varno = 0;
+       }
        if (inner_plan)
+       {
                innercontext = deparse_context_for_subplan(inner_name,
                                                                                                   (Node *) inner_plan);
+               inner_varno = INNER;
+       }
        else
+       {
                innercontext = NULL;
+               inner_varno = 0;
+       }
        context = deparse_context_for_plan(outer_varno, outercontext,
                                                                           inner_varno, innercontext,
                                                                           es->rtable);
index f6ee9b275e716e3fb2fa9574973e8531f502ec2a..58e59c60c5a7aeef5851ec8b5475e41c03ceede2 100644 (file)
@@ -61,7 +61,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * 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,
 
 /*
  * 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
  * (this might be in a hashtable entry).
  *
@@ -643,8 +643,8 @@ find_unaggregated_cols_walker(Node *node, Bitmapset **colnos)
        {
                Var                *var = (Var *) node;
 
-               /* setrefs.c should have set the varno to 0 */
-               Assert(var->varno == 0);
+               /* setrefs.c should have set the varno to OUTER */
+               Assert(var->varno == OUTER);
                Assert(var->varlevelsup == 0);
                *colnos = bms_add_member(*colnos, var->varattno);
                return false;
@@ -905,7 +905,7 @@ agg_retrieve_direct(AggState *aggstate)
                        aggstate->grp_firstTuple = NULL;        /* don't keep two pointers */
 
                        /* 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,
@@ -926,7 +926,7 @@ agg_retrieve_direct(AggState *aggstate)
                                        break;
                                }
                                /* 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
@@ -973,7 +973,7 @@ agg_retrieve_direct(AggState *aggstate)
                 * with an empty firstSlot ... but if not grouping, there can't be any
                 * 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
@@ -1022,7 +1022,7 @@ agg_fill_hash_table(AggState *aggstate)
                if (TupIsNull(outerslot))
                        break;
                /* set up for advance_aggregates call */
-               tmpcontext->ecxt_scantuple = outerslot;
+               tmpcontext->ecxt_outertuple = outerslot;
 
                /* Find or build hashtable entry for this tuple's group */
                entry = lookup_hash_entry(aggstate, outerslot);
@@ -1116,7 +1116,7 @@ agg_retrieve_hash_table(AggState *aggstate)
                 * Use the representative input tuple for any references to
                 * 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
index 0b636aa01e4e7298c3650b1546f68754e665f6d3..ce03f94e2e56276cfab60d91ef84895abd4e4b71 100644 (file)
@@ -15,7 +15,7 @@
  *       locate group boundaries.
  *
  * 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)
                        node->grp_done = TRUE;
                        return NULL;
                }
-               /* Copy tuple, set up as input for qual test and projection */
+               /* Copy tuple into firsttupleslot */
                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
@@ -126,7 +131,7 @@ ExecGroup(GroupState *node)
                 */
                /* Copy tuple, set up as input for qual test and projection */
                ExecCopySlot(firsttupleslot, outerslot);
-               econtext->ecxt_scantuple = firsttupleslot;
+               econtext->ecxt_outertuple = firsttupleslot;
 
                /*
                 * Check the qual (HAVING clause); if the group does not match, ignore
index 98e9d219727c702628ef3242081a0cf345177b97..5ea5132dd22ccd49054bda8ac626021ec7b011e4 100644 (file)
@@ -38,7 +38,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * 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)
                        if (TupIsNull(outerTupleSlot))
                                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_scantuple = outerTupleSlot;
                }
                else
                {
index aaa383742e7bdb2b798f72920a934aaec2176dff..5240a7283b2ff41befd4b5cf5f00c3044c3a0fd2 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * 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
 typedef struct
 {
        indexed_tlist *subplan_itlist;
-       Index           subvarno;
        int                     rtoffset;
 } fix_upper_expr_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_inner_join_references(Plan *inner_plan,
                                                  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 Var *search_indexed_tlist_for_var(Var *var,
                                                         indexed_tlist *itlist,
@@ -90,7 +89,6 @@ static Node *fix_join_expr_mutator(Node *node,
                                                                   fix_join_expr_context *context);
 static Node *fix_upper_expr(Node *node,
                                                        indexed_tlist *subplan_itlist,
-                                                       Index subvarno,
                                                        int rtoffset);
 static Node *fix_upper_expr_mutator(Node *node,
                                                                        fix_upper_expr_context *context);
@@ -345,7 +343,7 @@ set_plan_refs(PlannerGlobal *glob, Plan *plan, int rtoffset)
                        break;
                case T_Agg:
                case T_Group:
-                       set_upper_references(plan, (Index) 0, rtoffset);
+                       set_upper_references(plan, rtoffset);
                        break;
                case T_Result:
                        {
@@ -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
                                 * like a scan node than an upper node.
-                                *
-                                * XXX why does Result use a different subvarno from Agg/Group?
                                 */
                                if (splan->plan.lefttree != NULL)
-                                       set_upper_references(plan, (Index) OUTER, rtoffset);
+                                       set_upper_references(plan, rtoffset);
                                else
                                {
                                        splan->plan.targetlist =
@@ -889,7 +885,7 @@ set_inner_join_references(Plan *inner_plan, indexed_tlist *outer_itlist)
  * the expression.
  */
 static void
-set_upper_references(Plan *plan, Index subvarno, int rtoffset)
+set_upper_references(Plan *plan, int rtoffset)
 {
        Plan       *subplan = plan->lefttree;
        indexed_tlist *subplan_itlist;
@@ -909,7 +905,6 @@ set_upper_references(Plan *plan, Index subvarno, int rtoffset)
 
                newexpr = fix_upper_expr((Node *) tle->expr,
                                                                 subplan_itlist,
-                                                                subvarno,
                                                                 rtoffset);
                tle = flatCopyTargetEntry(tle);
                tle->expr = (Expr *) newexpr;
@@ -920,7 +915,6 @@ set_upper_references(Plan *plan, Index subvarno, int rtoffset)
        plan->qual = (List *)
                fix_upper_expr((Node *) plan->qual,
                                           subplan_itlist,
-                                          subvarno,
                                           rtoffset);
 
        pfree(subplan_itlist);
@@ -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)
  * 'subplan_itlist': indexed target list for subplan
- * 'subvarno': varno to be assigned to all Vars
  * 'rtoffset': how much to increment varnoold by
  *
  * 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.
  */
 static Node *
 fix_upper_expr(Node *node,
                           indexed_tlist *subplan_itlist,
-                          Index subvarno,
                           int rtoffset)
 {
        fix_upper_expr_context context;
 
        context.subplan_itlist = subplan_itlist;
-       context.subvarno = subvarno;
        context.rtoffset = rtoffset;
        return fix_upper_expr_mutator(node, &context);
 }
@@ -1267,7 +1258,7 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context)
 
                newvar = search_indexed_tlist_for_var(var,
                                                                                          context->subplan_itlist,
-                                                                                         context->subvarno,
+                                                                                         OUTER,
                                                                                          context->rtoffset);
                if (!newvar)
                        elog(ERROR, "variable not found in subplan target list");
@@ -1278,7 +1269,7 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context)
        {
                newvar = search_indexed_tlist_for_non_var(node,
                                                                                                  context->subplan_itlist,
-                                                                                                 context->subvarno);
+                                                                                                 OUTER);
                if (newvar)
                        return (Node *) newvar;
        }
index 064b8e07f76b3c233b053b620bfcd23307b2fb97..2f61b4a9fc57faec2d246b67c4f9bfd8573d5dfe 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * 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,
 
        /*
         * 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
         * subplan, varnoold will be 0, and we fall back to looking at the special
         * subplan RTEs.