1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-07 06:01:31 +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
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;

View File

@ -742,3 +742,20 @@ DROP FUNCTION test_function;
test_function(@to_var9)
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';
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;

View File

@ -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;

View File

@ -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);