postgresql/src/backend
Richard Guo 5a55ea507a Consider collation when proving uniqueness from unique indexes
relation_has_unique_index_for() has long had an XXX noting that it
doesn't check collations when matching a unique index's columns
against equality clauses.  This was benign as long as all collations
in play reduced to the same notion of equality, but has been incorrect
since nondeterministic collations were introduced in PG 12: a unique
index under a deterministic collation does not prove uniqueness under
a nondeterministic collation, nor vice versa.

The consequence is wrong query results for any planner optimization
that consumes the faulty proof, including inner-unique join execution
(which stops the inner search after the first match per outer row),
useless-left-join removal, semijoin-to-innerjoin reduction, and
self-join elimination.

Fix by requiring the index's collation to agree on equality with the
clause's input collation.  Two collations agree on equality if either
is InvalidOid (denoting a non-collation-sensitive operation, which
cannot conflict with the other side), if they have the same OID, or if
both are deterministic: by definition a deterministic collation treats
two strings as equal iff they are byte-wise equal (see CREATE
COLLATION), so any two deterministic collations share the same
equality relation and the uniqueness proof carries over.  Any mismatch
involving a nondeterministic collation is rejected.

Back-patch to all supported branches; the bug has existed since
nondeterministic collations were introduced in PG 12.

Author: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAMbWs4_XUUSTyzCaRjUeeahWNqi=8ZOA5Q4coi8zUVEDSBkM6A@mail.gmail.com
Backpatch-through: 14
2026-05-05 10:22:53 +09:00
..
access Wake standby_write/standby_flush waiters from the WAL replay loop 2026-05-03 16:22:02 +03:00
archive Don't include wait_event.h in pgstat.h 2026-03-06 16:24:58 +01:00
backup Online enabling and disabling of data checksums 2026-04-03 22:58:51 +02:00
bootstrap Rework signal handler infrastructure to pass sender info as argument. 2026-04-15 07:30:34 -04:00
catalog Do not define type for a property graph 2026-05-04 15:45:56 +02:00
commands Fix off-by-one in repack index loop 2026-05-04 20:01:19 +02:00
executor Use "concurrent delete" in serialization error for TM_Deleted cases 2026-05-01 10:00:29 +09:00
foreign Remove bits* typedefs. 2026-03-30 16:12:08 -05:00
jit jit: No backport::SectionMemoryManager for LLVM 22. 2026-04-03 14:55:11 +13:00
lib Fix a set of typos and grammar issues across the tree 2026-04-21 14:46:22 +09:00
libpq Declare load_hosts() as returning HostsFileLoadResult. 2026-05-04 18:33:06 -04:00
main Update copyright for 2026 2026-01-01 13:24:10 -05:00
nodes Handle nodes that may appear in GraphPattern expression trees 2026-05-04 17:34:32 +02:00
optimizer Consider collation when proving uniqueness from unique indexes 2026-05-05 10:22:53 +09:00
parser Fix JSON_ARRAY(query) empty set handling and view deparsing 2026-05-01 09:42:00 +09:00
partitioning Add missing Datum conversions 2026-04-20 07:22:16 +02:00
po Update copyright for 2026 2026-01-01 13:24:10 -05:00
port Rework signal handler infrastructure to pass sender info as argument. 2026-04-15 07:30:34 -04:00
postmaster Improve database detection logic in datachecksumsworker 2026-04-30 13:41:55 +02:00
regex Use fallthrough attribute instead of comment 2026-02-19 08:51:12 +01:00
replication Simplify translatable messages for tuple value details in conflict.c. 2026-05-04 12:06:41 +05:30
rewrite Fix typos and grammar in graph table rewrite code 2026-04-24 08:27:04 +02:00
snowball Fix meson build of snowball code. 2026-01-05 16:51:36 -05:00
statistics Add missing serial commas 2026-05-04 11:53:04 +02:00
storage Mark modified the FSM buffer as dirty during recovery 2026-05-03 20:23:50 +03:00
tcop Only show signal-sender PID/UID detail in server log 2026-05-01 13:20:08 -04:00
tsearch Prevent some buffer overruns in spell.c's parsing of affix files. 2026-04-22 12:02:15 -04:00
utils Consider collation when proving uniqueness from unique indexes 2026-05-05 10:22:53 +09:00
.gitignore Add .gitignore entries for AIX-specific intermediate build artifacts. 2015-07-08 20:44:22 -04:00
common.mk Blind attempt to fix LLVM dependency in the backend 2022-09-15 10:53:48 +07:00
Makefile ssl: Serverside SNI support for libpq 2026-03-18 12:37:11 +01:00
meson.build Add CONCURRENTLY option to REPACK 2026-04-06 21:55:08 +02:00
nls.mk Create a separate file listing backend types 2025-09-26 15:21:49 +02:00