summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Shulga <dmitry.shulga@mariadb.com>2021-01-29 18:58:53 +0700
committerDmitry Shulga <dmitry.shulga@mariadb.com>2021-01-29 18:58:53 +0700
commitaada8f03d67abdb9e9d30611f92d73110ac0a2eb (patch)
treea556e62183cc85cd578a4d123a7eaa12b194e663
parentbdae8bb6fdb7e9c7875f9a3fff02eadadea50dab (diff)
downloadmariadb-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.test5
-rw-r--r--sql/sql_lex.cc35
-rw-r--r--sql/sql_lex.h20
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();