Skip to content

Commit 3c209bf

Browse files
committed
MDEV-25994: Crash with union of my_decimal type in ORDER BY clause
When single-row subquery fails with "Subquery reutrns more than 1 row" error, it will raise an error and return NULL. On the other hand, Item_singlerow_subselect sets item->maybe_null=0 for table-less subqueries like "(SELECT not_null_value)" (*) This discrepancy (item with maybe_null=0 returning NULL) causes the code in Type_handler_decimal_result::make_sort_key_part() to crash. Fixed this by allowing inference (*) only when the subquery is NOT a UNION.
1 parent 2be617d commit 3c209bf

9 files changed

+62
-10
lines changed

mysql-test/r/order_by.result

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3508,4 +3508,24 @@ DELETE FROM t1 ORDER BY c;
35083508
DROP TABLE t1;
35093509
SET @@SESSION.max_sort_length=DEFAULT;
35103510
SET sql_mode=DEFAULT;
3511+
#
3512+
# MDEV-25994 Crash with union of my_decimal type in ORDER BY clause
3513+
#
3514+
CREATE TABLE t1 (v1 INTEGER) ;
3515+
INSERT INTO t1 (v1) VALUES (8);
3516+
UPDATE t1 SET v1 = 1 ORDER BY (SELECT 1.1 UNION SELECT -1);
3517+
ERROR 21000: Subquery returns more than 1 row
3518+
# This one must be successful
3519+
UPDATE t1 SET v1 = 2 ORDER BY (SELECT 1 UNION SELECT 1);
3520+
UPDATE t1 SET v1 = 3 ORDER BY (SELECT 'a' UNION SELECT 'b');
3521+
ERROR 21000: Subquery returns more than 1 row
3522+
# Insert some more data
3523+
INSERT INTO t1 (v1) VALUES (8),(9),(100),(-234),(46584),(0);
3524+
UPDATE t1 SET v1 = v1+1 ORDER BY (SELECT 100.122 UNION SELECT -189.2);
3525+
ERROR 21000: Subquery returns more than 1 row
3526+
# This one must be successful
3527+
UPDATE t1 SET v1 = v1-200 ORDER BY (SELECT 1 UNION SELECT 1);
3528+
UPDATE t1 SET v1 = v1 ORDER BY (SELECT 'abc' UNION SELECT 'bbb');
3529+
ERROR 21000: Subquery returns more than 1 row
3530+
DROP TABLE t1;
35113531
# End of 10.2 tests

mysql-test/r/subselect.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1261,7 +1261,7 @@ a
12611261
SHOW CREATE TABLE t1;
12621262
Table Create Table
12631263
t1 CREATE TABLE `t1` (
1264-
`a` bigint(20) NOT NULL
1264+
`a` bigint(20) DEFAULT NULL
12651265
) ENGINE=MyISAM DEFAULT CHARSET=latin1
12661266
drop table t1;
12671267
create table t1 (a int);

mysql-test/r/subselect_no_exists_to_in.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,7 @@ a
12651265
SHOW CREATE TABLE t1;
12661266
Table Create Table
12671267
t1 CREATE TABLE `t1` (
1268-
`a` bigint(20) NOT NULL
1268+
`a` bigint(20) DEFAULT NULL
12691269
) ENGINE=MyISAM DEFAULT CHARSET=latin1
12701270
drop table t1;
12711271
create table t1 (a int);

mysql-test/r/subselect_no_mat.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1268,7 +1268,7 @@ a
12681268
SHOW CREATE TABLE t1;
12691269
Table Create Table
12701270
t1 CREATE TABLE `t1` (
1271-
`a` bigint(20) NOT NULL
1271+
`a` bigint(20) DEFAULT NULL
12721272
) ENGINE=MyISAM DEFAULT CHARSET=latin1
12731273
drop table t1;
12741274
create table t1 (a int);

mysql-test/r/subselect_no_opts.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1264,7 +1264,7 @@ a
12641264
SHOW CREATE TABLE t1;
12651265
Table Create Table
12661266
t1 CREATE TABLE `t1` (
1267-
`a` bigint(20) NOT NULL
1267+
`a` bigint(20) DEFAULT NULL
12681268
) ENGINE=MyISAM DEFAULT CHARSET=latin1
12691269
drop table t1;
12701270
create table t1 (a int);

mysql-test/r/subselect_no_scache.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1267,7 +1267,7 @@ a
12671267
SHOW CREATE TABLE t1;
12681268
Table Create Table
12691269
t1 CREATE TABLE `t1` (
1270-
`a` bigint(20) NOT NULL
1270+
`a` bigint(20) DEFAULT NULL
12711271
) ENGINE=MyISAM DEFAULT CHARSET=latin1
12721272
drop table t1;
12731273
create table t1 (a int);

mysql-test/r/subselect_no_semijoin.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1264,7 +1264,7 @@ a
12641264
SHOW CREATE TABLE t1;
12651265
Table Create Table
12661266
t1 CREATE TABLE `t1` (
1267-
`a` bigint(20) NOT NULL
1267+
`a` bigint(20) DEFAULT NULL
12681268
) ENGINE=MyISAM DEFAULT CHARSET=latin1
12691269
drop table t1;
12701270
create table t1 (a int);

mysql-test/t/order_by.test

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2331,5 +2331,30 @@ DROP TABLE t1;
23312331
SET @@SESSION.max_sort_length=DEFAULT;
23322332
SET sql_mode=DEFAULT;
23332333

2334+
--echo #
2335+
--echo # MDEV-25994 Crash with union of my_decimal type in ORDER BY clause
2336+
--echo #
2337+
2338+
CREATE TABLE t1 (v1 INTEGER) ;
2339+
INSERT INTO t1 (v1) VALUES (8);
2340+
--error ER_SUBQUERY_NO_1_ROW
2341+
UPDATE t1 SET v1 = 1 ORDER BY (SELECT 1.1 UNION SELECT -1);
2342+
--echo # This one must be successful
2343+
UPDATE t1 SET v1 = 2 ORDER BY (SELECT 1 UNION SELECT 1);
2344+
--error ER_SUBQUERY_NO_1_ROW
2345+
UPDATE t1 SET v1 = 3 ORDER BY (SELECT 'a' UNION SELECT 'b');
2346+
2347+
-- echo # Insert some more data
2348+
INSERT INTO t1 (v1) VALUES (8),(9),(100),(-234),(46584),(0);
2349+
--error ER_SUBQUERY_NO_1_ROW
2350+
UPDATE t1 SET v1 = v1+1 ORDER BY (SELECT 100.122 UNION SELECT -189.2);
2351+
--echo # This one must be successful
2352+
UPDATE t1 SET v1 = v1-200 ORDER BY (SELECT 1 UNION SELECT 1);
2353+
--error ER_SUBQUERY_NO_1_ROW
2354+
UPDATE t1 SET v1 = v1 ORDER BY (SELECT 'abc' UNION SELECT 'bbb');
2355+
2356+
2357+
DROP TABLE t1;
2358+
23342359

23352360
--echo # End of 10.2 tests

sql/item_subselect.cc

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,11 +1266,18 @@ bool Item_singlerow_subselect::fix_length_and_dec()
12661266
}
12671267
unsigned_flag= value->unsigned_flag;
12681268
/*
1269-
If there are not tables in subquery then ability to have NULL value
1270-
depends on SELECT list (if single row subquery have tables then it
1271-
always can be NULL if there are not records fetched).
1269+
If the subquery has no tables (1) and is not a UNION (2), like:
1270+
1271+
(SELECT subq_value)
1272+
1273+
then its NULLability is the same as subq_value's NULLability.
1274+
1275+
(1): A subquery that uses a table will return NULL when the table is empty.
1276+
(2): A UNION subquery will return NULL if it produces a "Subquery returns
1277+
more than one row" error.
12721278
*/
1273-
if (engine->no_tables())
1279+
if (engine->no_tables() &&
1280+
engine->engine_type() != subselect_engine::UNION_ENGINE)
12741281
maybe_null= engine->may_be_null();
12751282
else
12761283
{

0 commit comments

Comments
 (0)