Re: BUG #19853: Memoize returns wrong rows when the join operator is hashable but its equality semantics differ from

From: David Rowley <dgrowleyml(at)gmail(dot)com>
To: 303677365(at)qq(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #19853: Memoize returns wrong rows when the join operator is hashable but its equality semantics differ from
Date: 2026-11-08 23:07:45
Message-ID: CAApHDvq+atDgBEYnxMBbQyGji0y3sBtpa4zhYnXqb77UfyxzMA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

On Sun, 8 Nov 2026 at 22:55, PG Bug reporting form
<noreply(at)postgresql(dot)org> wrote:
> Memoize decides "are these outer-scan parameters the same as a cached
> entry's?" using the **type's default equality operator** (texteq for text),
> not the operator the join clause actually uses. When the join uses a
> hashable operator whose equality semantics differ from the default '=' —
> here a user-defined `===` that compares the raw bytes (case-SENSITIVE) while
> the column uses a nondeterministic (case-insensitive) collation — the
> default texteq treats 'abc' == 'ABC', so the cache wrongly shares one entry
> between the two outer values. The cached inner rows computed for one key are
> then returned for the other: group counts silently merge across values the
> join distinguishes.

Thanks for the report.

The attached is a lightly edited LLM-generated fix with my
supervision. Its first choice was to switch to binary mode for this
case, but I told it to only change check_memoizable() and use the
joinoperator when the left and right types match, and then only check
to see if there's another suitable operator when the types don't
match.

I (not the LLM) also noticed that during ExecInitMemoize(), the
cache_eq_expr is initialised even when in binary mode. Since it's not
used in binary mode, this seems like a waste of effort. The 0002
adjusts Memoize so it doesn't do this. This seems more like
master-only material. Further to that, the lookup_type_cache() code in
check_memoizable() doesn't technically seem needed as if
paraminfo_get_equal_hashops() sees an invalid hashjoinoperator while
processing the ppi_clauses, it'll switch to binary mode, so
technically we don't need a hash operator as binary mode uses
datum_image_hash() and datum_image_eq(). I'm not so sure about
changing that however, as 1) it's likely not causing many cases not to
Memoize that could, and b) someone might have left off a hash operator
to ensure the planner opts not to Memoize anything using that type.

David

Attachment Content-Type Size
v1-0001-Fix-Memoize-using-the-wrong-equality-operator-for.patch application/octet-stream 10.5 KB
v1-0002-Don-t-build-unused-Memoize-hash-and-equality-stat.patch application/octet-stream 3.9 KB

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message David Rowley 2026-11-09 00:10:27 Re: BUG #19836: Backend crash with large hash partition modulus
Previous Message Michael Paquier 2026-11-08 22:25:17 Re: BUG #19780: gtsvector_picksplit() reads uninitialized data when called with three entries