Skip to content

Commit 01e4d8e

Browse files
authored
collations: fix sorting in UCA900 collations (vitessio#12555) (vitessio#12562)
* collations: fix sorting in UCA900 collations When using the fast iterator to _compare_ two strings with an UCA collation, we need to keep in mind that the weights in the collation are in BIG ENDIAN (this is the output format for the weight strings, so we store the weights this way), so comparing them directly will not result in the proper collation order. They need to be byte-swapped before they can be compared with an arithmetic operation! * collations: comment --------- Signed-off-by: Vicent Marti <vmg@strn.cat>
1 parent af42116 commit 01e4d8e

File tree

1 file changed

+10
-6
lines changed

1 file changed

+10
-6
lines changed

go/mysql/collations/internal/uca/iter_fast_900.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func (it *FastIterator900) FastForward32(it2 *FastIterator900) int {
6666

6767
p1 := it.input
6868
p2 := it2.input
69-
var w1, w2 uint32
69+
var w1, w2 uint16
7070

7171
for len(p1) >= 4 && len(p2) >= 4 {
7272
dword1 := *(*uint32)(unsafe.Pointer(&p1[0]))
@@ -75,17 +75,20 @@ func (it *FastIterator900) FastForward32(it2 *FastIterator900) int {
7575

7676
if nonascii == 0 {
7777
if dword1 != dword2 {
78+
// Use the weight string fast tables for quick weight comparisons;
79+
// see (*FastIterator900).NextWeightBlock64 for a description of
80+
// the table format
7881
table := it.fastTable
79-
if w1, w2 = table[p1[0]], table[p2[0]]; w1 != w2 {
82+
if w1, w2 = uint16(table[p1[0]]), uint16(table[p2[0]]); w1 != w2 {
8083
goto mismatch
8184
}
82-
if w1, w2 = table[p1[1]], table[p2[1]]; w1 != w2 {
85+
if w1, w2 = uint16(table[p1[1]]), uint16(table[p2[1]]); w1 != w2 {
8386
goto mismatch
8487
}
85-
if w1, w2 = table[p1[2]], table[p2[2]]; w1 != w2 {
88+
if w1, w2 = uint16(table[p1[2]]), uint16(table[p2[2]]); w1 != w2 {
8689
goto mismatch
8790
}
88-
if w1, w2 = table[p1[3]], table[p2[3]]; w1 != w2 {
91+
if w1, w2 = uint16(table[p1[3]]), uint16(table[p2[3]]); w1 != w2 {
8992
goto mismatch
9093
}
9194
}
@@ -114,7 +117,8 @@ mismatch:
114117
it.unicode++
115118
return 0
116119
}
117-
return int(w1) - int(w2)
120+
// The weights must be byte-swapped before comparison because they're stored in big endian
121+
return int(bits.ReverseBytes16(w1)) - int(bits.ReverseBytes16(w2))
118122
}
119123

120124
// NextWeightBlock64 takes a byte slice of 16 bytes and fills it with the next

0 commit comments

Comments
 (0)