diff --git a/mysql-test/include/ctype_filesort2.inc b/mysql-test/include/ctype_filesort2.inc index 7b09eb482a5..7b576034136 100644 --- a/mysql-test/include/ctype_filesort2.inc +++ b/mysql-test/include/ctype_filesort2.inc @@ -14,3 +14,12 @@ SELECT HEX(a), HEX(CONVERT(a USING utf8mb4)) FROM t1 ORDER BY a; ALTER TABLE t1 ADD KEY(a); SELECT HEX(a), HEX(CONVERT(a USING utf8mb4)) FROM t1 ORDER BY a; DROP TABLE IF EXISTS t1; +--echo # +--echo # BUG#16691598 - ORDER BY LOWER(COLUMN) PRODUCES +--echo # OUT-OF-ORDER RESULTS +--echo # +CREATE TABLE t1 SELECT ('a a') as n; +INSERT INTO t1 VALUES('a b'); +SELECT * FROM t1 ORDER BY LOWER(n) ASC; +SELECT * FROM t1 ORDER BY LOWER(n) DESC; +DROP TABLE t1; diff --git a/mysql-test/r/ctype_utf16.result b/mysql-test/r/ctype_utf16.result index 42897ca580f..70b1ddde5c7 100644 --- a/mysql-test/r/ctype_utf16.result +++ b/mysql-test/r/ctype_utf16.result @@ -636,6 +636,21 @@ FF9D EFBE9D D800DF84 F0908E84 DBC0DC00 F4808080 DROP TABLE IF EXISTS t1; +# +# BUG#16691598 - ORDER BY LOWER(COLUMN) PRODUCES +# OUT-OF-ORDER RESULTS +# +CREATE TABLE t1 SELECT ('a a') as n; +INSERT INTO t1 VALUES('a b'); +SELECT * FROM t1 ORDER BY LOWER(n) ASC; +n +a a +a b +SELECT * FROM t1 ORDER BY LOWER(n) DESC; +n +a b +a a +DROP TABLE t1; select @@collation_connection; @@collation_connection utf16_bin diff --git a/mysql-test/r/ctype_utf32.result b/mysql-test/r/ctype_utf32.result index 2433f2426a4..85e6220f5e8 100644 --- a/mysql-test/r/ctype_utf32.result +++ b/mysql-test/r/ctype_utf32.result @@ -635,6 +635,21 @@ HEX(a) HEX(CONVERT(a USING utf8mb4)) 00010384 F0908E84 00100000 F4808080 DROP TABLE IF EXISTS t1; +# +# BUG#16691598 - ORDER BY LOWER(COLUMN) PRODUCES +# OUT-OF-ORDER RESULTS +# +CREATE TABLE t1 SELECT ('a a') as n; +INSERT INTO t1 VALUES('a b'); +SELECT * FROM t1 ORDER BY LOWER(n) ASC; +n +a a +a b +SELECT * FROM t1 ORDER BY LOWER(n) DESC; +n +a b +a a +DROP TABLE t1; select @@collation_connection; @@collation_connection utf32_bin diff --git a/mysql-test/r/ctype_utf8mb4.result b/mysql-test/r/ctype_utf8mb4.result index c7084134cd3..fa5abc5425f 100644 --- a/mysql-test/r/ctype_utf8mb4.result +++ b/mysql-test/r/ctype_utf8mb4.result @@ -1012,6 +1012,21 @@ EFBE9D EFBE9D F0908E84 F0908E84 F4808080 F4808080 DROP TABLE IF EXISTS t1; +# +# BUG#16691598 - ORDER BY LOWER(COLUMN) PRODUCES +# OUT-OF-ORDER RESULTS +# +CREATE TABLE t1 SELECT ('a a') as n; +INSERT INTO t1 VALUES('a b'); +SELECT * FROM t1 ORDER BY LOWER(n) ASC; +n +a a +a b +SELECT * FROM t1 ORDER BY LOWER(n) DESC; +n +a b +a a +DROP TABLE t1; select @@collation_connection; @@collation_connection utf8mb4_bin diff --git a/sql/filesort.cc b/sql/filesort.cc index 6f59c505615..20a290d24a0 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -813,8 +813,6 @@ static void make_sortkey(register SORTPARAM *param, { CHARSET_INFO *cs=item->collation.collation; char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' '); - int diff; - uint sort_field_length; if (maybe_null) *to++=1; @@ -842,25 +840,13 @@ static void make_sortkey(register SORTPARAM *param, break; } length= res->length(); - sort_field_length= sort_field->length - sort_field->suffix_length; - diff=(int) (sort_field_length - length); - if (diff < 0) - { - diff=0; - length= sort_field_length; - } - if (sort_field->suffix_length) - { - /* Store length last in result_string */ - store_length(to + sort_field_length, length, - sort_field->suffix_length); - } if (sort_field->need_strxnfrm) { char *from=(char*) res->ptr(); uint tmp_length; if ((uchar*) from == to) { + DBUG_ASSERT(sort_field->length >= length); set_if_smaller(length,sort_field->length); memcpy(param->tmp_buffer,from,length); from=param->tmp_buffer; @@ -871,6 +857,22 @@ static void make_sortkey(register SORTPARAM *param, } else { + uint diff; + uint sort_field_length= sort_field->length - + sort_field->suffix_length; + if (sort_field_length < length) + { + diff= 0; + length= sort_field_length; + } + else + diff= sort_field_length - length; + if (sort_field->suffix_length) + { + /* Store length last in result_string */ + store_length(to + sort_field_length, length, + sort_field->suffix_length); + } my_strnxfrm(cs,(uchar*)to,length,(const uchar*)res->ptr(),length); cs->cset->fill(cs, (char *)to+length,diff,fill_char); } diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index cecd4424108..f1d0e775804 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1664,7 +1664,7 @@ CHARSET_INFO my_charset_utf16_general_ci= CHARSET_INFO my_charset_utf16_bin= { 55,0,0, /* number */ - MY_CS_COMPILED|MY_CS_BINSORT|MY_CS_UNICODE|MY_CS_NONASCII, + MY_CS_COMPILED|MY_CS_BINSORT|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII, "utf16", /* cs name */ "utf16_bin", /* name */ "UTF-16 Unicode", /* comment */ diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 4976a9cf31a..62d5fbe0111 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -5435,7 +5435,8 @@ CHARSET_INFO my_charset_utf8mb4_general_ci= CHARSET_INFO my_charset_utf8mb4_bin= { 46,0,0, /* number */ - MY_CS_COMPILED|MY_CS_BINSORT|MY_CS_UNICODE|MY_CS_UNICODE_SUPPLEMENT, /* state */ + MY_CS_COMPILED|MY_CS_BINSORT|MY_CS_STRNXFRM|MY_CS_UNICODE| + MY_CS_UNICODE_SUPPLEMENT, /* state */ MY_UTF8MB4, /* cs name */ MY_UTF8MB4_BIN, /* name */ "UTF-8 Unicode", /* comment */