summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorunknown <anozdrin/alik@ibm.opbmk>2007-08-31 20:42:14 +0400
committerunknown <anozdrin/alik@ibm.opbmk>2007-08-31 20:42:14 +0400
commit7e0ad09edff587dadc3e9855fc81e1b7de8f2199 (patch)
tree38c6a445d870a736939fb8fa36bb8dc40fb08e20 /sql/sp_head.cc
parent3edb630197ae42353905325e9d1c8e78d329c23a (diff)
downloadmariadb-git-7e0ad09edff587dadc3e9855fc81e1b7de8f2199.tar.gz
Fix for BUG#25843: changing default database between PREPARE and EXECUTE
of statement breaks binlog. There were two problems discovered by this bug: 1. Default (current) database is not fixed at the creation time. That leads to wrong output of DATABASE() function. 2. Database attributes (@@collation_database) are not fixed at the creation time. That leads to wrong resultset. Binlog breakage and Query Cache wrong output happened because of the first problem. The fix is to remember the current database at the PREPARE-time and set it each time at EXECUTE. mysql-test/include/query_cache_sql_prepare.inc: The first part of the test case for BUG#25843. mysql-test/r/query_cache_ps_no_prot.result: Update result file. mysql-test/r/query_cache_ps_ps_prot.result: Update result file. mysql-test/suite/rpl/r/rpl_ps.result: Update result file. mysql-test/suite/rpl/t/rpl_ps.test: The second part of the test case for BUG#25843. sql/mysql_priv.h: Added mysql_opt_change_db() prototype. sql/sp.cc: 1. Polishing; 2. sp_use_new_db() has been removed; 3. Use mysql_opt_change_db() instead of sp_use_new_db(). sql/sp.h: sp_use_new_db() has been removed. This function has nothing to do with a) sp and b) *new* database. It was merely "switch the current database if needed". sql/sp_head.cc: 1. Polishing. 2. Use mysql_opt_change_db() instead of sp_use_new_db(). sql/sql_class.cc: Move THD::{db, db_length} into Statement. sql/sql_class.h: Move THD::{db, db_length} into Statement. sql/sql_db.cc: Introduce mysql_opt_change_db() as a replacement (and inspired by) sp_use_new_db(). sql/sql_prepare.cc: 1. Remember the current database in Prepared_statement::prepare(). 2. Switch/restore the current database in Prepared_statement::execute().
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc22
1 files changed, 13 insertions, 9 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index de8c4d89466..1c2dcef476b 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1015,9 +1015,10 @@ bool
sp_head::execute(THD *thd)
{
DBUG_ENTER("sp_head::execute");
- char old_db_buf[NAME_LEN+1];
- LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
- bool dbchanged;
+ char saved_cur_db_name_buf[NAME_LEN+1];
+ LEX_STRING saved_cur_db_name=
+ { saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
+ bool cur_db_changed= FALSE;
sp_rcontext *ctx;
bool err_status= FALSE;
uint ip= 0;
@@ -1072,8 +1073,11 @@ sp_head::execute(THD *thd)
*/
if (m_db.length &&
- (err_status= sp_use_new_db(thd, m_db, &old_db, 0, &dbchanged)))
+ (err_status= mysql_opt_change_db(thd, &m_db, &saved_cur_db_name, FALSE,
+ &cur_db_changed)))
+ {
goto done;
+ }
if ((ctx= thd->spcont))
ctx->clear_handler();
@@ -1252,14 +1256,14 @@ sp_head::execute(THD *thd)
If the DB has changed, the pointer has changed too, but the
original thd->db will then have been freed
*/
- if (dbchanged)
+ if (cur_db_changed && !thd->killed)
{
/*
- No access check when changing back to where we came from.
- (It would generate an error from mysql_change_db() when old_db=="")
+ Force switching back to the saved current database, because it may be
+ NULL. In this case, mysql_change_db() would generate an error.
*/
- if (! thd->killed)
- err_status|= mysql_change_db(thd, &old_db, TRUE);
+
+ err_status|= mysql_change_db(thd, &saved_cur_db_name, TRUE);
}
m_flags&= ~IS_INVOKED;
DBUG_PRINT("info",