Get rid of hashkeys field of Hash plan node, since it's redundant with

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.
This commit is contained in:
Tom Lane 2003-11-25 21:00:54 +00:00
parent 38ba28e5c1
commit a64846f3ad
8 changed files with 31 additions and 66 deletions

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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.plan = (Plan *) node;
hashstate->ps.state = estate; hashstate->ps.state = estate;
hashstate->hashtable = NULL; hashstate->hashtable = NULL;
hashstate->hashkeys = NIL; /* will be set by parent HashJoin */
/* /*
* Miscellaneous initialization * Miscellaneous initialization

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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; HashJoinState *hjstate;
Plan *outerNode; Plan *outerNode;
Hash *hashNode; Hash *hashNode;
List *hclauses; List *lclauses;
List *rclauses;
List *hoperators; List *hoperators;
List *hcl; List *hcl;
@ -410,31 +411,31 @@ ExecInitHashJoin(HashJoin *node, EState *estate)
hjstate->hj_CurTuple = (HashJoinTuple) NULL; hjstate->hj_CurTuple = (HashJoinTuple) NULL;
/* /*
* The planner already made a list of the inner hashkeys for us, but * Deconstruct the hash clauses into outer and inner argument values,
* we also need a list of the outer hashkeys, as well as a list of the * so that we can evaluate those subexpressions separately. Also make
* hash operator OIDs. Both lists of exprs must then be prepared for * a list of the hash operator OIDs, in preparation for looking up the
* execution. * hash functions to use.
*/ */
hjstate->hj_InnerHashKeys = (List *) lclauses = NIL;
ExecInitExpr((Expr *) hashNode->hashkeys, rclauses = NIL;
innerPlanState(hjstate));
((HashState *) innerPlanState(hjstate))->hashkeys =
hjstate->hj_InnerHashKeys;
hclauses = NIL;
hoperators = 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)); 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); hoperators = lappendo(hoperators, hclause->opno);
} }
hjstate->hj_OuterHashKeys = (List *) hjstate->hj_OuterHashKeys = lclauses;
ExecInitExpr((Expr *) hclauses, hjstate->hj_InnerHashKeys = rclauses;
(PlanState *) hjstate);
hjstate->hj_HashOperators = hoperators; 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_OuterTupleSlot = NULL;
hjstate->js.ps.ps_TupFromTlist = false; hjstate->js.ps.ps_TupFromTlist = false;

View File

@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 remainder of node
*/ */
COPY_NODE_FIELD(hashkeys);
return newnode; return newnode;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* Every node type that can appear in stored rules' parsetrees *must* * Every node type that can appear in stored rules' parsetrees *must*
@ -531,8 +531,6 @@ _outHash(StringInfo str, Hash *node)
WRITE_NODE_TYPE("HASH"); WRITE_NODE_TYPE("HASH");
_outPlanInfo(str, (Plan *) node); _outPlanInfo(str, (Plan *) node);
WRITE_NODE_FIELD(hashkeys);
} }
/***************************************************************************** /*****************************************************************************

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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, List *hashclauses,
Plan *lefttree, Plan *righttree, Plan *lefttree, Plan *righttree,
JoinType jointype); 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, static MergeJoin *make_mergejoin(List *tlist,
List *joinclauses, List *otherclauses, List *joinclauses, List *otherclauses,
List *mergeclauses, List *mergeclauses,
@ -1067,8 +1067,6 @@ create_hashjoin_plan(Query *root,
List *hashclauses; List *hashclauses;
HashJoin *join_plan; HashJoin *join_plan;
Hash *hash_plan; Hash *hash_plan;
List *innerhashkeys;
List *hcl;
/* Get the join qual clauses (in plain expression form) */ /* Get the join qual clauses (in plain expression form) */
if (IS_OUTER_JOIN(best_path->jpath.jointype)) if (IS_OUTER_JOIN(best_path->jpath.jointype))
@ -1102,14 +1100,6 @@ create_hashjoin_plan(Query *root,
otherclauses = order_qual_clauses(root, otherclauses); otherclauses = order_qual_clauses(root, otherclauses);
hashclauses = order_qual_clauses(root, hashclauses); 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 */ /* We don't want any excess columns in the hashed tuples */
disuse_physical_tlist(inner_plan, best_path->jpath.innerjoinpath); 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. * Build the hash node and hash join node.
*/ */
hash_plan = make_hash(inner_plan->targetlist, hash_plan = make_hash(inner_plan->targetlist,
innerhashkeys,
inner_plan); inner_plan);
join_plan = make_hashjoin(tlist, join_plan = make_hashjoin(tlist,
joinclauses, joinclauses,
@ -1728,7 +1717,7 @@ make_hashjoin(List *tlist,
} }
static Hash * static Hash *
make_hash(List *tlist, List *hashkeys, Plan *lefttree) make_hash(List *tlist, Plan *lefttree)
{ {
Hash *node = makeNode(Hash); Hash *node = makeNode(Hash);
Plan *plan = &node->plan; Plan *plan = &node->plan;
@ -1744,7 +1733,6 @@ make_hash(List *tlist, List *hashkeys, Plan *lefttree)
plan->qual = NIL; plan->qual = NIL;
plan->lefttree = lefttree; plan->lefttree = lefttree;
plan->righttree = NULL; plan->righttree = NULL;
node->hashkeys = hashkeys;
return node; return node;
} }

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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); (Node *) ((HashJoin *) plan)->hashclauses);
break; break;
case T_Hash: 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_Material:
case T_Sort: case T_Sort:
case T_Unique: case T_Unique:

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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; break;
case T_Hash: case T_Hash:
finalize_primnode((Node *) ((Hash *) plan)->hashkeys,
&context);
break;
case T_Agg: case T_Agg:
case T_SeqScan: case T_SeqScan:
case T_Material: case T_Material:

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 typedef struct Hash
{ {
Plan plan; Plan plan;
List *hashkeys; /* all other info is in the parent HashJoin node */
} Hash; } Hash;
/* ---------------- /* ----------------