Skip to content

Commit a18639f

Browse files
author
Varun Gupta
committed
MDEV-23216: LONGTEXT column with collation doesn't sort
An overflow was happening with LONGTEXT columns, when the length was converted to the length in the strxfrm form (mem-comparable keys). Introduced a function to truncate the length to the max_sort_length before calculating the length of the strxfrm form.
1 parent a8d5f57 commit a18639f

File tree

4 files changed

+40
-5
lines changed

4 files changed

+40
-5
lines changed

mysql-test/main/order_by.result

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4079,4 +4079,22 @@ COUNT(DISTINCT a)
40794079
34
40804080
SET @@tmp_memory_table_size= @save_tmp_memory_table_size;
40814081
DROP TABLE t1;
4082+
#
4083+
# MDEV-23216: LONGTEXT column with collation doesn't sort
4084+
#
4085+
CREATE TABLE t1 (a LONGTEXT COLLATE utf8mb4_swedish_ci);
4086+
INSERT INTO t1 VALUES ('A'),('Z'),('B'),('Y');
4087+
SELECT * FROM t1 ORDER BY a;
4088+
a
4089+
A
4090+
B
4091+
Y
4092+
Z
4093+
SELECT * FROM t1 ORDER BY a DESC;
4094+
a
4095+
Z
4096+
Y
4097+
B
4098+
A
4099+
DROP TABLE t1;
40824100
# End of 10.5 tests

mysql-test/main/order_by.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2522,5 +2522,15 @@ SELECT COUNT(DISTINCT a) FROM t1;
25222522
SET @@tmp_memory_table_size= @save_tmp_memory_table_size;
25232523
DROP TABLE t1;
25242524

2525+
--echo #
2526+
--echo # MDEV-23216: LONGTEXT column with collation doesn't sort
2527+
--echo #
2528+
2529+
CREATE TABLE t1 (a LONGTEXT COLLATE utf8mb4_swedish_ci);
2530+
INSERT INTO t1 VALUES ('A'),('Z'),('B'),('Y');
2531+
SELECT * FROM t1 ORDER BY a;
2532+
SELECT * FROM t1 ORDER BY a DESC;
2533+
2534+
DROP TABLE t1;
25252535

25262536
--echo # End of 10.5 tests

sql/filesort.cc

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2102,9 +2102,7 @@ Type_handler_string_result::sort_length(THD *thd,
21022102
SORT_FIELD_ATTR *sortorder) const
21032103
{
21042104
CHARSET_INFO *cs;
2105-
sortorder->length= item->max_length;
2106-
set_if_smaller(sortorder->length, thd->variables.max_sort_length);
2107-
sortorder->original_length= item->max_length;
2105+
sortorder->set_length_and_original_length(thd, item->max_length);
21082106

21092107
if (use_strnxfrm((cs= item->collation.collation)))
21102108
{
@@ -2211,9 +2209,9 @@ sortlength(THD *thd, Sort_keys *sort_keys, bool *allow_packing_for_sortkeys)
22112209
{
22122210
Field *field= sortorder->field;
22132211
CHARSET_INFO *cs= sortorder->field->sort_charset();
2214-
sortorder->length= sortorder->field->sort_length();
2212+
sortorder->set_length_and_original_length(thd, field->sort_length());
2213+
22152214
sortorder->suffix_length= sortorder->field->sort_suffix_length();
2216-
sortorder->original_length= sortorder->length;
22172215
sortorder->type= field->is_packable() ?
22182216
SORT_FIELD_ATTR::VARIABLE_SIZE :
22192217
SORT_FIELD_ATTR::FIXED_SIZE;
@@ -2748,6 +2746,14 @@ bool SORT_FIELD_ATTR::check_if_packing_possible(THD *thd) const
27482746
}
27492747

27502748

2749+
void SORT_FIELD_ATTR::set_length_and_original_length(THD *thd, uint length_arg)
2750+
{
2751+
length= length_arg;
2752+
set_if_smaller(length, thd->variables.max_sort_length);
2753+
original_length= length_arg;
2754+
}
2755+
2756+
27512757
/*
27522758
Compare function used for packing sort keys
27532759
*/

sql/sql_class.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6454,6 +6454,7 @@ struct SORT_FIELD_ATTR
64546454
uchar *b, size_t *b_len);
64556455
bool check_if_packing_possible(THD *thd) const;
64566456
bool is_variable_sized() { return type == VARIABLE_SIZE; }
6457+
void set_length_and_original_length(THD *thd, uint length_arg);
64576458
};
64586459

64596460

0 commit comments

Comments
 (0)