summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2017-01-24 17:29:51 +0400
committerAlexander Barkov <bar@mariadb.org>2017-01-24 17:29:51 +0400
commit106fbadaba03daf51a62c40c1edbe9afb386d149 (patch)
tree21706b3ae45900df9bbb76723718c853634e7309
parentae91690d893c13e86fd9f84e0c37fd9640bca257 (diff)
downloadmariadb-git-106fbadaba03daf51a62c40c1edbe9afb386d149.tar.gz
MDEV-11848 Automatic statement repreparation changes query semantics
-rw-r--r--mysql-test/r/set_statement.result8
-rw-r--r--mysql-test/r/sql_mode.result17
-rw-r--r--mysql-test/t/set_statement.test6
-rw-r--r--mysql-test/t/sql_mode.test14
-rw-r--r--sql/sql_prepare.cc9
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(&copy));
+ thd->variables.sql_mode= save_sql_mode;
if (cur_db_changed)
mysql_change_db(thd, &saved_cur_db_name, TRUE);