| 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 |
| 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 |