summaryrefslogtreecommitdiff
path: root/sql/item_func.cc
diff options
context:
space:
mode:
authorunknown <aelkin@mysql.com>2006-05-05 11:21:21 +0300
committerunknown <aelkin@mysql.com>2006-05-05 11:21:21 +0300
commit4ab4631b068587756e247652d000e87bdb460d1a (patch)
tree44698c3171fd396854d7b6616d38dc3cc1f31e49 /sql/item_func.cc
parente38edaefed4a74c6b21fc92c98468016a6090631 (diff)
downloadmariadb-git-4ab4631b068587756e247652d000e87bdb460d1a.tar.gz
Bug#19136: Crashing log-bin and uninitialized user variables in a derived table
The reason of the bug is in that `get_var_with_binlog' performs missed assingment of the variables as side-effect. Doing that it eventually calls `free_underlaid_joins' to pass as an argument `thd->lex->select_lex' of the lex which belongs to the user query, not to one which is emulated i.e SET @var1:=NULL. `get_var_with_binlog' is refined to supply a temporary lex to sql_set_variables's stack. mysql-test/r/rpl_user_variables.result: results changed mysql-test/t/rpl_user_variables.test: a problematic query to be binlogged is added sql/item_func.cc: BUG#19136: Crashing log-bin and uninitialized user variables The reason of the bug is in that how `get_var_with_binlog' performs missed assingment of the variables: `free_underlaid_joins' gets as an argument `thd->lex->select_lex' which belongs to the user query, not to one which is emulated i.e SET @var1:=NULL. `get_var_with_binlog' is refined to supply a temporary lex to sql_set_variables's stack.
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r--sql/item_func.cc10
1 files changed, 10 insertions, 0 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 174a8c55d01..15e272cdef8 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2733,14 +2733,24 @@ int get_var_with_binlog(THD *thd, LEX_STRING &name,
sql_set_variables(), we could instead manually call check() and update();
this would save memory and time; but calling sql_set_variables() makes
one unique place to maintain (sql_set_variables()).
+
+ Manipulation with lex is necessary since free_underlaid_joins
+ is going to release memory belonging to the main query.
*/
List<set_var_base> tmp_var_list;
+ LEX *sav_lex= thd->lex, lex_tmp;
+ thd->lex= &lex_tmp;
+ lex_start(thd, NULL, 0);
tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name,
new Item_null())));
/* Create the variable */
if (sql_set_variables(thd, &tmp_var_list))
+ {
+ thd->lex= sav_lex;
goto err;
+ }
+ thd->lex= sav_lex;
if (!(var_entry= get_variable(&thd->user_vars, name, 0)))
goto err;
}