Skip to content

fix: reject a collation on a string set column unless it compares bytes, on 10.x (port of #483, #496) - #500

Merged
CaffeinatedCoder merged 3 commits into
release/10.xfrom
fix/496-reject-nondeterministic-string-set-collation-10.x
Oct 26, 2026
Merged

CaffeinatedCoder merged 3 commits into
release/10.xfrom
fix/496-reject-nondeterministic-string-set-collation-10.x

Conversation

@CaffeinatedCoder

Copy link
Copy Markdown
Owner

Closes #496

Problem

On release/10.x, a nondeterministic (case-insensitive) collation on a StringSet column made the database answer differently from memory:

  • Contains("a"), IsSubsetOf, Overlaps and == matched {A};
  • ExecuteUpdate with Remove("a") stored {}.

main rejects such a collation since #483 (PR #492, merged as 3776504).

Change

Cherry-picked with -x: 98e51a1 and 5ca7a14 from PR #492.

  • Code: StringSetCollationConvention through IConventionSetPlugin rejects a collation on a string set column other than C, POSIX, ucs_basic, pg_c_utf8 and default. The guard refuses EF.Functions.Collate over a string set.
  • Tests: StringSetCollationTests and StringSetCollationIntegrationTests.
  • 10.x release form: it changes answers, so the root and EF Core changelogs open [10.4.0] with "Some calls answer differently" and a ### Changed answers row linking 10.x: reject a collation on a string set column unless it compares bytes (port of #483) #496 and the migration guide. docs/migration.md gets ## Changed answers in 10.4.0 with Check string set columns with a collation, the same text as main's v10.x section.

Tests

On EF Core 10.0.0, PostgreSQL 16 and 18: conventions (including the Changed answers checks), no-database EF tests, ASP.NET Core tests and the integration suite (318 tests). On the newest-patch leg: the collation tests. Re-proved on EF Core 10: without the plugin's registration both model-build tests fail.

🤖 Generated with Claude Code

CaffeinatedCoder and others added 2 commits October 26, 2026 13:13
…es (#483)

PostgreSQL compares text[] elements with the column's collation, memory
ordinally. Under a nondeterministic collation A equals a: on a case-insensitive
StringSet column Contains("a") matched {A}, IsSubsetOf, Overlaps and == agreed
with it, and ExecuteUpdate with Remove("a") stored {} where memory keeps {A}.

Translating with COLLATE "C" was measured and rejected: the GIN index carries
the column's collation, so a collated operand turns every indexed @> into a
sequential scan, on an en_US column too (PostgreSQL 16 and 18).

So a model-finalizing convention, added through IConventionSetPlugin, throws
for a collation on a StringSet or StringSet<T> column other than C, POSIX,
ucs_basic, pg_c_utf8 and default, which compare bytes; a name doesn't say
whether a collation is deterministic. ValueSetSqlGuard refuses
EF.Functions.Collate over a string set the same way. A JSON document holds
the set's literal and is not checked.

Found-By: CA
Defect-Class: SQL

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 98e51a1)
…migration and changelog (#483)

The model-build rejection and the Collate refusal in the previous commit, in
the EF guide's value set section, the v10.x migration list and its section,
the Breaking lines of 11.0.0-preview.1, claim E86, and the live test that a
column collated "C" answers as memory does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 5ca7a14)
@CaffeinatedCoder CaffeinatedCoder added this to the 10.4.0 milestone Oct 26, 2026
@CaffeinatedCoder CaffeinatedCoder added bug Something isn't working silent Answers wrongly without throwing — fixes go in the next major, never deferred area/value-sets Value set families and wrapper arities package/efcore Affects CodoMetis.ValueRanges.EFCore.PostgreSQL severity/medium Inconsistency or failure in a narrow scenario labels Oct 26, 2026
…llation-10.x

# Conflicts:
#	test/oracles/claims.json
@CaffeinatedCoder
CaffeinatedCoder merged commit 6cbddaf into release/10.x Oct 26, 2026
10 checks passed
@CaffeinatedCoder
CaffeinatedCoder deleted the fix/496-reject-nondeterministic-string-set-collation-10.x branch October 26, 2026 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/value-sets Value set families and wrapper arities bug Something isn't working package/efcore Affects CodoMetis.ValueRanges.EFCore.PostgreSQL severity/medium Inconsistency or failure in a narrow scenario silent Answers wrongly without throwing — fixes go in the next major, never deferred

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant