1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-08 17:02:21 +03:00

MDEV-11848 Automatic statement repreparation changes query semantics

This commit is contained in:
Alexander Barkov
2017-01-24 17:29:51 +04:00
parent ae91690d89
commit 106fbadaba
5 changed files with 47 additions and 7 deletions

View File

@ -652,7 +652,9 @@ v1 v2
3 4 3 4
ALTER TABLE t1 ADD COLUMN v3 int; ALTER TABLE t1 ADD COLUMN v3 int;
execute stmt; 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; ALTER TABLE t1 drop COLUMN v3;
deallocate prepare stmt; deallocate prepare stmt;
'' ''
@ -670,7 +672,9 @@ v1 v2
3 4 3 4
ALTER TABLE t1 ADD COLUMN v3 int; ALTER TABLE t1 ADD COLUMN v3 int;
execute stmt; 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; ALTER TABLE t1 drop COLUMN v3;
deallocate prepare stmt; deallocate prepare stmt;
SELECT @@sql_mode; SELECT @@sql_mode;

View File

@ -742,3 +742,20 @@ DROP FUNCTION test_function;
test_function(@to_var9) test_function(@to_var9)
wxyz\_ef wxyz\_ef
# END OF CASE - STRING LILTERAL WITH BACKSLASH IN FUNCTION RETURNING STRING
DROP TABLE test_table;
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;

View File

@ -618,8 +618,7 @@ SELECT @@sql_mode;
SET STATEMENT sql_mode='ansi' FOR PREPARE stmt FROM 'SELECT "t1".* FROM t1'; SET STATEMENT sql_mode='ansi' FOR PREPARE stmt FROM 'SELECT "t1".* FROM t1';
execute stmt; execute stmt;
ALTER TABLE t1 ADD COLUMN v3 int; ALTER TABLE t1 ADD COLUMN v3 int;
# repreparation with other mode cause an error # repreparation with other mode does not cause an error
--error ER_PARSE_ERROR
execute stmt; execute stmt;
ALTER TABLE t1 drop COLUMN v3; ALTER TABLE t1 drop COLUMN v3;
deallocate prepare stmt; deallocate prepare stmt;
@ -632,8 +631,7 @@ PREPARE stmt FROM 'SELECT "t1".* FROM t1';
SET sql_mode=default; SET sql_mode=default;
execute stmt; execute stmt;
ALTER TABLE t1 ADD COLUMN v3 int; ALTER TABLE t1 ADD COLUMN v3 int;
# repreparation with other mode cause an error # repreparation with other mode does not cause an error
--error ER_PARSE_ERROR
execute stmt; execute stmt;
ALTER TABLE t1 drop COLUMN v3; ALTER TABLE t1 drop COLUMN v3;
deallocate prepare stmt; deallocate prepare stmt;

View File

@ -513,3 +513,17 @@ SET @@sql_mode= @org_mode;
--echo --echo
--echo #End of Test for Bug#12601974 --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;

View File

@ -227,6 +227,7 @@ private:
SELECT_LEX and other classes). SELECT_LEX and other classes).
*/ */
MEM_ROOT main_mem_root; MEM_ROOT main_mem_root;
sql_mode_t m_sql_mode;
private: private:
bool set_db(const char *db, uint db_length); bool set_db(const char *db, uint db_length);
bool set_parameters(String *expanded_query, bool set_parameters(String *expanded_query,
@ -3603,7 +3604,8 @@ Prepared_statement::Prepared_statement(THD *thd_arg)
param_count(0), param_count(0),
last_errno(0), last_errno(0),
flags((uint) IS_IN_USE), 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, init_sql_alloc(&main_mem_root, thd_arg->variables.query_alloc_block_size,
thd_arg->variables.query_prealloc_size, MYF(MY_THREAD_SPECIFIC)); 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; Statement stmt_backup;
Query_arena *old_stmt_arena; Query_arena *old_stmt_arena;
DBUG_ENTER("Prepared_statement::prepare"); 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. If this is an SQLCOM_PREPARE, we also increase Com_prepare_sql.
However, it seems handy if com_stmt_prepare is increased always, However, it seems handy if com_stmt_prepare is increased always,
@ -4365,6 +4368,7 @@ Prepared_statement::reprepare()
bool error; bool error;
Prepared_statement copy(thd); Prepared_statement copy(thd);
copy.m_sql_mode= m_sql_mode;
copy.set_sql_prepare(); /* To suppress sending metadata to the client. */ copy.set_sql_prepare(); /* To suppress sending metadata to the client. */
@ -4374,9 +4378,12 @@ Prepared_statement::reprepare()
&cur_db_changed)) &cur_db_changed))
return TRUE; 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)) || error= ((name.str && copy.set_name(&name)) ||
copy.prepare(query(), query_length()) || copy.prepare(query(), query_length()) ||
validate_metadata(&copy)); validate_metadata(&copy));
thd->variables.sql_mode= save_sql_mode;
if (cur_db_changed) if (cur_db_changed)
mysql_change_db(thd, &saved_cur_db_name, TRUE); mysql_change_db(thd, &saved_cur_db_name, TRUE);