[Commits] 2b4479b: MDEV-16930 Crash when VALUES in derived table contains expressions
revision-id: 2b4479bca822827c6c8cc85f45c11b36ae9aff4a (mariadb-10.3.7-109-g2b4479b) parent(s): d453374fc480112266996a1026b97654cc174c09 author: Igor Babaev committer: Igor Babaev timestamp: 2018-08-12 23:11:14 -0700 message: MDEV-16930 Crash when VALUES in derived table contains expressions This patch provides columns of the temporary table used for materialization of a table value constructor with comprehensive names. Before this patch these names were always borrowed from the items of the first row of the table value constructor. When this row contained expressions and expressions were not named then it could cause different kinds of problems. In particular if the TVC is used as the specification of a derived table this could cause a crash. --- mysql-test/main/table_value_constr.result | 17 ++++++++++++++++ mysql-test/main/table_value_constr.test | 11 ++++++++++ sql/sql_tvc.cc | 34 ++++++++++++++++++++++++++++--- 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/mysql-test/main/table_value_constr.result b/mysql-test/main/table_value_constr.result index 9e0a096..6eacc57 100644 --- a/mysql-test/main/table_value_constr.result +++ b/mysql-test/main/table_value_constr.result @@ -2097,3 +2097,20 @@ v # with t as (values (),()) select 1 from t; ERROR HY000: Row with no elements is not allowed in table value constructor in this context +# +# MDEV-16930: expression in the first row of TVC specifying derived table +# +VALUES(1+1,2); +exp_1 2 +2 2 +SELECT * FROM (VALUES(1+1,2)) t; +exp_1 2 +2 2 +PREPARE stmt FROM "SELECT * FROM (VALUES(1+1,2)) t"; +EXECUTE stmt; +exp_1 2 +2 2 +EXECUTE stmt; +exp_1 2 +2 2 +DEALLOCATE PREPARE stmt; diff --git a/mysql-test/main/table_value_constr.test b/mysql-test/main/table_value_constr.test index eb5ea59..12bae99 100644 --- a/mysql-test/main/table_value_constr.test +++ b/mysql-test/main/table_value_constr.test @@ -1075,3 +1075,14 @@ DELIMITER ;| --error ER_EMPTY_ROW_IN_TVC with t as (values (),()) select 1 from t; + +--echo # +--echo # MDEV-16930: expression in the first row of TVC specifying derived table +--echo # + +VALUES(1+1,2); +SELECT * FROM (VALUES(1+1,2)) t; +PREPARE stmt FROM "SELECT * FROM (VALUES(1+1,2)) t"; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc index 188ba8c..a184487 100644 --- a/sql/sql_tvc.cc +++ b/sql/sql_tvc.cc @@ -237,10 +237,27 @@ bool table_value_constr::prepare(THD *thd, SELECT_LEX *sl, get_type_attributes_for_tvc(thd, li, holders, lists_of_values.elements, cnt)) DBUG_RETURN(true); - + List_iterator_fast<Item> it(*first_elem); Item *item; - + + /* + Temporarily set comprehensive names for those items in the first_elem list + that have no name. Each item from the first_elem list must have a name as + this name will be used as the corresponding column name of the temporary table + that is created for the table value constructor. + */ + size_t name_len; + char buff[NAME_LEN]; + for (uint column_no= 1; (item= it++); column_no++) + { + if ((item->orig_name= item->name.str)) + continue; + name_len= my_snprintf(buff, NAME_LEN, "exp_%u", column_no); + item->set_name(thd, buff, name_len, system_charset_info); + } + + it.rewind(); sl->item_list.empty(); for (uint pos= 0; (item= it++); pos++) { @@ -254,7 +271,18 @@ bool table_value_constr::prepare(THD *thd, SELECT_LEX *sl, new_holder->fix_fields(thd, 0); sl->item_list.push_back(new_holder); } - + + /* + Restore the original names of the items in the first_elem list. + This is needed for execution of prepared statements. + */ + it.rewind(); + while((item= it++)) + { + if (!item->orig_name) + item->name= null_clex_str; + } + if (unlikely(thd->is_fatal_error)) DBUG_RETURN(true); // out of memory
participants (1)
-
IgorBabaev