diff options
author | Alexander Barkov <bar@mariadb.org> | 2017-01-24 17:29:51 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-01-24 17:29:51 +0400 |
commit | 106fbadaba03daf51a62c40c1edbe9afb386d149 (patch) | |
tree | 21706b3ae45900df9bbb76723718c853634e7309 | |
parent | ae91690d893c13e86fd9f84e0c37fd9640bca257 (diff) | |
download | mariadb-git-106fbadaba03daf51a62c40c1edbe9afb386d149.tar.gz |
MDEV-11848 Automatic statement repreparation changes query semantics
-rw-r--r-- | mysql-test/r/set_statement.result | 8 | ||||
-rw-r--r-- | mysql-test/r/sql_mode.result | 17 | ||||
-rw-r--r-- | mysql-test/t/set_statement.test | 6 | ||||
-rw-r--r-- | mysql-test/t/sql_mode.test | 14 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 9 |
5 files changed, 47 insertions, 7 deletions
diff --git a/mysql-test/r/set_statement.result b/mysql-test/r/set_statement.result index 4cb143f6ba5..91b8aa6fe59 100644 --- a/mysql-test/r/set_statement.result +++ b/mysql-test/r/set_statement.result @@ -652,7 +652,9 @@ v1 v2 3 4 ALTER TABLE t1 ADD COLUMN v3 int; execute stmt; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '.* FROM t1' at line 1 +v1 v2 v3 +1 2 NULL +3 4 NULL ALTER TABLE t1 drop COLUMN v3; deallocate prepare stmt; '' @@ -670,7 +672,9 @@ v1 v2 3 4 ALTER TABLE t1 ADD COLUMN v3 int; execute stmt; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '.* FROM t1' at line 1 +v1 v2 v3 +1 2 NULL +3 4 NULL ALTER TABLE t1 drop COLUMN v3; deallocate prepare stmt; SELECT @@sql_mode; diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result index 782ae00bb33..04935a4a268 100644 --- a/mysql-test/r/sql_mode.result +++ b/mysql-test/r/sql_mode.result @@ -742,3 +742,20 @@ DROP FUNCTION test_function; SET @@sql_mode= @org_mode; #End of Test for Bug#12601974 +# +# MDEV-11848 Automatic statement repreparation changes query semantics +# +SET sql_mode=DEFAULT; +CREATE OR REPLACE TABLE t1 (a TEXT); +PREPARE stmt FROM 'INSERT INTO t1 (a) VALUES (2||3)'; +EXECUTE stmt; +SET sql_mode=ORACLE; +EXECUTE stmt; +ALTER TABLE t1 ADD b INT; +EXECUTE stmt; +SELECT * FROM t1; +a b +1 NULL +1 NULL +1 NULL +DROP TABLE t1; diff --git a/mysql-test/t/set_statement.test b/mysql-test/t/set_statement.test index a91c53c8dee..32f56e498df 100644 --- a/mysql-test/t/set_statement.test +++ b/mysql-test/t/set_statement.test @@ -618,8 +618,7 @@ SELECT @@sql_mode; SET STATEMENT sql_mode='ansi' FOR PREPARE stmt FROM 'SELECT "t1".* FROM t1'; execute stmt; ALTER TABLE t1 ADD COLUMN v3 int; -# repreparation with other mode cause an error ---error ER_PARSE_ERROR +# repreparation with other mode does not cause an error execute stmt; ALTER TABLE t1 drop COLUMN v3; deallocate prepare stmt; @@ -632,8 +631,7 @@ PREPARE stmt FROM 'SELECT "t1".* FROM t1'; SET sql_mode=default; execute stmt; ALTER TABLE t1 ADD COLUMN v3 int; -# repreparation with other mode cause an error ---error ER_PARSE_ERROR +# repreparation with other mode does not cause an error execute stmt; ALTER TABLE t1 drop COLUMN v3; deallocate prepare stmt; diff --git a/mysql-test/t/sql_mode.test b/mysql-test/t/sql_mode.test index 869bf45dbf3..263437a0bf1 100644 --- a/mysql-test/t/sql_mode.test +++ b/mysql-test/t/sql_mode.test @@ -513,3 +513,17 @@ SET @@sql_mode= @org_mode; --echo --echo #End of Test for Bug#12601974 + +--echo # +--echo # MDEV-11848 Automatic statement repreparation changes query semantics +--echo # +SET sql_mode=DEFAULT; +CREATE OR REPLACE TABLE t1 (a TEXT); +PREPARE stmt FROM 'INSERT INTO t1 (a) VALUES (2||3)'; +EXECUTE stmt; +SET sql_mode=ORACLE; +EXECUTE stmt; +ALTER TABLE t1 ADD b INT; +EXECUTE stmt; +SELECT * FROM t1; +DROP TABLE t1; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 735bdb73d58..f5e0244f75a 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -227,6 +227,7 @@ private: SELECT_LEX and other classes). */ MEM_ROOT main_mem_root; + sql_mode_t m_sql_mode; private: bool set_db(const char *db, uint db_length); bool set_parameters(String *expanded_query, @@ -3603,7 +3604,8 @@ Prepared_statement::Prepared_statement(THD *thd_arg) param_count(0), last_errno(0), flags((uint) IS_IN_USE), - start_param(0) + start_param(0), + m_sql_mode(thd->variables.sql_mode) { init_sql_alloc(&main_mem_root, thd_arg->variables.query_alloc_block_size, thd_arg->variables.query_prealloc_size, MYF(MY_THREAD_SPECIFIC)); @@ -3777,6 +3779,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) Statement stmt_backup; Query_arena *old_stmt_arena; DBUG_ENTER("Prepared_statement::prepare"); + DBUG_ASSERT(m_sql_mode == thd->variables.sql_mode); /* If this is an SQLCOM_PREPARE, we also increase Com_prepare_sql. However, it seems handy if com_stmt_prepare is increased always, @@ -4365,6 +4368,7 @@ Prepared_statement::reprepare() bool error; Prepared_statement copy(thd); + copy.m_sql_mode= m_sql_mode; copy.set_sql_prepare(); /* To suppress sending metadata to the client. */ @@ -4374,9 +4378,12 @@ Prepared_statement::reprepare() &cur_db_changed)) return TRUE; + sql_mode_t save_sql_mode= thd->variables.sql_mode; + thd->variables.sql_mode= m_sql_mode; error= ((name.str && copy.set_name(&name)) || copy.prepare(query(), query_length()) || validate_metadata(©)); + thd->variables.sql_mode= save_sql_mode; if (cur_db_changed) mysql_change_db(thd, &saved_cur_db_name, TRUE); |