#At file:///home/sven/bzr/b36826-pb_rpl_slave_status/5.1-bugteam/
2648 Sven Sandberg 2008-05-26 [merge]
Merge
added:
.bzr-mysql/
.bzr-mysql/default.conf
mysql-test/r/ps_ddl1.result
mysql-test/t/ps_ddl1.test
modified:
Makefile.am
configure.in
include/errmsg.h
include/my_global.h
include/my_sys.h
include/mysql_com.h
libmysql/errmsg.c
libmysql/libmysql.c
libmysqld/lib_sql.cc
mysql-test/r/func_misc.result
mysql-test/r/general_log_file_basic.result
mysql-test/r/grant.result
mysql-test/r/log_output_basic.result
mysql-test/r/log_state.result
mysql-test/r/ps.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_ddl.result
mysql-test/r/query_cache_merge.result
mysql-test/r/slow_query_log_file_basic.result
mysql-test/r/status.result
mysql-test/r/table_definition_cache_basic.result
mysql-test/r/trigger.result
mysql-test/r/variables.result
mysql-test/suite/rpl/t/rpl_server_id1.test
mysql-test/t/disabled.def
mysql-test/t/func_misc.test
mysql-test/t/general_log_file_basic.test
mysql-test/t/grant.test
mysql-test/t/log_output_basic.test
mysql-test/t/log_state.test
mysql-test/t/ps.test
mysql-test/t/ps_1general.test
mysql-test/t/ps_ddl.test
mysql-test/t/query_cache_merge.test
mysql-test/t/slow_query_log_file_basic.test
mysql-test/t/status.test
mysql-test/t/trigger.test
mysql-test/t/variables.test
mysys/my_alloc.c
sql/item.cc
sql/item.h
sql/log.cc
sql/my_decimal.h
sql/mysql_priv.h
sql/mysqld.cc
sql/opt_range.cc
sql/set_var.cc
sql/set_var.h
sql/share/errmsg.txt
sql/sp.cc
sql/sp.h
sql/sp_head.cc
sql/sql_acl.cc
sql/sql_base.cc
sql/sql_class.cc
sql/sql_class.h
sql/sql_cursor.cc
sql/sql_parse.cc
sql/sql_prepare.cc
sql/sql_table.cc
sql/sql_update.cc
sql/sql_yacc.yy
sql/table.h
storage/myisam/mi_create.c
tests/mysql_client_test.c
=== added directory '.bzr-mysql'
=== added file '.bzr-mysql/default.conf'
--- a/.bzr-mysql/default.conf 1970-01-01 00:00:00 +0000
+++ b/.bzr-mysql/default.conf 2008-05-22 22:25:21 +0000
@@ -0,0 +1,4 @@
+[MYSQL]
+post_commit_to = "commits@stripped"
+post_push_to = "commits@stripped"
+tree_name = "mysql-5.1"
=== modified file 'Makefile.am'
--- a/Makefile.am 2008-04-08 09:44:18 +0000
+++ b/Makefile.am 2008-05-20 07:38:17 +0000
@@ -66,7 +66,7 @@
test-pl test-force-pl test-full-pl test-force-full-pl test-force-pl-mem \
test-unit test-ps test-nr test-pr test-ns test-binlog-statement \
test-ext-funcs test-ext-rpl test-ext-partitions test-ext-jp \
- test-ext-stress test-ext test-embedded \
+ test-ext-stress test-ext test-embedded test-reprepare \
test-fast test-fast-cursor test-fast-view test-fast-prepare \
test-full-qa
@@ -111,6 +111,11 @@
echo "no program found for 'embedded' tests - skipped testing" ; \
fi
+test-reprepare:
+ cd mysql-test ; \
+ @PERL@ ./mysql-test-run.pl $(force) $(mem) --ps-protocol \
+ --mysqld=--debug=+d,reprepare_each_statement
+
test: test-unit test-ns test-pr
test-full: test test-nr test-ps
=== modified file 'configure.in'
--- a/configure.in 2008-05-18 08:42:55 +0000
+++ b/configure.in 2008-05-21 07:59:58 +0000
@@ -10,7 +10,7 @@
#
# When changing major version number please also check switch statement
# in mysqlbinlog::check_master_version().
-AM_INIT_AUTOMAKE(mysql, 5.1.25-rc)
+AM_INIT_AUTOMAKE(mysql, 5.1.26-rc)
AM_CONFIG_HEADER([include/config.h:config.h.in])
PROTOCOL_VERSION=10
=== modified file 'include/errmsg.h'
--- a/include/errmsg.h 2007-04-12 22:56:22 +0000
+++ b/include/errmsg.h 2008-05-20 16:36:26 +0000
@@ -96,6 +96,7 @@
#define CR_NOT_IMPLEMENTED 2054
#define CR_SERVER_LOST_EXTENDED 2055
#define CR_STMT_CLOSED 2056
-#define CR_ERROR_LAST /*Copy last error nr:*/ 2056
+#define CR_NEW_STMT_METADATA 2057
+#define CR_ERROR_LAST /*Copy last error nr:*/ 2057
/* Add error numbers before CR_ERROR_LAST and change it accordingly. */
=== modified file 'include/my_global.h'
--- a/include/my_global.h 2008-04-28 19:03:07 +0000
+++ b/include/my_global.h 2008-05-20 07:38:17 +0000
@@ -570,7 +570,7 @@
#define CMP_NUM(a,b) (((a) < (b)) ? -1 : ((a) == (b)) ? 0 : 1)
#define sgn(a) (((a) < 0) ? -1 : ((a) > 0) ? 1 : 0)
-#define swap_variables(t, a, b) { register t dummy; dummy= a; a= b; b= dummy; }
+#define swap_variables(t, a, b) { t dummy; dummy= a; a= b; b= dummy; }
#define test(a) ((a) ? 1 : 0)
#define set_if_bigger(a,b) do { if ((a) < (b)) (a)=(b); } while(0)
#define set_if_smaller(a,b) do { if ((a) > (b)) (a)=(b); } while(0)
=== modified file 'include/my_sys.h'
--- a/include/my_sys.h 2008-02-27 14:46:32 +0000
+++ b/include/my_sys.h 2008-05-17 21:51:18 +0000
@@ -90,6 +90,9 @@
#define ME_COLOUR1 ((1 << ME_HIGHBYTE)) /* Possibly error-colours */
#define ME_COLOUR2 ((2 << ME_HIGHBYTE))
#define ME_COLOUR3 ((3 << ME_HIGHBYTE))
+#define ME_FATALERROR 1024 /* Fatal statement error */
+#define ME_NO_WARNING_FOR_ERROR 2048 /* Don't push a warning for error */
+#define ME_NO_SP_HANDLER 4096 /* Don't call stored routine error handlers */
/* Bits in last argument to fn_format */
#define MY_REPLACE_DIR 1 /* replace dir in name with 'dir' */
=== modified file 'include/mysql_com.h'
--- a/include/mysql_com.h 2008-03-25 16:18:58 +0000
+++ b/include/mysql_com.h 2008-05-20 16:36:26 +0000
@@ -184,19 +184,38 @@
#define SERVER_MORE_RESULTS_EXISTS 8 /* Multi query - next query exists */
#define SERVER_QUERY_NO_GOOD_INDEX_USED 16
#define SERVER_QUERY_NO_INDEX_USED 32
-/*
+/**
The server was able to fulfill the clients request and opened a
read-only non-scrollable cursor for a query. This flag comes
in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands.
*/
#define SERVER_STATUS_CURSOR_EXISTS 64
-/*
+/**
This flag is sent when a read-only cursor is exhausted, in reply to
COM_STMT_FETCH command.
*/
#define SERVER_STATUS_LAST_ROW_SENT 128
#define SERVER_STATUS_DB_DROPPED 256 /* A database was dropped */
#define SERVER_STATUS_NO_BACKSLASH_ESCAPES 512
+/**
+ Sent to the client if after a prepared statement reprepare
+ we discovered that the new statement returns a different
+ number of result set columns.
+*/
+#define SERVER_STATUS_METADATA_CHANGED 1024
+
+/**
+ Server status flags that must be cleared when starting
+ execution of a new SQL statement.
+ Flags from this set are only added to the
+ current server status by the execution engine, but
+ never removed -- the execution engine expects them
+ to disappear automagically by the next command.
+*/
+#define SERVER_STATUS_CLEAR_SET (SERVER_QUERY_NO_GOOD_INDEX_USED| \
+ SERVER_QUERY_NO_INDEX_USED|\
+ SERVER_MORE_RESULTS_EXISTS|\
+ SERVER_STATUS_METADATA_CHANGED)
#define MYSQL_ERRMSG_SIZE 512
#define NET_READ_TIMEOUT 30 /* Timeout on read */
@@ -205,6 +224,7 @@
#define ONLY_KILL_QUERY 1
+
struct st_vio; /* Only C */
typedef struct st_vio Vio;
=== modified file 'libmysql/errmsg.c'
--- a/libmysql/errmsg.c 2007-04-12 22:56:22 +0000
+++ b/libmysql/errmsg.c 2008-05-20 16:36:26 +0000
@@ -84,6 +84,7 @@
"This feature is not implemented yet",
"Lost connection to MySQL server at '%s', system error: %d",
"Statement closed indirectly because of a preceeding %s() call",
+ "The number of columns in the result set differs from the number of bound buffers. You
must reset the statement, rebind the result set columns, and execute the statement
again",
""
};
@@ -149,6 +150,7 @@
"This feature is not implemented yet",
"Lost connection to MySQL server at '%s', system error: %d",
"Statement closed indirectly because of a preceeding %s() call",
+ "The number of columns in the result set differs from the number of bound buffers. You
must reset the statement, rebind the result set columns, and execute the statement
again",
""
};
@@ -212,6 +214,7 @@
"This feature is not implemented yet",
"Lost connection to MySQL server at '%s', system error: %d",
"Statement closed indirectly because of a preceeding %s() call",
+ "The number of columns in the result set differs from the number of bound buffers. You
must reset the statement, rebind the result set columns, and execute the statement
again",
""
};
#endif
=== modified file 'libmysql/libmysql.c'
--- a/libmysql/libmysql.c 2008-03-29 08:02:54 +0000
+++ b/libmysql/libmysql.c 2008-05-20 16:36:26 +0000
@@ -1706,6 +1706,7 @@
#define RESET_SERVER_SIDE 1
#define RESET_LONG_DATA 2
#define RESET_STORE_RESULT 4
+#define RESET_CLEAR_ERROR 8
static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags);
@@ -2090,7 +2091,7 @@
To be removed when all commands will fully support prepared mode.
*/
-static unsigned int alloc_stmt_fields(MYSQL_STMT *stmt)
+static void alloc_stmt_fields(MYSQL_STMT *stmt)
{
MYSQL_FIELD *fields, *field, *end;
MEM_ROOT *alloc= &stmt->mem_root;
@@ -2108,7 +2109,10 @@
!(stmt->bind= (MYSQL_BIND *) alloc_root(alloc,
sizeof(MYSQL_BIND) *
stmt->field_count)))
- return 0;
+ {
+ set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate, NULL);
+ return;
+ }
for (fields= mysql->fields, end= fields+stmt->field_count,
field= stmt->fields;
@@ -2127,13 +2131,15 @@
field->def = fields->def ? strdup_root(alloc,fields->def): 0;
field->max_length= 0;
}
- return stmt->field_count;
}
-/*
+/**
Update result set columns metadata if it was sent again in
reply to COM_STMT_EXECUTE.
+
+ @note If the new field count is different from the original one,
+ an error is set and no update is performed.
*/
static void update_stmt_fields(MYSQL_STMT *stmt)
@@ -2143,7 +2149,22 @@
MYSQL_FIELD *stmt_field= stmt->fields;
MYSQL_BIND *my_bind= stmt->bind_result_done ? stmt->bind : 0;
- DBUG_ASSERT(stmt->field_count == stmt->mysql->field_count);
+ if (stmt->field_count != stmt->mysql->field_count)
+ {
+ /*
+ The tables used in the statement were altered,
+ and the query now returns a different number of columns.
+ There is no way to continue without reallocating the bind
+ array:
+ - if the number of columns increased, mysql_stmt_fetch()
+ will write beyond allocated memory
+ - if the number of columns decreased, some user-bound
+ buffers will be left unassigned without user knowing
+ that.
+ */
+ set_stmt_error(stmt, CR_NEW_STMT_METADATA, unknown_sqlstate, NULL);
+ return;
+ }
for (; field < field_end; ++field, ++stmt_field)
{
@@ -2792,6 +2813,50 @@
}
+/**
+ Update statement result set metadata from with the new field
+ information sent during statement execute.
+
+ @pre mysql->field_count is not zero
+
+ @retval TRUE if error: out of memory or the new
+ result set has a different number of columns
+ @retval FALSE success
+*/
+
+static void reinit_result_set_metadata(MYSQL_STMT *stmt)
+{
+ /* Server has sent result set metadata */
+ if (stmt->field_count == 0)
+ {
+ /*
+ This is 'SHOW'/'EXPLAIN'-like query. Current implementation of
+ prepared statements can't send result set metadata for these queries
+ on prepare stage. Read it now.
+ */
+ alloc_stmt_fields(stmt);
+ }
+ else
+ {
+ /*
+ Update result set metadata if it for some reason changed between
+ prepare and execute, i.e.:
+ - in case of 'SELECT ?' we don't know column type unless data was
+ supplied to mysql_stmt_execute, so updated column type is sent
+ now.
+ - if data dictionary changed between prepare and execute, for
+ example a table used in the query was altered.
+ Note, that now (4.1.3) we always send metadata in reply to
+ COM_STMT_EXECUTE (even if it is not necessary), so either this or
+ previous branch always works.
+ TODO: send metadata only when it's really necessary and add a warning
+ 'Metadata changed' when it's sent twice.
+ */
+ update_stmt_fields(stmt);
+ }
+}
+
+
/*
Send placeholders data to server (if there are placeholders)
and execute prepared statement.
@@ -2847,7 +2912,7 @@
DBUG_RETURN(1);
}
- if (reset_stmt_handle(stmt, RESET_STORE_RESULT))
+ if (reset_stmt_handle(stmt, RESET_STORE_RESULT | RESET_CLEAR_ERROR))
DBUG_RETURN(1);
/*
No need to check for stmt->state: if the statement wasn't
@@ -2855,40 +2920,10 @@
*/
if (mysql->methods->stmt_execute(stmt))
DBUG_RETURN(1);
+ stmt->state= MYSQL_STMT_EXECUTE_DONE;
if (mysql->field_count)
{
- /* Server has sent result set metadata */
- if (stmt->field_count == 0)
- {
- /*
- This is 'SHOW'/'EXPLAIN'-like query. Current implementation of
- prepared statements can't send result set metadata for these queries
- on prepare stage. Read it now.
- */
- alloc_stmt_fields(stmt);
- }
- else
- {
- /*
- Update result set metadata if it for some reason changed between
- prepare and execute, i.e.:
- - in case of 'SELECT ?' we don't know column type unless data was
- supplied to mysql_stmt_execute, so updated column type is sent
- now.
- - if data dictionary changed between prepare and execute, for
- example a table used in the query was altered.
- Note, that now (4.1.3) we always send metadata in reply to
- COM_STMT_EXECUTE (even if it is not necessary), so either this or
- previous branch always works.
- TODO: send metadata only when it's really necessary and add a warning
- 'Metadata changed' when it's sent twice.
- */
- update_stmt_fields(stmt);
- }
- }
- stmt->state= MYSQL_STMT_EXECUTE_DONE;
- if (stmt->field_count)
- {
+ reinit_result_set_metadata(stmt);
if (stmt->server_status & SERVER_STATUS_CURSOR_EXISTS)
{
mysql->status= MYSQL_STATUS_READY;
@@ -2903,7 +2938,7 @@
network or b) is more efficient if all (few) result set rows are
precached on client and server's resources are freed.
*/
- DBUG_RETURN(mysql_stmt_store_result(stmt));
+ mysql_stmt_store_result(stmt);
}
else
{
@@ -2912,7 +2947,7 @@
stmt->read_row_func= stmt_read_row_unbuffered;
}
}
- DBUG_RETURN(0);
+ DBUG_RETURN(test(stmt->last_errno));
}
@@ -4766,6 +4801,12 @@
DBUG_RETURN(1);
}
+ if (stmt->last_errno)
+ {
+ /* An attempt to use an invalid statement handle. */
+ DBUG_RETURN(1);
+ }
+
if (mysql->status == MYSQL_STATUS_READY &&
stmt->server_status & SERVER_STATUS_CURSOR_EXISTS)
{
@@ -4973,9 +5014,10 @@
stmt->state= MYSQL_STMT_INIT_DONE;
return 1;
}
- stmt_clear_error(stmt);
}
}
+ if (flags & RESET_CLEAR_ERROR)
+ stmt_clear_error(stmt);
stmt->state= MYSQL_STMT_PREPARE_DONE;
}
return 0;
@@ -4986,7 +5028,8 @@
DBUG_ENTER("mysql_stmt_free_result");
/* Free the client side and close the server side cursor if there is one */
- DBUG_RETURN(reset_stmt_handle(stmt, RESET_LONG_DATA | RESET_STORE_RESULT));
+ DBUG_RETURN(reset_stmt_handle(stmt, RESET_LONG_DATA | RESET_STORE_RESULT |
+ RESET_CLEAR_ERROR));
}
/********************************************************************
@@ -5067,7 +5110,9 @@
DBUG_RETURN(1);
}
/* Reset the client and server sides of the prepared statement */
- DBUG_RETURN(reset_stmt_handle(stmt, RESET_SERVER_SIDE | RESET_LONG_DATA));
+ DBUG_RETURN(reset_stmt_handle(stmt,
+ RESET_SERVER_SIDE | RESET_LONG_DATA |
+ RESET_CLEAR_ERROR));
}
/*
=== modified file 'libmysqld/lib_sql.cc'
--- a/libmysqld/lib_sql.cc 2008-05-12 10:10:57 +0000
+++ b/libmysqld/lib_sql.cc 2008-05-20 07:38:17 +0000
@@ -285,7 +285,7 @@
my_bool res;
int4store(header, stmt->stmt_id);
- header[4]= (uchar)stmt->flags;
+ header[4]= (uchar) stmt->flags;
thd= (THD*)stmt->mysql->thd;
thd->client_param_count= stmt->param_count;
thd->client_params= stmt->params;
=== modified file 'mysql-test/r/func_misc.result'
--- a/mysql-test/r/func_misc.result 2008-03-16 08:52:37 +0000
+++ b/mysql-test/r/func_misc.result 2008-05-23 15:23:55 +0000
@@ -104,41 +104,76 @@
`length(uuid())` int(10) NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
-create table t1 (a timestamp default '2005-05-05 01:01:01',
+create table t1 (id int,
+a timestamp default '2005-05-05 01:01:01',
b timestamp default '2005-05-05 01:01:01');
-insert into t1 set a = now();
-select sleep(3);
-sleep(3)
-0
-update t1 set b = now();
-select timediff(b, a) >= '00:00:03' from t1;
-timediff(b, a) >= '00:00:03'
-1
-drop table t1;
-set global query_cache_size=1355776;
-create table t1 (a int);
-insert into t1 values (1),(1),(1);
-create table t2 (a datetime default null, b datetime default null);
-insert into t2 set a = now();
-select a from t1 where sleep(1);
-a
-update t2 set b = now() where b is null;
-insert into t2 set a = now();
-select a from t1 where sleep(a);
-a
-update t2 set b = now() where b is null;
-insert into t2 set a = now();
-select a from t1 where sleep(1);
-a
-update t2 set b = now() where b is null;
-select timediff(b, a) >= '00:00:03' from t2;
-timediff(b, a) >= '00:00:03'
-1
-1
-1
-drop table t2;
-drop table t1;
-set global query_cache_size=default;
+insert into t1 set id = 1,a = now();
+select sleep(3);
+sleep(3)
+0
+update t1 set b = now() where id = 1;
+insert into t1 set id = 2,a = now();
+select sleep(3);
+sleep(3)
+0
+update t1 set b = now() where id = 2;
+select count(*) >= 1 from t1
+where timediff(b, a) between '00:00:03' and '00:00:07';
+count(*) >= 1
+1
+drop table t1;
+SET @@global.query_cache_size = 1024 * 64;
+SELECT 1 as some_value, sleep(1);
+some_value sleep(1)
+1 0
+SELECT <Qcache_queries_in_cache_before> = <Qcache_queries_in_cache_before>
+AS "Was the query not cached (= expectation)?";
+Was the query not cached (= expectation)?
+1
+DROP TEMPORARY TABLE IF EXISTS proclist_history;
+DROP TABLE IF EXISTS t1;
+CREATE TEMPORARY TABLE proclist_history AS
+SELECT 'Bug 1' AS test, 0 AS attempt, NOW() AS observation_time, state, time
+FROM information_schema.processlist WHERE 1 = 0;
+CREATE TABLE t1 (f1 BIGINT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+SET @sleep_time_per_result_row = 1;
+----- establish connection con1 (user = root) -----
+SET @sleep_time_per_result_row = 1;
+Qcache_queries_in_cache: 0
+# Send query with send, pull server responses later
+SELECT sleep(@sleep_time_per_result_row) FROM t1;
+----- switch to connection default (user = root) -----
+----- switch to connection con1 (user = root) -----
+# Pull server responses of last query
+sleep(@sleep_time_per_result_row)
+0
+0
+0
+0
+----- switch to connection con1 (user = root) -----
+# Send query with send, pull server responses later
+SELECT sleep(@sleep_time_per_result_row) FROM t1;
+----- switch to connection default (user = root) -----
+SELECT COUNT(*) FROM information_schema.processlist
+WHERE info = 'SELECT sleep(@sleep_time_per_result_row) FROM t1'
+ AND state = 'User sleep';
+COUNT(*)
+1
+----- switch to connection con1 (user = root) -----
+# Pull server responses of last query
+sleep(@sleep_time_per_result_row)
+0
+0
+0
+0
+----- switch to connection default and close connection con1 -----
+SET @@global.query_cache_size = default;
+DROP TABLE t1;
+DROP TEMPORARY TABLE proclist_history;
create table t1 select INET_ATON('255.255.0.1') as `a`;
show create table t1;
Table Create Table
=== modified file 'mysql-test/r/general_log_file_basic.result'
--- a/mysql-test/r/general_log_file_basic.result 2008-04-10 13:14:28 +0000
+++ b/mysql-test/r/general_log_file_basic.result 2008-05-20 18:23:58 +0000
@@ -9,7 +9,8 @@
master.log
'#--------------------FN_DYNVARS_004_02------------------------#'
SET @@global.general_log_file = mytest.log;
-ERROR 42000: Variable 'general_log_file' can't be set to the value of 'log'
+SET @@global.general_log_file = 12;
+ERROR 42000: Incorrect argument type to variable 'general_log_file'
'#----------------------FN_DYNVARS_004_03------------------------#'
SELECT @@global.general_log_file = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
=== modified file 'mysql-test/r/grant.result'
--- a/mysql-test/r/grant.result 2008-03-28 08:41:52 +0000
+++ b/mysql-test/r/grant.result 2008-04-19 10:58:37 +0000
@@ -1218,6 +1218,12 @@
DROP DATABASE db27878;
use test;
DROP TABLE t1;
+#
+# Bug#33275 Server crash when creating temporary table mysql.user
+#
+CREATE TEMPORARY TABLE mysql.user (id INT);
+FLUSH PRIVILEGES;
+DROP TABLE mysql.user;
drop table if exists test;
Warnings:
Note 1051 Unknown table 'test'
=== modified file 'mysql-test/r/log_output_basic.result'
--- a/mysql-test/r/log_output_basic.result 2008-04-10 13:14:28 +0000
+++ b/mysql-test/r/log_output_basic.result 2008-05-20 18:23:58 +0000
@@ -15,9 +15,10 @@
SET @@global.log_output = NULL;
ERROR 42000: Variable 'log_output' can't be set to the value of 'NULL'
SET @@global.log_output = "";
+ERROR 42000: Variable 'log_output' can't be set to the value of ''
SELECT @@global.log_output;
@@global.log_output
-
+FILE
'Bug# 34838: Empty value is allowed where as it is not specified in';
'documentation';
'#--------------------FN_DYNVARS_065_03------------------------#'
@@ -117,6 +118,7 @@
1
'#---------------------FN_DYNVARS_065_07-------------------------#'
SET @@global.log_output = 0;
+ERROR 42000: Variable 'log_output' can't be set to the value of '0'
SELECT @@global.log_output;
@@global.log_output
@@ -156,9 +158,10 @@
@@global.log_output
NONE
SET @@global.log_output = FALSE;
+ERROR 42000: Variable 'log_output' can't be set to the value of '0'
SELECT @@global.log_output;
@@global.log_output
-
+NONE
'#---------------------FN_DYNVARS_065_09----------------------#'
SET log_output = ON;
ERROR HY000: Variable 'log_output' is a GLOBAL variable and should be set with SET GLOBAL
=== modified file 'mysql-test/r/log_state.result'
--- a/mysql-test/r/log_state.result 2007-12-05 19:33:36 +0000
+++ b/mysql-test/r/log_state.result 2008-03-28 18:46:18 +0000
@@ -249,4 +249,25 @@
ERROR 42000: Variable 'slow_query_log_file' can't be set to the value of 'NULL'
set global general_log_file= @old_general_log_file;
set global slow_query_log_file= @old_slow_query_log_file;
+
+# --
+# -- Bug#32748: Inconsistent handling of assignments to
+# -- general_log_file/slow_query_log_file.
+# --
+
+SET @general_log_file_saved = @@global.general_log_file;
+SET @slow_query_log_file_saved = @@global.slow_query_log_file;
+
+SET GLOBAL general_log_file = 'bug32748.query.log';
+SET GLOBAL slow_query_log_file = 'bug32748.slow.log';
+
+SHOW VARIABLES LIKE '%log_file';
+Variable_name Value
+general_log_file bug32748.query.log
+slow_query_log_file bug32748.slow.log
+
+SET GLOBAL general_log_file = @general_log_file_saved;
+SET GLOBAL slow_query_log_file = @slow_query_log_file_saved;
+
+# -- End of Bug#32748.
End of 5.1 tests
=== modified file 'mysql-test/r/ps.result'
--- a/mysql-test/r/ps.result 2008-02-28 23:22:50 +0000
+++ b/mysql-test/r/ps.result 2008-05-20 18:43:26 +0000
@@ -2902,4 +2902,22 @@
ERROR 21000: Subquery returns more than 1 row
deallocate prepare stmt;
drop table t1, t2;
+#
+# Bug#27430 Crash in subquery code when in PS and table DDL changed
+# after PREPARE
+#
+# This part of the test doesn't work in embedded server, this is
+# why it's here. For the main test see ps_ddl*.test
+
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "show events where (1) in (select * from t1)";
+execute stmt;
+Db Name Definer Time zone Type Execute at Interval value Interval
field Starts Ends Status Originator character_set_client collation_connection Database
Collation
+drop table t1;
+create table t1 (x int);
+execute stmt;
+Db Name Definer Time zone Type Execute at Interval value Interval
field Starts Ends Status Originator character_set_client collation_connection Database
Collation
+drop table t1;
+deallocate prepare stmt;
End of 5.1 tests.
=== modified file 'mysql-test/r/ps_1general.result'
--- a/mysql-test/r/ps_1general.result 2007-09-20 09:10:05 +0000
+++ b/mysql-test/r/ps_1general.result 2008-04-08 16:01:20 +0000
@@ -143,32 +143,32 @@
);
insert into t5( a, b, c) values( 9, 'recreated table', 9);
execute stmt2 ;
-a b c
-9 recreated table 9
+a c b
+9 9 recreated table
drop table t5 ;
create table t5
(
a int primary key,
b char(30),
c int,
-d timestamp default current_timestamp
+d timestamp default '2008-02-23 09:23:45'
);
insert into t5( a, b, c) values( 9, 'recreated table', 9);
execute stmt2 ;
-a b c
-9 recreated table 9
+a b c d
+9 recreated table 9 2008-02-23 09:23:45
drop table t5 ;
create table t5
(
a int primary key,
-d timestamp default current_timestamp,
+d timestamp default '2008-02-23 09:23:45',
b char(30),
c int
);
insert into t5( a, b, c) values( 9, 'recreated table', 9);
execute stmt2 ;
-a b c
-9 recreated table 9
+a d b c
+9 2008-02-23 09:23:45 recreated table 9
drop table t5 ;
create table t5
(
@@ -189,7 +189,8 @@
);
insert into t5( f1, f2, f3) values( 9, 'recreated table', 9);
execute stmt2 ;
-ERROR 42S22: Unknown column 'test.t5.a' in 'field list'
+f1 f2 f3
+9 recreated table 9
drop table t5 ;
prepare stmt1 from ' select * from t1 where a <= 2 ' ;
execute stmt1 ;
=== modified file 'mysql-test/r/ps_ddl.result'
--- a/mysql-test/r/ps_ddl.result 2008-02-07 19:00:48 +0000
+++ b/mysql-test/r/ps_ddl.result 2008-05-20 18:43:26 +0000
@@ -1,543 +1,252 @@
-SELECT VARIABLE_VALUE from
-INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
-into @base_count ;
-set @expected = 0;
-=====================================================================
-Testing 1: NOTHING -> TABLE transitions
-=====================================================================
-drop table if exists t1;
-prepare stmt from 'select * from t1';
-ERROR 42S02: Table 'test.t1' doesn't exist
-=====================================================================
-Testing 2: NOTHING -> TEMPORARY TABLE transitions
-=====================================================================
-=====================================================================
-Testing 3: NOTHING -> VIEW transitions
-=====================================================================
-=====================================================================
-Testing 4: TABLE -> NOTHING transitions
-=====================================================================
-drop table if exists t4;
-create table t4(a int);
-prepare stmt from 'select * from t4';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t4;
-execute stmt;
-ERROR 42S02: Table 'test.t4' doesn't exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-ERROR 42S02: Table 'test.t4' doesn't exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-=====================================================================
-Testing 5: TABLE -> TABLE (DDL) transitions
-=====================================================================
-drop table if exists t5;
-create table t5(a int);
-prepare stmt from 'select a from t5';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t5 add column (b int);
-set @expected = @expected + 1;
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t5;
-=====================================================================
-Testing 6: TABLE -> TABLE (TRIGGER) transitions
-=====================================================================
-drop table if exists t6;
-create table t6(a int);
-prepare stmt from 'insert into t6(a) value (?)';
+drop temporary table if exists t1, t2, t3;
+drop table if exists t1, t2, t3;
+drop procedure if exists p_verify_reprepare_count;
+drop procedure if exists p1;
+drop function if exists f1;
+drop view if exists v1, v2;
+create procedure p_verify_reprepare_count(expected int)
+begin
+declare old_reprepare_count int default @reprepare_count;
+select variable_value from
+information_schema.session_status where
+variable_name='com_stmt_reprepare'
+ into @reprepare_count;
+if old_reprepare_count + expected <> @reprepare_count then
+select concat("Expected: ", expected,
+", actual: ", @reprepare_count - old_reprepare_count)
+as "ERROR";
+else
+select '' as "SUCCESS";
+end if;
+end|
+set @reprepare_count= 0;
+flush status;
+=====================================================================
+Part 1: NOTHING -> TABLE transitions
+=====================================================================
+prepare stmt from "select * from t1";
+ERROR 42S02: Table 'test.t1' doesn't exist
+=====================================================================
+Part 2: NOTHING -> TEMPORARY TABLE transitions
+=====================================================================
+=====================================================================
+Part 3: NOTHING -> VIEW transitions
+=====================================================================
+=====================================================================
+Part 4: TABLE -> NOTHING transitions
+=====================================================================
+# Test 4-a: select ... from <table>
+create table t1 (a int);
+prepare stmt from "select * from t1";
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t1;
+execute stmt;
+ERROR 42S02: Table 'test.t1' doesn't exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+execute stmt;
+ERROR 42S02: Table 'test.t1' doesn't exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+deallocate prepare stmt;
+# Test 4-b: TABLE -> NOTHING by renaming the table
+create table t1 (a int);
+prepare stmt from "select * from t1";
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+rename table t1 to t2;
+execute stmt;
+ERROR 42S02: Table 'test.t1' doesn't exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+execute stmt;
+ERROR 42S02: Table 'test.t1' doesn't exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+deallocate prepare stmt;
+drop table t2;
+=====================================================================
+Part 5: TABLE -> TABLE (DDL) transitions
+=====================================================================
+create table t1 (a int);
+prepare stmt from "select a from t1";
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+alter table t1 add column (b int);
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t1;
+deallocate prepare stmt;
+=====================================================================
+Part 6: TABLE -> TABLE (TRIGGER) transitions
+=====================================================================
+# Test 6-a: adding a relevant trigger
+create table t1 (a int);
+prepare stmt from "insert into t1 (a) value (?)";
set @val=1;
execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+call p_verify_reprepare_count(0);
+SUCCESS
+
+create trigger t1_bi before insert on t1 for each row
+set @message= new.a;
set @val=2;
execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-create trigger t6_bi before insert on t6 for each row
-begin
-set @message= "t6_bi";
-end
-$$
-set @message="none";
+call p_verify_reprepare_count(1);
+SUCCESS
+
+select @message;
+@message
+2
set @val=3;
-set @expected = @expected + 1;
execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+call p_verify_reprepare_count(0);
+SUCCESS
+
select @message;
@message
-t6_bi
+3
+prepare stmt from "insert into t1 (a) value (?)";
set @val=4;
execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+call p_verify_reprepare_count(0);
+SUCCESS
+
select @message;
@message
-t6_bi
-prepare stmt from 'insert into t6(a) value (?)';
-set @message="none";
+4
+# Test 6-b: adding an irrelevant trigger
+create trigger t1_bd before delete on t1 for each row
+set @message= old.a;
set @val=5;
execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+call p_verify_reprepare_count(1);
+SUCCESS
+
select @message;
@message
-t6_bi
-set @message="none";
+5
set @val=6;
execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+call p_verify_reprepare_count(0);
+SUCCESS
+
select @message;
@message
-t6_bi
-create trigger t6_bd before delete on t6 for each row
-begin
-set @message= "t6_bd";
-end
-$$
-set @message="none";
+6
+prepare stmt from "insert into t1 (a) value (?)";
set @val=7;
-set @expected = @expected + 1;
execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+call p_verify_reprepare_count(0);
+SUCCESS
+
select @message;
@message
-t6_bi
-set @message="none";
+7
+# Test 6-c: changing a relevant trigger
+drop trigger t1_bi;
+create trigger t1_bi before insert on t1 for each row
+set @message= concat("new trigger: ", new.a);
set @val=8;
execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+call p_verify_reprepare_count(1);
+SUCCESS
+
select @message;
@message
-t6_bi
-prepare stmt from 'insert into t6(a) value (?)';
-set @message="none";
+new trigger: 8
set @val=9;
execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+call p_verify_reprepare_count(0);
+SUCCESS
+
select @message;
@message
-t6_bi
-set @message="none";
+new trigger: 9
+prepare stmt from "insert into t1 (a) value (?)";
set @val=10;
execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+call p_verify_reprepare_count(0);
+SUCCESS
+
select @message;
@message
-t6_bi
-drop trigger t6_bi;
-create trigger t6_bi before insert on t6 for each row
-begin
-set @message= "t6_bi (2)";
-end
-$$
-set @message="none";
+new trigger: 10
+# Test 6-d: changing an irrelevant trigger
+drop trigger t1_bd;
set @val=11;
-set @expected = @expected + 1;
execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+call p_verify_reprepare_count(1);
+SUCCESS
+
select @message;
@message
-t6_bi (2)
+new trigger: 11
+Test 6-e: removing a relevant trigger
+drop trigger t1_bi;
set @val=12;
execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+call p_verify_reprepare_count(1);
+SUCCESS
+
select @message;
@message
-t6_bi (2)
-prepare stmt from 'insert into t6(a) value (?)';
-set @message="none";
+new trigger: 11
set @val=13;
execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+call p_verify_reprepare_count(0);
+SUCCESS
+
select @message;
@message
-t6_bi (2)
-set @message="none";
+new trigger: 11
+prepare stmt from "insert into t1 (a) value (?)";
set @val=14;
execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-select @message;
-@message
-t6_bi (2)
-drop trigger t6_bd;
-create trigger t6_bd before delete on t6 for each row
-begin
-set @message= "t6_bd (2)";
-end
-$$
-set @message="none";
-set @val=15;
-set @expected = @expected + 1;
-execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-select @message;
-@message
-t6_bi (2)
-set @message="none";
-set @val=16;
-execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-select @message;
-@message
-t6_bi (2)
-prepare stmt from 'insert into t6(a) value (?)';
-set @message="none";
-set @val=17;
-execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-select @message;
-@message
-t6_bi (2)
-set @message="none";
-set @val=18;
-execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-select @message;
-@message
-t6_bi (2)
-drop trigger t6_bi;
-set @message="none";
-set @val=19;
-set @expected = @expected + 1;
-execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-select @message;
-@message
-none
-set @val=20;
-execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-select @message;
-@message
-none
-prepare stmt from 'insert into t6(a) value (?)';
-set @message="none";
-set @val=21;
-execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-select @message;
-@message
-none
-set @val=22;
-execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-select @message;
-@message
-none
-drop trigger t6_bd;
-set @val=23;
-set @expected = @expected + 1;
-execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-select @message;
-@message
-none
-set @val=24;
-execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-select @message;
-@message
-none
-select * from t6 order by a;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+select @message;
+@message
+new trigger: 11
+select * from t1 order by a;
a
1
2
@@ -553,2796 +262,1116 @@
12
13
14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-drop table t6;
-=====================================================================
-Testing 7: TABLE -> TABLE (TRIGGER dependencies) transitions
-=====================================================================
-drop table if exists t7_proc;
-drop table if exists t7_func;
-drop table if exists t7_view;
-drop table if exists t7_table;
-drop table if exists t7_dependent_table;
-drop table if exists t7_table_trigger;
-drop table if exists t7_audit;
-drop procedure if exists audit_proc;
-drop function if exists audit_func;
-drop view if exists audit_view;
-create table t7_proc(a int);
-create table t7_func(a int);
-create table t7_view(a int);
-create table t7_table(a int);
-create table t7_table_trigger(a int);
-create table t7_audit(old_a int, new_a int, reason varchar(50));
-create table t7_dependent_table(old_a int, new_a int, reason varchar(50));
-create procedure audit_proc(a int)
-insert into t7_audit values (NULL, a, "proc v1");
-create function audit_func() returns varchar(50)
-return "func v1";
-create view audit_view as select "view v1" as reason from dual;
-create trigger t7_proc_bi before insert on t7_proc for each row
-call audit_proc(NEW.a);
-create trigger t7_func_bi before insert on t7_func for each row
-insert into t7_audit values (NULL, NEW.a, audit_func());
-create trigger t7_view_bi before insert on t7_view for each row
-insert into t7_audit values (NULL, NEW.a, (select reason from audit_view));
-create trigger t7_table_bi before insert on t7_table for each row
-insert into t7_dependent_table values (NULL, NEW.a, "dependent table");
-create trigger t7_table_trigger_bi before insert on t7_dependent_table
-for each row set NEW.reason="trigger v1";
-prepare stmt_proc from 'insert into t7_proc(a) value (?)';
-set @val=101;
-execute stmt_proc using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @val=102;
-execute stmt_proc using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop procedure audit_proc;
-create procedure audit_proc(a int)
-insert into t7_audit values (NULL, a, "proc v2");
-set @val=103;
-set @expected = @expected + 1;
-execute stmt_proc using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @val=104;
-execute stmt_proc using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-prepare stmt_func from 'insert into t7_func(a) value (?)';
-set @val=201;
-execute stmt_func using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @val=202;
-execute stmt_func using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop function audit_func;
-create function audit_func() returns varchar(50)
-return "func v2";
-set @val=203;
-set @expected = @expected + 1;
-execute stmt_func using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @val=204;
-execute stmt_func using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-prepare stmt_view from 'insert into t7_view(a) value (?)';
-set @val=301;
-execute stmt_view using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @val=302;
-execute stmt_view using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop view audit_view;
-create view audit_view as select "view v2" as reason from dual;
-set @val=303;
-set @expected = @expected + 1;
-execute stmt_view using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @val=304;
-execute stmt_view using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-prepare stmt_table from 'insert into t7_table(a) value (?)';
-set @val=401;
-execute stmt_table using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @val=402;
-execute stmt_table using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t7_dependent_table add column comments varchar(100) default NULL;
-set @val=403;
-set @expected = @expected + 1;
-execute stmt_table using @val;
-ERROR 21S01: Column count doesn't match value count at row 1
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @val=404;
-set @expected = @expected + 1;
-execute stmt_table using @val;
-ERROR 21S01: Column count doesn't match value count at row 1
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t7_dependent_table drop column comments;
-set @val=405;
-set @expected = @expected + 1;
-execute stmt_table using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @val=406;
-execute stmt_table using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-prepare stmt_table_trigger from 'insert into t7_table(a) value (?)';
-set @val=501;
-execute stmt_table_trigger using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @val=502;
-execute stmt_table_trigger using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop trigger t7_table_trigger_bi;
-create trigger t7_table_trigger_bi before insert on t7_dependent_table
-for each row set NEW.reason="trigger v2";
-set @val=503;
-set @expected = @expected + 1;
-execute stmt_table_trigger using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @val=504;
-execute stmt_table_trigger using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-select * from t7_audit order by new_a;
-old_a new_a reason
-NULL 101 proc v1
-NULL 102 proc v1
-NULL 103 proc v2
-NULL 104 proc v2
-NULL 201 func v1
-NULL 202 func v1
-NULL 203 func v2
-NULL 204 func v2
-NULL 301 view v1
-NULL 302 view v1
-NULL 303 view v1
-NULL 304 view v1
-select * from t7_dependent_table order by new_a;
-old_a new_a reason
-NULL 401 trigger v1
-NULL 402 trigger v1
-NULL 405 trigger v1
-NULL 406 trigger v1
-NULL 501 trigger v1
-NULL 502 trigger v1
-NULL 503 trigger v2
-NULL 504 trigger v2
-drop table t7_proc;
-drop table t7_func;
-drop table t7_view;
-drop table t7_table;
-drop table t7_dependent_table;
-drop table t7_table_trigger;
-drop table t7_audit;
-drop procedure audit_proc;
-drop function audit_func;
-drop view audit_view;
-=====================================================================
-Testing 8: TABLE -> TEMPORARY TABLE transitions
-=====================================================================
-drop table if exists t8;
-create table t8(a int);
-prepare stmt from 'select * from t8';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t8;
-create temporary table t8(a int);
-set @expected = @expected + 1;
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t8;
-=====================================================================
-Testing 9: TABLE -> VIEW transitions
-=====================================================================
-drop table if exists t9;
-drop table if exists t9_b;
-create table t9(a int);
-create table t9_b(a int);
-prepare stmt from 'select * from t9';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t9;
-create view t9 as select * from t9_b;
-set @expected = @expected + 1;
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop view t9;
-drop table t9_b;
-=====================================================================
-Testing 10: TEMPORARY TABLE -> NOTHING transitions
-=====================================================================
-drop temporary table if exists t10;
-create temporary table t10(a int);
-prepare stmt from 'select * from t10';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop temporary table t10;
-execute stmt;
-ERROR 42S02: Table 'test.t10' doesn't exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-ERROR 42S02: Table 'test.t10' doesn't exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-=====================================================================
-Testing 11: TEMPORARY TABLE -> TABLE transitions
-=====================================================================
-drop table if exists t11;
-drop temporary table if exists t11;
-create table t11(a int);
-insert into t11(a) value (1);
-create temporary table t11(a int);
-prepare stmt from 'select * from t11';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop temporary table t11;
-set @expected = @expected + 1;
-execute stmt;
-a
-1
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-1
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-select * from t11;
-a
-1
-drop table t11;
-=====================================================================
-Testing 12: TEMPORARY TABLE -> TEMPORARY TABLE (DDL) transitions
-=====================================================================
-drop temporary table if exists t12;
-create temporary table t12(a int);
-prepare stmt from 'select a from t12';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop temporary table t12;
-create temporary table t12(a int, b int);
-set @expected = @expected + 1;
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-select * from t12;
-a b
-drop table t12;
-=====================================================================
-Testing 13: TEMPORARY TABLE -> VIEW transitions
-=====================================================================
-drop temporary table if exists t13;
-drop table if exists t13_b;
-create temporary table t13(a int);
-create table t13_b(a int);
-prepare stmt from 'select * from t13';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop temporary table t13;
-create view t13 as select * from t13_b;
-set @expected = @expected + 1;
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop view t13;
-drop table t13_b;
-=====================================================================
-Testing 14: VIEW -> NOTHING transitions
-=====================================================================
-drop view if exists t14;
-drop table if exists t14_b;
-create table t14_b(a int);
-create view t14 as select * from t14_b;
-prepare stmt from 'select * from t14';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop view t14;
-set @expected = @expected + 1;
-execute stmt;
-ERROR 42S02: Table 'test.t14' doesn't exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @expected = @expected + 1;
-execute stmt;
-ERROR 42S02: Table 'test.t14' doesn't exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t14_b;
-=====================================================================
-Testing 15: VIEW -> TABLE transitions
-=====================================================================
-drop view if exists t15;
-drop table if exists t15_b;
-create table t15_b(a int);
-create view t15 as select * from t15_b;
-prepare stmt from 'select * from t15';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop view t15;
-create table t15(a int);
-set @expected = @expected + 1;
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t15_b;
-drop table t15;
-=====================================================================
-Testing 16: VIEW -> TEMPORARY TABLE transitions
-=====================================================================
-drop view if exists t16;
-drop table if exists t16_b;
-create table t16_b(a int);
-create view t16 as select * from t16_b;
-prepare stmt from 'select * from t16';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop view t16;
-create temporary table t16(a int);
-set @expected = @expected + 1;
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t16_b;
-drop temporary table t16;
-=====================================================================
-Testing 17: VIEW -> VIEW (DDL) transitions
-=====================================================================
-drop view if exists t17;
-drop table if exists t17_b;
-create table t17_b(a int);
-insert into t17_b values (10), (20), (30);
-create view t17 as select a, 2*a as b, 3*a as c from t17_b;
-select * from t17;
-a b c
-10 20 30
-20 40 60
-30 60 90
-prepare stmt from 'select * from t17';
-execute stmt;
-a b c
-10 20 30
-20 40 60
-30 60 90
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a b c
-10 20 30
-20 40 60
-30 60 90
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop view t17;
-create view t17 as select a, 2*a as b, 5*a as c from t17_b;
-select * from t17;
-a b c
-10 20 50
-20 40 100
-30 60 150
-set @expected = @expected + 1;
-execute stmt;
-a b c
-10 20 50
-20 40 100
-30 60 150
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a b c
-10 20 50
-20 40 100
-30 60 150
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t17_b;
-drop view t17;
-=====================================================================
-Testing 18: VIEW -> VIEW (VIEW dependencies) transitions
-=====================================================================
-drop table if exists t18;
-drop table if exists t18_dependent_table;
-drop view if exists t18_func;
-drop view if exists t18_view;
-drop view if exists t18_table;
-drop function if exists view_func;
-drop view if exists view_view;
-create table t18(a int);
-insert into t18 values (1), (2), (3);
-create function view_func(x int) returns int
-return x+1;
-create view view_view as select "view v1" as reason from dual;
-create table t18_dependent_table(a int);
-create view t18_func as select a, view_func(a) as b from t18;
-create view t18_view as select a, reason as b from t18, view_view;
-create view t18_table as select * from t18;
-prepare stmt_func from 'select * from t18_func';
-execute stmt_func;
-a b
-1 2
-2 3
-3 4
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt_func;
-a b
-1 2
-2 3
-3 4
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop function view_func;
-create function view_func(x int) returns int
-return x*x;
-set @expected = @expected + 1;
-execute stmt_func;
-a b
-1 1
-2 4
-3 9
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt_func;
-a b
-1 1
-2 4
-3 9
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-prepare stmt_view from 'select * from t18_view';
-execute stmt_view;
-a b
-1 view v1
-2 view v1
-3 view v1
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt_view;
-a b
-1 view v1
-2 view v1
-3 view v1
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop view view_view;
-create view view_view as select "view v2" as reason from dual;
-set @expected = @expected + 1;
-execute stmt_view;
-a b
-1 view v2
-2 view v2
-3 view v2
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt_view;
-a b
-1 view v2
-2 view v2
-3 view v2
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-prepare stmt_table from 'select * from t18_table';
-execute stmt_table;
-a
-1
-2
-3
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt_table;
-a
-1
-2
-3
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t18 add column comments varchar(50) default NULL;
-set @expected = @expected + 1;
-execute stmt_table;
-a
-1
-2
-3
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt_table;
-a
-1
-2
-3
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t18;
-drop table t18_dependent_table;
-drop view t18_func;
-drop view t18_view;
-drop view t18_table;
-drop function view_func;
-drop view view_view;
-=====================================================================
-Testing 19: Special tables (INFORMATION_SCHEMA)
-=====================================================================
-drop procedure if exists proc_19;
+drop table t1;
+deallocate prepare stmt;
+=====================================================================
+Part 7: TABLE -> TABLE (TRIGGER dependencies) transitions
+=====================================================================
+# Test 7-a: dependent PROCEDURE has changed
+#
+# Note, this scenario is not supported, subject of Bug#12093
+#
+create table t1 (a int);
+create trigger t1_ai after insert on t1 for each row
+call p1(new.a);
+create procedure p1(a int) begin end;
+prepare stmt from "insert into t1 (a) values (?)";
+set @var= 1;
+execute stmt using @var;
+drop procedure p1;
+create procedure p1 (a int) begin end;
+set @var= 2;
+execute stmt using @var;
+ERROR 42000: PROCEDURE test.p1 does not exist
+# Cleanup
+drop procedure p1;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+# Test 7-b: dependent FUNCTION has changed
+#
+# Note, this scenario is not supported, subject of Bug#12093
+#
+drop trigger t1_ai;
+create trigger t1_ai after insert on t1 for each row
+select f1(new.a+1) into @var;
+create function f1 (a int) returns int return a;
+prepare stmt from "insert into t1(a) values (?)";
+set @var=3;
+execute stmt using @var;
+select @var;
+@var
+4
+drop function f1;
+create function f1 (a int) returns int return 0;
+execute stmt using @var;
+ERROR 42000: FUNCTION test.f1 does not exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop function f1;
+deallocate prepare stmt;
+# Test 7-c: dependent VIEW has changed
+#
+# Note, this scenario is not functioning correctly, see
+# Bug#33255 Trigger using views and view ddl : corrupted triggers
+# and Bug #33000 Triggers do not detect changes in meta-data.
+#
+drop trigger t1_ai;
+create table t2 (a int unique);
+create table t3 (a int unique);
+create view v1 as select a from t2;
+create trigger t1_ai after insert on t1 for each row
+insert into v1 (a) values (new.a);
+# Demonstrate that the same bug is present
+# without prepared statements
+insert into t1 (a) values (5);
+select * from t2;
+a
+5
+select * from t3;
+a
+drop view v1;
+create view v1 as select a from t3;
+insert into t1 (a) values (6);
+ERROR 42S02: Table 'test.t2' doesn't exist
+flush table t1;
+insert into t1 (a) values (6);
+select * from t2;
+a
+5
+select * from t3;
+a
+6
+prepare stmt from "insert into t1 (a) values (?)";
+set @var=7;
+execute stmt using @var;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+select * from t3;
+a
+6
+7
+select * from t2;
+a
+5
+drop view v1;
+create view v1 as select a from t2;
+set @var=8;
+execute stmt using @var;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+#
+# Sic: the insert went into t3, even though the view now
+# points at t2. This is because neither the merged view
+# nor its prelocking list are affected by view DDL
+# The binary log is of course wrong, since it is not
+# using prepared statements
+#
+select * from t2;
+a
+5
+select * from t3;
+a
+6
+7
+8
+flush table t1;
+set @var=9;
+execute stmt using @var;
+call p_verify_reprepare_count(1);
+SUCCESS
+
+select * from t2;
+a
+5
+9
+select * from t3;
+a
+6
+7
+8
+drop view v1;
+drop table t1,t2,t3;
+# Test 7-d: dependent TABLE has changed
+create table t1 (a int);
+create trigger t1_ai after insert on t1 for each row
+insert into t2 (a) values (new.a);
+create table t2 (a int);
+prepare stmt from "insert into t1 (a) values (?)";
+set @var=1;
+execute stmt using @var;
+alter table t2 add column comment varchar(255);
+set @var=2;
+# Since the dependent table is tracked in the prelocked
+# list of the prepared statement, invalidation happens
+# and the statement is re-prepared. This is an unnecessary
+# side effect, since the statement that *is* dependent
+# on t2 definition is inside the trigger, and it is currently
+# not reprepared (see the previous test case).
+execute stmt using @var;
+call p_verify_reprepare_count(1);
+SUCCESS
+
+select * from t1;
+a
+1
+2
+select * from t2;
+a comment
+1 NULL
+2 NULL
+drop table t1,t2;
+# Test 7-e: dependent TABLE TRIGGER has changed
+create table t1 (a int);
+create trigger t1_ai after insert on t1 for each row
+insert into t2 (a) values (new.a);
+create table t2 (a int unique);
+create trigger t2_ai after insert on t2 for each row
+insert into t3 (a) values (new.a);
+create table t3 (a int unique);
+create table t4 (a int unique);
+insert into t1 (a) values (1);
+select * from t1 join t2 on (t1.a=t2.a) join t3 on (t2.a=t3.a);
+a a a
+1 1 1
+drop trigger t2_ai;
+create trigger t2_ai after insert on t2 for each row
+insert into t4 (a) values (new.a);
+insert into t1 (a) values (2);
+select * from t1 join t2 on (t1.a=t2.a) join t4 on (t2.a=t4.a);
+a a a
+2 2 2
+prepare stmt from "insert into t1 (a) values (?)";
+set @var=3;
+execute stmt using @var;
+select * from t1 join t2 on (t1.a=t2.a) join t4 on (t2.a=t4.a);
+a a a
+2 2 2
+3 3 3
+drop trigger t2_ai;
+create trigger t2_ai after insert on t2 for each row
+insert into t3 (a) values (new.a);
+set @var=4;
+execute stmt using @var;
+call p_verify_reprepare_count(1);
+SUCCESS
+
+select * from t1 join t2 on (t1.a=t2.a) join t3 on (t2.a=t3.a);
+a a a
+1 1 1
+4 4 4
+select * from t1 join t2 on (t1.a=t2.a) join t4 on (t2.a=t4.a);
+a a a
+2 2 2
+3 3 3
+drop table t1, t2, t3, t4;
+deallocate prepare stmt;
+=====================================================================
+Part 8: TABLE -> TEMPORARY TABLE transitions
+=====================================================================
+# Test 8-a: base table used recreated as temporary table
+create table t1 (a int);
+prepare stmt from "select * from t1";
+execute stmt;
+a
+drop table t1;
+create temporary table t1 (a int);
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t1;
+deallocate prepare stmt;
+# Test 8-b: temporary table has precedence over base table with same name
+create table t1 (a int);
+prepare stmt from 'select count(*) from t1';
+execute stmt;
+count(*)
+0
+call p_verify_reprepare_count(0);
+SUCCESS
+
+execute stmt;
+count(*)
+0
+call p_verify_reprepare_count(0);
+SUCCESS
+
+create temporary table t1 AS SELECT 1;
+execute stmt;
+count(*)
+1
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+count(*)
+1
+call p_verify_reprepare_count(0);
+SUCCESS
+
+deallocate prepare stmt;
+drop temporary table t1;
+drop table t1;
+=====================================================================
+Part 9: TABLE -> VIEW transitions
+=====================================================================
+create table t1 (a int);
+prepare stmt from "select * from t1";
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t1;
+create table t2 (a int);
+create view t1 as select * from t2;
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+drop view t1;
+drop table t2;
+deallocate prepare stmt;
+=====================================================================
+Part 10: TEMPORARY TABLE -> NOTHING transitions
+=====================================================================
+create temporary table t1 (a int);
+prepare stmt from "select * from t1";
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop temporary table t1;
+execute stmt;
+ERROR 42S02: Table 'test.t1' doesn't exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+deallocate prepare stmt;
+=====================================================================
+Part 11: TEMPORARY TABLE -> TABLE transitions
+=====================================================================
+# Test 11-a: temporary table replaced by base table
+create table t1 (a int);
+insert into t1 (a) value (1);
+create temporary table t1 (a int);
+prepare stmt from "select * from t1";
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop temporary table t1;
+execute stmt;
+a
+1
+call p_verify_reprepare_count(1);
+SUCCESS
+
+select * from t1;
+a
+1
+drop table t1;
+deallocate prepare stmt;
+# Test 11-b: temporary table has precedence over base table with same name
+# temporary table disappears
+create table t1 (a int);
+create temporary table t1 as select 1 as a;
+prepare stmt from "select count(*) from t1";
+execute stmt;
+count(*)
+1
+call p_verify_reprepare_count(0);
+SUCCESS
+
+execute stmt;
+count(*)
+1
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop temporary table t1;
+execute stmt;
+count(*)
+0
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+count(*)
+0
+call p_verify_reprepare_count(0);
+SUCCESS
+
+deallocate prepare stmt;
+drop table t1;
+=====================================================================
+Part 12: TEMPORARY TABLE -> TEMPORARY TABLE (DDL) transitions
+=====================================================================
+create temporary table t1 (a int);
+prepare stmt from "select a from t1";
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop temporary table t1;
+create temporary table t1 (a int, b int);
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+select * from t1;
+a b
+drop temporary table t1;
+deallocate prepare stmt;
+=====================================================================
+Part 13: TEMPORARY TABLE -> VIEW transitions
+=====================================================================
+create temporary table t1 (a int);
+create table t2 (a int);
+prepare stmt from "select * from t1";
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop temporary table t1;
+create view t1 as select * from t2;
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+drop view t1;
+drop table t2;
+deallocate prepare stmt;
+=====================================================================
+Part 14: VIEW -> NOTHING transitions
+=====================================================================
+create table t2 (a int);
+create view t1 as select * from t2;
+prepare stmt from "select * from t1";
+execute stmt;
+a
+drop view t1;
+execute stmt;
+ERROR 42S02: Table 'test.t1' doesn't exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+execute stmt;
+ERROR 42S02: Table 'test.t1' doesn't exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t2;
+deallocate prepare stmt;
+=====================================================================
+Part 15: VIEW -> TABLE transitions
+=====================================================================
+create table t2 (a int);
+create view t1 as select * from t2;
+prepare stmt from "select * from t1";
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop view t1;
+create table t1 (a int);
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+drop table t2;
+drop table t1;
+deallocate prepare stmt;
+=====================================================================
+Part 16: VIEW -> TEMPORARY TABLE transitions
+=====================================================================
+create table t2 (a int);
+insert into t2 (a) values (1);
+create view t1 as select * from t2;
+prepare stmt from "select * from t1";
+execute stmt;
+a
+1
+call p_verify_reprepare_count(0);
+SUCCESS
+
+create temporary table t1 (a int);
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+drop view t1;
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t2;
+drop temporary table t1;
+deallocate prepare stmt;
+=====================================================================
+Part 17: VIEW -> VIEW (DDL) transitions
+=====================================================================
+create table t2 (a int);
+insert into t2 values (10), (20), (30);
+create view t1 as select a, 2*a as b, 3*a as c from t2;
+select * from t1;
+a b c
+10 20 30
+20 40 60
+30 60 90
+prepare stmt from "select * from t1";
+execute stmt;
+a b c
+10 20 30
+20 40 60
+30 60 90
+drop view t1;
+create view t1 as select a, 2*a as b, 5*a as c from t2;
+select * from t1;
+a b c
+10 20 50
+20 40 100
+30 60 150
+# Currently a different result from conventional statements.
+# A view is inlined once at prepare, later on view DDL
+# does not affect prepared statement and it is not re-prepared.
+# This is reported in Bug#36002 Prepared statements: if a view
+# used in a statement is replaced, bad data
+execute stmt;
+a b c
+10 20 30
+20 40 60
+30 60 90
+call p_verify_reprepare_count(0);
+SUCCESS
+
+flush table t2;
+execute stmt;
+a b c
+10 20 50
+20 40 100
+30 60 150
+call p_verify_reprepare_count(1);
+SUCCESS
+
+drop table t2;
+drop view t1;
+deallocate prepare stmt;
+=====================================================================
+Part 18: VIEW -> VIEW (VIEW dependencies) transitions
+=====================================================================
+# Part 18a: dependent function has changed
+create table t1 (a int);
+insert into t1 (a) values (1), (2), (3);
+create function f1() returns int return (select max(a) from t1);
+create view v1 as select f1();
+prepare stmt from "select * from v1";
+execute stmt;
+f1()
+3
+execute stmt;
+f1()
+3
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop function f1;
+create function f1() returns int return 2;
+# XXX: Bug#12093. We only get a different error
+# message because the non-existing procedure error is masked
+# by the view.
+execute stmt;
+ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or
definer/invoker of view lack rights to use them
+execute stmt;
+ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or
definer/invoker of view lack rights to use them
+call p_verify_reprepare_count(0);
+SUCCESS
+
+# Part 18b: dependent procedure has changed (referred to via a function)
+create table t2 (a int);
+insert into t2 (a) values (4), (5), (6);
+drop function f1;
+create function f1() returns int
+begin
+declare x int;
+call p1(x);
+return x;
+end|
+create procedure p1(out x int) select max(a) from t1 into x;
+prepare stmt from "select * from v1";
+execute stmt;
+f1()
+3
+execute stmt;
+f1()
+3
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop procedure p1;
+create procedure p1(out x int) select max(a) from t2 into x;
+# XXX: bug. The prelocked list is not invalidated
+# and we keep opening table t1, whereas the procedure
+# is now referring to table t2
+execute stmt;
+ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or
definer/invoker of view lack rights to use them
+call p_verify_reprepare_count(0);
+SUCCESS
+
+flush table t1;
+execute stmt;
+f1()
+6
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+f1()
+6
+# Test 18-c: dependent VIEW has changed
+drop view v1;
+create view v2 as select a from t1;
+create view v1 as select * from v2;
+prepare stmt from "select * from v1";
+execute stmt;
+a
+1
+2
+3
+execute stmt;
+a
+1
+2
+3
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop view v2;
+create view v2 as select a from t2;
+execute stmt;
+a
+1
+2
+3
+execute stmt;
+a
+1
+2
+3
+call p_verify_reprepare_count(0);
+SUCCESS
+
+flush table t1;
+execute stmt;
+a
+4
+5
+6
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a
+4
+5
+6
+# Test 18-d: dependent TABLE has changed
+drop view v2;
+create table v2 as select * from t1;
+execute stmt;
+a
+1
+2
+3
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a
+1
+2
+3
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table v2;
+create table v2 (a int unique) as select * from t2;
+execute stmt;
+a
+4
+5
+6
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a
+4
+5
+6
+call p_verify_reprepare_count(0);
+SUCCESS
+
+# Test 18-e: dependent TABLE trigger has changed
+prepare stmt from "insert into v1 (a) values (?)";
+set @var= 7;
+execute stmt using @var;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+create trigger v2_bi before insert on v2 for each row set @message="v2_bi";
+set @var=8;
+execute stmt using @var;
+call p_verify_reprepare_count(1);
+SUCCESS
+
+select @message;
+@message
+v2_bi
+drop trigger v2_bi;
+set @message=null;
+set @var=9;
+execute stmt using @var;
+call p_verify_reprepare_count(1);
+SUCCESS
+
+select @message;
+@message
+NULL
+create trigger v2_bi after insert on v2 for each row set @message="v2_ai";
+set @var= 10;
+execute stmt using @var;
+call p_verify_reprepare_count(1);
+SUCCESS
+
+select @message;
+@message
+v2_ai
+select * from v1;
+a
+4
+5
+6
+7
+8
+9
+10
+# Cleanup
+drop table if exists t1, t2, v1, v2;
+drop view if exists v1, v2;
+drop function f1;
+drop procedure p1;
+deallocate prepare stmt;
+=====================================================================
+Part 19: Special tables (INFORMATION_SCHEMA)
+=====================================================================
prepare stmt from
-'select ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE
+"select ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE
from INFORMATION_SCHEMA.ROUTINES where
- routine_name=\'proc_19\'';
-create procedure proc_19() select "hi there";
-execute stmt;
-ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE
-test proc_19 PROCEDURE
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE
-test proc_19 PROCEDURE
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop procedure proc_19;
-create procedure proc_19() select "hi there, again";
-execute stmt;
-ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE
-test proc_19 PROCEDURE
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE
-test proc_19 PROCEDURE
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop procedure proc_19;
-=====================================================================
-Testing 20: Special tables (log tables)
-=====================================================================
-prepare stmt from
-'select * from mysql.general_log where argument=\'IMPOSSIBLE QUERY STRING\'';
-execute stmt;
-event_time user_host thread_id server_id command_type argument
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-event_time user_host thread_id server_id command_type argument
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-event_time user_host thread_id server_id command_type argument
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-event_time user_host thread_id server_id command_type argument
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-=====================================================================
-Testing 21: Special tables (system tables)
-=====================================================================
-drop procedure if exists proc_21;
-prepare stmt from
-'select type, db, name from mysql.proc where name=\'proc_21\'';
-create procedure proc_21() select "hi there";
-execute stmt;
-type db name
-PROCEDURE test proc_21
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-type db name
-PROCEDURE test proc_21
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop procedure proc_21;
-create procedure proc_21() select "hi there, again";
-execute stmt;
-type db name
-PROCEDURE test proc_21
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-type db name
-PROCEDURE test proc_21
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop procedure proc_21;
-=====================================================================
-Testing 22: Special tables (views temp tables)
-=====================================================================
-drop table if exists t22_b;
-drop view if exists t22;
-create table t22_b(a int);
-create algorithm=temptable view t22 as select a*a as a2 from t22_b;
-show create view t22;
+ routine_name='p1'";
+create procedure p1() select "hi there";
+execute stmt;
+ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE
+test p1 PROCEDURE
+execute stmt;
+ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE
+test p1 PROCEDURE
+drop procedure p1;
+create procedure p1() select "hi there, again";
+execute stmt;
+ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE
+test p1 PROCEDURE
+execute stmt;
+ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE
+test p1 PROCEDURE
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop procedure p1;
+deallocate prepare stmt;
+=====================================================================
+Part 20: Special tables (log tables)
+=====================================================================
+prepare stmt from
+"select * from mysql.general_log where argument='IMPOSSIBLE QUERY STRING'";
+execute stmt;
+execute stmt;
+execute stmt;
+execute stmt;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+deallocate prepare stmt;
+=====================================================================
+Part 21: Special tables (system tables)
+=====================================================================
+prepare stmt from
+"select type, db, name from mysql.proc where name='p1'";
+create procedure p1() select "hi there";
+execute stmt;
+type db name
+PROCEDURE test p1
+execute stmt;
+type db name
+PROCEDURE test p1
+drop procedure p1;
+create procedure p1() select "hi there, again";
+execute stmt;
+type db name
+PROCEDURE test p1
+execute stmt;
+type db name
+PROCEDURE test p1
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop procedure p1;
+deallocate prepare stmt;
+=====================================================================
+Part 22: Special tables (views temp tables)
+=====================================================================
+create table t1 (a int);
+create algorithm=temptable view v1 as select a*a as a2 from t1;
+# Using a temporary table internally should not confuse the prepared
+# statement code, and should not raise ER_PS_INVALIDATED errors
+show create view v1;
View Create View character_set_client collation_connection
-t22 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `t22`
AS select (`t22_b`.`a` * `t22_b`.`a`) AS `a2` from `t22_b` latin1 latin1_swedish_ci
-prepare stmt from 'select * from t22';
-insert into t22_b values (1), (2), (3);
-execute stmt;
-a2
-1
-4
-9
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a2
-1
-4
-9
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-insert into t22_b values (4), (5), (6);
-execute stmt;
-a2
-1
-4
-9
-16
-25
-36
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a2
-1
-4
-9
-16
-25
-36
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t22_b;
-drop view t22;
-=====================================================================
-Testing 23: Special tables (internal join tables)
-=====================================================================
-drop table if exists t23_a;
-drop table if exists t23_b;
-create table t23_a(a int);
-create table t23_b(b int);
-prepare stmt from 'select * from t23_a join t23_b';
-insert into t23_a values (1), (2), (3);
-insert into t23_b values (10), (20), (30);
-execute stmt;
-a b
-1 10
-2 10
-3 10
-1 20
-2 20
-3 20
-1 30
-2 30
-3 30
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a b
-1 10
-2 10
-3 10
-1 20
-2 20
-3 20
-1 30
-2 30
-3 30
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-insert into t23_a values (4);
-insert into t23_b values (40);
-execute stmt;
-a b
-1 10
-2 10
-3 10
-4 10
-1 20
-2 20
-3 20
-4 20
-1 30
-2 30
-3 30
-4 30
-1 40
-2 40
-3 40
-4 40
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a b
-1 10
-2 10
-3 10
-4 10
-1 20
-2 20
-3 20
-4 20
-1 30
-2 30
-3 30
-4 30
-1 40
-2 40
-3 40
-4 40
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t23_a;
-drop table t23_b;
-=====================================================================
-Testing 24: Special statements
-=====================================================================
-drop table if exists t24_alter;
-create table t24_alter(a int);
-prepare stmt from 'alter table t24_alter add column b int';
-execute stmt;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t24_alter;
-create table t24_alter(a1 int, a2 int);
-execute stmt;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t24_alter drop column b;
-execute stmt;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t24_alter drop column b;
-execute stmt;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t24_alter;
-drop table if exists t24_repair;
-create table t24_repair(a int);
-insert into t24_repair values (1), (2), (3);
-prepare stmt from 'repair table t24_repair';
-execute stmt;
-Table Op Msg_type Msg_text
-test.t24_repair repair status OK
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t24_repair;
-create table t24_repair(a1 int, a2 int);
-insert into t24_repair values (1, 10), (2, 20), (3, 30);
-execute stmt;
-Table Op Msg_type Msg_text
-test.t24_repair repair status OK
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t24_repair add column b varchar(50) default NULL;
-execute stmt;
-Table Op Msg_type Msg_text
-test.t24_repair repair status OK
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t24_repair drop column b;
-execute stmt;
-Table Op Msg_type Msg_text
-test.t24_repair repair status OK
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t24_repair;
-drop table if exists t24_analyze;
-create table t24_analyze(a int);
-insert into t24_analyze values (1), (2), (3);
-prepare stmt from 'analyze table t24_analyze';
-execute stmt;
-Table Op Msg_type Msg_text
-test.t24_analyze analyze status OK
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t24_analyze;
-create table t24_analyze(a1 int, a2 int);
-insert into t24_analyze values (1, 10), (2, 20), (3, 30);
-execute stmt;
-Table Op Msg_type Msg_text
-test.t24_analyze analyze status OK
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t24_analyze add column b varchar(50) default NULL;
-execute stmt;
-Table Op Msg_type Msg_text
-test.t24_analyze analyze status OK
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t24_analyze drop column b;
-execute stmt;
-Table Op Msg_type Msg_text
-test.t24_analyze analyze status OK
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t24_analyze;
-drop table if exists t24_optimize;
-create table t24_optimize(a int);
-insert into t24_optimize values (1), (2), (3);
-prepare stmt from 'optimize table t24_optimize';
-execute stmt;
-Table Op Msg_type Msg_text
-test.t24_optimize optimize status OK
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t24_optimize;
-create table t24_optimize(a1 int, a2 int);
-insert into t24_optimize values (1, 10), (2, 20), (3, 30);
-execute stmt;
-Table Op Msg_type Msg_text
-test.t24_optimize optimize status OK
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t24_optimize add column b varchar(50) default NULL;
-execute stmt;
-Table Op Msg_type Msg_text
-test.t24_optimize optimize status OK
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t24_optimize drop column b;
-execute stmt;
-Table Op Msg_type Msg_text
-test.t24_optimize optimize status OK
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t24_optimize;
-drop procedure if exists changing_proc;
-prepare stmt from 'show create procedure changing_proc';
-execute stmt;
-ERROR 42000: PROCEDURE changing_proc does not exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-ERROR 42000: PROCEDURE changing_proc does not exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-create procedure changing_proc() begin end;
-execute stmt;
-Procedure sql_mode Create Procedure character_set_client collation_connection Database
Collation
-changing_proc CREATE DEFINER=`root`@`localhost` PROCEDURE `changing_proc`()
-begin end latin1 latin1_swedish_ci latin1_swedish_ci
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-Procedure sql_mode Create Procedure character_set_client collation_connection Database
Collation
-changing_proc CREATE DEFINER=`root`@`localhost` PROCEDURE `changing_proc`()
-begin end latin1 latin1_swedish_ci latin1_swedish_ci
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop procedure changing_proc;
-create procedure changing_proc(x int, y int) begin end;
-execute stmt;
-Procedure sql_mode Create Procedure character_set_client collation_connection Database
Collation
-changing_proc CREATE DEFINER=`root`@`localhost` PROCEDURE `changing_proc`(x int, y int)
-begin end latin1 latin1_swedish_ci latin1_swedish_ci
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-Procedure sql_mode Create Procedure character_set_client collation_connection Database
Collation
-changing_proc CREATE DEFINER=`root`@`localhost` PROCEDURE `changing_proc`(x int, y int)
-begin end latin1 latin1_swedish_ci latin1_swedish_ci
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop procedure changing_proc;
-execute stmt;
-ERROR 42000: PROCEDURE changing_proc does not exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-ERROR 42000: PROCEDURE changing_proc does not exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop function if exists changing_func;
-prepare stmt from 'show create function changing_func';
-execute stmt;
-ERROR 42000: FUNCTION changing_func does not exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-ERROR 42000: FUNCTION changing_func does not exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-create function changing_func() returns int return 0;
-execute stmt;
-Function sql_mode Create Function character_set_client collation_connection Database
Collation
-changing_func CREATE DEFINER=`root`@`localhost` FUNCTION `changing_func`() RETURNS
int(11)
-return 0 latin1 latin1_swedish_ci latin1_swedish_ci
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-Function sql_mode Create Function character_set_client collation_connection Database
Collation
-changing_func CREATE DEFINER=`root`@`localhost` FUNCTION `changing_func`() RETURNS
int(11)
-return 0 latin1 latin1_swedish_ci latin1_swedish_ci
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop function changing_func;
-create function changing_func(x int, y int) returns int return x+y;
-execute stmt;
-Function sql_mode Create Function character_set_client collation_connection Database
Collation
-changing_func CREATE DEFINER=`root`@`localhost` FUNCTION `changing_func`(x int, y int)
RETURNS int(11)
-return x+y latin1 latin1_swedish_ci latin1_swedish_ci
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-Function sql_mode Create Function character_set_client collation_connection Database
Collation
-changing_func CREATE DEFINER=`root`@`localhost` FUNCTION `changing_func`(x int, y int)
RETURNS int(11)
-return x+y latin1 latin1_swedish_ci latin1_swedish_ci
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop function changing_func;
-execute stmt;
-ERROR 42000: FUNCTION changing_func does not exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-ERROR 42000: FUNCTION changing_func does not exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table if exists t24_trigger;
-create table t24_trigger(a int);
-prepare stmt from 'show create trigger t24_bi;';
-execute stmt;
-ERROR HY000: Trigger does not exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-ERROR HY000: Trigger does not exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-create trigger t24_bi before insert on t24_trigger for each row
-begin
-set @message= "t24_bi";
-end
-$$
-execute stmt;
-Trigger sql_mode SQL Original
Statement character_set_client collation_connection Database Collation
-t24_bi CREATE DEFINER=`root`@`localhost` trigger t24_bi before insert on t24_trigger for
each row
-begin
-set @message= "t24_bi";
-end latin1 latin1_swedish_ci latin1_swedish_ci
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-Trigger sql_mode SQL Original
Statement character_set_client collation_connection Database Collation
-t24_bi CREATE DEFINER=`root`@`localhost` trigger t24_bi before insert on t24_trigger for
each row
-begin
-set @message= "t24_bi";
-end latin1 latin1_swedish_ci latin1_swedish_ci
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop trigger t24_bi;
-create trigger t24_bi before insert on t24_trigger for each row
-begin
-set @message= "t24_bi (2)";
-end
-$$
-set @expected = @expected + 1;
-execute stmt;
-Trigger sql_mode SQL Original
Statement character_set_client collation_connection Database Collation
-t24_bi CREATE DEFINER=`root`@`localhost` trigger t24_bi before insert on t24_trigger for
each row
-begin
-set @message= "t24_bi (2)";
-end latin1 latin1_swedish_ci latin1_swedish_ci
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-Trigger sql_mode SQL Original
Statement character_set_client collation_connection Database Collation
-t24_bi CREATE DEFINER=`root`@`localhost` trigger t24_bi before insert on t24_trigger for
each row
-begin
-set @message= "t24_bi (2)";
-end latin1 latin1_swedish_ci latin1_swedish_ci
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop trigger t24_bi;
-execute stmt;
-ERROR HY000: Trigger does not exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-ERROR HY000: Trigger does not exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t24_trigger;
-=====================================================================
-Testing 25: Testing the strength of TABLE_SHARE version
-=====================================================================
-drop table if exists t25_num_col;
-create table t25_num_col(a int);
-prepare stmt from 'select a from t25_num_col';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t25_num_col add column b varchar(50) default NULL;
-set @expected = @expected + 1;
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t25_num_col;
-drop table if exists t25_col_name;
-create table t25_col_name(a int);
-prepare stmt from 'select * from t25_col_name';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t25_col_name change a b int;
-set @expected = @expected + 1;
-execute stmt;
-ERROR HY000: Prepared statement result set has changed, rebind needed
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @expected = @expected + 1;
-execute stmt;
-ERROR HY000: Prepared statement result set has changed, rebind needed
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t25_col_name;
-drop table if exists t25_col_type;
-create table t25_col_type(a int);
-prepare stmt from 'select * from t25_col_type';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t25_col_type change a a varchar(10);
-set @expected = @expected + 1;
-execute stmt;
-ERROR HY000: Prepared statement result set has changed, rebind needed
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @expected = @expected + 1;
-execute stmt;
-ERROR HY000: Prepared statement result set has changed, rebind needed
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t25_col_type;
-drop table if exists t25_col_type_length;
-create table t25_col_type_length(a varchar(10));
-prepare stmt from 'select * from t25_col_type_length';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t25_col_type_length change a a varchar(20);
-set @expected = @expected + 1;
-execute stmt;
-ERROR HY000: Prepared statement result set has changed, rebind needed
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @expected = @expected + 1;
-execute stmt;
-ERROR HY000: Prepared statement result set has changed, rebind needed
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t25_col_type_length;
-drop table if exists t25_col_null;
-create table t25_col_null(a varchar(10));
-prepare stmt from 'select * from t25_col_null';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t25_col_null change a a varchar(10) NOT NULL;
-set @expected = @expected + 1;
-execute stmt;
-ERROR HY000: Prepared statement result set has changed, rebind needed
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @expected = @expected + 1;
-execute stmt;
-ERROR HY000: Prepared statement result set has changed, rebind needed
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t25_col_null;
-drop table if exists t25_col_default;
-create table t25_col_default(a int, b int DEFAULT 10);
-prepare stmt from 'insert into t25_col_default(a) values (?)';
-set @val=1;
-execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @val=2;
-execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t25_col_default change b b int DEFAULT 20;
-set @val=3;
-set @expected = @expected + 1;
-execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @val=4;
-execute stmt using @val;
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-select * from t25_col_default;
-a b
-1 10
-2 10
-3 20
-4 20
-drop table t25_col_default;
-drop table if exists t25_index;
-create table t25_index(a varchar(10));
-prepare stmt from 'select * from t25_index';
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-create index i1 on t25_index(a);
-set @expected = @expected + 1;
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t25_index;
-drop table if exists t25_index_unique;
-create table t25_index_unique(a varchar(10), b varchar(10));
-create index i1 on t25_index_unique(a, b);
-show create table t25_index_unique;
-Table Create Table
-t25_index_unique CREATE TABLE `t25_index_unique` (
- `a` varchar(10) DEFAULT NULL,
- `b` varchar(10) DEFAULT NULL,
- KEY `i1` (`a`,`b`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-prepare stmt from 'select * from t25_index_unique';
-execute stmt;
-a b
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a b
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-alter table t25_index_unique drop index i1;
-create unique index i1 on t25_index_unique(a, b);
-show create table t25_index_unique;
-Table Create Table
-t25_index_unique CREATE TABLE `t25_index_unique` (
- `a` varchar(10) DEFAULT NULL,
- `b` varchar(10) DEFAULT NULL,
- UNIQUE KEY `i1` (`a`,`b`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-set @expected = @expected + 1;
-execute stmt;
-a b
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a b
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop table t25_index_unique;
+v1 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1`
AS select (`t1`.`a` * `t1`.`a`) AS `a2` from `t1` latin1 latin1_swedish_ci
+prepare stmt from "select * from v1";
+insert into t1 values (1), (2), (3);
+execute stmt;
+a2
+1
+4
+9
+execute stmt;
+a2
+1
+4
+9
+insert into t1 values (4), (5), (6);
+execute stmt;
+a2
+1
+4
+9
+16
+25
+36
+execute stmt;
+a2
+1
+4
+9
+16
+25
+36
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t1;
+drop view v1;
+=====================================================================
+Part 23: Special statements
+=====================================================================
+# SQLCOM_ALTER_TABLE:
+create table t1 (a int);
+prepare stmt from "alter table t1 add column b int";
+execute stmt;
+drop table t1;
+create table t1 (a1 int, a2 int);
+# t1 has changed, and it's does not lead to reprepare
+execute stmt;
+alter table t1 drop column b;
+execute stmt;
+alter table t1 drop column b;
+execute stmt;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t1;
+# SQLCOM_REPAIR:
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+prepare stmt from "repair table t1";
+execute stmt;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+execute stmt;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+drop table t1;
+create table t1 (a1 int, a2 int);
+insert into t1 values (1, 10), (2, 20), (3, 30);
+# t1 has changed, and it's does not lead to reprepare
+execute stmt;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+alter table t1 add column b varchar(50) default NULL;
+execute stmt;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+call p_verify_reprepare_count(0);
+SUCCESS
+
+alter table t1 drop column b;
+execute stmt;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+call p_verify_reprepare_count(0);
+SUCCESS
+
+# SQLCOM_ANALYZE:
+prepare stmt from "analyze table t1";
+execute stmt;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+drop table t1;
+create table t1 (a1 int, a2 int);
+insert into t1 values (1, 10), (2, 20), (3, 30);
+# t1 has changed, and it's not a problem
+execute stmt;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+alter table t1 add column b varchar(50) default NULL;
+execute stmt;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+alter table t1 drop column b;
+execute stmt;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+call p_verify_reprepare_count(0);
+SUCCESS
+
+# SQLCOM_OPTIMIZE:
+prepare stmt from "optimize table t1";
+execute stmt;
+Table Op Msg_type Msg_text
+test.t1 optimize status Table is already up to date
+drop table t1;
+create table t1 (a1 int, a2 int);
+insert into t1 values (1, 10), (2, 20), (3, 30);
+# t1 has changed, and it's not a problem
+execute stmt;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+alter table t1 add column b varchar(50) default NULL;
+execute stmt;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+alter table t1 drop column b;
+execute stmt;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t1;
+# SQLCOM_SHOW_CREATE_PROC:
+prepare stmt from "show create procedure p1";
+execute stmt;
+ERROR 42000: PROCEDURE p1 does not exist
+execute stmt;
+ERROR 42000: PROCEDURE p1 does not exist
+create procedure p1() begin end;
+execute stmt;
+execute stmt;
+drop procedure p1;
+create procedure p1(x int, y int) begin end;
+execute stmt;
+execute stmt;
+drop procedure p1;
+execute stmt;
+ERROR 42000: PROCEDURE p1 does not exist
+execute stmt;
+ERROR 42000: PROCEDURE p1 does not exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+# SQLCOM_SHOW_CREATE_FUNC:
+prepare stmt from "show create function f1";
+execute stmt;
+ERROR 42000: FUNCTION f1 does not exist
+execute stmt;
+ERROR 42000: FUNCTION f1 does not exist
+create function f1() returns int return 0;
+execute stmt;
+execute stmt;
+drop function f1;
+create function f1(x int, y int) returns int return x+y;
+execute stmt;
+execute stmt;
+drop function f1;
+execute stmt;
+ERROR 42000: FUNCTION f1 does not exist
+execute stmt;
+ERROR 42000: FUNCTION f1 does not exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+# SQLCOM_SHOW_CREATE_TRIGGER:
+create table t1 (a int);
+prepare stmt from "show create trigger t1_bi";
+execute stmt;
+ERROR HY000: Trigger does not exist
+execute stmt;
+ERROR HY000: Trigger does not exist
+create trigger t1_bi before insert on t1 for each row set @message= "t1_bi";
+execute stmt;
+execute stmt;
+drop trigger t1_bi;
+create trigger t1_bi before insert on t1 for each row set @message= "t1_bi (2)";
+execute stmt;
+execute stmt;
+drop trigger t1_bi;
+execute stmt;
+ERROR HY000: Trigger does not exist
+execute stmt;
+ERROR HY000: Trigger does not exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t1;
+deallocate prepare stmt;
+=====================================================================
+Part 24: Testing the strength of TABLE_SHARE version
+=====================================================================
+# Test 24-a: number of columns
+create table t1 (a int);
+prepare stmt from "select a from t1";
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+alter table t1 add column b varchar(50) default NULL;
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+# Test 24-b: column name
+alter table t1 change b c int;
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+# Test 24-c: column type
+alter table t1 change a a varchar(10);
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+# Test 24-d: column type length
+alter table t1 change a a varchar(20);
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+# Test 24-e: column NULL property
+alter table t1 change a a varchar(20) NOT NULL;
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+# Test 24-f: column DEFAULT
+alter table t1 change c c int DEFAULT 20;
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+# Test 24-g: number of keys
+create unique index t1_a_idx on t1 (a);
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+# Test 24-h: changing index uniqueness
+drop index t1_a_idx on t1;
+create index t1_a_idx on t1 (a);
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+# Cleanup
+drop table t1;
+deallocate prepare stmt;
=====================================================================
Testing reported bugs
=====================================================================
-drop table if exists table_12093;
-drop function if exists func_12093;
-drop function if exists func_12093_unrelated;
-drop procedure if exists proc_12093;
-create table table_12093(a int);
-create function func_12093()
-returns int
-begin
-return (select count(*) from table_12093);
-end//
-create procedure proc_12093(a int)
-begin
-select * from table_12093;
-end//
-create function func_12093_unrelated() returns int return 2;
-create procedure proc_12093_unrelated() begin end;
-prepare stmt_sf from 'select func_12093();';
-prepare stmt_sp from 'call proc_12093(func_12093())';
-execute stmt_sf;
-func_12093()
-0
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt_sp;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop function func_12093_unrelated;
-drop procedure proc_12093_unrelated;
-execute stmt_sf;
-func_12093()
-0
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt_sp;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt_sf;
-func_12093()
-0
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt_sp;
-a
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-deallocate prepare stmt_sf;
-deallocate prepare stmt_sp;
-drop table table_12093;
-drop function func_12093;
-drop procedure proc_12093;
-drop function if exists func_21294;
-create function func_21294() returns int return 10;
-prepare stmt from "select func_21294()";
-execute stmt;
-func_21294()
-10
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop function func_21294;
-create function func_21294() returns int return 10;
-execute stmt;
-func_21294()
-10
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-drop function func_21294;
-create function func_21294() returns int return 20;
-set @expected = @expected + 1;
-execute stmt;
-func_21294()
-20
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-deallocate prepare stmt;
-drop function func_21294;
+#
+# Bug#27420 A combination of PS and view operations cause
+# error + assertion on shutdown
+#
drop table if exists t_27420_100;
drop table if exists t_27420_101;
drop view if exists v_27420;
@@ -3353,55 +1382,36 @@
create view v_27420 as select t_27420_100.a X, t_27420_101.a Y
from t_27420_100, t_27420_101
where t_27420_100.a=t_27420_101.a;
-prepare stmt from 'select * from v_27420';
+prepare stmt from "select * from v_27420";
execute stmt;
X Y
1 1
2 2
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+call p_verify_reprepare_count(0);
+SUCCESS
+
drop view v_27420;
create table v_27420(X int, Y int);
-set @expected = @expected + 1;
execute stmt;
X Y
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+call p_verify_reprepare_count(1);
+SUCCESS
+
drop table v_27420;
create table v_27420 (a int, b int, filler char(200));
-set @expected = @expected + 1;
execute stmt;
-ERROR HY000: Prepared statement result set has changed, rebind needed
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-deallocate prepare stmt;
+a b filler
+call p_verify_reprepare_count(1);
+SUCCESS
+
drop table t_27420_100;
drop table t_27420_101;
drop table v_27420;
+deallocate prepare stmt;
+#
+# Bug#27430 Crash in subquery code when in PS and table DDL changed
+# after PREPARE
+#
drop table if exists t_27430_1;
drop table if exists t_27430_2;
create table t_27430_1 (a int not null, oref int not null, key(a));
@@ -3417,43 +1427,20 @@
(2, 2),
(1234, 3),
(1234, 4);
-prepare stmt from
-'select oref, a, a in (select a from t_27430_1 where oref=t_27430_2.oref) Z from
t_27430_2';
-execute stmt;
-oref a Z
-1 1 1
-2 2 0
-3 1234 0
-4 1234 0
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-oref a Z
-1 1 1
-2 2 0
-3 1234 0
-4 1234 0
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+prepare stmt from
+"select oref, a, a in (select a from t_27430_1 where oref=t_27430_2.oref) Z from
t_27430_2";
+execute stmt;
+oref a Z
+1 1 1
+2 2 0
+3 1234 0
+4 1234 0
+call p_verify_reprepare_count(0);
+SUCCESS
+
drop table t_27430_1, t_27430_2;
create table t_27430_1 (a int, oref int, key(a));
-insert into t_27430_1 values
+insert into t_27430_1 values
(1, 1),
(1, NULL),
(2, 3),
@@ -3465,35 +1452,22 @@
(2,2),
(NULL, 3),
(NULL, 4);
-set @expected = @expected + 1;
-execute stmt;
-ERROR HY000: Prepared statement result set has changed, rebind needed
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-set @expected = @expected + 1;
-execute stmt;
-ERROR HY000: Prepared statement result set has changed, rebind needed
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-deallocate prepare stmt;
+execute stmt;
+oref a Z
+1 1 1
+2 2 0
+3 NULL NULL
+4 NULL 0
+call p_verify_reprepare_count(1);
+SUCCESS
+
drop table t_27430_1;
drop table t_27430_2;
+deallocate prepare stmt;
+#
+# Bug#27690 Re-execution of prepared statement after table
+# was replaced with a view crashes
+#
drop table if exists t_27690_1;
drop view if exists v_27690_1;
drop table if exists v_27690_2;
@@ -3501,107 +1475,730 @@
insert into t_27690_1 values (1,1),(2,2);
create table v_27690_1 as select * from t_27690_1;
create table v_27690_2 as select * from t_27690_1;
-prepare stmt from 'select * from v_27690_1, v_27690_2';
-execute stmt;
-a b a b
-1 1 1 1
-2 2 1 1
-1 1 2 2
-2 2 2 2
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a b a b
-1 1 1 1
-2 2 1 1
-1 1 2 2
-2 2 2 2
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+prepare stmt from "select * from v_27690_1, v_27690_2";
+execute stmt;
+a b a b
+1 1 1 1
+2 2 1 1
+1 1 2 2
+2 2 2 2
+execute stmt;
+a b a b
+1 1 1 1
+2 2 1 1
+1 1 2 2
+2 2 2 2
drop table v_27690_1;
execute stmt;
ERROR 42S02: Table 'test.v_27690_1' doesn't exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
execute stmt;
ERROR 42S02: Table 'test.v_27690_1' doesn't exist
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
+call p_verify_reprepare_count(0);
+SUCCESS
+
create view v_27690_1 as select A.a, A.b from t_27690_1 A, t_27690_1 B;
-set @expected = @expected + 1;
-execute stmt;
-a b a b
-1 1 1 1
-2 2 1 1
-1 1 1 1
-2 2 1 1
-1 1 2 2
-2 2 2 2
-1 1 2 2
-2 2 2 2
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-execute stmt;
-a b a b
-1 1 1 1
-2 2 1 1
-1 1 1 1
-2 2 1 1
-1 1 2 2
-2 2 2 2
-1 1 2 2
-2 2 2 2
-SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
-WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
-AS `CHECK`,
-(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
-where variable_name='COM_STMT_REPREPARE' ;
-CHECK OFFSET
-PASSED 0
-deallocate prepare stmt;
+execute stmt;
+a b a b
+1 1 1 1
+2 2 1 1
+1 1 1 1
+2 2 1 1
+1 1 2 2
+2 2 2 2
+1 1 2 2
+2 2 2 2
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a b a b
+1 1 1 1
+2 2 1 1
+1 1 1 1
+2 2 1 1
+1 1 2 2
+2 2 2 2
+1 1 2 2
+2 2 2 2
+call p_verify_reprepare_count(0);
+SUCCESS
+
drop table t_27690_1;
drop view v_27690_1;
drop table v_27690_2;
+deallocate prepare stmt;
+#=====================================================================
+# TODO: fix the below two bugs and modify their tests
+#
+# Bug#21294 Executing a prepared statement that executes
+# a stored function which was recreat
+#
+create function f1() returns int return 10;
+prepare stmt from "select f1()";
+execute stmt;
+f1()
+10
+drop function f1;
+create function f1() returns int return 10;
+execute stmt;
+ERROR 42000: FUNCTION test.f1 does not exist
+drop function f1;
+create function f1() returns int return 20;
+execute stmt;
+ERROR 42000: FUNCTION test.f1 does not exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop function f1;
+deallocate prepare stmt;
+#
+# Bug#12093 SP not found on second PS execution if another thread drops
+# other SP in between
+#
+drop table if exists t_12093;
+drop function if exists f_12093;
+drop function if exists f_12093_unrelated;
+drop procedure if exists p_12093;
+create table t_12093 (a int);
+create function f_12093() returns int return (select count(*) from t_12093);
+create procedure p_12093(a int) select * from t_12093;
+create function f_12093_unrelated() returns int return 2;
+create procedure p_12093_unrelated() begin end;
+prepare stmt_sf from 'select f_12093();';
+prepare stmt_sp from 'call p_12093(f_12093())';
+execute stmt_sf;
+f_12093()
+0
+execute stmt_sp;
+a
+drop function f_12093_unrelated;
+drop procedure p_12093_unrelated;
+# XXX: bug
+execute stmt_sf;
+ERROR 42000: FUNCTION test.f_12093 does not exist
+# XXX: bug
+execute stmt_sp;
+ERROR 42000: PROCEDURE test.p_12093 does not exist
+# XXX: bug
+execute stmt_sf;
+ERROR 42000: FUNCTION test.f_12093 does not exist
+# XXX: bug
+execute stmt_sp;
+ERROR 42000: PROCEDURE test.p_12093 does not exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t_12093;
+drop function f_12093;
+drop procedure p_12093;
+deallocate prepare stmt_sf;
+deallocate prepare stmt_sp;
+=====================================================================
+Ensure that metadata validation is performed for every type of
+SQL statement where it is needed.
+=====================================================================
+#
+# SQLCOM_SELECT
+#
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "select 1 as res from dual where (1) in (select * from t1)";
+drop table t1;
+create table t1 (x int);
+execute stmt;
+res
+drop table t1;
+deallocate prepare stmt;
+call p_verify_reprepare_count(1);
+SUCCESS
+
+#
+# SQLCOM_CREATE_TABLE
+#
+drop table if exists t1;
+drop table if exists t2;
+create table t1 (a int);
+prepare stmt from 'create table t2 as select * from t1';
+execute stmt;
+drop table t2;
+execute stmt;
+drop table t2;
+execute stmt;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+execute stmt;
+ERROR 42S01: Table 't2' already exists
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+ERROR 42S01: Table 't2' already exists
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t2;
+create temporary table t2 (a int);
+execute stmt;
+ERROR 42S01: Table 't2' already exists
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+ERROR 42S01: Table 't2' already exists
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop temporary table t2;
+execute stmt;
+call p_verify_reprepare_count(1);
+SUCCESS
+
+drop table t2;
+execute stmt;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t2;
+create view t2 as select 1;
+execute stmt;
+Got one of the listed errors
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+Got one of the listed errors
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop view t2;
+drop table t1;
+create table t1 (x varchar(20));
+execute stmt;
+call p_verify_reprepare_count(1);
+SUCCESS
+
+select * from t2;
+x
+drop table t2;
+execute stmt;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t2;
+alter table t1 add column y decimal(10,3);
+execute stmt;
+call p_verify_reprepare_count(1);
+SUCCESS
+
+select * from t2;
+x y
+drop table t2;
+execute stmt;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t1;
+deallocate prepare stmt;
+# XXX: no validation of the first table in case of
+# CREATE TEMPORARY TABLE. This is a shortcoming of the current code,
+# but since validation is not strictly necessary, nothing is done
+# about it.
+# Will be fixed as part of work on Bug#21431 "Incomplete support of
+# temporary tables"
+create table t1 (a int);
+insert into t1 (a) values (1);
+prepare stmt from "create temporary table if not exists t2 as select * from t1";
+execute stmt;
+drop table t2;
+execute stmt;
+execute stmt;
+Warnings:
+Note 1050 Table 't2' already exists
+select * from t2;
+a
+1
+1
+execute stmt;
+Warnings:
+Note 1050 Table 't2' already exists
+select * from t2;
+a
+1
+1
+1
+drop table t2;
+create temporary table t2 (a varchar(10));
+execute stmt;
+Warnings:
+Note 1050 Table 't2' already exists
+select * from t2;
+a
+1
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t1;
+create table t1 (x int);
+execute stmt;
+Warnings:
+Note 1050 Table 't2' already exists
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+Warnings:
+Note 1050 Table 't2' already exists
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t1;
+drop temporary table t2;
+drop table t2;
+deallocate prepare stmt;
+create table t1 (a int);
+prepare stmt from "create table t2 like t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t2;
+execute stmt;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t2;
+drop table t1;
+execute stmt;
+ERROR 42S02: Table 'test.t1' doesn't exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+execute stmt;
+ERROR 42S02: Table 'test.t1' doesn't exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+create table t1 (x char(17));
+execute stmt;
+call p_verify_reprepare_count(1);
+SUCCESS
+
+drop table t2;
+execute stmt;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t2;
+alter table t1 add column y time;
+execute stmt;
+call p_verify_reprepare_count(1);
+SUCCESS
+
+select * from t2;
+x y
+drop table t2;
+execute stmt;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t1;
+drop table t2;
+deallocate prepare stmt;
+#
+# SQLCOM_UPDATE
+#
+drop table if exists t1, t2;
+create table t1 (a int);
+create table t2 (a int);
+prepare stmt from "update t2 set a=a+1 where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1, t2;
+deallocate prepare stmt;
+#
+# SQLCOM_INSERT
+#
+drop table if exists t1, t2;
+create table t1 (a int);
+create table t2 (a int);
+prepare stmt from "insert into t2 set a=((1) in (select * from t1))";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1, t2;
+deallocate prepare stmt;
+#
+# SQLCOM_INSERT_SELECT
+#
+drop table if exists t1, t2;
+create table t1 (a int);
+create table t2 (a int);
+prepare stmt from "insert into t2 select * from t1";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1, t2;
+deallocate prepare stmt;
+#
+# SQLCOM_REPLACE
+#
+drop table if exists t1, t2;
+create table t1 (a int);
+create table t2 (a int);
+prepare stmt from "replace t2 set a=((1) in (select * from t1))";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1, t2;
+deallocate prepare stmt;
+#
+# SQLCOM_REPLACE_SELECT
+#
+drop table if exists t1, t2;
+create table t1 (a int);
+create table t2 (a int);
+prepare stmt from "replace t2 select * from t1";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1, t2;
+deallocate prepare stmt;
+#
+# SQLCOM_DELETE
+#
+drop table if exists t1, t2;
+create table t1 (a int);
+create table t2 (a int);
+prepare stmt from "delete from t2 where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1, t2;
+deallocate prepare stmt;
+#
+# SQLCOM_DELETE_MULTI
+#
+drop table if exists t1, t2, t3;
+create table t1 (a int);
+create table t2 (a int);
+create table t3 (a int);
+prepare stmt from "delete t2, t3 from t2, t3 where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1, t2, t3;
+deallocate prepare stmt;
+#
+# SQLCOM_UPDATE_MULTI
+#
+drop table if exists t1, t2, t3;
+create table t1 (a int);
+create table t2 (a int);
+create table t3 (a int);
+prepare stmt from "update t2, t3 set t3.a=t2.a, t2.a=null where (1) in (select * from
t1)";
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1, t2, t3;
+deallocate prepare stmt;
+# Intermediate results: 8 SQLCOMs tested, 8 automatic reprepares
+call p_verify_reprepare_count(8);
+SUCCESS
+
+#
+# SQLCOM_LOAD
+#
+drop table if exists t1;
+create table t1 (a varchar(20));
+prepare stmt from "load data infile '../std_data_ln/words.dat' into table t1";
+ERROR HY000: This command is not supported in the prepared statement protocol yet
+drop table t1;
+#
+# SQLCOM_SHOW_DATABASES
+#
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "show databases where (1) in (select * from t1)";
+execute stmt;
+Database
+drop table t1;
+create table t1 (x int);
+execute stmt;
+Database
+drop table t1;
+deallocate prepare stmt;
+#
+# SQLCOM_SHOW_TABLES
+#
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "show tables where (1) in (select * from t1)";
+execute stmt;
+Tables_in_test
+drop table t1;
+create table t1 (x int);
+execute stmt;
+Tables_in_test
+drop table t1;
+deallocate prepare stmt;
+#
+# SQLCOM_SHOW_FIELDS
+#
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "show fields from t1 where (1) in (select * from t1)";
+execute stmt;
+Field Type Null Key Default Extra
+drop table t1;
+create table t1 (x int);
+execute stmt;
+Field Type Null Key Default Extra
+drop table t1;
+deallocate prepare stmt;
+#
+# SQLCOM_SHOW_KEYS
+#
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "show keys from t1 where (1) in (select * from t1)";
+execute stmt;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+drop table t1;
+create table t1 (x int);
+execute stmt;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+drop table t1;
+deallocate prepare stmt;
+#
+# SQLCOM_SHOW_VARIABLES
+#
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "show variables where (1) in (select * from t1)";
+execute stmt;
+Variable_name Value
+drop table t1;
+create table t1 (x int);
+execute stmt;
+Variable_name Value
+drop table t1;
+deallocate prepare stmt;
+#
+# SQLCOM_SHOW_STATUS
+#
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "show status where (1) in (select * from t1)";
+execute stmt;
+Variable_name Value
+drop table t1;
+create table t1 (x int);
+execute stmt;
+Variable_name Value
+drop table t1;
+deallocate prepare stmt;
+#
+# SQLCOM_SHOW_ENGINE_STATUS, SQLCOM_SHOW_ENGINE_LOGS,
+# SQLCOM_SHOW_ENGINE_MUTEX, SQLCOM_SHOW_PROCESSLIST
+#
+# Currently can not have a where clause, need to be covered
+# with tests
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "show engine all status where (1) in (select * from t1)";
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near 'where (1) in (select * from
t1)' at line 1
+prepare stmt from "show engine all logs where (1) in (select * from t1)";
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near 'where (1) in (select * from
t1)' at line 1
+prepare stmt from "show engine all mutex where (1) in (select * from t1)";
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near 'where (1) in (select * from
t1)' at line 1
+prepare stmt from "show processlist where (1) in (select * from t1)";
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near 'where (1) in (select * from
t1)' at line 1
+drop table t1;
+#
+# SQLCOM_SHOW_CHARSETS
+#
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "show charset where (1) in (select * from t1)";
+execute stmt;
+Charset Description Default collation Maxlen
+drop table t1;
+create table t1 (x int);
+execute stmt;
+Charset Description Default collation Maxlen
+drop table t1;
+deallocate prepare stmt;
+#
+# SQLCOM_SHOW_COLLATIONS
+#
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "show collation where (1) in (select * from t1)";
+execute stmt;
+Collation Charset Id Default Compiled Sortlen
+drop table t1;
+create table t1 (x int);
+execute stmt;
+Collation Charset Id Default Compiled Sortlen
+drop table t1;
+deallocate prepare stmt;
+#
+# SQLCOM_SHOW_TABLE_STATUS
+#
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "show table status where (1) in (select * from t1)";
+execute stmt;
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
+drop table t1;
+create table t1 (x int);
+execute stmt;
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
+drop table t1;
+deallocate prepare stmt;
+#
+# SQLCOM_SHOW_TRIGGERS
+#
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "show triggers where (1) in (select * from t1)";
+execute stmt;
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database
Collation
+drop table t1;
+create table t1 (x int);
+execute stmt;
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database
Collation
+drop table t1;
+deallocate prepare stmt;
+#
+# SQLCOM_SHOW_OPEN_TABLES
+#
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "show open tables where (1) in (select * from t1)";
+execute stmt;
+Database Table In_use Name_locked
+drop table t1;
+create table t1 (x int);
+execute stmt;
+Database Table In_use Name_locked
+drop table t1;
+deallocate prepare stmt;
+#
+# SQLCOM_SHOW_STATUS_PROC
+#
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "show procedure status where (1) in (select * from t1)";
+execute stmt;
+Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database
Collation
+drop table t1;
+create table t1 (x int);
+execute stmt;
+Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database
Collation
+drop table t1;
+deallocate prepare stmt;
+#
+# SQLCOM_SHOW_STATUS_FUNC
+#
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "show function status where (1) in (select * from t1)";
+execute stmt;
+Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database
Collation
+drop table t1;
+create table t1 (x int);
+execute stmt;
+Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database
Collation
+drop table t1;
+deallocate prepare stmt;
+#
+# SQLCOM_SHOW_EVENTS
+#
+#
+# Please see this test in ps.test, it requires not_embedded.inc
+#
+#
+# SQLCOM_SET_OPTION
+#
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "set @a=((1) in (select * from t1))";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+#
+# SQLCOM_DO
+#
+drop table if exists t1;
+create table t1 (a int);
+prepare stmt from "do ((1) in (select * from t1))";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+#
+# SQLCOM_CALL
+#
+drop table if exists t1;
+drop procedure if exists p1;
+create procedure p1(a int) begin end;
+create table t1 (a int);
+prepare stmt from "call p1((1) in (select * from t1))";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+drop procedure p1;
+deallocate prepare stmt;
+#
+# SQLCOM_CREATE_VIEW
+#
+drop table if exists t1;
+drop view if exists v1;
+create table t1 (a int);
+prepare stmt from "create view v1 as select * from t1";
+execute stmt;
+drop view v1;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop view v1;
+drop table t1;
+deallocate prepare stmt;
+# Intermediate result: number of reprepares matches the number
+# of tests
+call p_verify_reprepare_count(17);
+SUCCESS
+
+#
+# SQLCOM_ALTER_VIEW
+#
+drop view if exists v1;
+create view v1 as select 1;
+prepare stmt from "alter view v1 as select 2";
+ERROR HY000: This command is not supported in the prepared statement protocol yet
+drop view v1;
+# Cleanup
+#
+drop temporary table if exists t1, t2, t3;
+drop table if exists t1, t2, t3, v1, v2;
+drop procedure if exists p_verify_reprepare_count;
+drop procedure if exists p1;
+drop function if exists f1;
+drop view if exists v1, v2;
=== added file 'mysql-test/r/ps_ddl1.result'
--- a/mysql-test/r/ps_ddl1.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/ps_ddl1.result 2008-04-18 19:18:53 +0000
@@ -0,0 +1,482 @@
+drop temporary table if exists t1;
+drop table if exists t1, t2;
+drop procedure if exists p_verify_reprepare_count;
+drop procedure if exists p1;
+drop function if exists f1;
+drop view if exists t1;
+drop schema if exists mysqltest;
+create procedure p_verify_reprepare_count(expected int)
+begin
+declare old_reprepare_count int default @reprepare_count;
+select variable_value from
+information_schema.session_status where
+variable_name='com_stmt_reprepare'
+ into @reprepare_count;
+if old_reprepare_count + expected <> @reprepare_count then
+select concat("Expected: ", expected,
+", actual: ", @reprepare_count - old_reprepare_count)
+as "ERROR";
+else
+select '' as "SUCCESS";
+end if;
+end|
+set @reprepare_count= 0;
+flush status;
+drop table if exists t1;
+# Column added or dropped is not within the list of selected columns
+# or table comment has changed.
+# A reprepare is probably not needed.
+create table t1 (a int, b int);
+prepare stmt from "select a from t1";
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+alter table t1 add column c int;
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+alter table t1 drop column b;
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+alter table t1 comment "My best table";
+execute stmt;
+a
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+a
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t1;
+deallocate prepare stmt;
+# Selects using the table at various positions, inser,update ...
+# + the table disappears
+create table t1 (a int);
+prepare stmt1 from "truncate t1";
+prepare stmt2 from "select 1 as my_column from t1";
+prepare stmt3 from "select 1 as my_column from (select * from t1) as t2";
+prepare stmt4 from
+"select 1 as my_column from (select 1) as t2 where exists (select 1 from t1)";
+prepare stmt5 from "select * from (select 1 as b) as t2, t1";
+prepare stmt6 from "select * from t1 union all select 1.5";
+prepare stmt7 from "select 1 as my_column union all select 1 from t1";
+prepare stmt8 from "insert into t1 values(1),(2)";
+prepare stmt9 from "update t1 set a = 3 where a = 2";
+prepare stmt10 from "delete from t1 where a = 1";
+# Attention: Result logging is disabled.
+execute stmt10;
+execute stmt9;
+execute stmt8;
+execute stmt7;
+execute stmt6;
+execute stmt5;
+execute stmt4;
+execute stmt3;
+execute stmt2;
+execute stmt1;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t1;
+execute stmt10;
+ERROR 42S02: Table 'test.t1' doesn't exist
+execute stmt9;
+ERROR 42S02: Table 'test.t1' doesn't exist
+execute stmt8;
+ERROR 42S02: Table 'test.t1' doesn't exist
+execute stmt7;
+ERROR 42S02: Table 'test.t1' doesn't exist
+execute stmt6;
+ERROR 42S02: Table 'test.t1' doesn't exist
+execute stmt5;
+ERROR 42S02: Table 'test.t1' doesn't exist
+execute stmt4;
+ERROR 42S02: Table 'test.t1' doesn't exist
+execute stmt3;
+ERROR 42S02: Table 'test.t1' doesn't exist
+execute stmt2;
+ERROR 42S02: Table 'test.t1' doesn't exist
+execute stmt1;
+ERROR 42S02: Table 'test.t1' doesn't exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+deallocate prepare stmt10;
+deallocate prepare stmt9;
+deallocate prepare stmt8;
+deallocate prepare stmt7;
+deallocate prepare stmt6;
+deallocate prepare stmt5;
+deallocate prepare stmt4;
+deallocate prepare stmt3;
+deallocate prepare stmt2;
+deallocate prepare stmt1;
+# Selects using the table at various positions, inser,update ...
+# + layout change (drop column) which must cause a reprepare
+create table t1 (a int, b int);
+insert into t1 values(1,1),(2,2),(3,3);
+create table t2 like t1;
+insert into t1 values(2,2);
+prepare stmt1 from "select a,b from t1";
+prepare stmt2 from "select a,b from (select * from t1) as t1";
+prepare stmt3 from "select * from t1 where a = 2 and b = 2";
+prepare stmt4 from "select * from t2 where (a,b) in (select * from t1)";
+prepare stmt5 from "select * from t1 union select * from t2";
+prepare stmt6 from "select * from t1 union all select * from t2";
+prepare stmt7 from "insert into t1 set a = 4, b = 4";
+prepare stmt8 from "insert into t1 select * from t2";
+# Attention: Result logging is disabled.
+execute stmt8;
+execute stmt7;
+execute stmt6;
+execute stmt5;
+execute stmt4;
+execute stmt3;
+execute stmt2;
+execute stmt1;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+alter table t1 drop column b;
+execute stmt8;
+ERROR 21S01: Column count doesn't match value count at row 1
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt7;
+ERROR 42S22: Unknown column 'b' in 'field list'
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt6;
+ERROR 21000: The used SELECT statements have a different number of columns
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt5;
+ERROR 21000: The used SELECT statements have a different number of columns
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt4;
+ERROR 21000: Operand should contain 2 column(s)
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt3;
+ERROR 42S22: Unknown column 'b' in 'where clause'
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt2;
+ERROR 42S22: Unknown column 'b' in 'field list'
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt1;
+ERROR 42S22: Unknown column 'b' in 'field list'
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt8;
+ERROR 21S01: Column count doesn't match value count at row 1
+call p_verify_reprepare_count(1);
+ERROR
+Expected: 1, actual: 0
+execute stmt7;
+ERROR 42S22: Unknown column 'b' in 'field list'
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt6;
+ERROR 21000: The used SELECT statements have a different number of columns
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt5;
+ERROR 21000: The used SELECT statements have a different number of columns
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt4;
+ERROR 21000: Operand should contain 2 column(s)
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt3;
+ERROR 42S22: Unknown column 'b' in 'where clause'
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt2;
+ERROR 42S22: Unknown column 'b' in 'field list'
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt1;
+ERROR 42S22: Unknown column 'b' in 'field list'
+call p_verify_reprepare_count(1);
+SUCCESS
+
+# Why does the INSERT ... SELECT does not get a reprepare or is
+# only the counter not incremented?
+execute stmt8;
+ERROR 21S01: Column count doesn't match value count at row 1
+call p_verify_reprepare_count(1);
+ERROR
+Expected: 1, actual: 0
+alter table t2 add column c int;
+execute stmt8;
+ERROR 21S01: Column count doesn't match value count at row 1
+call p_verify_reprepare_count(1);
+SUCCESS
+
+deallocate prepare stmt8;
+deallocate prepare stmt7;
+deallocate prepare stmt6;
+deallocate prepare stmt5;
+deallocate prepare stmt4;
+deallocate prepare stmt3;
+deallocate prepare stmt2;
+deallocate prepare stmt1;
+drop table t1;
+drop table t2;
+# select AVG(<col>) + optimizer uses index meets loss of the index
+create table t1 (a int, b int, primary key(b),unique index t1_unq_idx(a));
+insert into t1 set a = 0, b = 0;
+insert into t1 select a + 1, b + 1 from t1;
+insert into t1 select a + 2, b + 2 from t1;
+insert into t1 select a + 4, b + 4 from t1;
+insert into t1 select a + 8, b + 8 from t1;
+# Optimizer strategy: Possible keys = NULL , Extra = Using index
+prepare stmt from "select avg(a) from t1";
+execute stmt;
+avg(a)
+7.5000
+call p_verify_reprepare_count(0);
+SUCCESS
+
+execute stmt;
+avg(a)
+7.5000
+call p_verify_reprepare_count(0);
+SUCCESS
+
+alter table t1 drop index t1_unq_idx;
+# Optimizer strategy: Possible keys = NULL , Extra =
+execute stmt;
+avg(a)
+7.5000
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+avg(a)
+7.5000
+call p_verify_reprepare_count(0);
+SUCCESS
+
+# select AVG(<col>) + optimizer uses table scan meets a new index
+alter table t1 add unique index t1_unq_idx(a);
+# Optimizer strategy: Possible keys = NULL , Extra = Using index
+execute stmt;
+avg(a)
+7.5000
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+avg(a)
+7.5000
+call p_verify_reprepare_count(0);
+SUCCESS
+
+deallocate prepare stmt;
+drop table t1;
+# table replaced by not updatable view - Insert
+create table t1 (a int);
+prepare stmt from "insert into t1 values(1)";
+execute stmt;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop table t1;
+create view t1 as select 1;
+execute stmt;
+ERROR HY000: The target table t1 of the INSERT is not insertable-into
+call p_verify_reprepare_count(1);
+SUCCESS
+
+drop view t1;
+create table t2 (a int);
+create view t1 as select * from t2 with check option;
+execute stmt;
+call p_verify_reprepare_count(1);
+SUCCESS
+
+execute stmt;
+call p_verify_reprepare_count(0);
+SUCCESS
+
+select * from t1;
+a
+1
+1
+deallocate prepare stmt;
+drop view t1;
+drop table t2;
+=====================================================================
+Some freestyle tests
+=====================================================================
+create temporary table t1 as select 1 as a;
+create procedure p1()
+begin
+drop temporary table t1;
+end|
+create function f1() returns int
+begin
+call p1();
+return 1;
+end|
+prepare stmt from "select f1() as my_column, a from t1";
+execute stmt;
+ERROR HY000: Can't reopen table: 't1'
+call p_verify_reprepare_count(0);
+SUCCESS
+
+select * from t1;
+a
+1
+prepare stmt from "select a, f1() as my_column from t1";
+execute stmt;
+ERROR HY000: Can't reopen table: 't1'
+call p_verify_reprepare_count(0);
+SUCCESS
+
+select * from t1;
+a
+1
+prepare stmt from "select f1() as my_column, count(*) from t1";
+execute stmt;
+ERROR HY000: Can't reopen table: 't1'
+call p_verify_reprepare_count(0);
+SUCCESS
+
+select * from t1;
+a
+1
+prepare stmt from "select count(*), f1() as my_column from t1";
+execute stmt;
+ERROR HY000: Can't reopen table: 't1'
+call p_verify_reprepare_count(0);
+SUCCESS
+
+select * from t1;
+a
+1
+# Execute fails, no drop of temporary table
+prepare stmt from "select 1 as my_column from (select 1) as t2
+ where exists (select f1() from t1)";
+execute stmt;
+my_column
+1
+call p_verify_reprepare_count(0);
+SUCCESS
+
+execute stmt;
+my_column
+1
+call p_verify_reprepare_count(0);
+SUCCESS
+
+select * from t1;
+a
+1
+# Execute drops temporary table
+prepare stmt from "select f1()";
+execute stmt;
+f1()
+1
+call p_verify_reprepare_count(0);
+SUCCESS
+
+execute stmt;
+ERROR 42S02: Unknown table 't1'
+call p_verify_reprepare_count(0);
+SUCCESS
+
+drop function f1;
+drop procedure p1;
+deallocate prepare stmt;
+# Execute fails, temporary table is not replaced by another
+create temporary table t1 as select 1 as a;
+create procedure p1()
+begin
+drop temporary table t1;
+create temporary table t1 as select 'abc' as a;
+end|
+create function f1() returns int
+begin
+call p1();
+return 1;
+end|
+prepare stmt from "select count(*), f1() as my_column from t1";
+execute stmt;
+ERROR HY000: Can't reopen table: 't1'
+call p_verify_reprepare_count(0);
+SUCCESS
+
+select * from t1;
+a
+1
+deallocate prepare stmt;
+prepare stmt from "call p1";
+execute stmt;
+drop procedure p1;
+create schema mysqltest;
+create procedure mysqltest.p1()
+begin
+drop schema mysqltest;
+create schema mysqltest;
+end|
+execute stmt;
+ERROR 42000: PROCEDURE test.p1 does not exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+execute stmt;
+ERROR 42000: PROCEDURE test.p1 does not exist
+call p_verify_reprepare_count(0);
+SUCCESS
+
+deallocate prepare stmt;
+drop schema mysqltest;
+drop temporary table t1;
+# Cleanup
+#
+drop temporary table if exists t1;
+drop table if exists t1, t2;
+drop procedure if exists p_verify_reprepare_count;
+drop procedure if exists p1;
+drop function if exists f1;
+drop view if exists t1;
+drop schema if exists mysqltest;
=== modified file 'mysql-test/r/query_cache_merge.result'
--- a/mysql-test/r/query_cache_merge.result 2003-08-22 01:07:40 +0000
+++ b/mysql-test/r/query_cache_merge.result 2008-04-08 16:01:20 +0000
@@ -18,3 +18,4 @@
Qcache_queries_in_cache 0
drop table
t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40,t41,t42,t43,t44,t45,t46,t47,t48,t49,t50,t51,t52,t53,t54,t55,t56,t57,t58,t59,t60,t61,t62,t63,t64,t65,t66,t67,t68,t69,t70,t71,t72,t73,t74,t75,t76,t77,t78,t79,t80,t81,t82,t83,t84,t85,t86,t87,t88,t89,t90,t91,t92,t93,t94,t95,t96,t97,t98,t99,t100,t101,t102,t103,t104,t105,t106,t107,t108,t109,t110,t111,t112,t113,t114,t115,t116,t117,t118,t119,t120,t121,t122,t123,t124,t125,t126,t127,t128,t129,t130,t131,t132,t133,t134,t135,t136,t137,t138,t139,t140,t141,t142,t143,t144,t145,t146,t147,t148,t149,t150,t151,t152,t153,t154,t155,t156,t157,t158,t159,t160,t161,t162,t163,t164,t165,t166,t167,t168,t169,t170,t171,t172,t173,t174,t175,t176,t177,t178,t179,t180,t181,t182,t183,t184,t185,t186,t187,t188,t189,t190,t191,t192,t193,t194,t195,t196,t197,t198,t199,t200,t201,t202,t203,t204,t205,t206,t207,t208,t209,t210,t211,t212,t213,t214,t215,t216,t217,t
218,t219,t220,t221,t222,t223,t224,t225,t226,t227,t228,t229,t230,t231,t232,t233,t234,t235,t236,t237,t238,t239,t240,t241,t242,t243,t244,t245,t246,t247,t248,t249,t250,t251,t252,t253,t254,t255,t256,t257,t00;
SET @@global.query_cache_size=0;
+set @@global.table_definition_cache=@save_table_definition_cache;
=== modified file 'mysql-test/r/slow_query_log_file_basic.result'
--- a/mysql-test/r/slow_query_log_file_basic.result 2008-04-10 13:14:28 +0000
+++ b/mysql-test/r/slow_query_log_file_basic.result 2008-05-20 18:23:58 +0000
@@ -9,7 +9,8 @@
master-slow.log
'#--------------------FN_DYNVARS_004_02------------------------#'
SET @@global.slow_query_log_file = mytest.log;
-ERROR 42000: Variable 'slow_query_log_file' can't be set to the value of 'log'
+SET @@global.slow_query_log_file = 12;
+ERROR 42000: Incorrect argument type to variable 'slow_query_log_file'
'#----------------------FN_DYNVARS_004_03------------------------#'
SELECT @@global.slow_query_log_file = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
=== modified file 'mysql-test/r/status.result'
--- a/mysql-test/r/status.result 2008-05-13 14:10:08 +0000
+++ b/mysql-test/r/status.result 2008-05-21 15:34:14 +0000
@@ -163,13 +163,11 @@
rnd_diff tmp_table_diff
20 8
flush status;
-show status like 'Com%function%';
+show status like 'Com%function';
Variable_name Value
Com_alter_function 0
Com_create_function 0
Com_drop_function 0
-Com_show_function_code 0
-Com_show_function_status 0
create function f1 (x INTEGER) returns integer
begin
declare ret integer;
@@ -177,10 +175,8 @@
return ret;
end //
drop function f1;
-show status like 'Com%function%';
+show status like 'Com%function';
Variable_name Value
Com_alter_function 0
Com_create_function 1
Com_drop_function 1
-Com_show_function_code 0
-Com_show_function_status 0
=== modified file 'mysql-test/r/table_definition_cache_basic.result'
--- a/mysql-test/r/table_definition_cache_basic.result 2008-04-10 13:14:28 +0000
+++ b/mysql-test/r/table_definition_cache_basic.result 2008-05-20 17:07:11 +0000
@@ -1,27 +1,33 @@
SET @start_value = @@global.table_definition_cache;
SELECT @start_value;
@start_value
-128
+256
'#--------------------FN_DYNVARS_019_01------------------------#'
SET @@global.table_definition_cache = 100;
+Warnings:
+Warning 1292 Truncated incorrect table_definition_cache value: '100'
SET @@global.table_definition_cache = DEFAULT;
SELECT @@global.table_definition_cache;
@@global.table_definition_cache
-128
+256
'#---------------------FN_DYNVARS_019_02-------------------------#'
SET @@global.table_definition_cache = DEFAULT;
SELECT @@global.table_definition_cache = 128;
@@global.table_definition_cache = 128
-1
+0
'#--------------------FN_DYNVARS_019_03------------------------#'
SET @@global.table_definition_cache = 1;
+Warnings:
+Warning 1292 Truncated incorrect table_definition_cache value: '1'
SELECT @@global.table_definition_cache;
@@global.table_definition_cache
-1
+256
SET @@global.table_definition_cache = 2;
+Warnings:
+Warning 1292 Truncated incorrect table_definition_cache value: '2'
SELECT @@global.table_definition_cache;
@@global.table_definition_cache
-2
+256
SET @@global.table_definition_cache = 524287;
SELECT @@global.table_definition_cache;
@@global.table_definition_cache
@@ -36,13 +42,13 @@
Warning 1292 Truncated incorrect table_definition_cache value: '0'
SELECT @@global.table_definition_cache;
@@global.table_definition_cache
-1
+256
SET @@global.table_definition_cache = -1024;
Warnings:
Warning 1292 Truncated incorrect table_definition_cache value: '0'
SELECT @@global.table_definition_cache;
@@global.table_definition_cache
-1
+256
SET @@global.table_definition_cache = 524289;
Warnings:
Warning 1292 Truncated incorrect table_definition_cache value: '524289'
@@ -73,17 +79,21 @@
1
'#---------------------FN_DYNVARS_019_07----------------------#'
SET @@global.table_definition_cache = TRUE;
+Warnings:
+Warning 1292 Truncated incorrect table_definition_cache value: '1'
SELECT @@global.table_definition_cache;
@@global.table_definition_cache
-1
+256
SET @@global.table_definition_cache = FALSE;
Warnings:
Warning 1292 Truncated incorrect table_definition_cache value: '0'
SELECT @@global.table_definition_cache;
@@global.table_definition_cache
-1
+256
'#---------------------FN_DYNVARS_019_08----------------------#'
SET @@global.table_definition_cache = 5;
+Warnings:
+Warning 1292 Truncated incorrect table_definition_cache value: '5'
SELECT @@table_definition_cache = @@global.table_definition_cache;
@@table_definition_cache = @@global.table_definition_cache
1
@@ -99,4 +109,4 @@
SET @@global.table_definition_cache = @start_value;
SELECT @@global.table_definition_cache;
@@global.table_definition_cache
-128
+256
=== modified file 'mysql-test/r/trigger.result'
--- a/mysql-test/r/trigger.result 2008-02-12 11:44:27 +0000
+++ b/mysql-test/r/trigger.result 2008-04-08 16:01:20 +0000
@@ -820,7 +820,6 @@
drop trigger t1_bi;
create trigger t1_bi after insert on t1 for each row insert into t3 values (new.id);
execute stmt1;
-ERROR 42S02: Table 'test.t3' doesn't exist
call p1();
ERROR 42S02: Table 'test.t3' doesn't exist
deallocate prepare stmt1;
=== modified file 'mysql-test/r/variables.result'
--- a/mysql-test/r/variables.result 2008-03-14 17:32:01 +0000
+++ b/mysql-test/r/variables.result 2008-03-28 15:10:04 +0000
@@ -1014,3 +1014,13 @@
Variable_name Value
table_definition_cache #
table_lock_wait_timeout #
+
+# --
+# -- Bug#34820: log_output can be set to illegal value.
+# --
+SET GLOBAL log_output = '';
+ERROR 42000: Variable 'log_output' can't be set to the value of ''
+SET GLOBAL log_output = 0;
+ERROR 42000: Variable 'log_output' can't be set to the value of '0'
+
+# -- End of Bug#34820.
=== modified file 'mysql-test/suite/rpl/t/rpl_server_id1.test'
--- a/mysql-test/suite/rpl/t/rpl_server_id1.test 2008-02-20 21:18:01 +0000
+++ b/mysql-test/suite/rpl/t/rpl_server_id1.test 2008-05-20 15:14:03 +0000
@@ -10,6 +10,7 @@
# replicate ourselves
stop slave;
+source include/wait_for_slave_to_stop.inc;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval change master to master_port=$SLAVE_MYPORT;
start slave;
=== modified file 'mysql-test/t/disabled.def'
--- a/mysql-test/t/disabled.def 2008-05-15 09:50:04 +0000
+++ b/mysql-test/t/disabled.def 2008-05-23 16:42:54 +0000
@@ -10,10 +10,8 @@
#
##############################################################################
federated_transactions : Bug#29523 Transactions do not work
-ps_ddl : Bug#12093 2007-12-14 pending WL#4165 / WL#4166
csv_alter_table : Bug#33696 2008-01-21 pcrews no .result file - bug allows NULL
columns in CSV tables
user_limits : Bug#23921 random failure of user_limits.test
-status : Bug#32966 main.status fails
thread_cache_size_func : Bug#36733 main.thread_cache_size_func fails randomly
binlog_cache_size_basic_32 : Bug #36522: Some tests of system variables have
diffs on 64bit platorms
bulk_insert_buffer_size_basic_32 : Bug #36522: Some tests of system variables have
diffs on 64bit platorms
=== modified file 'mysql-test/t/func_misc.test'
--- a/mysql-test/t/func_misc.test 2008-03-16 08:52:37 +0000
+++ b/mysql-test/t/func_misc.test 2008-05-23 15:23:55 +0000
@@ -105,34 +105,293 @@
#
# Bug #6760: Add SLEEP() function
#
-create table t1 (a timestamp default '2005-05-05 01:01:01',
+# Note (mleich):
+# --------------
+# The experiments around
+# Bug#36345 Test 'func_misc' fails on RHAS3 x86_64
+# showed that the original test for Bug#6760 produced false alarms in case
+# of parallel system time decreases. It was therefore modified.
+# Solution:
+# We run the test two times and assume a pass if at least one attempt
+# is successful. The disadvantage is that a parallel "unnatural" increase of
+# system time (set time via ntpd etc.) is able to hide a wrong working SLEEP
+# function. This is no problem because
+# - such changes of the system are rare
+# - there is an extreme high probability that either the following test
+# or the frequent runs of the current test on the current testing box or
+# other boxes catch a wrong working SLEEP function.
+create table t1 (id int,
+ a timestamp default '2005-05-05 01:01:01',
b timestamp default '2005-05-05 01:01:01');
-insert into t1 set a = now();
-select sleep(3);
-update t1 set b = now();
-select timediff(b, a) >= '00:00:03' from t1;
+insert into t1 set id = 1,a = now();
+select sleep(3);
+update t1 set b = now() where id = 1;
+insert into t1 set id = 2,a = now();
+select sleep(3);
+update t1 set b = now() where id = 2;
+# Check that the timediff caused by the length of the sleep is not plain wrong.
+# We can have delays in statement processing of 1 - 2 seconds on
+# an overloaded testing box.
+# Minimum (= ideal) real timediff = '00:00:03'
+# Maximum acceptable real timediff = '00:00:07'
+select count(*) >= 1 from t1
+where timediff(b, a) between '00:00:03' and '00:00:07';
drop table t1;
-#
+################################################################################
# Bug #12689: SLEEP() gets incorrectly cached/optimized-away
#
-set global query_cache_size=1355776;
-create table t1 (a int);
-insert into t1 values (1),(1),(1);
-create table t2 (a datetime default null, b datetime default null);
-insert into t2 set a = now();
-select a from t1 where sleep(1);
-update t2 set b = now() where b is null;
-insert into t2 set a = now();
-select a from t1 where sleep(a);
-update t2 set b = now() where b is null;
-insert into t2 set a = now();
-select a from t1 where sleep(1);
-update t2 set b = now() where b is null;
-select timediff(b, a) >= '00:00:03' from t2;
-drop table t2;
-drop table t1;
-set global query_cache_size=default;
+# Description from bug report (slightly modified)
+# ===============================================
+# Bug 1 (happened all time):
+# SELECT * FROM t1 WHERE SLEEP(1) will only result in a sleep of 1
+# second, regardless of the number of rows in t1.
+# Bug 2 (happened all time):
+# Such a query will also get cached by the query cache, but should not.
+#
+# Notes (mleich, May 2008)
+# ========================
+# 1. The testcase for this bug had to be reimplemented because of
+# Bug#36345 Test 'func_misc' fails on RHAS3 x86_64
+# - Bad effect: We did not reach the expected time differences.
+# - Experiments showed that for example a parallel change of the system
+# time (decrease of time value) like via ntpd provokes this effect.
+#
+# It is a clear error within the setup of the testing environment if
+# tests relying on derivates of the system time can meet parallel
+# manipulations of this time. Covering these weaknesses by workarounds
+# within the tests is often not perfect doable at all and costs
+# significant development and/or runtime per test.
+#
+# Results of experiments with/without manipulation of system time:
+# ----------------------------------------------------------------
+# Definition: Predicted_cumulative_sleep_time =
+# #_of_result_rows * sleep_time_per_result_row
+# processlist.time refers to the session in state 'User sleep'
+#
+# 1. Total (real sleep time) ~= predicted_cumulative_sleep_time !!
+# 2. processlist.time behaves "synchronous" to system time and NOW() and
+# shows also the "jumps" caused by system time manipulations
+# 3. processlist.time is unsigned, the next value below 0 is ~ 4G
+# 4. Current processlist.time ~= current real sleep time
+# if the system time was not manipulated
+#
+# 2. How to reveal the absence of Bug 1:
+#
+# The state of a session within the PROCESSLIST changes to 'User sleep'
+# if the sessions runs a statement containing the sleep function and the
+# processing of the statement is just within the phase where the sleep
+# is done.
+#
+# As soon as the "Real" time where the session is in state 'User sleep'
+# exceeds the sleep_time_per_result_row we can be sure that the execution
+# of the query slept more time than needed for just one row.
+#
+# "Real" time in state 'User sleep' > sleep_time_per_result_row
+#
+# Estimation 1:
+# -------------
+# n = how often we observed the session is in state 'User sleep'
+#
+# "Real" time in state 'User sleep'
+# = (n - 1) * sleep_time_in_loop
+# + time needed for the execution of the statements within the loop
+# (includes the time waiting for getting resources like CPU etc.
+# which si significant in case of high load on testing box)
+#
+# (n - 1) * sleep_time_in_loop >= sleep_time_per_result_row
+#
+# n >= sleep_time_per_result_row / sleep_time_in_loop + 1
+#
+# Simplification taking truncation of values etc. into account:
+# n >= sleep_time_per_result_row / sleep_time_in_loop + 2
+#
+# We cannot have met Bug 1 if
+# n >= sleep_time_per_result_row / sleep_time_in_loop + 2
+# is fulfilled.
+# But there is a significant risk that a run on an overloaded box
+# does not reach the estimated limit.
+#
+# Estimation 2:
+# -------------
+# processlist.time should show how long a session is within the current
+# state. I verified by experimenting that this value is not reset per
+# row of the the result set.
+#
+# "Real" time in state 'User sleep'
+# >= highest observed value of processlist.time
+#
+# We cannot have met Bug 1 if
+# highest observed value of processlist.time > sleep_time_per_result_row
+# is fulfilled.
+# Unfortunately processlist.time is no more reliable in case of parallel
+# changes of the system time.
+#
+# Final solution:
+# ---------------
+# Run a subtest with "judging" based on estimation 1. If the limit is not
+# reached, assume that we suffered from high load and try estimation 2.
+# If estimation 2 gets cheated by parallel increase of system time
+# assume that later runs on the same box or other boxes will show if
+# Bug#12689 occured again.
+#
+# 3. How to reveal the absence of Bug 2:
+# - By checking the behaviour during second execution:
+# We run the same statement again and meet the session at least once in
+# state 'User sleep'.
+# - By checking secondary information (query cache statistics)
+# The first execution of the statment must not cause that
+# Qcache_queries_in_cache is incremented.
+#
+# 4. We do not run
+# --source include/have_query_cache.inc
+# at the beginning of this script because we want that this script is not
+# skipped if the query cache is disabled. This means the detection of wrongly
+# cached queries is in such cases without real effect.
+#
+# 5. Thanks to Davi for excellent hints and ideas.
+#
+################################################################################
+
+# 1. For Bug 2: Qcache_queries_in_cache must be not incremented if a query with
+# sleep was first time executed.
+SET @@global.query_cache_size = 1024 * 64;
+let $Qcache_queries_in_cache_before =
+ query_get_value(SHOW STATUS LIKE 'Qcache_queries_in_cache', Value, 1);
+SELECT 1 as some_value, sleep(1);
+let $Qcache_queries_in_cache_after =
+ query_get_value(SHOW STATUS LIKE 'Qcache_queries_in_cache', Value, 1);
+# Show that the query with sleep was not cached via query cache statistics.
+--replace_result $Qcache_queries_in_cache_before <Qcache_queries_in_cache_before>
$Qcache_queries_in_cache_after <Qcache_queries_in_cache_after>
+eval SELECT $Qcache_queries_in_cache_before = $Qcache_queries_in_cache_after
+ AS "Was the query not cached (= expectation)?";
+#
+# 2. For Bug 1: Estimation 1
+# Real sleep time must exceed the sleep time for just one row.
+#
+let $sleep_time_per_result_row = 1;
+let $row_count = 4;
+
+--disable_warnings
+DROP TEMPORARY TABLE IF EXISTS proclist_history;
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+CREATE TEMPORARY TABLE proclist_history AS
+SELECT 'Bug 1' AS test, 0 AS attempt, NOW() AS observation_time, state, time
+FROM information_schema.processlist WHERE 1 = 0;
+CREATE TABLE t1 (f1 BIGINT);
+let $num = $row_count;
+while ($num)
+{
+ INSERT INTO t1 VALUES (1);
+ dec $num;
+}
+
+eval SET @sleep_time_per_result_row = $sleep_time_per_result_row;
+let $sleep_command = SELECT sleep(@sleep_time_per_result_row) FROM t1;
+
+# Set wait_timeout to a useful small value.
+let $wait_timeout= `SELECT $row_count * $sleep_time_per_result_row + 5`;
+let $wait_condition =
+ SELECT COUNT(*) >= @sleep_time_per_result_row / 0.1 + 2
+ FROM proclist_history WHERE test = 'Bug 1';
+
+--echo ----- establish connection con1 (user = root) -----
+connect (con1,localhost,root,,);
+eval SET @sleep_time_per_result_row = $sleep_time_per_result_row;
+let $Qcache_queries_in_cache_before =
+ query_get_value(SHOW STATUS LIKE 'Qcache_queries_in_cache', Value, 1);
+--echo Qcache_queries_in_cache: $Qcache_queries_in_cache_before
+--echo # Send query with send, pull server responses later
+send;
+eval $sleep_command;
+#
+--echo ----- switch to connection default (user = root) -----
+connection default;
+#
+--disable_query_log
+let $wait_counter= `SELECT $wait_timeout * 10`;
+let $wait_condition_reps= 0;
+while ($wait_counter)
+{
+ let $success= `$wait_condition`;
+ inc $wait_condition_reps;
+ eval
+ INSERT INTO proclist_history
+ ( test, attempt, observation_time, state, time)
+ SELECT 'Bug 1', $wait_condition_reps, NOW(), state, time
+ FROM information_schema.processlist
+ WHERE info = '$sleep_command';
+ if ($success)
+ {
+ let $wait_counter= 0;
+ }
+ if (!$success)
+ {
+ real_sleep 0.1;
+ dec $wait_counter;
+ }
+}
+--enable_query_log
+if (!$success)
+{
+ # Estimation 1 had no success - We are most probably on a testing box
+ # running under high load.
+ # Try Estimation 2:
+ let $success = `SELECT MAX(time) > @sleep_time_per_result_row
+ FROM proclist_history WHERE test = 'Bug 1'`;
+}
+if (!$success)
+{
+ --echo # ------------------------------------------------------------
+ --echo # The check for
+ --echo # Bug#12689: SLEEP() gets incorrectly cached/optimized-away
+ --echo # failed. None of both estimations are fulfilled.
+ --echo #
+ --echo # Dumping debug information
+ --echo #
+ --echo # Estimation 1:
+ eval $wait_condition;
+ --echo # ------------------------------------------------------------
+ --echo # Estimation 2:
+ SELECT MAX(time) > @sleep_time_per_result_row
+ FROM proclist_history WHERE test = 'Bug 1';
+ --echo # ------------------------------------------------------------
+ SELECT attempt, observation_time, state, time FROM proclist_history
+ WHERE test = 'Bug 1' ORDER BY attempt;
+ --echo # ------------------------------------------------------------
+}
+--echo ----- switch to connection con1 (user = root) -----
+connection con1;
+--echo # Pull server responses of last query
+reap;
+#
+# 3. For Bug 2: A second execution of the same statement must again show
+# the session in state 'User sleep'.
+--echo ----- switch to connection con1 (user = root) -----
+connection con1;
+--echo # Send query with send, pull server responses later
+send;
+eval $sleep_command;
+#
+--echo ----- switch to connection default (user = root) -----
+connection default;
+let $wait_condition = SELECT COUNT(*) FROM information_schema.processlist
+ WHERE info = '$sleep_command'
+ AND state = 'User sleep';
+--source include/wait_condition.inc
+# Simply show that we reached the expected state.
+eval $wait_condition;
+--echo ----- switch to connection con1 (user = root) -----
+connection con1;
+--echo # Pull server responses of last query
+reap;
+--echo ----- switch to connection default and close connection con1 -----
+connection default;
+disconnect con1;
+SET @@global.query_cache_size = default;
+DROP TABLE t1;
+DROP TEMPORARY TABLE proclist_history;
#
# Bug #21466: INET_ATON() returns signed, not unsigned
=== modified file 'mysql-test/t/general_log_file_basic.test'
--- a/mysql-test/t/general_log_file_basic.test 2008-04-10 13:14:28 +0000
+++ b/mysql-test/t/general_log_file_basic.test 2008-05-20 18:23:58 +0000
@@ -52,8 +52,11 @@
# Change the value of general_log_file to a invalid value #
#######################################################################
---Error ER_WRONG_VALUE_FOR_VAR
+# Assumed text if no quotes or numbers.
SET @@global.general_log_file = mytest.log;
+--error ER_WRONG_TYPE_FOR_VAR
+SET @@global.general_log_file = 12;
+
--echo '#----------------------FN_DYNVARS_004_03------------------------#'
##############################################################################
=== modified file 'mysql-test/t/grant.test'
--- a/mysql-test/t/grant.test 2008-03-28 08:41:52 +0000
+++ b/mysql-test/t/grant.test 2008-04-19 10:58:37 +0000
@@ -1266,6 +1266,12 @@
use test;
DROP TABLE t1;
+--echo #
+--echo # Bug#33275 Server crash when creating temporary table mysql.user
+--echo #
+CREATE TEMPORARY TABLE mysql.user (id INT);
+FLUSH PRIVILEGES;
+DROP TABLE mysql.user;
#
# Bug #33201 Crash occurs when granting update privilege on one column of a view
#
=== modified file 'mysql-test/t/log_output_basic.test'
--- a/mysql-test/t/log_output_basic.test 2008-04-10 13:14:28 +0000
+++ b/mysql-test/t/log_output_basic.test 2008-05-20 18:23:58 +0000
@@ -59,6 +59,7 @@
--Error ER_WRONG_VALUE_FOR_VAR
SET @@global.log_output = NULL;
+--Error ER_WRONG_VALUE_FOR_VAR
SET @@global.log_output = "";
SELECT @@global.log_output;
--echo 'Bug# 34838: Empty value is allowed where as it is not specified in';
@@ -171,6 +172,7 @@
###################################################################
# test if variable accepts 0,1,2
+--Error ER_WRONG_VALUE_FOR_VAR
SET @@global.log_output = 0;
SELECT @@global.log_output;
@@ -206,6 +208,7 @@
SET @@global.log_output = TRUE;
SELECT @@global.log_output;
+--Error ER_WRONG_VALUE_FOR_VAR
SET @@global.log_output = FALSE;
SELECT @@global.log_output;
=== modified file 'mysql-test/t/log_state.test'
--- a/mysql-test/t/log_state.test 2007-12-05 19:33:36 +0000
+++ b/mysql-test/t/log_state.test 2008-03-28 18:46:18 +0000
@@ -231,6 +231,34 @@
set global general_log_file= @old_general_log_file;
set global slow_query_log_file= @old_slow_query_log_file;
+###########################################################################
+
+--echo
+--echo # --
+--echo # -- Bug#32748: Inconsistent handling of assignments to
+--echo # -- general_log_file/slow_query_log_file.
+--echo # --
+
+--echo
+SET @general_log_file_saved = @@global.general_log_file;
+SET @slow_query_log_file_saved = @@global.slow_query_log_file;
+
+--echo
+SET GLOBAL general_log_file = 'bug32748.query.log';
+SET GLOBAL slow_query_log_file = 'bug32748.slow.log';
+
+--echo
+SHOW VARIABLES LIKE '%log_file';
+
+--echo
+SET GLOBAL general_log_file = @general_log_file_saved;
+SET GLOBAL slow_query_log_file = @slow_query_log_file_saved;
+
+--echo
+--echo # -- End of Bug#32748.
+
+###########################################################################
+
--echo End of 5.1 tests
--enable_ps_protocol
=== modified file 'mysql-test/t/ps.test'
--- a/mysql-test/t/ps.test 2008-02-28 23:22:50 +0000
+++ b/mysql-test/t/ps.test 2008-05-20 18:43:26 +0000
@@ -2979,6 +2979,24 @@
deallocate prepare stmt;
drop table t1, t2;
+--echo #
+--echo # Bug#27430 Crash in subquery code when in PS and table DDL changed
+--echo # after PREPARE
+--echo #
+--echo # This part of the test doesn't work in embedded server, this is
+--echo # why it's here. For the main test see ps_ddl*.test
+--echo
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "show events where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
--echo End of 5.1 tests.
=== modified file 'mysql-test/t/ps_1general.test'
--- a/mysql-test/t/ps_1general.test 2007-08-15 08:18:41 +0000
+++ b/mysql-test/t/ps_1general.test 2008-04-08 16:01:20 +0000
@@ -181,7 +181,7 @@
a int primary key,
b char(30),
c int,
- d timestamp default current_timestamp
+ d timestamp default '2008-02-23 09:23:45'
);
insert into t5( a, b, c) values( 9, 'recreated table', 9);
execute stmt2 ;
@@ -191,7 +191,7 @@
create table t5
(
a int primary key,
- d timestamp default current_timestamp,
+ d timestamp default '2008-02-23 09:23:45',
b char(30),
c int
);
@@ -218,7 +218,6 @@
f3 int
);
insert into t5( f1, f2, f3) values( 9, 'recreated table', 9);
---error 1054
execute stmt2 ;
drop table t5 ;
=== modified file 'mysql-test/t/ps_ddl.test'
--- a/mysql-test/t/ps_ddl.test 2008-02-07 19:00:48 +0000
+++ b/mysql-test/t/ps_ddl.test 2008-05-20 18:43:26 +0000
@@ -47,1629 +47,1146 @@
# - Part 20: Special tables (log tables)
# - Part 21: Special tables (system tables)
# - Part 22: Special tables (views temp tables)
-# - Part 23: Special tables (internal join tables)
-# - Part 24: Special statements
-# - Part 25: Testing the strength of TABLE_SHARE version
-
-let $base_count = SELECT VARIABLE_VALUE from
-INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
-into @base_count ;
-
-let $check = SELECT CASE (VARIABLE_VALUE - @base_count - @expected)
- WHEN 0 THEN "PASSED"
- ELSE "FAILED"
- END
- AS `CHECK`,
- (VARIABLE_VALUE - @base_count - @expected) AS `OFFSET`
- from INFORMATION_SCHEMA.SESSION_STATUS
- where variable_name='COM_STMT_REPREPARE' ;
-
-eval $base_count;
-set @expected = 0;
-
-# Maintainer:
-# When not expecting a re-prepare, write the test like this:
-# execute stmt;
-# eval $check;
-#
-# When expecting a re-prepare, write the test like this:
-# set @expected = @expected + 1;
-# execute stmt;
-# eval $check;
-#
-
---echo =====================================================================
---echo Testing 1: NOTHING -> TABLE transitions
---echo =====================================================================
-
+# - Part 23: Special statements
+# - Part 24: Testing the strength of TABLE_SHARE version
--disable_warnings
-drop table if exists t1;
+drop temporary table if exists t1, t2, t3;
+drop table if exists t1, t2, t3;
+drop procedure if exists p_verify_reprepare_count;
+drop procedure if exists p1;
+drop function if exists f1;
+drop view if exists v1, v2;
--enable_warnings
+delimiter |;
+create procedure p_verify_reprepare_count(expected int)
+begin
+ declare old_reprepare_count int default @reprepare_count;
+
+ select variable_value from
+ information_schema.session_status where
+ variable_name='com_stmt_reprepare'
+ into @reprepare_count;
+
+ if old_reprepare_count + expected <> @reprepare_count then
+ select concat("Expected: ", expected,
+ ", actual: ", @reprepare_count - old_reprepare_count)
+ as "ERROR";
+ else
+ select '' as "SUCCESS";
+ end if;
+end|
+delimiter ;|
+set @reprepare_count= 0;
+flush status;
+
+--echo =====================================================================
+--echo Part 1: NOTHING -> TABLE transitions
+--echo =====================================================================
+
# can not be tested since prepare failed
--error ER_NO_SUCH_TABLE
-prepare stmt from 'select * from t1';
-
---echo =====================================================================
---echo Testing 2: NOTHING -> TEMPORARY TABLE transitions
---echo =====================================================================
-
-# can not be tested
-
---echo =====================================================================
---echo Testing 3: NOTHING -> VIEW transitions
---echo =====================================================================
-
-# can not be tested
-
---echo =====================================================================
---echo Testing 4: TABLE -> NOTHING transitions
---echo =====================================================================
-
---disable_warnings
-drop table if exists t4;
---enable_warnings
-
-create table t4(a int);
-
-prepare stmt from 'select * from t4';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop table t4;
---error ER_NO_SUCH_TABLE
-execute stmt;
-eval $check;
---error ER_NO_SUCH_TABLE
-execute stmt;
-eval $check;
-
---echo =====================================================================
---echo Testing 5: TABLE -> TABLE (DDL) transitions
---echo =====================================================================
-
---disable_warnings
-drop table if exists t5;
---enable_warnings
-
-create table t5(a int);
-
-prepare stmt from 'select a from t5';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-alter table t5 add column (b int);
-
-set @expected = @expected + 1;
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop table t5;
-
---echo =====================================================================
---echo Testing 6: TABLE -> TABLE (TRIGGER) transitions
---echo =====================================================================
-
-#
-# Test 6-a: adding a relevant trigger
-# Test 6-b: adding an irrelevant trigger
-# Test 6-c: changing a relevant trigger
-# Test 6-d: changing an irrelevant trigger
-# Test 6-e: removing a relevant trigger
-# Test 6-f: removing an irrelevant trigger
-#
-
---disable_warnings
-drop table if exists t6;
---enable_warnings
-
-create table t6(a int);
-
-prepare stmt from 'insert into t6(a) value (?)';
+prepare stmt from "select * from t1";
+
+--echo =====================================================================
+--echo Part 2: NOTHING -> TEMPORARY TABLE transitions
+--echo =====================================================================
+
+# can not be tested
+
+--echo =====================================================================
+--echo Part 3: NOTHING -> VIEW transitions
+--echo =====================================================================
+
+# can not be tested
+
+--echo =====================================================================
+--echo Part 4: TABLE -> NOTHING transitions
+--echo =====================================================================
+
+--echo # Test 4-a: select ... from <table>
+create table t1 (a int);
+
+prepare stmt from "select * from t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop table t1;
+--error ER_NO_SUCH_TABLE
+execute stmt;
+call p_verify_reprepare_count(0);
+--error ER_NO_SUCH_TABLE
+execute stmt;
+call p_verify_reprepare_count(0);
+deallocate prepare stmt;
+
+--echo # Test 4-b: TABLE -> NOTHING by renaming the table
+create table t1 (a int);
+prepare stmt from "select * from t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+rename table t1 to t2;
+--error ER_NO_SUCH_TABLE
+execute stmt;
+call p_verify_reprepare_count(0);
+--error ER_NO_SUCH_TABLE
+execute stmt;
+call p_verify_reprepare_count(0);
+
+deallocate prepare stmt;
+drop table t2;
+
+--echo =====================================================================
+--echo Part 5: TABLE -> TABLE (DDL) transitions
+--echo =====================================================================
+
+create table t1 (a int);
+
+prepare stmt from "select a from t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+alter table t1 add column (b int);
+
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop table t1;
+deallocate prepare stmt;
+
+
+--echo =====================================================================
+--echo Part 6: TABLE -> TABLE (TRIGGER) transitions
+--echo =====================================================================
+
+--echo # Test 6-a: adding a relevant trigger
+
+create table t1 (a int);
+
+prepare stmt from "insert into t1 (a) value (?)";
set @val=1;
execute stmt using @val;
-eval $check;
+call p_verify_reprepare_count(0);
+
+# Relevant trigger: execute should reprepare
+create trigger t1_bi before insert on t1 for each row
+ set @message= new.a;
+
set @val=2;
execute stmt using @val;
-eval $check;
-
-# Relevant trigger: execute should reprepare
-delimiter $$;
-create trigger t6_bi before insert on t6 for each row
- begin
- set @message= "t6_bi";
- end
-$$
-delimiter ;$$
-
-set @message="none";
+call p_verify_reprepare_count(1);
+select @message;
set @val=3;
-set @expected = @expected + 1;
execute stmt using @val;
-eval $check;
+call p_verify_reprepare_count(0);
select @message;
+
+prepare stmt from "insert into t1 (a) value (?)";
set @val=4;
execute stmt using @val;
-eval $check;
+call p_verify_reprepare_count(0);
select @message;
-prepare stmt from 'insert into t6(a) value (?)';
-set @message="none";
+--echo # Test 6-b: adding an irrelevant trigger
+
+# Unrelated trigger: reprepare may or may not happen, implementation dependent
+create trigger t1_bd before delete on t1 for each row
+ set @message= old.a;
+
set @val=5;
execute stmt using @val;
-eval $check;
+call p_verify_reprepare_count(1);
select @message;
-set @message="none";
set @val=6;
execute stmt using @val;
-eval $check;
+call p_verify_reprepare_count(0);
select @message;
-# Unrelated trigger: execute can pass of fail, implementation dependent
-delimiter $$;
-create trigger t6_bd before delete on t6 for each row
- begin
- set @message= "t6_bd";
- end
-$$
-delimiter ;$$
-
-set @message="none";
+prepare stmt from "insert into t1 (a) value (?)";
set @val=7;
-set @expected = @expected + 1;
execute stmt using @val;
-eval $check;
+call p_verify_reprepare_count(0);
select @message;
-set @message="none";
+
+--echo # Test 6-c: changing a relevant trigger
+
+# Relevant trigger: execute should reprepare
+drop trigger t1_bi;
+create trigger t1_bi before insert on t1 for each row
+ set @message= concat("new trigger: ", new.a);
+
set @val=8;
execute stmt using @val;
-eval $check;
+call p_verify_reprepare_count(1);
select @message;
-
-prepare stmt from 'insert into t6(a) value (?)';
-set @message="none";
set @val=9;
execute stmt using @val;
-eval $check;
+call p_verify_reprepare_count(0);
select @message;
-set @message="none";
+
+prepare stmt from "insert into t1 (a) value (?)";
set @val=10;
execute stmt using @val;
-eval $check;
+call p_verify_reprepare_count(0);
select @message;
-# Relevant trigger: execute should reprepare
-drop trigger t6_bi;
-delimiter $$;
-create trigger t6_bi before insert on t6 for each row
- begin
- set @message= "t6_bi (2)";
- end
-$$
-delimiter ;$$
-
-set @message="none";
+--echo # Test 6-d: changing an irrelevant trigger
+
+# Unrelated trigger: reprepare may or may not happen, implementation dependent
+drop trigger t1_bd;
+
set @val=11;
-set @expected = @expected + 1;
execute stmt using @val;
-eval $check;
+call p_verify_reprepare_count(1);
select @message;
+
+--echo Test 6-e: removing a relevant trigger
+
+drop trigger t1_bi;
+
set @val=12;
execute stmt using @val;
-eval $check;
+call p_verify_reprepare_count(1);
select @message;
-
-prepare stmt from 'insert into t6(a) value (?)';
-set @message="none";
set @val=13;
execute stmt using @val;
-eval $check;
+call p_verify_reprepare_count(0);
select @message;
-set @message="none";
+
+prepare stmt from "insert into t1 (a) value (?)";
set @val=14;
execute stmt using @val;
-eval $check;
-select @message;
-
-# Unrelated trigger: execute can pass of fail, implementation dependent
-drop trigger t6_bd;
-delimiter $$;
-create trigger t6_bd before delete on t6 for each row
- begin
- set @message= "t6_bd (2)";
- end
-$$
-delimiter ;$$
-
-set @message="none";
-set @val=15;
-set @expected = @expected + 1;
-execute stmt using @val;
-eval $check;
-select @message;
-set @message="none";
-set @val=16;
-execute stmt using @val;
-eval $check;
-select @message;
-
-prepare stmt from 'insert into t6(a) value (?)';
-set @message="none";
-set @val=17;
-execute stmt using @val;
-eval $check;
-select @message;
-set @message="none";
-set @val=18;
-execute stmt using @val;
-eval $check;
-select @message;
-
-drop trigger t6_bi;
-
-set @message="none";
-set @val=19;
-set @expected = @expected + 1;
-execute stmt using @val;
-eval $check;
-select @message;
-set @val=20;
-execute stmt using @val;
-eval $check;
-select @message;
-
-prepare stmt from 'insert into t6(a) value (?)';
-set @message="none";
-set @val=21;
-execute stmt using @val;
-eval $check;
-select @message;
-set @val=22;
-execute stmt using @val;
-eval $check;
-select @message;
-
-drop trigger t6_bd;
-
-set @val=23;
-set @expected = @expected + 1;
-execute stmt using @val;
-eval $check;
-select @message;
-set @val=24;
-execute stmt using @val;
-eval $check;
-select @message;
-
-select * from t6 order by a;
-drop table t6;
-
---echo =====================================================================
---echo Testing 7: TABLE -> TABLE (TRIGGER dependencies) transitions
---echo =====================================================================
-
-#
-# Test 7-a: dependent PROCEDURE has changed
-# Test 7-b: dependent FUNCTION has changed
-# Test 7-c: dependent VIEW has changed
-# Test 7-d: dependent TABLE has changed
-# Test 7-e: dependent TABLE TRIGGER has changed
-#
-
---disable_warnings
-drop table if exists t7_proc;
-drop table if exists t7_func;
-drop table if exists t7_view;
-drop table if exists t7_table;
-drop table if exists t7_dependent_table;
-drop table if exists t7_table_trigger;
-drop table if exists t7_audit;
-drop procedure if exists audit_proc;
-drop function if exists audit_func;
-drop view if exists audit_view;
---enable_warnings
-
-create table t7_proc(a int);
-create table t7_func(a int);
-create table t7_view(a int);
-create table t7_table(a int);
-create table t7_table_trigger(a int);
-
-create table t7_audit(old_a int, new_a int, reason varchar(50));
-create table t7_dependent_table(old_a int, new_a int, reason varchar(50));
-
-create procedure audit_proc(a int)
- insert into t7_audit values (NULL, a, "proc v1");
-
-create function audit_func() returns varchar(50)
- return "func v1";
-
-create view audit_view as select "view v1" as reason from dual;
-
-create trigger t7_proc_bi before insert on t7_proc for each row
- call audit_proc(NEW.a);
-
-create trigger t7_func_bi before insert on t7_func for each row
- insert into t7_audit values (NULL, NEW.a, audit_func());
-
-create trigger t7_view_bi before insert on t7_view for each row
- insert into t7_audit values (NULL, NEW.a, (select reason from audit_view));
-
-create trigger t7_table_bi before insert on t7_table for each row
- insert into t7_dependent_table values (NULL, NEW.a, "dependent table");
-
-create trigger t7_table_trigger_bi before insert on t7_dependent_table
- for each row set NEW.reason="trigger v1";
-
-prepare stmt_proc from 'insert into t7_proc(a) value (?)';
-set @val=101;
-execute stmt_proc using @val;
-eval $check;
-set @val=102;
-execute stmt_proc using @val;
-eval $check;
-
-drop procedure audit_proc;
-
-create procedure audit_proc(a int)
- insert into t7_audit values (NULL, a, "proc v2");
-
-set @val=103;
-set @expected = @expected + 1;
-execute stmt_proc using @val;
-eval $check;
-set @val=104;
-execute stmt_proc using @val;
-eval $check;
-
-
-prepare stmt_func from 'insert into t7_func(a) value (?)';
-set @val=201;
-execute stmt_func using @val;
-eval $check;
-set @val=202;
-execute stmt_func using @val;
-eval $check;
-
-drop function audit_func;
-
-create function audit_func() returns varchar(50)
- return "func v2";
-
-set @val=203;
-set @expected = @expected + 1;
-execute stmt_func using @val;
-eval $check;
-set @val=204;
-execute stmt_func using @val;
-eval $check;
-
-prepare stmt_view from 'insert into t7_view(a) value (?)';
-set @val=301;
-execute stmt_view using @val;
-eval $check;
-set @val=302;
-execute stmt_view using @val;
-eval $check;
-
-drop view audit_view;
-
-create view audit_view as select "view v2" as reason from dual;
-
-# Because of Bug#33255, the wrong result is still produced for cases
-# 303 and 304, even after re-preparing the statement.
-# This is because the table trigger is cached and is not invalidated.
-
-set @val=303;
-set @expected = @expected + 1;
-execute stmt_view using @val;
-eval $check;
-set @val=304;
-execute stmt_view using @val;
-eval $check;
-
-
-prepare stmt_table from 'insert into t7_table(a) value (?)';
-set @val=401;
-execute stmt_table using @val;
-eval $check;
-set @val=402;
-execute stmt_table using @val;
-eval $check;
-
-alter table t7_dependent_table add column comments varchar(100) default NULL;
-
-set @val=403;
-set @expected = @expected + 1;
---error ER_WRONG_VALUE_COUNT_ON_ROW
-execute stmt_table using @val;
-eval $check;
-set @val=404;
-set @expected = @expected + 1;
---error ER_WRONG_VALUE_COUNT_ON_ROW
-execute stmt_table using @val;
-eval $check;
-
-alter table t7_dependent_table drop column comments;
-
-set @val=405;
-set @expected = @expected + 1;
-execute stmt_table using @val;
-eval $check;
-set @val=406;
-execute stmt_table using @val;
-eval $check;
-
-
-prepare stmt_table_trigger from 'insert into t7_table(a) value (?)';
-set @val=501;
-execute stmt_table_trigger using @val;
-eval $check;
-set @val=502;
-execute stmt_table_trigger using @val;
-eval $check;
-
-drop trigger t7_table_trigger_bi;
-
-create trigger t7_table_trigger_bi before insert on t7_dependent_table
- for each row set NEW.reason="trigger v2";
-
-set @val=503;
-set @expected = @expected + 1;
-execute stmt_table_trigger using @val;
-eval $check;
-set @val=504;
-execute stmt_table_trigger using @val;
-eval $check;
-
-select * from t7_audit order by new_a;
-
-select * from t7_dependent_table order by new_a;
-
-drop table t7_proc;
-drop table t7_func;
-drop table t7_view;
-drop table t7_table;
-drop table t7_dependent_table;
-drop table t7_table_trigger;
-drop table t7_audit;
-drop procedure audit_proc;
-drop function audit_func;
-drop view audit_view;
-
---echo =====================================================================
---echo Testing 8: TABLE -> TEMPORARY TABLE transitions
---echo =====================================================================
-
---disable_warnings
-drop table if exists t8;
---enable_warnings
-
-create table t8(a int);
-
-prepare stmt from 'select * from t8';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop table t8;
-create temporary table t8(a int);
-
-set @expected = @expected + 1;
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop table t8;
-
---echo =====================================================================
---echo Testing 9: TABLE -> VIEW transitions
---echo =====================================================================
-
---disable_warnings
-drop table if exists t9;
-drop table if exists t9_b;
---enable_warnings
-
-create table t9(a int);
-create table t9_b(a int);
-
-prepare stmt from 'select * from t9';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop table t9;
-create view t9 as select * from t9_b;
-
-set @expected = @expected + 1;
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop view t9;
-drop table t9_b;
-
---echo =====================================================================
---echo Testing 10: TEMPORARY TABLE -> NOTHING transitions
---echo =====================================================================
-
---disable_warnings
-drop temporary table if exists t10;
---enable_warnings
-
-create temporary table t10(a int);
-
-prepare stmt from 'select * from t10';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop temporary table t10;
---error ER_NO_SUCH_TABLE
-execute stmt;
-eval $check;
---error ER_NO_SUCH_TABLE
-execute stmt;
-eval $check;
-
---echo =====================================================================
---echo Testing 11: TEMPORARY TABLE -> TABLE transitions
---echo =====================================================================
-
---disable_warnings
-drop table if exists t11;
-drop temporary table if exists t11;
---enable_warnings
-
-create table t11(a int);
-insert into t11(a) value (1);
-create temporary table t11(a int);
-
-prepare stmt from 'select * from t11';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop temporary table t11;
-
-set @expected = @expected + 1;
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-select * from t11;
-drop table t11;
-
---echo =====================================================================
---echo Testing 12: TEMPORARY TABLE -> TEMPORARY TABLE (DDL) transitions
---echo =====================================================================
-
---disable_warnings
-drop temporary table if exists t12;
---enable_warnings
-
-create temporary table t12(a int);
-
-prepare stmt from 'select a from t12';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop temporary table t12;
-create temporary table t12(a int, b int);
-
-set @expected = @expected + 1;
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-select * from t12;
-drop table t12;
-
---echo =====================================================================
---echo Testing 13: TEMPORARY TABLE -> VIEW transitions
---echo =====================================================================
-
---disable_warnings
-drop temporary table if exists t13;
-drop table if exists t13_b;
---enable_warnings
-
-create temporary table t13(a int);
-create table t13_b(a int);
-
-prepare stmt from 'select * from t13';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop temporary table t13;
-create view t13 as select * from t13_b;
-
-set @expected = @expected + 1;
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop view t13;
-drop table t13_b;
-
---echo =====================================================================
---echo Testing 14: VIEW -> NOTHING transitions
---echo =====================================================================
-
---disable_warnings
-drop view if exists t14;
-drop table if exists t14_b;
---enable_warnings
-
-create table t14_b(a int);
-create view t14 as select * from t14_b;
-
-prepare stmt from 'select * from t14';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop view t14;
-
-set @expected = @expected + 1;
---error ER_NO_SUCH_TABLE
-execute stmt;
-eval $check;
-set @expected = @expected + 1;
---error ER_NO_SUCH_TABLE
-execute stmt;
-eval $check;
-
-drop table t14_b;
-
---echo =====================================================================
---echo Testing 15: VIEW -> TABLE transitions
---echo =====================================================================
-
---disable_warnings
-drop view if exists t15;
-drop table if exists t15_b;
---enable_warnings
-
-create table t15_b(a int);
-create view t15 as select * from t15_b;
-
-prepare stmt from 'select * from t15';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop view t15;
-create table t15(a int);
-
-set @expected = @expected + 1;
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop table t15_b;
-drop table t15;
-
---echo =====================================================================
---echo Testing 16: VIEW -> TEMPORARY TABLE transitions
---echo =====================================================================
-
---disable_warnings
-drop view if exists t16;
-drop table if exists t16_b;
---enable_warnings
-
-create table t16_b(a int);
-create view t16 as select * from t16_b;
-
-prepare stmt from 'select * from t16';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop view t16;
-create temporary table t16(a int);
-
-set @expected = @expected + 1;
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop table t16_b;
-drop temporary table t16;
-
---echo =====================================================================
---echo Testing 17: VIEW -> VIEW (DDL) transitions
---echo =====================================================================
-
---disable_warnings
-drop view if exists t17;
-drop table if exists t17_b;
---enable_warnings
-
-create table t17_b(a int);
-insert into t17_b values (10), (20), (30);
-
-create view t17 as select a, 2*a as b, 3*a as c from t17_b;
-select * from t17;
-
-prepare stmt from 'select * from t17';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop view t17;
-create view t17 as select a, 2*a as b, 5*a as c from t17_b;
-select * from t17;
-
-set @expected = @expected + 1;
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop table t17_b;
-drop view t17;
-
---echo =====================================================================
---echo Testing 18: VIEW -> VIEW (VIEW dependencies) transitions
---echo =====================================================================
-
-#
-# Test 18-a: dependent PROCEDURE has changed (via a trigger)
-# Test 18-b: dependent FUNCTION has changed
-# Test 18-c: dependent VIEW has changed
-# Test 18-d: dependent TABLE has changed
-# Test 18-e: dependent TABLE TRIGGER has changed
-#
-
---disable_warnings
-drop table if exists t18;
-drop table if exists t18_dependent_table;
-drop view if exists t18_func;
-drop view if exists t18_view;
-drop view if exists t18_table;
-drop function if exists view_func;
-drop view if exists view_view;
---enable_warnings
-
-# TODO: insertable view -> trigger
-# TODO: insertable view -> trigger -> proc ?
-
-create table t18(a int);
-insert into t18 values (1), (2), (3);
-
-create function view_func(x int) returns int
- return x+1;
-
-create view view_view as select "view v1" as reason from dual;
-
-create table t18_dependent_table(a int);
-
-create view t18_func as select a, view_func(a) as b from t18;
-create view t18_view as select a, reason as b from t18, view_view;
-create view t18_table as select * from t18;
-
-prepare stmt_func from 'select * from t18_func';
-execute stmt_func;
-eval $check;
-execute stmt_func;
-eval $check;
-
-drop function view_func;
-create function view_func(x int) returns int
- return x*x;
-
-set @expected = @expected + 1;
-execute stmt_func;
-eval $check;
-execute stmt_func;
-eval $check;
-
-prepare stmt_view from 'select * from t18_view';
-execute stmt_view;
-eval $check;
-execute stmt_view;
-eval $check;
-
-drop view view_view;
-create view view_view as select "view v2" as reason from dual;
-
-set @expected = @expected + 1;
-execute stmt_view;
-eval $check;
-execute stmt_view;
-eval $check;
-
-prepare stmt_table from 'select * from t18_table';
-execute stmt_table;
-eval $check;
-execute stmt_table;
-eval $check;
-
-alter table t18 add column comments varchar(50) default NULL;
-
-set @expected = @expected + 1;
-execute stmt_table;
-eval $check;
-execute stmt_table;
-eval $check;
-
-drop table t18;
-drop table t18_dependent_table;
-drop view t18_func;
-drop view t18_view;
-drop view t18_table;
-drop function view_func;
-drop view view_view;
-
---echo =====================================================================
---echo Testing 19: Special tables (INFORMATION_SCHEMA)
---echo =====================================================================
-
---disable_warnings
-drop procedure if exists proc_19;
---enable_warnings
+call p_verify_reprepare_count(0);
+select @message;
+
+select * from t1 order by a;
+drop table t1;
+deallocate prepare stmt;
+
+--echo =====================================================================
+--echo Part 7: TABLE -> TABLE (TRIGGER dependencies) transitions
+--echo =====================================================================
+
+--echo # Test 7-a: dependent PROCEDURE has changed
+--echo #
+--echo # Note, this scenario is not supported, subject of Bug#12093
+--echo #
+
+create table t1 (a int);
+create trigger t1_ai after insert on t1 for each row
+ call p1(new.a);
+create procedure p1(a int) begin end;
+prepare stmt from "insert into t1 (a) values (?)";
+set @var= 1;
+execute stmt using @var;
+drop procedure p1;
+create procedure p1 (a int) begin end;
+set @var= 2;
+--error ER_SP_DOES_NOT_EXIST
+execute stmt using @var;
+--echo # Cleanup
+drop procedure p1;
+call p_verify_reprepare_count(0);
+
+--echo # Test 7-b: dependent FUNCTION has changed
+--echo #
+--echo # Note, this scenario is not supported, subject of Bug#12093
+--echo #
+drop trigger t1_ai;
+create trigger t1_ai after insert on t1 for each row
+ select f1(new.a+1) into @var;
+create function f1 (a int) returns int return a;
+prepare stmt from "insert into t1(a) values (?)";
+set @var=3;
+execute stmt using @var;
+select @var;
+drop function f1;
+create function f1 (a int) returns int return 0;
+--error ER_SP_DOES_NOT_EXIST
+execute stmt using @var;
+call p_verify_reprepare_count(0);
+drop function f1;
+deallocate prepare stmt;
+
+--echo # Test 7-c: dependent VIEW has changed
+--echo #
+--echo # Note, this scenario is not functioning correctly, see
+--echo # Bug#33255 Trigger using views and view ddl : corrupted triggers
+--echo # and Bug #33000 Triggers do not detect changes in meta-data.
+--echo #
+drop trigger t1_ai;
+create table t2 (a int unique);
+create table t3 (a int unique);
+create view v1 as select a from t2;
+create trigger t1_ai after insert on t1 for each row
+ insert into v1 (a) values (new.a);
+
+--echo # Demonstrate that the same bug is present
+--echo # without prepared statements
+insert into t1 (a) values (5);
+select * from t2;
+select * from t3;
+drop view v1;
+create view v1 as select a from t3;
+--error ER_NO_SUCH_TABLE
+insert into t1 (a) values (6);
+flush table t1;
+insert into t1 (a) values (6);
+select * from t2;
+select * from t3;
+
+prepare stmt from "insert into t1 (a) values (?)";
+set @var=7;
+execute stmt using @var;
+call p_verify_reprepare_count(0);
+select * from t3;
+select * from t2;
+drop view v1;
+create view v1 as select a from t2;
+set @var=8;
+execute stmt using @var;
+call p_verify_reprepare_count(0);
+--echo #
+--echo # Sic: the insert went into t3, even though the view now
+--echo # points at t2. This is because neither the merged view
+--echo # nor its prelocking list are affected by view DDL
+--echo # The binary log is of course wrong, since it is not
+--echo # using prepared statements
+--echo #
+select * from t2;
+select * from t3;
+flush table t1;
+set @var=9;
+execute stmt using @var;
+call p_verify_reprepare_count(1);
+select * from t2;
+select * from t3;
+drop view v1;
+drop table t1,t2,t3;
+
+--echo # Test 7-d: dependent TABLE has changed
+create table t1 (a int);
+create trigger t1_ai after insert on t1 for each row
+ insert into t2 (a) values (new.a);
+create table t2 (a int);
+
+prepare stmt from "insert into t1 (a) values (?)";
+set @var=1;
+execute stmt using @var;
+alter table t2 add column comment varchar(255);
+set @var=2;
+--echo # Since the dependent table is tracked in the prelocked
+--echo # list of the prepared statement, invalidation happens
+--echo # and the statement is re-prepared. This is an unnecessary
+--echo # side effect, since the statement that *is* dependent
+--echo # on t2 definition is inside the trigger, and it is currently
+--echo # not reprepared (see the previous test case).
+execute stmt using @var;
+call p_verify_reprepare_count(1);
+select * from t1;
+select * from t2;
+drop table t1,t2;
+
+--echo # Test 7-e: dependent TABLE TRIGGER has changed
+create table t1 (a int);
+create trigger t1_ai after insert on t1 for each row
+ insert into t2 (a) values (new.a);
+create table t2 (a int unique);
+create trigger t2_ai after insert on t2 for each row
+ insert into t3 (a) values (new.a);
+create table t3 (a int unique);
+create table t4 (a int unique);
+
+insert into t1 (a) values (1);
+select * from t1 join t2 on (t1.a=t2.a) join t3 on (t2.a=t3.a);
+drop trigger t2_ai;
+create trigger t2_ai after insert on t2 for each row
+ insert into t4 (a) values (new.a);
+insert into t1 (a) values (2);
+select * from t1 join t2 on (t1.a=t2.a) join t4 on (t2.a=t4.a);
+
+prepare stmt from "insert into t1 (a) values (?)";
+set @var=3;
+execute stmt using @var;
+select * from t1 join t2 on (t1.a=t2.a) join t4 on (t2.a=t4.a);
+drop trigger t2_ai;
+create trigger t2_ai after insert on t2 for each row
+ insert into t3 (a) values (new.a);
+set @var=4;
+execute stmt using @var;
+call p_verify_reprepare_count(1);
+select * from t1 join t2 on (t1.a=t2.a) join t3 on (t2.a=t3.a);
+select * from t1 join t2 on (t1.a=t2.a) join t4 on (t2.a=t4.a);
+
+drop table t1, t2, t3, t4;
+deallocate prepare stmt;
+
+--echo =====================================================================
+--echo Part 8: TABLE -> TEMPORARY TABLE transitions
+--echo =====================================================================
+
+--echo # Test 8-a: base table used recreated as temporary table
+create table t1 (a int);
+
+prepare stmt from "select * from t1";
+execute stmt;
+
+drop table t1;
+create temporary table t1 (a int);
+
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop table t1;
+deallocate prepare stmt;
+
+--echo # Test 8-b: temporary table has precedence over base table with same name
+create table t1 (a int);
+prepare stmt from 'select count(*) from t1';
+execute stmt;
+call p_verify_reprepare_count(0);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+create temporary table t1 AS SELECT 1;
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+deallocate prepare stmt;
+drop temporary table t1;
+drop table t1;
+
+
+--echo =====================================================================
+--echo Part 9: TABLE -> VIEW transitions
+--echo =====================================================================
+
+create table t1 (a int);
+
+prepare stmt from "select * from t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop table t1;
+create table t2 (a int);
+create view t1 as select * from t2;
+
+execute stmt;
+call p_verify_reprepare_count(1);
+
+drop view t1;
+drop table t2;
+deallocate prepare stmt;
+
+--echo =====================================================================
+--echo Part 10: TEMPORARY TABLE -> NOTHING transitions
+--echo =====================================================================
+
+create temporary table t1 (a int);
+
+prepare stmt from "select * from t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop temporary table t1;
+--error ER_NO_SUCH_TABLE
+execute stmt;
+call p_verify_reprepare_count(0);
+deallocate prepare stmt;
+
+--echo =====================================================================
+--echo Part 11: TEMPORARY TABLE -> TABLE transitions
+--echo =====================================================================
+
+--echo # Test 11-a: temporary table replaced by base table
+create table t1 (a int);
+insert into t1 (a) value (1);
+create temporary table t1 (a int);
+
+prepare stmt from "select * from t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop temporary table t1;
+
+execute stmt;
+call p_verify_reprepare_count(1);
+
+select * from t1;
+drop table t1;
+deallocate prepare stmt;
+
+
+--echo # Test 11-b: temporary table has precedence over base table with same name
+--echo # temporary table disappears
+create table t1 (a int);
+create temporary table t1 as select 1 as a;
+prepare stmt from "select count(*) from t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop temporary table t1;
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+deallocate prepare stmt;
+drop table t1;
+
+
+--echo =====================================================================
+--echo Part 12: TEMPORARY TABLE -> TEMPORARY TABLE (DDL) transitions
+--echo =====================================================================
+
+create temporary table t1 (a int);
+
+prepare stmt from "select a from t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop temporary table t1;
+create temporary table t1 (a int, b int);
+
+execute stmt;
+call p_verify_reprepare_count(1);
+
+select * from t1;
+drop temporary table t1;
+deallocate prepare stmt;
+
+--echo =====================================================================
+--echo Part 13: TEMPORARY TABLE -> VIEW transitions
+--echo =====================================================================
+
+create temporary table t1 (a int);
+create table t2 (a int);
+
+prepare stmt from "select * from t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop temporary table t1;
+create view t1 as select * from t2;
+
+execute stmt;
+call p_verify_reprepare_count(1);
+
+drop view t1;
+drop table t2;
+deallocate prepare stmt;
+
+--echo =====================================================================
+--echo Part 14: VIEW -> NOTHING transitions
+--echo =====================================================================
+
+create table t2 (a int);
+create view t1 as select * from t2;
+
+prepare stmt from "select * from t1";
+execute stmt;
+drop view t1;
+
+--error ER_NO_SUCH_TABLE
+execute stmt;
+call p_verify_reprepare_count(0);
+--error ER_NO_SUCH_TABLE
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop table t2;
+deallocate prepare stmt;
+
+--echo =====================================================================
+--echo Part 15: VIEW -> TABLE transitions
+--echo =====================================================================
+
+create table t2 (a int);
+create view t1 as select * from t2;
+
+prepare stmt from "select * from t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop view t1;
+create table t1 (a int);
+
+execute stmt;
+call p_verify_reprepare_count(1);
+
+drop table t2;
+drop table t1;
+deallocate prepare stmt;
+
+--echo =====================================================================
+--echo Part 16: VIEW -> TEMPORARY TABLE transitions
+--echo =====================================================================
+
+create table t2 (a int);
+insert into t2 (a) values (1);
+create view t1 as select * from t2;
+
+prepare stmt from "select * from t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+
+create temporary table t1 (a int);
+execute stmt;
+call p_verify_reprepare_count(1);
+drop view t1;
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop table t2;
+drop temporary table t1;
+deallocate prepare stmt;
+
+--echo =====================================================================
+--echo Part 17: VIEW -> VIEW (DDL) transitions
+--echo =====================================================================
+
+create table t2 (a int);
+insert into t2 values (10), (20), (30);
+
+create view t1 as select a, 2*a as b, 3*a as c from t2;
+select * from t1;
+
+prepare stmt from "select * from t1";
+execute stmt;
+
+drop view t1;
+create view t1 as select a, 2*a as b, 5*a as c from t2;
+select * from t1;
+
+--echo # Currently a different result from conventional statements.
+--echo # A view is inlined once at prepare, later on view DDL
+--echo # does not affect prepared statement and it is not re-prepared.
+--echo # This is reported in Bug#36002 Prepared statements: if a view
+--echo # used in a statement is replaced, bad data
+execute stmt;
+call p_verify_reprepare_count(0);
+flush table t2;
+execute stmt;
+call p_verify_reprepare_count(1);
+
+drop table t2;
+drop view t1;
+deallocate prepare stmt;
+
+--echo =====================================================================
+--echo Part 18: VIEW -> VIEW (VIEW dependencies) transitions
+--echo =====================================================================
+
+--echo # Part 18a: dependent function has changed
+create table t1 (a int);
+insert into t1 (a) values (1), (2), (3);
+create function f1() returns int return (select max(a) from t1);
+create view v1 as select f1();
+prepare stmt from "select * from v1";
+execute stmt;
+execute stmt;
+call p_verify_reprepare_count(0);
+drop function f1;
+create function f1() returns int return 2;
+--echo # XXX: Bug#12093. We only get a different error
+--echo # message because the non-existing procedure error is masked
+--echo # by the view.
+--error ER_VIEW_INVALID
+execute stmt;
+--error ER_VIEW_INVALID
+execute stmt;
+call p_verify_reprepare_count(0);
+
+--echo # Part 18b: dependent procedure has changed (referred to via a function)
+
+create table t2 (a int);
+insert into t2 (a) values (4), (5), (6);
+
+drop function f1;
+delimiter |;
+create function f1() returns int
+begin
+ declare x int;
+ call p1(x);
+ return x;
+end|
+delimiter ;|
+create procedure p1(out x int) select max(a) from t1 into x;
+
+prepare stmt from "select * from v1";
+execute stmt;
+execute stmt;
+call p_verify_reprepare_count(0);
+drop procedure p1;
+create procedure p1(out x int) select max(a) from t2 into x;
+--echo # XXX: bug. The prelocked list is not invalidated
+--echo # and we keep opening table t1, whereas the procedure
+--echo # is now referring to table t2
+--error ER_VIEW_INVALID
+execute stmt;
+call p_verify_reprepare_count(0);
+flush table t1;
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+
+--echo # Test 18-c: dependent VIEW has changed
+
+drop view v1;
+create view v2 as select a from t1;
+create view v1 as select * from v2;
+prepare stmt from "select * from v1";
+execute stmt;
+execute stmt;
+call p_verify_reprepare_count(0);
+drop view v2;
+create view v2 as select a from t2;
+execute stmt;
+execute stmt;
+call p_verify_reprepare_count(0);
+flush table t1;
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+--echo # Test 18-d: dependent TABLE has changed
+drop view v2;
+create table v2 as select * from t1;
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+drop table v2;
+create table v2 (a int unique) as select * from t2;
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+--echo # Test 18-e: dependent TABLE trigger has changed
+
+prepare stmt from "insert into v1 (a) values (?)";
+set @var= 7;
+execute stmt using @var;
+call p_verify_reprepare_count(0);
+create trigger v2_bi before insert on v2 for each row set @message="v2_bi";
+set @var=8;
+execute stmt using @var;
+call p_verify_reprepare_count(1);
+select @message;
+drop trigger v2_bi;
+set @message=null;
+set @var=9;
+execute stmt using @var;
+call p_verify_reprepare_count(1);
+select @message;
+create trigger v2_bi after insert on v2 for each row set @message="v2_ai";
+set @var= 10;
+execute stmt using @var;
+call p_verify_reprepare_count(1);
+select @message;
+select * from v1;
+
+--echo # Cleanup
+
+--disable_warnings
+drop table if exists t1, t2, v1, v2;
+drop view if exists v1, v2;
+drop function f1;
+drop procedure p1;
+--enable_warnings
+deallocate prepare stmt;
+
+--echo =====================================================================
+--echo Part 19: Special tables (INFORMATION_SCHEMA)
+--echo =====================================================================
# Using a temporary table internally should not confuse the prepared
# statement code, and should not raise ER_PS_INVALIDATED errors
prepare stmt from
- 'select ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE
+ "select ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE
from INFORMATION_SCHEMA.ROUTINES where
- routine_name=\'proc_19\'';
-
-create procedure proc_19() select "hi there";
-
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop procedure proc_19;
-create procedure proc_19() select "hi there, again";
-
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop procedure proc_19;
-
---echo =====================================================================
---echo Testing 20: Special tables (log tables)
---echo =====================================================================
-
-prepare stmt from
- 'select * from mysql.general_log where argument=\'IMPOSSIBLE QUERY STRING\'';
-
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
---echo =====================================================================
---echo Testing 21: Special tables (system tables)
---echo =====================================================================
-
---disable_warnings
-drop procedure if exists proc_21;
---enable_warnings
-
-prepare stmt from
- 'select type, db, name from mysql.proc where name=\'proc_21\'';
-
-create procedure proc_21() select "hi there";
-
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop procedure proc_21;
-create procedure proc_21() select "hi there, again";
-
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop procedure proc_21;
-
---echo =====================================================================
---echo Testing 22: Special tables (views temp tables)
---echo =====================================================================
-
---disable_warnings
-drop table if exists t22_b;
-drop view if exists t22;
---enable_warnings
-
-create table t22_b(a int);
-
-create algorithm=temptable view t22 as select a*a as a2 from t22_b;
-
-# Using a temporary table internally should not confuse the prepared
-# statement code, and should not raise ER_PS_INVALIDATED errors
-show create view t22;
-
-prepare stmt from 'select * from t22';
-
-insert into t22_b values (1), (2), (3);
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-insert into t22_b values (4), (5), (6);
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop table t22_b;
-drop view t22;
-
---echo =====================================================================
---echo Testing 23: Special tables (internal join tables)
---echo =====================================================================
-
---disable_warnings
-drop table if exists t23_a;
-drop table if exists t23_b;
---enable_warnings
-
-create table t23_a(a int);
-create table t23_b(b int);
-
-# Using a temporary table internally should not confuse the prepared
-# statement code, and should not raise ER_PS_INVALIDATED errors
-prepare stmt from 'select * from t23_a join t23_b';
-
-insert into t23_a values (1), (2), (3);
-insert into t23_b values (10), (20), (30);
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-insert into t23_a values (4);
-insert into t23_b values (40);
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop table t23_a;
-drop table t23_b;
-
---echo =====================================================================
---echo Testing 24: Special statements
---echo =====================================================================
-
-# SQLCOM_ALTER_TABLE:
-
---disable_warnings
-drop table if exists t24_alter;
---enable_warnings
-
-create table t24_alter(a int);
-
-prepare stmt from 'alter table t24_alter add column b int';
-execute stmt;
-eval $check;
-
-drop table t24_alter;
-create table t24_alter(a1 int, a2 int);
-
-# t24_alter has changed, and it's not a problem
-execute stmt;
-eval $check;
-
-alter table t24_alter drop column b;
-execute stmt;
-eval $check;
-
-alter table t24_alter drop column b;
-execute stmt;
-eval $check;
-
-drop table t24_alter;
-
-# SQLCOM_REPAIR:
-
---disable_warnings
-drop table if exists t24_repair;
---enable_warnings
-
-create table t24_repair(a int);
-insert into t24_repair values (1), (2), (3);
-
-prepare stmt from 'repair table t24_repair';
-execute stmt;
-eval $check;
-
-drop table t24_repair;
-create table t24_repair(a1 int, a2 int);
-insert into t24_repair values (1, 10), (2, 20), (3, 30);
-
-# t24_repair has changed, and it's not a problem
-execute stmt;
-eval $check;
-
-alter table t24_repair add column b varchar(50) default NULL;
-execute stmt;
-eval $check;
-
-alter table t24_repair drop column b;
-execute stmt;
-eval $check;
-
-drop table t24_repair;
-
-# SQLCOM_ANALYZE:
-
---disable_warnings
-drop table if exists t24_analyze;
---enable_warnings
-
-create table t24_analyze(a int);
-insert into t24_analyze values (1), (2), (3);
-
-prepare stmt from 'analyze table t24_analyze';
-execute stmt;
-eval $check;
-
-drop table t24_analyze;
-create table t24_analyze(a1 int, a2 int);
-insert into t24_analyze values (1, 10), (2, 20), (3, 30);
-
-# t24_analyze has changed, and it's not a problem
-execute stmt;
-eval $check;
-
-alter table t24_analyze add column b varchar(50) default NULL;
-execute stmt;
-eval $check;
-
-alter table t24_analyze drop column b;
-execute stmt;
-eval $check;
-
-drop table t24_analyze;
-
-# SQLCOM_OPTIMIZE:
-
---disable_warnings
-drop table if exists t24_optimize;
---enable_warnings
-
-create table t24_optimize(a int);
-insert into t24_optimize values (1), (2), (3);
-
-prepare stmt from 'optimize table t24_optimize';
-execute stmt;
-eval $check;
-
-drop table t24_optimize;
-create table t24_optimize(a1 int, a2 int);
-insert into t24_optimize values (1, 10), (2, 20), (3, 30);
-
-# t24_optimize has changed, and it's not a problem
-execute stmt;
-eval $check;
-
-alter table t24_optimize add column b varchar(50) default NULL;
-execute stmt;
-eval $check;
-
-alter table t24_optimize drop column b;
-execute stmt;
-eval $check;
-
-drop table t24_optimize;
-
-# SQLCOM_SHOW_CREATE_PROC:
-
---disable_warnings
-drop procedure if exists changing_proc;
---enable_warnings
-
-prepare stmt from 'show create procedure changing_proc';
---error ER_SP_DOES_NOT_EXIST
-execute stmt;
-eval $check;
---error ER_SP_DOES_NOT_EXIST
-execute stmt;
-eval $check;
-
-create procedure changing_proc() begin end;
-
-# changing_proc has changed, and it's not a problem
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop procedure changing_proc;
-create procedure changing_proc(x int, y int) begin end;
-
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop procedure changing_proc;
-
---error ER_SP_DOES_NOT_EXIST
-execute stmt;
-eval $check;
---error ER_SP_DOES_NOT_EXIST
-execute stmt;
-eval $check;
-
-# SQLCOM_SHOW_CREATE_FUNC:
-
---disable_warnings
-drop function if exists changing_func;
---enable_warnings
-
-prepare stmt from 'show create function changing_func';
---error ER_SP_DOES_NOT_EXIST
-execute stmt;
-eval $check;
---error ER_SP_DOES_NOT_EXIST
-execute stmt;
-eval $check;
-
-create function changing_func() returns int return 0;
-
-# changing_proc has changed, and it's not a problem
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop function changing_func;
-create function changing_func(x int, y int) returns int return x+y;
-
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop function changing_func;
-
---error ER_SP_DOES_NOT_EXIST
-execute stmt;
-eval $check;
---error ER_SP_DOES_NOT_EXIST
-execute stmt;
-eval $check;
-
-# SQLCOM_SHOW_CREATE_TRIGGER:
-
---disable_warnings
-drop table if exists t24_trigger;
---enable_warnings
-
-create table t24_trigger(a int);
-
-prepare stmt from 'show create trigger t24_bi;';
---error ER_TRG_DOES_NOT_EXIST
-execute stmt;
-eval $check;
---error ER_TRG_DOES_NOT_EXIST
-execute stmt;
-eval $check;
-
-delimiter $$;
-create trigger t24_bi before insert on t24_trigger for each row
- begin
- set @message= "t24_bi";
- end
-$$
-delimiter ;$$
-
-# t24_bi has changed, and it's not a problem
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop trigger t24_bi;
-delimiter $$;
-create trigger t24_bi before insert on t24_trigger for each row
- begin
- set @message= "t24_bi (2)";
- end
-$$
-delimiter ;$$
-
-# t24_bi has changed, and it's not a problem
-set @expected = @expected + 1;
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop trigger t24_bi;
-
---error ER_TRG_DOES_NOT_EXIST
-execute stmt;
-eval $check;
---error ER_TRG_DOES_NOT_EXIST
-execute stmt;
-eval $check;
-
-drop table t24_trigger;
-
---echo =====================================================================
---echo Testing 25: Testing the strength of TABLE_SHARE version
---echo =====================================================================
-
-# Test 25-a: number of columns
-
---disable_warnings
-drop table if exists t25_num_col;
---enable_warnings
-
-create table t25_num_col(a int);
-
-prepare stmt from 'select a from t25_num_col';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-alter table t25_num_col add column b varchar(50) default NULL;
-
-set @expected = @expected + 1;
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop table t25_num_col;
-
-# Test 25-b: column name
-
---disable_warnings
-drop table if exists t25_col_name;
---enable_warnings
-
-create table t25_col_name(a int);
-
-prepare stmt from 'select * from t25_col_name';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-alter table t25_col_name change a b int;
-
-set @expected = @expected + 1;
---error ER_PS_REBIND
-execute stmt;
-eval $check;
-set @expected = @expected + 1;
---error ER_PS_REBIND
-execute stmt;
-eval $check;
-
-drop table t25_col_name;
-
-# Test 25-c: column type
-
---disable_warnings
-drop table if exists t25_col_type;
---enable_warnings
-
-create table t25_col_type(a int);
-
-prepare stmt from 'select * from t25_col_type';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-alter table t25_col_type change a a varchar(10);
-
-set @expected = @expected + 1;
---error ER_PS_REBIND
-execute stmt;
-eval $check;
-set @expected = @expected + 1;
---error ER_PS_REBIND
-execute stmt;
-eval $check;
-
-drop table t25_col_type;
-
-# Test 25-d: column type length
-
---disable_warnings
-drop table if exists t25_col_type_length;
---enable_warnings
-
-create table t25_col_type_length(a varchar(10));
-
-prepare stmt from 'select * from t25_col_type_length';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-alter table t25_col_type_length change a a varchar(20);
-
-set @expected = @expected + 1;
---error ER_PS_REBIND
-execute stmt;
-eval $check;
-set @expected = @expected + 1;
---error ER_PS_REBIND
-execute stmt;
-eval $check;
-
-drop table t25_col_type_length;
-
-# Test 25-e: column NULL property
-
---disable_warnings
-drop table if exists t25_col_null;
---enable_warnings
-
-create table t25_col_null(a varchar(10));
-
-prepare stmt from 'select * from t25_col_null';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-alter table t25_col_null change a a varchar(10) NOT NULL;
-
-set @expected = @expected + 1;
---error ER_PS_REBIND
-execute stmt;
-eval $check;
-set @expected = @expected + 1;
---error ER_PS_REBIND
-execute stmt;
-eval $check;
-
-drop table t25_col_null;
-
-# Test 25-f: column DEFAULT
-
---disable_warnings
-drop table if exists t25_col_default;
---enable_warnings
-
-create table t25_col_default(a int, b int DEFAULT 10);
-
-prepare stmt from 'insert into t25_col_default(a) values (?)';
-set @val=1;
-execute stmt using @val;
-eval $check;
-set @val=2;
-execute stmt using @val;
-eval $check;
-
-alter table t25_col_default change b b int DEFAULT 20;
-
-set @val=3;
-# Must insert the correct default value for b
-set @expected = @expected + 1;
-execute stmt using @val;
-eval $check;
-
-set @val=4;
-# Must insert the correct default value for b
-execute stmt using @val;
-eval $check;
-
-select * from t25_col_default;
-
-drop table t25_col_default;
-
-# Test 25-g: number of keys
-
---disable_warnings
-drop table if exists t25_index;
---enable_warnings
-
-create table t25_index(a varchar(10));
-
-prepare stmt from 'select * from t25_index';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-create index i1 on t25_index(a);
-
-set @expected = @expected + 1;
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop table t25_index;
-
-# Test 25-h: changing index uniqueness
-
---disable_warnings
-drop table if exists t25_index_unique;
---enable_warnings
-
-create table t25_index_unique(a varchar(10), b varchar(10));
-create index i1 on t25_index_unique(a, b);
-
-show create table t25_index_unique;
-
-prepare stmt from 'select * from t25_index_unique';
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-alter table t25_index_unique drop index i1;
-create unique index i1 on t25_index_unique(a, b);
-
-show create table t25_index_unique;
-
-set @expected = @expected + 1;
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
-
-drop table t25_index_unique;
+ routine_name='p1'";
+
+create procedure p1() select "hi there";
+
+execute stmt;
+execute stmt;
+
+drop procedure p1;
+create procedure p1() select "hi there, again";
+
+execute stmt;
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop procedure p1;
+deallocate prepare stmt;
+
+--echo =====================================================================
+--echo Part 20: Special tables (log tables)
+--echo =====================================================================
+
+prepare stmt from
+ "select * from mysql.general_log where argument='IMPOSSIBLE QUERY STRING'";
+
+--disable_result_log
+execute stmt;
+execute stmt;
+execute stmt;
+execute stmt;
+--enable_result_log
+call p_verify_reprepare_count(0);
+deallocate prepare stmt;
+
+--echo =====================================================================
+--echo Part 21: Special tables (system tables)
+--echo =====================================================================
+
+prepare stmt from
+ "select type, db, name from mysql.proc where name='p1'";
+
+create procedure p1() select "hi there";
+
+execute stmt;
+execute stmt;
+
+drop procedure p1;
+create procedure p1() select "hi there, again";
+
+execute stmt;
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop procedure p1;
+deallocate prepare stmt;
+
+--echo =====================================================================
+--echo Part 22: Special tables (views temp tables)
+--echo =====================================================================
+
+create table t1 (a int);
+
+create algorithm=temptable view v1 as select a*a as a2 from t1;
+
+--echo # Using a temporary table internally should not confuse the prepared
+--echo # statement code, and should not raise ER_PS_INVALIDATED errors
+show create view v1;
+
+prepare stmt from "select * from v1";
+
+insert into t1 values (1), (2), (3);
+execute stmt;
+execute stmt;
+
+insert into t1 values (4), (5), (6);
+execute stmt;
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop table t1;
+drop view v1;
+
+--echo =====================================================================
+--echo Part 23: Special statements
+--echo =====================================================================
+
+--echo # SQLCOM_ALTER_TABLE:
+
+
+create table t1 (a int);
+
+prepare stmt from "alter table t1 add column b int";
+execute stmt;
+
+drop table t1;
+create table t1 (a1 int, a2 int);
+
+--echo # t1 has changed, and it's does not lead to reprepare
+execute stmt;
+
+alter table t1 drop column b;
+execute stmt;
+
+alter table t1 drop column b;
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop table t1;
+
+--echo # SQLCOM_REPAIR:
+
+create table t1 (a int);
+
+insert into t1 values (1), (2), (3);
+
+prepare stmt from "repair table t1";
+
+execute stmt;
+execute stmt;
+
+drop table t1;
+create table t1 (a1 int, a2 int);
+insert into t1 values (1, 10), (2, 20), (3, 30);
+
+--echo # t1 has changed, and it's does not lead to reprepare
+execute stmt;
+
+alter table t1 add column b varchar(50) default NULL;
+execute stmt;
+call p_verify_reprepare_count(0);
+
+alter table t1 drop column b;
+execute stmt;
+call p_verify_reprepare_count(0);
+
+--echo # SQLCOM_ANALYZE:
+
+prepare stmt from "analyze table t1";
+execute stmt;
+
+drop table t1;
+create table t1 (a1 int, a2 int);
+insert into t1 values (1, 10), (2, 20), (3, 30);
+--echo # t1 has changed, and it's not a problem
+execute stmt;
+
+alter table t1 add column b varchar(50) default NULL;
+execute stmt;
+
+alter table t1 drop column b;
+execute stmt;
+
+call p_verify_reprepare_count(0);
+
+--echo # SQLCOM_OPTIMIZE:
+
+prepare stmt from "optimize table t1";
+execute stmt;
+
+drop table t1;
+create table t1 (a1 int, a2 int);
+insert into t1 values (1, 10), (2, 20), (3, 30);
+
+--echo # t1 has changed, and it's not a problem
+execute stmt;
+
+alter table t1 add column b varchar(50) default NULL;
+execute stmt;
+
+alter table t1 drop column b;
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop table t1;
+
+--echo # SQLCOM_SHOW_CREATE_PROC:
+
+prepare stmt from "show create procedure p1";
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+
+create procedure p1() begin end;
+
+--disable_result_log
+execute stmt;
+execute stmt;
+--enable_result_log
+
+drop procedure p1;
+create procedure p1(x int, y int) begin end;
+
+--disable_result_log
+execute stmt;
+execute stmt;
+--enable_result_log
+
+drop procedure p1;
+
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+call p_verify_reprepare_count(0);
+
+--echo # SQLCOM_SHOW_CREATE_FUNC:
+
+prepare stmt from "show create function f1";
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+
+create function f1() returns int return 0;
+
+--disable_result_log
+execute stmt;
+execute stmt;
+--enable_result_log
+
+drop function f1;
+create function f1(x int, y int) returns int return x+y;
+
+--disable_result_log
+execute stmt;
+execute stmt;
+--enable_result_log
+
+drop function f1;
+
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+call p_verify_reprepare_count(0);
+
+--echo # SQLCOM_SHOW_CREATE_TRIGGER:
+
+create table t1 (a int);
+
+prepare stmt from "show create trigger t1_bi";
+--error ER_TRG_DOES_NOT_EXIST
+execute stmt;
+--error ER_TRG_DOES_NOT_EXIST
+execute stmt;
+
+create trigger t1_bi before insert on t1 for each row set @message= "t1_bi";
+
+--disable_result_log
+execute stmt;
+execute stmt;
+--enable_result_log
+
+drop trigger t1_bi;
+
+create trigger t1_bi before insert on t1 for each row set @message= "t1_bi (2)";
+
+--disable_result_log
+execute stmt;
+execute stmt;
+--enable_result_log
+
+drop trigger t1_bi;
+
+--error ER_TRG_DOES_NOT_EXIST
+execute stmt;
+--error ER_TRG_DOES_NOT_EXIST
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop table t1;
+deallocate prepare stmt;
+
+--echo =====================================================================
+--echo Part 24: Testing the strength of TABLE_SHARE version
+--echo =====================================================================
+
+--echo # Test 24-a: number of columns
+
+create table t1 (a int);
+
+prepare stmt from "select a from t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+
+alter table t1 add column b varchar(50) default NULL;
+
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+--echo # Test 24-b: column name
+
+alter table t1 change b c int;
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+--echo # Test 24-c: column type
+
+alter table t1 change a a varchar(10);
+
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+--echo # Test 24-d: column type length
+
+alter table t1 change a a varchar(20);
+
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+--echo # Test 24-e: column NULL property
+
+alter table t1 change a a varchar(20) NOT NULL;
+
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+--echo # Test 24-f: column DEFAULT
+
+alter table t1 change c c int DEFAULT 20;
+
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+--echo # Test 24-g: number of keys
+create unique index t1_a_idx on t1 (a);
+
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+--echo # Test 24-h: changing index uniqueness
+
+drop index t1_a_idx on t1;
+create index t1_a_idx on t1 (a);
+
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+--echo # Cleanup
+drop table t1;
+
+deallocate prepare stmt;
--echo =====================================================================
--echo Testing reported bugs
--echo =====================================================================
-#
-# Bug#12093 (SP not found on second PS execution if another thread drops
-# other SP in between)
-#
-
---disable_warnings
-drop table if exists table_12093;
-drop function if exists func_12093;
-drop function if exists func_12093_unrelated;
-drop procedure if exists proc_12093;
---enable_warnings
-
-connect (con1,localhost,root,,);
-
-connection default;
-
-create table table_12093(a int);
-
-delimiter //;
-
-create function func_12093()
-returns int
-begin
- return (select count(*) from table_12093);
-end//
-
-create procedure proc_12093(a int)
-begin
- select * from table_12093;
-end//
-
-delimiter ;//
-
-create function func_12093_unrelated() returns int return 2;
-create procedure proc_12093_unrelated() begin end;
-
-prepare stmt_sf from 'select func_12093();';
-prepare stmt_sp from 'call proc_12093(func_12093())';
-
-execute stmt_sf;
-eval $check;
-execute stmt_sp;
-eval $check;
-
-connection con1;
-
-drop function func_12093_unrelated;
-drop procedure proc_12093_unrelated;
-
-connection default;
-
-# previously, failed with --error 1305
-execute stmt_sf;
-eval $check;
-# previously, failed with --error 1305
-execute stmt_sp;
-eval $check;
-
-# previously, failed with --error 1305
-execute stmt_sf;
-eval $check;
-# previously, failed with --error 1305
-execute stmt_sp;
-eval $check;
-
-deallocate prepare stmt_sf;
-deallocate prepare stmt_sp;
-
-disconnect con1;
-
-drop table table_12093;
-drop function func_12093;
-drop procedure proc_12093;
-
-#
-# Bug#21294 (executing a prepared statement that executes a stored function
-# which was recreat)
-#
-
---disable_warnings
-drop function if exists func_21294;
---enable_warnings
-
-create function func_21294() returns int return 10;
-
-prepare stmt from "select func_21294()";
-execute stmt;
-eval $check;
-
-drop function func_21294;
-create function func_21294() returns int return 10;
-
-# might pass or fail, implementation dependent
-execute stmt;
-eval $check;
-
-drop function func_21294;
-create function func_21294() returns int return 20;
-
-set @expected = @expected + 1;
-execute stmt;
-eval $check;
-
-deallocate prepare stmt;
-drop function func_21294;
-
-#
-# Bug#27420 (A combination of PS and view operations cause error + assertion
-# on shutdown)
-#
+--echo #
+--echo # Bug#27420 A combination of PS and view operations cause
+--echo # error + assertion on shutdown
+--echo #
--disable_warnings
drop table if exists t_27420_100;
@@ -1677,10 +1194,6 @@
drop view if exists v_27420;
--enable_warnings
-connect (con1,localhost,root,,);
-
-connection default;
-
create table t_27420_100(a int);
insert into t_27420_100 values (1), (2);
@@ -1691,46 +1204,33 @@
from t_27420_100, t_27420_101
where t_27420_100.a=t_27420_101.a;
-prepare stmt from 'select * from v_27420';
+prepare stmt from "select * from v_27420";
execute stmt;
-eval $check;
-
-connection con1;
+call p_verify_reprepare_count(0);
drop view v_27420;
create table v_27420(X int, Y int);
-connection default;
-
-set @expected = @expected + 1;
execute stmt;
-eval $check;
-
-connection con1;
+call p_verify_reprepare_count(1);
drop table v_27420;
# passes in 5.0, fails in 5.1, should pass
create table v_27420 (a int, b int, filler char(200));
-connection default;
-
-set @expected = @expected + 1;
---error ER_PS_REBIND
execute stmt;
-eval $check;
-
-disconnect con1;
-
-deallocate prepare stmt;
+call p_verify_reprepare_count(1);
+
drop table t_27420_100;
drop table t_27420_101;
drop table v_27420;
+deallocate prepare stmt;
-#
-# Bug#27430 (Crash in subquery code when in PS and table DDL changed after
-# PREPARE)
-#
+--echo #
+--echo # Bug#27430 Crash in subquery code when in PS and table DDL changed
+--echo # after PREPARE
+--echo #
--disable_warnings
drop table if exists t_27430_1;
@@ -1752,18 +1252,16 @@
(1234, 3),
(1234, 4);
-prepare stmt from
- 'select oref, a, a in (select a from t_27430_1 where oref=t_27430_2.oref) Z from
t_27430_2';
+prepare stmt from
+ "select oref, a, a in (select a from t_27430_1 where oref=t_27430_2.oref) Z from
t_27430_2";
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
+execute stmt;
+call p_verify_reprepare_count(0);
drop table t_27430_1, t_27430_2;
create table t_27430_1 (a int, oref int, key(a));
-insert into t_27430_1 values
+insert into t_27430_1 values
(1, 1),
(1, NULL),
(2, 3),
@@ -1777,23 +1275,17 @@
(NULL, 3),
(NULL, 4);
-set @expected = @expected + 1;
---error ER_PS_REBIND
-execute stmt;
-eval $check;
-set @expected = @expected + 1;
---error ER_PS_REBIND
-execute stmt;
-eval $check;
+execute stmt;
+call p_verify_reprepare_count(1);
-deallocate prepare stmt;
drop table t_27430_1;
drop table t_27430_2;
+deallocate prepare stmt;
-#
-# Bug#27690 (Re-execution of prepared statement after table was replaced
-# with a view crashes)
-#
+--echo #
+--echo # Bug#27690 Re-execution of prepared statement after table
+--echo # was replaced with a view crashes
+--echo #
--disable_warnings
drop table if exists t_27690_1;
@@ -1807,33 +1299,764 @@
create table v_27690_1 as select * from t_27690_1;
create table v_27690_2 as select * from t_27690_1;
-prepare stmt from 'select * from v_27690_1, v_27690_2';
+prepare stmt from "select * from v_27690_1, v_27690_2";
execute stmt;
-eval $check;
execute stmt;
-eval $check;
drop table v_27690_1;
--error ER_NO_SUCH_TABLE
execute stmt;
-eval $check;
--error ER_NO_SUCH_TABLE
execute stmt;
-eval $check;
+call p_verify_reprepare_count(0);
create view v_27690_1 as select A.a, A.b from t_27690_1 A, t_27690_1 B;
-set @expected = @expected + 1;
-execute stmt;
-eval $check;
-execute stmt;
-eval $check;
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
-deallocate prepare stmt;
drop table t_27690_1;
drop view v_27690_1;
drop table v_27690_2;
-
+deallocate prepare stmt;
+
+--echo #=====================================================================
+--echo # TODO: fix the below two bugs and modify their tests
+--echo #
+--echo # Bug#21294 Executing a prepared statement that executes
+--echo # a stored function which was recreat
+--echo #
+
+create function f1() returns int return 10;
+
+prepare stmt from "select f1()";
+execute stmt;
+
+drop function f1;
+create function f1() returns int return 10;
+
+# might pass or fail, implementation dependent
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+
+drop function f1;
+create function f1() returns int return 20;
+
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop function f1;
+deallocate prepare stmt;
+
+--echo #
+--echo # Bug#12093 SP not found on second PS execution if another thread drops
+--echo # other SP in between
+--echo #
+--disable_warnings
+drop table if exists t_12093;
+drop function if exists f_12093;
+drop function if exists f_12093_unrelated;
+drop procedure if exists p_12093;
+--enable_warnings
+
+create table t_12093 (a int);
+
+create function f_12093() returns int return (select count(*) from t_12093);
+
+create procedure p_12093(a int) select * from t_12093;
+
+create function f_12093_unrelated() returns int return 2;
+create procedure p_12093_unrelated() begin end;
+
+prepare stmt_sf from 'select f_12093();';
+prepare stmt_sp from 'call p_12093(f_12093())';
+
+execute stmt_sf;
+execute stmt_sp;
+
+connect (con1,localhost,root,,);
+connection con1;
+
+drop function f_12093_unrelated;
+drop procedure p_12093_unrelated;
+
+connection default;
+
+--echo # XXX: bug
+--error ER_SP_DOES_NOT_EXIST
+execute stmt_sf;
+--echo # XXX: bug
+--error ER_SP_DOES_NOT_EXIST
+execute stmt_sp;
+
+--echo # XXX: bug
+--error ER_SP_DOES_NOT_EXIST
+execute stmt_sf;
+--echo # XXX: bug
+--error ER_SP_DOES_NOT_EXIST
+execute stmt_sp;
+call p_verify_reprepare_count(0);
+
+disconnect con1;
+
+drop table t_12093;
+drop function f_12093;
+drop procedure p_12093;
+deallocate prepare stmt_sf;
+deallocate prepare stmt_sp;
+
+
+--echo =====================================================================
+--echo Ensure that metadata validation is performed for every type of
+--echo SQL statement where it is needed.
+--echo =====================================================================
+
+--echo #
+--echo # SQLCOM_SELECT
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "select 1 as res from dual where (1) in (select * from t1)";
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+call p_verify_reprepare_count(1);
+
+--echo #
+--echo # SQLCOM_CREATE_TABLE
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+drop table if exists t2;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from 'create table t2 as select * from t1';
+execute stmt;
+drop table t2;
+execute stmt;
+drop table t2;
+execute stmt;
+call p_verify_reprepare_count(0);
+# Base table with name of table to be created exists
+--error ER_TABLE_EXISTS_ERROR
+execute stmt;
+call p_verify_reprepare_count(1);
+--error ER_TABLE_EXISTS_ERROR
+execute stmt;
+call p_verify_reprepare_count(0);
+drop table t2;
+# Temporary table with name of table to be created exists
+create temporary table t2 (a int);
+--error ER_TABLE_EXISTS_ERROR
+execute stmt;
+call p_verify_reprepare_count(1);
+--error ER_TABLE_EXISTS_ERROR
+execute stmt;
+call p_verify_reprepare_count(0);
+drop temporary table t2;
+execute stmt;
+call p_verify_reprepare_count(1);
+drop table t2;
+execute stmt;
+call p_verify_reprepare_count(0);
+drop table t2;
+# View with name of table to be created exists
+# Attention:
+# We cannot print the error message because it contains a random filename.
+# Example: 1050: Table '<some_path>/var/tmp/#sql_6979_0' already exists
+# Therefore we mangle it via
+# "--error ER_TABLE_EXISTS_ERROR,9999" (9999 is currently not used)
+# to "Got one of the listed errors".
+create view t2 as select 1;
+--error ER_TABLE_EXISTS_ERROR,9999
+execute stmt;
+call p_verify_reprepare_count(1);
+--error ER_TABLE_EXISTS_ERROR,9999
+execute stmt;
+call p_verify_reprepare_count(0);
+drop view t2;
+drop table t1;
+# Table to be used recreated (drop,create) with different layout
+create table t1 (x varchar(20));
+execute stmt;
+call p_verify_reprepare_count(1);
+select * from t2;
+drop table t2;
+execute stmt;
+call p_verify_reprepare_count(0);
+drop table t2;
+# Table to be used has a modified (alter table) layout
+alter table t1 add column y decimal(10,3);
+execute stmt;
+call p_verify_reprepare_count(1);
+select * from t2;
+drop table t2;
+execute stmt;
+call p_verify_reprepare_count(0);
+drop table t1;
+deallocate prepare stmt;
+--echo # XXX: no validation of the first table in case of
+--echo # CREATE TEMPORARY TABLE. This is a shortcoming of the current code,
+--echo # but since validation is not strictly necessary, nothing is done
+--echo # about it.
+--echo # Will be fixed as part of work on Bug#21431 "Incomplete support of
+--echo # temporary tables"
+create table t1 (a int);
+insert into t1 (a) values (1);
+prepare stmt from "create temporary table if not exists t2 as select * from t1";
+execute stmt;
+drop table t2;
+execute stmt;
+execute stmt;
+select * from t2;
+execute stmt;
+select * from t2;
+drop table t2;
+create temporary table t2 (a varchar(10));
+execute stmt;
+select * from t2;
+call p_verify_reprepare_count(0);
+drop table t1;
+create table t1 (x int);
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+drop table t1;
+drop temporary table t2;
+drop table t2;
+deallocate prepare stmt;
+
+create table t1 (a int);
+prepare stmt from "create table t2 like t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+drop table t2;
+execute stmt;
+call p_verify_reprepare_count(0);
+drop table t2;
+# Table to be used does not exist
+drop table t1;
+--error ER_NO_SUCH_TABLE
+execute stmt;
+call p_verify_reprepare_count(0);
+--error ER_NO_SUCH_TABLE
+execute stmt;
+call p_verify_reprepare_count(0);
+# Table to be used recreated (drop,create) with different layout
+create table t1 (x char(17));
+execute stmt;
+call p_verify_reprepare_count(1);
+drop table t2;
+execute stmt;
+call p_verify_reprepare_count(0);
+drop table t2;
+# Table to be used has a modified (alter table) layout
+alter table t1 add column y time;
+execute stmt;
+call p_verify_reprepare_count(1);
+select * from t2;
+drop table t2;
+execute stmt;
+call p_verify_reprepare_count(0);
+drop table t1;
+drop table t2;
+deallocate prepare stmt;
+
+
+--echo #
+--echo # SQLCOM_UPDATE
+--echo #
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+create table t1 (a int);
+create table t2 (a int);
+prepare stmt from "update t2 set a=a+1 where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1, t2;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_INSERT
+--echo #
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+create table t1 (a int);
+create table t2 (a int);
+prepare stmt from "insert into t2 set a=((1) in (select * from t1))";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+
+drop table t1, t2;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_INSERT_SELECT
+--echo #
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+create table t1 (a int);
+create table t2 (a int);
+prepare stmt from "insert into t2 select * from t1";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1, t2;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_REPLACE
+--echo #
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+create table t1 (a int);
+create table t2 (a int);
+prepare stmt from "replace t2 set a=((1) in (select * from t1))";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1, t2;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_REPLACE_SELECT
+--echo #
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+create table t1 (a int);
+create table t2 (a int);
+prepare stmt from "replace t2 select * from t1";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1, t2;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_DELETE
+--echo #
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+create table t1 (a int);
+create table t2 (a int);
+prepare stmt from "delete from t2 where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1, t2;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_DELETE_MULTI
+--echo #
+
+--disable_warnings
+drop table if exists t1, t2, t3;
+--enable_warnings
+create table t1 (a int);
+create table t2 (a int);
+create table t3 (a int);
+prepare stmt from "delete t2, t3 from t2, t3 where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1, t2, t3;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_UPDATE_MULTI
+--echo #
+
+--disable_warnings
+drop table if exists t1, t2, t3;
+--enable_warnings
+create table t1 (a int);
+create table t2 (a int);
+create table t3 (a int);
+prepare stmt from "update t2, t3 set t3.a=t2.a, t2.a=null where (1) in (select * from
t1)";
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1, t2, t3;
+deallocate prepare stmt;
+--echo # Intermediate results: 8 SQLCOMs tested, 8 automatic reprepares
+call p_verify_reprepare_count(8);
+
+--echo #
+--echo # SQLCOM_LOAD
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a varchar(20));
+--error ER_UNSUPPORTED_PS
+prepare stmt from "load data infile '../std_data_ln/words.dat' into table t1";
+drop table t1;
+
+--echo #
+--echo # SQLCOM_SHOW_DATABASES
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "show databases where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_SHOW_TABLES
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "show tables where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_SHOW_FIELDS
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "show fields from t1 where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_SHOW_KEYS
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "show keys from t1 where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_SHOW_VARIABLES
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "show variables where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_SHOW_STATUS
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "show status where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_SHOW_ENGINE_STATUS, SQLCOM_SHOW_ENGINE_LOGS,
+--echo # SQLCOM_SHOW_ENGINE_MUTEX, SQLCOM_SHOW_PROCESSLIST
+--echo #
+
+--echo # Currently can not have a where clause, need to be covered
+--echo # with tests
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+--error ER_PARSE_ERROR
+prepare stmt from "show engine all status where (1) in (select * from t1)";
+--error ER_PARSE_ERROR
+prepare stmt from "show engine all logs where (1) in (select * from t1)";
+--error ER_PARSE_ERROR
+prepare stmt from "show engine all mutex where (1) in (select * from t1)";
+--error ER_PARSE_ERROR
+prepare stmt from "show processlist where (1) in (select * from t1)";
+drop table t1;
+
+--echo #
+--echo # SQLCOM_SHOW_CHARSETS
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "show charset where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_SHOW_COLLATIONS
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "show collation where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_SHOW_TABLE_STATUS
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "show table status where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_SHOW_TRIGGERS
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "show triggers where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_SHOW_OPEN_TABLES
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "show open tables where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_SHOW_STATUS_PROC
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "show procedure status where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_SHOW_STATUS_FUNC
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "show function status where (1) in (select * from t1)";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_SHOW_EVENTS
+--echo #
+--echo #
+--echo # Please see this test in ps.test, it requires not_embedded.inc
+--echo #
+
+--echo #
+--echo # SQLCOM_SET_OPTION
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "set @a=((1) in (select * from t1))";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_DO
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "do ((1) in (select * from t1))";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_CALL
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+drop procedure if exists p1;
+--enable_warnings
+create procedure p1(a int) begin end;
+create table t1 (a int);
+prepare stmt from "call p1((1) in (select * from t1))";
+execute stmt;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop table t1;
+drop procedure p1;
+deallocate prepare stmt;
+
+--echo #
+--echo # SQLCOM_CREATE_VIEW
+--echo #
+
+--disable_warnings
+drop table if exists t1;
+drop view if exists v1;
+--enable_warnings
+create table t1 (a int);
+prepare stmt from "create view v1 as select * from t1";
+execute stmt;
+drop view v1;
+drop table t1;
+create table t1 (x int);
+execute stmt;
+drop view v1;
+drop table t1;
+deallocate prepare stmt;
+--echo # Intermediate result: number of reprepares matches the number
+--echo # of tests
+call p_verify_reprepare_count(17);
+
+--echo #
+--echo # SQLCOM_ALTER_VIEW
+--echo #
+
+--disable_warnings
+drop view if exists v1;
+--enable_warnings
+create view v1 as select 1;
+--error ER_UNSUPPORTED_PS
+prepare stmt from "alter view v1 as select 2";
+drop view v1;
+
+--echo # Cleanup
+--echo #
+--disable_warnings
+drop temporary table if exists t1, t2, t3;
+drop table if exists t1, t2, t3, v1, v2;
+drop procedure if exists p_verify_reprepare_count;
+drop procedure if exists p1;
+drop function if exists f1;
+drop view if exists v1, v2;
+--enable_warnings
=== added file 'mysql-test/t/ps_ddl1.test'
--- a/mysql-test/t/ps_ddl1.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/ps_ddl1.test 2008-04-18 19:18:53 +0000
@@ -0,0 +1,398 @@
+#
+# Testing the behavior of 'PREPARE', 'DDL', 'EXECUTE' scenarios
+#
+# There are several subtests which are probably "superfluous" because a DDL
+# statement before the EXECUTE <prepared stmt handle> contained a keyword
+# or action (Example: Alter) which causes that all prepared statements using
+# the modified object are reprepared before execution.
+# Please do not delete these subtests if they disturb. Just disable them by
+# if (0)
+# {
+# <tests to disable>
+# }.
+# There might be future optimisations of the server which decrease the amount
+# of unneeded reprepares or skip unneeded prepare steps and than these subtests
+# might become valuable.
+# Example:
+# Every preceding ALTER TABLE seems to cause a reprepare.
+# But if the ALTER only changed the table comment ...
+#
+# Created: 2008-04-18 mleich
+#
+
+--disable_warnings
+drop temporary table if exists t1;
+drop table if exists t1, t2;
+drop procedure if exists p_verify_reprepare_count;
+drop procedure if exists p1;
+drop function if exists f1;
+drop view if exists t1;
+drop schema if exists mysqltest;
+--enable_warnings
+
+delimiter |;
+create procedure p_verify_reprepare_count(expected int)
+begin
+ declare old_reprepare_count int default @reprepare_count;
+
+ select variable_value from
+ information_schema.session_status where
+ variable_name='com_stmt_reprepare'
+ into @reprepare_count;
+
+ if old_reprepare_count + expected <> @reprepare_count then
+ select concat("Expected: ", expected,
+ ", actual: ", @reprepare_count - old_reprepare_count)
+ as "ERROR";
+ else
+ select '' as "SUCCESS";
+ end if;
+end|
+delimiter ;|
+set @reprepare_count= 0;
+flush status;
+
+--disable_warnings
+drop table if exists t1;
+--disable_warnings
+
+--echo # Column added or dropped is not within the list of selected columns
+--echo # or table comment has changed.
+--echo # A reprepare is probably not needed.
+create table t1 (a int, b int);
+prepare stmt from "select a from t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+alter table t1 add column c int;
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+alter table t1 drop column b;
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+alter table t1 comment "My best table";
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+drop table t1;
+deallocate prepare stmt;
+
+--echo # Selects using the table at various positions, inser,update ...
+--echo # + the table disappears
+create table t1 (a int);
+# Attention:
+# "truncate" must have the first position (= executed as last prepared
+# statement), because it recreates the table which has leads to reprepare
+# (is this really needed) of all statements.
+prepare stmt1 from "truncate t1";
+prepare stmt2 from "select 1 as my_column from t1";
+prepare stmt3 from "select 1 as my_column from (select * from t1) as t2";
+prepare stmt4 from
+"select 1 as my_column from (select 1) as t2 where exists (select 1 from t1)";
+prepare stmt5 from "select * from (select 1 as b) as t2, t1";
+prepare stmt6 from "select * from t1 union all select 1.5";
+prepare stmt7 from "select 1 as my_column union all select 1 from t1";
+prepare stmt8 from "insert into t1 values(1),(2)";
+prepare stmt9 from "update t1 set a = 3 where a = 2";
+prepare stmt10 from "delete from t1 where a = 1";
+let ps_stmt_count= 10;
+--echo # Attention: Result logging is disabled.
+# Checks of correct results of statements are not the goal of this test.
+let $num= $ps_stmt_count;
+while ($num)
+{
+ --disable_result_log
+ eval execute stmt$num;
+ --enable_result_log
+ dec $num;
+}
+# There was no reprepare needed, because none of the objects has changed.
+call p_verify_reprepare_count(0);
+drop table t1;
+let $num= $ps_stmt_count;
+while ($num)
+{
+ --error ER_NO_SUCH_TABLE
+ eval execute stmt$num;
+ dec $num;
+}
+# There was no reprepare needed, because the statement is no more applicable.
+call p_verify_reprepare_count(0);
+let $num= $ps_stmt_count;
+while ($num)
+{
+ eval deallocate prepare stmt$num;
+ dec $num;
+}
+
+--echo # Selects using the table at various positions, inser,update ...
+--echo # + layout change (drop column) which must cause a reprepare
+create table t1 (a int, b int);
+insert into t1 values(1,1),(2,2),(3,3);
+create table t2 like t1;
+insert into t1 values(2,2);
+prepare stmt1 from "select a,b from t1";
+prepare stmt2 from "select a,b from (select * from t1) as t1";
+prepare stmt3 from "select * from t1 where a = 2 and b = 2";
+prepare stmt4 from "select * from t2 where (a,b) in (select * from t1)";
+prepare stmt5 from "select * from t1 union select * from t2";
+prepare stmt6 from "select * from t1 union all select * from t2";
+prepare stmt7 from "insert into t1 set a = 4, b = 4";
+prepare stmt8 from "insert into t1 select * from t2";
+let ps_stmt_count= 8;
+--echo # Attention: Result logging is disabled.
+# Checks of correct results of statements are not the goal of this test.
+let $num= $ps_stmt_count;
+while ($num)
+{
+ --disable_result_log
+ eval execute stmt$num;
+ --enable_result_log
+ dec $num;
+}
+call p_verify_reprepare_count(0);
+alter table t1 drop column b;
+--disable_abort_on_error
+let $num= $ps_stmt_count;
+while ($num)
+{
+ eval execute stmt$num;
+ # A reprepare is needed, because layout change of t1 affects statement.
+ call p_verify_reprepare_count(1);
+ dec $num;
+}
+let $num= $ps_stmt_count;
+while ($num)
+{
+ eval execute stmt$num;
+ call p_verify_reprepare_count(1);
+ dec $num;
+}
+--echo # Why does the INSERT ... SELECT does not get a reprepare or is
+--echo # only the counter not incremented?
+eval execute stmt8;
+call p_verify_reprepare_count(1);
+--enable_abort_on_error
+alter table t2 add column c int;
+--error ER_WRONG_VALUE_COUNT_ON_ROW
+eval execute stmt8;
+call p_verify_reprepare_count(1);
+let $num= $ps_stmt_count;
+while ($num)
+{
+ eval deallocate prepare stmt$num;
+ dec $num;
+}
+drop table t1;
+drop table t2;
+
+
+--echo # select AVG(<col>) + optimizer uses index meets loss of the index
+create table t1 (a int, b int, primary key(b),unique index t1_unq_idx(a));
+# We need an index which is not converted to PRIMARY KEY (becomes in
+# case of InnoDB the key used for table clustering).
+insert into t1 set a = 0, b = 0;
+insert into t1 select a + 1, b + 1 from t1;
+insert into t1 select a + 2, b + 2 from t1;
+insert into t1 select a + 4, b + 4 from t1;
+insert into t1 select a + 8, b + 8 from t1;
+# "using index" optimizer strategy is intended
+let $possible_keys=
+ query_get_value(explain select avg(a) from t1, possible_keys, 1);
+let $extra=
+ query_get_value(explain select avg(a) from t1, Extra, 1);
+--echo # Optimizer strategy: Possible keys = $possible_keys , Extra = $extra
+prepare stmt from "select avg(a) from t1";
+execute stmt;
+call p_verify_reprepare_count(0);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+alter table t1 drop index t1_unq_idx;
+let $possible_keys=
+ query_get_value(explain select avg(a) from t1, possible_keys, 1);
+let $extra=
+ query_get_value(explain select avg(a) from t1, Extra, 1);
+--echo # Optimizer strategy: Possible keys = $possible_keys , Extra = $extra
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+
+--echo # select AVG(<col>) + optimizer uses table scan meets a new index
+alter table t1 add unique index t1_unq_idx(a);
+let $possible_keys=
+ query_get_value(explain select avg(a) from t1, possible_keys, 1);
+let $extra=
+ query_get_value(explain select avg(a) from t1, Extra, 1);
+--echo # Optimizer strategy: Possible keys = $possible_keys , Extra = $extra
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+
+deallocate prepare stmt;
+drop table t1;
+
+
+--echo # table replaced by not updatable view - Insert
+create table t1 (a int);
+prepare stmt from "insert into t1 values(1)";
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop table t1;
+create view t1 as select 1;
+--error ER_NON_INSERTABLE_TABLE
+execute stmt;
+call p_verify_reprepare_count(1);
+
+drop view t1;
+create table t2 (a int);
+create view t1 as select * from t2 with check option;
+execute stmt;
+call p_verify_reprepare_count(1);
+execute stmt;
+call p_verify_reprepare_count(0);
+select * from t1;
+
+deallocate prepare stmt;
+drop view t1;
+drop table t2;
+
+
+--echo =====================================================================
+--echo Some freestyle tests
+--echo =====================================================================
+
+create temporary table t1 as select 1 as a;
+delimiter |;
+create procedure p1()
+begin
+ drop temporary table t1;
+end|
+create function f1() returns int
+begin
+ call p1();
+ return 1;
+end|
+delimiter ;|
+
+prepare stmt from "select f1() as my_column, a from t1";
+--error ER_CANT_REOPEN_TABLE
+execute stmt;
+call p_verify_reprepare_count(0);
+select * from t1;
+
+prepare stmt from "select a, f1() as my_column from t1";
+--error ER_CANT_REOPEN_TABLE
+execute stmt;
+call p_verify_reprepare_count(0);
+select * from t1;
+
+prepare stmt from "select f1() as my_column, count(*) from t1";
+--error ER_CANT_REOPEN_TABLE
+execute stmt;
+call p_verify_reprepare_count(0);
+select * from t1;
+
+prepare stmt from "select count(*), f1() as my_column from t1";
+--error ER_CANT_REOPEN_TABLE
+execute stmt;
+call p_verify_reprepare_count(0);
+select * from t1;
+
+
+--echo # Execute fails, no drop of temporary table
+prepare stmt from "select 1 as my_column from (select 1) as t2
+ where exists (select f1() from t1)";
+execute stmt;
+call p_verify_reprepare_count(0);
+execute stmt;
+call p_verify_reprepare_count(0);
+select * from t1;
+
+--echo # Execute drops temporary table
+prepare stmt from "select f1()";
+execute stmt;
+call p_verify_reprepare_count(0);
+--error ER_BAD_TABLE_ERROR
+execute stmt;
+call p_verify_reprepare_count(0);
+
+drop function f1;
+drop procedure p1;
+deallocate prepare stmt;
+
+--echo # Execute fails, temporary table is not replaced by another
+create temporary table t1 as select 1 as a;
+delimiter |;
+create procedure p1()
+begin
+ drop temporary table t1;
+ create temporary table t1 as select 'abc' as a;
+end|
+create function f1() returns int
+begin
+ call p1();
+ return 1;
+end|
+delimiter ;|
+prepare stmt from "select count(*), f1() as my_column from t1";
+--error ER_CANT_REOPEN_TABLE
+execute stmt;
+call p_verify_reprepare_count(0);
+select * from t1;
+deallocate prepare stmt;
+
+prepare stmt from "call p1";
+execute stmt;
+drop procedure p1;
+create schema mysqltest;
+delimiter |;
+create procedure mysqltest.p1()
+begin
+ drop schema mysqltest;
+ create schema mysqltest;
+end|
+delimiter ;|
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+call p_verify_reprepare_count(0);
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+call p_verify_reprepare_count(0);
+deallocate prepare stmt;
+drop schema mysqltest;
+drop temporary table t1;
+
+
+# Bug#36089 drop temp table in SP called by function, crash
+# Note: A non prepared "select 1 from t1 having count(*) = f1();" is sufficient.
+if (0)
+{
+create temporary table t1 as select 1 as a;
+prepare stmt from "select 1 from t1 having count(*) = f1()";
+execute stmt;
+call p_verify_reprepare_count(0);
+deallocate prepare stmt;
+drop temporary table t1;
+}
+
+
+--echo # Cleanup
+--echo #
+--disable_warnings
+drop temporary table if exists t1;
+drop table if exists t1, t2;
+drop procedure if exists p_verify_reprepare_count;
+drop procedure if exists p1;
+drop function if exists f1;
+drop view if exists t1;
+drop schema if exists mysqltest;
+--enable_warnings
=== modified file 'mysql-test/t/query_cache_merge.test'
--- a/mysql-test/t/query_cache_merge.test 2005-07-28 00:22:47 +0000
+++ b/mysql-test/t/query_cache_merge.test 2008-04-08 16:01:20 +0000
@@ -25,6 +25,15 @@
}
--enable_warnings
+#
+# In order for the test to pass in --ps-protocol, we must
+# set table_definition_cache size to at least 258 elements.
+# Otherwise table versions are bound to change between
+# prepare and execute, and we will get a constant validation
+# error. See WL#4165 for details.
+#
+set @save_table_definition_cache= @@global.table_definition_cache;
+set @@global.table_definition_cache=512;
create table t00 (a int) engine=MERGE
UNION=(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40,t41,t42,t43,t44,t45,t46,t47,t48,t49,t50,t51,t52,t53,t54,t55,t56,t57,t58,t59,t60,t61,t62,t63,t64,t65,t66,t67,t68,t69,t70,t71,t72,t73,t74,t75,t76,t77,t78,t79,t80,t81,t82,t83,t84,t85,t86,t87,t88,t89,t90,t91,t92,t93,t94,t95,t96,t97,t98,t99,t100,t101,t102,t103,t104,t105,t106,t107,t108,t109,t110,t111,t112,t113,t114,t115,t116,t117,t118,t119,t120,t121,t122,t123,t124,t125,t126,t127,t128,t129,t130,t131,t132,t133,t134,t135,t136,t137,t138,t139,t140,t141,t142,t143,t144,t145,t146,t147,t148,t149,t150,t151,t152,t153,t154,t155,t156,t157,t158,t159,t160,t161,t162,t163,t164,t165,t166,t167,t168,t169,t170,t171,t172,t173,t174,t175,t176,t177,t178,t179,t180,t181,t182,t183,t184,t185,t186,t187,t188,t189,t190,t191,t192,t193,t194,t195,t196,t197,t198,t199,t200,t201,t202,t203,t204,t205,t206,t207,t208,t209,t210,t2
11,t212,t213,t214,t215,t216,t217,t218,t219,t220,t221,t222,t223,t224,t225,t226,t227,t228,t229,t230,t231,t232,t233,t234,t235,t236,t237,t238,t239,t240,t241,t242,t243,t244,t245,t246,t247,t248,t249,t250,t251,t252,t253,t254,t255,t256,t257)
INSERT_METHOD=FIRST;
enable_query_log;
select count(*) from t00;
@@ -36,5 +45,6 @@
drop table
t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40,t41,t42,t43,t44,t45,t46,t47,t48,t49,t50,t51,t52,t53,t54,t55,t56,t57,t58,t59,t60,t61,t62,t63,t64,t65,t66,t67,t68,t69,t70,t71,t72,t73,t74,t75,t76,t77,t78,t79,t80,t81,t82,t83,t84,t85,t86,t87,t88,t89,t90,t91,t92,t93,t94,t95,t96,t97,t98,t99,t100,t101,t102,t103,t104,t105,t106,t107,t108,t109,t110,t111,t112,t113,t114,t115,t116,t117,t118,t119,t120,t121,t122,t123,t124,t125,t126,t127,t128,t129,t130,t131,t132,t133,t134,t135,t136,t137,t138,t139,t140,t141,t142,t143,t144,t145,t146,t147,t148,t149,t150,t151,t152,t153,t154,t155,t156,t157,t158,t159,t160,t161,t162,t163,t164,t165,t166,t167,t168,t169,t170,t171,t172,t173,t174,t175,t176,t177,t178,t179,t180,t181,t182,t183,t184,t185,t186,t187,t188,t189,t190,t191,t192,t193,t194,t195,t196,t197,t198,t199,t200,t201,t202,t203,t204,t205,t206,t207,t208,t209,t210,t211,t212,t213,t214,t215,t216,t217,t
218,t219,t220,t221,t222,t223,t224,t225,t226,t227,t228,t229,t230,t231,t232,t233,t234,t235,t236,t237,t238,t239,t240,t241,t242,t243,t244,t245,t246,t247,t248,t249,t250,t251,t252,t253,t254,t255,t256,t257,t00;
SET @@global.query_cache_size=0;
+set @@global.table_definition_cache=@save_table_definition_cache;
# End of 4.1 tests
=== modified file 'mysql-test/t/slow_query_log_file_basic.test'
--- a/mysql-test/t/slow_query_log_file_basic.test 2008-04-10 13:14:28 +0000
+++ b/mysql-test/t/slow_query_log_file_basic.test 2008-05-20 18:23:58 +0000
@@ -52,8 +52,10 @@
# Change the value of slow_query_log_file to a invalid value #
#######################################################################
---Error ER_WRONG_VALUE_FOR_VAR
+# Assumed text if no quotes or numbers.
SET @@global.slow_query_log_file = mytest.log;
+--error ER_WRONG_TYPE_FOR_VAR
+SET @@global.slow_query_log_file = 12;
--echo '#----------------------FN_DYNVARS_004_03------------------------#'
##############################################################################
=== modified file 'mysql-test/t/status.test'
--- a/mysql-test/t/status.test 2008-05-13 14:10:08 +0000
+++ b/mysql-test/t/status.test 2008-05-21 15:34:14 +0000
@@ -246,7 +246,7 @@
# Bug#30252 Com_create_function is not incremented.
#
flush status;
-show status like 'Com%function%';
+show status like 'Com%function';
DELIMITER //;
create function f1 (x INTEGER) returns integer
@@ -258,7 +258,7 @@
DELIMITER ;//
drop function f1;
-show status like 'Com%function%';
+show status like 'Com%function';
# End of 5.1 tests
=== modified file 'mysql-test/t/trigger.test'
--- a/mysql-test/t/trigger.test 2008-02-12 11:44:27 +0000
+++ b/mysql-test/t/trigger.test 2008-04-08 16:01:20 +0000
@@ -997,11 +997,10 @@
# Altering trigger forcing it use different set of tables
drop trigger t1_bi;
create trigger t1_bi after insert on t1 for each row insert into t3 values (new.id);
-# Until we implement proper mechanism for invalidation of PS/SP when table
-# or SP's are changed these two statements will fail with 'Table ... was
-# not locked' error (this mechanism should be based on the new TDC).
---error ER_NO_SUCH_TABLE
execute stmt1;
+# Until we implement proper mechanism for invalidation of SP statements
+# invoked whenever a table used in SP changes, this statement will fail with
+# 'Table ... does not exist' error.
--error ER_NO_SUCH_TABLE
call p1();
deallocate prepare stmt1;
=== modified file 'mysql-test/t/variables.test'
--- a/mysql-test/t/variables.test 2008-03-14 17:32:01 +0000
+++ b/mysql-test/t/variables.test 2008-03-28 15:10:04 +0000
@@ -778,3 +778,20 @@
--replace_column 2 #
show global variables where Variable_name='table_definition_cache' or
Variable_name='table_lock_wait_timeout';
+
+###########################################################################
+
+--echo
+--echo # --
+--echo # -- Bug#34820: log_output can be set to illegal value.
+--echo # --
+
+--error ER_WRONG_VALUE_FOR_VAR
+SET GLOBAL log_output = '';
+
+--error ER_WRONG_VALUE_FOR_VAR
+SET GLOBAL log_output = 0;
+
+--echo
+--echo # -- End of Bug#34820.
+
=== modified file 'mysys/my_alloc.c'
--- a/mysys/my_alloc.c 2007-05-10 09:59:39 +0000
+++ b/mysys/my_alloc.c 2008-04-07 09:29:45 +0000
@@ -202,7 +202,7 @@
{
if (mem_root->error_handler)
(*mem_root->error_handler)();
- return((void*) 0); /* purecov: inspected */
+ DBUG_RETURN((void*) 0); /* purecov: inspected */
}
mem_root->block_num++;
next->next= *prev;
=== modified file 'sql/item.cc'
--- a/sql/item.cc 2008-04-21 23:36:24 +0000
+++ b/sql/item.cc 2008-05-20 07:38:17 +0000
@@ -3161,6 +3161,49 @@
}
+/**
+ Preserve the original parameter types and values
+ when re-preparing a prepared statement.
+
+ @details Copy parameter type information and conversion
+ function pointers from a parameter of the old statement
+ to the corresponding parameter of the new one.
+
+ Move parameter values from the old parameters to the new
+ one. We simply "exchange" the values, which allows
+ to save on allocation and character set conversion in
+ case a parameter is a string or a blob/clob.
+
+ The old parameter gets the value of this one, which
+ ensures that all memory of this parameter is freed
+ correctly.
+
+ @param[in] src parameter item of the original
+ prepared statement
+*/
+
+void
+Item_param::set_param_type_and_swap_value(Item_param *src)
+{
+ unsigned_flag= src->unsigned_flag;
+ param_type= src->param_type;
+ set_param_func= src->set_param_func;
+ item_type= src->item_type;
+ item_result_type= src->item_result_type;
+
+ collation.set(src->collation);
+ maybe_null= src->maybe_null;
+ null_value= src->null_value;
+ max_length= src->max_length;
+ decimals= src->decimals;
+ state= src->state;
+ value= src->value;
+
+ decimal_value.swap(src->decimal_value);
+ str_value.swap(src->str_value);
+ str_value_ptr.swap(src->str_value_ptr);
+}
+
/****************************************************************************
Item_copy_string
****************************************************************************/
=== modified file 'sql/item.h'
--- a/sql/item.h 2008-03-12 08:21:12 +0000
+++ b/sql/item.h 2008-04-08 16:01:20 +0000
@@ -1684,6 +1684,7 @@
bool eq(const Item *item, bool binary_cmp) const;
/** Item is a argument to a limit clause. */
bool limit_clause_param;
+ void set_param_type_and_swap_value(Item_param *from);
};
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2008-03-31 08:57:18 +0000
+++ b/sql/log.cc 2008-05-21 12:44:30 +0000
@@ -741,10 +741,14 @@
ulonglong query_utime, ulonglong lock_utime, bool is_command,
const char *sql_text, uint sql_text_len)
{
- return mysql_slow_log.write(thd, current_time, query_start_arg,
- user_host, user_host_len,
- query_utime, lock_utime, is_command,
- sql_text, sql_text_len);
+ Silence_log_table_errors error_handler;
+ thd->push_internal_handler(&error_handler);
+ bool retval= mysql_slow_log.write(thd, current_time, query_start_arg,
+ user_host, user_host_len,
+ query_utime, lock_utime, is_command,
+ sql_text, sql_text_len);
+ thd->pop_internal_handler();
+ return retval;
}
@@ -760,9 +764,13 @@
const char *sql_text, uint sql_text_len,
CHARSET_INFO *client_cs)
{
- return mysql_log.write(event_time, user_host, user_host_len,
- thread_id, command_type, command_type_len,
- sql_text, sql_text_len);
+ Silence_log_table_errors error_handler;
+ thd->push_internal_handler(&error_handler);
+ bool retval= mysql_log.write(event_time, user_host, user_host_len,
+ thread_id, command_type, command_type_len,
+ sql_text, sql_text_len);
+ thd->pop_internal_handler();
+ return retval;
}
=== modified file 'sql/my_decimal.h'
--- a/sql/my_decimal.h 2008-04-28 18:12:52 +0000
+++ b/sql/my_decimal.h 2008-05-20 07:38:17 +0000
@@ -114,6 +114,14 @@
bool sign() const { return decimal_t::sign; }
void sign(bool s) { decimal_t::sign= s; }
uint precision() const { return intg + frac; }
+
+ /** Swap two my_decimal values */
+ void swap(my_decimal &rhs)
+ {
+ swap_variables(my_decimal, *this, rhs);
+ /* Swap the buffer pointers back */
+ swap_variables(decimal_digit_t *, buf, rhs.buf);
+ }
};
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2008-03-31 07:40:39 +0000
+++ b/sql/mysql_priv.h 2008-05-20 07:29:16 +0000
@@ -259,6 +259,21 @@
#define USER_VARS_HASH_SIZE 16
#define TABLE_OPEN_CACHE_MIN 64
#define TABLE_OPEN_CACHE_DEFAULT 64
+#define TABLE_DEF_CACHE_DEFAULT 256
+/**
+ We must have room for at least 256 table definitions in the table
+ cache, since otherwise there is no chance prepared
+ statements that use these many tables can work.
+ Prepared statements use table definition cache ids (table_map_id)
+ as table version identifiers. If the table definition
+ cache size is less than the number of tables used in a statement,
+ the contents of the table definition cache is guaranteed to rotate
+ between a prepare and execute. This leads to stable validation
+ errors. In future we shall use more stable version identifiers,
+ for now the only solution is to ensure that the table definition
+ cache can contain at least all tables of a given statement.
+*/
+#define TABLE_DEF_CACHE_MIN 256
/*
Value of 9236 discovered through binary search 2006-09-26 on Ubuntu Dapper
@@ -670,6 +685,31 @@
const char *calling_file,
const unsigned int calling_line);
+/**
+ Enumerate possible types of a table from re-execution
+ standpoint.
+ TABLE_LIST class has a member of this type.
+ At prepared statement prepare, this member is assigned a value
+ as of the current state of the database. Before (re-)execution
+ of a prepared statement, we check that the value recorded at
+ prepare matches the type of the object we obtained from the
+ table definition cache.
+
+ @sa check_and_update_table_version()
+ @sa Execute_observer
+ @sa Prepared_statement::reprepare()
+*/
+
+enum enum_table_ref_type
+{
+ /** Initial value set by the parser */
+ TABLE_REF_NULL= 0,
+ TABLE_REF_VIEW,
+ TABLE_REF_BASE_TABLE,
+ TABLE_REF_I_S_TABLE,
+ TABLE_REF_TMP_TABLE
+};
+
/*
External variables
*/
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2008-05-09 07:43:02 +0000
+++ b/sql/mysqld.cc 2008-05-20 07:38:17 +0000
@@ -1957,9 +1957,11 @@
between main thread doing initialization and CTRL-C thread doing
cleanup, which can result into crash.
*/
+#ifndef EMBEDDED_LIBRARY
if(hEventShutdown)
kill_mysql();
else
+#endif
sql_print_warning("CTRL-C ignored during startup");
DBUG_RETURN(TRUE);
}
@@ -2843,6 +2845,7 @@
by the stored procedures code.
*/
if (thd->spcont &&
+ ! (MyFlags & ME_NO_SP_HANDLER) &&
thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd))
{
/*
@@ -2852,7 +2855,8 @@
DBUG_RETURN(0);
}
- if (!thd->no_warnings_for_error)
+ if (!thd->no_warnings_for_error &&
+ !(MyFlags & ME_NO_WARNING_FOR_ERROR))
{
/*
Suppress infinite recursion if there a memory allocation error
@@ -3092,6 +3096,7 @@
{"stmt_execute", (char*) offsetof(STATUS_VAR, com_stmt_execute),
SHOW_LONG_STATUS},
{"stmt_fetch", (char*) offsetof(STATUS_VAR, com_stmt_fetch),
SHOW_LONG_STATUS},
{"stmt_prepare", (char*) offsetof(STATUS_VAR, com_stmt_prepare),
SHOW_LONG_STATUS},
+ {"stmt_reprepare", (char*) offsetof(STATUS_VAR, com_stmt_reprepare),
SHOW_LONG_STATUS},
{"stmt_reset", (char*) offsetof(STATUS_VAR, com_stmt_reset),
SHOW_LONG_STATUS},
{"stmt_send_long_data", (char*) offsetof(STATUS_VAR, com_stmt_send_long_data),
SHOW_LONG_STATUS},
{"truncate", (char*) offsetof(STATUS_VAR, com_stat[(uint)
SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
@@ -3180,7 +3185,7 @@
We have few debug-only commands in com_status_vars, only visible in debug
builds. for simplicity we enable the assert only in debug builds
- There are 7 Com_ variables which don't have corresponding SQLCOM_ values:
+ There are 8 Com_ variables which don't have corresponding SQLCOM_ values:
(TODO strictly speaking they shouldn't be here, should not have Com_ prefix
that is. Perhaps Stmt_ ? Comstmt_ ? Prepstmt_ ?)
@@ -3189,6 +3194,7 @@
Com_stmt_execute => com_stmt_execute
Com_stmt_fetch => com_stmt_fetch
Com_stmt_prepare => com_stmt_prepare
+ Com_stmt_reprepare => com_stmt_reprepare
Com_stmt_reset => com_stmt_reset
Com_stmt_send_long_data => com_stmt_send_long_data
@@ -3197,7 +3203,7 @@
of SQLCOM_ constants.
*/
compile_time_assert(sizeof(com_status_vars)/sizeof(com_status_vars[0]) - 1 ==
- SQLCOM_END + 7);
+ SQLCOM_END + 8);
#endif
load_defaults(conf_file_name, groups, &argc, &argv);
@@ -6766,7 +6772,8 @@
{"table_definition_cache", OPT_TABLE_DEF_CACHE,
"The number of cached table definitions.",
(uchar**) &table_def_size, (uchar**) &table_def_size,
- 0, GET_ULONG, REQUIRED_ARG, 128, 1, 512*1024L, 0, 1, 0},
+ 0, GET_ULONG, REQUIRED_ARG, TABLE_DEF_CACHE_DEFAULT, TABLE_DEF_CACHE_MIN,
+ 512*1024L, 0, 1, 0},
{"table_open_cache", OPT_TABLE_OPEN_CACHE,
"The number of cached open tables.",
(uchar**) &table_cache_size, (uchar**) &table_cache_size, 0, GET_ULONG,
=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc 2008-03-31 07:40:39 +0000
+++ b/sql/opt_range.cc 2008-04-14 10:58:53 +0000
@@ -2314,9 +2314,6 @@
table deletes.
*/
if ((thd->lex->sql_command != SQLCOM_DELETE))
-#ifdef NOT_USED
- if ((thd->lex->sql_command != SQLCOM_UPDATE))
-#endif
{
/*
Get best non-covering ROR-intersection plan and prepare data for
=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc 2008-05-09 07:43:02 +0000
+++ b/sql/set_var.cc 2008-05-20 07:38:17 +0000
@@ -1667,6 +1667,14 @@
strmov(buff, "NULL");
goto err;
}
+
+ if (!m_allow_empty_value &&
+ res->length() == 0)
+ {
+ buff[0]= 0;
+ goto err;
+ }
+
var->save_result.ulong_value= ((ulong)
find_set(enum_names, res->c_ptr(),
res->length(),
@@ -1682,10 +1690,19 @@
else
{
ulonglong tmp= var->value->val_int();
- /*
- For when the enum is made to contain 64 elements, as 1ULL<<64 is
- undefined, we guard with a "count<64" test.
- */
+
+ if (!m_allow_empty_value &&
+ tmp == 0)
+ {
+ buff[0]= '0';
+ buff[1]= 0;
+ goto err;
+ }
+
+ /*
+ For when the enum is made to contain 64 elements, as 1ULL<<64 is
+ undefined, we guard with a "count<64" test.
+ */
if (unlikely((tmp >= ((ULL(1)) << enum_names->count)) &&
(enum_names->count < 64)))
{
@@ -2385,32 +2402,51 @@
MY_STAT f_stat;
String str(buff, sizeof(buff), system_charset_info), *res;
const char *log_file_str;
-
+ size_t path_length;
+
if (!(res= var->value->val_str(&str)))
goto err;
log_file_str= res->c_ptr();
bzero(&f_stat, sizeof(MY_STAT));
- (void) unpack_filename(path, log_file_str);
+ path_length= unpack_filename(path, log_file_str);
+
+ if (!path_length)
+ {
+ /* File name is empty. */
+
+ goto err;
+ }
+
if (my_stat(path, &f_stat, MYF(0)))
{
- /* Check if argument is a file and we have 'write' permission */
+ /*
+ A file system object exists. Check if argument is a file and we have
+ 'write' permission.
+ */
+
if (!MY_S_ISREG(f_stat.st_mode) ||
!(f_stat.st_mode & MY_S_IWRITE))
goto err;
- }
- else
- {
- size_t path_length;
- /*
- Check if directory exists and
- we have permission to create file & write to file
- */
- (void) dirname_part(path, log_file_str, &path_length);
- if (my_access(path, (F_OK|W_OK)))
- goto err;
- }
+
+ return 0;
+ }
+
+ /* Get dirname of the file path. */
+ (void) dirname_part(path, log_file_str, &path_length);
+
+ /* Dirname is empty if file path is relative. */
+ if (!path_length)
+ return 0;
+
+ /*
+ Check if directory exists and we have permission to create file and
+ write to file.
+ */
+ if (my_access(path, (F_OK|W_OK)))
+ goto err;
+
return 0;
err:
=== modified file 'sql/set_var.h'
--- a/sql/set_var.h 2008-05-09 07:43:02 +0000
+++ b/sql/set_var.h 2008-05-20 07:38:17 +0000
@@ -74,7 +74,8 @@
sys_var(const char *name_arg, sys_after_update_func func= NULL,
Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
:name(name_arg), after_update(func), no_support_one_shot(1),
- binlog_status(binlog_status_arg)
+ binlog_status(binlog_status_arg),
+ m_allow_empty_value(TRUE)
{}
virtual ~sys_var() {}
void chain_sys_var(sys_var_chain *chain_arg)
@@ -109,8 +110,16 @@
virtual bool is_readonly() const { return 0; }
virtual sys_var_pluginvar *cast_pluginvar() { return 0; }
+protected:
+ void set_allow_empty_value(bool allow_empty_value)
+ {
+ m_allow_empty_value= allow_empty_value;
+ }
+
private:
const Binlog_status_enum binlog_status;
+
+ bool m_allow_empty_value;
};
@@ -878,8 +887,11 @@
sys_var_log_output(sys_var_chain *chain, const char *name_arg, ulong *value_arg,
TYPELIB *typelib, sys_after_update_func func)
:sys_var(name_arg,func), value(value_arg), enum_names(typelib)
- { chain_sys_var(chain); }
- bool check(THD *thd, set_var *var)
+ {
+ chain_sys_var(chain);
+ set_allow_empty_value(FALSE);
+ }
+ virtual bool check(THD *thd, set_var *var)
{
return check_set(thd, var, enum_names);
}
=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt 2008-04-10 21:48:33 +0000
+++ b/sql/share/errmsg.txt 2008-05-20 16:36:26 +0000
@@ -6121,8 +6121,12 @@
eng "The BINLOG statement of type `%s` was not preceded by a format description BINLOG
statement."
ER_SLAVE_CORRUPT_EVENT
eng "Corrupted replication event was detected"
+
ER_LOAD_DATA_INVALID_COLUMN
eng "Invalid column reference (%-.64s) in LOAD DATA"
ER_LOG_PURGE_NO_FILE
eng "Being purged log %s was not found"
+
+ER_NEED_REPREPARE
+ eng "Prepared statement needs to be re-prepared"
=== modified file 'sql/sp.cc'
--- a/sql/sp.cc 2008-05-15 23:45:42 +0000
+++ b/sql/sp.cc 2008-05-20 07:38:17 +0000
@@ -1076,210 +1076,6 @@
}
-struct st_used_field
-{
- const char *field_name;
- uint field_length;
- enum enum_field_types field_type;
- Field *field;
-};
-
-static struct st_used_field init_fields[]=
-{
- { "Db", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0},
- { "Name", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0},
- { "Type", 9, MYSQL_TYPE_STRING, 0},
- { "Definer", USER_HOST_BUFF_SIZE, MYSQL_TYPE_STRING, 0},
- { "Modified", 0, MYSQL_TYPE_TIMESTAMP, 0},
- { "Created", 0, MYSQL_TYPE_TIMESTAMP, 0},
- { "Security_type", 1, MYSQL_TYPE_STRING, 0},
- { "Comment", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0},
- { "character_set_client", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0},
- { "collation_connection", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0},
- { "Database Collation", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0},
- { 0, 0, MYSQL_TYPE_STRING, 0}
-};
-
-
-static int
-print_field_values(THD *thd, TABLE *table,
- struct st_used_field *used_fields,
- int type, const char *wild)
-{
- Protocol *protocol= thd->protocol;
-
- if (table->field[MYSQL_PROC_MYSQL_TYPE]->val_int() == type)
- {
- String db_string;
- String name_string;
- struct st_used_field *used_field= used_fields;
-
- if (get_field(thd->mem_root, used_field->field, &db_string))
- db_string.set_ascii("", 0);
- used_field+= 1;
- get_field(thd->mem_root, used_field->field, &name_string);
-
- if (!wild || !wild[0] || !wild_compare(name_string.ptr(), wild, 0))
- {
- protocol->prepare_for_resend();
- protocol->store(&db_string);
- protocol->store(&name_string);
- for (used_field++;
- used_field->field_name;
- used_field++)
- {
- switch (used_field->field_type) {
- case MYSQL_TYPE_TIMESTAMP:
- {
- MYSQL_TIME tmp_time;
-
- bzero((char *)&tmp_time, sizeof(tmp_time));
- ((Field_timestamp *) used_field->field)->get_time(&tmp_time);
- protocol->store(&tmp_time);
- }
- break;
- default:
- {
- String tmp_string;
-
- get_field(thd->mem_root, used_field->field, &tmp_string);
- protocol->store(&tmp_string);
- }
- break;
- }
- }
- if (protocol->write())
- return SP_INTERNAL_ERROR;
- }
- }
-
- return SP_OK;
-}
-
-
-/**
- Implement SHOW STATUS statement for stored routines.
-
- @param thd Thread context.
- @param type Stored routine type
- (TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION)
- @param name_pattern Stored routine name pattern.
-
- @return Error code. SP_OK is returned on success. Other SP_ constants are
- used to indicate about errors.
-*/
-
-int
-sp_show_status_routine(THD *thd, int type, const char *name_pattern)
-{
- TABLE *table;
- TABLE_LIST tables;
- int res;
- DBUG_ENTER("sp_show_status_routine");
-
- DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
- type == TYPE_ENUM_FUNCTION);
-
- memset(&tables, 0, sizeof(tables));
- tables.db= (char*)"mysql";
- tables.table_name= tables.alias= (char*)"proc";
-
- if (! (table= open_ltable(thd, &tables, TL_READ, 0)))
- {
- res= SP_OPEN_TABLE_FAILED;
- goto done;
- }
- else
- {
- Item *item;
- List<Item> field_list;
- struct st_used_field *used_field;
- TABLE_LIST *leaves= 0;
- st_used_field used_fields[array_elements(init_fields)];
-
- table->use_all_columns();
- memcpy((char*) used_fields, (char*) init_fields, sizeof(used_fields));
- /* Init header */
- for (used_field= &used_fields[0];
- used_field->field_name;
- used_field++)
- {
- switch (used_field->field_type) {
- case MYSQL_TYPE_TIMESTAMP:
- item= new Item_return_date_time(used_field->field_name,
- MYSQL_TYPE_DATETIME);
- field_list.push_back(item);
- break;
- default:
- item= new Item_empty_string(used_field->field_name,
- used_field->field_length);
- field_list.push_back(item);
- break;
- }
- }
- /* Print header */
- if (thd->protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
- Protocol::SEND_EOF))
- {
- res= SP_INTERNAL_ERROR;
- goto err_case;
- }
-
- /*
- Init fields
-
- tables is not VIEW for sure => we can pass 0 as condition
- */
- thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
- setup_tables(thd, &thd->lex->select_lex.context,
- &thd->lex->select_lex.top_join_list,
- &tables, &leaves, FALSE);
- for (used_field= &used_fields[0];
- used_field->field_name;
- used_field++)
- {
- Item_field *field= new Item_field(&thd->lex->select_lex.context,
- "mysql", "proc",
- used_field->field_name);
- if (!field ||
- !(used_field->field= find_field_in_tables(thd, field, &tables, NULL,
- 0, REPORT_ALL_ERRORS, 1,
- TRUE)))
- {
- res= SP_INTERNAL_ERROR;
- goto err_case1;
- }
- }
-
- table->file->ha_index_init(0, 1);
- if ((res= table->file->index_first(table->record[0])))
- {
- res= (res == HA_ERR_END_OF_FILE) ? 0 : SP_INTERNAL_ERROR;
- goto err_case1;
- }
-
- do
- {
- res= print_field_values(thd, table, used_fields, type, name_pattern);
-
- if (res)
- goto err_case1;
- }
- while (!table->file->index_next(table->record[0]));
-
- res= SP_OK;
- }
-
-err_case1:
- my_eof(thd);
-err_case:
- table->file->ha_index_end();
- close_thread_tables(thd);
-done:
- DBUG_RETURN(res);
-}
-
-
/**
Drop all routines in database 'db'
=== modified file 'sql/sp.h'
--- a/sql/sp.h 2007-10-17 08:13:56 +0000
+++ b/sql/sp.h 2008-04-08 16:31:40 +0000
@@ -49,9 +49,6 @@
sp_show_create_routine(THD *thd, int type, sp_name *name);
int
-sp_show_status_routine(THD *thd, int type, const char *wild);
-
-int
sp_create_routine(THD *thd, int type, sp_head *sp);
int
=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc 2008-05-15 23:45:42 +0000
+++ b/sql/sp_head.cc 2008-05-20 07:38:17 +0000
@@ -1072,6 +1072,7 @@
LEX *old_lex;
Item_change_list old_change_list;
String old_packet;
+ Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
Object_creation_ctx *saved_creation_ctx;
@@ -1139,6 +1140,25 @@
thd->variables.sql_mode= m_sql_mode;
save_abort_on_warning= thd->abort_on_warning;
thd->abort_on_warning= 0;
+ /**
+ When inside a substatement (a stored function or trigger
+ statement), clear the metadata observer in THD, if any.
+ Remember the value of the observer here, to be able
+ to restore it when leaving the substatement.
+
+ We reset the observer to suppress errors when a substatement
+ uses temporary tables. If a temporary table does not exist
+ at start of the main statement, it's not prelocked
+ and thus is not validated with other prelocked tables.
+
+ Later on, when the temporary table is opened, metadata
+ versions mismatch, expectedly.
+
+ The proper solution for the problem is to re-validate tables
+ of substatements (Bug#12257, Bug#27011, Bug#32868, Bug#33000),
+ but it's not implemented yet.
+ */
+ thd->m_reprepare_observer= 0;
/*
It is also more efficient to save/restore current thd->lex once when
@@ -1301,6 +1321,7 @@
thd->derived_tables= old_derived_tables;
thd->variables.sql_mode= save_sql_mode;
thd->abort_on_warning= save_abort_on_warning;
+ thd->m_reprepare_observer= save_reprepare_observer;
thd->stmt_arena= old_arena;
state= EXECUTED;
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2008-03-28 09:28:50 +0000
+++ b/sql/sql_acl.cc 2008-04-19 10:58:37 +0000
@@ -695,6 +695,8 @@
tables[0].next_local= tables[0].next_global= tables+1;
tables[1].next_local= tables[1].next_global= tables+2;
tables[0].lock_type=tables[1].lock_type=tables[2].lock_type=TL_READ;
+ tables[0].skip_temporary= tables[1].skip_temporary=
+ tables[2].skip_temporary= TRUE;
if (simple_open_n_lock_tables(thd, tables))
{
@@ -3537,7 +3539,7 @@
bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
MEM_ROOT **save_mem_root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**,
THR_MALLOC);
- DBUG_ENTER("grant_load");
+ DBUG_ENTER("grant_load_procs_priv");
(void) hash_init(&proc_priv_hash,system_charset_info,
0,0,0, (hash_get_key) get_grant_table,
0,0);
@@ -3721,6 +3723,7 @@
table.alias= table.table_name= (char*) "procs_priv";
table.db= (char *) "mysql";
table.lock_type= TL_READ;
+ table.skip_temporary= 1;
if (simple_open_n_lock_tables(thd, &table))
{
@@ -3786,7 +3789,7 @@
tables[0].db= tables[1].db= (char *) "mysql";
tables[0].next_local= tables[0].next_global= tables+1;
tables[0].lock_type= tables[1].lock_type= TL_READ;
-
+ tables[0].skip_temporary= tables[1].skip_temporary= TRUE;
/*
To avoid deadlocks we should obtain table locks before
obtaining LOCK_grant rwlock.
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc 2008-05-12 17:50:53 +0000
+++ b/sql/sql_base.cc 2008-05-20 07:38:17 +0000
@@ -345,26 +345,9 @@
if (!(share= alloc_table_share(table_list, key, key_length)))
{
-#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
- pthread_mutex_unlock(&LOCK_open);
-#endif
DBUG_RETURN(0);
}
-#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
- // We need a write lock to be able to add a new entry
- pthread_mutex_unlock(&LOCK_open);
- pthread_mutex_lock(&LOCK_open);
- /* Check that another thread didn't insert the same table in between */
- if ((old_share= hash_search(&table_def_cache, (uchar*) key, key_length)))
- {
- (void) pthread_mutex_lock(&share->mutex);
- free_table_share(share);
- share= old_share;
- goto found;
- }
-#endif
-
/*
Lock mutex to be able to read table definition from file without
conflicts
@@ -388,29 +371,11 @@
if (my_hash_insert(&table_def_cache, (uchar*) share))
{
-#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
- pthread_mutex_unlock(&LOCK_open);
- (void) pthread_mutex_unlock(&share->mutex);
-#endif
free_table_share(share);
DBUG_RETURN(0); // return error
}
-#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
- pthread_mutex_unlock(&LOCK_open);
-#endif
if (open_table_def(thd, share, db_flags))
{
-#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
- /*
- No such table or wrong table definition file
- Lock first the table cache and then the mutex.
- This will ensure that no other thread is using the share
- structure.
- */
- (void) pthread_mutex_unlock(&share->mutex);
- (void) pthread_mutex_lock(&LOCK_open);
- (void) pthread_mutex_lock(&share->mutex);
-#endif
*error= share->error;
(void) hash_delete(&table_def_cache, (uchar*) share);
DBUG_RETURN(0);
@@ -429,9 +394,6 @@
/* We must do a lock to ensure that the structure is initialized */
(void) pthread_mutex_lock(&share->mutex);
-#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
- pthread_mutex_unlock(&LOCK_open);
-#endif
if (share->error)
{
/* Table definition contained an error */
@@ -618,52 +580,6 @@
}
pthread_mutex_unlock(&share->mutex);
DBUG_VOID_RETURN;
-
-
-#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
- if (to_be_deleted)
- {
- /*
- We must try again with new locks as we must get LOCK_open
- before share->mutex
- */
- pthread_mutex_unlock(&share->mutex);
- pthread_mutex_lock(&LOCK_open);
- pthread_mutex_lock(&share->mutex);
- if (!share->ref_count)
- { // No one is using this now
- TABLE_SHARE *name_lock;
- if (share->replace_with_name_lock && (name_lock=get_name_lock(share)))
- {
- /*
- This code is execured when someone does FLUSH TABLES while on has
- locked tables.
- */
- (void) hash_search(&def_cache,(uchar*) key,key_length);
- hash_replace(&def_cache, def_cache.current_record,(uchar*) name_lock);
- }
- else
- {
- /* Remove table definition */
- hash_delete(&def_cache,(uchar*) share);
- }
- pthread_mutex_unlock(&LOCK_open);
- free_table_share(share);
- }
- else
- {
- pthread_mutex_unlock(&LOCK_open);
- if (type == RELEASE_WAIT_FOR_DROP)
- wait_for_table(share, "Waiting for close");
- else
- pthread_mutex_unlock(&share->mutex);
- }
- }
- else if (type == RELEASE_WAIT_FOR_DROP)
- wait_for_table(share, "Waiting for close");
- else
- pthread_mutex_unlock(&share->mutex);
-#endif
}
@@ -3801,6 +3717,73 @@
DBUG_VOID_RETURN;
}
+
+/**
+ Compare metadata versions of an element obtained from the table
+ definition cache and its corresponding node in the parse tree.
+
+ @details If the new and the old values mismatch, invoke
+ Metadata_version_observer.
+ At prepared statement prepare, all TABLE_LIST version values are
+ NULL and we always have a mismatch. But there is no observer set
+ in THD, and therefore no error is reported. Instead, we update
+ the value in the parse tree, effectively recording the original
+ version.
+ At prepared statement execute, an observer may be installed. If
+ there is a version mismatch, we push an error and return TRUE.
+
+ For conventional execution (no prepared statements), the
+ observer is never installed.
+
+ @sa Execute_observer
+ @sa check_prepared_statement() to see cases when an observer is installed
+ @sa TABLE_LIST::is_table_ref_id_equal()
+ @sa TABLE_SHARE::get_table_ref_id()
+
+ @param[in] thd used to report errors
+ @param[in,out] tables TABLE_LIST instance created by the parser
+ Metadata version information in this object
+ is updated upon success.
+ @param[in] table_share an element from the table definition cache
+
+ @retval TRUE an error, which has been reported
+ @retval FALSE success, version in TABLE_LIST has been updated
+*/
+
+bool
+check_and_update_table_version(THD *thd,
+ TABLE_LIST *tables, TABLE_SHARE *table_share)
+{
+ if (! tables->is_table_ref_id_equal(table_share))
+ {
+ if (thd->m_reprepare_observer &&
+ thd->m_reprepare_observer->report_error(thd))
+ {
+ /*
+ Version of the table share is different from the
+ previous execution of the prepared statement, and it is
+ unacceptable for this SQLCOM. Error has been reported.
+ */
+ DBUG_ASSERT(thd->is_error());
+ return TRUE;
+ }
+ /* Always maintain the latest version and type */
+ tables->set_table_ref_id(table_share);
+ }
+
+#ifndef DBUG_OFF
+ /* Spuriously reprepare each statement. */
+ if (_db_strict_keyword_("reprepare_each_statement") &&
+ thd->m_reprepare_observer && thd->stmt_arena->is_reprepared ==
FALSE)
+ {
+ thd->m_reprepare_observer->report_error(thd);
+ return TRUE;
+ }
+#endif
+
+ return FALSE;
+}
+
/*
Load a table definition from file and open unireg table
@@ -3846,6 +3829,12 @@
if (share->is_view)
{
+ /*
+ This table is a view. Validate its metadata version: in particular,
+ that it was a view when the statement was prepared.
+ */
+ if (check_and_update_table_version(thd, table_list, share))
+ goto err;
if (table_list->i_s_requested_object & OPEN_TABLE_ONLY)
goto err;
@@ -3863,6 +3852,26 @@
release_table_share(share, RELEASE_NORMAL);
DBUG_RETURN((flags & OPEN_VIEW_NO_PARSE)? -1 : 0);
}
+ else if (table_list->view)
+ {
+ /*
+ We're trying to open a table for what was a view.
+ This can only happen during (re-)execution.
+ At prepared statement prepare the view has been opened and
+ merged into the statement parse tree. After that, someone
+ performed a DDL and replaced the view with a base table.
+ Don't try to open the table inside a prepared statement,
+ invalidate it instead.
+
+ Note, the assert below is known to fail inside stored
+ procedures (Bug#27011).
+ */
+ DBUG_ASSERT(thd->m_reprepare_observer);
+ check_and_update_table_version(thd, table_list, share);
+ /* Always an error. */
+ DBUG_ASSERT(thd->is_error());
+ goto err;
+ }
if (table_list->i_s_requested_object & OPEN_VIEW_ONLY)
goto err;
@@ -4464,8 +4473,18 @@
*/
if (tables->schema_table)
{
- if (!mysql_schema_table(thd, thd->lex, tables))
+ /*
+ If this information_schema table is merged into a mergeable
+ view, ignore it for now -- it will be filled when its respective
+ TABLE_LIST is processed. This code works only during re-execution.
+ */
+ if (tables->view)
+ goto process_view_routines;
+ if (!mysql_schema_table(thd, thd->lex, tables) &&
+ !check_and_update_table_version(thd, tables, tables->table->s))
+ {
continue;
+ }
DBUG_RETURN(-1);
}
(*counter)++;
@@ -4613,6 +4632,13 @@
}
tables->table->grant= tables->grant;
+ /* Check and update metadata version of a base table. */
+ if (check_and_update_table_version(thd, tables, tables->table->s))
+ {
+ result= -1;
+ goto err;
+ }
+
/* Attach MERGE children if not locked already. */
DBUG_PRINT("tcache", ("is parent: %d is child: %d",
test(tables->table->child_l),
@@ -4671,7 +4697,11 @@
error happens on a MERGE child, clear the parents TABLE reference.
*/
if (tables->parent_l)
+ {
+ if (tables->parent_l->next_global ==
tables->parent_l->table->child_l)
+ tables->parent_l->next_global=
*tables->parent_l->table->child_last_l;
tables->parent_l->table= NULL;
+ }
tables->table= NULL;
}
DBUG_PRINT("tcache", ("returning: %d", result));
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2008-05-13 15:10:46 +0000
+++ b/sql/sql_class.cc 2008-05-20 07:38:17 +0000
@@ -198,6 +198,19 @@
** Thread specific functions
****************************************************************************/
+/** Push an error to the error stack and return TRUE for now. */
+
+bool
+Reprepare_observer::report_error(THD *thd)
+{
+ my_error(ER_NEED_REPREPARE, MYF(ME_NO_WARNING_FOR_ERROR|ME_NO_SP_HANDLER));
+
+ m_invalidated= TRUE;
+
+ return TRUE;
+}
+
+
Open_tables_state::Open_tables_state(ulong version_arg)
:version(version_arg), state_flags(0U)
{
@@ -2770,7 +2783,8 @@
DBUG_ASSERT(open_tables == 0 && temporary_tables == 0 &&
handler_tables == 0 && derived_tables == 0 &&
lock == 0 && locked_tables == 0 &&
- prelocked_mode == NON_PRELOCKED);
+ prelocked_mode == NON_PRELOCKED &&
+ m_reprepare_observer == NULL);
set_open_tables_state(backup);
DBUG_VOID_RETURN;
}
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2008-05-13 15:10:46 +0000
+++ b/sql/sql_class.h 2008-05-20 07:38:17 +0000
@@ -23,6 +23,51 @@
#include "log.h"
#include "rpl_tblmap.h"
+/**
+ An interface that is used to take an action when
+ the locking module notices that a table version has changed
+ since the last execution. "Table" here may refer to any kind of
+ table -- a base table, a temporary table, a view or an
+ information schema table.
+
+ When we open and lock tables for execution of a prepared
+ statement, we must verify that they did not change
+ since statement prepare. If some table did change, the statement
+ parse tree *may* be no longer valid, e.g. in case it contains
+ optimizations that depend on table metadata.
+
+ This class provides an interface (a method) that is
+ invoked when such a situation takes place.
+ The implementation of the method simply reports an error, but
+ the exact details depend on the nature of the SQL statement.
+
+ At most 1 instance of this class is active at a time, in which
+ case THD::m_reprepare_observer is not NULL.
+
+ @sa check_and_update_table_version() for details of the
+ version tracking algorithm
+
+ @sa Open_tables_state::m_reprepare_observer for the life cycle
+ of metadata observers.
+*/
+
+class Reprepare_observer
+{
+public:
+ /**
+ Check if a change of metadata is OK. In future
+ the signature of this method may be extended to accept the old
+ and the new versions, but since currently the check is very
+ simple, we only need the THD to report an error.
+ */
+ bool report_error(THD *thd);
+ bool is_invalidated() const { return m_invalidated; }
+ void reset_reprepare_observer() { m_invalidated= FALSE; }
+private:
+ bool m_invalidated;
+};
+
+
class Relay_log_info;
class Query_log_event;
@@ -406,6 +451,7 @@
ulong filesort_scan_count;
/* Prepared statements and binary protocol */
ulong com_stmt_prepare;
+ ulong com_stmt_reprepare;
ulong com_stmt_execute;
ulong com_stmt_send_long_data;
ulong com_stmt_fetch;
@@ -436,7 +482,7 @@
/* The following macro is to make init of Query_arena simpler */
#ifndef DBUG_OFF
-#define INIT_ARENA_DBUG_INFO is_backup_arena= 0
+#define INIT_ARENA_DBUG_INFO is_backup_arena= 0; is_reprepared= FALSE;
#else
#define INIT_ARENA_DBUG_INFO
#endif
@@ -452,6 +498,7 @@
MEM_ROOT *mem_root; // Pointer to current memroot
#ifndef DBUG_OFF
bool is_backup_arena; /* True if this arena is used for backup. */
+ bool is_reprepared;
#endif
/*
The states relfects three diffrent life cycles for three
@@ -789,6 +836,20 @@
{
public:
/**
+ As part of class THD, this member is set during execution
+ of a prepared statement. When it is set, it is used
+ by the locking subsystem to report a change in table metadata.
+
+ When Open_tables_state part of THD is reset to open
+ a system or INFORMATION_SCHEMA table, the member is cleared
+ to avoid spurious ER_NEED_REPREPARE errors -- system and
+ INFORMATION_SCHEMA tables are not subject to metadata version
+ tracking.
+ @sa check_and_update_table_version()
+ */
+ Reprepare_observer *m_reprepare_observer;
+
+ /**
List of regular tables in use by this thread. Contains temporary and
base tables that were opened with @see open_tables().
*/
@@ -891,6 +952,7 @@
extra_lock= lock= locked_tables= 0;
prelocked_mode= NON_PRELOCKED;
state_flags= 0U;
+ m_reprepare_observer= NULL;
}
};
@@ -2812,6 +2874,20 @@
#define CF_STATUS_COMMAND 4
#define CF_SHOW_TABLE_COMMAND 8
#define CF_WRITE_LOGS_COMMAND 16
+/**
+ Must be set for SQL statements that may contain
+ Item expressions and/or use joins and tables.
+ Indicates that the parse tree of such statement may
+ contain rule-based optimizations that depend on metadata
+ (i.e. number of columns in a table), and consequently
+ that the statement must be re-prepared whenever
+ referenced metadata changes. Must not be set for
+ statements that themselves change metadata, e.g. RENAME,
+ ALTER and other DDL, since otherwise will trigger constant
+ reprepare. Consequently, complex item expressions and
+ joins are currently prohibited in these statements.
+*/
+#define CF_REEXECUTION_FRAGILE 32
/* Functions in sql_class.cc */
=== modified file 'sql/sql_cursor.cc'
--- a/sql/sql_cursor.cc 2008-02-21 01:30:29 +0000
+++ b/sql/sql_cursor.cc 2008-04-17 19:02:01 +0000
@@ -111,7 +111,8 @@
select_result *result; /**< the result object of the caller (PS or SP) */
public:
Materialized_cursor *materialized_cursor;
- Select_materialize(select_result *result_arg) :result(result_arg) {}
+ Select_materialize(select_result *result_arg)
+ :result(result_arg), materialized_cursor(0) {}
virtual bool send_fields(List<Item> &list, uint flags);
};
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2008-05-09 07:43:02 +0000
+++ b/sql/sql_parse.cc 2008-05-20 16:36:26 +0000
@@ -200,45 +200,56 @@
{
bzero((uchar*) &sql_command_flags, sizeof(sql_command_flags));
- sql_command_flags[SQLCOM_CREATE_TABLE]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_CREATE_TABLE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND;
sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND;
sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA;
- sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
sql_command_flags[SQLCOM_CREATE_DB]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_DROP_DB]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_RENAME_TABLE]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_BACKUP_TABLE]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_RESTORE_TABLE]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA;
- sql_command_flags[SQLCOM_CREATE_VIEW]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_CREATE_VIEW]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
sql_command_flags[SQLCOM_DROP_VIEW]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_CREATE_EVENT]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_ALTER_EVENT]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_DROP_EVENT]= CF_CHANGES_DATA;
- sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
- sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
- sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
- sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
- sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
- sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
- sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
- sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+ sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
+ CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
+ CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
+ CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
+ CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
+ CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
+ CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
+ CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
+ CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_SELECT]= CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_SET_OPTION]= CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_DO]= CF_REEXECUTION_FRAGILE;
- sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND;
- sql_command_flags[SQLCOM_SHOW_STATUS]= CF_STATUS_COMMAND;
- sql_command_flags[SQLCOM_SHOW_DATABASES]= CF_STATUS_COMMAND;
- sql_command_flags[SQLCOM_SHOW_TRIGGERS]= CF_STATUS_COMMAND;
- sql_command_flags[SQLCOM_SHOW_EVENTS]= CF_STATUS_COMMAND;
- sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND;
+ sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_SHOW_STATUS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_SHOW_DATABASES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_SHOW_TRIGGERS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_SHOW_EVENTS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
sql_command_flags[SQLCOM_SHOW_PLUGINS]= CF_STATUS_COMMAND;
- sql_command_flags[SQLCOM_SHOW_FIELDS]= CF_STATUS_COMMAND;
- sql_command_flags[SQLCOM_SHOW_KEYS]= CF_STATUS_COMMAND;
- sql_command_flags[SQLCOM_SHOW_VARIABLES]= CF_STATUS_COMMAND;
- sql_command_flags[SQLCOM_SHOW_CHARSETS]= CF_STATUS_COMMAND;
- sql_command_flags[SQLCOM_SHOW_COLLATIONS]= CF_STATUS_COMMAND;
+ sql_command_flags[SQLCOM_SHOW_FIELDS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_SHOW_KEYS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_SHOW_VARIABLES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_SHOW_CHARSETS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_SHOW_COLLATIONS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
sql_command_flags[SQLCOM_SHOW_NEW_MASTER]= CF_STATUS_COMMAND;
sql_command_flags[SQLCOM_SHOW_BINLOGS]= CF_STATUS_COMMAND;
sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS]= CF_STATUS_COMMAND;
@@ -262,7 +273,7 @@
sql_command_flags[SQLCOM_SHOW_CREATE_PROC]= CF_STATUS_COMMAND;
sql_command_flags[SQLCOM_SHOW_CREATE_FUNC]= CF_STATUS_COMMAND;
sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER]= CF_STATUS_COMMAND;
- sql_command_flags[SQLCOM_SHOW_STATUS_FUNC]= CF_STATUS_COMMAND;
+ sql_command_flags[SQLCOM_SHOW_STATUS_FUNC]= CF_STATUS_COMMAND |
CF_REEXECUTION_FRAGILE;
sql_command_flags[SQLCOM_SHOW_PROC_CODE]= CF_STATUS_COMMAND;
sql_command_flags[SQLCOM_SHOW_FUNC_CODE]= CF_STATUS_COMMAND;
sql_command_flags[SQLCOM_SHOW_CREATE_EVENT]= CF_STATUS_COMMAND;
@@ -270,9 +281,11 @@
sql_command_flags[SQLCOM_SHOW_PROFILE]= CF_STATUS_COMMAND;
sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND |
- CF_SHOW_TABLE_COMMAND);
+ CF_SHOW_TABLE_COMMAND |
+ CF_REEXECUTION_FRAGILE);
sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
- CF_SHOW_TABLE_COMMAND);
+ CF_SHOW_TABLE_COMMAND |
+ CF_REEXECUTION_FRAGILE);
/*
The following is used to preserver CF_ROW_COUNT during the
@@ -280,7 +293,7 @@
last called (or executed) statement is preserved.
See mysql_execute_command() for how CF_ROW_COUNT is used.
*/
- sql_command_flags[SQLCOM_CALL]= CF_HAS_ROW_COUNT;
+ sql_command_flags[SQLCOM_CALL]= CF_HAS_ROW_COUNT | CF_REEXECUTION_FRAGILE;
sql_command_flags[SQLCOM_EXECUTE]= CF_HAS_ROW_COUNT;
/*
@@ -901,8 +914,11 @@
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
VOID(pthread_mutex_unlock(&LOCK_thread_count));
- thd->server_status&=
- ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
+ /**
+ Clear the set of flags that are expected to be cleared at the
+ beginning of each command.
+ */
+ thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
switch (command) {
case COM_INIT_DB:
{
@@ -4315,20 +4331,6 @@
}
break;
}
-#ifdef NOT_USED
- case SQLCOM_SHOW_STATUS_PROC:
- {
- res= sp_show_status_routine(thd, TYPE_ENUM_PROCEDURE,
- (lex->wild ? lex->wild->ptr() : NullS));
- break;
- }
- case SQLCOM_SHOW_STATUS_FUNC:
- {
- res= sp_show_status_routine(thd, TYPE_ENUM_FUNCTION,
- (lex->wild ? lex->wild->ptr() : NullS));
- break;
- }
-#endif
#ifndef DBUG_OFF
case SQLCOM_SHOW_PROC_CODE:
case SQLCOM_SHOW_FUNC_CODE:
@@ -5378,9 +5380,11 @@
thd->query_start_used= 0;
thd->is_fatal_error= thd->time_zone_used= 0;
- thd->server_status&= ~ (SERVER_MORE_RESULTS_EXISTS |
- SERVER_QUERY_NO_INDEX_USED |
- SERVER_QUERY_NO_GOOD_INDEX_USED);
+ /*
+ Clear the status flag that are expected to be cleared at the
+ beginning of each SQL statement.
+ */
+ thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
/*
If in autocommit mode and not in a transaction, reset
OPTION_STATUS_NO_TRANS_UPDATE | OPTION_KEEP_LOG to not get warnings
=== modified file 'sql/sql_prepare.cc'
--- a/sql/sql_prepare.cc 2008-03-27 12:07:01 +0000
+++ b/sql/sql_prepare.cc 2008-05-20 16:36:26 +0000
@@ -155,21 +155,28 @@
virtual void cleanup_stmt();
bool set_name(LEX_STRING *name);
inline void close_cursor() { delete cursor; cursor= 0; }
-
+ inline bool is_in_use() { return flags & (uint) IS_IN_USE; }
+ inline bool is_protocol_text() const { return protocol == &thd->protocol_text; }
bool prepare(const char *packet, uint packet_length);
- bool execute(String *expanded_query, bool open_cursor);
+ bool execute_loop(String *expanded_query,
+ bool open_cursor,
+ uchar *packet_arg, uchar *packet_end_arg);
/* Destroy this statement */
- bool deallocate();
+ void deallocate();
private:
/**
- Store the parsed tree of a prepared statement here.
- */
- LEX main_lex;
- /**
The memory root to allocate parsed tree elements (instances of Item,
SELECT_LEX and other classes).
*/
MEM_ROOT main_mem_root;
+private:
+ bool set_db(const char *db, uint db_length);
+ bool set_parameters(String *expanded_query,
+ uchar *packet, uchar *packet_end);
+ bool execute(String *expanded_query, bool open_cursor);
+ bool reprepare();
+ bool validate_metadata(Prepared_statement *copy);
+ void swap_prepared_statement(Prepared_statement *copy);
};
@@ -198,7 +205,7 @@
*/
static Prepared_statement *
-find_prepared_statement(THD *thd, ulong id, const char *where)
+find_prepared_statement(THD *thd, ulong id)
{
/*
To strictly separate namespaces of SQL prepared statements and C API
@@ -208,12 +215,8 @@
Statement *stmt= thd->stmt_map.find(id);
if (stmt == 0 || stmt->type() != Query_arena::PREPARED_STATEMENT)
- {
- char llbuf[22];
- my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf), llstr(id, llbuf),
- where);
- return 0;
- }
+ return NULL;
+
return (Prepared_statement *) stmt;
}
@@ -945,6 +948,55 @@
#endif /*!EMBEDDED_LIBRARY*/
+/**
+ Setup data conversion routines using an array of parameter
+ markers from the original prepared statement.
+ Swap the parameter data of the original prepared
+ statement to the new one.
+
+ Used only when we re-prepare a prepared statement.
+ There are two reasons for this function to exist:
+
+ 1) In the binary client/server protocol, parameter metadata
+ is sent only at first execute. Consequently, if we need to
+ reprepare a prepared statement at a subsequent execution,
+ we may not have metadata information in the packet.
+ In that case we use the parameter array of the original
+ prepared statement to setup parameter types of the new
+ prepared statement.
+
+ 2) In the binary client/server protocol, we may supply
+ long data in pieces. When the last piece is supplied,
+ we assemble the pieces and convert them from client
+ character set to the connection character set. After
+ that the parameter value is only available inside
+ the parameter, the original pieces are lost, and thus
+ we can only assign the corresponding parameter of the
+ reprepared statement from the original value.
+
+ @param[out] param_array_dst parameter markers of the new statement
+ @param[in] param_array_src parameter markers of the original
+ statement
+ @param[in] param_count total number of parameters. Is the
+ same in src and dst arrays, since
+ the statement query is the same
+
+ @return this function never fails
+*/
+
+static void
+swap_parameter_array(Item_param **param_array_dst,
+ Item_param **param_array_src,
+ uint param_count)
+{
+ Item_param **dst= param_array_dst;
+ Item_param **src= param_array_src;
+ Item_param **end= param_array_dst + param_count;
+
+ for (; dst < end; ++src, ++dst)
+ (*dst)->set_param_type_and_swap_value(*src);
+}
+
/**
Assign prepared statement parameters from user variables.
@@ -1268,7 +1320,7 @@
*/
static int mysql_test_select(Prepared_statement *stmt,
- TABLE_LIST *tables, bool text_protocol)
+ TABLE_LIST *tables)
{
THD *thd= stmt->thd;
LEX *lex= stmt->lex;
@@ -1304,7 +1356,7 @@
*/
if (unit->prepare(thd, 0, 0))
goto error;
- if (!lex->describe && !text_protocol)
+ if (!lex->describe && !stmt->is_protocol_text())
{
/* Make copy of item list, as change_columns may change it */
List<Item> fields(lex->select_lex.item_list);
@@ -1396,6 +1448,43 @@
/**
+ Validate and prepare for execution CALL statement expressions.
+
+ @param stmt prepared statement
+ @param tables list of tables used in this query
+ @param value_list list of expressions
+
+ @retval FALSE success
+ @retval TRUE error, error message is set in THD
+*/
+
+static bool mysql_test_call_fields(Prepared_statement *stmt,
+ TABLE_LIST *tables,
+ List<Item> *value_list)
+{
+ DBUG_ENTER("mysql_test_call_fields");
+
+ List_iterator<Item> it(*value_list);
+ THD *thd= stmt->thd;
+ Item *item;
+
+ if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE) ||
+ open_normal_and_derived_tables(thd, tables, 0))
+ goto err;
+
+ while ((item= it++))
+ {
+ if (!item->fixed && item->fix_fields(thd, it.ref()) ||
+ item->check_cols(1))
+ goto err;
+ }
+ DBUG_RETURN(FALSE);
+err:
+ DBUG_RETURN(TRUE);
+}
+
+
+/**
Check internal SELECT of the prepared command.
@param stmt prepared statement
@@ -1516,6 +1605,17 @@
res= select_like_stmt_test(stmt, 0, 0);
}
+ else if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE)
+ {
+ /*
+ Check that the source table exist, and also record
+ its metadata version. Even though not strictly necessary,
+ we validate metadata of all CREATE TABLE statements,
+ which keeps metadata validation code simple.
+ */
+ if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0))
+ DBUG_RETURN(TRUE);
+ }
/* put tables back for PS rexecuting */
lex->link_first_table_back(create_table, link_to_local);
@@ -1712,8 +1812,7 @@
TRUE error, error message is set in THD (but not sent)
*/
-static bool check_prepared_statement(Prepared_statement *stmt,
- bool text_protocol)
+static bool check_prepared_statement(Prepared_statement *stmt)
{
THD *thd= stmt->thd;
LEX *lex= stmt->lex;
@@ -1754,9 +1853,23 @@
case SQLCOM_DELETE:
res= mysql_test_delete(stmt, tables);
break;
-
+ /* The following allow WHERE clause, so they must be tested like SELECT */
+ case SQLCOM_SHOW_DATABASES:
+ case SQLCOM_SHOW_TABLES:
+ case SQLCOM_SHOW_TRIGGERS:
+ case SQLCOM_SHOW_EVENTS:
+ case SQLCOM_SHOW_OPEN_TABLES:
+ case SQLCOM_SHOW_FIELDS:
+ case SQLCOM_SHOW_KEYS:
+ case SQLCOM_SHOW_COLLATIONS:
+ case SQLCOM_SHOW_CHARSETS:
+ case SQLCOM_SHOW_VARIABLES:
+ case SQLCOM_SHOW_STATUS:
+ case SQLCOM_SHOW_TABLE_STATUS:
+ case SQLCOM_SHOW_STATUS_PROC:
+ case SQLCOM_SHOW_STATUS_FUNC:
case SQLCOM_SELECT:
- res= mysql_test_select(stmt, tables, text_protocol);
+ res= mysql_test_select(stmt, tables);
if (res == 2)
{
/* Statement and field info has already been sent */
@@ -1779,6 +1892,9 @@
res= mysql_test_do_fields(stmt, tables, lex->insert_list);
break;
+ case SQLCOM_CALL:
+ res= mysql_test_call_fields(stmt, tables, &lex->value_list);
+ break;
case SQLCOM_SET_OPTION:
res= mysql_test_set_fields(stmt, tables, &lex->var_list);
break;
@@ -1828,7 +1944,6 @@
case SQLCOM_DROP_INDEX:
case SQLCOM_ROLLBACK:
case SQLCOM_TRUNCATE:
- case SQLCOM_CALL:
case SQLCOM_DROP_VIEW:
case SQLCOM_REPAIR:
case SQLCOM_ANALYZE:
@@ -1871,8 +1986,8 @@
break;
}
if (res == 0)
- DBUG_RETURN(text_protocol? FALSE : (send_prep_stmt(stmt, 0) ||
- thd->protocol->flush()));
+ DBUG_RETURN(stmt->is_protocol_text() ?
+ FALSE : (send_prep_stmt(stmt, 0) || thd->protocol->flush()));
error:
DBUG_RETURN(TRUE);
}
@@ -2121,8 +2236,13 @@
If there is a statement with the same name, remove it. It is ok to
remove old and fail to insert a new one at the same time.
*/
- if (stmt->deallocate())
+ if (stmt->is_in_use())
+ {
+ my_error(ER_PS_NO_RECURSION, MYF(0));
DBUG_VOID_RETURN;
+ }
+
+ stmt->deallocate();
}
if (! (query= get_dynamic_sql_string(lex, &query_len)) ||
@@ -2308,11 +2428,9 @@
ulong flags= (ulong) packet[4];
/* Query text for binary, general or slow log, if any of them is open */
String expanded_query;
-#ifndef EMBEDDED_LIBRARY
uchar *packet_end= packet + packet_length;
-#endif
Prepared_statement *stmt;
- bool error;
+ bool open_cursor;
DBUG_ENTER("mysql_stmt_execute");
packet+= 9; /* stmt_id + 5 bytes of flags */
@@ -2320,8 +2438,13 @@
/* First of all clear possible warnings from the previous command */
mysql_reset_thd_for_next_command(thd);
- if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute")))
+ if (!(stmt= find_prepared_statement(thd, stmt_id)))
+ {
+ char llbuf[22];
+ my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
+ llstr(stmt_id, llbuf), "mysql_stmt_execute");
DBUG_VOID_RETURN;
+ }
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
thd->profiling.set_query_source(stmt->query, stmt->query_length);
@@ -2332,44 +2455,12 @@
sp_cache_flush_obsolete(&thd->sp_proc_cache);
sp_cache_flush_obsolete(&thd->sp_func_cache);
-#ifndef EMBEDDED_LIBRARY
- if (stmt->param_count)
- {
- uchar *null_array= packet;
- if (setup_conversion_functions(stmt, &packet, packet_end) ||
- stmt->set_params(stmt, null_array, packet, packet_end,
- &expanded_query))
- goto set_params_data_err;
- }
-#else
- /*
- In embedded library we re-install conversion routines each time
- we set params, and also we don't need to parse packet.
- So we do it in one function.
- */
- if (stmt->param_count && stmt->set_params_data(stmt,
&expanded_query))
- goto set_params_data_err;
-#endif
- if (!(specialflag & SPECIAL_NO_PRIOR))
- my_pthread_setprio(pthread_self(),QUERY_PRIOR);
-
- /*
- If the free_list is not empty, we'll wrongly free some externally
- allocated items when cleaning up after validation of the prepared
- statement.
- */
- DBUG_ASSERT(thd->free_list == NULL);
-
- error= stmt->execute(&expanded_query,
- test(flags & (ulong) CURSOR_TYPE_READ_ONLY));
- if (!(specialflag & SPECIAL_NO_PRIOR))
- my_pthread_setprio(pthread_self(), WAIT_PRIOR);
- DBUG_VOID_RETURN;
-
-set_params_data_err:
- my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_execute");
- reset_stmt_params(stmt);
- DBUG_VOID_RETURN;
+ open_cursor= test(flags & (ulong) CURSOR_TYPE_READ_ONLY);
+
+ stmt->execute_loop(&expanded_query, open_cursor, packet, packet_end);
+
+ DBUG_VOID_RETURN;
+
}
@@ -2415,24 +2506,8 @@
DBUG_PRINT("info",("stmt: 0x%lx", (long) stmt));
- /*
- If the free_list is not empty, we'll wrongly free some externally
- allocated items when cleaning up after validation of the prepared
- statement.
- */
- DBUG_ASSERT(thd->free_list == NULL);
-
- if (stmt->set_params_from_vars(stmt, lex->prepared_stmt_params,
- &expanded_query))
- goto set_params_data_err;
-
- (void) stmt->execute(&expanded_query, FALSE);
-
- DBUG_VOID_RETURN;
-
-set_params_data_err:
- my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE");
- reset_stmt_params(stmt);
+ (void) stmt->execute_loop(&expanded_query, FALSE, NULL, NULL);
+
DBUG_VOID_RETURN;
}
@@ -2458,8 +2533,13 @@
/* First of all clear possible warnings from the previous command */
mysql_reset_thd_for_next_command(thd);
status_var_increment(thd->status_var.com_stmt_fetch);
- if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_fetch")))
+ if (!(stmt= find_prepared_statement(thd, stmt_id)))
+ {
+ char llbuf[22];
+ my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
+ llstr(stmt_id, llbuf), "mysql_stmt_fetch");
DBUG_VOID_RETURN;
+ }
cursor= stmt->cursor;
if (!cursor)
@@ -2520,8 +2600,13 @@
mysql_reset_thd_for_next_command(thd);
status_var_increment(thd->status_var.com_stmt_reset);
- if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset")))
+ if (!(stmt= find_prepared_statement(thd, stmt_id)))
+ {
+ char llbuf[22];
+ my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
+ llstr(stmt_id, llbuf), "mysql_stmt_reset");
DBUG_VOID_RETURN;
+ }
stmt->close_cursor();
@@ -2557,15 +2642,15 @@
thd->main_da.disable_status();
- if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_close")))
+ if (!(stmt= find_prepared_statement(thd, stmt_id)))
DBUG_VOID_RETURN;
/*
The only way currently a statement can be deallocated when it's
in use is from within Dynamic SQL.
*/
- DBUG_ASSERT(! (stmt->flags & (uint) Prepared_statement::IS_IN_USE));
- (void) stmt->deallocate();
+ DBUG_ASSERT(! stmt->is_in_use());
+ stmt->deallocate();
general_log_print(thd, thd->command, NullS);
DBUG_VOID_RETURN;
@@ -2592,14 +2677,15 @@
name->str));
if (! (stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name)))
- {
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0),
name->length, name->str, "DEALLOCATE PREPARE");
- return;
- }
-
- if (stmt->deallocate() == 0)
+ else if (stmt->is_in_use())
+ my_error(ER_PS_NO_RECURSION, MYF(0));
+ else
+ {
+ stmt->deallocate();
my_ok(thd);
+ }
}
/**
@@ -2633,17 +2719,13 @@
#ifndef EMBEDDED_LIBRARY
/* Minimal size of long data packet is 6 bytes */
if (packet_length < MYSQL_LONG_DATA_HEADER)
- {
- my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_send_long_data");
DBUG_VOID_RETURN;
- }
#endif
stmt_id= uint4korr(packet);
packet+= 4;
- if (!(stmt=find_prepared_statement(thd, stmt_id,
- "mysql_stmt_send_long_data")))
+ if (!(stmt=find_prepared_statement(thd, stmt_id)))
DBUG_VOID_RETURN;
param_number= uint2korr(packet);
@@ -2729,7 +2811,7 @@
****************************************************************************/
Prepared_statement::Prepared_statement(THD *thd_arg, Protocol *protocol_arg)
- :Statement(&main_lex, &main_mem_root,
+ :Statement(NULL, &main_mem_root,
INITIALIZED, ++thd_arg->statement_id_counter),
thd(thd_arg),
result(thd_arg),
@@ -2800,7 +2882,11 @@
like Item_param, don't free everything until free_items()
*/
free_items();
- delete lex->result;
+ if (lex)
+ {
+ delete lex->result;
+ delete (st_lex_local *) lex;
+ }
free_root(&main_mem_root, MYF(0));
DBUG_VOID_RETURN;
}
@@ -2836,6 +2922,34 @@
return name.str == 0;
}
+
+/**
+ Remember the current database.
+
+ We must reset/restore the current database during execution of
+ a prepared statement since it affects execution environment:
+ privileges, @@character_set_database, and other.
+
+ @return Returns an error if out of memory.
+*/
+
+bool
+Prepared_statement::set_db(const char *db_arg, uint db_length_arg)
+{
+ /* Remember the current database. */
+ if (db_arg && db_length_arg)
+ {
+ db= this->strmake(db_arg, db_length_arg);
+ db_length= db_length_arg;
+ }
+ else
+ {
+ db= NULL;
+ db_length= 0;
+ }
+ return db_arg != NULL && db == NULL;
+}
+
/**************************************************************************
Common parts of mysql_[sql]_stmt_prepare, mysql_[sql]_stmt_execute.
Essentially, these functions do all the magic of preparing/executing
@@ -2877,6 +2991,12 @@
*/
status_var_increment(thd->status_var.com_stmt_prepare);
+ if (! (lex= new (mem_root) st_lex_local))
+ DBUG_RETURN(TRUE);
+
+ if (set_db(thd->db, thd->db_length))
+ DBUG_RETURN(TRUE);
+
/*
alloc_query() uses thd->memroot && thd->query, so we should call
both of backup_statement() and backup_query_arena() here.
@@ -2904,19 +3024,6 @@
lex->set_trg_event_type_for_tables();
- /* Remember the current database. */
-
- if (thd->db && thd->db_length)
- {
- db= this->strmake(thd->db, thd->db_length);
- db_length= thd->db_length;
- }
- else
- {
- db= NULL;
- db_length= 0;
- }
-
/*
While doing context analysis of the query (in check_prepared_statement)
we allocate a lot of additional memory: for open tables, JOINs, derived
@@ -2940,7 +3047,7 @@
*/
if (error == 0)
- error= check_prepared_statement(this, name.str != 0);
+ error= check_prepared_statement(this);
/*
Currently CREATE PROCEDURE/TRIGGER/EVENT are prohibited in prepared
@@ -2987,6 +3094,305 @@
DBUG_RETURN(error);
}
+
+/**
+ Assign parameter values either from variables, in case of SQL PS
+ or from the execute packet.
+
+ @param expanded_query a container with the original SQL statement.
+ '?' placeholders will be replaced with
+ their values in case of success.
+ The result is used for logging and replication
+ @param packet pointer to execute packet.
+ NULL in case of SQL PS
+ @param packet_end end of the packet. NULL in case of SQL PS
+
+ @todo Use a paremeter source class family instead of 'if's, and
+ support stored procedure variables.
+
+ @retval TRUE an error occurred when assigning a parameter (likely
+ a conversion error or out of memory, or malformed packet)
+ @retval FALSE success
+*/
+
+bool
+Prepared_statement::set_parameters(String *expanded_query,
+ uchar *packet, uchar *packet_end)
+{
+ bool is_sql_ps= packet == NULL;
+ bool res= FALSE;
+
+ if (is_sql_ps)
+ {
+ /* SQL prepared statement */
+ res= set_params_from_vars(this, thd->lex->prepared_stmt_params,
+ expanded_query);
+ }
+ else if (param_count)
+ {
+#ifndef EMBEDDED_LIBRARY
+ uchar *null_array= packet;
+ res= (setup_conversion_functions(this, &packet, packet_end) ||
+ set_params(this, null_array, packet, packet_end, expanded_query));
+#else
+ /*
+ In embedded library we re-install conversion routines each time
+ we set parameters, and also we don't need to parse packet.
+ So we do it in one function.
+ */
+ res= set_params_data(this, expanded_query);
+#endif
+ }
+ if (res)
+ {
+ my_error(ER_WRONG_ARGUMENTS, MYF(0),
+ is_sql_ps ? "EXECUTE" : "mysql_stmt_execute");
+ reset_stmt_params(this);
+ }
+ return res;
+}
+
+
+/**
+ Execute a prepared statement. Re-prepare it a limited number
+ of times if necessary.
+
+ Try to execute a prepared statement. If there is a metadata
+ validation error, prepare a new copy of the prepared statement,
+ swap the old and the new statements, and try again.
+ If there is a validation error again, repeat the above, but
+ perform no more than MAX_REPREPARE_ATTEMPTS.
+
+ @note We have to try several times in a loop since we
+ release metadata locks on tables after prepared statement
+ prepare. Therefore, a DDL statement may sneak in between prepare
+ and execute of a new statement. If this happens repeatedly
+ more than MAX_REPREPARE_ATTEMPTS times, we give up.
+
+ In future we need to be able to keep the metadata locks between
+ prepare and execute, but right now open_and_lock_tables(), as
+ well as close_thread_tables() are buried deep inside
+ execution code (mysql_execute_command()).
+
+ @return TRUE if an error, FALSE if success
+ @retval TRUE either MAX_REPREPARE_ATTEMPTS has been reached,
+ or some general error
+ @retval FALSE successfully executed the statement, perhaps
+ after having reprepared it a few times.
+*/
+
+bool
+Prepared_statement::execute_loop(String *expanded_query,
+ bool open_cursor,
+ uchar *packet,
+ uchar *packet_end)
+{
+ const int MAX_REPREPARE_ATTEMPTS= 3;
+ Reprepare_observer reprepare_observer;
+ bool error;
+ int reprepare_attempt= 0;
+
+ if (set_parameters(expanded_query, packet, packet_end))
+ return TRUE;
+
+reexecute:
+ reprepare_observer.reset_reprepare_observer();
+
+ /*
+ If the free_list is not empty, we'll wrongly free some externally
+ allocated items when cleaning up after validation of the prepared
+ statement.
+ */
+ DBUG_ASSERT(thd->free_list == NULL);
+
+ /*
+ Install the metadata observer. If some metadata version is
+ different from prepare time and an observer is installed,
+ the observer method will be invoked to push an error into
+ the error stack.
+ */
+ if (sql_command_flags[lex->sql_command] &
+ CF_REEXECUTION_FRAGILE)
+ {
+ DBUG_ASSERT(thd->m_reprepare_observer == NULL);
+ thd->m_reprepare_observer = &reprepare_observer;
+ }
+
+ if (!(specialflag & SPECIAL_NO_PRIOR))
+ my_pthread_setprio(pthread_self(),QUERY_PRIOR);
+
+ error= execute(expanded_query, open_cursor) || thd->is_error();
+
+ if (!(specialflag & SPECIAL_NO_PRIOR))
+ my_pthread_setprio(pthread_self(), WAIT_PRIOR);
+
+ thd->m_reprepare_observer= NULL;
+
+ if (error && !thd->is_fatal_error && !thd->killed &&
+ reprepare_observer.is_invalidated() &&
+ reprepare_attempt++ < MAX_REPREPARE_ATTEMPTS)
+ {
+ DBUG_ASSERT(thd->main_da.sql_errno() == ER_NEED_REPREPARE);
+ thd->clear_error();
+
+ error= reprepare();
+
+ if (! error) /* Success */
+ goto reexecute;
+ }
+ reset_stmt_params(this);
+
+ return error;
+}
+
+
+/**
+ Reprepare this prepared statement.
+
+ Currently this is implemented by creating a new prepared
+ statement, preparing it with the original query and then
+ swapping the new statement and the original one.
+
+ @retval TRUE an error occurred. Possible errors include
+ incompatibility of new and old result set
+ metadata
+ @retval FALSE success, the statement has been reprepared
+*/
+
+bool
+Prepared_statement::reprepare()
+{
+ 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) };
+ LEX_STRING stmt_db_name= { db, db_length };
+ bool cur_db_changed;
+ bool error;
+
+ Prepared_statement copy(thd, &thd->protocol_text);
+
+ status_var_increment(thd->status_var.com_stmt_reprepare);
+
+ if (mysql_opt_change_db(thd, &stmt_db_name, &saved_cur_db_name, TRUE,
+ &cur_db_changed))
+ return TRUE;
+
+ error= (name.str && copy.set_name(&name) ||
+ copy.prepare(query, query_length) ||
+ validate_metadata(©));
+
+ if (cur_db_changed)
+ mysql_change_db(thd, &saved_cur_db_name, TRUE);
+
+ if (! error)
+ {
+ swap_prepared_statement(©);
+ swap_parameter_array(param_array, copy.param_array, param_count);
+#ifndef DBUG_OFF
+ is_reprepared= TRUE;
+#endif
+ /*
+ Clear possible warnings during reprepare, it has to be completely
+ transparent to the user. We use mysql_reset_errors() since
+ there were no separate query id issued for re-prepare.
+ Sic: we can't simply silence warnings during reprepare, because if
+ it's failed, we need to return all the warnings to the user.
+ */
+ mysql_reset_errors(thd, TRUE);
+ }
+ return error;
+}
+
+
+/**
+ Validate statement result set metadata (if the statement returns
+ a result set).
+
+ Currently we only check that the number of columns of the result
+ set did not change.
+ This is a helper method used during re-prepare.
+
+ @param[in] copy the re-prepared prepared statement to verify
+ the metadata of
+
+ @retval TRUE error, ER_PS_REBIND is reported
+ @retval FALSE statement return no or compatible metadata
+*/
+
+
+bool Prepared_statement::validate_metadata(Prepared_statement *copy)
+{
+ /**
+ If this is an SQL prepared statement or EXPLAIN,
+ return FALSE -- the metadata of the original SELECT,
+ if any, has not been sent to the client.
+ */
+ if (is_protocol_text() || lex->describe)
+ return FALSE;
+
+ if (lex->select_lex.item_list.elements !=
+ copy->lex->select_lex.item_list.elements)
+ {
+ /** Column counts mismatch, update the client */
+ thd->server_status|= SERVER_STATUS_METADATA_CHANGED;
+ }
+
+ return FALSE;
+}
+
+
+/**
+ Replace the original prepared statement with a prepared copy.
+
+ This is a private helper that is used as part of statement
+ reprepare
+
+ @return This function does not return any errors.
+*/
+
+void
+Prepared_statement::swap_prepared_statement(Prepared_statement *copy)
+{
+ Statement tmp_stmt;
+
+ /* Swap memory roots. */
+ swap_variables(MEM_ROOT, main_mem_root, copy->main_mem_root);
+
+ /* Swap the arenas */
+ tmp_stmt.set_query_arena(this);
+ set_query_arena(copy);
+ copy->set_query_arena(&tmp_stmt);
+
+ /* Swap the statement parent classes */
+ tmp_stmt.set_statement(this);
+ set_statement(copy);
+ copy->set_statement(&tmp_stmt);
+
+ /* Swap ids back, we need the original id */
+ swap_variables(ulong, id, copy->id);
+ /* Swap mem_roots back, they must continue pointing at the main_mem_roots */
+ swap_variables(MEM_ROOT *, mem_root, copy->mem_root);
+ /*
+ Swap the old and the new parameters array. The old array
+ is allocated in the old arena.
+ */
+ swap_variables(Item_param **, param_array, copy->param_array);
+ /* Swap flags: this is perhaps unnecessary */
+ swap_variables(uint, flags, copy->flags);
+ /* Swap names, the old name is allocated in the wrong memory root */
+ swap_variables(LEX_STRING, name, copy->name);
+ /* Ditto */
+ swap_variables(char *, db, copy->db);
+
+ DBUG_ASSERT(db_length == copy->db_length);
+ DBUG_ASSERT(param_count == copy->param_count);
+ DBUG_ASSERT(thd == copy->thd);
+ last_error[0]= '\0';
+ last_errno= 0;
+ /* Do not swap protocols, the copy always has protocol_text */
+}
+
+
/**
Execute a prepared statement.
@@ -3149,10 +3555,7 @@
DBUG_ASSERT(! (error && cursor));
if (! cursor)
- {
cleanup_stmt();
- reset_stmt_params(this);
- }
thd->set_statement(&stmt_backup);
thd->stmt_arena= old_stmt_arena;
@@ -3186,16 +3589,10 @@
/** Common part of DEALLOCATE PREPARE and mysql_stmt_close. */
-bool Prepared_statement::deallocate()
+void Prepared_statement::deallocate()
{
/* We account deallocate in the same manner as mysql_stmt_close */
status_var_increment(thd->status_var.com_stmt_close);
- if (flags & (uint) IS_IN_USE)
- {
- my_error(ER_PS_NO_RECURSION, MYF(0));
- return TRUE;
- }
/* Statement map calls delete stmt on erase */
thd->stmt_map.erase(this);
- return FALSE;
}
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2008-05-12 19:37:45 +0000
+++ b/sql/sql_table.cc 2008-05-20 07:38:17 +0000
@@ -4783,9 +4783,6 @@
DBUG_ENTER("mysql_create_like_table");
- /* CREATE TABLE ... LIKE is not allowed for views. */
- src_table->required_type= FRMTYPE_TABLE;
-
/*
By opening source table we guarantee that it exists and no concurrent
DDL operation will mess with it. Later we also take an exclusive
=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc 2008-05-18 09:27:44 +0000
+++ b/sql/sql_update.cc 2008-05-20 07:38:17 +0000
@@ -853,8 +853,9 @@
Item **conds, uint order_num, ORDER *order)
{
Item *fake_conds= 0;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
TABLE *table= table_list->table;
- TABLE_LIST tables;
+#endif
List<Item> all_fields;
SELECT_LEX *select_lex= &thd->lex->select_lex;
DBUG_ENTER("mysql_prepare_update");
@@ -878,9 +879,6 @@
table_list->register_want_access(SELECT_ACL);
#endif
- bzero((char*) &tables,sizeof(tables)); // For ORDER BY
- tables.table= table;
- tables.alias= table_list->alias;
thd->lex->allow_sum_func= 0;
if (setup_tables_and_check_access(thd, &select_lex->context,
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2008-05-13 15:10:46 +0000
+++ b/sql/sql_yacc.yy 2008-05-20 07:38:17 +0000
@@ -3582,20 +3582,30 @@
| LIKE table_ident
{
THD *thd= YYTHD;
+ TABLE_LIST *src_table;
LEX *lex= thd->lex;
lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE;
- if (!lex->select_lex.add_table_to_list(thd, $2, NULL, 0, TL_READ))
+ src_table= lex->select_lex.add_table_to_list(thd, $2, NULL, 0,
+ TL_READ);
+ if (! src_table)
MYSQL_YYABORT;
+ /* CREATE TABLE ... LIKE is not allowed for views. */
+ src_table->required_type= FRMTYPE_TABLE;
}
| '(' LIKE table_ident ')'
{
THD *thd= YYTHD;
+ TABLE_LIST *src_table;
LEX *lex= thd->lex;
lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE;
- if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0, TL_READ))
+ src_table= lex->select_lex.add_table_to_list(thd, $3, NULL, 0,
+ TL_READ);
+ if (! src_table)
MYSQL_YYABORT;
+ /* CREATE TABLE ... LIKE is not allowed for views. */
+ src_table->required_type= FRMTYPE_TABLE;
}
;
=== modified file 'sql/table.h'
--- a/sql/table.h 2008-03-13 21:35:52 +0000
+++ b/sql/table.h 2008-05-20 07:29:16 +0000
@@ -438,6 +438,105 @@
return table_map_id;
}
+ /**
+ Convert unrelated members of TABLE_SHARE to one enum
+ representing its type.
+
+ @todo perhaps we need to have a member instead of a function.
+ */
+ enum enum_table_ref_type get_table_ref_type() const
+ {
+ if (is_view)
+ return TABLE_REF_VIEW;
+ switch (tmp_table) {
+ case NO_TMP_TABLE:
+ return TABLE_REF_BASE_TABLE;
+ case SYSTEM_TMP_TABLE:
+ return TABLE_REF_I_S_TABLE;
+ default:
+ return TABLE_REF_TMP_TABLE;
+ }
+ }
+ /**
+ Return a table metadata version.
+ * for base tables, we return table_map_id.
+ It is assigned from a global counter incremented for each
+ new table loaded into the table definition cache (TDC).
+ * for temporary tables it's table_map_id again. But for
+ temporary tables table_map_id is assigned from
+ thd->query_id. The latter is assigned from a thread local
+ counter incremented for every new SQL statement. Since
+ temporary tables are thread-local, each temporary table
+ gets a unique id.
+ * for everything else (views, information schema tables),
+ the version id is zero.
+
+ This choice of version id is a large compromise
+ to have a working prepared statement validation in 5.1. In
+ future version ids will be persistent, as described in WL#4180.
+
+ Let's try to explain why and how this limited solution allows
+ to validate prepared statements.
+
+ Firstly, sets (in mathematical sense) of version numbers
+ never intersect for different table types. Therefore,
+ version id of a temporary table is never compared with
+ a version id of a view, and vice versa.
+
+ Secondly, for base tables, we know that each DDL flushes the
+ respective share from the TDC. This ensures that whenever
+ a table is altered or dropped and recreated, it gets a new
+ version id.
+ Unfortunately, since elements of the TDC are also flushed on
+ LRU basis, this choice of version ids leads to false positives.
+ E.g. when the TDC size is too small, we may have a SELECT
+ * FROM INFORMATION_SCHEMA.TABLES flush all its elements, which
+ in turn will lead to a validation error and a subsequent
+ reprepare of all prepared statements. This is
+ considered acceptable, since as long as prepared statements are
+ automatically reprepared, spurious invalidation is only
+ a performance hit. Besides, no better simple solution exists.
+
+ For temporary tables, using thd->query_id ensures that if
+ a temporary table was altered or recreated, a new version id is
+ assigned. This suits validation needs very well and will perhaps
+ never change.
+
+ Metadata of information schema tables never changes.
+ Thus we can safely assume 0 for a good enough version id.
+
+ Views are a special and tricky case. A view is always inlined
+ into the parse tree of a prepared statement at prepare.
+ Thus, when we execute a prepared statement, the parse tree
+ will not get modified even if the view is replaced with another
+ view. Therefore, we can safely choose 0 for version id of
+ views and effectively never invalidate a prepared statement
+ when a view definition is altered. Note, that this leads to
+ wrong binary log in statement-based replication, since we log
+ prepared statement execution in form Query_log_events
+ containing conventional statements. But since there is no
+ metadata locking for views, the very same problem exists for
+ conventional statements alone, as reported in Bug#25144. The only
+ difference between prepared and conventional execution is,
+ effectively, that for prepared statements the race condition
+ window is much wider.
+ In 6.0 we plan to support view metadata locking (WL#3726) and
+ extend table definition cache to cache views (WL#4298).
+ When this is done, views will be handled in the same fashion
+ as the base tables.
+
+ Finally, by taking into account table type, we always
+ track that a change has taken place when a view is replaced
+ with a base table, a base table is replaced with a temporary
+ table and so on.
+
+ @sa TABLE_LIST::is_table_ref_id_equal()
+ */
+ ulong get_table_ref_version() const
+ {
+ return (tmp_table == SYSTEM_TMP_TABLE || is_view) ? 0 : table_map_id;
+ }
+
} TABLE_SHARE;
@@ -1233,6 +1332,33 @@
child_def_version= ~0UL;
}
+ /**
+ Compare the version of metadata from the previous execution
+ (if any) with values obtained from the current table
+ definition cache element.
+
+ @sa check_and_update_table_version()
+ */
+ inline
+ bool is_table_ref_id_equal(TABLE_SHARE *s) const
+ {
+ return (m_table_ref_type == s->get_table_ref_type() &&
+ m_table_ref_version == s->get_table_ref_version());
+ }
+
+ /**
+ Record the value of metadata version of the corresponding
+ table definition cache element in this parse tree node.
+
+ @sa check_and_update_table_version()
+ */
+ inline
+ void set_table_ref_id(TABLE_SHARE *s)
+ {
+ m_table_ref_type= s->get_table_ref_type();
+ m_table_ref_version= s->get_table_ref_version();
+ }
+
private:
bool prep_check_option(THD *thd, uint8 check_opt_type);
bool prep_where(THD *thd, Item **conds, bool no_where_clause);
@@ -1243,6 +1369,10 @@
/* Remembered MERGE child def version. See top comment in ha_myisammrg.cc */
ulong child_def_version;
+ /** See comments for set_metadata_id() */
+ enum enum_table_ref_type m_table_ref_type;
+ /** See comments for set_metadata_id() */
+ ulong m_table_ref_version;
};
class Item;
=== modified file 'storage/myisam/mi_create.c'
--- a/storage/myisam/mi_create.c 2007-10-11 15:07:40 +0000
+++ b/storage/myisam/mi_create.c 2008-04-19 10:58:37 +0000
@@ -634,6 +634,7 @@
my_printf_error(0, "MyISAM table '%s' is in use "
"(most likely by a MERGE table). Try FLUSH TABLES.",
MYF(0), name + dirname_length(name));
+ my_errno= HA_ERR_TABLE_EXIST;
goto err;
}
=== modified file 'tests/mysql_client_test.c'
--- a/tests/mysql_client_test.c 2008-03-28 21:08:38 +0000
+++ b/tests/mysql_client_test.c 2008-05-20 18:23:58 +0000
@@ -6668,10 +6668,10 @@
check_execute_r(stmt, rc); /* unsupported buffer type */
rc= mysql_stmt_store_result(stmt);
- check_execute(stmt, rc);
+ DIE_UNLESS(rc);
rc= mysql_stmt_store_result(stmt);
- check_execute_r(stmt, rc); /* commands out of sync */
+ DIE_UNLESS(rc); /* Old error must be reset first */
mysql_stmt_close(stmt);
@@ -8423,6 +8423,9 @@
rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
check_execute_r(stmt, rc);
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
rc= mysql_stmt_bind_result(stmt, my_bind);
check_execute(stmt, rc);
@@ -9901,7 +9904,7 @@
MYSQL_STMT *stmt;
const char *query= "rename table t1 to t2, t3 to t4";
int rc;
- myheader("test_table_manipulation");
+ myheader("test_table_rename");
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4");
myquery(rc);
@@ -11132,7 +11135,7 @@
int rc;
MYSQL_STMT backup;
- myheader("test_bug4296");
+ myheader("test_bug4236");
stmt= mysql_stmt_init(mysql);
@@ -17383,6 +17386,214 @@
DBUG_VOID_RETURN;
}
+static void test_wl4166_1()
+{
+ MYSQL_STMT *stmt;
+ int int_data;
+ char str_data[50];
+ char tiny_data;
+ short small_data;
+ longlong big_data;
+ float real_data;
+ double double_data;
+ ulong length[7];
+ my_bool is_null[7];
+ MYSQL_BIND my_bind[7];
+ int rc;
+ int i;
+
+ myheader("test_wl4166_1");
+
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS table_4166");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "CREATE TABLE table_4166(col1 tinyint NOT NULL, "
+ "col2 varchar(15), col3 int, "
+ "col4 smallint, col5 bigint, "
+ "col6 float, col7 double, "
+ "colX varchar(10) default NULL)");
+ myquery(rc);
+
+ stmt= mysql_simple_prepare(mysql,
+ "INSERT INTO table_4166(col1, col2, col3, col4, col5, col6, col7) "
+ "VALUES(?, ?, ?, ?, ?, ?, ?)");
+ check_stmt(stmt);
+
+ verify_param_count(stmt, 7);
+
+ bzero(my_bind, sizeof(my_bind));
+ /* tinyint */
+ my_bind[0].buffer_type= MYSQL_TYPE_TINY;
+ my_bind[0].buffer= (void *)&tiny_data;
+ /* string */
+ my_bind[1].buffer_type= MYSQL_TYPE_STRING;
+ my_bind[1].buffer= (void *)str_data;
+ my_bind[1].buffer_length= 1000; /* Max string length */
+ /* integer */
+ my_bind[2].buffer_type= MYSQL_TYPE_LONG;
+ my_bind[2].buffer= (void *)&int_data;
+ /* short */
+ my_bind[3].buffer_type= MYSQL_TYPE_SHORT;
+ my_bind[3].buffer= (void *)&small_data;
+ /* bigint */
+ my_bind[4].buffer_type= MYSQL_TYPE_LONGLONG;
+ my_bind[4].buffer= (void *)&big_data;
+ /* float */
+ my_bind[5].buffer_type= MYSQL_TYPE_FLOAT;
+ my_bind[5].buffer= (void *)&real_data;
+ /* double */
+ my_bind[6].buffer_type= MYSQL_TYPE_DOUBLE;
+ my_bind[6].buffer= (void *)&double_data;
+
+ for (i= 0; i < (int) array_elements(my_bind); i++)
+ {
+ my_bind[i].length= &length[i];
+ my_bind[i].is_null= &is_null[i];
+ is_null[i]= 0;
+ }
+
+ rc= mysql_stmt_bind_param(stmt, my_bind);
+ check_execute(stmt, rc);
+
+ int_data= 320;
+ small_data= 1867;
+ big_data= 1000;
+ real_data= 2;
+ double_data= 6578.001;
+
+ /* now, execute the prepared statement to insert 10 records.. */
+ for (tiny_data= 0; tiny_data < 10; tiny_data++)
+ {
+ length[1]= my_sprintf(str_data, (str_data, "MySQL%d", int_data));
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ int_data += 25;
+ small_data += 10;
+ big_data += 100;
+ real_data += 1;
+ double_data += 10.09;
+ }
+
+ /* force a re-prepare with some DDL */
+
+ rc= mysql_query(mysql,
+ "ALTER TABLE table_4166 change colX colX varchar(20) default NULL");
+ myquery(rc);
+
+ /*
+ execute the prepared statement again,
+ without changing the types of parameters already bound.
+ */
+
+ for (tiny_data= 50; tiny_data < 60; tiny_data++)
+ {
+ length[1]= my_sprintf(str_data, (str_data, "MySQL%d", int_data));
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ int_data += 25;
+ small_data += 10;
+ big_data += 100;
+ real_data += 1;
+ double_data += 10.09;
+ }
+
+ mysql_stmt_close(stmt);
+
+ rc= mysql_query(mysql, "DROP TABLE table_4166");
+ myquery(rc);
+}
+
+
+static void test_wl4166_2()
+{
+ MYSQL_STMT *stmt;
+ int c_int;
+ MYSQL_TIME d_date;
+ MYSQL_BIND bind_out[2];
+ int rc;
+
+ myheader("test_wl4166_2");
+
+ rc= mysql_query(mysql, "drop table if exists t1");
+ myquery(rc);
+ rc= mysql_query(mysql, "create table t1 (c_int int, d_date date)");
+ myquery(rc);
+ rc= mysql_query(mysql,
+ "insert into t1 (c_int, d_date) values (42, '1948-05-15')");
+ myquery(rc);
+
+ stmt= mysql_simple_prepare(mysql, "select * from t1");
+ check_stmt(stmt);
+
+ bzero(bind_out, sizeof(bind_out));
+ bind_out[0].buffer_type= MYSQL_TYPE_LONG;
+ bind_out[0].buffer= (void*) &c_int;
+
+ bind_out[1].buffer_type= MYSQL_TYPE_DATE;
+ bind_out[1].buffer= (void*) &d_date;
+
+ rc= mysql_stmt_bind_result(stmt, bind_out);
+ check_execute(stmt, rc);
+
+ /* int -> varchar transition */
+
+ rc= mysql_query(mysql,
+ "alter table t1 change column c_int c_int varchar(11)");
+ myquery(rc);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_fetch(stmt);
+ check_execute(stmt, rc);
+
+ DIE_UNLESS(c_int == 42);
+ DIE_UNLESS(d_date.year == 1948);
+ DIE_UNLESS(d_date.month == 5);
+ DIE_UNLESS(d_date.day == 15);
+
+ rc= mysql_stmt_fetch(stmt);
+ DIE_UNLESS(rc == MYSQL_NO_DATA);
+
+ /* varchar to int retrieval with truncation */
+
+ rc= mysql_query(mysql, "update t1 set c_int='abcde'");
+ myquery(rc);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_fetch(stmt);
+ check_execute_r(stmt, rc);
+
+ DIE_UNLESS(c_int == 0);
+
+ rc= mysql_stmt_fetch(stmt);
+ DIE_UNLESS(rc == MYSQL_NO_DATA);
+
+ /* alter table and increase the number of columns */
+ rc= mysql_query(mysql, "alter table t1 add column d_int int");
+ myquery(rc);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute_r(stmt, rc);
+
+ rc= mysql_stmt_reset(stmt);
+ check_execute(stmt, rc);
+
+ /* decrease the number of columns */
+ rc= mysql_query(mysql, "alter table t1 drop d_date, drop d_int");
+ myquery(rc);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute_r(stmt, rc);
+
+ mysql_stmt_close(stmt);
+ rc= mysql_query(mysql, "drop table t1");
+ myquery(rc);
+
+}
+
/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -17689,6 +17900,8 @@
{ "test_bug31418", test_bug31418 },
{ "test_bug31669", test_bug31669 },
{ "test_bug28386", test_bug28386 },
+ { "test_wl4166_1", test_wl4166_1 },
+ { "test_wl4166_2", test_wl4166_2 },
{ 0, 0 }
};
| Thread |
|---|
| • commit into mysql-5.1 branch (sven:2648) | Sven Sandberg | 26 May |