diff options
author | unknown <aelkin@mysql.com> | 2006-05-05 11:21:21 +0300 |
---|---|---|
committer | unknown <aelkin@mysql.com> | 2006-05-05 11:21:21 +0300 |
commit | 4ab4631b068587756e247652d000e87bdb460d1a (patch) | |
tree | 44698c3171fd396854d7b6616d38dc3cc1f31e49 /sql/item_func.cc | |
parent | e38edaefed4a74c6b21fc92c98468016a6090631 (diff) | |
download | mariadb-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.cc | 10 |
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; } |