Skip to content
Permalink
Browse files
MDEV-25484 Crash when parsing query using derived table containing TVC
This patch fixes parsing problems concerning derived tables that use table
value constructors (TVC) with LIMIT and ORDER BY clauses of the form
  ((VALUES ... LIMIT ...) ORDER BY ...) as dt
The fix has to be applied only to 10.3 as 10.4 that employs a different
grammar rules has no such problems. The test cases should be merged
upstream.

Approved by Oleksandr Byelkin <sanja@mariadb.com>
  • Loading branch information
igorbabaev committed Jul 23, 2021
1 parent 73d32cc commit 9fde2bb
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 5 deletions.
@@ -3062,4 +3062,42 @@ a
2
3
drop table t1;
#
# MDEV-25484: Derived table using TVC with LIMIT and ORDER BY
#
create table t1 (a int);
insert into t1 values (3), (7), (1);
select * from ( (select * from t1 limit 2) order by 1 desc) as dt;
a
7
3
(values (3), (7), (1) limit 2) order by 1 desc;
3
7
3
select * from ( (values (3), (7), (1) limit 2) order by 1 desc) as dt;
3
7
3
select * from ( select * from t1 order by 1 limit 2 ) as dt;
a
1
3
values (3),(7),(1) order by 1 limit 2;
3
1
3
select * from ( values (3),(7),(1) order by 1 limit 2 ) as dt;
3
1
3
values (3),(7),(1) union values (2),(4) order by 1 limit 2;
3
1
2
select * from (values (3),(7),(1) union values (2),(4) order by 1 limit 2) as dt;
3
1
2
drop table t1;
End of 10.3 tests
@@ -1628,4 +1628,26 @@ select * from t1;

drop table t1;


--echo #
--echo # MDEV-25484: Derived table using TVC with LIMIT and ORDER BY
--echo #

create table t1 (a int);
insert into t1 values (3), (7), (1);

select * from ( (select * from t1 limit 2) order by 1 desc) as dt;
(values (3), (7), (1) limit 2) order by 1 desc;
select * from ( (values (3), (7), (1) limit 2) order by 1 desc) as dt;


select * from ( select * from t1 order by 1 limit 2 ) as dt;
values (3),(7),(1) order by 1 limit 2;
select * from ( values (3),(7),(1) order by 1 limit 2 ) as dt;

values (3),(7),(1) union values (2),(4) order by 1 limit 2;
select * from (values (3),(7),(1) union values (2),(4) order by 1 limit 2) as dt;

drop table t1;

--echo End of 10.3 tests
@@ -8396,8 +8396,15 @@ bool LEX::tvc_finalize_derived()
thd->parse_error();
return true;
}
if (unlikely(!(current_select->tvc=
new (thd->mem_root)
table_value_constr(many_values,
current_select,
current_select->options))))
return true;
restore_values_list_state();
current_select->linkage= DERIVED_TABLE_TYPE;
return tvc_finalize();
return false;
}


@@ -12855,10 +12855,13 @@ order_clause:
created yet.
*/
SELECT_LEX *first_sl= unit->first_select();
if (unlikely(!unit->is_unit_op() &&
(first_sl->order_list.elements ||
first_sl->select_limit) &&
if (unlikely(!first_sl->next_select() && first_sl->tvc &&
unit->add_fake_select_lex(thd)))
MYSQL_YYABORT;
else if (unlikely(!unit->is_unit_op() &&
(first_sl->order_list.elements ||
first_sl->select_limit) &&
unit->add_fake_select_lex(thd)))
MYSQL_YYABORT;
}
if (sel->master_unit()->is_unit_op() && !sel->braces)
@@ -12907,7 +12910,8 @@ limit_clause_init:
LIMIT
{
SELECT_LEX *sel= Select;
if (sel->master_unit()->is_unit_op() && !sel->braces)
if (sel->master_unit()->is_unit_op() && !sel->braces &&
sel->master_unit()->fake_select_lex)
{
/* Move LIMIT that belongs to UNION to fake_select_lex */
Lex->current_select= sel->master_unit()->fake_select_lex;

0 comments on commit 9fde2bb

Please sign in to comment.