aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/path/joinpath.c38
-rw-r--r--src/backend/optimizer/plan/createplan.c10
-rw-r--r--src/backend/optimizer/util/pathnode.c4
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,
&param_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: