diff options
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r-- | src/backend/optimizer/path/joinpath.c | 38 | ||||
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 10 | ||||
-rw-r--r-- | src/backend/optimizer/util/pathnode.c | 4 |
3 files changed, 44 insertions, 8 deletions
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 6407ede12a6..c5640b4d3a1 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -371,19 +371,21 @@ allow_star_schema_join(PlannerInfo *root, * Returns true the hashing is possible, otherwise return false. * * Additionally we also collect the outer exprs and the hash operators for - * each parameter to innerrel. These set in 'param_exprs' and 'operators' - * when we return true. + * each parameter to innerrel. These set in 'param_exprs', 'operators' and + * 'binary_mode' when we return true. */ static bool paraminfo_get_equal_hashops(PlannerInfo *root, ParamPathInfo *param_info, RelOptInfo *outerrel, RelOptInfo *innerrel, - List **param_exprs, List **operators) + List **param_exprs, List **operators, + bool *binary_mode) { ListCell *lc; *param_exprs = NIL; *operators = NIL; + *binary_mode = false; if (param_info != NULL) { @@ -416,6 +418,20 @@ paraminfo_get_equal_hashops(PlannerInfo *root, ParamPathInfo *param_info, *operators = lappend_oid(*operators, rinfo->hasheqoperator); *param_exprs = lappend(*param_exprs, expr); + + /* + * When the join operator is not hashable then it's possible that + * the operator will be able to distinguish something that the + * hash equality operator could not. For example with floating + * point types -0.0 and +0.0 are classed as equal by the hash + * function and equality function, but some other operator may be + * able to tell those values apart. This means that we must put + * memoize into binary comparison mode so that it does bit-by-bit + * comparisons rather than a "logical" comparison as it would + * using the hash equality operator. + */ + if (!OidIsValid(rinfo->hashjoinoperator)) + *binary_mode = true; } } @@ -446,6 +462,17 @@ paraminfo_get_equal_hashops(PlannerInfo *root, ParamPathInfo *param_info, *operators = lappend_oid(*operators, typentry->eq_opr); *param_exprs = lappend(*param_exprs, expr); + + /* + * We must go into binary mode as we don't have too much of an idea of + * how these lateral Vars are being used. See comment above when we + * set *binary_mode for the non-lateral Var case. This could be + * relaxed a bit if we had the RestrictInfos and knew the operators + * being used, however for cases like Vars that are arguments to + * functions we must operate in binary mode as we don't have + * visibility into what the function is doing with the Vars. + */ + *binary_mode = true; } /* We're okay to use memoize */ @@ -466,6 +493,7 @@ get_memoize_path(PlannerInfo *root, RelOptInfo *innerrel, List *param_exprs; List *hash_operators; ListCell *lc; + bool binary_mode; /* Obviously not if it's disabled */ if (!enable_memoize) @@ -557,7 +585,8 @@ get_memoize_path(PlannerInfo *root, RelOptInfo *innerrel, outerrel, innerrel, ¶m_exprs, - &hash_operators)) + &hash_operators, + &binary_mode)) { return (Path *) create_memoize_path(root, innerrel, @@ -565,6 +594,7 @@ get_memoize_path(PlannerInfo *root, RelOptInfo *innerrel, param_exprs, hash_operators, extra->inner_unique, + binary_mode, outer_path->parent->rows); } diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 92dd322c622..cc8d44bdc09 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -279,7 +279,8 @@ static Sort *make_sort_from_groupcols(List *groupcls, static Material *make_material(Plan *lefttree); static Memoize *make_memoize(Plan *lefttree, Oid *hashoperators, Oid *collations, List *param_exprs, - bool singlerow, uint32 est_entries); + bool singlerow, bool binary_mode, + uint32 est_entries); static WindowAgg *make_windowagg(List *tlist, Index winref, int partNumCols, AttrNumber *partColIdx, Oid *partOperators, Oid *partCollations, int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations, @@ -1617,7 +1618,8 @@ create_memoize_plan(PlannerInfo *root, MemoizePath *best_path, int flags) } plan = make_memoize(subplan, operators, collations, param_exprs, - best_path->singlerow, best_path->est_entries); + best_path->singlerow, best_path->binary_mode, + best_path->est_entries); copy_generic_path_info(&plan->plan, (Path *) best_path); @@ -6416,7 +6418,8 @@ materialize_finished_plan(Plan *subplan) static Memoize * make_memoize(Plan *lefttree, Oid *hashoperators, Oid *collations, - List *param_exprs, bool singlerow, uint32 est_entries) + List *param_exprs, bool singlerow, bool binary_mode, + uint32 est_entries) { Memoize *node = makeNode(Memoize); Plan *plan = &node->plan; @@ -6431,6 +6434,7 @@ make_memoize(Plan *lefttree, Oid *hashoperators, Oid *collations, node->collations = collations; node->param_exprs = param_exprs; node->singlerow = singlerow; + node->binary_mode = binary_mode; node->est_entries = est_entries; return node; diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index 41cbf328c46..ad3070352f0 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -1583,7 +1583,7 @@ create_material_path(RelOptInfo *rel, Path *subpath) MemoizePath * create_memoize_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *param_exprs, List *hash_operators, - bool singlerow, double calls) + bool singlerow, bool binary_mode, double calls) { MemoizePath *pathnode = makeNode(MemoizePath); @@ -1603,6 +1603,7 @@ create_memoize_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, pathnode->hash_operators = hash_operators; pathnode->param_exprs = param_exprs; pathnode->singlerow = singlerow; + pathnode->binary_mode = binary_mode; pathnode->calls = calls; /* @@ -3942,6 +3943,7 @@ reparameterize_path(PlannerInfo *root, Path *path, mpath->param_exprs, mpath->hash_operators, mpath->singlerow, + mpath->binary_mode, mpath->calls); } default: |