summaryrefslogtreecommitdiff
path: root/sql/sql_lex.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2021-03-05 20:18:28 -0800
committerIgor Babaev <igor@askmonty.org>2021-03-05 20:18:28 -0800
commitc24bcd5948bd69f336af61214c0f31165d19dc14 (patch)
tree24a449247e4055e4b659af041e32ab7dd467fb5c /sql/sql_lex.cc
parentfcc9f8b10cd2f497ff410b592808eedb3ee5f212 (diff)
downloadmariadb-git-bb-10.4-mdev-22786.tar.gz
MDEV-22786 Crashes with nested table value constructorsbb-10.4-mdev-22786
The bug caused crashes of the server when processing queries with nested table value constructors (TVC) . It happened because the grammar rules to parse TVC used the same global lists for both nested TVC and nesting TVC. As a result invalid select trees were constructed for queries with nested TVC and this led to crashes at the prepare stage. This patch provides its own lists structures for each TVC nest level. Besides the patch fixes a bug in the function wrap_tvc() that missed inheritance of the SELECT_LEX::exclude_from_table_unique_test for selects that wrapped TVCs. This inheritance is critical for specifications of derived tables that employ nested TVCs. Approved by dmitry.shulga@mariadb.com
Diffstat (limited to 'sql/sql_lex.cc')
-rw-r--r--sql/sql_lex.cc21
1 files changed, 18 insertions, 3 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 73cbcf569f5..17186e064d2 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2487,6 +2487,8 @@ void st_select_lex::init_select()
with_dep= 0;
join= 0;
lock_type= TL_READ_DEFAULT;
+ save_many_values.empty();
+ save_insert_list= 0;
tvc= 0;
in_funcs.empty();
curr_tvc_name= 0;
@@ -8897,7 +8899,6 @@ bool LEX::last_field_generated_always_as_row_end()
VERS_SYS_END_FLAG);
}
-
void st_select_lex_unit::reset_distinct()
{
union_distinct= NULL;
@@ -8913,6 +8914,20 @@ void st_select_lex_unit::reset_distinct()
}
+void LEX::save_values_list_state()
+{
+ current_select->save_many_values= many_values;
+ current_select->save_insert_list= insert_list;
+}
+
+
+void LEX::restore_values_list_state()
+{
+ many_values= current_select->save_many_values;
+ insert_list= current_select->save_insert_list;
+}
+
+
void st_select_lex_unit::fix_distinct()
{
if (union_distinct && this != union_distinct->master_unit())
@@ -9409,6 +9424,7 @@ bool LEX::parsed_insert_select(SELECT_LEX *first_select)
bool LEX::parsed_TVC_start()
{
SELECT_LEX *sel;
+ save_values_list_state();
many_values.empty();
insert_list= 0;
if (!(sel= alloc_select(TRUE)) ||
@@ -9422,14 +9438,13 @@ bool LEX::parsed_TVC_start()
SELECT_LEX *LEX::parsed_TVC_end()
{
-
SELECT_LEX *res= pop_select(); // above TVC select
if (!(res->tvc=
new (thd->mem_root) table_value_constr(many_values,
res,
res->options)))
return NULL;
- many_values.empty();
+ restore_values_list_state();
return res;
}