You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/// collation into <see cref="NextToken"/>; other literal kinds (varbinary,
32
+
/// money) don't carry collation and ignore the parameter.
33
+
/// </para>
25
34
/// </remarks>
26
35
staticclassTokenizer
27
36
{
@@ -30,17 +39,18 @@ static class Tokenizer
30
39
/// </summary>
31
40
/// <param name="command">The command from which a token is produced.</param>
32
41
/// <param name="index">The position of the next un-read character (0 to begin); updated to the next un-read position past the returned token.</param>
42
+
/// <param name="activeCollation">Collation tagged onto string-literal <see cref="SqlValue"/>s; supplied by the caller's active <see cref="Database"/>.</param>
33
43
/// <returns>The next token, or null if the end of <paramref name="command"/> has been reached.</returns>
34
44
/// <exception cref="SimulatedSqlException">Incorrect or unsupported syntax.</exception>
result.AddWarning($"Database declares Collation '{collation}' which isn't on the simulator's recognized list — stored as metadata, but comparison semantics fall back to the default. Add it to Collation.Recognized to surface in catalog views.");
273
+
result.AddWarning($"Database declares Collation '{collation}' which the simulator's catalog doesn't recognize — the database keeps its server-default collation; columns declared with their own COLLATE clauses still pin those collations.");
Copy file name to clipboardExpand all lines: docs/claude/collations.md
+7-2Lines changed: 7 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -73,13 +73,18 @@ Sites routed through the active DB collation:
73
73
74
74
Probe-confirmed fidelity (real SQL Server CS database, 2026-05-22): `SELECT IIF(CHAR(65) = CHAR(97), 'eq', 'neq')` returns `'neq'` (literals don't case-fold under CS). The simulator now matches; the `CsDatabase_*CharFunctionResultUsesActiveCollation` tests in `NameComparisonRegimeTests.cs` lock the behavior in.
75
75
76
-
Sites that intentionally stay on `Collation.Default` (~34 references):
76
+
Sites that intentionally stay on `Collation.Default`:
77
77
- System catalog schemas in `BuiltInResources.cs` — process-wide statics, no per-Simulation affinity.
- Error-message type placeholders, dynamic-SQL string extraction, PRINT formatting — collation irrelevant to the surfaced value.
81
81
-`Simulation.ServerCollation` initializer — the deliberate anchor for "what does the simulator's hardcoded baseline resolve to."
82
-
-**String literals via the tokenizer** (`Value` / `Literal`) — literals like `'A'` and `N'foo'` still carry `Collation.Default` because the tokenizer materializes the `SqlValue` without batch context. Closing this would require threading `BatchContext` through `Tokenizer.NextToken` — deferred. The gap surfaces as: `SELECT 'A' = 'a'` on a CS database returns `1` (CI compare) instead of `0` (CS compare). Real workloads typically have a column on at least one side, and the column's `Implicit`-rank collation wins via `Collation.Resolve`, so this gap is unobservable in EF Core workloads.
82
+
83
+
## String literals carry the active DB collation
84
+
85
+
`Tokenizer.NextToken` takes a `Collation activeCollation` parameter; `ParserContext.MoveNext` threads `context.CurrentDatabase.Collation` in. The two string-literal entry points (`ParseStringLiteral` for `'foo'`, `ParseNPrefixedStringLiteral` for `N'foo'`) construct `VarcharSqlType.Get(0, activeCollation, Coercibility.CoercibleDefault)` / `NVarcharSqlType` and tag the resulting `SqlValue` with it. Other literal kinds (varbinary `0xHEX`, currency `$1.23`) don't carry collation and ignore the parameter.
86
+
87
+
Effect: `SELECT IIF('A' = 'a', 'eq', 'neq')` on a CS database returns `'neq'` (case-sensitive), matching real SQL Server. The `CsDatabase_TwoVarcharLiteralsCompareCaseSensitively` / `CsDatabase_TwoNVarcharLiteralsCompareCaseSensitively` tests in `NameComparisonRegimeTests.cs` lock the behavior in. The earlier deferral framing (literal pairs falling through to the CI baseline because the tokenizer was stateless) is closed.
83
88
84
89
`ALTER COLUMN` without an explicit `COLLATE` clause preserves the existing column's collation (probe-aligned). With an explicit `COLLATE`, the new collation pins at `Implicit` rank.
0 commit comments