diff options
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 38 | ||||
-rw-r--r-- | src/backend/optimizer/plan/setrefs.c | 44 |
2 files changed, 82 insertions, 0 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 12fba56285d..39458034c1a 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -222,9 +222,12 @@ static NestLoop *make_nestloop(List *tlist, static HashJoin *make_hashjoin(List *tlist, List *joinclauses, List *otherclauses, List *hashclauses, + List *hashoperators, List *hashcollations, + List *hashkeys, Plan *lefttree, Plan *righttree, JoinType jointype, bool inner_unique); static Hash *make_hash(Plan *lefttree, + List *hashkeys, Oid skewTable, AttrNumber skewColumn, bool skewInherit); @@ -4381,9 +4384,14 @@ create_hashjoin_plan(PlannerInfo *root, List *joinclauses; List *otherclauses; List *hashclauses; + List *hashoperators = NIL; + List *hashcollations = NIL; + List *inner_hashkeys = NIL; + List *outer_hashkeys = NIL; Oid skewTable = InvalidOid; AttrNumber skewColumn = InvalidAttrNumber; bool skewInherit = false; + ListCell *lc; /* * HashJoin can project, so we don't have to demand exact tlists from the @@ -4476,9 +4484,28 @@ create_hashjoin_plan(PlannerInfo *root, } /* + * Collect hash related information. The hashed expressions are + * deconstructed into outer/inner expressions, so they can be computed + * separately (inner expressions are used to build the hashtable via Hash, + * outer expressions to perform lookups of tuples from HashJoin's outer + * plan in the hashtable). Also collect operator information necessary to + * build the hashtable. + */ + foreach(lc, hashclauses) + { + OpExpr *hclause = lfirst_node(OpExpr, lc); + + hashoperators = lappend_oid(hashoperators, hclause->opno); + hashcollations = lappend_oid(hashcollations, hclause->inputcollid); + outer_hashkeys = lappend(outer_hashkeys, linitial(hclause->args)); + inner_hashkeys = lappend(inner_hashkeys, lsecond(hclause->args)); + } + + /* * Build the hash node and hash join node. */ hash_plan = make_hash(inner_plan, + inner_hashkeys, skewTable, skewColumn, skewInherit); @@ -4505,6 +4532,9 @@ create_hashjoin_plan(PlannerInfo *root, joinclauses, otherclauses, hashclauses, + hashoperators, + hashcollations, + outer_hashkeys, outer_plan, (Plan *) hash_plan, best_path->jpath.jointype, @@ -5546,6 +5576,9 @@ make_hashjoin(List *tlist, List *joinclauses, List *otherclauses, List *hashclauses, + List *hashoperators, + List *hashcollations, + List *hashkeys, Plan *lefttree, Plan *righttree, JoinType jointype, @@ -5559,6 +5592,9 @@ make_hashjoin(List *tlist, plan->lefttree = lefttree; plan->righttree = righttree; node->hashclauses = hashclauses; + node->hashoperators = hashoperators; + node->hashcollations = hashcollations; + node->hashkeys = hashkeys; node->join.jointype = jointype; node->join.inner_unique = inner_unique; node->join.joinqual = joinclauses; @@ -5568,6 +5604,7 @@ make_hashjoin(List *tlist, static Hash * make_hash(Plan *lefttree, + List *hashkeys, Oid skewTable, AttrNumber skewColumn, bool skewInherit) @@ -5580,6 +5617,7 @@ make_hash(Plan *lefttree, plan->lefttree = lefttree; plan->righttree = NULL; + node->hashkeys = hashkeys; node->skewTable = skewTable; node->skewColumn = skewColumn; node->skewInherit = skewInherit; diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index dc11f098e0f..329ebd5f287 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -107,6 +107,7 @@ static Plan *set_append_references(PlannerInfo *root, static Plan *set_mergeappend_references(PlannerInfo *root, MergeAppend *mplan, int rtoffset); +static void set_hash_references(PlannerInfo *root, Plan *plan, int rtoffset); static Node *fix_scan_expr(PlannerInfo *root, Node *node, int rtoffset); static Node *fix_scan_expr_mutator(Node *node, fix_scan_expr_context *context); static bool fix_scan_expr_walker(Node *node, fix_scan_expr_context *context); @@ -646,6 +647,9 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) break; case T_Hash: + set_hash_references(root, plan, rtoffset); + break; + case T_Material: case T_Sort: case T_Unique: @@ -1419,6 +1423,36 @@ set_mergeappend_references(PlannerInfo *root, return (Plan *) mplan; } +/* + * set_hash_references + * Do set_plan_references processing on a Hash node + */ +static void +set_hash_references(PlannerInfo *root, Plan *plan, int rtoffset) +{ + Hash *hplan = (Hash *) plan; + Plan *outer_plan = plan->lefttree; + indexed_tlist *outer_itlist; + + /* + * Hash's hashkeys are used when feeding tuples into the hashtable, + * therefore have them reference Hash's outer plan (which itself is the + * inner plan of the HashJoin). + */ + outer_itlist = build_tlist_index(outer_plan->targetlist); + hplan->hashkeys = (List *) + fix_upper_expr(root, + (Node *) hplan->hashkeys, + outer_itlist, + OUTER_VAR, + rtoffset); + + /* Hash doesn't project */ + set_dummy_tlist_references(plan, rtoffset); + + /* Hash nodes don't have their own quals */ + Assert(plan->qual == NIL); +} /* * copyVar @@ -1754,6 +1788,16 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset) inner_itlist, (Index) 0, rtoffset); + + /* + * HashJoin's hashkeys are used to look for matching tuples from its + * outer plan (not the Hash node!) in the hashtable. + */ + hj->hashkeys = (List *) fix_upper_expr(root, + (Node *) hj->hashkeys, + outer_itlist, + OUTER_VAR, + rtoffset); } /* |