Commit bdae8bb6 authored by Igor Babaev's avatar Igor Babaev

MDEV-24675 Server crash when table value constructor uses a subselect

This patch actually fixes the bug MDEV-24675 and the bug MDEV-24618:
Assertion failure when TVC uses a row in the context expecting scalar value

The cause of these bugs is the same wrong call of the function that fixes
value expressions in the value list of a table value constructor.
The assertion failure happened when an expression in the value list is of
the row type. In this case an error message was expected, but it was not
issued because the function fix_fields_if_needed() was called for to
check fields of value expressions in a TVC instead of the function
fix_fields_if_needed_for_scalar() that would also check that the value
expressions are are of a scalar type.
The first bug happened when a table value expression used an expression
returned by single-row subselect. In this case the call of the
fix_fields_if_needed_for_scalar virtual function must be provided with
and address to which the single-row subselect has to be attached.

Test cases were added for each of the bugs.

Approved by Oleksandr Byelkin <sanja@mariadb.com>
parent 21809f9a
...@@ -2621,3 +2621,57 @@ EXECUTE IMMEDIATE 'VALUES (?)' USING IGNORE; ...@@ -2621,3 +2621,57 @@ EXECUTE IMMEDIATE 'VALUES (?)' USING IGNORE;
ERROR HY000: 'ignore' is not allowed in this context ERROR HY000: 'ignore' is not allowed in this context
EXECUTE IMMEDIATE 'VALUES (?)' USING DEFAULT; EXECUTE IMMEDIATE 'VALUES (?)' USING DEFAULT;
ERROR HY000: 'default' is not allowed in this context ERROR HY000: 'default' is not allowed in this context
#
# MDEV-24675: TVC using subqueries
#
values((select 1));
(select 1)
1
values (2), ((select 1));
2
2
1
values ((select 1)), (2), ((select 3));
(select 1)
1
2
3
values ((select 1), 2), (3,4), (5, (select 6));
(select 1) 2
1 2
3 4
5 6
create table t1 (a int, b int);
insert into t1 values (1,3), (2,3), (3,2), (1,2);
values((select max(a) from t1));
(select max(a) from t1)
3
values((select min(b) from t1));
(select min(b) from t1)
2
values ((select max(a) from t1), (select min(b) from t1));
(select max(a) from t1) (select min(b) from t1)
3 2
values((select * from (select max(b) from t1) as t));
(select * from (select max(b) from t1) as t)
3
drop table t1;
#
# MDEV-24618: TVC contains extra parenthesis for row expressions
# in value list
#
create table t1 (a int, b int);
insert into t1 values (1,3), (2,3);
insert into t1 values ((5,4));
ERROR 21000: Operand should contain 1 column(s)
values ((1,2));
ERROR 21000: Operand should contain 1 column(s)
select * from (values ((1,2))) dt;
ERROR 21000: Operand should contain 1 column(s)
values (1,2);
1 2
1 2
values ((select min(a), max(b) from t1));
ERROR 21000: Operand should contain 1 column(s)
drop table t1;
End of 10.3 tests
...@@ -1353,3 +1353,52 @@ VALUES (DEFAULT); ...@@ -1353,3 +1353,52 @@ VALUES (DEFAULT);
EXECUTE IMMEDIATE 'VALUES (?)' USING IGNORE; EXECUTE IMMEDIATE 'VALUES (?)' USING IGNORE;
--error ER_UNKNOWN_ERROR --error ER_UNKNOWN_ERROR
EXECUTE IMMEDIATE 'VALUES (?)' USING DEFAULT; EXECUTE IMMEDIATE 'VALUES (?)' USING DEFAULT;
--echo #
--echo # MDEV-24675: TVC using subqueries
--echo #
values((select 1));
values (2), ((select 1));
values ((select 1)), (2), ((select 3));
values ((select 1), 2), (3,4), (5, (select 6));
create table t1 (a int, b int);
insert into t1 values (1,3), (2,3), (3,2), (1,2);
values((select max(a) from t1));
values((select min(b) from t1));
values ((select max(a) from t1), (select min(b) from t1));
values((select * from (select max(b) from t1) as t));
drop table t1;
--echo #
--echo # MDEV-24618: TVC contains extra parenthesis for row expressions
--echo # in value list
--echo #
create table t1 (a int, b int);
insert into t1 values (1,3), (2,3);
--error ER_OPERAND_COLUMNS
insert into t1 values ((5,4));
--error ER_OPERAND_COLUMNS
values ((1,2));
--error ER_OPERAND_COLUMNS
select * from (values ((1,2))) dt;
values (1,2);
--error ER_OPERAND_COLUMNS
values ((select min(a), max(b) from t1));
drop table t1;
--echo End of 10.3 tests
...@@ -47,7 +47,7 @@ bool fix_fields_for_tvc(THD *thd, List_iterator_fast<List_item> &li) ...@@ -47,7 +47,7 @@ bool fix_fields_for_tvc(THD *thd, List_iterator_fast<List_item> &li)
while ((lst= li++)) while ((lst= li++))
{ {
List_iterator_fast<Item> it(*lst); List_iterator<Item> it(*lst);
Item *item; Item *item;
while ((item= it++)) while ((item= it++))
...@@ -59,7 +59,7 @@ bool fix_fields_for_tvc(THD *thd, List_iterator_fast<List_item> &li) ...@@ -59,7 +59,7 @@ bool fix_fields_for_tvc(THD *thd, List_iterator_fast<List_item> &li)
while replacing their values to NAME_CONST()s. while replacing their values to NAME_CONST()s.
So fix only those that have not been. So fix only those that have not been.
*/ */
if (item->fix_fields_if_needed(thd, 0) || if (item->fix_fields_if_needed_for_scalar(thd, it.ref()) ||
item->check_is_evaluable_expression_or_error()) item->check_is_evaluable_expression_or_error())
DBUG_RETURN(true); DBUG_RETURN(true);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment