Skip to content

Commit cbba9d8

Browse files
terry1purcellclaude
andcommitted
expression: cover latin1_swedish_ci in collation aggregation tests
Pin how latin1_swedish_ci behaves in inferCollation, which the new collator reaches through isBinCollation. At equal coercibility the _bin collation wins regardless of argument order, an explicit COLLATE beats it either way round, two conflicting explicit collations cannot be aggregated, and both binary and utf8mb4 take precedence over latin1 at equal coercibility. Also extend TestCompareString with the latin1 collations, including the entries where latin1_swedish_ci deliberately differs from the utf8 collations already covered there: sharp s (0xDF) folds to nothing, and A-ring, A-diaeresis and O-diaeresis sort after Z rather than onto A and O. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TgAxo4cK4qCpuLrhroHWy1
1 parent 2763bc2 commit cbba9d8

1 file changed

Lines changed: 96 additions & 0 deletions

File tree

pkg/expression/collation_test.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,85 @@ func TestInferCollation(t *testing.T) {
177177
false,
178178
&ExprCollation{CoercibilityImplicit, UNICODE, charset.CharsetBin, charset.CollationBin},
179179
},
180+
// latin1_bin mixed with latin1_swedish_ci. At equal coercibility the _bin
181+
// collation wins regardless of argument order, so latin1_swedish_ci must be
182+
// recognized as the non-bin side (see isBinCollation).
183+
{
184+
[]Expression{
185+
newExpression(CoercibilityImplicit, UNICODE, charset.CharsetLatin1, charset.CollationLatin1),
186+
newExpression(CoercibilityImplicit, UNICODE, charset.CharsetLatin1, "latin1_swedish_ci"),
187+
},
188+
false,
189+
&ExprCollation{CoercibilityImplicit, UNICODE, charset.CharsetLatin1, charset.CollationLatin1},
190+
},
191+
{
192+
[]Expression{
193+
newExpression(CoercibilityImplicit, UNICODE, charset.CharsetLatin1, "latin1_swedish_ci"),
194+
newExpression(CoercibilityImplicit, UNICODE, charset.CharsetLatin1, charset.CollationLatin1),
195+
},
196+
false,
197+
&ExprCollation{CoercibilityImplicit, UNICODE, charset.CharsetLatin1, charset.CollationLatin1},
198+
},
199+
{
200+
[]Expression{
201+
newExpression(CoercibilityImplicit, UNICODE, charset.CharsetLatin1, "latin1_swedish_ci"),
202+
newExpression(CoercibilityImplicit, UNICODE, charset.CharsetLatin1, "latin1_swedish_ci"),
203+
},
204+
false,
205+
&ExprCollation{CoercibilityImplicit, UNICODE, charset.CharsetLatin1, "latin1_swedish_ci"},
206+
},
207+
// An explicit COLLATE still beats the _bin collation, either way round.
208+
{
209+
[]Expression{
210+
newExpression(CoercibilityExplicit, UNICODE, charset.CharsetLatin1, "latin1_swedish_ci"),
211+
newExpression(CoercibilityImplicit, UNICODE, charset.CharsetLatin1, charset.CollationLatin1),
212+
},
213+
false,
214+
&ExprCollation{CoercibilityExplicit, UNICODE, charset.CharsetLatin1, "latin1_swedish_ci"},
215+
},
216+
{
217+
[]Expression{
218+
newExpression(CoercibilityImplicit, UNICODE, charset.CharsetLatin1, charset.CollationLatin1),
219+
newExpression(CoercibilityExplicit, UNICODE, charset.CharsetLatin1, "latin1_swedish_ci"),
220+
},
221+
false,
222+
&ExprCollation{CoercibilityExplicit, UNICODE, charset.CharsetLatin1, "latin1_swedish_ci"},
223+
},
224+
// Two conflicting explicit collations cannot be aggregated.
225+
{
226+
[]Expression{
227+
newExpression(CoercibilityExplicit, UNICODE, charset.CharsetLatin1, charset.CollationLatin1),
228+
newExpression(CoercibilityExplicit, UNICODE, charset.CharsetLatin1, "latin1_swedish_ci"),
229+
},
230+
true,
231+
nil,
232+
},
233+
// latin1 is not a Unicode charset, so utf8mb4 wins at equal coercibility.
234+
{
235+
[]Expression{
236+
newExpression(CoercibilityImplicit, UNICODE, charset.CharsetLatin1, "latin1_swedish_ci"),
237+
newExpression(CoercibilityImplicit, UNICODE, charset.CharsetUTF8MB4, charset.CollationUTF8MB4),
238+
},
239+
false,
240+
&ExprCollation{CoercibilityImplicit, UNICODE, charset.CharsetUTF8MB4, charset.CollationUTF8MB4},
241+
},
242+
{
243+
[]Expression{
244+
newExpression(CoercibilityImplicit, UNICODE, charset.CharsetUTF8MB4, charset.CollationUTF8MB4),
245+
newExpression(CoercibilityImplicit, UNICODE, charset.CharsetLatin1, "latin1_swedish_ci"),
246+
},
247+
false,
248+
&ExprCollation{CoercibilityImplicit, UNICODE, charset.CharsetUTF8MB4, charset.CollationUTF8MB4},
249+
},
250+
// binary takes precedence over latin1_swedish_ci at equal coercibility.
251+
{
252+
[]Expression{
253+
newExpression(CoercibilityImplicit, UNICODE, charset.CharsetLatin1, "latin1_swedish_ci"),
254+
newExpression(CoercibilityImplicit, UNICODE, charset.CharsetBin, charset.CollationBin),
255+
},
256+
false,
257+
&ExprCollation{CoercibilityImplicit, UNICODE, charset.CharsetBin, charset.CollationBin},
258+
},
180259
// binary charset with non-binary charset.
181260
{
182261
[]Expression{
@@ -830,6 +909,23 @@ func TestCompareString(t *testing.T) {
830909
require.NotEqual(t, 0, types.CompareString("\U000FFFFE", "\U000FFFFF", "utf8mb4_0900_ai_ci"))
831910
require.Equal(t, 0, types.CompareString("æ", "ae", "utf8mb4_0900_ai_ci"))
832911

912+
// latin1 collations are byte-oriented, so the arguments are spelled as cp1252
913+
// bytes rather than as Go literals, which the compiler would encode as UTF-8.
914+
require.Equal(t, 0, types.CompareString("a", "A", "latin1_swedish_ci"))
915+
require.Equal(t, 0, types.CompareString("\xE9", "E", "latin1_swedish_ci"))
916+
require.Equal(t, 0, types.CompareString("a ", "a ", "latin1_swedish_ci"))
917+
require.Equal(t, 0, types.CompareString("\xDC", "Y", "latin1_swedish_ci"))
918+
// Å, Ä and Ö sort after Z rather than folding onto A and O.
919+
require.NotEqual(t, 0, types.CompareString("\xC5", "A", "latin1_swedish_ci"))
920+
require.NotEqual(t, 0, types.CompareString("\xD6", "O", "latin1_swedish_ci"))
921+
require.Equal(t, 1, types.CompareString("\xC5", "Z", "latin1_swedish_ci"))
922+
// ß folds to nothing here, unlike in the utf8 collations above.
923+
require.NotEqual(t, 0, types.CompareString("\xDF", "s", "latin1_swedish_ci"))
924+
require.NotEqual(t, 0, types.CompareString("\xDF", "ss", "latin1_swedish_ci"))
925+
926+
require.NotEqual(t, 0, types.CompareString("a", "A", "latin1_bin"))
927+
require.Equal(t, 0, types.CompareString("a ", "a ", "latin1_bin"))
928+
833929
require.NotEqual(t, 0, types.CompareString("a", "A", "binary"))
834930
require.NotEqual(t, 0, types.CompareString("À", "A", "binary"))
835931
require.NotEqual(t, 0, types.CompareString("😜", "😃", "binary"))

0 commit comments

Comments
 (0)