summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Rowley2021-11-08 01:41:13 +0000
committerDavid Rowley2021-11-08 01:41:13 +0000
commit1f194ed6c26e67ce92437729fc46193cc6e913d2 (patch)
tree2d7304b3c394ecee20d90afcc5cbea9baa3cebb2
parentbb003edbb7b1e8fb2ce488e2f047e5e1982b95fd (diff)
Fix incorrect hash equality operator bug in Memoize
In v14, because we don't have a field in RestrictInfo to cache both the left and right type's hash equality operator, we just restrict the scope of Memoize to only when the left and right types of a RestrictInfo are the same. In master we add another field to RestrictInfo and cache both hash equality operators. Reported-by: Jaime Casanova Author: David Rowley Discussion: https://postgr.es/m/20210929185544.GB24346%40ahch-to Backpatch-through: 14
-rw-r--r--src/backend/optimizer/plan/initsplan.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index e25dc9a7ca7..276e62b74b6 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -2719,7 +2719,8 @@ check_memoizable(RestrictInfo *restrictinfo)
{
TypeCacheEntry *typentry;
Expr *clause = restrictinfo->clause;
- Node *leftarg;
+ Oid lefttype;
+ Oid righttype;
if (restrictinfo->pseudoconstant)
return;
@@ -2728,10 +2729,20 @@ check_memoizable(RestrictInfo *restrictinfo)
if (list_length(((OpExpr *) clause)->args) != 2)
return;
- leftarg = linitial(((OpExpr *) clause)->args);
+ lefttype = exprType(linitial(((OpExpr *) clause)->args));
+ righttype = exprType(lsecond(((OpExpr *) clause)->args));
+
+ /*
+ * Really there should be a field for both the left and right hash
+ * equality operator, however, in v14, there's only a single field in
+ * RestrictInfo to record the operator in, so we must insist that the left
+ * and right types match.
+ */
+ if (lefttype != righttype)
+ return;
- typentry = lookup_type_cache(exprType(leftarg), TYPECACHE_HASH_PROC |
- TYPECACHE_EQ_OPR);
+ typentry = lookup_type_cache(lefttype, TYPECACHE_HASH_PROC |
+ TYPECACHE_EQ_OPR);
if (!OidIsValid(typentry->hash_proc) || !OidIsValid(typentry->eq_opr))
return;