Get rid of hashkeys field of Hash plan node, since it's redundant with
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 25 Nov 2003 21:00:54 +0000 (21:00 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 25 Nov 2003 21:00:54 +0000 (21:00 +0000)
the hashclauses field of the parent HashJoin.  This avoids problems with
duplicated links to SubPlans in hash clauses, as per report from
Andrew Holm-Hansen.

src/backend/executor/nodeHash.c
src/backend/executor/nodeHashjoin.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/outfuncs.c
src/backend/optimizer/plan/createplan.c
src/backend/optimizer/plan/setrefs.c
src/backend/optimizer/plan/subselect.c
src/include/nodes/plannodes.h

index b925517d7b1590951da71a5bc307bf678c61c0ea..6b13dab764529cae788b1a2426b3be634a20e5a4 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/nodeHash.c,v 1.79 2003/08/04 02:39:59 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/nodeHash.c,v 1.80 2003/11/25 21:00:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -113,6 +113,7 @@ ExecInitHash(Hash *node, EState *estate)
        hashstate->ps.plan = (Plan *) node;
        hashstate->ps.state = estate;
        hashstate->hashtable = NULL;
+       hashstate->hashkeys = NIL;      /* will be set by parent HashJoin */
 
        /*
         * Miscellaneous initialization
index 112155bdd376c77f79f07f6d63236876c45eb3ce..be0543ac61373b0d61405ecd5db8507f6c9bd1aa 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v 1.57 2003/09/25 06:57:59 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v 1.58 2003/11/25 21:00:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -308,7 +308,8 @@ ExecInitHashJoin(HashJoin *node, EState *estate)
        HashJoinState *hjstate;
        Plan       *outerNode;
        Hash       *hashNode;
-       List       *hclauses;
+       List       *lclauses;
+       List       *rclauses;
        List       *hoperators;
        List       *hcl;
 
@@ -410,31 +411,31 @@ ExecInitHashJoin(HashJoin *node, EState *estate)
        hjstate->hj_CurTuple = (HashJoinTuple) NULL;
 
        /*
-        * The planner already made a list of the inner hashkeys for us, but
-        * we also need a list of the outer hashkeys, as well as a list of the
-        * hash operator OIDs.  Both lists of exprs must then be prepared for
-        * execution.
+        * Deconstruct the hash clauses into outer and inner argument values,
+        * so that we can evaluate those subexpressions separately.  Also make
+        * a list of the hash operator OIDs, in preparation for looking up the
+        * hash functions to use.
         */
-       hjstate->hj_InnerHashKeys = (List *)
-               ExecInitExpr((Expr *) hashNode->hashkeys,
-                                        innerPlanState(hjstate));
-       ((HashState *) innerPlanState(hjstate))->hashkeys =
-               hjstate->hj_InnerHashKeys;
-
-       hclauses = NIL;
+       lclauses = NIL;
+       rclauses = NIL;
        hoperators = NIL;
-       foreach(hcl, node->hashclauses)
+       foreach(hcl, hjstate->hashclauses)
        {
-               OpExpr     *hclause = (OpExpr *) lfirst(hcl);
+               FuncExprState *fstate = (FuncExprState *) lfirst(hcl);
+               OpExpr     *hclause;
 
+               Assert(IsA(fstate, FuncExprState));
+               hclause = (OpExpr *) fstate->xprstate.expr;
                Assert(IsA(hclause, OpExpr));
-               hclauses = lappend(hclauses, get_leftop((Expr *) hclause));
+               lclauses = lappend(lclauses, lfirst(fstate->args));
+               rclauses = lappend(rclauses, lsecond(fstate->args));
                hoperators = lappendo(hoperators, hclause->opno);
        }
-       hjstate->hj_OuterHashKeys = (List *)
-               ExecInitExpr((Expr *) hclauses,
-                                        (PlanState *) hjstate);
+       hjstate->hj_OuterHashKeys = lclauses;
+       hjstate->hj_InnerHashKeys = rclauses;
        hjstate->hj_HashOperators = hoperators;
+       /* child Hash node needs to evaluate inner hash keys, too */
+       ((HashState *) innerPlanState(hjstate))->hashkeys = rclauses;
 
        hjstate->js.ps.ps_OuterTupleSlot = NULL;
        hjstate->js.ps.ps_TupFromTlist = false;
index 6cf8450567aa20e5567e64d996896d4b7502559a..54dc63654eb8ff923ebd47e2d75b9361830a9876 100644 (file)
@@ -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.267 2003/11/12 21:15:52 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.268 2003/11/25 21:00:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -551,7 +551,6 @@ _copyHash(Hash *from)
        /*
         * copy remainder of node
         */
-       COPY_NODE_FIELD(hashkeys);
 
        return newnode;
 }
index cb875bd6769c446da3ffaebb6cd1360573699d0f..b9dc382484e8e05be76c3cd7ad757195e7944bc0 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.220 2003/11/12 21:15:52 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.221 2003/11/25 21:00:53 tgl Exp $
  *
  * NOTES
  *       Every node type that can appear in stored rules' parsetrees *must*
@@ -531,8 +531,6 @@ _outHash(StringInfo str, Hash *node)
        WRITE_NODE_TYPE("HASH");
 
        _outPlanInfo(str, (Plan *) node);
-
-       WRITE_NODE_FIELD(hashkeys);
 }
 
 /*****************************************************************************
index a5efcb339e0a3f06f3efcd09e7b4affb2988a4c8..c455946ae38bebfacd7e85d0eb47602b2cb0efa1 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.159 2003/11/12 21:15:53 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.160 2003/11/25 21:00:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -97,7 +97,7 @@ static HashJoin *make_hashjoin(List *tlist,
                          List *hashclauses,
                          Plan *lefttree, Plan *righttree,
                          JoinType jointype);
-static Hash *make_hash(List *tlist, List *hashkeys, Plan *lefttree);
+static Hash *make_hash(List *tlist, Plan *lefttree);
 static MergeJoin *make_mergejoin(List *tlist,
                           List *joinclauses, List *otherclauses,
                           List *mergeclauses,
@@ -1067,8 +1067,6 @@ create_hashjoin_plan(Query *root,
        List       *hashclauses;
        HashJoin   *join_plan;
        Hash       *hash_plan;
-       List       *innerhashkeys;
-       List       *hcl;
 
        /* Get the join qual clauses (in plain expression form) */
        if (IS_OUTER_JOIN(best_path->jpath.jointype))
@@ -1102,14 +1100,6 @@ create_hashjoin_plan(Query *root,
        otherclauses = order_qual_clauses(root, otherclauses);
        hashclauses = order_qual_clauses(root, hashclauses);
 
-       /*
-        * Extract the inner hash keys (right-hand operands of the
-        * hashclauses) to put in the Hash node.
-        */
-       innerhashkeys = NIL;
-       foreach(hcl, hashclauses)
-               innerhashkeys = lappend(innerhashkeys, get_rightop(lfirst(hcl)));
-
        /* We don't want any excess columns in the hashed tuples */
        disuse_physical_tlist(inner_plan, best_path->jpath.innerjoinpath);
 
@@ -1117,7 +1107,6 @@ create_hashjoin_plan(Query *root,
         * Build the hash node and hash join node.
         */
        hash_plan = make_hash(inner_plan->targetlist,
-                                                 innerhashkeys,
                                                  inner_plan);
        join_plan = make_hashjoin(tlist,
                                                          joinclauses,
@@ -1728,7 +1717,7 @@ make_hashjoin(List *tlist,
 }
 
 static Hash *
-make_hash(List *tlist, List *hashkeys, Plan *lefttree)
+make_hash(List *tlist, Plan *lefttree)
 {
        Hash       *node = makeNode(Hash);
        Plan       *plan = &node->plan;
@@ -1744,7 +1733,6 @@ make_hash(List *tlist, List *hashkeys, Plan *lefttree)
        plan->qual = NIL;
        plan->lefttree = lefttree;
        plan->righttree = NULL;
-       node->hashkeys = hashkeys;
 
        return node;
 }
index ec21c1a8d3be5819b2a93d7fdde0d3c60071b843..2952e8f0773b08c0e10e1b76e3f4113a2d2a4f46 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.97 2003/08/08 21:41:50 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.98 2003/11/25 21:00:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -167,24 +167,6 @@ set_plan_references(Plan *plan, List *rtable)
                                                          (Node *) ((HashJoin *) plan)->hashclauses);
                        break;
                case T_Hash:
-
-                       /*
-                        * Hash does not evaluate its targetlist or quals, so don't
-                        * touch those (see comments below).  But we do need to fix
-                        * its hashkeys.  The hashkeys are a little bizarre because
-                        * they need to match the hashclauses of the parent HashJoin
-                        * node, so we use join_references to fix them.
-                        */
-                       ((Hash *) plan)->hashkeys =
-                               join_references(((Hash *) plan)->hashkeys,
-                                                               rtable,
-                                                               NIL,
-                                                               plan->lefttree->targetlist,
-                                                               (Index) 0,
-                                       targetlist_has_non_vars(plan->lefttree->targetlist));
-                       fix_expr_references(plan,
-                                                               (Node *) ((Hash *) plan)->hashkeys);
-                       break;
                case T_Material:
                case T_Sort:
                case T_Unique:
index 11612f408c9817446b0afc3593ef588abd989a16..dab4cf3233afe8ebd4fb5cf91f47cfc44d8b52fa 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.83 2003/10/18 16:52:15 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.84 2003/11/25 21:00:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1013,10 +1013,6 @@ finalize_plan(Plan *plan, List *rtable,
                        break;
 
                case T_Hash:
-                       finalize_primnode((Node *) ((Hash *) plan)->hashkeys,
-                                                         &context);
-                       break;
-
                case T_Agg:
                case T_SeqScan:
                case T_Material:
index 669ce93e70a51ed9d9d95df2cd42b5bfbde0d497..6513bf35105f45738707ab50587cbd70205e1138 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: plannodes.h,v 1.70 2003/11/12 21:15:59 tgl Exp $
+ * $Id: plannodes.h,v 1.71 2003/11/25 21:00:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -350,7 +350,7 @@ typedef struct Unique
 typedef struct Hash
 {
        Plan            plan;
-       List       *hashkeys;
+       /* all other info is in the parent HashJoin node */
 } Hash;
 
 /* ----------------