aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/createplan.c
diff options
context:
space:
mode:
authorDavid Rowley <drowley@postgresql.org>2021-11-24 10:06:59 +1300
committerDavid Rowley <drowley@postgresql.org>2021-11-24 10:06:59 +1300
commite502150f7d0be41e3c8784be007fa871a32d8a7f (patch)
treea6c96abbe3eae534d938d05539627b4f03d23f62 /src/backend/optimizer/plan/createplan.c
parent1922d7c6e1a74178bd2f1d5aa5a6ab921b3fcd34 (diff)
downloadpostgresql-e502150f7d0be41e3c8784be007fa871a32d8a7f.tar.gz
postgresql-e502150f7d0be41e3c8784be007fa871a32d8a7f.zip
Allow Memoize to operate in binary comparison mode
Memoize would always use the hash equality operator for the cache key types to determine if the current set of parameters were the same as some previously cached set. Certain types such as floating points where -0.0 and +0.0 differ in their binary representation but are classed as equal by the hash equality operator may cause problems as unless the join uses the same operator it's possible that whichever join operator is being used would be able to distinguish the two values. In which case we may accidentally return in the incorrect rows out of the cache. To fix this here we add a binary mode to Memoize to allow it to the current set of parameters to previously cached values by comparing bit-by-bit rather than logically using the hash equality operator. This binary mode is always used for LATERAL joins and it's used for normal joins when any of the join operators are not hashable. Reported-by: Tom Lane Author: David Rowley Discussion: https://postgr.es/m/3004308.1632952496@sss.pgh.pa.us Backpatch-through: 14, where Memoize was added
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r--src/backend/optimizer/plan/createplan.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 3dc0176a516..866f19f64c1 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);
@@ -6417,7 +6419,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;
@@ -6432,6 +6435,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;