Skip to content

Commit 221cdc4

Browse files
author
Ramil Kalimullin
committed
Fix for bug#49897: crash in ptr_compare when char(0) NOT NULL
column is used for ORDER BY Problem: filesort isn't meant for null length sort data (e.g. char(0)), that leads to a server crash. Fix: disregard sort order if sort data record length is 0 (nothing to sort).
1 parent 6e351da commit 221cdc4

File tree

4 files changed

+119
-0
lines changed

4 files changed

+119
-0
lines changed

mysql-test/r/select.result

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4540,4 +4540,68 @@ id select_type table type possible_keys key key_len ref rows Extra
45404540
1 SIMPLE z system NULL NULL NULL NULL 1
45414541
Warnings:
45424542
Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01 00:00:00' AS `a`,'2001-01-01 00:00:00' AS `a` from `test`.`t1` `x` join `test`.`t1` `y` join `test`.`t1` `z` where 1
4543+
DROP TABLE t1;
4544+
#
4545+
# Bug #49897: crash in ptr_compare when char(0) NOT NULL
4546+
# column is used for ORDER BY
4547+
#
4548+
SET @old_sort_buffer_size= @@session.sort_buffer_size;
4549+
SET @@sort_buffer_size= 40000;
4550+
CREATE TABLE t1(a CHAR(0) NOT NULL);
4551+
INSERT INTO t1 VALUES (0), (0), (0);
4552+
INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
4553+
INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
4554+
INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
4555+
EXPLAIN SELECT a FROM t1 ORDER BY a;
4556+
id select_type table type possible_keys key key_len ref rows Extra
4557+
1 SIMPLE t1 ALL NULL NULL NULL NULL 24492
4558+
SELECT a FROM t1 ORDER BY a;
4559+
DROP TABLE t1;
4560+
CREATE TABLE t1(a CHAR(0) NOT NULL, b CHAR(0) NOT NULL, c int);
4561+
INSERT INTO t1 VALUES (0, 0, 0), (0, 0, 2), (0, 0, 1);
4562+
INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
4563+
INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
4564+
INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
4565+
EXPLAIN SELECT a FROM t1 ORDER BY a LIMIT 5;
4566+
id select_type table type possible_keys key key_len ref rows Extra
4567+
1 SIMPLE t1 ALL NULL NULL NULL NULL 24492
4568+
SELECT a FROM t1 ORDER BY a LIMIT 5;
4569+
a
4570+
4571+
4572+
4573+
4574+
4575+
EXPLAIN SELECT * FROM t1 ORDER BY a, b LIMIT 5;
4576+
id select_type table type possible_keys key key_len ref rows Extra
4577+
1 SIMPLE t1 ALL NULL NULL NULL NULL 24492
4578+
SELECT * FROM t1 ORDER BY a, b LIMIT 5;
4579+
a b c
4580+
0
4581+
2
4582+
1
4583+
0
4584+
2
4585+
EXPLAIN SELECT * FROM t1 ORDER BY a, b, c LIMIT 5;
4586+
id select_type table type possible_keys key key_len ref rows Extra
4587+
1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 Using filesort
4588+
SELECT * FROM t1 ORDER BY a, b, c LIMIT 5;
4589+
a b c
4590+
0
4591+
0
4592+
0
4593+
0
4594+
0
4595+
EXPLAIN SELECT * FROM t1 ORDER BY c, a LIMIT 5;
4596+
id select_type table type possible_keys key key_len ref rows Extra
4597+
1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 Using filesort
4598+
SELECT * FROM t1 ORDER BY c, a LIMIT 5;
4599+
a b c
4600+
0
4601+
0
4602+
0
4603+
0
4604+
0
4605+
SET @@sort_buffer_size= @old_sort_buffer_size;
4606+
DROP TABLE t1;
45434607
End of 5.0 tests

mysql-test/t/select.test

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3844,6 +3844,46 @@ EXPLAIN EXTENDED SELECT x.a, y.a, z.a FROM t1 x
38443844
JOIN t1 y ON x.a=y.a
38453845
JOIN t1 z ON y.a=z.a
38463846
WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00';
3847+
DROP TABLE t1;
3848+
3849+
3850+
--echo #
3851+
--echo # Bug #49897: crash in ptr_compare when char(0) NOT NULL
3852+
--echo # column is used for ORDER BY
3853+
--echo #
3854+
SET @old_sort_buffer_size= @@session.sort_buffer_size;
3855+
SET @@sort_buffer_size= 40000;
3856+
3857+
CREATE TABLE t1(a CHAR(0) NOT NULL);
3858+
--disable_warnings
3859+
INSERT INTO t1 VALUES (0), (0), (0);
3860+
--enable_warnings
3861+
INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
3862+
INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
3863+
INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12;
3864+
EXPLAIN SELECT a FROM t1 ORDER BY a;
3865+
--disable_result_log
3866+
SELECT a FROM t1 ORDER BY a;
3867+
--enable_result_log
3868+
DROP TABLE t1;
38473869

3870+
CREATE TABLE t1(a CHAR(0) NOT NULL, b CHAR(0) NOT NULL, c int);
3871+
--disable_warnings
3872+
INSERT INTO t1 VALUES (0, 0, 0), (0, 0, 2), (0, 0, 1);
3873+
--enable_warnings
3874+
INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
3875+
INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
3876+
INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12;
3877+
EXPLAIN SELECT a FROM t1 ORDER BY a LIMIT 5;
3878+
SELECT a FROM t1 ORDER BY a LIMIT 5;
3879+
EXPLAIN SELECT * FROM t1 ORDER BY a, b LIMIT 5;
3880+
SELECT * FROM t1 ORDER BY a, b LIMIT 5;
3881+
EXPLAIN SELECT * FROM t1 ORDER BY a, b, c LIMIT 5;
3882+
SELECT * FROM t1 ORDER BY a, b, c LIMIT 5;
3883+
EXPLAIN SELECT * FROM t1 ORDER BY c, a LIMIT 5;
3884+
SELECT * FROM t1 ORDER BY c, a LIMIT 5;
3885+
3886+
SET @@sort_buffer_size= @old_sort_buffer_size;
3887+
DROP TABLE t1;
38483888

38493889
--echo End of 5.0 tests

sql/filesort.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
134134
error= 1;
135135
bzero((char*) &param,sizeof(param));
136136
param.sort_length= sortlength(thd, sortorder, s_length, &multi_byte_charset);
137+
/* filesort cannot handle zero-length records. */
138+
DBUG_ASSERT(param.sort_length);
137139
param.ref_length= table->file->ref_length;
138140
param.addon_field= 0;
139141
param.addon_length= 0;

sql/sql_select.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,13 +521,26 @@ JOIN::prepare(Item ***rref_pointer_array,
521521

522522
if (order)
523523
{
524+
bool real_order= FALSE;
524525
ORDER *ord;
525526
for (ord= order; ord; ord= ord->next)
526527
{
527528
Item *item= *ord->item;
529+
/*
530+
Disregard sort order if there's only "{VAR}CHAR(0) NOT NULL" fields
531+
there. Such fields don't contain any data to sort.
532+
*/
533+
if (!real_order &&
534+
(item->type() != Item::Item::FIELD_ITEM ||
535+
((Item_field *) item)->field->maybe_null() ||
536+
((Item_field *) item)->field->sort_length()))
537+
real_order= TRUE;
538+
528539
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
529540
item->split_sum_func(thd, ref_pointer_array, all_fields);
530541
}
542+
if (!real_order)
543+
order= NULL;
531544
}
532545

533546
if (having && having->with_sum_func)

0 commit comments

Comments
 (0)