diff options
author | Dmitry Shulga <dmitry.shulga@mariadb.com> | 2021-01-29 18:58:53 +0700 |
---|---|---|
committer | Dmitry Shulga <dmitry.shulga@mariadb.com> | 2021-01-29 18:58:53 +0700 |
commit | aada8f03d67abdb9e9d30611f92d73110ac0a2eb (patch) | |
tree | a556e62183cc85cd578a4d123a7eaa12b194e663 | |
parent | bdae8bb6fdb7e9c7875f9a3fff02eadadea50dab (diff) | |
download | mariadb-git-bb-10.3-MDEV-22786-1.tar.gz |
MDEV-22786: VALUES ((VALUES(1))) leads to SIGSEGV in Item_field::type_handlerbb-10.3-MDEV-22786-1
Draft patch based on proposal described on the bug report's page to fix the crash
-rw-r--r-- | mysql-test/main/table_value_constr.test | 5 | ||||
-rw-r--r-- | sql/sql_lex.cc | 35 | ||||
-rw-r--r-- | sql/sql_lex.h | 20 |
3 files changed, 51 insertions, 9 deletions
diff --git a/mysql-test/main/table_value_constr.test b/mysql-test/main/table_value_constr.test index e8697bef589..651c83c8a4b 100644 --- a/mysql-test/main/table_value_constr.test +++ b/mysql-test/main/table_value_constr.test @@ -1401,4 +1401,9 @@ values ((select min(a), max(b) from t1)); drop table t1; +--echo # +--echo # MDEV-22786: VALUES ((VALUES(1))) leads to SIGSEGV in Item_field::type_handler +--echo # +VALUES ((VALUES(1))); + --echo End of 10.3 tests diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index b8f6610e066..5901e9c1e50 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2426,6 +2426,9 @@ void st_select_lex::init_select() curr_tvc_name= 0; in_tvc= false; versioned_tables= 0; + save_field_list.empty(); + save_many_values.empty(); + save_insert_list= 0; } /* @@ -7686,6 +7689,20 @@ Item *st_select_lex::build_cond_for_grouping_fields(THD *thd, Item *cond, } +void st_select_lex::backup_tvc_affectable_lex_fields(LEX *lex) +{ + save_field_list= lex->field_list; + save_many_values= lex->many_values; + save_insert_list= lex->insert_list; +} + +void st_select_lex::restore_tvc_affectable_lex_fields(LEX *lex) +{ + lex->field_list= save_field_list; + lex->many_values= save_many_values; + lex->insert_list= save_insert_list; +} + int set_statement_var_if_exists(THD *thd, const char *var_name, size_t var_name_length, ulonglong value) { @@ -8276,16 +8293,30 @@ bool LEX::last_field_generated_always_as_row_end() } +void LEX::tvc_start() +{ + if (!nest_level) + current_select->init_select(); + else + current_select->backup_tvc_affectable_lex_fields(this); + + field_list.empty(); + many_values.empty(); + insert_list= 0; +} + + bool LEX::tvc_finalize() { - mysql_init_select(this); if (unlikely(!(current_select->tvc= new (thd->mem_root) table_value_constr(many_values, current_select, current_select->options)))) return true; - many_values.empty(); + + current_select->restore_tvc_affectable_lex_fields(this); + if (!current_select->master_unit()->fake_select_lex) current_select->master_unit()->add_fake_select_lex(thd); return false; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 55929ed7df6..55df258321e 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1401,7 +1401,7 @@ public: bool cond_pushdown_is_allowed() const { return !olap && !explicit_limit && !tvc; } - + private: bool m_non_agg_field_used; bool m_agg_func_used; @@ -1413,12 +1413,23 @@ private: /* a list of USE/FORCE/IGNORE INDEX */ List<Index_hint> *index_hints; + /* + The following data members are for storing original values of corresponding + LEX counterpart members changed on parse phase in TVC handling. + */ + List<Item> save_field_list; + List<List_item> save_many_values; + List<Item> *save_insert_list; public: inline void add_where_field(st_select_lex *sel) { DBUG_ASSERT(this != sel); select_n_where_fields+= sel->select_n_where_fields; } + + void backup_tvc_affectable_lex_fields(LEX *lex); + + void restore_tvc_affectable_lex_fields(LEX *lex); }; typedef class st_select_lex SELECT_LEX; @@ -4045,12 +4056,7 @@ public: return false; } - void tvc_start() - { - field_list.empty(); - many_values.empty(); - insert_list= 0; - } + void tvc_start(); bool tvc_finalize(); bool tvc_finalize_derived(); |