From 0a6cf80947b69af372937014bf4380f55d5788d6 Mon Sep 17 00:00:00 2001 From: "thek@adventure.(none)" <> Date: Tue, 18 Mar 2008 14:24:52 +0100 Subject: [PATCH 01/16] Bug#32059 thread_id is a long rather than ulong thread_id should be defined as a dword (32 bit unsigned). --- mysys/my_thr_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index c446808c7da..481d72cf3fe 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -223,7 +223,7 @@ void my_thread_global_end(void) #endif } -static long thread_id=0; +static ulong thread_id=0; /* Allocate thread specific memory for the thread, used by mysys and dbug From eb5cdca66fac397d7224f78b1304892914150aa0 Mon Sep 17 00:00:00 2001 From: "thek@adventure.(none)" <> Date: Tue, 25 Mar 2008 12:52:55 +0100 Subject: [PATCH 02/16] Bug#33275 Server crash when creating temporary table mysql.user When creating a temporary table that uses the same name as the mysql privs table the server would crash on FLUSH PRIVILEGES. This patches corrects the problem by setting a flag to ignore any temporary table when trying to reload the privileges. --- mysql-test/r/grant.result | 6 ++++++ mysql-test/t/grant.test | 7 +++++++ sql/sql_acl.cc | 5 ++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index e27ef64af43..8a89a9dc264 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1129,4 +1129,10 @@ DROP USER mysqltest_1@localhost; 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; End of 5.0 tests diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index ed95d90c8f8..93c416133e8 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1153,4 +1153,11 @@ DROP DATABASE db27878; 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; + --echo End of 5.0 tests diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 8fdd054eb39..64b1e699289 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -558,6 +558,8 @@ my_bool acl_reload(THD *thd) 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)) { @@ -3528,7 +3530,8 @@ my_bool grant_reload(THD *thd) 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; /* To avoid deadlocks we should obtain table locks before obtaining LOCK_grant rwlock. From c7b6a0b0068d9f01229882a54da9511d654de28f Mon Sep 17 00:00:00 2001 From: "davi@mysql.com/endora.local" <> Date: Tue, 25 Mar 2008 20:48:20 -0300 Subject: [PATCH 03/16] Post-merge fixes for bug 35103 Don't signal errors for the COM_STMT_SEND_LONG_DATA and COM_STMT_CLOSE commands. --- sql/sql_prepare.cc | 73 +++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index c922b21af90..aea2c806d85 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -155,11 +155,11 @@ public: 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; } bool prepare(const char *packet, uint packet_length); bool execute(String *expanded_query, bool open_cursor); /* Destroy this statement */ - bool deallocate(); + void deallocate(); private: /** Store the parsed tree of a prepared statement here. @@ -198,7 +198,7 @@ inline bool is_param_null(const uchar *pos, ulong param_no) */ 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 +208,8 @@ find_prepared_statement(THD *thd, ulong id, const char *where) 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; } @@ -2121,8 +2117,13 @@ void mysql_sql_stmt_prepare(THD *thd) 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)) || @@ -2320,8 +2321,13 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length) /* 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); @@ -2458,8 +2464,13 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) /* 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 +2531,13 @@ void mysql_stmt_reset(THD *thd, char *packet) 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 +2573,15 @@ void mysql_stmt_close(THD *thd, char *packet) 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 +2608,15 @@ void mysql_sql_stmt_close(THD *thd) 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 +2650,13 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) #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); @@ -3186,16 +3199,10 @@ error: /** 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; } From c3d51823103e0a9ef1dfcbeb815e5b8073f2558d Mon Sep 17 00:00:00 2001 From: "thek@adventure.(none)" <> Date: Wed, 26 Mar 2008 14:03:01 +0100 Subject: [PATCH 04/16] Corrected result-file merge error. --- mysql-test/r/grant.result | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index c157e1d4706..b91f2016a9e 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1218,6 +1218,12 @@ DROP USER mysqltest_1@localhost; 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' From 8010fa87a4e99603009c5490a9acc8bcc345bdef Mon Sep 17 00:00:00 2001 From: "anozdrin/alik@quad.opbmk" <> Date: Thu, 27 Mar 2008 13:42:42 +0300 Subject: [PATCH 05/16] Disable cast.test due to Bug#35594. --- mysql-test/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 9e0b681528b..4e58c30b812 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -21,3 +21,4 @@ ctype_create : Bug#32965 main.ctype_create fails status : Bug#32966 main.status fails 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 +cast : Bug#35594 2008-03-27 main.cast fails on Windows2003-64 From d02459cbae885aea96d88173b55b8efc9a1f5f88 Mon Sep 17 00:00:00 2001 From: "anozdrin/alik@quad.opbmk" <> Date: Fri, 28 Mar 2008 18:10:04 +0300 Subject: [PATCH 06/16] A patch for Bug#34820: log_output can be set to illegal value. We have "set" variables, which can accept empty values (like sql_mode), and which can not (like log_output). The problem was that the code does not distinguish them and allow empty values for every set variable. The fix is to introduce an attribute of a set variable telling whether it can accept empty values. --- mysql-test/r/variables.result | 10 ++++++++++ mysql-test/t/variables.test | 17 +++++++++++++++++ sql/set_var.cc | 25 +++++++++++++++++++++---- sql/set_var.h | 18 +++++++++++++++--- 4 files changed, 63 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index e5c3c860c93..3f66599751d 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -1014,3 +1014,13 @@ Variable_name='table_lock_wait_timeout'; 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. diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 51f8d6db1db..221f46605cd 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -778,3 +778,20 @@ set global thread_cache_size =@my_thread_cache_size; --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. + diff --git a/sql/set_var.cc b/sql/set_var.cc index 46a64b1a87c..6b07d81125a 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1664,6 +1664,14 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names) 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(), @@ -1679,10 +1687,19 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names) 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))) { diff --git a/sql/set_var.h b/sql/set_var.h index b33a3a968bb..c4fc13f1321 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -74,7 +74,8 @@ public: 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 @@ public: 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 @@ public: 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); } From 73345d0fbdffb5f22d3610bcda40b03dad7d62bc Mon Sep 17 00:00:00 2001 From: "anozdrin/alik@quad.opbmk" <> Date: Fri, 28 Mar 2008 21:46:18 +0300 Subject: [PATCH 07/16] Fix for Bug#32748: Inconsistent handling of assignments to general_log_file/slow_query_log_file. The problem was that log file path was rejected if directory path was empty. The fix is to reject log file path only if it is entirely empty. --- mysql-test/r/log_state.result | 21 ++++++++++++++++ mysql-test/t/log_state.test | 28 +++++++++++++++++++++ sql/set_var.cc | 47 ++++++++++++++++++++++++----------- 3 files changed, 82 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/log_state.result b/mysql-test/r/log_state.result index 8ecfe3b2094..c293956148f 100644 --- a/mysql-test/r/log_state.result +++ b/mysql-test/r/log_state.result @@ -249,4 +249,25 @@ set global slow_query_log_file= NULL; 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 diff --git a/mysql-test/t/log_state.test b/mysql-test/t/log_state.test index a340238b724..2fd2cabc97c 100644 --- a/mysql-test/t/log_state.test +++ b/mysql-test/t/log_state.test @@ -231,6 +231,34 @@ set global slow_query_log_file= NULL; 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 diff --git a/sql/set_var.cc b/sql/set_var.cc index 6b07d81125a..e44fdc201ca 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2399,32 +2399,51 @@ static int sys_check_log_path(THD *thd, set_var *var) 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; + + return 0; } - 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; - } + + /* 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: From ad4113f72fe64622c5ad3862ac32bba6041bdd58 Mon Sep 17 00:00:00 2001 From: "kostja@dipika.(none)" <> Date: Mon, 31 Mar 2008 14:52:41 +0400 Subject: [PATCH 08/16] Remove some unused code. --- sql/sql_base.cc | 84 ------------------------------------------------- 1 file changed, 84 deletions(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3f0c1ee8a80..f0faf034027 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -345,26 +345,9 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, 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 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, 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 @@ found: /* 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 @@ void release_table_share(TABLE_SHARE *share, enum release_type type) } 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 } From e392f406f5127c98fb07f596b85e8f1b0ffccc6c Mon Sep 17 00:00:00 2001 From: "thek@adventure.(none)" <> Date: Tue, 1 Apr 2008 14:41:13 +0200 Subject: [PATCH 09/16] Bug#26208 a typo (wrong variable name) in mysql_prepare_update function's source code? This is a code clean up. Removed redundant (and unused) TABLE_LIST variable intended as an IN- parameter for setup_order. --- sql/sql_update.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 23ad5ce9385..fe34301cda0 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -854,7 +854,6 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, { Item *fake_conds= 0; TABLE *table= table_list->table; - TABLE_LIST tables; List all_fields; SELECT_LEX *select_lex= &thd->lex->select_lex; DBUG_ENTER("mysql_prepare_update"); @@ -878,9 +877,6 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, 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, From 15fd42b7ddefbfca92002c295065db51318dbad9 Mon Sep 17 00:00:00 2001 From: "dlenev@mockturtle.local" <> Date: Mon, 7 Apr 2008 12:59:57 +0400 Subject: [PATCH 10/16] Fix for bug #35733 "main.symlink.test fails". The problem was that symlink.test failed due to debug assertions or due to errors emitted for wrong statements (in non-debug builds) if 6.0 version of server was run with --thread-handling=pool-of-threads option. The above problems were caused by that on the one hand code mi_create() which handles case when error is returned relies on my_errno being set to appropriate non-0 value, but on the other it has not done this in case when error was emitted due to discovery that share for table which we are going to create is already present in the list of open shares. Running server with pool-of-threads option just exposed this bug since in this scheduler mode my_errno is reset to 0 when connection (THD) is reattached to the "real" thread. This fix ensures that code in mi_create() properly sets my_errno in the case described above. Since original reason that caused this bug to be exposed in 6.0 tree might also under very special conditions lead to incorrect behavior of earlier versions of server (i.e. to errors emitted for wrong statements) this patch is also being pushed into 5.1 tree. No test case is present as this code is already covered by a test case + pushbuild options combination in 6.0. --- storage/myisam/mi_create.c | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c index 0cac5f08b3b..8bd93faba3a 100644 --- a/storage/myisam/mi_create.c +++ b/storage/myisam/mi_create.c @@ -633,6 +633,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, 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; } From 27b6c17d94e3fe47f12b5d5f6c6d485ad219f3b8 Mon Sep 17 00:00:00 2001 From: "thek@adventure.(none)" <> Date: Mon, 7 Apr 2008 11:29:45 +0200 Subject: [PATCH 11/16] Bug#34183 Missing DBUG_RETURN in alloc_root DBUG_RETURN was missing form an exit path in 5.1 branch of alloc_root --- mysys/my_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index 9203ce9c34e..2607ea57d08 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -202,7 +202,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) { 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; From 968b1a08103d6a19220d8f35773531514a030ddc Mon Sep 17 00:00:00 2001 From: "kostja@dipika.(none)" <> Date: Mon, 7 Apr 2008 13:35:42 +0400 Subject: [PATCH 12/16] Review and update WL#4165 and WL#4166 test coverage. --- mysql-test/r/ps_ddl.result | 4196 +++++++++--------------------------- mysql-test/t/ps_ddl.test | 2204 ++++++++----------- 2 files changed, 1910 insertions(+), 4490 deletions(-) diff --git a/mysql-test/r/ps_ddl.result b/mysql-test/r/ps_ddl.result index 531d29d219e..fe7062716ea 100644 --- a/mysql-test/r/ps_ddl.result +++ b/mysql-test/r/ps_ddl.result @@ -1,543 +1,224 @@ -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; -set @expected = 0; +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; ===================================================================== -Testing 1: NOTHING -> TABLE transitions +Part 1: NOTHING -> TABLE transitions ===================================================================== -drop table if exists t1; -prepare stmt from 'select * from t1'; +prepare stmt from "select * from t1"; ERROR 42S02: Table 'test.t1' doesn't exist ===================================================================== -Testing 2: NOTHING -> TEMPORARY TABLE transitions +Part 2: NOTHING -> TEMPORARY TABLE transitions ===================================================================== ===================================================================== -Testing 3: NOTHING -> VIEW transitions +Part 3: NOTHING -> VIEW transitions ===================================================================== ===================================================================== -Testing 4: TABLE -> NOTHING transitions +Part 4: TABLE -> NOTHING transitions ===================================================================== -drop table if exists t4; -create table t4(a int); -prepare stmt from 'select * from t4'; +create table t1 (a int); +prepare stmt from "select * from t1"; 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 +call p_verify_reprepare_count(0); +SUCCESS + 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; +call p_verify_reprepare_count(0); +SUCCESS + +drop table t1; 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 +ERROR 42S02: Table 'test.t1' doesn't exist +call p_verify_reprepare_count(0); +SUCCESS + 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 +ERROR 42S02: Table 'test.t1' doesn't exist +call p_verify_reprepare_count(0); +SUCCESS + +deallocate prepare stmt; ===================================================================== -Testing 5: TABLE -> TABLE (DDL) transitions +Part 5: TABLE -> TABLE (DDL) transitions ===================================================================== -drop table if exists t5; -create table t5(a int); -prepare stmt from 'select a from t5'; +create table t1 (a int); +prepare stmt from "select a from t1"; 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 +call p_verify_reprepare_count(0); +SUCCESS + 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; +call p_verify_reprepare_count(0); +SUCCESS + +alter table t1 add column (b int); 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 +call p_verify_reprepare_count(1); +SUCCESS + 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; +call p_verify_reprepare_count(0); +SUCCESS + +drop table t1; +deallocate prepare stmt; ===================================================================== -Testing 6: TABLE -> TABLE (TRIGGER) transitions +Part 6: TABLE -> TABLE (TRIGGER) transitions ===================================================================== -drop table if exists t6; -create table t6(a int); -prepare stmt from 'insert into t6(a) value (?)'; +# 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"; -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(1); +SUCCESS + select @message; @message -t6_bi +2 +set @val=3; +execute stmt using @val; +call p_verify_reprepare_count(0); +SUCCESS + +select @message; +@message +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 +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 +call p_verify_reprepare_count(0); +SUCCESS + 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; +new trigger: 11 +select * from t1 order by a; a 1 2 @@ -553,1443 +234,747 @@ a 12 13 14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -drop table t6; +drop table t1; +deallocate prepare stmt; ===================================================================== -Testing 7: TABLE -> TABLE (TRIGGER dependencies) transitions +Part 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; +# 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; ===================================================================== -Testing 8: TABLE -> TEMPORARY TABLE transitions +Part 8: TABLE -> TEMPORARY TABLE transitions ===================================================================== -drop table if exists t8; -create table t8(a int); -prepare stmt from 'select * from t8'; +create table t1 (a int); +prepare stmt from "select * from t1"; 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 t1; +create temporary table t1 (a int); 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; +call p_verify_reprepare_count(1); +SUCCESS + 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; +call p_verify_reprepare_count(0); +SUCCESS + +drop table t1; +deallocate prepare stmt; ===================================================================== -Testing 9: TABLE -> VIEW transitions +Part 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'; +create table t1 (a int); +prepare stmt from "select * from t1"; 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 +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 -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; +call p_verify_reprepare_count(1); +SUCCESS + +drop view t1; +drop table t2; +deallocate prepare stmt; ===================================================================== -Testing 10: TEMPORARY TABLE -> NOTHING transitions +Part 10: TEMPORARY TABLE -> NOTHING transitions ===================================================================== -drop temporary table if exists t10; -create temporary table t10(a int); -prepare stmt from 'select * from t10'; +create temporary table t1 (a int); +prepare stmt from "select * from t1"; 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 +call p_verify_reprepare_count(0); +SUCCESS + +drop temporary table t1; 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 +ERROR 42S02: Table 'test.t1' doesn't exist +call p_verify_reprepare_count(0); +SUCCESS + +deallocate prepare stmt; ===================================================================== -Testing 11: TEMPORARY TABLE -> TABLE transitions +Part 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'; +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 -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; +call p_verify_reprepare_count(0); +SUCCESS + +drop temporary table t1; 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; +call p_verify_reprepare_count(1); +SUCCESS + +select * from t1; 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; +drop table t1; +deallocate prepare stmt; ===================================================================== -Testing 12: TEMPORARY TABLE -> TEMPORARY TABLE (DDL) transitions +Part 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'; +create temporary table t1 (a int); +prepare stmt from "select a from t1"; 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 +call p_verify_reprepare_count(0); +SUCCESS + +drop temporary table t1; +create temporary table t1 (a int, b int); 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; +call p_verify_reprepare_count(1); +SUCCESS + +select * from t1; a b -drop table t12; +drop temporary table t1; +deallocate prepare stmt; ===================================================================== -Testing 13: TEMPORARY TABLE -> VIEW transitions +Part 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'; +create temporary table t1 (a int); +create table t2 (a int); +prepare stmt from "select * from t1"; 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 +call p_verify_reprepare_count(0); +SUCCESS + +drop temporary table t1; +create view t1 as select * from t2; 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; +call p_verify_reprepare_count(1); +SUCCESS + +drop view t1; +drop table t2; +deallocate prepare stmt; ===================================================================== -Testing 14: VIEW -> NOTHING transitions +Part 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'; +create table t2 (a int); +create view t1 as select * from t2; +prepare stmt from "select * from t1"; 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 t1; 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; +ERROR 42S02: Table 'test.t1' doesn't exist +call p_verify_reprepare_count(0); +SUCCESS + 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; +ERROR 42S02: Table 'test.t1' doesn't exist +call p_verify_reprepare_count(0); +SUCCESS + +drop table t2; +deallocate prepare stmt; ===================================================================== -Testing 15: VIEW -> TABLE transitions +Part 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'; +create table t2 (a int); +create view t1 as select * from t2; +prepare stmt from "select * from t1"; 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 +call p_verify_reprepare_count(0); +SUCCESS + +drop view t1; +create table t1 (a int); 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; +call p_verify_reprepare_count(1); +SUCCESS + +drop table t2; +drop table t1; +deallocate prepare stmt; ===================================================================== -Testing 16: VIEW -> TEMPORARY TABLE transitions +Part 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'; +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 -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 +1 +call p_verify_reprepare_count(0); +SUCCESS + +create temporary table t1 (a int); 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; +call p_verify_reprepare_count(1); +SUCCESS + +drop view t1; 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; +call p_verify_reprepare_count(0); +SUCCESS + +drop table t2; +drop temporary table t1; +deallocate prepare stmt; ===================================================================== -Testing 17: VIEW -> VIEW (DDL) transitions +Part 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; +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 t17'; +prepare stmt from "select * from t1"; 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 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. 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; +call p_verify_reprepare_count(0); +SUCCESS + +flush table t2; 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 +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 +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 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; +execute stmt; 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; +call p_verify_reprepare_count(0); +SUCCESS + +drop view v2; +create view v2 as select a from t2; +execute stmt; 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; +execute stmt; 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; +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; ===================================================================== -Testing 19: Special tables (INFORMATION_SCHEMA) +Part 19: Special tables (INFORMATION_SCHEMA) ===================================================================== -drop procedure if exists proc_19; 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"; + routine_name='p1'"; +create procedure p1() 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 +test p1 PROCEDURE 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"; +test p1 PROCEDURE +drop procedure p1; +create procedure p1() 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 +test p1 PROCEDURE 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; +test p1 PROCEDURE +call p_verify_reprepare_count(0); +SUCCESS + +drop procedure p1; +deallocate prepare stmt; ===================================================================== -Testing 20: Special tables (log tables) +Part 20: Special tables (log tables) ===================================================================== prepare stmt from -'select * from mysql.general_log where argument=\'IMPOSSIBLE QUERY STRING\''; +"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 +call p_verify_reprepare_count(0); +SUCCESS + +deallocate prepare stmt; ===================================================================== -Testing 21: Special tables (system tables) +Part 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"; +"select type, db, name from mysql.proc where name='p1'"; +create procedure p1() 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 +PROCEDURE test p1 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"; +PROCEDURE test p1 +drop procedure p1; +create procedure p1() 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 +PROCEDURE test p1 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; +PROCEDURE test p1 +call p_verify_reprepare_count(0); +SUCCESS + +drop procedure p1; +deallocate prepare stmt; ===================================================================== -Testing 22: Special tables (views temp tables) +Part 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; +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); +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 -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); +insert into t1 values (4), (5), (6); execute stmt; a2 1 @@ -1998,16 +983,6 @@ a2 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 @@ -2016,1333 +991,291 @@ a2 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; +call p_verify_reprepare_count(0); +SUCCESS + +drop table t1; +drop view v1; ===================================================================== -Testing 23: Special tables (internal join tables) +Part 23: Special statements ===================================================================== -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); +# SQLCOM_ALTER_TABLE: +create table t1 (a int); +prepare stmt from "alter table t1 add column b int"; 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 +drop table t1; +create table t1 (a1 int, a2 int); +# t1 has changed, and it's does not lead to reprepare 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); +alter table t1 drop column b; 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 +alter table t1 drop column b; 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'; +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.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); +test.t1 repair status OK 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; +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.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; +test.t1 repair status OK +alter table t1 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 -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'; +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.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); +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.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; +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.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; +test.t1 analyze status OK +alter table t1 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 -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'; +test.t1 analyze status OK +alter table t1 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; -create table t24_optimize(a1 int, a2 int); -insert into t24_optimize values (1, 10), (2, 20), (3, 30); +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.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; +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.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; +test.t1 optimize status OK +alter table t1 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 -drop table t24_optimize; -drop procedure if exists changing_proc; -prepare stmt from 'show create procedure changing_proc'; +test.t1 optimize status OK +alter table t1 drop column b; 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 +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 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; +ERROR 42000: PROCEDURE p1 does not exist 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 +ERROR 42000: PROCEDURE p1 does not exist +create procedure p1() 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 -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 +drop procedure p1; +create procedure p1(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 -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 +drop procedure p1; 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'; +ERROR 42000: PROCEDURE p1 does not exist 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 +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 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; +ERROR 42000: FUNCTION f1 does not exist 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 +ERROR 42000: FUNCTION f1 does not exist +create function f1() 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 -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 +drop function f1; +create function f1(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 -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 +drop function f1; 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;'; +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 -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 -$$ +create trigger t1_bi before insert on t1 for each row set @message= "t1_bi"; 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; +drop trigger t1_bi; +create trigger t1_bi before insert on t1 for each row set @message= "t1_bi (2)"; 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; +drop trigger t1_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; +call p_verify_reprepare_count(0); +SUCCESS + +drop table t1; +deallocate prepare stmt; ===================================================================== -Testing 25: Testing the strength of TABLE_SHARE version +Part 24: 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'; +# Test 24-a: number of columns +create table t1 (a int); +prepare stmt from "select a from t1"; 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 +call p_verify_reprepare_count(0); +SUCCESS + +alter table t1 add column b varchar(50) default 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 -alter table t25_num_col add column b varchar(50) default NULL; -set @expected = @expected + 1; +call p_verify_reprepare_count(1); +SUCCESS + 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 +call p_verify_reprepare_count(0); +SUCCESS + +# Test 24-b: column name +alter table t1 change b c int; 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'; +call p_verify_reprepare_count(1); +SUCCESS + 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 +call p_verify_reprepare_count(0); +SUCCESS + +# Test 24-c: column type +alter table t1 change a a varchar(10); 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'; +call p_verify_reprepare_count(1); +SUCCESS + 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 +call p_verify_reprepare_count(0); +SUCCESS + +# Test 24-d: column type length +alter table t1 change a a varchar(20); 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'; +call p_verify_reprepare_count(1); +SUCCESS + 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 +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 -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'; +call p_verify_reprepare_count(1); +SUCCESS + 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 +call p_verify_reprepare_count(0); +SUCCESS + +# Test 24-f: column DEFAULT +alter table t1 change c c int DEFAULT 20; 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'; +call p_verify_reprepare_count(1); +SUCCESS + 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 +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 -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; +call p_verify_reprepare_count(1); +SUCCESS + 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 +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 -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'; +call p_verify_reprepare_count(1); +SUCCESS + 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; +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 +1286,36 @@ insert into t_27420_101 values (1), (2); 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)); @@ -3418,39 +1332,16 @@ insert into t_27430_2 values (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'; +"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 +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 @@ -3465,35 +1356,22 @@ insert into t_27430_2 values (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; +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,66 +1379,28 @@ create table t_27690_1 (a int, b int); 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'; +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 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 @@ -3571,16 +1411,9 @@ a b a b 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 +call p_verify_reprepare_count(1); +SUCCESS + execute stmt; a b a b 1 1 1 1 @@ -3591,17 +1424,84 @@ a b a b 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; +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; +# 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; diff --git a/mysql-test/t/ps_ddl.test b/mysql-test/t/ps_ddl.test index c824d17063b..d3df035444c 100644 --- a/mysql-test/t/ps_ddl.test +++ b/mysql-test/t/ps_ddl.test @@ -47,1629 +47,1082 @@ # - 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'; +prepare stmt from "select * from t1"; --echo ===================================================================== ---echo Testing 2: NOTHING -> TEMPORARY TABLE transitions +--echo Part 2: NOTHING -> TEMPORARY TABLE transitions --echo ===================================================================== # can not be tested --echo ===================================================================== ---echo Testing 3: NOTHING -> VIEW transitions +--echo Part 3: NOTHING -> VIEW transitions --echo ===================================================================== # can not be tested --echo ===================================================================== ---echo Testing 4: TABLE -> NOTHING transitions +--echo Part 4: TABLE -> NOTHING transitions --echo ===================================================================== ---disable_warnings -drop table if exists t4; ---enable_warnings +create table t1 (a int); -create table t4(a int); - -prepare stmt from 'select * from t4'; +prepare stmt from "select * from t1"; execute stmt; -eval $check; +call p_verify_reprepare_count(0); execute stmt; -eval $check; +call p_verify_reprepare_count(0); -drop table t4; +drop table t1; --error ER_NO_SUCH_TABLE execute stmt; -eval $check; +call p_verify_reprepare_count(0); --error ER_NO_SUCH_TABLE execute stmt; -eval $check; +call p_verify_reprepare_count(0); +deallocate prepare stmt; --echo ===================================================================== ---echo Testing 5: TABLE -> TABLE (DDL) transitions +--echo Part 5: TABLE -> TABLE (DDL) transitions --echo ===================================================================== ---disable_warnings -drop table if exists t5; ---enable_warnings +create table t1 (a int); -create table t5(a int); - -prepare stmt from 'select a from t5'; +prepare stmt from "select a from t1"; execute stmt; -eval $check; +call p_verify_reprepare_count(0); execute stmt; -eval $check; +call p_verify_reprepare_count(0); -alter table t5 add column (b int); +alter table t1 add column (b int); -set @expected = @expected + 1; execute stmt; -eval $check; +call p_verify_reprepare_count(1); execute stmt; -eval $check; +call p_verify_reprepare_count(0); -drop table t5; +drop table t1; +deallocate prepare stmt; --echo ===================================================================== ---echo Testing 6: TABLE -> TABLE (TRIGGER) transitions +--echo Part 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 +--echo # Test 6-a: adding a relevant trigger -create table t6(a int); +create table t1 (a int); -prepare stmt from 'insert into t6(a) value (?)'; +prepare stmt from "insert into t1 (a) value (?)"; set @val=1; execute stmt using @val; -eval $check; -set @val=2; -execute stmt using @val; -eval $check; +call p_verify_reprepare_count(0); # Relevant trigger: execute should reprepare -delimiter $$; -create trigger t6_bi before insert on t6 for each row - begin - set @message= "t6_bi"; - end -$$ -delimiter ;$$ +create trigger t1_bi before insert on t1 for each row + set @message= new.a; -set @message="none"; -set @val=3; -set @expected = @expected + 1; +set @val=2; execute stmt using @val; -eval $check; +call p_verify_reprepare_count(1); select @message; +set @val=3; +execute stmt using @val; +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; -select @message; -set @message="none"; -set @val=8; -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"; -set @val=9; -execute stmt using @val; -eval $check; -select @message; -set @message="none"; -set @val=10; -execute stmt using @val; -eval $check; -select @message; +--echo # Test 6-c: changing a relevant trigger # 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 ;$$ +drop trigger t1_bi; +create trigger t1_bi before insert on t1 for each row + set @message= concat("new trigger: ", new.a); -set @message="none"; -set @val=11; -set @expected = @expected + 1; +set @val=8; execute stmt using @val; -eval $check; +call p_verify_reprepare_count(1); select @message; +set @val=9; +execute stmt using @val; +call p_verify_reprepare_count(0); +select @message; + +prepare stmt from "insert into t1 (a) value (?)"; +set @val=10; +execute stmt using @val; +call p_verify_reprepare_count(0); +select @message; + +--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; +execute stmt using @val; +call p_verify_reprepare_count(1); +select @message; + +--ehco 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; +call p_verify_reprepare_count(0); 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; +select * from t1 order by a; +drop table t1; +deallocate prepare stmt; --echo ===================================================================== ---echo Testing 7: TABLE -> TABLE (TRIGGER dependencies) transitions +--echo Part 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 -# +--echo # Test 7-a: dependent PROCEDURE has changed +--echo # +--echo # Note, this scenario is not supported, subject of Bug#12093 +--echo # ---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 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); -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); +--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; -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)); +--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); -create procedure audit_proc(a int) - insert into t7_audit values (NULL, a, "proc v1"); +--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; -create function audit_func() returns varchar(50) - return "func v1"; +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; -create view audit_view as select "view v1" as reason from dual; +--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); -create trigger t7_proc_bi before insert on t7_proc for each row - call audit_proc(NEW.a); +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; -create trigger t7_func_bi before insert on t7_func for each row - insert into t7_audit values (NULL, NEW.a, audit_func()); +--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); -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)); +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); -create trigger t7_table_bi before insert on t7_table for each row - insert into t7_dependent_table values (NULL, NEW.a, "dependent table"); +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); -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; +drop table t1, t2, t3, t4; +deallocate prepare stmt; --echo ===================================================================== ---echo Testing 8: TABLE -> TEMPORARY TABLE transitions +--echo Part 8: TABLE -> TEMPORARY TABLE transitions --echo ===================================================================== ---disable_warnings -drop table if exists t8; ---enable_warnings +create table t1 (a int); -create table t8(a int); - -prepare stmt from 'select * from t8'; +prepare stmt from "select * from t1"; execute stmt; -eval $check; -execute stmt; -eval $check; -drop table t8; -create temporary table t8(a int); +drop table t1; +create temporary table t1 (a int); -set @expected = @expected + 1; execute stmt; -eval $check; +call p_verify_reprepare_count(1); execute stmt; -eval $check; +call p_verify_reprepare_count(0); -drop table t8; +drop table t1; +deallocate prepare stmt; --echo ===================================================================== ---echo Testing 9: TABLE -> VIEW transitions +--echo Part 9: TABLE -> VIEW transitions --echo ===================================================================== ---disable_warnings -drop table if exists t9; -drop table if exists t9_b; ---enable_warnings +create table t1 (a int); -create table t9(a int); -create table t9_b(a int); - -prepare stmt from 'select * from t9'; +prepare stmt from "select * from t1"; execute stmt; -eval $check; -execute stmt; -eval $check; +call p_verify_reprepare_count(0); -drop table t9; -create view t9 as select * from t9_b; +drop table t1; +create table t2 (a int); +create view t1 as select * from t2; -set @expected = @expected + 1; execute stmt; -eval $check; -execute stmt; -eval $check; +call p_verify_reprepare_count(1); -drop view t9; -drop table t9_b; +drop view t1; +drop table t2; +deallocate prepare stmt; --echo ===================================================================== ---echo Testing 10: TEMPORARY TABLE -> NOTHING transitions +--echo Part 10: TEMPORARY TABLE -> NOTHING transitions --echo ===================================================================== ---disable_warnings -drop temporary table if exists t10; ---enable_warnings +create temporary table t1 (a int); -create temporary table t10(a int); - -prepare stmt from 'select * from t10'; +prepare stmt from "select * from t1"; execute stmt; -eval $check; -execute stmt; -eval $check; +call p_verify_reprepare_count(0); -drop temporary table t10; +drop temporary table t1; --error ER_NO_SUCH_TABLE execute stmt; -eval $check; +call p_verify_reprepare_count(0); +deallocate prepare stmt; + +--echo ===================================================================== +--echo Part 11: TEMPORARY TABLE -> TABLE transitions +--echo ===================================================================== + +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 ===================================================================== +--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; -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; +call p_verify_reprepare_count(0); --error ER_NO_SUCH_TABLE execute stmt; -eval $check; -set @expected = @expected + 1; ---error ER_NO_SUCH_TABLE +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; -eval $check; +call p_verify_reprepare_count(0); -drop table t14_b; +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 Testing 15: VIEW -> TABLE transitions +--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. +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 +--ehco # 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 view if exists t15; -drop table if exists t15_b; +drop table if exists t1, t2, v1, v2; +drop view if exists v1, v2; +drop function f1; +drop procedure p1; --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; +deallocate prepare stmt; --echo ===================================================================== ---echo Testing 16: VIEW -> TEMPORARY TABLE transitions +--echo Part 19: Special tables (INFORMATION_SCHEMA) --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 - # 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\''; + routine_name='p1'"; -create procedure proc_19() select "hi there"; +create procedure p1() select "hi there"; execute stmt; -eval $check; execute stmt; -eval $check; -drop procedure proc_19; -create procedure proc_19() select "hi there, again"; +drop procedure p1; +create procedure p1() select "hi there, again"; execute stmt; -eval $check; execute stmt; -eval $check; +call p_verify_reprepare_count(0); -drop procedure proc_19; +drop procedure p1; +deallocate prepare stmt; --echo ===================================================================== ---echo Testing 20: Special tables (log tables) +--echo Part 20: Special tables (log tables) --echo ===================================================================== prepare stmt from - 'select * from mysql.general_log where argument=\'IMPOSSIBLE QUERY STRING\''; + "select * from mysql.general_log where argument='IMPOSSIBLE QUERY STRING'"; +--disable_result_log execute stmt; -eval $check; execute stmt; -eval $check; execute stmt; -eval $check; execute stmt; -eval $check; +--enable_result_log +call p_verify_reprepare_count(0); +deallocate prepare stmt; --echo ===================================================================== ---echo Testing 21: Special tables (system tables) +--echo Part 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\''; + "select type, db, name from mysql.proc where name='p1'"; -create procedure proc_21() select "hi there"; +create procedure p1() select "hi there"; execute stmt; -eval $check; execute stmt; -eval $check; -drop procedure proc_21; -create procedure proc_21() select "hi there, again"; +drop procedure p1; +create procedure p1() select "hi there, again"; execute stmt; -eval $check; execute stmt; -eval $check; +call p_verify_reprepare_count(0); -drop procedure proc_21; +drop procedure p1; +deallocate prepare stmt; --echo ===================================================================== ---echo Testing 22: Special tables (views temp tables) +--echo Part 22: Special tables (views temp tables) --echo ===================================================================== ---disable_warnings -drop table if exists t22_b; -drop view if exists t22; ---enable_warnings +create table t1 (a int); -create table t22_b(a int); +create algorithm=temptable view v1 as select a*a as a2 from t1; -create algorithm=temptable view t22 as select a*a as a2 from t22_b; +--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; -# 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 v1"; -prepare stmt from 'select * from t22'; - -insert into t22_b values (1), (2), (3); +insert into t1 values (1), (2), (3); execute stmt; -eval $check; execute stmt; -eval $check; -insert into t22_b values (4), (5), (6); +insert into t1 values (4), (5), (6); execute stmt; -eval $check; execute stmt; -eval $check; +call p_verify_reprepare_count(0); -drop table t22_b; -drop view t22; +drop table t1; +drop view v1; --echo ===================================================================== ---echo Testing 23: Special tables (internal join tables) +--echo Part 23: Special statements --echo ===================================================================== ---disable_warnings -drop table if exists t23_a; -drop table if exists t23_b; ---enable_warnings +--echo # SQLCOM_ALTER_TABLE: -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'; +create table t1 (a int); -insert into t23_a values (1), (2), (3); -insert into t23_b values (10), (20), (30); +prepare stmt from "alter table t1 add column b int"; execute stmt; -eval $check; + +drop table t1; +create table t1 (a1 int, a2 int); + +--echo # t1 has changed, and it's does not lead to reprepare execute stmt; -eval $check; -insert into t23_a values (4); -insert into t23_b values (40); +alter table t1 drop column b; execute stmt; -eval $check; + +alter table t1 drop column b; execute stmt; -eval $check; +call p_verify_reprepare_count(0); -drop table t23_a; -drop table t23_b; +drop table t1; ---echo ===================================================================== ---echo Testing 24: Special statements ---echo ===================================================================== +--echo # SQLCOM_REPAIR: -# SQLCOM_ALTER_TABLE: +create table t1 (a int); ---disable_warnings -drop table if exists t24_alter; ---enable_warnings +insert into t1 values (1), (2), (3); -create table t24_alter(a int); +prepare stmt from "repair table t1"; -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; +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; -eval $check; -alter table t24_alter drop column b; +alter table t1 add column b varchar(50) default NULL; execute stmt; -eval $check; +call p_verify_reprepare_count(0); -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'; +alter table t1 drop column b; execute stmt; -eval $check; +call p_verify_reprepare_count(0); -drop table t24_repair; -create table t24_repair(a1 int, a2 int); -insert into t24_repair values (1, 10), (2, 20), (3, 30); +--echo # SQLCOM_ANALYZE: -# t24_repair has changed, and it's not a problem +prepare stmt from "analyze table t1"; execute stmt; -eval $check; -alter table t24_repair add column b varchar(50) default NULL; +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; -eval $check; -alter table t24_repair drop column b; +alter table t1 add column b varchar(50) default NULL; 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'; +alter table t1 drop column b; 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); +call p_verify_reprepare_count(0); -# t24_analyze has changed, and it's not a problem +--echo # SQLCOM_OPTIMIZE: + +prepare stmt from "optimize table t1"; execute stmt; -eval $check; -alter table t24_analyze add column b varchar(50) default NULL; +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; -eval $check; -alter table t24_analyze drop column b; +alter table t1 add column b varchar(50) default NULL; 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'; +alter table t1 drop column b; execute stmt; -eval $check; +call p_verify_reprepare_count(0); -drop table t24_optimize; -create table t24_optimize(a1 int, a2 int); -insert into t24_optimize values (1, 10), (2, 20), (3, 30); +drop table t1; -# t24_optimize has changed, and it's not a problem -execute stmt; -eval $check; +--echo # SQLCOM_SHOW_CREATE_PROC: -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'; +prepare stmt from "show create procedure p1"; --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; +create procedure p1() begin end; -# changing_proc has changed, and it's not a problem +--disable_result_log execute stmt; -eval $check; execute stmt; -eval $check; +--enable_result_log -drop procedure changing_proc; -create procedure changing_proc(x int, y int) begin end; +drop procedure p1; +create procedure p1(x int, y int) begin end; +--disable_result_log execute stmt; -eval $check; execute stmt; -eval $check; +--enable_result_log -drop procedure changing_proc; +drop procedure p1; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $check; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $check; +call p_verify_reprepare_count(0); -# SQLCOM_SHOW_CREATE_FUNC: +--echo # SQLCOM_SHOW_CREATE_FUNC: ---disable_warnings -drop function if exists changing_func; ---enable_warnings - -prepare stmt from 'show create function changing_func'; +prepare stmt from "show create function f1"; --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; +create function f1() returns int return 0; -# changing_proc has changed, and it's not a problem +--disable_result_log execute stmt; -eval $check; execute stmt; -eval $check; +--enable_result_log -drop function changing_func; -create function changing_func(x int, y int) returns int return x+y; +drop function f1; +create function f1(x int, y int) returns int return x+y; +--disable_result_log execute stmt; -eval $check; execute stmt; -eval $check; +--enable_result_log -drop function changing_func; +drop function f1; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $check; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $check; +call p_verify_reprepare_count(0); -# SQLCOM_SHOW_CREATE_TRIGGER: +--echo # SQLCOM_SHOW_CREATE_TRIGGER: ---disable_warnings -drop table if exists t24_trigger; ---enable_warnings +create table t1 (a int); -create table t24_trigger(a int); - -prepare stmt from 'show create trigger t24_bi;'; +prepare stmt from "show create trigger t1_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 ;$$ +create trigger t1_bi before insert on t1 for each row set @message= "t1_bi"; -# t24_bi has changed, and it's not a problem +--disable_result_log execute stmt; -eval $check; execute stmt; -eval $check; +--enable_result_log -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 ;$$ +drop trigger t1_bi; -# t24_bi has changed, and it's not a problem -set @expected = @expected + 1; +create trigger t1_bi before insert on t1 for each row set @message= "t1_bi (2)"; + +--disable_result_log execute stmt; -eval $check; execute stmt; -eval $check; +--enable_result_log -drop trigger t24_bi; +drop trigger t1_bi; --error ER_TRG_DOES_NOT_EXIST execute stmt; -eval $check; --error ER_TRG_DOES_NOT_EXIST execute stmt; -eval $check; +call p_verify_reprepare_count(0); -drop table t24_trigger; +drop table t1; +deallocate prepare stmt; --echo ===================================================================== ---echo Testing 25: Testing the strength of TABLE_SHARE version +--echo Part 24: Testing the strength of TABLE_SHARE version --echo ===================================================================== -# Test 25-a: number of columns +--echo # Test 24-a: number of columns ---disable_warnings -drop table if exists t25_num_col; ---enable_warnings +create table t1 (a int); -create table t25_num_col(a int); - -prepare stmt from 'select a from t25_num_col'; +prepare stmt from "select a from t1"; execute stmt; -eval $check; +call p_verify_reprepare_count(0); + +alter table t1 add column b varchar(50) default NULL; + execute stmt; -eval $check; - -alter table t25_num_col add column b varchar(50) default NULL; - -set @expected = @expected + 1; +call p_verify_reprepare_count(1); execute stmt; -eval $check; +call p_verify_reprepare_count(0); + +--echo # Test 24-b: column name + +alter table t1 change b c int; 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'; +call p_verify_reprepare_count(1); execute stmt; -eval $check; +call p_verify_reprepare_count(0); + +--echo # Test 24-c: column type + +alter table t1 change a a varchar(10); + execute stmt; -eval $check; - -alter table t25_col_name change a b int; - -set @expected = @expected + 1; ---error ER_PS_REBIND +call p_verify_reprepare_count(1); execute stmt; -eval $check; -set @expected = @expected + 1; ---error ER_PS_REBIND +call p_verify_reprepare_count(0); + +--echo # Test 24-d: column type length + +alter table t1 change a a varchar(20); + 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'; +call p_verify_reprepare_count(1); execute stmt; -eval $check; +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; -eval $check; - -alter table t25_col_type change a a varchar(10); - -set @expected = @expected + 1; ---error ER_PS_REBIND +call p_verify_reprepare_count(1); execute stmt; -eval $check; -set @expected = @expected + 1; ---error ER_PS_REBIND +call p_verify_reprepare_count(0); + +--echo # Test 24-f: column DEFAULT + +alter table t1 change c c int DEFAULT 20; + 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'; +call p_verify_reprepare_count(1); execute stmt; -eval $check; +call p_verify_reprepare_count(0); + +--echo # Test 24-g: number of keys +create unique index t1_a_idx on t1 (a); + execute stmt; -eval $check; - -alter table t25_col_type_length change a a varchar(20); - -set @expected = @expected + 1; ---error ER_PS_REBIND +call p_verify_reprepare_count(1); execute stmt; -eval $check; -set @expected = @expected + 1; ---error ER_PS_REBIND +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; -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'; +call p_verify_reprepare_count(1); execute stmt; -eval $check; -execute stmt; -eval $check; +call p_verify_reprepare_count(0); -alter table t25_col_null change a a varchar(10) NOT NULL; +--echo # Cleanup +drop table t1; -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; +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 +1130,6 @@ drop table if exists t_27420_101; 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 +1140,33 @@ 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; -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; +call p_verify_reprepare_count(1); -disconnect con1; - -deallocate prepare stmt; 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; @@ -1753,12 +1189,10 @@ insert into t_27430_2 values (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'; + "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; +call p_verify_reprepare_count(0); drop table t_27430_1, t_27430_2; @@ -1777,23 +1211,17 @@ insert into t_27430_2 values (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; +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 +1235,125 @@ 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'; +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; +call p_verify_reprepare_count(1); execute stmt; -eval $check; +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 # 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 From 63944ed537f1a77ee87758721c2662308803789c Mon Sep 17 00:00:00 2001 From: "kostja@dipika.(none)" <> Date: Mon, 7 Apr 2008 15:42:32 +0400 Subject: [PATCH 13/16] A fix for Bug#32724 "innodb_mysql.test fails randomly". Enable back the disabled test case. --- mysql-test/t/disabled.def | 1 - sql/sql_parse.cc | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 4e58c30b812..af7b9c25f18 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -16,7 +16,6 @@ ctype_big5 : BUG#26711 2007-06-21 Lars Test has never worked on Do federated_transactions : Bug#29523 Transactions do not work lowercase_table3 : Bug#32667 lowercase_table3.test reports to error log -innodb_mysql : Bug#32724: innodb_mysql.test fails randomly ctype_create : Bug#32965 main.ctype_create fails status : Bug#32966 main.status fails ps_ddl : Bug#12093 2007-12-14 pending WL#4165 / WL#4166 diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3edad3a2184..c28fea57c64 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3301,6 +3301,7 @@ end_with_restore_list: can free its locks if LOCK TABLES locked some tables before finding that it can't lock a table in its list */ + ha_autocommit_or_rollback(thd, 1); end_active_trans(thd); thd->options&= ~(OPTION_TABLE_LOCK); } From a9fff11f49d88e3fec08232b24a721cc515639fc Mon Sep 17 00:00:00 2001 From: "kostja@dipika.(none)" <> Date: Mon, 7 Apr 2008 23:57:47 +0400 Subject: [PATCH 14/16] Fix a compilation warning (unused variable). --- sql/sql_update.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index fe34301cda0..103ac17a821 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -853,7 +853,9 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, Item **conds, uint order_num, ORDER *order) { Item *fake_conds= 0; +#ifndef NO_EMBEDDED_ACCESS_CHECKS TABLE *table= table_list->table; +#endif List all_fields; SELECT_LEX *select_lex= &thd->lex->select_lex; DBUG_ENTER("mysql_prepare_update"); From 38effd5603b55c9ea6688a6461b73ea5c08a21a0 Mon Sep 17 00:00:00 2001 From: "thek@adventure.(none)" <> Date: Tue, 8 Apr 2008 15:57:44 +0200 Subject: [PATCH 15/16] Merge error between two patches caused error out-of-bounds assignment. --- sql/sql_acl.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 91fa3e48ee0..0b33abcfba2 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3539,7 +3539,7 @@ static my_bool grant_load_procs_priv(TABLE *p_table) 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); @@ -3723,6 +3723,7 @@ static my_bool grant_reload_procs_priv(THD *thd) 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)) { @@ -3788,8 +3789,7 @@ my_bool grant_reload(THD *thd) 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= - tables[2].skip_temporary= TRUE; + tables[0].skip_temporary= tables[1].skip_temporary= TRUE; /* To avoid deadlocks we should obtain table locks before obtaining LOCK_grant rwlock. From 84de43cda6b1e9f00b0aa63be2d6aa55cbdad271 Mon Sep 17 00:00:00 2001 From: "kostja@dipika.(none)" <> Date: Tue, 8 Apr 2008 20:31:40 +0400 Subject: [PATCH 16/16] Remove dead code. --- sql/opt_range.cc | 3 - sql/sp.cc | 204 ----------------------------------------------- sql/sp.h | 3 - sql/sql_parse.cc | 14 ---- 4 files changed, 224 deletions(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index b8bdb604eea..454c68e11a1 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2317,9 +2317,6 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, 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 diff --git a/sql/sp.cc b/sql/sp.cc index 69eae8de207..3fe0841e879 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1070,210 +1070,6 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) } -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 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' diff --git a/sql/sp.h b/sql/sp.h index 31173e1f90c..75088ea0b83 100644 --- a/sql/sp.h +++ b/sql/sp.h @@ -48,9 +48,6 @@ sp_routine_exists_in_table(THD *thd, int type, sp_name *name); bool 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); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c28fea57c64..62047e70d51 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4305,20 +4305,6 @@ create_sp_error: } 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: