diff options
author | David Rowley | 2021-11-08 01:41:13 +0000 |
---|---|---|
committer | David Rowley | 2021-11-08 01:41:13 +0000 |
commit | 1f194ed6c26e67ce92437729fc46193cc6e913d2 (patch) | |
tree | 2d7304b3c394ecee20d90afcc5cbea9baa3cebb2 | |
parent | bb003edbb7b1e8fb2ce488e2f047e5e1982b95fd (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.c | 19 |
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; |