From 2cad3bb8dae2fc4dc8e28ccf6ab5db3e9026b0c6 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 31 Oct 2007 18:44:31 +0100 Subject: [PATCH 01/56] Backport mysqltests "change_user" command --- client/mysqltest.c | 67 ++++++++++++++++++++++++++++++++++- mysql-test/r/mysqltest.result | 3 ++ mysql-test/t/mysqltest.test | 19 ++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index eae3b05f61a..a0674a5edb6 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -277,7 +277,7 @@ enum enum_commands { Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST, Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP, Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES, - Q_SEND_QUIT, + Q_SEND_QUIT, Q_CHANGE_USER, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ @@ -366,6 +366,7 @@ const char *command_names[]= "cat_file", "diff_files", "send_quit", + "change_user", 0 }; @@ -3046,6 +3047,69 @@ void do_send_quit(struct st_command *command) } +/* + SYNOPSIS + do_change_user + command called command + + DESCRIPTION + change_user [], [], [] + - user to change to + - user password + - default database + + Changes the user and causes the database specified by db to become + the default (current) database for the the current connection. + +*/ + +void do_change_user(struct st_command *command) +{ + MYSQL *mysql = &cur_con->mysql; + /* static keyword to make the NetWare compiler happy. */ + static DYNAMIC_STRING ds_user, ds_passwd, ds_db; + const struct command_arg change_user_args[] = { + { "user", ARG_STRING, FALSE, &ds_user, "User to connect as" }, + { "password", ARG_STRING, FALSE, &ds_passwd, "Password used when connecting" }, + { "database", ARG_STRING, FALSE, &ds_db, "Database to select after connect" }, + }; + + DBUG_ENTER("do_change_user"); + + check_command_args(command, command->first_argument, + change_user_args, + sizeof(change_user_args)/sizeof(struct command_arg), + ','); + + if (cur_con->stmt) + { + mysql_stmt_close(cur_con->stmt); + cur_con->stmt= NULL; + } + + if (!ds_user.length) + dynstr_set(&ds_user, mysql->user); + + if (!ds_passwd.length) + dynstr_set(&ds_passwd, mysql->passwd); + + if (!ds_db.length) + dynstr_set(&ds_db, mysql->db); + + DBUG_PRINT("info",("connection: '%s' user: '%s' password: '%s' database: '%s'", + cur_con->name, ds_user.str, ds_passwd.str, ds_db.str)); + + if (mysql_change_user(mysql, ds_user.str, ds_passwd.str, ds_db.str)) + die("change user failed: %s", mysql_error(mysql)); + + dynstr_free(&ds_user); + dynstr_free(&ds_passwd); + dynstr_free(&ds_db); + + DBUG_VOID_RETURN; +} + + /* SYNOPSIS do_perl @@ -6852,6 +6916,7 @@ int main(int argc, char **argv) case Q_APPEND_FILE: do_append_file(command); break; case Q_DIFF_FILES: do_diff_files(command); break; case Q_SEND_QUIT: do_send_quit(command); break; + case Q_CHANGE_USER: do_change_user(command); break; case Q_CAT_FILE: do_cat_file(command); break; case Q_COPY_FILE: do_copy_file(command); break; case Q_CHMOD_FILE: do_chmod_file(command); break; diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index d03e21b1bb0..a7df1a523cf 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -722,4 +722,7 @@ a int(11) YES NULL b varchar(255) YES NULL c datetime YES NULL drop table t1; +mysqltest: At line 1: change user failed: Unknown database 'inexistent' +mysqltest: At line 1: change user failed: Access denied for user 'inexistent'@'localhost' (using password: NO) +mysqltest: At line 1: change user failed: Access denied for user 'root'@'localhost' (using password: YES) End of tests diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index ec188af0244..c5ff9cf924a 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -2083,5 +2083,24 @@ eval $show_statement; drop table t1; +# ---------------------------------------------------------------------------- +# Test change_user command +# ---------------------------------------------------------------------------- + +--error 1 +--exec echo "--change_user root,,inexistent" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "--change_user inexistent,,test" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "--change_user root,inexistent,test" | $MYSQL_TEST 2>&1 + +--change_user +--change_user root +--change_user root,, +--change_user root,,test + + --echo End of tests From 2a415a2f9d92e1b07eb308a42ea8d84e8da1ec3f Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 1 Nov 2007 15:42:19 +0100 Subject: [PATCH 02/56] Bug#31004 mysqltest needs a --mkdir command - Add new mysqltest command "mkdir" and "rmdir" client/CMakeLists.txt: Build mysys/my_mkdir.c with mysqltest client/Makefile.am: Build mysys/my_mkdir.c with mysqltest client/mysqltest.c: Add new mysqltest commands "mkdir" and "rmdir" mysql-test/t/mysqltest.test: Add tests for "mkdir" and ""rmdir" --- client/CMakeLists.txt | 3 +- client/Makefile.am | 3 +- client/mysqltest.c | 68 ++++++++++++++++++++++++++++++++++++- mysql-test/t/mysqltest.test | 22 ++++++++++++ 4 files changed, 93 insertions(+), 3 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 89675138750..a419da5eabf 100755 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -32,7 +32,8 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c) TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32) -ADD_EXECUTABLE(mysqltest mysqltest.c ../mysys/my_getsystime.c ../mysys/my_copy.c) +ADD_EXECUTABLE(mysqltest mysqltest.c ../mysys/my_getsystime.c + ../mysys/my_copy.c ../mysys/my_mkdir.c) TARGET_LINK_LIBRARIES(mysqltest mysqlclient_notls regex wsock32) ADD_EXECUTABLE(mysqlcheck mysqlcheck.c) diff --git a/client/Makefile.am b/client/Makefile.am index c7663c7da82..672bb2e0c47 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -34,7 +34,8 @@ mysqladmin_SOURCES = mysqladmin.cc mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS) mysqltest_SOURCES= mysqltest.c \ $(top_srcdir)/mysys/my_getsystime.c \ - $(top_srcdir)/mysys/my_copy.c + $(top_srcdir)/mysys/my_copy.c \ + $(top_srcdir)/mysys/my_mkdir.c mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD) mysqlbinlog_SOURCES = mysqlbinlog.cc \ diff --git a/client/mysqltest.c b/client/mysqltest.c index a0674a5edb6..2104f43f6fb 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -277,7 +277,7 @@ enum enum_commands { Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST, Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP, Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES, - Q_SEND_QUIT, Q_CHANGE_USER, + Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ @@ -367,6 +367,9 @@ const char *command_names[]= "diff_files", "send_quit", "change_user", + "mkdir", + "rmdir", + 0 }; @@ -2742,6 +2745,67 @@ void do_file_exist(struct st_command *command) } +/* + SYNOPSIS + do_mkdir + command called command + + DESCRIPTION + mkdir + Create the directory +*/ + +void do_mkdir(struct st_command *command) +{ + int error; + static DYNAMIC_STRING ds_dirname; + const struct command_arg mkdir_args[] = { + "dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to create" + }; + DBUG_ENTER("do_mkdir"); + + check_command_args(command, command->first_argument, + mkdir_args, sizeof(mkdir_args)/sizeof(struct command_arg), + ' '); + + DBUG_PRINT("info", ("creating directory: %s", ds_dirname.str)); + error= my_mkdir(ds_dirname.str, 0777, MYF(0)) != 0; + handle_command_error(command, error); + dynstr_free(&ds_dirname); + DBUG_VOID_RETURN; +} + +/* + SYNOPSIS + do_rmdir + command called command + + DESCRIPTION + rmdir + Remove the empty directory +*/ + +void do_rmdir(struct st_command *command) +{ + int error; + static DYNAMIC_STRING ds_dirname; + const struct command_arg rmdir_args[] = { + "dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to remove" + }; + DBUG_ENTER("do_rmdir"); + + check_command_args(command, command->first_argument, + rmdir_args, sizeof(rmdir_args)/sizeof(struct command_arg), + ' '); + + DBUG_PRINT("info", ("removing directory: %s", ds_dirname.str)); + error= rmdir(ds_dirname.str) != 0; + handle_command_error(command, error); + dynstr_free(&ds_dirname); + DBUG_VOID_RETURN; +} + + /* Read characters from line buffer or file. This is needed to allow my_ungetc() to buffer MAX_DELIMITER_LENGTH characters for a file @@ -6911,6 +6975,8 @@ int main(int argc, char **argv) case Q_ECHO: do_echo(command); command_executed++; break; case Q_SYSTEM: do_system(command); break; case Q_REMOVE_FILE: do_remove_file(command); break; + case Q_MKDIR: do_mkdir(command); break; + case Q_RMDIR: do_rmdir(command); break; case Q_FILE_EXIST: do_file_exist(command); break; case Q_WRITE_FILE: do_write_file(command); break; case Q_APPEND_FILE: do_append_file(command); break; diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index c5ff9cf924a..5856bfff036 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -2101,6 +2101,28 @@ drop table t1; --change_user root,, --change_user root,,test +# ---------------------------------------------------------------------------- +# Test mkdir and rmdir command +# ---------------------------------------------------------------------------- + +mkdir $MYSQLTEST_VARDIR/tmp/testdir; +rmdir $MYSQLTEST_VARDIR/tmp/testdir; + +# Directory already exist +mkdir $MYSQLTEST_VARDIR/tmp/testdir; +--error 1 +mkdir $MYSQLTEST_VARDIR/tmp/testdir; + +# Remove dir with file inside +write_file $MYSQLTEST_VARDIR/tmp/testdir/file1.txt; +hello +EOF +--error 1 +rmdir $MYSQLTEST_VARDIR/tmp/testdir; + +remove_file $MYSQLTEST_VARDIR/tmp/testdir/file1.txt; +rmdir $MYSQLTEST_VARDIR/tmp/testdir; + --echo End of tests From a574ce21fc627642e555b5d234b966a4e4332e48 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 1 Nov 2007 17:09:49 +0100 Subject: [PATCH 03/56] Bug#31004 mysqltest needs a --mkdir command mysql-test/t/upgrade.test: Remove kludge in upgrade.test --- mysql-test/t/upgrade.test | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/mysql-test/t/upgrade.test b/mysql-test/t/upgrade.test index 05f430b087b..ce40ec8ed77 100644 --- a/mysql-test/t/upgrade.test +++ b/mysql-test/t/upgrade.test @@ -1,10 +1,5 @@ -- source include/not_embedded.inc -# Temporary disabled on windows, -# because of --exec mkdir -# TODO: implement Bug#31004 and remove this limitation ---source include/not_windows.inc - --disable_warnings drop database if exists `mysqltest1`; drop database if exists `mysqltest-1`; @@ -75,7 +70,7 @@ create table tabc.t1 (a int); FLUSH TABLES; # Manually make a 5.0 database from the template ---exec mkdir $MYSQLTEST_VARDIR/master-data/a-b-c +--mkdir $MYSQLTEST_VARDIR/master-data/a-b-c --copy_file $MYSQLTEST_VARDIR/master-data/tabc/db.opt $MYSQLTEST_VARDIR/master-data/a-b-c/db.opt --copy_file $MYSQLTEST_VARDIR/master-data/tabc/t1.frm $MYSQLTEST_VARDIR/master-data/a-b-c/t1.frm --copy_file $MYSQLTEST_VARDIR/master-data/tabc/t1.MYD $MYSQLTEST_VARDIR/master-data/a-b-c/t1.MYD From 3d5e32b27d35655ab509f5567be7eeda58418052 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 Jan 2008 10:52:41 -0200 Subject: [PATCH 04/56] Bug#30331 Table_locks_waited shows inaccurate values The problem is that the Table_locks_waited was incremented only when the lock request succeed. If a thread waiting for the lock gets killed or the lock request is aborted, the variable would not be incremented, leading to inaccurate values in the variable. The solution is to increment the Table_locks_waited whenever the lock request is queued. This reflects better the intended behavior of the variable -- show how many times a lock was waited. mysql-test/r/lock_multi.result: Add test case result for Bug#30331 mysql-test/t/lock_multi.test: Add test case for Bug#30331 mysys/thr_lock.c: Increment locks_waited whenever the thread is supposed to wait for the lock. --- mysql-test/r/lock_multi.result | 12 ++++++++++++ mysql-test/t/lock_multi.test | 26 ++++++++++++++++++++++++++ mysys/thr_lock.c | 3 ++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result index 9c4f1b17dcc..e17b56e0695 100644 --- a/mysql-test/r/lock_multi.result +++ b/mysql-test/r/lock_multi.result @@ -143,4 +143,16 @@ connection: default flush tables; unlock tables; drop table t1; +drop table if exists t1,t2; +create table t1 (a int); +flush status; +lock tables t1 read; +show status like 'Table_locks_waited'; +Variable_name Value +Table_locks_waited 0 +insert into t1 values(1);; +drop table t1; +show status like 'Table_locks_waited'; +Variable_name Value +Table_locks_waited 1 End of 5.1 tests diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index 0d36b79df78..c73ebab056e 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -439,4 +439,30 @@ connection default; disconnect flush; drop table t1; +# +# Bug#30331: Table_locks_waited shows inaccurate values +# + +--disable_warnings +drop table if exists t1,t2; +--enable_warnings + +create table t1 (a int); +flush status; +lock tables t1 read; +show status like 'Table_locks_waited'; +connect (waiter,localhost,root,,); +connection waiter; +--send insert into t1 values(1); +connection default; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Locked" and info = "insert into t1 values(1)"; +--source include/wait_condition.inc +drop table t1; +disconnect waiter; +connection default; +show status like 'Table_locks_waited'; +#show global status like "Table_locks_waited"; + --echo End of 5.1 tests diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 7f7be4835a5..afe8f289089 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -405,6 +405,8 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, wait->last= &data->next; } + statistic_increment(locks_waited, &THR_LOCK_lock); + /* Set up control struct to allow others to abort locks */ thread_var->current_mutex= &data->lock->mutex; thread_var->current_cond= cond; @@ -469,7 +471,6 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, else { result= THR_LOCK_SUCCESS; - statistic_increment(locks_waited, &THR_LOCK_lock); if (data->lock->get_status) (*data->lock->get_status)(data->status_param, 0); check_locks(data->lock,"got wait_for_lock",0); From cdc66b12c5efc66b8148f98fc78134e7db938080 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 Jan 2008 11:21:39 -0200 Subject: [PATCH 05/56] Remove spurious commented out test line. mysql-test/t/lock_multi.test: Remove spurious test line. --- mysql-test/t/lock_multi.test | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index c73ebab056e..c8feace5c4a 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -463,6 +463,5 @@ drop table t1; disconnect waiter; connection default; show status like 'Table_locks_waited'; -#show global status like "Table_locks_waited"; --echo End of 5.1 tests From e743c791cba5bca00b81f21d7b5e5ea1c19ce9b5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Jan 2008 14:14:34 +0300 Subject: [PATCH 06/56] Fix Bug#27812 "an ampersand is missed in sql/sql_bitmap.h, line 68" --- sql/sql_bitmap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h index 9a765120895..97accefe8aa 100644 --- a/sql/sql_bitmap.h +++ b/sql/sql_bitmap.h @@ -65,7 +65,7 @@ public: my_bool is_clear_all() const { return bitmap_is_clear_all(&map); } my_bool is_set_all() const { return bitmap_is_set_all(&map); } my_bool is_subset(const Bitmap& map2) const { return bitmap_is_subset(&map, &map2.map); } - my_bool is_overlapping(const Bitmap& map2) const { return bitmap_is_overlapping(&map, map2.map); } + my_bool is_overlapping(const Bitmap& map2) const { return bitmap_is_overlapping(&map, &map2.map); } my_bool operator==(const Bitmap& map2) const { return bitmap_cmp(&map, &map2.map); } char *print(char *buf) const { From b46d5d6b2fbf5cd67c9c853f489221d50bec973a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Jan 2008 10:37:44 -0200 Subject: [PATCH 07/56] Fix test case of Bug 30331 mysql-test/r/lock_multi.result: Update test case result. mysql-test/t/lock_multi.test: Don't print the value of Table_lock_waited, check the precedence instead. Unlock the table before dropping. --- mysql-test/r/lock_multi.result | 10 ++++------ mysql-test/t/lock_multi.test | 10 ++++++++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result index e17b56e0695..cd05fc1473f 100644 --- a/mysql-test/r/lock_multi.result +++ b/mysql-test/r/lock_multi.result @@ -147,12 +147,10 @@ drop table if exists t1,t2; create table t1 (a int); flush status; lock tables t1 read; -show status like 'Table_locks_waited'; -Variable_name Value -Table_locks_waited 0 insert into t1 values(1);; +unlock tables; drop table t1; -show status like 'Table_locks_waited'; -Variable_name Value -Table_locks_waited 1 +select @tlwa < @tlwb; +@tlwa < @tlwb +1 End of 5.1 tests diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index c8feace5c4a..f1e9c0d253f 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -450,7 +450,7 @@ drop table if exists t1,t2; create table t1 (a int); flush status; lock tables t1 read; -show status like 'Table_locks_waited'; +let $tlwa= `show status like 'Table_locks_waited'`; connect (waiter,localhost,root,,); connection waiter; --send insert into t1 values(1); @@ -459,9 +459,15 @@ let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Locked" and info = "insert into t1 values(1)"; --source include/wait_condition.inc +let $tlwb= `show status like 'Table_locks_waited'`; +unlock tables; drop table t1; disconnect waiter; connection default; -show status like 'Table_locks_waited'; +--disable_query_log +eval SET @tlwa= SUBSTRING_INDEX('$tlwa', ' ', -1); +eval SET @tlwb= SUBSTRING_INDEX('$tlwb', ' ', -1); +--enable_query_log +select @tlwa < @tlwb; --echo End of 5.1 tests From 37513aa54b383f030486694ac62b19887704f071 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Jan 2008 14:47:26 +0100 Subject: [PATCH 08/56] BUG#32434: Replication doesn't work between 5.2.1-a_drop6p9-log and 5.1.22-ndb-6.3.6-telco Problem: When slave reads format_description_log_event, it checks if the master is a version that uses an old binlog format. See also BUG#27779. Not all possible server_versions were listed. Fix: Check for all server_versions which use the old binlog_format. sql/log_event.cc: In the place where we check if server_version indicates that master is the alcatel branch, we now check all currently possible alcatel versions, not just a subset. Added comment to explain which clones are affected. --- sql/log_event.cc | 65 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 45478020a36..df8c90c4a83 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2944,18 +2944,63 @@ Format_description_log_event(const char* buf, If post_header_len is null, it means malloc failed, and is_valid will fail, so there is no need to do anything. - The trees which have wrong event id's are: - mysql-5.1-wl2325-5.0-drop6p13-alpha, mysql-5.1-wl2325-5.0-drop6, - mysql-5.1-wl2325-5.0, mysql-5.1-wl2325-no-dd (`grep -C2 - BEGIN_LOAD_QUERY_EVENT /home/bk/ * /sql/log_event.h`). The - corresponding version (`grep mysql, configure.in` in those trees) - strings are 5.2.2-a_drop6p13-alpha, 5.2.2-a_drop6p13c, - 5.1.5-a_drop5p20, 5.1.2-a_drop5p5. + The trees in which events have wrong id's are: + + mysql-5.1-wl1012.old mysql-5.1-wl2325-5.0-drop6p13-alpha + mysql-5.1-wl2325-5.0-drop6 mysql-5.1-wl2325-5.0 + mysql-5.1-wl2325-no-dd + + (this was found by grepping for two lines in sequence where the + first matches "FORMAT_DESCRIPTION_EVENT," and the second matches + "TABLE_MAP_EVENT," in log_event.h in all trees) + + In these trees, the following server_versions existed since + TABLE_MAP_EVENT was introduced: + + 5.1.1-a_drop5p3 5.1.1-a_drop5p4 5.1.1-alpha + 5.1.2-a_drop5p10 5.1.2-a_drop5p11 5.1.2-a_drop5p12 + 5.1.2-a_drop5p13 5.1.2-a_drop5p14 5.1.2-a_drop5p15 + 5.1.2-a_drop5p16 5.1.2-a_drop5p16b 5.1.2-a_drop5p16c + 5.1.2-a_drop5p17 5.1.2-a_drop5p4 5.1.2-a_drop5p5 + 5.1.2-a_drop5p6 5.1.2-a_drop5p7 5.1.2-a_drop5p8 + 5.1.2-a_drop5p9 5.1.3-a_drop5p17 5.1.3-a_drop5p17b + 5.1.3-a_drop5p17c 5.1.4-a_drop5p18 5.1.4-a_drop5p19 + 5.1.4-a_drop5p20 5.1.4-a_drop6p0 5.1.4-a_drop6p1 + 5.1.4-a_drop6p2 5.1.5-a_drop5p20 5.2.0-a_drop6p3 + 5.2.0-a_drop6p4 5.2.0-a_drop6p5 5.2.0-a_drop6p6 + 5.2.1-a_drop6p10 5.2.1-a_drop6p11 5.2.1-a_drop6p12 + 5.2.1-a_drop6p6 5.2.1-a_drop6p7 5.2.1-a_drop6p8 + 5.2.2-a_drop6p13 5.2.2-a_drop6p13-alpha 5.2.2-a_drop6p13b + 5.2.2-a_drop6p13c + + (this was found by grepping for "mysql," in all historical + versions of configure.in in the trees listed above). + + There are 5.1.1-alpha versions that use the new event id's, so we + do not test that version string. So replication from 5.1.1-alpha + with the other event id's to a new version does not work. + Moreover, we can safely ignore the part after drop[56]. This + allows us to simplify the big list above to the following regexes: + + 5\.1\.[1-5]-a_drop5.* + 5\.1\.4-a_drop6.* + 5\.2\.[0-2]-a_drop6.* + + This is what we test for in the 'if' below. */ if (post_header_len && - (strncmp(server_version, "5.1.2-a_drop5", 13) == 0 || - strncmp(server_version, "5.1.5-a_drop5", 13) == 0 || - strncmp(server_version, "5.2.2-a_drop6", 13) == 0)) + server_version[0] == '5' && server_version[1] == '.' && + server_version[3] == '.' && + strncmp(server_version + 5, "-a_drop", 7) == 0 && + ((server_version[2] == '1' && + server_version[4] >= '1' && server_version[4] <= '5' && + server_version[12] == '5') || + (server_version[2] == '1' && + server_version[4] == '4' && + server_version[12] == '6') || + (server_version[2] == '2' && + server_version[4] >= '0' && server_version[4] <= '2' && + server_version[12] == '6'))) { if (number_of_event_types != 22) { From ed9e73077dd9562b77485fc034f5e3b7688b5dd0 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Jan 2008 14:12:40 +0100 Subject: [PATCH 09/56] BUG#34141: mysqlbinlog cannot read 4.1 binlogs containing load data infile Main problem: mysql 5.1 cannot read binlogs from 4.1. Subproblem 1: There is a mistake in sql_ex_info::init. The read_str() function updates its first argument to point to the next character to read. However, it is applied only to a copy of the buffer pointer, so the real buffer pointer is not updated. Fix 1: do not take a copy of the buffer pointer. The copy was needed because sql_ex_info::init does not use the const attribute on some of its arguments. So we add the const attribute, too. Subproblem 2: The first BINLOG statement is asserted to be a FORMAT_DESCRIPTION_LOG_EVENT, but 4.1 binlogs begin with START_EVENT_V3. Fix 2: allow START_EVENT_V3 too. mysql-test/suite/binlog/std_data/binlog_old_version_4_1.000001: New BitKeeper file ``mysql-test/suite/binlog/std_data/binlog_old_version_4_1.000001'' mysql-test/suite/binlog/r/binlog_old_versions.result: Updated result file. mysql-test/suite/binlog/t/binlog_old_versions.test: Added a test reading an old 4.1 binlog. sql/log_event.cc: 1. Added const keyword at the following places: - input buffer for pretty_print_str - input buffer for write_str - input buffer, end pointer, and return value from sql_ex_info::init 2. Fixed the bug by not taking a copy of buf before calling read_str in sql_ex_info::init(). sql/log_event.h: Added const keyword to fields of the sql_ex_info struct. Added const keyword to arguments and return value of sql_ex_info::init sql/sql_binlog.cc: The first BINLOG statement must describe the format for future BINLOG statements. Otherwise, we do not know how to read the BINLOG statement. Problem: only FORMAT_DESCRIPTION_EVENT is currently allowed as the first event. Binlogs from 4.1 begin with a START_EVENT_V3, which serves the same purpose. Fix: We now allow the first BINLOG statement to be a START_EVENT_V3, as well as a FORMAT_DESCRIPTION_EVENT. --- .../suite/binlog/r/binlog_old_versions.result | 10 ++++++++ .../std_data/binlog_old_version_4_1.000001 | Bin 0 -> 149436 bytes .../suite/binlog/t/binlog_old_versions.test | 15 +++++++++++ sql/log_event.cc | 24 +++++++++--------- sql/log_event.h | 12 ++++----- sql/sql_binlog.cc | 7 +++-- 6 files changed, 46 insertions(+), 22 deletions(-) create mode 100644 mysql-test/suite/binlog/std_data/binlog_old_version_4_1.000001 diff --git a/mysql-test/suite/binlog/r/binlog_old_versions.result b/mysql-test/suite/binlog/r/binlog_old_versions.result index a514f9278a6..77289252b4c 100644 --- a/mysql-test/suite/binlog/r/binlog_old_versions.result +++ b/mysql-test/suite/binlog/r/binlog_old_versions.result @@ -29,6 +29,16 @@ SELECT COUNT(*) FROM t3; COUNT(*) 17920 DROP TABLE t1, t2, t3; +==== Read binlog from version 4.1 ==== +SELECT * FROM t1 ORDER BY a; +a b +0 last_insert_id +4 four +190243 random +SELECT COUNT(*) FROM t3; +COUNT(*) +17920 +DROP TABLE t1, t3; ==== Read binlog from alcatel tree (mysql-5.1-wl2325-5.0-drop6) ==== SELECT * FROM t1 ORDER BY a; a b diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_4_1.000001 b/mysql-test/suite/binlog/std_data/binlog_old_version_4_1.000001 new file mode 100644 index 0000000000000000000000000000000000000000..66db9668d46eeb5a3659253091a62b79d718f0cb GIT binary patch literal 149436 zcmeI5O=}xh6oyA`3W=fJwu?dsx`-2!kgqOFt2V;8O&o}wK%m9USYt~>8Ntlh#QUzh z?KYeImqMYxqR@X)dfs#Aj+>eWX{1&A1f-dftQko;y7zg{*Znh}mY+UX@c`_RA zkJA0&*AGW&b0^)((rMY;Nb~e?l2u!u-@bM&9qn%K?2ghe(nn`Id&5WFS--UNyz#TW z`>gkLRzKZcozC9WhkC(vyZzq1{8h4{^If)E_|QqxU1($v`b(03UT9}`Z}en8-PzrL ztatxx`0(jyFWvg;)s6J((fp*k>X-XKFZ;}Hd;a<#e`!9pgXGQ6zinvSUFWGCocfZmteTwEo3@#ko5MWIvrW4lzR>+qqkH?PW!x6yxHm12vr4t`I_)oO?SSq=PzlB zN@ud4k8kw4Vea2euGi+pS-98J`CK30?(M^C<409-I<=SUiFQ|CUEKGVg~!8NYM+?; zSABlqXVj(4+zS0K_*SpBooSiPw0Cl-D{A8(NIT&??VkU+Jvi4#(qr=~KBV*OJ=zOx zXXba)OomX*YBz|Y8W(nDd!Q<_W}^2}RA&FWq;~vL7!gKf=716TD5W1)Rx=X$Si?wE z#_38EX|N5SewfaD7AyQaVLDq1vV5HJVJ0vPOyooZ6D>pP7?J&g0BbXY733a9gb}Um zGr)*2B8&(>5za;%2^*Y^I2$Lery7qn9&02%VUM1{IKUdP2CM;Vz#6b7im%xaunrj@ zniok0v2VfBieiA4d?NCR6r>M=OM9&f*KRZtqWC1Gd1jmq9U4A}o%zp&%*MqAjI;I9QN_na-&8Seb({B8&(l^3nk6&Zs+U zAE?J}%G|geblZ z4&+#qV{K#OqB&%MHDC=`1J-~wU=3Kawnvt?i#JfbXlP{V2*cb41_2dd4Oj!#$F$ok zvxeeDiWgf4W*)7b#xsVyK0w^ERAH>}(0Q4qy#f z1J-~wU=3K4ltxloM^PlDk(73-gdUhz`E8n6be0c*e-um-FFYrxvp$jq^oBur8``Q8*-3^d~x&P1I6Z zZX4m=yNonNEKv%3fHhzZSOeC8HDFCD2+qbeG(Rs;rcH&`x7*C)VFF7PlTTcKar+I+U<=^ zyHUJI@uJt_S^3Ab%x1zRGmCcPQ>KpPMh?%o#0$G~Rfc0k)SXdx)-THqb*2G?C_Yhq zqWDDd1>{528R`sm23XV3!3CGtNO=aRv!&)oz#6b7>_ONgggflFK-dGY2CM;Vz#6ay ztoyIR2Ur8vfHhzZSldY0;IXzMGnVgU`A$nC(!5AMkz5URw`ObD^Exq_q02hRCkku) zQZhuz5UUKa%Fr6h#Hhum7Jp?$juBx*7!eH}Xy_pQMjvacJ?LXiA8YzpcPgDe*8M7c z0BgV+um-FFYrvW^YQi2JP|+!kPHCr8D|@wwaa^)fjRfMprp&lVC(CzU95?`Lz#6ay ztO0Al8nC`NKYAWo$VQ_-5&en!c`q>{`vuXT$jso7k|ETY*?}e+PvZ5xwuR=!*#~uo zIzyeI&QNDUDDsKOCnBGSd?NCRx|jxGkA8|Aum-FFYrq`cB%lF~>@BPorfG?LOf=|xgn zzj!HN4Oj!#fHhzZSd)}SQd$R8G`TV~GMPDC!#WQdTF7jin`Di7Ma0gQ&Mm=+qVdEn zMuZVr7e1K*0ayaCG6Mpzmaivj$=2)}T>A-`&f+u{w@hbDXG~}IYoI@oCNicoOS`U^ z&O*9v(=ALK_B2`8V40@q&bQD=Ei18bH{7Ss41iFmlojWqq&7z{I-iM z>I`*;I@6G#ASu-zI2%!Cl3vbOsIx4$Z^HD~%I(`0n`^q3ml8;77^3%qK z?db+8X#hCVeCUW2x1bWieJ7+6RB|yz>NUZA`5L`08dN&eupmMLmCEBdX%gHgxKD8Z z-0^6?3w)4(wT4Gl^|ZXms?3^+8tusS2v~p(C%W)CN7IFmE`0swM>ikMu5{s}3twNz!iXf` zS$v3QA+2XKhCmcFZubMO#RIR3K0i7G=}hqF6JO JH`}o-%3l=-N?iZ| literal 0 HcmV?d00001 diff --git a/mysql-test/suite/binlog/t/binlog_old_versions.test b/mysql-test/suite/binlog/t/binlog_old_versions.test index 9fb7343e761..b2922809b1b 100644 --- a/mysql-test/suite/binlog/t/binlog_old_versions.test +++ b/mysql-test/suite/binlog/t/binlog_old_versions.test @@ -51,6 +51,21 @@ SELECT COUNT(*) FROM t3; DROP TABLE t1, t2, t3; +--echo ==== Read binlog from version 4.1 ==== + +# In this version, neither row-based binlogging nor Xid events +# existed, so the binlog was generated without the "row-based tests" +# part and the "get xid event" part, and it does not create table t2. + +# Read binlog. +--exec $MYSQL_BINLOG suite/binlog/std_data/binlog_old_version_4_1.000001 | $MYSQL +# Show result. +SELECT * FROM t1 ORDER BY a; +SELECT COUNT(*) FROM t3; +# Reset. +DROP TABLE t1, t3; + + --echo ==== Read binlog from alcatel tree (mysql-5.1-wl2325-5.0-drop6) ==== # In this version, it was not possible to switch between row-based and diff --git a/sql/log_event.cc b/sql/log_event.cc index 45478020a36..070e6ab4c12 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -212,9 +212,9 @@ uint debug_not_change_ts_if_art_event= 1; // bug#29309 simulation */ #ifdef MYSQL_CLIENT -static void pretty_print_str(IO_CACHE* cache, char* str, int len) +static void pretty_print_str(IO_CACHE* cache, const char* str, int len) { - char* end = str + len; + const char* end = str + len; my_b_printf(cache, "\'"); while (str < end) { @@ -277,9 +277,9 @@ inline int ignored_error_code(int err_code) */ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -static char *pretty_print_str(char *packet, char *str, int len) +static char *pretty_print_str(char *packet, const char *str, int len) { - char *end= str + len; + const char *end= str + len; char *pos= packet; *pos++= '\''; while (str < end) @@ -388,7 +388,7 @@ static void cleanup_load_tmpdir() write_str() */ -static bool write_str(IO_CACHE *file, char *str, uint length) +static bool write_str(IO_CACHE *file, const char *str, uint length) { uchar tmp[1]; tmp[0]= (uchar) length; @@ -6011,7 +6011,8 @@ bool sql_ex_info::write_data(IO_CACHE* file) sql_ex_info::init() */ -char *sql_ex_info::init(char *buf, char *buf_end, bool use_new_format) +const char *sql_ex_info::init(const char *buf, const char *buf_end, + bool use_new_format) { cached_new_format = use_new_format; if (use_new_format) @@ -6024,12 +6025,11 @@ char *sql_ex_info::init(char *buf, char *buf_end, bool use_new_format) the case when we have old format because we will be reusing net buffer to read the actual file before we write out the Create_file event. */ - const char *ptr= buf; - if (read_str(&ptr, buf_end, (const char **) &field_term, &field_term_len) || - read_str(&ptr, buf_end, (const char **) &enclosed, &enclosed_len) || - read_str(&ptr, buf_end, (const char **) &line_term, &line_term_len) || - read_str(&ptr, buf_end, (const char **) &line_start, &line_start_len) || - read_str(&ptr, buf_end, (const char **) &escaped, &escaped_len)) + if (read_str(&buf, buf_end, &field_term, &field_term_len) || + read_str(&buf, buf_end, &enclosed, &enclosed_len) || + read_str(&buf, buf_end, &line_term, &line_term_len) || + read_str(&buf, buf_end, &line_start, &line_start_len) || + read_str(&buf, buf_end, &escaped, &escaped_len)) return 0; opt_flags = *buf++; } diff --git a/sql/log_event.h b/sql/log_event.h index 31c1ab7173a..c85d620d831 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -152,11 +152,11 @@ struct old_sql_ex struct sql_ex_info { sql_ex_info() {} /* Remove gcc warning */ - char* field_term; - char* enclosed; - char* line_term; - char* line_start; - char* escaped; + const char* field_term; + const char* enclosed; + const char* line_term; + const char* line_start; + const char* escaped; int cached_new_format; uint8 field_term_len,enclosed_len,line_term_len,line_start_len, escaped_len; char opt_flags; @@ -171,7 +171,7 @@ struct sql_ex_info line_start_len + escaped_len + 6 : 7); } bool write_data(IO_CACHE* file); - char* init(char* buf,char* buf_end,bool use_new_format); + const char* init(const char* buf, const char* buf_end, bool use_new_format); bool new_format() { return ((cached_new_format != -1) ? cached_new_format : diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc index 543b1af9fc0..778aa46149c 100644 --- a/sql/sql_binlog.cc +++ b/sql/sql_binlog.cc @@ -159,14 +159,13 @@ void mysql_client_binlog_statement(THD* thd) */ if (!have_fd_event) { - if (bufptr[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) + int type = bufptr[EVENT_TYPE_OFFSET]; + if (type == FORMAT_DESCRIPTION_EVENT || type == START_EVENT_V3) have_fd_event= TRUE; else { my_error(ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT, - MYF(0), - Log_event::get_type_str( - (Log_event_type)bufptr[EVENT_TYPE_OFFSET])); + MYF(0), Log_event::get_type_str((Log_event_type)type)); goto end; } } From 39509d64c370b5a309f1c905d847ea0f92921327 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Jan 2008 18:27:41 +0300 Subject: [PATCH 10/56] A fix and a test case for Bug#34166 Server crash in SHOW OPEN TABLES and pre-locking. The crash was caused by an implicit assumption in check_table_access() that table_list parameter is always a part of lex->query_tables. When iterating over the passed list of tables, check_table_access() used to stop only when lex->query_tables_last_not_own was reached. In case of pre-locking, lex->query_tables_last_own is not NULL and points to some element of lex->query_tables. When the parameter of check_table_access() was not part of lex->query_tables, loop invariant could never be violated and a crash would happen when the current table pointer would point beyond the end of the provided list. The fix is to change the signature of check_table_access() to also accept a numeric limit of loop iterations, similarly to check_grant(), and supply this limit in all places when we want to check access of tables that are outside lex->query_tables, or just want to check access to one table. mysql-test/r/information_schema.result: Update test results (Bug#34166). mysql-test/t/information_schema.test: Add a test case for Bug#34166. sql/mysql_priv.h: Change signature of check_table_access() to accept a numeric limit of tables to check. sql/sp_head.cc: Update to the new signature of check_table_access(). sql/sql_acl.cc: Improve code clarity: if there is a numeric limit, we should not need to look at first_not_own_table. sql/sql_base.cc: Update to the new signature of check_table_access(). sql/sql_cache.cc: Update to the new signature of check_table_access(). sql/sql_parse.cc: Update to the new signature of check_table_access(). Change check_table_access() to accept an optional numeric limit of tables to check. A crash would happen when check_table_access() was passed a list of tables that is not part of lex->query_tables and lex->query_tables_last_own was not NULL. sql/sql_plugin.cc: Update to the new signature of check_table_access(). sql/sql_prepare.cc: Update to the new signature of check_table_access(). sql/sql_show.cc: Update to the new signature of check_table_access(). Ensure that check_table_access() only checks access to the first table in the table list when called from list_open_tables(). list_open_tables() supplies a table list that is created on stack, whereas check_table_access() used to assume that the supplied list is a part of thd->lex. sql/sql_trigger.cc: Update to the new signature of check_table_access(). sql/sql_view.cc: Update to the new signature of check_table_access(). --- mysql-test/r/information_schema.result | 15 ++++++ mysql-test/t/information_schema.test | 22 ++++++++ sql/mysql_priv.h | 4 +- sql/sp_head.cc | 4 +- sql/sql_acl.cc | 2 +- sql/sql_base.cc | 2 +- sql/sql_cache.cc | 2 +- sql/sql_parse.cc | 74 ++++++++++++++------------ sql/sql_plugin.cc | 2 +- sql/sql_prepare.cc | 6 +-- sql/sql_show.cc | 6 +-- sql/sql_trigger.cc | 2 +- sql/sql_view.cc | 6 +-- 13 files changed, 94 insertions(+), 53 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 0cb4b10a789..dc76a2693be 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1619,4 +1619,19 @@ Db Name Definer Time zone Type Execute at Interval value Interval field Starts E show events where Db= 'information_schema'; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation use test; +# +# Bug#34166: Server crash in SHOW OPEN TABLES and prelocking +# +drop table if exists t1; +drop function if exists f1; +create table t1 (a int); +create function f1() returns int +begin +insert into t1 (a) values (1); +return 0; +end| +show open tables where f1()=0; +show open tables where f1()=0; +drop table t1; +drop function f1; End of 5.1 tests. diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 2a9319fe010..6e76a043645 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1248,4 +1248,26 @@ show events from information_schema; show events where Db= 'information_schema'; use test; +--echo # +--echo # Bug#34166: Server crash in SHOW OPEN TABLES and prelocking +--echo # +--disable_warnings +drop table if exists t1; +drop function if exists f1; +--enable_warnings +create table t1 (a int); +delimiter |; +create function f1() returns int +begin + insert into t1 (a) values (1); + return 0; +end| +delimiter ;| +--disable_result_log +show open tables where f1()=0; +show open tables where f1()=0; +--enable_result_log +drop table t1; +drop function f1; + --echo End of 5.1 tests. diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f61267711b0..696e0bce50c 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1015,7 +1015,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, bool check_access(THD *thd, ulong access, const char *db, ulong *save_priv, bool no_grant, bool no_errors, bool schema_db); bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables, - bool no_errors); + uint number, bool no_errors); bool check_global_access(THD *thd, ulong want_access); #else inline bool check_access(THD *thd, ulong access, const char *db, @@ -1027,7 +1027,7 @@ inline bool check_access(THD *thd, ulong access, const char *db, return false; } inline bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables, - bool no_errors) + uint number, bool no_errors) { return false; } inline bool check_global_access(THD *thd, ulong want_access) { return false; } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 74f5bf55828..036101021f5 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2265,7 +2265,7 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access) bzero((char*) &tables,sizeof(tables)); tables.db= (char*) "mysql"; tables.table_name= tables.alias= (char*) "proc"; - *full_access= (!check_table_access(thd, SELECT_ACL, &tables, 1) || + *full_access= (!check_table_access(thd, SELECT_ACL, &tables, 1, TRUE) || (!strcmp(sp->m_definer_user.str, thd->security_ctx->priv_user) && !strcmp(sp->m_definer_host.str, @@ -2712,7 +2712,7 @@ int sp_instr::exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables) Check whenever we have access to tables for this statement and open and lock them before executing instructions core function. */ - if (check_table_access(thd, SELECT_ACL, tables, 0) + if (check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE) || open_and_lock_tables(thd, tables)) result= -1; else diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index d2d26da229a..da0b7bb89fc 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3862,7 +3862,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, of other queries). For simple queries first_not_own_table is 0. */ for (i= 0, table= tables; - table != first_not_own_table && i < number; + i < number && table != first_not_own_table; table= table->next_global, i++) { /* Remove SHOW_VIEW_ACL, because it will be checked during making view */ diff --git a/sql/sql_base.cc b/sql/sql_base.cc index c50c89d6937..b79ce3fe70e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -799,7 +799,7 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild) table_list.table_name= share->table_name.str; table_list.grant.privilege=0; - if (check_table_access(thd,SELECT_ACL | EXTRA_ACL,&table_list,1)) + if (check_table_access(thd,SELECT_ACL | EXTRA_ACL,&table_list, 1, TRUE)) continue; /* need to check if we haven't already listed it */ for (table= open_list ; table ; table=table->next) diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 47301e1d205..be2322360fb 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1378,7 +1378,7 @@ def_week_frmt: %lu", table_list.db = table->db(); table_list.alias= table_list.table_name= table->table(); #ifndef NO_EMBEDDED_ACCESS_CHECKS - if (check_table_access(thd,SELECT_ACL,&table_list,1)) + if (check_table_access(thd,SELECT_ACL,&table_list, 1, TRUE)) { DBUG_PRINT("qcache", ("probably no SELECT access to %s.%s => return to normal processing", diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b60a72e4c53..3a89b745d4a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -495,7 +495,7 @@ static bool check_merge_table_access(THD *thd, char *db, tlist->db= db; /* purecov: inspected */ } error= check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL, - table_list,0); + table_list, UINT_MAX, FALSE); } return error; } @@ -1994,7 +1994,7 @@ mysql_execute_command(THD *thd) res= check_table_access(thd, lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL, - all_tables, 0); + all_tables, UINT_MAX, FALSE); } else res= check_access(thd, @@ -2019,7 +2019,7 @@ mysql_execute_command(THD *thd) break; } case SQLCOM_DO: - if (check_table_access(thd, SELECT_ACL, all_tables, 0) || + if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) || open_and_lock_tables(thd, all_tables)) goto error; @@ -2116,7 +2116,7 @@ mysql_execute_command(THD *thd) case SQLCOM_BACKUP_TABLE: { DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_table_access(thd, SELECT_ACL, all_tables, 0) || + if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) || check_global_access(thd, FILE_ACL)) goto error; /* purecov: inspected */ thd->enable_slow_log= opt_log_slow_admin_statements; @@ -2128,7 +2128,7 @@ mysql_execute_command(THD *thd) case SQLCOM_RESTORE_TABLE: { DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_table_access(thd, INSERT_ACL, all_tables, 0) || + if (check_table_access(thd, INSERT_ACL, all_tables, UINT_MAX, FALSE) || check_global_access(thd, FILE_ACL)) goto error; /* purecov: inspected */ thd->enable_slow_log= opt_log_slow_admin_statements; @@ -2677,7 +2677,8 @@ end_with_restore_list: case SQLCOM_CHECKSUM: { DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_table_access(thd, SELECT_ACL | EXTRA_ACL, all_tables, 0)) + if (check_table_access(thd, SELECT_ACL | EXTRA_ACL, all_tables, + UINT_MAX, FALSE)) goto error; /* purecov: inspected */ res = mysql_checksum_table(thd, first_table, &lex->check_opt); break; @@ -2685,7 +2686,8 @@ end_with_restore_list: case SQLCOM_REPAIR: { DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0)) + if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, + UINT_MAX, FALSE)) goto error; /* purecov: inspected */ thd->enable_slow_log= opt_log_slow_admin_statements; res= mysql_repair_table(thd, first_table, &lex->check_opt); @@ -2704,7 +2706,8 @@ end_with_restore_list: case SQLCOM_CHECK: { DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_table_access(thd, SELECT_ACL | EXTRA_ACL , all_tables, 0)) + if (check_table_access(thd, SELECT_ACL | EXTRA_ACL , all_tables, + UINT_MAX, FALSE)) goto error; /* purecov: inspected */ thd->enable_slow_log= opt_log_slow_admin_statements; res = mysql_check_table(thd, first_table, &lex->check_opt); @@ -2715,7 +2718,8 @@ end_with_restore_list: case SQLCOM_ANALYZE: { DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0)) + if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, + UINT_MAX, FALSE)) goto error; /* purecov: inspected */ thd->enable_slow_log= opt_log_slow_admin_statements; res= mysql_analyze_table(thd, first_table, &lex->check_opt); @@ -2735,7 +2739,8 @@ end_with_restore_list: case SQLCOM_OPTIMIZE: { DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0)) + if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, + UINT_MAX, FALSE)) goto error; /* purecov: inspected */ thd->enable_slow_log= opt_log_slow_admin_statements; res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ? @@ -3064,7 +3069,7 @@ end_with_restore_list: DBUG_ASSERT(first_table == all_tables && first_table != 0); if (!lex->drop_temporary) { - if (check_table_access(thd, DROP_ACL, all_tables, 0)) + if (check_table_access(thd, DROP_ACL, all_tables, UINT_MAX, FALSE)) goto error; /* purecov: inspected */ if (end_active_trans(thd)) goto error; @@ -3168,7 +3173,7 @@ end_with_restore_list: if (lex->autocommit && end_active_trans(thd)) goto error; - if ((check_table_access(thd, SELECT_ACL, all_tables, 0) || + if ((check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) || open_and_lock_tables(thd, all_tables))) goto error; if (lex->one_shot_set && not_all_support_one_shot(lex_var_list)) @@ -3210,7 +3215,8 @@ end_with_restore_list: /* we must end the trasaction first, regardless of anything */ if (end_active_trans(thd)) goto error; - if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, 0)) + if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, + UINT_MAX, FALSE)) goto error; thd->in_lock_tables=1; thd->options|= OPTION_TABLE_LOCK; @@ -3704,7 +3710,7 @@ end_with_restore_list: #endif case SQLCOM_HA_OPEN: DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_table_access(thd, SELECT_ACL, all_tables, 0)) + if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE)) goto error; res= mysql_ha_open(thd, first_table, 0); break; @@ -3952,7 +3958,7 @@ create_sp_error: This will cache all SP and SF and open and lock all tables required for execution. */ - if (check_table_access(thd, SELECT_ACL, all_tables, 0) || + if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) || open_and_lock_tables(thd, all_tables)) goto error; @@ -4299,7 +4305,7 @@ create_sp_error: } case SQLCOM_DROP_VIEW: { - if (check_table_access(thd, DROP_ACL, all_tables, 0) || + if (check_table_access(thd, DROP_ACL, all_tables, UINT_MAX, FALSE) || end_active_trans(thd)) goto error; /* Conditionally writes to binlog. */ @@ -4778,7 +4784,7 @@ bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables) subselects_tables= subselects_tables->next_global; } if (subselects_tables && - (check_table_access(thd, SELECT_ACL, subselects_tables, 0))) + (check_table_access(thd, SELECT_ACL, subselects_tables, UINT_MAX, FALSE))) return 1; } return 0; @@ -5011,39 +5017,39 @@ static bool check_show_access(THD *thd, TABLE_LIST *table) /* Check the privilege for all used tables. - SYNOPSYS - check_table_access() - thd Thread context - want_access Privileges requested - tables List of tables to be checked - no_errors FALSE/TRUE - report/don't report error to - the client (using my_error() call). + @param thd Thread context + @param want_access Privileges requested + @param tables List of tables to be checked + @param number Check at most this number of tables. + @param no_errors FALSE/TRUE - report/don't report error to + the client (using my_error() call). - NOTES + @note Table privileges are cached in the table list for GRANT checking. This functions assumes that table list used and thd->lex->query_tables_own_last value correspond to each other (the latter should be either 0 or point to next_global member of one of elements of this table list). - RETURN VALUE - FALSE - OK - TRUE - Access denied + @retval FALSE OK + @retval TRUE Access denied */ bool check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, - bool no_errors) + uint number, bool no_errors) { TABLE_LIST *org_tables= tables; TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table(); + uint i= 0; Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx; /* The check that first_not_own_table is not reached is for the case when the given table list refers to the list for prelocking (contains tables of other queries). For simple queries first_not_own_table is 0. */ - for (; tables != first_not_own_table; tables= tables->next_global) + for (; i < number && tables != first_not_own_table; + tables= tables->next_global, i++) { if (tables->security_ctx) sctx= tables->security_ctx; @@ -5093,7 +5099,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, } thd->security_ctx= backup_ctx; return check_grant(thd,want_access & ~EXTRA_ACL,org_tables, - test(want_access & EXTRA_ACL), UINT_MAX, no_errors); + test(want_access & EXTRA_ACL), number, no_errors); deny: thd->security_ctx= backup_ctx; return TRUE; @@ -6855,7 +6861,7 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables) /* sql_yacc guarantees that tables and aux_tables are not zero */ DBUG_ASSERT(aux_tables != 0); - if (check_table_access(thd, SELECT_ACL, tables, 0)) + if (check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) DBUG_RETURN(TRUE); /* @@ -6864,7 +6870,7 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables) call check_table_access() safely. */ thd->lex->query_tables_own_last= 0; - if (check_table_access(thd, DELETE_ACL, aux_tables, 0)) + if (check_table_access(thd, DELETE_ACL, aux_tables, UINT_MAX, FALSE)) { thd->lex->query_tables_own_last= save_query_tables_own_last; DBUG_RETURN(TRUE); @@ -7108,7 +7114,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, } } #endif - if (tables && check_table_access(thd, SELECT_ACL, tables,0)) + if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) goto err; } else if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 2a86844c8c6..5cd056807a6 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1619,7 +1619,7 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl bzero(&tables, sizeof(tables)); tables.db= (char *)"mysql"; tables.table_name= tables.alias= (char *)"plugin"; - if (check_table_access(thd, INSERT_ACL, &tables, 0)) + if (check_table_access(thd, INSERT_ACL, &tables, 1, FALSE)) DBUG_RETURN(TRUE); /* need to open before acquiring LOCK_plugin or it will deadlock */ diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 52e6fcc5d58..b76ed0852f5 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1272,7 +1272,7 @@ static int mysql_test_select(Prepared_statement *stmt, ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL; if (tables) { - if (check_table_access(thd, privilege, tables,0)) + if (check_table_access(thd, privilege, tables, UINT_MAX, FALSE)) goto error; } else if (check_access(thd, privilege, any_db,0,0,0,0)) @@ -1342,7 +1342,7 @@ static bool mysql_test_do_fields(Prepared_statement *stmt, THD *thd= stmt->thd; DBUG_ENTER("mysql_test_do_fields"); - if (tables && check_table_access(thd, SELECT_ACL, tables, 0)) + if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) DBUG_RETURN(TRUE); if (open_normal_and_derived_tables(thd, tables, 0)) @@ -1374,7 +1374,7 @@ static bool mysql_test_set_fields(Prepared_statement *stmt, THD *thd= stmt->thd; set_var_base *var; - if (tables && check_table_access(thd, SELECT_ACL, tables, 0) || + if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE) || open_normal_and_derived_tables(thd, tables, 0)) goto error; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 20cf12b95c5..644aa3fd4cb 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4059,7 +4059,7 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond) proc_tables.table_name= proc_tables.alias= (char*) "proc"; proc_tables.table_name_length= 4; proc_tables.lock_type= TL_READ; - full_access= !check_table_access(thd, SELECT_ACL, &proc_tables, 1); + full_access= !check_table_access(thd, SELECT_ACL, &proc_tables, 1, TRUE); if (!(proc_table= open_proc_table_for_read(thd, &open_tables_state_backup))) { DBUG_RETURN(1); @@ -4447,10 +4447,8 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables, Table_triggers_list *triggers= tables->table->triggers; int event, timing; -#ifndef NO_EMBEDDED_ACCESS_CHECKS - if (check_table_access(thd, TRIGGER_ACL, tables, 1)) + if (check_table_access(thd, TRIGGER_ACL, tables, 1, TRUE)) goto ret; -#endif for (event= 0; event < (int)TRG_EVENT_MAX; event++) { diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index b421f57b7ab..7925eb3e95a 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -418,7 +418,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last; thd->lex->query_tables_own_last= 0; - err_status= check_table_access(thd, TRIGGER_ACL, tables, 0); + err_status= check_table_access(thd, TRIGGER_ACL, tables, 1, FALSE); thd->lex->query_tables_own_last= save_query_tables_own_last; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index f7223cafb5e..ec3f8b5e84c 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1123,8 +1123,8 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, if (!table->prelocking_placeholder && (old_lex->sql_command == SQLCOM_SELECT && old_lex->describe)) { - if (check_table_access(thd, SELECT_ACL, view_tables, 1) && - check_table_access(thd, SHOW_VIEW_ACL, table, 1)) + if (check_table_access(thd, SELECT_ACL, view_tables, UINT_MAX, TRUE) && + check_table_access(thd, SHOW_VIEW_ACL, table, UINT_MAX, TRUE)) { my_message(ER_VIEW_NO_EXPLAIN, ER(ER_VIEW_NO_EXPLAIN), MYF(0)); goto err; @@ -1134,7 +1134,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, (old_lex->sql_command == SQLCOM_SHOW_CREATE) && !table->belong_to_view) { - if (check_table_access(thd, SHOW_VIEW_ACL, table, 0)) + if (check_table_access(thd, SHOW_VIEW_ACL, table, UINT_MAX, FALSE)) goto err; } From 96f33937779296da12b9818dd4d4c21371558c0d Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Jan 2008 23:04:55 +0300 Subject: [PATCH 11/56] Fix a build failure (embedded server). --- sql/sql_show.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 644aa3fd4cb..bc5628f12c0 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4486,9 +4486,7 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables, } } } -#ifndef NO_EMBEDDED_ACCESS_CHECKS ret: -#endif DBUG_RETURN(0); } From c8839950911c7b455a6053b268374475a177d568 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Jan 2008 16:51:55 +0800 Subject: [PATCH 12/56] Post merge fix mysql-test/suite/rpl/t/rpl_loaddata_map-master.opt: Rename: mysql-test/t/rpl_loaddata_map-master.opt -> mysql-test/suite/rpl/t/rpl_loaddata_map-master.opt mysql-test/suite/rpl/t/rpl_loaddata_map-slave.opt: Rename: mysql-test/t/rpl_loaddata_map-slave.opt -> mysql-test/suite/rpl/t/rpl_loaddata_map-slave.opt --- mysql-test/include/show_binlog_events2.inc | 2 +- mysql-test/r/rpl_loaddata_map.result | 28 ------------------- .../suite/rpl/r/rpl_loaddata_map.result | 28 +++++++++++++++++++ mysql-test/{ => suite/rpl}/r/rpl_user.result | 18 ++++++------ .../rpl}/t/rpl_loaddata_map-master.opt | 0 .../rpl}/t/rpl_loaddata_map-slave.opt | 0 .../{ => suite/rpl}/t/rpl_loaddata_map.test | 9 +++--- mysql-test/{ => suite/rpl}/t/rpl_user.test | 5 +++- 8 files changed, 48 insertions(+), 42 deletions(-) delete mode 100644 mysql-test/r/rpl_loaddata_map.result create mode 100644 mysql-test/suite/rpl/r/rpl_loaddata_map.result rename mysql-test/{ => suite/rpl}/r/rpl_user.result (69%) rename mysql-test/{ => suite/rpl}/t/rpl_loaddata_map-master.opt (100%) rename mysql-test/{ => suite/rpl}/t/rpl_loaddata_map-slave.opt (100%) rename mysql-test/{ => suite/rpl}/t/rpl_loaddata_map.test (81%) rename mysql-test/{ => suite/rpl}/t/rpl_user.test (93%) diff --git a/mysql-test/include/show_binlog_events2.inc b/mysql-test/include/show_binlog_events2.inc index fa244c5a5a3..5dd272c562d 100644 --- a/mysql-test/include/show_binlog_events2.inc +++ b/mysql-test/include/show_binlog_events2.inc @@ -1,4 +1,4 @@ ---let $binlog_start=98 +--let $binlog_start=106 --replace_result $binlog_start --replace_column 2 # 5 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ diff --git a/mysql-test/r/rpl_loaddata_map.result b/mysql-test/r/rpl_loaddata_map.result deleted file mode 100644 index 9bb02f5db1b..00000000000 --- a/mysql-test/r/rpl_loaddata_map.result +++ /dev/null @@ -1,28 +0,0 @@ -stop slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -start slave; -create table t2 (id int not null primary key auto_increment); -select @@session.read_buffer_size - @@session.max_allowed_packet > 0 ; -@@session.read_buffer_size - @@session.max_allowed_packet > 0 -1 -load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2; -select count(*) from t2 /* 5 000 */; -count(*) -5000 -show binlog events in 'master-bin.000002' from 98; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000002 98 Query 1 # use `test`; create table t2 (id int not null primary key auto_increment) -master-bin.000002 221 Begin_load_query 1 # ;file_id=1;block_len=7168 -master-bin.000002 7412 Append_block 1 # ;file_id=1;block_len=7168 -master-bin.000002 14603 Append_block 1 # ;file_id=1;block_len=2048 -master-bin.000002 16674 Append_block 1 # ;file_id=1;block_len=7168 -master-bin.000002 23865 Append_block 1 # ;file_id=1;block_len=341 -master-bin.000002 24229 Execute_load_query 1 # use `test`; load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2 ;file_id=1 -select count(*) from t2 /* 5 000 */; -count(*) -5000 -drop table t1, t2; -end of the tests diff --git a/mysql-test/suite/rpl/r/rpl_loaddata_map.result b/mysql-test/suite/rpl/r/rpl_loaddata_map.result new file mode 100644 index 00000000000..4129a88946d --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_loaddata_map.result @@ -0,0 +1,28 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +create table t2 (id int not null primary key auto_increment); +select @@session.read_buffer_size - @@session.max_allowed_packet > 0 ; +@@session.read_buffer_size - @@session.max_allowed_packet > 0 +1 +load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2; +select count(*) from t2 /* 5 000 */; +count(*) +5000 +show binlog events in 'master-bin.000002' from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000002 # Query # # use `test`; create table t2 (id int not null primary key auto_increment) +master-bin.000002 # Begin_load_query # # ;file_id=#;block_len=# +master-bin.000002 # Append_block # # ;file_id=#;block_len=# +master-bin.000002 # Append_block # # ;file_id=#;block_len=# +master-bin.000002 # Append_block # # ;file_id=#;block_len=# +master-bin.000002 # Append_block # # ;file_id=#;block_len=# +master-bin.000002 # Execute_load_query # # use `test`; load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2 ;file_id=# +select count(*) from t2 /* 5 000 */; +count(*) +5000 +drop table t1, t2; +end of the tests diff --git a/mysql-test/r/rpl_user.result b/mysql-test/suite/rpl/r/rpl_user.result similarity index 69% rename from mysql-test/r/rpl_user.result rename to mysql-test/suite/rpl/r/rpl_user.result index 475579e7d33..dd48d513352 100644 --- a/mysql-test/r/rpl_user.result +++ b/mysql-test/suite/rpl/r/rpl_user.result @@ -5,6 +5,9 @@ reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; reset master; +set sql_log_bin=0; +delete from mysql.user where Host='fakehost'; +set sql_log_bin=1; delete from mysql.user where Host='fakehost'; create user 'foo'@'fakehost'; create user 'foo'@'fakehost', 'bar'@'fakehost'; @@ -31,12 +34,11 @@ drop user 'not_exist_user1'@'fakehost', 'not_exist_user2'@'fakehost'; ERROR HY000: Operation DROP USER failed for 'not_exist_user1'@'fakehost','not_exist_user2'@'fakehost' select Host,User from mysql.user where Host='fakehost'; Host User -show binlog events from 98; +show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 98 Query 1 # use `test`; delete from mysql.user where Host='fakehost' -master-bin.000001 205 Query 1 # use `test`; create user 'foo'@'fakehost' -master-bin.000001 296 Query 1 # use `test`; create user 'foo'@'fakehost', 'bar'@'fakehost' -master-bin.000001 405 Query 1 # use `test`; rename user 'foo'@'fakehost' to 'foofoo'@'fakehost' -master-bin.000001 519 Query 1 # use `test`; rename user 'not_exist_user1'@'fakehost' to 'foobar'@'fakehost', 'bar'@'fakehost' to 'barbar'@'fakehost' -master-bin.000001 686 Query 1 # use `test`; drop user 'foofoo'@'fakehost' -master-bin.000001 778 Query 1 # use `test`; drop user 'not_exist_user1'@'fakehost', 'barbar'@'fakehost' +master-bin.000001 # Query # # use `test`; create user 'foo'@'fakehost' +master-bin.000001 # Query # # use `test`; create user 'foo'@'fakehost', 'bar'@'fakehost' +master-bin.000001 # Query # # use `test`; rename user 'foo'@'fakehost' to 'foofoo'@'fakehost' +master-bin.000001 # Query # # use `test`; rename user 'not_exist_user1'@'fakehost' to 'foobar'@'fakehost', 'bar'@'fakehost' to 'barbar'@'fakehost' +master-bin.000001 # Query # # use `test`; drop user 'foofoo'@'fakehost' +master-bin.000001 # Query # # use `test`; drop user 'not_exist_user1'@'fakehost', 'barbar'@'fakehost' diff --git a/mysql-test/t/rpl_loaddata_map-master.opt b/mysql-test/suite/rpl/t/rpl_loaddata_map-master.opt similarity index 100% rename from mysql-test/t/rpl_loaddata_map-master.opt rename to mysql-test/suite/rpl/t/rpl_loaddata_map-master.opt diff --git a/mysql-test/t/rpl_loaddata_map-slave.opt b/mysql-test/suite/rpl/t/rpl_loaddata_map-slave.opt similarity index 100% rename from mysql-test/t/rpl_loaddata_map-slave.opt rename to mysql-test/suite/rpl/t/rpl_loaddata_map-slave.opt diff --git a/mysql-test/t/rpl_loaddata_map.test b/mysql-test/suite/rpl/t/rpl_loaddata_map.test similarity index 81% rename from mysql-test/t/rpl_loaddata_map.test rename to mysql-test/suite/rpl/t/rpl_loaddata_map.test index f3d14278396..be06397a3ca 100644 --- a/mysql-test/t/rpl_loaddata_map.test +++ b/mysql-test/suite/rpl/t/rpl_loaddata_map.test @@ -7,6 +7,7 @@ # BUG#33413 show binlog events fails if binlog has event size of close # to max_allowed_packet +source include/have_binlog_format_mixed_or_statement.inc; source include/master-slave.inc; source include/have_innodb.inc; @@ -33,10 +34,10 @@ eval load data infile '$MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2; select count(*) from t2 /* 5 000 */; # the binglog will show fragmented Append_block events ---let $binlog_start=98 ---replace_column 5 # ---replace_regex /\/\* xid=.* \*\//\/* XID *\// ---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--let $binlog_start=106 +--replace_column 2 # 4 # 5 # +--replace_regex /\/\* xid=.* \*\//\/* XID *\// /file_id=[0-9]+/file_id=#/ /block_len=[0-9]+/block_len=#/ +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR $binlog_start --eval show binlog events in 'master-bin.000002' from $binlog_start diff --git a/mysql-test/t/rpl_user.test b/mysql-test/suite/rpl/t/rpl_user.test similarity index 93% rename from mysql-test/t/rpl_user.test rename to mysql-test/suite/rpl/t/rpl_user.test index 8c85b1e9249..1f5f5bc9fc5 100644 --- a/mysql-test/t/rpl_user.test +++ b/mysql-test/suite/rpl/t/rpl_user.test @@ -7,8 +7,11 @@ reset master; # # remove all users will be used in the test # +set sql_log_bin=0; +delete from mysql.user where Host='fakehost'; +set sql_log_bin=1; +connection slave; delete from mysql.user where Host='fakehost'; -sync_slave_with_master; # # Test create user From b6ec38cecc0285e8939e7b25aa5c63bada070974 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Jan 2008 14:54:03 +0200 Subject: [PATCH 13/56] Bug #32971 No user level error message from slave sql thread when ER_NO_DEFAULT_FOR_FIELD The error message due to lack of the default value for an extra field was not as informative as it should be. Fixed with improving the scheme of gathering, propagating and reporting errors in applying rows events. The scheme is in the following. Any kind of error of processing of a row event incidents are to be registered with my_error(). In the end Rows_log_event::do_apply_event() invokes rli->report() with the message to display consisting of all the errors. This mimics `show warnings' displaying. A simple test checks three errors in processing an event. Two hunks - a user level error and pushing it into the list - have been devoted to already fixed Bug@31702. Some open issues relating to this artifact listed on BUG@21842 page and on WL@3679. Todo: to synchronize the statement in the tests comments on Update and Delete events may not stop when an extra field does not have a default with wl@3228 spec. include/my_base.h: A new handler level error code that is supposed to be mapped to a set of more specific ER_ user level errors. mysql-test/extra/rpl_tests/rpl_row_tabledefs.test: Adding yet another extra fields to see more than one error in show slave status' report. mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result: results changed (the error message etc) mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result: results changed sql/log_event.cc: Refining slave_rows_error_report to iterate on the list of gathered errors; Simplifying signature of prepare_record as the function does not call rli->report to leave that duty to the event's top level code. sql/log_event.h: adding a corrupt event error pushing. The error will be seen with show slave status. sql/log_event_old.cc: similar to log_event.cc changes sql/rpl_record.cc: prepare_record only pushes an error to the list sql/rpl_record.h: signature changed sql/share/errmsg.txt: The user level error code that corresponds to HA_ERR_CORRUPT_EVENT. The error will be reported in show slave status if such a failure happens. --- include/my_base.h | 4 +- .../extra/rpl_tests/rpl_row_tabledefs.test | 6 +-- .../rpl/r/rpl_row_tabledefs_2myisam.result | 20 +++---- .../rpl/r/rpl_row_tabledefs_3innodb.result | 20 +++---- sql/log_event.cc | 52 ++++++++++++++----- sql/log_event.h | 2 + sql/log_event_old.cc | 4 +- sql/rpl_record.cc | 15 ++---- sql/rpl_record.h | 3 +- sql/share/errmsg.txt | 2 + 10 files changed, 77 insertions(+), 51 deletions(-) diff --git a/include/my_base.h b/include/my_base.h index e65a04bb16d..69a6de67359 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -411,7 +411,9 @@ enum ha_base_keytype { statement */ #define HA_ERR_CORRUPT_EVENT 171 /* The event was corrupt, leading to illegal data being read */ -#define HA_ERR_LAST 171 /*Copy last error nr.*/ +#define HA_ERR_ROWS_EVENT_APPLY 172 /* The event could not be processed + no other hanlder error happened */ +#define HA_ERR_LAST 172 /*Copy last error nr.*/ /* Add error numbers before HA_ERR_LAST and change it accordingly. */ #define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1) diff --git a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test index 1a6c59d0b83..7431c5f08f9 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test +++ b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test @@ -46,7 +46,7 @@ ALTER TABLE t1_bit ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; # ... and add one non-nullable INT column last in table 't1_text' # with no default, -ALTER TABLE t1_nodef ADD x INT NOT NULL; +ALTER TABLE t1_nodef ADD x INT NOT NULL, ADD y INT NOT NULL, ADD z INT NOT NULL; # ... and remove the last column in t2 ALTER TABLE t2 DROP b; # ... change the type of the single column in table 't4' @@ -222,8 +222,8 @@ sync_slave_with_master; --echo **** On Slave **** connection slave; -INSERT INTO t1_nodef VALUES (1,2,3); -INSERT INTO t1_nodef VALUES (2,4,6); +INSERT INTO t1_nodef VALUES (1,2,3,4,5); +INSERT INTO t1_nodef VALUES (2,4,6,8,10); --echo **** On Master **** connection master; diff --git a/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result b/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result index 14a4d52e3e9..87bfa5ac3c4 100644 --- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result +++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result @@ -26,7 +26,7 @@ ADD x BIT(3) DEFAULT b'011', ADD y BIT(5) DEFAULT b'10101', ADD z BIT(2) DEFAULT b'10'; ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; -ALTER TABLE t1_nodef ADD x INT NOT NULL; +ALTER TABLE t1_nodef ADD x INT NOT NULL, ADD y INT NOT NULL, ADD z INT NOT NULL; ALTER TABLE t2 DROP b; ALTER TABLE t4 MODIFY a FLOAT; ALTER TABLE t5 MODIFY b FLOAT; @@ -125,7 +125,7 @@ Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno 1364 -Last_Error Could not execute Write_rows event on table test.t1_nodef; handler error ; the event's master log master-bin.000001, end_log_pos 2674 +Last_Error Could not execute Write_rows event on table test.t1_nodef; Field 'x' doesn't have a default value, Error_code: 1364; Field 'y' doesn't have a default value, Error_code: 1364; Field 'z' doesn't have a default value, Error_code: 1364; handler error HA_ERR_ROWS_EVENT_APPLY; the event's master log master-bin.000001, end_log_pos 2674 Skip_Counter 0 Exec_Master_Log_Pos # Relay_Log_Space # @@ -143,7 +143,7 @@ Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 Last_IO_Error Last_SQL_Errno 1364 -Last_SQL_Error Could not execute Write_rows event on table test.t1_nodef; handler error ; the event's master log master-bin.000001, end_log_pos 2674 +Last_SQL_Error Could not execute Write_rows event on table test.t1_nodef; Field 'x' doesn't have a default value, Error_code: 1364; Field 'y' doesn't have a default value, Error_code: 1364; Field 'z' doesn't have a default value, Error_code: 1364; handler error HA_ERR_ROWS_EVENT_APPLY; the event's master log master-bin.000001, end_log_pos 2674 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; INSERT INTO t9 VALUES (2); @@ -393,8 +393,8 @@ INSERT INTO t1_nodef VALUES (1,2); INSERT INTO t1_nodef VALUES (2,4); SET SQL_LOG_BIN=1; **** On Slave **** -INSERT INTO t1_nodef VALUES (1,2,3); -INSERT INTO t1_nodef VALUES (2,4,6); +INSERT INTO t1_nodef VALUES (1,2,3,4,5); +INSERT INTO t1_nodef VALUES (2,4,6,8,10); **** On Master **** UPDATE t1_nodef SET b=2*b WHERE a=1; SELECT * FROM t1_nodef ORDER BY a; @@ -403,9 +403,9 @@ a b 2 4 **** On Slave **** SELECT * FROM t1_nodef ORDER BY a; -a b x -1 4 3 -2 4 6 +a b x y z +1 4 3 4 5 +2 4 6 8 10 **** On Master **** DELETE FROM t1_nodef WHERE a=2; SELECT * FROM t1_nodef ORDER BY a; @@ -413,8 +413,8 @@ a b 1 4 **** On Slave **** SELECT * FROM t1_nodef ORDER BY a; -a b x -1 4 3 +a b x y z +1 4 3 4 5 **** Cleanup **** DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result index 209388ed391..a28f9795b2f 100644 --- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result +++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result @@ -26,7 +26,7 @@ ADD x BIT(3) DEFAULT b'011', ADD y BIT(5) DEFAULT b'10101', ADD z BIT(2) DEFAULT b'10'; ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; -ALTER TABLE t1_nodef ADD x INT NOT NULL; +ALTER TABLE t1_nodef ADD x INT NOT NULL, ADD y INT NOT NULL, ADD z INT NOT NULL; ALTER TABLE t2 DROP b; ALTER TABLE t4 MODIFY a FLOAT; ALTER TABLE t5 MODIFY b FLOAT; @@ -125,7 +125,7 @@ Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno 1364 -Last_Error Could not execute Write_rows event on table test.t1_nodef; handler error ; the event's master log master-bin.000001, end_log_pos 2944 +Last_Error Could not execute Write_rows event on table test.t1_nodef; Field 'x' doesn't have a default value, Error_code: 1364; Field 'y' doesn't have a default value, Error_code: 1364; Field 'z' doesn't have a default value, Error_code: 1364; handler error HA_ERR_ROWS_EVENT_APPLY; the event's master log master-bin.000001, end_log_pos 3692 Skip_Counter 0 Exec_Master_Log_Pos # Relay_Log_Space # @@ -143,7 +143,7 @@ Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 Last_IO_Error Last_SQL_Errno 1364 -Last_SQL_Error Could not execute Write_rows event on table test.t1_nodef; handler error ; the event's master log master-bin.000001, end_log_pos 2944 +Last_SQL_Error Could not execute Write_rows event on table test.t1_nodef; Field 'x' doesn't have a default value, Error_code: 1364; Field 'y' doesn't have a default value, Error_code: 1364; Field 'z' doesn't have a default value, Error_code: 1364; handler error HA_ERR_ROWS_EVENT_APPLY; the event's master log master-bin.000001, end_log_pos 3692 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; INSERT INTO t9 VALUES (2); @@ -393,8 +393,8 @@ INSERT INTO t1_nodef VALUES (1,2); INSERT INTO t1_nodef VALUES (2,4); SET SQL_LOG_BIN=1; **** On Slave **** -INSERT INTO t1_nodef VALUES (1,2,3); -INSERT INTO t1_nodef VALUES (2,4,6); +INSERT INTO t1_nodef VALUES (1,2,3,4,5); +INSERT INTO t1_nodef VALUES (2,4,6,8,10); **** On Master **** UPDATE t1_nodef SET b=2*b WHERE a=1; SELECT * FROM t1_nodef ORDER BY a; @@ -403,9 +403,9 @@ a b 2 4 **** On Slave **** SELECT * FROM t1_nodef ORDER BY a; -a b x -1 4 3 -2 4 6 +a b x y z +1 4 3 4 5 +2 4 6 8 10 **** On Master **** DELETE FROM t1_nodef WHERE a=2; SELECT * FROM t1_nodef ORDER BY a; @@ -413,8 +413,8 @@ a b 1 4 **** On Slave **** SELECT * FROM t1_nodef ORDER BY a; -a b x -1 4 3 +a b x y z +1 4 3 4 5 **** Cleanup **** DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/sql/log_event.cc b/sql/log_event.cc index 31c14bbd81d..9197e26f84d 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -99,27 +99,51 @@ static const char *HA_ERR(int i) case HA_ERR_RECORD_IS_THE_SAME: return "HA_ERR_RECORD_IS_THE_SAME"; case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE"; case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT"; + case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY"; } return 0; } /** - macro to call from different branches of Rows_log_event::do_apply_event + Error reporting facility for Rows_log_event::do_apply_event + + @param level error, warning or info + @param ha_error HA_ERR_ code + @param rli pointer to the active Relay_log_info instance + @param thd pointer to the slave thread's thd + @param table pointer to the event's table object + @param type the type of the event + @param log_name the master binlog file name + @param pos the master binlog file pos (the next after the event) + */ static void inline slave_rows_error_report(enum loglevel level, int ha_error, Relay_log_info const *rli, THD *thd, TABLE *table, const char * type, const char *log_name, ulong pos) { - const char *handler_error= HA_ERR(ha_error); + const char *handler_error= HA_ERR(ha_error); + char buff[MAX_SLAVE_ERRMSG], *slider; + const char *buff_end= buff + sizeof(buff); + uint len; + List_iterator_fast it(thd->warn_list); + MYSQL_ERROR *err; + buff[0]= 0; + + for (err= it++, slider= buff; err && slider < buff_end - 1; + slider += len, err= it++) + { + len= my_snprintf(slider, buff_end - slider, + " %s, Error_code: %d;", err->msg, err->code); + } + rli->report(level, thd->net.last_errno, "Could not execute %s event on table %s.%s;" - "%s%s handler error %s; " + "%s handler error %s; " "the event's master log %s, end_log_pos %lu", type, table->s->db.str, table->s->table_name.str, - thd->net.last_error[0] != 0 ? thd->net.last_error : "", - thd->net.last_error[0] != 0 ? ";" : "", + buff, handler_error == NULL? "" : handler_error, log_name, pos); } @@ -7548,7 +7572,7 @@ Rows_log_event::write_row(const Relay_log_info *const rli, /* fill table->record[0] with default values */ - if ((error= prepare_record(rli, table, m_width, + if ((error= prepare_record(table, m_width, TRUE /* check if columns have def. values */))) DBUG_RETURN(error); @@ -7863,13 +7887,17 @@ int Rows_log_event::find_row(const Relay_log_info *rli) DBUG_ASSERT(m_table && m_table->in_use != NULL); TABLE *table= m_table; - int error; + int error= 0; - /* unpack row - missing fields get default values */ - - // TODO: shall we check and report errors here? - prepare_record(NULL,table,m_width,FALSE /* don't check errors */); - error= unpack_current_row(rli); + /* + rpl_row_tabledefs.test specifies that + if the extra field on the slave does not have a default value + and this is okay with Delete or Update events. + Todo: fix wl3228 hld that requires defauls for all types of events + */ + + prepare_record(table, m_width, FALSE); + error= unpack_current_row(rli); #ifndef DBUG_OFF DBUG_PRINT("info",("looking for the following record")); diff --git a/sql/log_event.h b/sql/log_event.h index 4a75f330203..10b9496b762 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -3127,6 +3127,8 @@ protected: ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT); int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols, &m_curr_row_end, &m_master_reclength); + if (m_curr_row_end > m_rows_end) + my_error(ER_SLAVE_CORRUPT_EVENT, MYF(0)); ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT); return result; } diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 12c3b2a6dc3..87e593ac7d0 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -2077,7 +2077,7 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli, /* fill table->record[0] with default values */ - if ((error= prepare_record(rli, table, m_width, + if ((error= prepare_record(table, m_width, TRUE /* check if columns have def. values */))) DBUG_RETURN(error); @@ -2288,7 +2288,7 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) /* unpack row - missing fields get default values */ // TODO: shall we check and report errors here? - prepare_record(NULL,table,m_width,FALSE /* don't check errors */); + prepare_record(table, m_width, FALSE /* don't check errors */); error= unpack_current_row(rli); #ifndef DBUG_OFF diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc index ed0dc82cf01..7c74dcba5a0 100644 --- a/sql/rpl_record.cc +++ b/sql/rpl_record.cc @@ -307,17 +307,15 @@ unpack_row(Relay_log_info const *rli, If @c check is true, fields are explicitly initialized only if they have default value or can be NULL. Otherwise error is reported. - @param log Used to report errors. @param table Table whose record[0] buffer is prepared. @param skip Number of columns for which default value initialization should be skipped. @param check Indicates if errors should be checked when setting default values. - @returns 0 on success. + @returns 0 on success or a handler level error code */ -int prepare_record(const Slave_reporting_capability *const log, - TABLE *const table, +int prepare_record(TABLE *const table, const uint skip, const bool check) { DBUG_ENTER("prepare_record"); @@ -337,13 +335,8 @@ int prepare_record(const Slave_reporting_capability *const log, if (check && ((f->flags & mask) == mask)) { - DBUG_ASSERT(log); - log->report(ERROR_LEVEL, ER_NO_DEFAULT_FOR_FIELD, - "Field `%s` of table `%s`.`%s` " - "has no default value and cannot be NULL", - f->field_name, table->s->db.str, - table->s->table_name.str); - error = ER_NO_DEFAULT_FOR_FIELD; + my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), f->field_name); + error = HA_ERR_ROWS_EVENT_APPLY; } else f->set_default(); diff --git a/sql/rpl_record.h b/sql/rpl_record.h index 0d6ceda7433..f9e64f0ab1d 100644 --- a/sql/rpl_record.h +++ b/sql/rpl_record.h @@ -30,8 +30,7 @@ int unpack_row(Relay_log_info const *rli, uchar const **const row_end, ulong *const master_reclength); // Fill table's record[0] with default values. -int prepare_record(const Slave_reporting_capability *const, TABLE *const, - const uint =0, const bool =FALSE); +int prepare_record(TABLE *const, const uint =0, const bool =FALSE); #endif #endif diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 026a0023660..ee3a7e6080a 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -6119,3 +6119,5 @@ ER_SLAVE_AMBIGOUS_EXEC_MODE ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT eng "The BINLOG statement of type `%s` was not preceded by a format description BINLOG statement." +ER_SLAVE_CORRUPT_EVENT + eng "Corrupted replication event was detected" From 6a873248d1d226b7610d2f3f0fa3c8d7e023ab87 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Jan 2008 16:23:27 +0300 Subject: [PATCH 14/56] Test case for bug#12691 mysql-test/suite/bugs/data/rpl_bug12691.dat: Data file for test case mysql-test/suite/bugs/r/rpl_bug12691.result: Result file --- mysql-test/suite/bugs/data/rpl_bug12691.dat | 3 ++ mysql-test/suite/bugs/r/rpl_bug12691.result | 34 +++++++++++++ mysql-test/suite/bugs/t/rpl_bug12691.test | 53 +++++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 mysql-test/suite/bugs/data/rpl_bug12691.dat create mode 100644 mysql-test/suite/bugs/r/rpl_bug12691.result create mode 100644 mysql-test/suite/bugs/t/rpl_bug12691.test diff --git a/mysql-test/suite/bugs/data/rpl_bug12691.dat b/mysql-test/suite/bugs/data/rpl_bug12691.dat new file mode 100644 index 00000000000..de980441c3a --- /dev/null +++ b/mysql-test/suite/bugs/data/rpl_bug12691.dat @@ -0,0 +1,3 @@ +a +b +c diff --git a/mysql-test/suite/bugs/r/rpl_bug12691.result b/mysql-test/suite/bugs/r/rpl_bug12691.result new file mode 100644 index 00000000000..69d5e8009b0 --- /dev/null +++ b/mysql-test/suite/bugs/r/rpl_bug12691.result @@ -0,0 +1,34 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; + +**** On Master **** +CREATE TABLE t1 (b CHAR(10)); + +**** On Slave **** +STOP SLAVE; + +**** On Master **** +LOAD DATA INFILE FILENAME +SELECT COUNT(*) FROM t1; +COUNT(*) +3 +SHOW BINLOG EVENTS; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Format_desc 1 # Server ver: # +master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1 (b CHAR(10)) +master-bin.000001 # Begin_load_query 1 # ;file_id=#;block_len=# +master-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE FILENAME ;file_id=# + +**** On Slave **** +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; +START SLAVE; +SELECT COUNT(*) FROM t1; +COUNT(*) +0 + +**** On Master **** +DROP TABLE t1; diff --git a/mysql-test/suite/bugs/t/rpl_bug12691.test b/mysql-test/suite/bugs/t/rpl_bug12691.test new file mode 100644 index 00000000000..b29c85584a5 --- /dev/null +++ b/mysql-test/suite/bugs/t/rpl_bug12691.test @@ -0,0 +1,53 @@ +# Bug#12691: Exec_master_log_pos corrupted with SQL_SLAVE_SKIP_COUNTER +# Date: 01/31/2008 +# Added: Serge Kozlov + +--source include/master-slave.inc +--connection master +--source include/have_binlog_format_mixed_or_statement.inc + +--echo +--echo **** On Master **** +CREATE TABLE t1 (b CHAR(10)); +--echo +--echo **** On Slave **** +--sync_slave_with_master +STOP SLAVE; +--source include/wait_for_slave_to_stop.inc + +--connection master + +--echo +--echo **** On Master **** +--exec cp $MYSQL_TEST_DIR/suite/bugs/data/rpl_bug12691.dat $MYSQLTEST_VARDIR/tmp/ +--echo LOAD DATA INFILE FILENAME +--disable_query_log +--eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/rpl_bug12691.dat' INTO TABLE t1 FIELDS TERMINATED BY '|' +--enable_query_log +--remove_file $MYSQLTEST_VARDIR/tmp/rpl_bug12691.dat + +SELECT COUNT(*) FROM t1; + +--replace_column 2 # 5 # +--replace_regex /Server ver: .+/Server ver: #/ /table_id: [0-9]+/table_id: #/ /COMMIT.+xid=[0-9]+.+/#/ /file_id=[0-9]+/file_id=#/ /block_len=[0-9]+/block_len=#/ /'.+'/FILENAME/ +SHOW BINLOG EVENTS; + +--save_master_pos + +--connection slave +--echo +--echo **** On Slave **** +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; +START SLAVE; +--source include/wait_for_slave_to_start.inc +--sync_with_master + +SELECT COUNT(*) FROM t1; + +# Clean up +--connection master +--echo +--echo **** On Master **** +DROP TABLE t1; +--sync_slave_with_master + From bce6e6a2cac034ac1c801c29e0d1bc34ab329dc7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Jan 2008 18:12:58 +0200 Subject: [PATCH 15/56] bug#32971 manual merge of two tests results mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result: manual merge mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result: manual merge --- .../suite/rpl/r/rpl_row_tabledefs_2myisam.result | 16 ++++++++-------- .../suite/rpl/r/rpl_row_tabledefs_3innodb.result | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result b/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result index 6859a406b16..e81d4f7454e 100644 --- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result +++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result @@ -26,7 +26,7 @@ ADD x BIT(3) DEFAULT b'011', ADD y BIT(5) DEFAULT b'10101', ADD z BIT(2) DEFAULT b'10'; ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; -ALTER TABLE t1_nodef ADD x INT NOT NULL; +ALTER TABLE t1_nodef ADD x INT NOT NULL, ADD y INT NOT NULL, ADD z INT NOT NULL; ALTER TABLE t2 DROP b; ALTER TABLE t4 MODIFY a FLOAT; ALTER TABLE t5 MODIFY b FLOAT; @@ -393,8 +393,8 @@ INSERT INTO t1_nodef VALUES (1,2); INSERT INTO t1_nodef VALUES (2,4); SET SQL_LOG_BIN=1; **** On Slave **** -INSERT INTO t1_nodef VALUES (1,2,3); -INSERT INTO t1_nodef VALUES (2,4,6); +INSERT INTO t1_nodef VALUES (1,2,3,4,5); +INSERT INTO t1_nodef VALUES (2,4,6,8,10); **** On Master **** UPDATE t1_nodef SET b=2*b WHERE a=1; SELECT * FROM t1_nodef ORDER BY a; @@ -403,9 +403,9 @@ a b 2 4 **** On Slave **** SELECT * FROM t1_nodef ORDER BY a; -a b x -1 4 3 -2 4 6 +a b x y z +1 4 3 4 5 +2 4 6 8 10 **** On Master **** DELETE FROM t1_nodef WHERE a=2; SELECT * FROM t1_nodef ORDER BY a; @@ -413,8 +413,8 @@ a b 1 4 **** On Slave **** SELECT * FROM t1_nodef ORDER BY a; -a b x -1 4 3 +a b x y z +1 4 3 4 5 **** Cleanup **** DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result index 17b2a2f7b52..a6834be5a86 100644 --- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result +++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result @@ -26,7 +26,7 @@ ADD x BIT(3) DEFAULT b'011', ADD y BIT(5) DEFAULT b'10101', ADD z BIT(2) DEFAULT b'10'; ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; -ALTER TABLE t1_nodef ADD x INT NOT NULL; +ALTER TABLE t1_nodef ADD x INT NOT NULL, ADD y INT NOT NULL, ADD z INT NOT NULL; ALTER TABLE t2 DROP b; ALTER TABLE t4 MODIFY a FLOAT; ALTER TABLE t5 MODIFY b FLOAT; @@ -393,8 +393,8 @@ INSERT INTO t1_nodef VALUES (1,2); INSERT INTO t1_nodef VALUES (2,4); SET SQL_LOG_BIN=1; **** On Slave **** -INSERT INTO t1_nodef VALUES (1,2,3); -INSERT INTO t1_nodef VALUES (2,4,6); +INSERT INTO t1_nodef VALUES (1,2,3,4,5); +INSERT INTO t1_nodef VALUES (2,4,6,8,10); **** On Master **** UPDATE t1_nodef SET b=2*b WHERE a=1; SELECT * FROM t1_nodef ORDER BY a; @@ -403,9 +403,9 @@ a b 2 4 **** On Slave **** SELECT * FROM t1_nodef ORDER BY a; -a b x -1 4 3 -2 4 6 +a b x y z +1 4 3 4 5 +2 4 6 8 10 **** On Master **** DELETE FROM t1_nodef WHERE a=2; SELECT * FROM t1_nodef ORDER BY a; @@ -413,8 +413,8 @@ a b 1 4 **** On Slave **** SELECT * FROM t1_nodef ORDER BY a; -a b x -1 4 3 +a b x y z +1 4 3 4 5 **** Cleanup **** DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t7,t8,t9; From 14de473881fa34ad357a58f41afe3cad953d87e2 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Jan 2008 18:26:04 +0200 Subject: [PATCH 16/56] failure in 5.1 tree for rpl_server_id caused by the wrong offset in the include file. fixed with correcting the offset. mysql-test/include/show_binlog_events2.inc: correcting 5.1 specific offset (which appeared to 5.0's) --- mysql-test/include/show_binlog_events2.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/include/show_binlog_events2.inc b/mysql-test/include/show_binlog_events2.inc index fa244c5a5a3..5dd272c562d 100644 --- a/mysql-test/include/show_binlog_events2.inc +++ b/mysql-test/include/show_binlog_events2.inc @@ -1,4 +1,4 @@ ---let $binlog_start=98 +--let $binlog_start=106 --replace_result $binlog_start --replace_column 2 # 5 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ From c47ba21160bc21044f713aefc348c6a3cd8b9e2b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Feb 2008 13:47:11 +0300 Subject: [PATCH 17/56] Fix merge. --- mysql-test/t/variables.test | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index c1580390f63..fd77a8fc9e9 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -141,9 +141,9 @@ set GLOBAL myisam_max_sort_file_size=2000000; show global variables like 'myisam_max_sort_file_size'; select * from information_schema.global_variables where variable_name like 'myisam_max_sort_file_size'; set GLOBAL myisam_max_sort_file_size=default; ---replace_result 2147483647 FILE_SIZE 9223372036854775807 FILE_SIZE -show variables like 'myisam_max_sort_file_size'; ---replace_result 2147483647 FILE_SIZE 9223372036854775807 FILE_SIZE +--replace_result 2147483647 FILE_SIZE 9223372036853727232 FILE_SIZE +show global variables like 'myisam_max_sort_file_size'; +--replace_result 2147483647 FILE_SIZE 9223372036853727232 FILE_SIZE select * from information_schema.session_variables where variable_name like 'myisam_max_sort_file_size'; set global net_retry_count=10, session net_retry_count=10; From f7d8fb1cdde7a9655b984827547a7f4f85560834 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Feb 2008 14:10:46 +0100 Subject: [PATCH 18/56] Bug#33201 Crash occurs when granting update privilege on one column of a view When issuing a column level grant on a table which require pre-locking the server crashed. The reason behind the crash was that data structures used by the lock api wasn't properly reinitialized in the case of a column level grant. mysql-test/r/grant.result: * Added test case mysql-test/t/grant.test: * Added test case sql/sql_acl.cc: * The lock api is dending on the thd->lex object and this variable needs to be re-initialized when opened with a new set of tables than specified in the original statement. --- mysql-test/r/grant.result | 22 ++++++++++++++++++++++ mysql-test/t/grant.test | 22 ++++++++++++++++++++++ sql/sql_acl.cc | 7 +++++++ 3 files changed, 51 insertions(+) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index e27ef64af43..98a21b14585 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1129,4 +1129,26 @@ DROP USER mysqltest_1@localhost; DROP DATABASE db27878; use test; DROP TABLE t1; +drop table if exists test; +Warnings: +Note 1051 Unknown table 'test' +drop function if exists test_function; +Warnings: +Note 1305 FUNCTION test_function does not exist +drop view if exists v1; +Warnings: +Note 1051 Unknown table 'test.v1' +create table test (col1 varchar(30)); +create function test_function() returns varchar(30) +begin +declare tmp varchar(30); +select col1 from test limit 1 into tmp; +return '1'; +end| +create view v1 as select test.* from test where test.col1=test_function(); +grant update (col1) on v1 to 'greg'; +revoke all privileges on v1 from 'greg'; +drop view v1; +drop table test; +drop function test_function; End of 5.0 tests diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index ed95d90c8f8..43548094a33 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1153,4 +1153,26 @@ DROP DATABASE db27878; use test; DROP TABLE t1; +# +# Bug #33201 Crash occurs when granting update privilege on one column of a view +# +drop table if exists test; +drop function if exists test_function; +drop view if exists v1; +create table test (col1 varchar(30)); +delimiter |; +create function test_function() returns varchar(30) +begin + declare tmp varchar(30); + select col1 from test limit 1 into tmp; + return '1'; +end| +delimiter ;| +create view v1 as select test.* from test where test.col1=test_function(); +grant update (col1) on v1 to 'greg'; +revoke all privileges on v1 from 'greg'; +drop view v1; +drop table test; +drop function test_function; + --echo End of 5.0 tests diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 134541368e9..703918329c2 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2878,6 +2878,12 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, } #endif + /* + The lock api is depending on the thd->lex variable which needs to be + re-initialized. + */ + Query_tables_list backup; + thd->lex->reset_n_backup_query_tables_list(&backup); if (simple_open_n_lock_tables(thd,tables)) { // Should never happen close_thread_tables(thd); /* purecov: deadcode */ @@ -3016,6 +3022,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, send_ok(thd); /* Tables are automatically closed */ + thd->lex->restore_backup_query_tables_list(&backup); DBUG_RETURN(result); } From bc070bd3b307f265a407968778f737f4e6482b81 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Feb 2008 14:33:36 +0100 Subject: [PATCH 19/56] * Manual merge fix. mysql-test/r/grant.result: - Manual merge step 2: Verify test cases and record new result set. --- mysql-test/r/grant.result | 46 +++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 579c3fa9232..e4334972845 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1218,6 +1218,28 @@ DROP USER mysqltest_1@localhost; DROP DATABASE db27878; use test; DROP TABLE t1; +drop table if exists test; +Warnings: +Note 1051 Unknown table 'test' +drop function if exists test_function; +Warnings: +Note 1305 FUNCTION test_function does not exist +drop view if exists v1; +Warnings: +Note 1051 Unknown table 'test.v1' +create table test (col1 varchar(30)); +create function test_function() returns varchar(30) +begin +declare tmp varchar(30); +select col1 from test limit 1 into tmp; +return '1'; +end| +create view v1 as select test.* from test where test.col1=test_function(); +grant update (col1) on v1 to 'greg'; +revoke all privileges on v1 from 'greg'; +drop view v1; +drop table test; +drop function test_function; End of 5.0 tests set names utf8; grant select on test.* to юзер_юзер@localhost; @@ -1283,26 +1305,4 @@ CALL mysqltest1.test(); DROP DATABASE mysqltest1; RENAME TABLE mysql.procs_gone TO mysql.procs_priv; FLUSH PRIVILEGES; - -drop table if exists test; -Warnings: -Note 1051 Unknown table 'test' -drop function if exists test_function; -Warnings: -Note 1305 FUNCTION test_function does not exist -drop view if exists v1; -Warnings: -Note 1051 Unknown table 'test.v1' -create table test (col1 varchar(30)); -create function test_function() returns varchar(30) -begin -declare tmp varchar(30); -select col1 from test limit 1 into tmp; -return '1'; -end| -create view v1 as select test.* from test where test.col1=test_function(); -grant update (col1) on v1 to 'greg'; -revoke all privileges on v1 from 'greg'; -drop view v1; -drop table test; -drop function test_function; +End of 5.1 tests From eab1044e23dc74b7e11e0a1a6a0178c161a83c54 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Feb 2008 17:23:46 +0300 Subject: [PATCH 20/56] Fix merge. --- mysql-test/t/variables.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index fd77a8fc9e9..4ae91dbcb69 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -144,7 +144,7 @@ set GLOBAL myisam_max_sort_file_size=default; --replace_result 2147483647 FILE_SIZE 9223372036853727232 FILE_SIZE show global variables like 'myisam_max_sort_file_size'; --replace_result 2147483647 FILE_SIZE 9223372036853727232 FILE_SIZE -select * from information_schema.session_variables where variable_name like 'myisam_max_sort_file_size'; +select * from information_schema.global_variables where variable_name like 'myisam_max_sort_file_size'; set global net_retry_count=10, session net_retry_count=10; set global net_buffer_length=1024, net_write_timeout=200, net_read_timeout=300; From ff8651c4ecb33305c84bf545b000241d34a9ed2a Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Feb 2008 16:39:55 -0200 Subject: [PATCH 21/56] Bug#21801 SQL exception handlers and warnings The problem is that deprecated syntax warnings were not being suppressed when the stored routine is being parsed for the first execution. It's doesn't make sense to print out deprecated syntax warnings when the routine is being executed because this kind of warning only matters when the routine is being created. The solution is to suppress deprecated syntax warnings when parsing the stored routine for loading into the cache (might mean that the routine is being executed for the first time). mysql-test/r/sp-error.result: Add test case result for Bug#21801 mysql-test/t/sp-error.test: Add test case for Bug#21801 sql/sp.cc: Implement a internal error handler to catch deprecated syntax warnings when loading a stored procedure into the cache. --- mysql-test/r/sp-error.result | 11 +++++++++++ mysql-test/t/sp-error.test | 18 ++++++++++++++++++ sql/sp.cc | 30 +++++++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index c33c378340e..bc2ab13fe5f 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -1627,3 +1627,14 @@ end loop label1; end loop; end| ERROR 42000: End-label label1 without match +drop procedure if exists p1; +create procedure p1() +begin +create table t1 (a int) type=MyISAM; +drop table t1; +end| +Warnings: +Warning 1287 The syntax 'TYPE=storage_engine' is deprecated and will be removed in MySQL 5.2. Please use 'ENGINE=storage_engine' instead +call p1(); +call p1(); +drop procedure p1; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 286722df65c..23bce3805af 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -2368,6 +2368,24 @@ end| delimiter ;| +# +# Bug#21801: SQL exception handlers and warnings +# + +--disable_warnings +drop procedure if exists p1; +--enable_warnings +delimiter |; +create procedure p1() +begin + create table t1 (a int) type=MyISAM; + drop table t1; +end| +delimiter ;| +call p1(); +call p1(); +drop procedure p1; + # # BUG#NNNN: New bug synopsis # diff --git a/sql/sp.cc b/sql/sp.cc index 99ffc18deea..5514cf0ed5f 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -507,6 +507,31 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp) } +/** + Silence DEPRECATED SYNTAX warnings when loading a stored procedure + into the cache. +*/ +struct Silence_deprecated_warning : public Internal_error_handler +{ +public: + virtual bool handle_error(uint sql_errno, const char *message, + MYSQL_ERROR::enum_warning_level level, + THD *thd); +}; + +bool +Silence_deprecated_warning::handle_error(uint sql_errno, const char *message, + MYSQL_ERROR::enum_warning_level level, + THD *thd) +{ + if (sql_errno == ER_WARN_DEPRECATED_SYNTAX && + level == MYSQL_ERROR::WARN_LEVEL_WARN) + return TRUE; + + return FALSE; +} + + static int db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, ulong sql_mode, const char *params, const char *returns, @@ -523,7 +548,8 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, ulong old_sql_mode= thd->variables.sql_mode; ha_rows old_select_limit= thd->variables.select_limit; sp_rcontext *old_spcont= thd->spcont; - + Silence_deprecated_warning warning_handler; + char definer_user_name_holder[USERNAME_LENGTH + 1]; LEX_STRING definer_user_name= { definer_user_name_holder, USERNAME_LENGTH }; @@ -583,7 +609,9 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, lex_start(thd); + thd->push_internal_handler(&warning_handler); ret= parse_sql(thd, &lip, creation_ctx) || newlex.sphead == NULL; + thd->pop_internal_handler(); /* Force switching back to the saved current database (if changed), From 4e8ef9c8a26984d969682fc75987bd75171fbcbe Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Feb 2008 19:55:36 +0100 Subject: [PATCH 22/56] Patch clean up. Fixed interference between tests: Users were added but not properly removed. This caused later tests to fail. mysql-test/r/grant.result: Fixed interference between tests: Users were added but not properly removed. This caused later tests to fail. mysql-test/t/grant.test: Fixed interference between tests: Users were added but not properly removed. This caused later tests to fail. --- mysql-test/r/grant.result | 5 +++-- mysql-test/t/grant.test | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index e4334972845..c157e1d4706 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1235,8 +1235,8 @@ select col1 from test limit 1 into tmp; return '1'; end| create view v1 as select test.* from test where test.col1=test_function(); -grant update (col1) on v1 to 'greg'; -revoke all privileges on v1 from 'greg'; +grant update (col1) on v1 to 'greg'@'localhost'; +drop user 'greg'@'localhost'; drop view v1; drop table test; drop function test_function; @@ -1304,5 +1304,6 @@ CALL mysqltest1.test(); 1 DROP DATABASE mysqltest1; RENAME TABLE mysql.procs_gone TO mysql.procs_priv; +DROP USER mysqltest_1@localhost; FLUSH PRIVILEGES; End of 5.1 tests diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index e3c7d44ea5c..e540ce703a1 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1282,8 +1282,8 @@ begin end| delimiter ;| create view v1 as select test.* from test where test.col1=test_function(); -grant update (col1) on v1 to 'greg'; -revoke all privileges on v1 from 'greg'; +grant update (col1) on v1 to 'greg'@'localhost'; +drop user 'greg'@'localhost'; drop view v1; drop table test; drop function test_function; @@ -1396,6 +1396,7 @@ GRANT ALL PRIVILEGES ON test.* TO mysqltest_1@localhost; CALL mysqltest1.test(); DROP DATABASE mysqltest1; RENAME TABLE mysql.procs_gone TO mysql.procs_priv; +DROP USER mysqltest_1@localhost; FLUSH PRIVILEGES; From 4e1be6221e8d683e525c9e0113ab48ae78e99f39 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Feb 2008 12:27:52 +0300 Subject: [PATCH 23/56] Fix merge: fix test. --- mysql-test/t/variables.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 4ae91dbcb69..51f8d6db1db 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -141,9 +141,9 @@ set GLOBAL myisam_max_sort_file_size=2000000; show global variables like 'myisam_max_sort_file_size'; select * from information_schema.global_variables where variable_name like 'myisam_max_sort_file_size'; set GLOBAL myisam_max_sort_file_size=default; ---replace_result 2147483647 FILE_SIZE 9223372036853727232 FILE_SIZE +--replace_result 9223372036853727232 FILE_SIZE 2146435072 FILE_SIZE show global variables like 'myisam_max_sort_file_size'; ---replace_result 2147483647 FILE_SIZE 9223372036853727232 FILE_SIZE +--replace_result 9223372036853727232 FILE_SIZE 2146435072 FILE_SIZE select * from information_schema.global_variables where variable_name like 'myisam_max_sort_file_size'; set global net_retry_count=10, session net_retry_count=10; From 4df3bc0c3d3b9f54e096b8bfcda46c1d98ddaaec Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Feb 2008 18:08:02 +0300 Subject: [PATCH 24/56] Disabling test case. Bug 34311: main.lock_multi.test fails. mysql-test/r/lock_multi.result: Update result file. mysql-test/t/lock_multi.test: Disabled test case for Bug#30331. --- mysql-test/r/lock_multi.result | 10 ------ mysql-test/t/lock_multi.test | 60 ++++++++++++++++++---------------- 2 files changed, 32 insertions(+), 38 deletions(-) diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result index cd05fc1473f..9c4f1b17dcc 100644 --- a/mysql-test/r/lock_multi.result +++ b/mysql-test/r/lock_multi.result @@ -143,14 +143,4 @@ connection: default flush tables; unlock tables; drop table t1; -drop table if exists t1,t2; -create table t1 (a int); -flush status; -lock tables t1 read; -insert into t1 values(1);; -unlock tables; -drop table t1; -select @tlwa < @tlwb; -@tlwa < @tlwb -1 End of 5.1 tests diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index f1e9c0d253f..a7965e429ef 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -440,34 +440,38 @@ disconnect flush; drop table t1; # -# Bug#30331: Table_locks_waited shows inaccurate values # - ---disable_warnings -drop table if exists t1,t2; ---enable_warnings - -create table t1 (a int); -flush status; -lock tables t1 read; -let $tlwa= `show status like 'Table_locks_waited'`; -connect (waiter,localhost,root,,); -connection waiter; ---send insert into t1 values(1); -connection default; -let $wait_condition= - select count(*) = 1 from information_schema.processlist - where state = "Locked" and info = "insert into t1 values(1)"; ---source include/wait_condition.inc -let $tlwb= `show status like 'Table_locks_waited'`; -unlock tables; -drop table t1; -disconnect waiter; -connection default; ---disable_query_log -eval SET @tlwa= SUBSTRING_INDEX('$tlwa', ' ', -1); -eval SET @tlwb= SUBSTRING_INDEX('$tlwb', ' ', -1); ---enable_query_log -select @tlwa < @tlwb; +# This test case was disabled due to Bug#34311: main.lock_multy.test fails. +# +# # +# # Bug#30331: Table_locks_waited shows inaccurate values +# # +# +# --disable_warnings +# drop table if exists t1,t2; +# --enable_warnings +# +# create table t1 (a int); +# flush status; +# lock tables t1 read; +# let $tlwa= `show status like 'Table_locks_waited'`; +# connect (waiter,localhost,root,,); +# connection waiter; +# --send insert into t1 values(1); +# connection default; +# let $wait_condition= +# select count(*) = 1 from information_schema.processlist +# where state = "Locked" and info = "insert into t1 values(1)"; +# --source include/wait_condition.inc +# let $tlwb= `show status like 'Table_locks_waited'`; +# unlock tables; +# drop table t1; +# disconnect waiter; +# connection default; +# --disable_query_log +# eval SET @tlwa= SUBSTRING_INDEX('$tlwa', ' ', -1); +# eval SET @tlwb= SUBSTRING_INDEX('$tlwb', ' ', -1); +# --enable_query_log +# select @tlwa < @tlwb; --echo End of 5.1 tests From 3b6a71a4b0573b5a7de4235d5f76932fa38c596f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Feb 2008 17:36:26 +0200 Subject: [PATCH 25/56] Bug #34305 show slave status handling segfaults when slave io is about to leave The artifact was caused by a flaw in concurrent accessing the slave's io thd by the io itself and a handling show slave status thread. Namely, show_master_info did not acquire mi->run_lock mutex that is specified for mi->io_thd member. Fixed with deploying the mutex locking and unlocking. The mutex is kept short time and without interleaving with mi->data_lock mutex. Todo: to report and fix an issue with sys_var_slave_skip_counter::{methods} seem to acquire incorrectly active_mi->rli.run_lock instead of the specified active_mi->rli.data_lock A test case is difficult to compose, so rpl_packet should continue serving as the indicator. sql/slave.cc: implementing a TODO left at 4.1 time: mending access to mi->io_thd with the specified mutex; sql/slave.h: adding a member name to the list of that run_lock guards. --- sql/slave.cc | 11 ++++++----- sql/slave.h | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/sql/slave.cc b/sql/slave.cc index 4a65e9aaa85..8a3620080f2 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2447,14 +2447,15 @@ bool show_master_info(THD* thd, MASTER_INFO* mi) protocol->prepare_for_resend(); /* - TODO: we read slave_running without run_lock, whereas these variables - are updated under run_lock and not data_lock. In 5.0 we should lock - run_lock on top of data_lock (with good order). + slave_running can be accessed without run_lock but not other + non-volotile members like mi->io_thd, which is guarded by the mutex. */ + pthread_mutex_lock(&mi->run_lock); + protocol->store(mi->io_thd ? mi->io_thd->proc_info : "", &my_charset_bin); + pthread_mutex_unlock(&mi->run_lock); + pthread_mutex_lock(&mi->data_lock); pthread_mutex_lock(&mi->rli.data_lock); - - protocol->store(mi->io_thd ? mi->io_thd->proc_info : "", &my_charset_bin); protocol->store(mi->host, &my_charset_bin); protocol->store(mi->user, &my_charset_bin); protocol->store((uint32) mi->port); diff --git a/sql/slave.h b/sql/slave.h index e7d4456ccd9..c61787cdf3b 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -65,8 +65,8 @@ mi->rli does not either. In MASTER_INFO: run_lock, data_lock - run_lock protects all information about the run state: slave_running, and the - existence of the I/O thread (to stop/start it, you need this mutex). + run_lock protects all information about the run state: slave_running, thd + and the existence of the I/O thread to stop/start it, you need this mutex). data_lock protects some moving members of the struct: counters (log name, position) and relay log (MYSQL_LOG object). From f0f956958a957a716879dfa67ee993ceef6784f1 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Feb 2008 17:05:59 +0100 Subject: [PATCH 26/56] Fixes to make tests pass on vanilla build. mysql-test/suite/binlog/t/binlog_old_versions.test: Adding --local-load to 'mysqlbinlog' and --local-infile=1 to 'mysql'. --- mysql-test/suite/binlog/t/binlog_old_versions.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/binlog/t/binlog_old_versions.test b/mysql-test/suite/binlog/t/binlog_old_versions.test index 465ca3be8ae..e991dcb6648 100644 --- a/mysql-test/suite/binlog/t/binlog_old_versions.test +++ b/mysql-test/suite/binlog/t/binlog_old_versions.test @@ -59,7 +59,7 @@ DROP TABLE t1, t2, t3; # part and the "get xid event" part, and it does not create table t2. # Read binlog. ---exec $MYSQL_BINLOG suite/binlog/std_data/binlog_old_version_4_1.000001 | $MYSQL +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_4_1.000001 | $MYSQL --local-infile=1 # Show result. SELECT * FROM t1 ORDER BY a; SELECT COUNT(*) FROM t3; From 781de1968802032b600704112a8b3fa7fa64d0a7 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Feb 2008 19:44:16 +0100 Subject: [PATCH 27/56] Updating result file for rpl_loaddata_map. mysql-test/suite/rpl/r/rpl_loaddata_map.result: Result change. --- mysql-test/suite/rpl/r/rpl_loaddata_map.result | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_loaddata_map.result b/mysql-test/suite/rpl/r/rpl_loaddata_map.result index 3809584c900..7078389c987 100644 --- a/mysql-test/suite/rpl/r/rpl_loaddata_map.result +++ b/mysql-test/suite/rpl/r/rpl_loaddata_map.result @@ -14,11 +14,11 @@ count(*) 5000 show binlog events in 'master-bin.000002' from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000002 106 Query 1 # use `test`; create table t2 (id int not null primary key auto_increment) -master-bin.000002 229 Begin_load_query 1 # ;file_id=#;block_len=8192 -master-bin.000002 8444 Append_block 1 # ;file_id=#;block_len=8192 -master-bin.000002 16659 Append_block 1 # ;file_id=#;block_len=7509 -master-bin.000002 24191 Execute_load_query 1 # use `test`; load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2 ;file_id=# +master-bin.000002 # Query # # use `test`; create table t2 (id int not null primary key auto_increment) +master-bin.000002 # Begin_load_query # # ;file_id=#;block_len=# +master-bin.000002 # Append_block # # ;file_id=#;block_len=# +master-bin.000002 # Append_block # # ;file_id=#;block_len=# +master-bin.000002 # Execute_load_query # # use `test`; load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2 ;file_id=# select count(*) from t2 /* 5 000 */; count(*) 5000 From 6cb9dfed6fb711b550c91f66609f4a34fa74cf78 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Feb 2008 06:18:06 +0100 Subject: [PATCH 28/56] Removing duplicate code from mysql-test-run.pl mysql-test/mysql-test-run.pl: Removing duplicate code. --- mysql-test/mysql-test-run.pl | 8 -------- 1 file changed, 8 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 536cb873b9a..89b4073ca87 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3870,14 +3870,6 @@ sub mysqld_arguments ($$$$) { mtr_add_arg($args, "%s--user=root"); } - # When mysqld is run by a root user(euid is 0), it will fail - # to start unless we specify what user to run as, see BUG#30630 - my $euid= $>; - if (!$glob_win32 and $euid == 0 and - (grep(/^--user/, @$extra_opt, @opt_extra_mysqld_opt)) == 0) { - mtr_add_arg($args, "%s--user=root", $prefix); - } - if ( $opt_valgrind_mysqld ) { mtr_add_arg($args, "%s--skip-safemalloc", $prefix); From ee42ff6398a1e1ccc1a820f63609849259fad768 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Feb 2008 09:40:59 -0200 Subject: [PATCH 29/56] Bug#34311 main.lock_multi.test fails Re-enable the test case for Bug 30331. mysql-test/r/lock_multi.result: Update the test case result for Bug#30331 mysql-test/t/lock_multi.test: Re-enable the test case for Bug#30331 --- mysql-test/r/lock_multi.result | 10 ++++++ mysql-test/t/lock_multi.test | 59 ++++++++++++++++------------------ 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result index 9c4f1b17dcc..cd05fc1473f 100644 --- a/mysql-test/r/lock_multi.result +++ b/mysql-test/r/lock_multi.result @@ -143,4 +143,14 @@ connection: default flush tables; unlock tables; drop table t1; +drop table if exists t1,t2; +create table t1 (a int); +flush status; +lock tables t1 read; +insert into t1 values(1);; +unlock tables; +drop table t1; +select @tlwa < @tlwb; +@tlwa < @tlwb +1 End of 5.1 tests diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index a7965e429ef..06488abb1ae 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -440,38 +440,33 @@ disconnect flush; drop table t1; # +# Bug#30331: Table_locks_waited shows inaccurate values # -# This test case was disabled due to Bug#34311: main.lock_multy.test fails. -# -# # -# # Bug#30331: Table_locks_waited shows inaccurate values -# # -# -# --disable_warnings -# drop table if exists t1,t2; -# --enable_warnings -# -# create table t1 (a int); -# flush status; -# lock tables t1 read; -# let $tlwa= `show status like 'Table_locks_waited'`; -# connect (waiter,localhost,root,,); -# connection waiter; -# --send insert into t1 values(1); -# connection default; -# let $wait_condition= -# select count(*) = 1 from information_schema.processlist -# where state = "Locked" and info = "insert into t1 values(1)"; -# --source include/wait_condition.inc -# let $tlwb= `show status like 'Table_locks_waited'`; -# unlock tables; -# drop table t1; -# disconnect waiter; -# connection default; -# --disable_query_log -# eval SET @tlwa= SUBSTRING_INDEX('$tlwa', ' ', -1); -# eval SET @tlwb= SUBSTRING_INDEX('$tlwb', ' ', -1); -# --enable_query_log -# select @tlwa < @tlwb; + +--disable_warnings +drop table if exists t1,t2; +--enable_warnings +create table t1 (a int); +flush status; +lock tables t1 read; +let $tlwa= `show status like 'Table_locks_waited'`; +connect (waiter,localhost,root,,); +connection waiter; +--send insert into t1 values(1); +connection default; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Locked" and info = "insert into t1 values(1)"; +--source include/wait_condition.inc +let $tlwb= `show status like 'Table_locks_waited'`; +unlock tables; +drop table t1; +disconnect waiter; +connection default; +--disable_query_log +eval SET @tlwa= SUBSTRING_INDEX('$tlwa', ' ', -1); +eval SET @tlwb= SUBSTRING_INDEX('$tlwb', ' ', -1); +--enable_query_log +select @tlwa < @tlwb; --echo End of 5.1 tests From 9f8fb5ed044e750feb82258520110cc662e45b13 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Feb 2008 14:55:19 +0300 Subject: [PATCH 30/56] Add a test case for Bug#21380: DEFAULT definition not always transfered by CREATE TABLE/SELECT to the new table. mysql-test/r/create.result: Update result file. --- mysql-test/r/create.result | 46 ++++++++++++++++++++++++++++++++++++++ mysql-test/t/create.test | 44 ++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 0613c9ba488..13192dca969 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1743,4 +1743,50 @@ t1 CREATE TABLE `t1` ( `MAXLEN` bigint(3) NOT NULL DEFAULT '0' ) ENGINE=MEMORY DEFAULT CHARSET=utf8 drop table t1; + +# -- +# -- Bug#21380: DEFAULT definition not always transfered by CREATE +# -- TABLE/SELECT to the new table. +# -- + +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; + +CREATE TABLE t1( +c1 INT DEFAULT 12 COMMENT 'column1', +c2 INT NULL COMMENT 'column2', +c3 INT NOT NULL COMMENT 'column3', +c4 VARCHAR(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a', +c5 VARCHAR(255) COLLATE utf8_unicode_ci NULL DEFAULT 'b', +c6 VARCHAR(255)) +COLLATE ucs2_unicode_ci; + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) DEFAULT '12' COMMENT 'column1', + `c2` int(11) DEFAULT NULL COMMENT 'column2', + `c3` int(11) NOT NULL COMMENT 'column3', + `c4` varchar(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a', + `c5` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT 'b', + `c6` varchar(255) COLLATE ucs2_unicode_ci DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=ucs2 COLLATE=ucs2_unicode_ci + +CREATE TABLE t2 AS SELECT * FROM t1; + +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `c1` int(11) DEFAULT '12' COMMENT 'column1', + `c2` int(11) DEFAULT NULL COMMENT 'column2', + `c3` int(11) NOT NULL COMMENT 'column3', + `c4` varchar(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a', + `c5` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT 'b', + `c6` varchar(255) CHARACTER SET ucs2 COLLATE ucs2_unicode_ci DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +DROP TABLE t2; + +# -- End of test case for Bug#21380. + End of 5.1 tests diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index dff6bf3fcff..1fc61010b8b 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -1341,4 +1341,48 @@ create table t1 like information_schema.character_sets; show create table t1; drop table t1; +--echo +--echo # -- +--echo # -- Bug#21380: DEFAULT definition not always transfered by CREATE +--echo # -- TABLE/SELECT to the new table. +--echo # -- +--echo + + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +--enable_warnings + +--echo + +CREATE TABLE t1( + c1 INT DEFAULT 12 COMMENT 'column1', + c2 INT NULL COMMENT 'column2', + c3 INT NOT NULL COMMENT 'column3', + c4 VARCHAR(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a', + c5 VARCHAR(255) COLLATE utf8_unicode_ci NULL DEFAULT 'b', + c6 VARCHAR(255)) + COLLATE ucs2_unicode_ci; + +--echo + +SHOW CREATE TABLE t1; + +--echo + +CREATE TABLE t2 AS SELECT * FROM t1; + +--echo + +SHOW CREATE TABLE t2; + +--echo + +DROP TABLE t2; + +--echo +--echo # -- End of test case for Bug#21380. +--echo + --echo End of 5.1 tests From 047d7d0791e459b5651dbff9a6cf526d076ecc5b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Feb 2008 14:18:26 +0100 Subject: [PATCH 31/56] Raise version number after cloning 5.0.56 --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index cf75aaa38f3..e65bbd51432 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.56) +AM_INIT_AUTOMAKE(mysql, 5.0.58) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 @@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=56 +NDB_VERSION_BUILD=58 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? From 3616b9136f2e44a73f49412ffafbe18d4c4688d9 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Feb 2008 11:20:15 -0200 Subject: [PATCH 32/56] Bug#32710: SHOW INNODB STATUS requires SUPER Changed "SHOW ENGINE ... STATUS" and "SHOW ENGINE ... MUTEX" to require the PROCESS privilege, instead of SUPER. Fixed by Damien Katz mysql-test/r/show_check.result: Add test case result for Bug#32710 mysql-test/t/show_check.test: Add test case for Bug#32710 sql/sql_parse.cc: Require PROCESS privilege instead of SUPER. --- mysql-test/r/show_check.result | 5 +++++ mysql-test/t/show_check.test | 19 +++++++++++++++++++ sql/sql_parse.cc | 4 ++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index ff32d2a1512..c5fcb833933 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -1427,4 +1427,9 @@ DROP FUNCTION f1; DROP TABLE t1; DROP EVENT ev1; SHOW TABLE TYPES; +CREATE USER test_u@localhost; +GRANT PROCESS ON *.* TO test_u@localhost; +SHOW ENGINE MYISAM MUTEX; +SHOW ENGINE MYISAM STATUS; +DROP USER test_u@localhost; End of 5.1 tests diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 34e1941c9d7..613e9acc4c4 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -1115,5 +1115,24 @@ DROP EVENT ev1; SHOW TABLE TYPES; --enable_result_log +# +# Bug #32710: SHOW INNODB STATUS requires SUPER +# + + +CREATE USER test_u@localhost; +GRANT PROCESS ON *.* TO test_u@localhost; + +connect (conn1, localhost, test_u,,); + +--disable_result_log +SHOW ENGINE MYISAM MUTEX; +SHOW ENGINE MYISAM STATUS; +--enable_result_log + +disconnect conn1; +connection default; +DROP USER test_u@localhost; + --echo End of 5.1 tests diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 221c156fe6b..226cd8f9432 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2271,14 +2271,14 @@ mysql_execute_command(THD *thd) #endif /* HAVE_REPLICATION */ case SQLCOM_SHOW_ENGINE_STATUS: { - if (check_global_access(thd, SUPER_ACL)) + if (check_global_access(thd, PROCESS_ACL)) goto error; res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_STATUS); break; } case SQLCOM_SHOW_ENGINE_MUTEX: { - if (check_global_access(thd, SUPER_ACL)) + if (check_global_access(thd, PROCESS_ACL)) goto error; res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_MUTEX); break; From be5a46a69b63eebfd4413e43a4f6a7b3c0c0bcd0 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Feb 2008 14:44:47 +0100 Subject: [PATCH 33/56] Patch to eliminate some valgrind warnings in debug printout code. sql/rpl_rli.cc: Adding variable to mark an instance of Relay_log_info as fake. sql/rpl_rli.h: Adding variable to mark an instance of Relay_log_info as fake. sql/slave.cc: Not printing debug information if we are working with a fake instance of Relay_log_info. This because the result of calling update is nonsense, and trying to print it generates valgrind warnings. sql/sql_binlog.cc: Marking newly created instance of Relay_log_info as a fake instance. --- sql/rpl_rli.cc | 5 ++++- sql/rpl_rli.h | 4 ++++ sql/slave.cc | 22 ++++++++++++++-------- sql/sql_binlog.cc | 3 +++ 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 3e9a484126a..03f790b934f 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -33,7 +33,10 @@ Relay_log_info::Relay_log_info() :Slave_reporting_capability("SQL"), no_storage(FALSE), replicate_same_server_id(::replicate_same_server_id), info_fd(-1), cur_log_fd(-1), save_temporary_tables(0), - group_relay_log_pos(0), + group_relay_log_pos(0), event_relay_log_pos(0), +#if HAVE_purify + is_fake(FALSE), +#endif cur_log_old_open_count(0), group_master_log_pos(0), log_space_total(0), ignore_log_space_limit(0), last_master_timestamp(0), slave_skip_counter(0), abort_pos_wait(0), slave_run_id(0), sql_thd(0), diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index a3a57ad4ce9..36daffae1af 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -154,6 +154,10 @@ public: ulonglong event_relay_log_pos; ulonglong future_event_relay_log_pos; +#ifdef HAVE_purify + bool is_fake; /* Mark that this is a fake relay log info structure */ +#endif + /* Original log name and position of the group we're currently executing (whose coordinates are group_relay_log_name/pos in the relay log) diff --git a/sql/slave.cc b/sql/slave.cc index 4ffc2023e85..c76e7c75a56 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1892,14 +1892,19 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli, if (exec_res == 0) { int error= ev->update_pos(rli); - char buf[22]; - DBUG_PRINT("info", ("update_pos error = %d", error)); - DBUG_PRINT("info", ("group %s %s", - llstr(rli->group_relay_log_pos, buf), - rli->group_relay_log_name)); - DBUG_PRINT("info", ("event %s %s", - llstr(rli->event_relay_log_pos, buf), - rli->event_relay_log_name)); +#ifdef HAVE_purify + if (!rli->is_fake) +#endif + { + char buf[22]; + DBUG_PRINT("info", ("update_pos error = %d", error)); + DBUG_PRINT("info", ("group %s %s", + llstr(rli->group_relay_log_pos, buf), + rli->group_relay_log_name)); + DBUG_PRINT("info", ("event %s %s", + llstr(rli->event_relay_log_pos, buf), + rli->event_relay_log_name)); + } /* The update should not fail, so print an error message and return an error code. @@ -1909,6 +1914,7 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli, */ if (error) { + char buf[22]; rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR, "It was not possible to update the positions" " of the relay log information: the slave may" diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc index 04f408453ea..f1fbe6eb4b7 100644 --- a/sql/sql_binlog.cc +++ b/sql/sql_binlog.cc @@ -56,6 +56,9 @@ void mysql_client_binlog_statement(THD* thd) if (!thd->rli_fake) { thd->rli_fake= new Relay_log_info; +#ifdef HAVE_purify + thd->rli_fake->is_fake= TRUE; +#endif have_fd_event= FALSE; } if (thd->rli_fake && !thd->rli_fake->relay_log.description_event_for_exec) From 7b82376f0a27228705aa0f4e988a7f881aea555c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Feb 2008 20:55:12 +0100 Subject: [PATCH 34/56] Replace windows path separator backslash by unix path separator forward slash in filenames also for Create_file_log_event. client/mysqlbinlog.cc: BUG#34355: mysqlbinlog outputs backslash as path separator for 4.1 binlogs Problem: When the windows version of mysqlbinlog reads 4.1 binlogs containing LOAD DATA INFILE, it outputs backslashes as path separators in filenames. However, the output is typically piped to a client, and client expects forward slashes. Fix: Replace '\\' by '/' in filenames. --- client/mysqlbinlog.cc | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 0553240894e..b4086b59c01 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -465,6 +465,31 @@ Create_file event for file_id: %u\n",ae->file_id); Load_log_processor load_processor; +/** + Replace windows-style backslashes by forward slashes so it can be + consumed by the mysql client, which requires Unix path. + + @todo This is only useful under windows, so may be ifdef'ed out on + other systems. /Sven + + @todo If a Create_file_log_event contains a filename with a + backslash (valid under unix), then we have problems under windows. + /Sven + + @param[in,out] fname Filename to modify. The filename is modified + in-place. +*/ +static void convert_path_to_forward_slashes(char *fname) +{ + while (*fname) + { + if (*fname == '\\') + *fname= '/'; + fname++; + } +} + + static bool check_database(const char *log_dbname) { return one_database && @@ -582,6 +607,11 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, */ if (ce) { + /* + We must not convert earlier, since the file is used by + my_open() in Load_log_processor::append(). + */ + convert_path_to_forward_slashes((char*) ce->fname); ce->print(result_file, print_event_info, TRUE); my_free((char*)ce->fname,MYF(MY_WME)); delete ce; @@ -622,13 +652,7 @@ Create_file event for file_id: %u\n",exv->file_id); if (fname) { - /* - Fix the path so it can be consumed by mysql client (requires Unix path). - */ - int stop= strlen(fname); - for (int i= 0; i < stop; i++) - if (fname[i] == '\\') - fname[i]= '/'; + convert_path_to_forward_slashes(fname); exlq->print(result_file, print_event_info, fname); my_free(fname, MYF(MY_WME)); } From 7144184ced4774da6bdfb34d9c2bae510877cbe8 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Feb 2008 08:41:32 +0100 Subject: [PATCH 35/56] Disabling declaration of debug variable for non-debug builds. sql/slave.cc: Disabling declaration in non-debug builds. --- sql/slave.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/slave.cc b/sql/slave.cc index c76e7c75a56..9dd52c60dad 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1896,7 +1896,9 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli, if (!rli->is_fake) #endif { +#ifndef DBUG_OFF char buf[22]; +#endif DBUG_PRINT("info", ("update_pos error = %d", error)); DBUG_PRINT("info", ("group %s %s", llstr(rli->group_relay_log_pos, buf), From 1b6b7010a6b1bd6e7f79632c2738d7a1654078e4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Feb 2008 08:47:39 -0200 Subject: [PATCH 36/56] Bug#32633 Can not create any routine if SQL_MODE=no_engine_substitution The problem is that one can not create a stored routine if sql_mode contains NO_ENGINE_SUBSTITUTION or PAD_CHAR_TO_FULL_LENGTH. Also when a event is created, the mode is silently lost if sql_mode contains one of the aforementioned. This was happening because the table definitions which stored sql_mode values weren't being updated to accept new values of sql_mode. The solution is to update, in a backwards compatible manner, the various table definitions (columns) that store the sql_mode value to take into account the new possible values. One incompatible change is that if a event that is being created can't be stored to the mysql.event table, an error will be raised. The tests case also ensure that new SQL modes will be added to the mysql.proc and mysql.event tables, otherwise the tests will fail. mysql-test/r/events_bugs.result: Add test case result for Bug#32633 mysql-test/r/information_schema.result: Update the sql_mode column definition. mysql-test/r/sp.result: Add test case result for Bug#32633 mysql-test/r/system_mysql_db.result: Update the sql_mode column definition. mysql-test/t/events_bugs.test: Add test case for Bug#32633 mysql-test/t/sp.test: Add test case for Bug#32633 mysql-test/t/system_mysql_db_fix50117.test: Update the sql_mode column definition. scripts/mysql_system_tables.sql: Update the sql_mode column definition. scripts/mysql_system_tables_fix.sql: Update the sql_mode column definition. sql/event_db_repository.cc: Reset and restore SQL modes when storing and loading a event from the data dictionary. Also throw out a error if a store fails. sql/mysqld.cc: Add warning to avoid this problem in the future. sql-common/my_user.c: Truncate length if user name or host name does not fit in the buffer. sql/sp.cc: SQL mode of the thread must not effect data dictionary operations. --- mysql-test/r/events_bugs.result | 13 ++++ mysql-test/r/information_schema.result | 2 +- mysql-test/r/sp.result | 16 +++++ mysql-test/r/system_mysql_db.result | 4 +- mysql-test/t/events_bugs.test | 20 +++++++ mysql-test/t/sp.test | 23 ++++++++ mysql-test/t/system_mysql_db_fix50117.test | 2 +- scripts/mysql_system_tables.sql | 4 +- scripts/mysql_system_tables_fix.sql | 8 ++- sql-common/my_user.c | 8 ++- sql/event_db_repository.cc | 69 ++++++++++++++-------- sql/mysqld.cc | 5 ++ sql/sp.cc | 13 +++- 13 files changed, 152 insertions(+), 35 deletions(-) diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index b91e7e88d64..814cf42d16c 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -722,4 +722,17 @@ DROP USER mysqltest_u1@localhost; # ##################################################################### +drop procedure if exists p; +set @old_mode= @@sql_mode; +set @@sql_mode= pow(2,32)-1; +create event e1 on schedule every 1 day do select 1; +select @@sql_mode; +@@sql_mode +REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,?,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH +set @@sql_mode= @old_mode; +select replace(@full_mode, '?', 'NOT_USED') into @full_mode; +select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode; +select name from mysql.event where name = 'p' and sql_mode = @full_mode; +name +drop event e1; DROP DATABASE events_test; diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 0416733255f..708d8ab027d 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -588,7 +588,7 @@ proc body longblob proc definer char(77) proc created timestamp proc modified timestamp -proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE') +proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') proc comment char(64) proc character_set_client char(32) proc collation_connection char(32) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 50ece83b258..a68be67a8e0 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6963,6 +6963,22 @@ END latin1 latin1_swedish_ci latin1_swedish_ci DROP FUNCTION f1; +drop procedure if exists p; +set @old_mode= @@sql_mode; +set @@sql_mode= pow(2,32)-1; +select @@sql_mode into @full_mode; +create procedure p() begin end; +call p(); +select @@sql_mode; +@@sql_mode +REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,?,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH +set @@sql_mode= @old_mode; +select replace(@full_mode, '?', 'NOT_USED') into @full_mode; +select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode; +select name from mysql.proc where name = 'p' and sql_mode = @full_mode; +name +p +drop procedure p; # ------------------------------------------------------------------ # -- End of 5.1 tests # ------------------------------------------------------------------ diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result index d1aff0fa657..171b53ebf09 100644 --- a/mysql-test/r/system_mysql_db.result +++ b/mysql-test/r/system_mysql_db.result @@ -201,7 +201,7 @@ proc CREATE TABLE `proc` ( `definer` char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '', `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', - `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE') NOT NULL DEFAULT '', + `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '', `comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '', `character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, `collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, @@ -226,7 +226,7 @@ event CREATE TABLE `event` ( `ends` datetime DEFAULT NULL, `status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED', `on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP', - `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE') NOT NULL DEFAULT '', + `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '', `comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '', `originator` int(10) NOT NULL, `time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test index efdb67349ec..b3b2f37e36f 100644 --- a/mysql-test/t/events_bugs.test +++ b/mysql-test/t/events_bugs.test @@ -935,6 +935,26 @@ DROP USER mysqltest_u1@localhost; --echo ##################################################################### --echo +# +# Bug#32633 Can not create any routine if SQL_MODE=no_engine_substitution +# +# Ensure that when new SQL modes are introduced, they are also added to +# the mysql.event table. +# + +--disable_warnings +drop procedure if exists p; +--enable_warnings +set @old_mode= @@sql_mode; +set @@sql_mode= pow(2,32)-1; +create event e1 on schedule every 1 day do select 1; +select @@sql_mode; +set @@sql_mode= @old_mode; +# Rename SQL modes that differ in name between the server and the table definition. +select replace(@full_mode, '?', 'NOT_USED') into @full_mode; +select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode; +select name from mysql.event where name = 'p' and sql_mode = @full_mode; +drop event e1; ########################################################################### # diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 6dc2f906d45..bb9aae6dee6 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -8135,6 +8135,29 @@ DROP FUNCTION f1; ########################################################################### +# +# Bug#32633 Can not create any routine if SQL_MODE=no_engine_substitution +# +# Ensure that when new SQL modes are introduced, they are also added to +# the mysql.proc table. +# + +--disable_warnings +drop procedure if exists p; +--enable_warnings +set @old_mode= @@sql_mode; +set @@sql_mode= pow(2,32)-1; +select @@sql_mode into @full_mode; +create procedure p() begin end; +call p(); +select @@sql_mode; +set @@sql_mode= @old_mode; +# Rename SQL modes that differ in name between the server and the table definition. +select replace(@full_mode, '?', 'NOT_USED') into @full_mode; +select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode; +select name from mysql.proc where name = 'p' and sql_mode = @full_mode; +drop procedure p; + --echo # ------------------------------------------------------------------ --echo # -- End of 5.1 tests --echo # ------------------------------------------------------------------ diff --git a/mysql-test/t/system_mysql_db_fix50117.test b/mysql-test/t/system_mysql_db_fix50117.test index 5f259ac6133..ea379757f26 100644 --- a/mysql-test/t/system_mysql_db_fix50117.test +++ b/mysql-test/t/system_mysql_db_fix50117.test @@ -78,7 +78,7 @@ CREATE TABLE IF NOT EXISTS proc ( db char(64) collate utf8_bin DEFAULT '' NOT NU CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges'; -CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events'; +CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events'; CREATE TABLE IF NOT EXISTS ndb_binlog_index (Position BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch BIGINT UNSIGNED NOT NULL, inserts BIGINT UNSIGNED NOT NULL, updates BIGINT UNSIGNED NOT NULL, deletes BIGINT UNSIGNED NOT NULL, schemaops BIGINT UNSIGNED NOT NULL, PRIMARY KEY(epoch)) ENGINE=MYISAM; diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index 7ca35ae0752..fdab9601129 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -60,7 +60,7 @@ CREATE TABLE IF NOT EXISTS time_zone_transition_type ( Time_zone_id int unsign CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=MyISAM CHARACTER SET utf8 comment='Leap seconds information for time zones'; -CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures'; +CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures'; CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges'; @@ -80,7 +80,7 @@ PREPARE stmt FROM @str; EXECUTE stmt; DROP PREPARE stmt; -CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator int(10) NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events'; +CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator int(10) NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events'; CREATE TABLE IF NOT EXISTS ndb_binlog_index (Position BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch BIGINT UNSIGNED NOT NULL, inserts BIGINT UNSIGNED NOT NULL, updates BIGINT UNSIGNED NOT NULL, deletes BIGINT UNSIGNED NOT NULL, schemaops BIGINT UNSIGNED NOT NULL, PRIMARY KEY(epoch)) ENGINE=MYISAM; diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index a43964bf09a..e2bdd668c0f 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -375,7 +375,9 @@ ALTER TABLE proc MODIFY name char(64) DEFAULT '' NOT NULL, 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', - 'HIGH_NOT_PRECEDENCE' + 'HIGH_NOT_PRECEDENCE', + 'NO_ENGINE_SUBSTITUTION', + 'PAD_CHAR_TO_FULL_LENGTH' ) DEFAULT '' NOT NULL, DEFAULT CHARACTER SET utf8; @@ -461,7 +463,9 @@ ALTER TABLE event ADD sql_mode 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', - 'HIGH_NOT_PRECEDENCE' + 'HIGH_NOT_PRECEDENCE', + 'NO_ENGINE_SUBSTITUTION', + 'PAD_CHAR_TO_FULL_LENGTH' ) DEFAULT '' NOT NULL AFTER on_completion; ALTER TABLE event MODIFY name char(64) CHARACTER SET utf8 NOT NULL default ''; ALTER TABLE event ADD COLUMN originator INT(10) NOT NULL AFTER comment; diff --git a/sql-common/my_user.c b/sql-common/my_user.c index 16a544387ee..d6f2818ad77 100644 --- a/sql-common/my_user.c +++ b/sql-common/my_user.c @@ -15,7 +15,7 @@ #include #include - +#include /* Parse user value to user name and host name parts. @@ -47,6 +47,12 @@ void parse_user(const char *user_id_str, size_t user_id_len, *user_name_len= p - user_id_str; *host_name_len= user_id_len - *user_name_len - 1; + if (*user_name_len > USERNAME_LENGTH) + *user_name_len= USERNAME_LENGTH; + + if (*host_name_len > HOSTNAME_LENGTH) + *host_name_len= HOSTNAME_LENGTH; + memcpy(user_name_str, user_id_str, *user_name_len); memcpy(host_name_str, p + 1, *host_name_len); } diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index 9a33b33d8c9..401f76f5d26 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -111,7 +111,7 @@ const TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] = "'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES'," "'STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES'," "'ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER'," - "'HIGH_NOT_PRECEDENCE')") }, + "'HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')") }, {NULL, 0} }, { @@ -172,11 +172,13 @@ mysql_event_fill_row(THD *thd, TABLE *table, Event_parse_data *et, sp_head *sp, + ulong sql_mode, my_bool is_update) { CHARSET_INFO *scs= system_charset_info; enum enum_events_table_field f_num; Field **fields= table->field; + int rs= FALSE; DBUG_ENTER("mysql_event_fill_row"); @@ -205,12 +207,9 @@ mysql_event_fill_row(THD *thd, goto err_truncate; /* both ON_COMPLETION and STATUS are NOT NULL thus not calling set_notnull()*/ - fields[ET_FIELD_ON_COMPLETION]->store((longlong)et->on_completion, TRUE); - - fields[ET_FIELD_STATUS]->store((longlong)et->status, TRUE); - - fields[ET_FIELD_ORIGINATOR]->store((longlong)et->originator, TRUE); - + rs|= fields[ET_FIELD_ON_COMPLETION]->store((longlong)et->on_completion, TRUE); + rs|= fields[ET_FIELD_STATUS]->store((longlong)et->status, TRUE); + rs|= fields[ET_FIELD_ORIGINATOR]->store((longlong)et->originator, TRUE); /* Change the SQL_MODE only if body was present in an ALTER EVENT and of course @@ -220,7 +219,7 @@ mysql_event_fill_row(THD *thd, { DBUG_ASSERT(sp->m_body.str); - fields[ET_FIELD_SQL_MODE]->store((longlong)thd->variables.sql_mode, TRUE); + rs|= fields[ET_FIELD_SQL_MODE]->store((longlong)sql_mode, TRUE); if (fields[f_num= ET_FIELD_BODY]->store(sp->m_body.str, sp->m_body.length, @@ -236,16 +235,16 @@ mysql_event_fill_row(THD *thd, if (!is_update || !et->starts_null) { fields[ET_FIELD_TIME_ZONE]->set_notnull(); - fields[ET_FIELD_TIME_ZONE]->store(tz_name->ptr(), tz_name->length(), - tz_name->charset()); + rs|= fields[ET_FIELD_TIME_ZONE]->store(tz_name->ptr(), tz_name->length(), + tz_name->charset()); } fields[ET_FIELD_INTERVAL_EXPR]->set_notnull(); - fields[ET_FIELD_INTERVAL_EXPR]->store((longlong)et->expression, TRUE); + rs|= fields[ET_FIELD_INTERVAL_EXPR]->store((longlong)et->expression, TRUE); fields[ET_FIELD_TRANSIENT_INTERVAL]->set_notnull(); - fields[ET_FIELD_TRANSIENT_INTERVAL]-> + rs|= fields[ET_FIELD_TRANSIENT_INTERVAL]-> store(interval_type_to_name[et->interval].str, interval_type_to_name[et->interval].length, scs); @@ -274,8 +273,8 @@ mysql_event_fill_row(THD *thd, { const String *tz_name= thd->variables.time_zone->get_name(); fields[ET_FIELD_TIME_ZONE]->set_notnull(); - fields[ET_FIELD_TIME_ZONE]->store(tz_name->ptr(), tz_name->length(), - tz_name->charset()); + rs|= fields[ET_FIELD_TIME_ZONE]->store(tz_name->ptr(), tz_name->length(), + tz_name->charset()); fields[ET_FIELD_INTERVAL_EXPR]->set_null(); fields[ET_FIELD_TRANSIENT_INTERVAL]->set_null(); @@ -308,13 +307,13 @@ mysql_event_fill_row(THD *thd, } fields[ET_FIELD_CHARACTER_SET_CLIENT]->set_notnull(); - fields[ET_FIELD_CHARACTER_SET_CLIENT]->store( + rs|= fields[ET_FIELD_CHARACTER_SET_CLIENT]->store( thd->variables.character_set_client->csname, strlen(thd->variables.character_set_client->csname), system_charset_info); fields[ET_FIELD_COLLATION_CONNECTION]->set_notnull(); - fields[ET_FIELD_COLLATION_CONNECTION]->store( + rs|= fields[ET_FIELD_COLLATION_CONNECTION]->store( thd->variables.collation_connection->name, strlen(thd->variables.collation_connection->name), system_charset_info); @@ -323,15 +322,23 @@ mysql_event_fill_row(THD *thd, CHARSET_INFO *db_cl= get_default_db_collation(thd, et->dbname.str); fields[ET_FIELD_DB_COLLATION]->set_notnull(); - fields[ET_FIELD_DB_COLLATION]->store( - db_cl->name, strlen(db_cl->name), system_charset_info); + rs|= fields[ET_FIELD_DB_COLLATION]->store(db_cl->name, + strlen(db_cl->name), + system_charset_info); } if (et->body_changed) { fields[ET_FIELD_BODY_UTF8]->set_notnull(); - fields[ET_FIELD_BODY_UTF8]->store( - sp->m_body_utf8.str, sp->m_body_utf8.length, system_charset_info); + rs|= fields[ET_FIELD_BODY_UTF8]->store(sp->m_body_utf8.str, + sp->m_body_utf8.length, + system_charset_info); + } + + if (rs) + { + my_error(ER_EVENT_STORE_FAILED, MYF(0), fields[f_num]->field_name, rs); + DBUG_RETURN(TRUE); } DBUG_RETURN(FALSE); @@ -585,12 +592,16 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, int ret= 1; TABLE *table= NULL; sp_head *sp= thd->lex->sphead; + ulong saved_mode= thd->variables.sql_mode; DBUG_ENTER("Event_db_repository::create_event"); DBUG_PRINT("info", ("open mysql.event for update")); DBUG_ASSERT(sp); + /* Reset sql_mode during data dictionary operations. */ + thd->variables.sql_mode= 0; + if (open_event_table(thd, TL_WRITE, &table)) goto end; @@ -646,7 +657,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, mysql_event_fill_row() calls my_error() in case of error so no need to handle it here */ - if (mysql_event_fill_row(thd, table, parse_data, sp, FALSE)) + if (mysql_event_fill_row(thd, table, parse_data, sp, saved_mode, FALSE)) goto end; table->field[ET_FIELD_STATUS]->store((longlong)parse_data->status, TRUE); @@ -661,6 +672,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, end: if (table) close_thread_tables(thd); + thd->variables.sql_mode= saved_mode; DBUG_RETURN(test(ret)); } @@ -691,6 +703,7 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data, CHARSET_INFO *scs= system_charset_info; TABLE *table= NULL; sp_head *sp= thd->lex->sphead; + ulong saved_mode= thd->variables.sql_mode; int ret= 1; DBUG_ENTER("Event_db_repository::update_event"); @@ -698,6 +711,9 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data, /* None or both must be set */ DBUG_ASSERT(new_dbname && new_name || new_dbname == new_name); + /* Reset sql_mode during data dictionary operations. */ + thd->variables.sql_mode= 0; + if (open_event_table(thd, TL_WRITE, &table)) goto end; @@ -736,7 +752,7 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data, mysql_event_fill_row() calls my_error() in case of error so no need to handle it here */ - if (mysql_event_fill_row(thd, table, parse_data, sp, TRUE)) + if (mysql_event_fill_row(thd, table, parse_data, sp, saved_mode, TRUE)) goto end; if (new_dbname) @@ -755,6 +771,7 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data, end: if (table) close_thread_tables(thd); + thd->variables.sql_mode= saved_mode; DBUG_RETURN(test(ret)); } @@ -950,13 +967,17 @@ bool Event_db_repository::load_named_event(THD *thd, LEX_STRING dbname, LEX_STRING name, Event_basic *etn) { - TABLE *table= NULL; bool ret; + TABLE *table= NULL; + ulong saved_mode= thd->variables.sql_mode; DBUG_ENTER("Event_db_repository::load_named_event"); DBUG_PRINT("enter",("thd: 0x%lx name: %*s", (long) thd, (int) name.length, name.str)); + /* Reset sql_mode during data dictionary operations. */ + thd->variables.sql_mode= 0; + if (!(ret= open_event_table(thd, TL_READ, &table))) { if ((ret= find_named_event(dbname, name, table))) @@ -967,7 +988,7 @@ Event_db_repository::load_named_event(THD *thd, LEX_STRING dbname, close_thread_tables(thd); } - + thd->variables.sql_mode= saved_mode; DBUG_RETURN(ret); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7b331d42941..9dc77fb8356 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -221,6 +221,11 @@ extern "C" int gethostname(char *name, int namelen); /* Constants */ const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"}; +/* + WARNING: When adding new SQL modes don't forget to update the + tables definitions that stores it's value. + (ie: mysql.event, mysql.proc) +*/ static const char *sql_mode_names[]= { "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", diff --git a/sql/sp.cc b/sql/sp.cc index 99ffc18deea..b6813d8948c 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -388,7 +388,7 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp) uint length; char buff[65]; String str(buff, sizeof(buff), &my_charset_bin); - ulong sql_mode; + ulong sql_mode, saved_mode= thd->variables.sql_mode; Open_tables_state open_tables_state_backup; Stored_program_creation_ctx *creation_ctx; @@ -400,6 +400,9 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp) if (!(table= open_proc_table_for_read(thd, &open_tables_state_backup))) DBUG_RETURN(SP_OPEN_TABLE_FAILED); + /* Reset sql_mode during data dictionary operations. */ + thd->variables.sql_mode= 0; + if ((ret= db_find_routine_aux(thd, type, name, table)) != SP_OK) goto done; @@ -503,6 +506,7 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp) done: if (table) close_system_tables(thd, &open_tables_state_backup); + thd->variables.sql_mode= saved_mode; DBUG_RETURN(ret); } @@ -675,6 +679,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) int ret; TABLE *table; char definer[USER_HOST_BUFF_SIZE]; + ulong saved_mode= thd->variables.sql_mode; CHARSET_INFO *db_cs= get_default_db_collation(thd, sp->m_db.str); @@ -689,6 +694,9 @@ sp_create_routine(THD *thd, int type, sp_head *sp) DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE || type == TYPE_ENUM_FUNCTION); + /* Reset sql_mode during data dictionary operations. */ + thd->variables.sql_mode= 0; + /* This statement will be replicated as a statement, even when using row-based replication. The flag will be reset at the end of the @@ -790,7 +798,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) store_failed= store_failed || table->field[MYSQL_PROC_FIELD_SQL_MODE]-> - store((longlong)thd->variables.sql_mode, TRUE); + store((longlong)saved_mode, TRUE); if (sp->m_chistics->comment.str) { @@ -890,6 +898,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) done: thd->count_cuted_fields= saved_count_cuted_fields; + thd->variables.sql_mode= saved_mode; close_thread_tables(thd); DBUG_RETURN(ret); From 2a482933b6da71bf3cd5b18a4c1a50b06ab3e5d3 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Feb 2008 12:30:52 +0100 Subject: [PATCH 37/56] Renaming some saved binary log files to avoid 99 characters limit for v7 tar. mysql-test/suite/binlog/std_data/ver_5_1_17.001: Rename: mysql-test/suite/binlog/std_data/binlog_old_version_5_1_17.000001 -> mysql-test/suite/binlog/std_data/ver_5_1_17.001 mysql-test/suite/binlog/std_data/ver_5_1_23.001: Rename: mysql-test/suite/binlog/std_data/binlog_old_version_5_1_23.000001 -> mysql-test/suite/binlog/std_data/ver_5_1_23.001 mysql-test/suite/binlog/std_data/ver_5_1-telco.001: Rename: mysql-test/suite/binlog/std_data/binlog_old_version_5_1-telco.000001 -> mysql-test/suite/binlog/std_data/ver_5_1-telco.001 mysql-test/suite/binlog/std_data/ver_5_1-wl2325_r.001: Rename: mysql-test/suite/binlog/std_data/binlog_old_version_5_1-wl2325_row.000001 -> mysql-test/suite/binlog/std_data/ver_5_1-wl2325_r.001 mysql-test/suite/binlog/std_data/ver_5_1-wl2325_s.001: Rename: mysql-test/suite/binlog/std_data/binlog_old_version_5_1-wl2325_stm.000001 -> mysql-test/suite/binlog/std_data/ver_5_1-wl2325_s.001 mysql-test/suite/binlog/std_data/bug32407.001: Rename: mysql-test/suite/binlog/std_data/binlog-bug32407.000001 -> mysql-test/suite/binlog/std_data/bug32407.001 --- .../{binlog-bug32407.000001 => bug32407.001} | Bin ...d_version_5_1-telco.000001 => ver_5_1-telco.001} | Bin ...n_5_1-wl2325_row.000001 => ver_5_1-wl2325_r.001} | Bin ...n_5_1-wl2325_stm.000001 => ver_5_1-wl2325_s.001} | Bin ...log_old_version_5_1_17.000001 => ver_5_1_17.001} | Bin ...log_old_version_5_1_23.000001 => ver_5_1_23.001} | Bin mysql-test/suite/binlog/t/binlog_base64_flag.test | 6 +++--- mysql-test/suite/binlog/t/binlog_old_versions.test | 10 +++++----- 8 files changed, 8 insertions(+), 8 deletions(-) rename mysql-test/suite/binlog/std_data/{binlog-bug32407.000001 => bug32407.001} (100%) rename mysql-test/suite/binlog/std_data/{binlog_old_version_5_1-telco.000001 => ver_5_1-telco.001} (100%) rename mysql-test/suite/binlog/std_data/{binlog_old_version_5_1-wl2325_row.000001 => ver_5_1-wl2325_r.001} (100%) rename mysql-test/suite/binlog/std_data/{binlog_old_version_5_1-wl2325_stm.000001 => ver_5_1-wl2325_s.001} (100%) rename mysql-test/suite/binlog/std_data/{binlog_old_version_5_1_17.000001 => ver_5_1_17.001} (100%) rename mysql-test/suite/binlog/std_data/{binlog_old_version_5_1_23.000001 => ver_5_1_23.001} (100%) diff --git a/mysql-test/suite/binlog/std_data/binlog-bug32407.000001 b/mysql-test/suite/binlog/std_data/bug32407.001 similarity index 100% rename from mysql-test/suite/binlog/std_data/binlog-bug32407.000001 rename to mysql-test/suite/binlog/std_data/bug32407.001 diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_5_1-telco.000001 b/mysql-test/suite/binlog/std_data/ver_5_1-telco.001 similarity index 100% rename from mysql-test/suite/binlog/std_data/binlog_old_version_5_1-telco.000001 rename to mysql-test/suite/binlog/std_data/ver_5_1-telco.001 diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_5_1-wl2325_row.000001 b/mysql-test/suite/binlog/std_data/ver_5_1-wl2325_r.001 similarity index 100% rename from mysql-test/suite/binlog/std_data/binlog_old_version_5_1-wl2325_row.000001 rename to mysql-test/suite/binlog/std_data/ver_5_1-wl2325_r.001 diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_5_1-wl2325_stm.000001 b/mysql-test/suite/binlog/std_data/ver_5_1-wl2325_s.001 similarity index 100% rename from mysql-test/suite/binlog/std_data/binlog_old_version_5_1-wl2325_stm.000001 rename to mysql-test/suite/binlog/std_data/ver_5_1-wl2325_s.001 diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_5_1_17.000001 b/mysql-test/suite/binlog/std_data/ver_5_1_17.001 similarity index 100% rename from mysql-test/suite/binlog/std_data/binlog_old_version_5_1_17.000001 rename to mysql-test/suite/binlog/std_data/ver_5_1_17.001 diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_5_1_23.000001 b/mysql-test/suite/binlog/std_data/ver_5_1_23.001 similarity index 100% rename from mysql-test/suite/binlog/std_data/binlog_old_version_5_1_23.000001 rename to mysql-test/suite/binlog/std_data/ver_5_1_23.001 diff --git a/mysql-test/suite/binlog/t/binlog_base64_flag.test b/mysql-test/suite/binlog/t/binlog_base64_flag.test index 32319460ab8..8f4619e5248 100644 --- a/mysql-test/suite/binlog/t/binlog_base64_flag.test +++ b/mysql-test/suite/binlog/t/binlog_base64_flag.test @@ -15,7 +15,7 @@ # The binlog contains row events equivalent to: # CREATE TABLE t1 (a int) engine = myisam # INSERT INTO t1 VALUES (1), (1) -exec $MYSQL_BINLOG suite/binlog/std_data/binlog-bug32407.000001 | $MYSQL; +exec $MYSQL_BINLOG suite/binlog/std_data/bug32407.001 | $MYSQL; # The above line should succeed and t1 should contain two ones select * from t1; @@ -68,7 +68,7 @@ select * from t1; # mysqlbinlog should fail --replace_regex /#[0-9][0-9][0-9][0-9][0-9][0-9] .*/#/ error 1; -exec $MYSQL_BINLOG --base64-output=never suite/binlog/std_data/binlog-bug32407.000001; +exec $MYSQL_BINLOG --base64-output=never suite/binlog/std_data/bug32407.001; # the above line should output the query log event and then stop @@ -78,7 +78,7 @@ exec $MYSQL_BINLOG --base64-output=never suite/binlog/std_data/binlog-bug32407.0 --echo ==== Test non-matching FD event and Row event ==== # This is the Format_description_log_event from -# binlog-bug32407.000001, encoded in base64. It contains only the old +# bug32407.001, encoded in base64. It contains only the old # row events (number of event types is 22) BINLOG ' 4CdYRw8BAAAAYgAAAGYAAAAAAAQANS4xLjE1LW5kYi02LjEuMjQtZGVidWctbG9nAAAAAAAAAAAA diff --git a/mysql-test/suite/binlog/t/binlog_old_versions.test b/mysql-test/suite/binlog/t/binlog_old_versions.test index 2d56ebd588d..7bf8350911b 100644 --- a/mysql-test/suite/binlog/t/binlog_old_versions.test +++ b/mysql-test/suite/binlog/t/binlog_old_versions.test @@ -31,7 +31,7 @@ DROP TABLE IF EXISTS t1, t2, t3; --echo ==== Read modern binlog (version 5.1.23) ==== # Read binlog. ---exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1_23.000001 | $MYSQL --local-infile=1 +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1_23.001 | $MYSQL --local-infile=1 # Show result. SELECT * FROM t1 ORDER BY a; SELECT * FROM t2 ORDER BY a; @@ -43,7 +43,7 @@ DROP TABLE t1, t2, t3; --echo ==== Read binlog from version 5.1.17 ==== # Read binlog. ---exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1_17.000001 | $MYSQL --local-infile=1 +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1_17.001 | $MYSQL --local-infile=1 # Show result. SELECT * FROM t1 ORDER BY a; SELECT * FROM t2 ORDER BY a; @@ -60,9 +60,9 @@ DROP TABLE t1, t2, t3; # replication. # Read rbr binlog. ---exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1-wl2325_row.000001 | $MYSQL --local-infile=1 +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1-wl2325_r.001 | $MYSQL --local-infile=1 # Read stm binlog. ---exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1-wl2325_stm.000001 | $MYSQL --local-infile=1 +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1-wl2325_s.001 | $MYSQL --local-infile=1 # Show result. SELECT * FROM t1 ORDER BY a; SELECT * FROM t2 ORDER BY a; @@ -74,7 +74,7 @@ DROP TABLE t1, t2, t3; --echo ==== Read binlog from ndb tree (mysql-5.1-telco-6.1) ==== # Read binlog. ---exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1-telco.000001 | $MYSQL --local-infile=1 +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1-telco.001 | $MYSQL --local-infile=1 # Show resulting tablea. SELECT * FROM t1 ORDER BY a; SELECT * FROM t2 ORDER BY a; From 187e5c5fa3444555b7e53addee6fb1dd947d4f5b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Feb 2008 19:21:23 +0100 Subject: [PATCH 38/56] WL#4078: Document binary format of binlog entries Documented Table_map_log_event and packed integer format. Improved other documentation. No change outside comments. sql/log_event.h: Documented Table_map_log_event and packed integer format. Improved other documentation. No change outside comments. --- sql/log_event.h | 613 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 490 insertions(+), 123 deletions(-) diff --git a/sql/log_event.h b/sql/log_event.h index 59d58d47bad..4e151d6cde9 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -667,34 +667,35 @@ typedef struct st_print_event_info @section Log_event_binary_format Binary Format - Any Log_event saved on disk consists of the following three + Any @c Log_event saved on disk consists of the following three components. - @li Common-Header - @li Post-Header - @li Body + * Common-Header + * Post-Header + * Body - The Common-Header, documented below, always has the same form and - length within one version of MySQL. Each event type specifies a - form and length of the Post-Header common to all events of the type. - The Body may be of different form and length even for different - events of the same type. The binary formats of Post-Header and Body - are documented separately in each subclass. The binary format of - Common-Header is as follows. + The Common-Header, documented in the table @ref Table_common_header + "below", always has the same form and length within one version of + MySQL. Each event type specifies a form and length of the + Post-Header common to all events of the type. The Body may be of + different form and length even for different events of the same + type. The binary formats of Post-Header and Body are documented + separately in each subclass. The binary format of Common-Header is + as follows. - + - @@ -705,14 +706,14 @@ typedef struct st_print_event_info - - + + - + @@ -720,9 +721,12 @@ typedef struct st_print_event_info - + @@ -736,13 +740,55 @@ typedef struct st_print_event_info Summing up the numbers above, we see that the total size of the common header is 19 bytes. - @subsection Log_event_endianness_and_string_formats Endianness and String Formats + @subsection Log_event_format_of_atomic_primitives Format of Atomic Primitives - All numbers, whether they are 16-, 32-, or 64-bit, are stored in - little endian, i.e., the least significant byte first. + - All numbers, whether they are 16-, 24-, 32-, or 64-bit numbers, + are stored in little endian, i.e., the least significant byte first, + unless otherwise specified. - Strings are stored in various formats. The format of each string is - documented separately. + @anchor packed_integer + - Some events use a special format for efficient representation of + unsigned integers, called Packed Integer. A Packed Integer has the + capacity of storing up to 8-byte integers, while small integers + still can use 1, 3, or 4 bytes. The first byte indicates how many + bytes are used by the integer, according to the following table: + +
Common-Header
NameFormat
Format Description
timestamp 4 byte unsigned integerThe number of seconds since 1970. + The time when the query started, in seconds since 1970.
master_id4 byte integerserver_id4 byte unsigned integer Server ID of the server that created the event.
total_size4 byte integer4 byte unsigned integer The total size of this event, in bytes. In other words, this is the sum of the sizes of Common-Header, Post-Header, and Body.
master_position4 byte integer4 byte unsigned integer The position of the next event in the master binary log, in - bytes from the beginning of the file. + bytes from the beginning of the file. In a binlog that is not a + relay log, this is just the position of the next event, in bytes + from the beginning of the file. In a relay log, this is + the position of the next event in the master's binlog.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Format of Packed Integer
First byteFormat
0-250The first byte is the number (in range 0-250), and no more + bytes are used.
252Two more bytes are used. The number is in the range + 251-0xffff.
253Three more bytes are used. The number is in the range + 0xffff-0xffffff.
254Eight more bytes are used. The number is in the range + 0xffffff-0xffffffffffffffff.
+ + - Strings are stored in various formats. The format of each string + is documented separately. */ class Log_event { @@ -1123,7 +1169,8 @@ protected: /** @class Query_log_event - Logs SQL queries. + A @c Query_log_event is created for each query that modifies the + database, unless the query is logged row-based. @section Query_log_event_binary_format Binary format @@ -1134,60 +1181,49 @@ protected: Name - Size
+ Format Description slave_proxy_id 4 byte unsigned integer - An integer identifying the client thread, which is unique on - the server. (Note, however, that two threads on different servers - may have the same slave_proxy_id.) This is used when a client - thread creates a temporary table. Temporary tables are local to - the client, and the slave_proxy_id is used to distinguish - temporary tables belonging to different clients. + An integer identifying the client thread that issued the + query. The id is unique per server. (Note, however, that two + threads on different servers may have the same slave_proxy_id.) + This is used when a client thread creates a temporary table local + to the client. The slave_proxy_id is used to distinguish + temporary tables that belong to different clients. exec_time - 4 byte integer - ???TODO + 4 byte unsigned integer + The time from when the query started to when it was logged in + the binlog, in seconds. db_len 1 byte integer - The length of the name of the currently selected - database. - + The length of the name of the currently selected database. error_code - 2 byte integer + 2 byte unsigned integer Error code generated by the master. If the master fails, the slave will fail with the same error code, except for the error - codes ER_DB_CREATE_EXISTS==1007 and ER_DB_DROP_EXISTS==1008. + codes ER_DB_CREATE_EXISTS == 1007 and ER_DB_DROP_EXISTS == 1008. status_vars_len - 2 byte integer + 2 byte unsigned integer The length of the status_vars block of the Body, in bytes. See - below. - - - - - Post-Header-For-Derived - 0 bytes - This field is only written by the subclass - Execute_load_query_log_event. In this base class, it takes 0 - bytes. See separate documentation for - Execute_load_query_log_event. + @ref query_log_event_status_vars "below". @@ -1199,19 +1235,19 @@ protected: Name - Size
+ Format Description - status_vars - variable length + @anchor query_log_event_status_vars status_vars + status_vars_len bytes Zero or more status variables. Each status variable consists of one byte identifying the variable stored, followed by the value of the variable. The possible variables are listed separately in - the table below. MySQL always writes events in the order defined - below; however, it is capable of reading them in any order. - + the table @ref Table_query_log_event_status_vars "below". MySQL + always writes events in the order defined below; however, it is + capable of reading them in any order. @@ -1237,13 +1273,14 @@ protected: The following table lists the status variables that may appear in the status_vars field. + @anchor Table_query_log_event_status_vars - - + + @@ -1251,13 +1288,13 @@ protected: - - - + @@ -1327,7 +1364,7 @@ protected: @@ -1351,14 +1388,14 @@ protected: - + @@ -1409,14 +1446,14 @@ protected: - + @@ -1717,26 +1755,27 @@ private: - + - - + @@ -1773,7 +1812,7 @@ private: - + @@ -1813,7 +1852,7 @@ private:
  • In the old format, we know that each string has length 0 or 1. Therefore, only the first byte of each string is stored. The order of the strings is the same as in the new format. These five - bytes are followed by the same 1-byte bitfield as in the new + bytes are followed by the same 1 byte bitfield as in the new format. Finally, a 1 byte bitfield called empty_flags is stored. The low 5 bits of empty_flags indicate which of the five strings have length 0. For each of the following flags that is set, the @@ -1831,7 +1870,7 @@ private:
  • - + @@ -1992,11 +2031,13 @@ extern char server_version[SERVER_VERSION_LENGTH]; Start_log_event_v3 is the Start_log_event of binlog format 3 (MySQL 3.23 and 4.x). - Format_description_log_event derives from Start_log_event_v3; it is the - Start_log_event of binlog format 4 (MySQL 5.0), that is, the event that - describes the other events' header/postheader lengths. This event is sent by - MySQL 5.0 whenever it starts sending a new binlog if the requested position - is >4 (otherwise if ==4 the event will be sent naturally). + + Format_description_log_event derives from Start_log_event_v3; it is + the Start_log_event of binlog format 4 (MySQL 5.0), that is, the + event that describes the other events' Common-Header/Post-Header + lengths. This event is sent by MySQL 5.0 whenever it starts sending + a new binlog if the requested position is >4 (otherwise if ==4 the + event will be sent naturally). @section Start_log_event_v3_binary_format Binary Format */ @@ -2150,7 +2191,9 @@ protected: /** @class Intvar_log_event - Logs special variables related to auto_increment values. + An Intvar_log_event will be created just before a Query_log_event, + if the query uses one of the variables LAST_INSERT_ID or INSERT_ID. + Each Intvar_log_event holds the value of one of these variables. @section Intvar_log_event_binary_format Binary Format @@ -2161,12 +2204,12 @@ protected: - + - +
    Status variables for Query_log_event
    Status variable1-byte identifierSize
    1 byte identifierFormat Description
    flags2 Q_FLAGS2_CODE == 0 4 byte bitfieldThe flags in thd->options, binary AND-ed with - OPTIONS_WRITTEN_TO_BIN_LOG. The thd->options bitfield contains - options for SELECT. OPTIONS_WRITTEN identifies those options that - need to be written to the binlog (not all do). Specifically, - OPTIONS_WRITTEN_TO_BIN_LOG equals (OPTION_AUTO_IS_NULL | - OPTION_NO_FOREIGN_KEY_CHECKS | OPTION_RELAXED_UNIQUE_CHECKS | - OPTION_NOT_AUTOCOMMIT), or 0x0c084000 in hex. + The flags in @c thd->options, binary AND-ed with @c + OPTIONS_WRITTEN_TO_BIN_LOG. The @c thd->options bitfield contains + options for "SELECT". @c OPTIONS_WRITTEN identifies those options + that need to be written to the binlog (not all do). Specifically, + @c OPTIONS_WRITTEN_TO_BIN_LOG equals (@c OPTION_AUTO_IS_NULL | @c + OPTION_NO_FOREIGN_KEY_CHECKS | @c OPTION_RELAXED_UNIQUE_CHECKS | + @c OPTION_NOT_AUTOCOMMIT), or 0x0c084000 in hex. These flags correspond to the SQL variables SQL_AUTO_IS_NULL, FOREIGN_KEY_CHECKS, UNIQUE_CHECKS, and AUTOCOMMIT, documented in @@ -1271,8 +1308,8 @@ protected:
    sql_mode Q_SQL_MODE_CODE == 18 byte integerThe sql_mode variable. See the section "SQL Modes" in the + 8 byte bitfieldThe @c sql_mode variable. See the section "SQL Modes" in the MySQL manual, and see mysql_priv.h for a list of the possible flags. Currently (2007-10-04), the following flags are available:
    @@ -1310,10 +1347,10 @@ protected:
         MODE_PAD_CHAR_TO_FULL_LENGTH==0x80000000
         
    All these flags are replicated from the server. However, all - flags except MODE_NO_DIR_IN_CREATE are honored by the slave; the - slave always preserves its old value of MODE_NO_DIR_IN_CREATE. - For a rationale, see comment in Query_log_event::do_apply_event in - log_event.cc. + flags except @c MODE_NO_DIR_IN_CREATE are honored by the slave; + the slave always preserves its old value of @c + MODE_NO_DIR_IN_CREATE. For a rationale, see comment in + @c Query_log_event::do_apply_event in @c log_event.cc. This field is always written to the binlog.
    Stores the client's current catalog. Every database belongs to a catalog, the same way that every table belongs to a - database. Currently, there is only one catalog, 'std'. + database. Currently, there is only one catalog, "std". This field is written if the length of the catalog is > 0; otherwise it is not written. @@ -1343,7 +1380,7 @@ protected: auto_increment_offset, in that order. For more information, see "System variables" in the MySQL manual. - This field is written if auto_increment>1; otherwise it is not + This field is written if auto_increment > 1. Otherwise, it is not written.
    charset Q_CHARSET_CODE == 4three 2-byte unsigned integers (i.e., 6 bytes)three 2 byte unsigned integers, totally 2+2+2=6 bytes The three variables character_set_client, collation_connection, and collation_server, in that order. - `character_set_client' is a code identifying the character set and + character_set_client is a code identifying the character set and collation used by the client to encode the query. - `collation_connection' identifies the character set and collation + collation_connection identifies the character set and collation that the master converts the query to when it receives it; this is - useful when comparing literal strings. `collation_server' is the + useful when comparing literal strings. collation_server is the default character set and collation used when a new database is created. @@ -1396,9 +1433,9 @@ protected: Q_LC_TIME_NAMES_CODE == 7 2 byte integer A code identifying a table of month and day names. The - mapping from codes to languages is defined in sql_locale.cc. + mapping from codes to languages is defined in @c sql_locale.cc. - This field is written if it is != 0, i.e., if the locale is not + This field is written if it is not 0, i.e., if the locale is not en_US.
    2 byte integer The value of the collation_database system variable (in the - source code stored in thd->variables.collation_database), which + source code stored in @c thd->variables.collation_database), which holds the code for a (character set, collation) pair as described above (see Q_CHARSET_CODE). - `collation_database' was used in old versions (???WHEN). Its - value was loaded when issuing a "use db" command and could be - changed by issuing a "SET collation_database=xxx" command. It - used to affect the "LOAD DATA INFILE" and "CREATE TABLE" commands. + collation_database was used in old versions (???WHEN). Its value + was loaded when issuing a "use db" query and could be changed by + issuing a "SET collation_database=xxx" query. It used to affect + the "LOAD DATA INFILE" and "CREATE TABLE" commands. In newer versions, "CREATE TABLE" has been changed to take the character set from the database of the created table, rather than @@ -1433,17 +1470,17 @@ protected: @subsection Query_log_event_notes_on_previous_versions Notes on Previous Versions - @li Status vars were introduced in version 5.0. To read earlier + * Status vars were introduced in version 5.0. To read earlier versions correctly, check the length of the Post-Header. - @li The status variable Q_CATALOG_CODE == 2 existed in MySQL 5.0.x, + * The status variable Q_CATALOG_CODE == 2 existed in MySQL 5.0.x, where 0<=x<=3. It was identical to Q_CATALOG_CODE, except that the string had a trailing '\0'. The '\0' was removed in 5.0.4 since it was redundant (the string length is stored before the string). The Q_CATALOG_CODE will never be written by a new master, but can still be understood by a new slave. - @li See Q_CHARSET_DATABASE_NUMBER in the table above. + * See Q_CHARSET_DATABASE_NUMBER in the table above. */ class Query_log_event: public Log_event @@ -1576,7 +1613,8 @@ public: /* !!! Public in this patch to allow old usage */ /** @class Muted_query_log_event - Pretends to log SQL queries, but doesn't actually do so. + Pretends to log SQL queries, but doesn't actually do so. This is + used internally only and never written to any binlog. @section Muted_query_log_event_binary_format Binary Format @@ -1603,7 +1641,7 @@ public: @class Slave_log_event Note that this class is currently not used at all; no code writes a - Slave_log_event (though some code in repl_failsafe.cc reads + @c Slave_log_event (though some code in @c repl_failsafe.cc reads @c Slave_log_event). So it's not a problem if this code is not maintained. @@ -1617,7 +1655,7 @@ public:
    NameSize
    Format Description
    NameSize
    Format Description
    slave_proxy_id 4 byte unsigned integerAn integer identifying the client thread, which is unique on - the server. (Note, however, that the same slave_proxy_id may - appear on different servers.) This is used when a client thread - creates a temporary table. Temporary tables are local to the - client, and the slave_proxy_id is used to distinguish temporary - tables belonging to different clients. + An integer identifying the client thread that issued the + query. The id is unique per server. (Note, however, that two + threads on different servers may have the same slave_proxy_id.) + This is used when a client thread creates a temporary table local + to the client. The slave_proxy_id is used to distinguish + temporary tables that belong to different clients.
    exec_time 4 byte unsigned integer???TODOThe time from when the query started to when it was logged in + the binlog, in seconds.
    NameSize
    Format Description
    field_lensnum_fields 1-byte unsigned integersnum_fields 1 byte unsigned integers An array of num_fields integers representing the length of each field in the query. (num_fields is from the Post-Header).
    NameSize
    Format Description
    Typetype 1 byte enumeration One byte identifying the type of variable stored. Currently, two identifiers are supported: LAST_INSERT_ID_EVENT==1 and @@ -2182,7 +2225,6 @@ protected:
    */ - class Intvar_log_event: public Log_event { public: @@ -2228,15 +2270,34 @@ private: written in 4.1.1 for PASSWORD() (but the fact that it is written is just a waste, it does not cause bugs). + The state of the random number generation consists of 128 bits, + which are stored internally as two 64-bit numbers. + @section Rand_log_event_binary_format Binary Format This event type has no Post-Header. The Body of this event type has two components: - @li seed1 (8 bytes): 64 bit random seed1. - @li seed2 (8 bytes): 64 bit random seed2. + + - The state of the random number generation consists of 128 bits, - which are stored internally as two 64-bit numbers. + + + + + + + + + + + + + + + + + +
    Post-Header for Intvar_log_event
    NameFormatDescription
    seed18 byte unsigned integer64 bit random seed1.
    seed28 byte unsigned integer64 bit random seed2.
    */ class Rand_log_event: public Log_event @@ -2423,14 +2484,14 @@ private: Name - Size
    + Format Description - pos + position 8 byte integer - ???TODO + The position within the binlog to rotate to. @@ -2442,17 +2503,17 @@ private: Name - Size
    + Format Description - new_log_ident + new_log variable length string without trailing zero, extending to the end of the event (determined by the length field of the Common-Header) - ???TODO + Name of the binlog to rotate to. @@ -2841,10 +2902,316 @@ char *str_to_hex(char *to, const char *from, uint len); /** @class Table_map_log_event - Create a mapping from a (database name, table name) couple to a table - identifier (an integer number). + In row-based mode, every row operation event is preceded by a + Table_map_log_event which maps a table definition to a number. The + table definition consists of database name, table name, and column + definitions. @section Table_map_log_event_binary_format Binary Format + + The Post-Header has the following components: + + + + + + + + + + + + + + + + + + + + + + +
    Post-Header for Table_map_log_event
    NameFormatDescription
    table_id6 bytes unsigned integerThe number that identifies the table.
    flags2 byte bitfieldReserved for future use; currently always 0.
    + + The Body has the following components: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Body for Table_map_log_event
    NameFormatDescription
    database_nameone byte string length, followed by null-terminated stringThe name of the database in which the table resides. The name + is represented as a one byte unsigned integer representing the + number of bytes in the name, followed by length bytes containing + the database name, followed by a terminating 0 byte. (Note the + redundancy in the representation of the length.)
    table_nameone byte string length, followed by null-terminated stringThe name of the table, encoded the same way as the database + name above.
    column_count@ref packed_integer "Packed Integer"The number of columns in the table, represented as a packed + variable-length integer.
    column_typeList of column_count 1 byte enumeration valuesThe type of each column in the table, listed from left to + right. Each byte is mapped to a column type according to the + enumeration type enum_field_types defined in mysql_com.h. The + mapping of types to numbers is listed in the table @ref + Table_table_map_log_event_column_types "below" (along with + description of the associated metadata field).
    metadata_length@ref packed_integer "Packed Integer"The length of the following metadata block
    metadatalist of metadata for each columnFor each column from left to right, a chunk of data who's + length and semantics depends on the type of the column. The + length and semantics for the metadata for each column are listed + in the table @ref Table_table_map_log_event_column_types + "below".
    null_bitscolumn_count bits, rounded up to nearest byteFor each column, a bit indicating whether data in the column + can be NULL or not. The number of bytes needed for this is + int((column_count+7)/8). The flag for the first column from the + left is in the least-significant bit of the first byte, the second + is in the second least significant bit of the first byte, the + ninth is in the least significant bit of the second byte, and so + on.
    + + The table below lists all column types, along with the numerical + identifier for it and the size and interpretation of meta-data used + to describe the type. + + @anchor Table_table_map_log_event_column_types + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table_map_log_event column types: numerical identifier and + metadata
    NameIdentifierSize of metadata in bytesDescription of metadata
    MYSQL_TYPE_DECIMAL00No column metadata.
    MYSQL_TYPE_TINY10No column metadata.
    MYSQL_TYPE_SHORT20No column metadata.
    MYSQL_TYPE_LONG30No column metadata.
    MYSQL_TYPE_FLOAT41 byte1 byte unsigned integer, representing the "pack_length", which + is equal to sizeof(float) on the server from which the event + originates.
    MYSQL_TYPE_DOUBLE51 byte1 byte unsigned integer, representing the "pack_length", which + is equal to sizeof(double) on the server from which the event + originates.
    MYSQL_TYPE_NULL60No column metadata.
    MYSQL_TYPE_TIMESTAMP70No column metadata.
    MYSQL_TYPE_LONGLONG80No column metadata.
    MYSQL_TYPE_INT2490No column metadata.
    MYSQL_TYPE_DATE100No column metadata.
    MYSQL_TYPE_TIME110No column metadata.
    MYSQL_TYPE_DATETIME120No column metadata.
    MYSQL_TYPE_YEAR130No column metadata.
    MYSQL_TYPE_NEWDATE14This enumeration value is only used internally and cannot + exist in a binlog.
    MYSQL_TYPE_VARCHAR152 bytes2 byte unsigned integer representing the maximum length of + the string.
    MYSQL_TYPE_BIT162 bytesA 1 byte unsigned int representing the length in bits of the + bitfield (0 to 64), followed by a 1 byte unsigned int + representing the number of bytes occupied by the bitfield. The + number of bytes is either int((length+7)/8) or int(length/8).
    MYSQL_TYPE_NEWDECIMAL2462 bytesA 1 byte unsigned int representing the precision, followed + by a 1 byte unsigned int representing the number of decimals.
    MYSQL_TYPE_ENUM247This enumeration value is only used internally and cannot + exist in a binlog.
    MYSQL_TYPE_SET248This enumeration value is only used internally and cannot + exist in a binlog.
    MYSQL_TYPE_TINY_BLOB249This enumeration value is only used internally and cannot + exist in a binlog.
    MYSQL_TYPE_MEDIUM_BLOB250This enumeration value is only used internally and cannot + exist in a binlog.
    MYSQL_TYPE_LONG_BLOB251This enumeration value is only used internally and cannot + exist in a binlog.
    MYSQL_TYPE_BLOB2521 byteThe pack length, i.e., the number of bytes needed to represent + the length of the blob: 1, 2, 3, or 4.
    MYSQL_TYPE_VAR_STRING2532 bytesThis is used to store both strings and enumeration values. + The first byte is a enumeration value storing the real + type, which may be either MYSQL_TYPE_VAR_STRING or + MYSQL_TYPE_ENUM. The second byte is a 1 byte unsigned integer + representing the field size, i.e., the number of bytes needed to + store the length of the string.
    MYSQL_TYPE_STRING2542 bytesThe first byte is always MYSQL_TYPE_VAR_STRING (i.e., 253). + The second byte is the field size, i.e., the number of bytes in + the representation of size of the string: 3 or 4.
    MYSQL_TYPE_GEOMETRY2551 byteThe pack length, i.e., the number of bytes needed to represent + the length of the geometry: 1, 2, 3, or 4.
    */ class Table_map_log_event : public Log_event { @@ -3410,7 +3777,7 @@ protected: Incident event format Symbol - Size
    (bytes) + Format Description From 6c97f05f97acd83209f88907b3df54a2d015d6ea Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Feb 2008 12:00:48 -0700 Subject: [PATCH 39/56] test update --- mysql-test/r/ps_ddl.result | 3282 +++++++++++++++++++++++++----------- mysql-test/t/ps_ddl.test | 618 ++++--- 2 files changed, 2583 insertions(+), 1317 deletions(-) diff --git a/mysql-test/r/ps_ddl.result b/mysql-test/r/ps_ddl.result index 0987e765265..531d29d219e 100644 --- a/mysql-test/r/ps_ddl.result +++ b/mysql-test/r/ps_ddl.result @@ -1,10 +1,11 @@ +SELECT VARIABLE_VALUE from +INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' +into @base_count ; +set @expected = 0; ===================================================================== Testing 1: NOTHING -> TABLE transitions ===================================================================== drop table if exists t1; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; prepare stmt from 'select * from t1'; ERROR 42S02: Table 'test.t1' doesn't exist ===================================================================== @@ -17,92 +18,144 @@ Testing 3: NOTHING -> VIEW transitions Testing 4: TABLE -> NOTHING transitions ===================================================================== drop table if exists t4; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t4(a int); prepare stmt from 'select * from t4'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t4; execute stmt; ERROR 42S02: Table 'test.t4' doesn't exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; ERROR 42S02: Table 'test.t4' doesn't exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 ===================================================================== Testing 5: TABLE -> TABLE (DDL) transitions ===================================================================== drop table if exists t5; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t5(a int); -prepare stmt from 'select * from t5'; +prepare stmt from 'select a from t5'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 alter table t5 add column (b int); +set @expected = @expected + 1; execute stmt; -a b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +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 b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +a +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t5; ===================================================================== Testing 6: TABLE -> TABLE (TRIGGER) transitions ===================================================================== drop table if exists t6; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t6(a int); prepare stmt from 'insert into t6(a) value (?)'; set @val=1; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 set @val=2; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 create trigger t6_bi before insert on t6 for each row begin set @message= "t6_bi"; @@ -110,20 +163,33 @@ end $$ set @message="none"; set @val=3; +set @expected = @expected + 1; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 @message; @message t6_bi set @val=4; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 @message; @message t6_bi @@ -131,20 +197,32 @@ prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=5; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 @message; @message t6_bi set @message="none"; set @val=6; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 @message; @message t6_bi @@ -155,21 +233,34 @@ end $$ set @message="none"; set @val=7; +set @expected = @expected + 1; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 @message; @message t6_bi set @message="none"; set @val=8; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 @message; @message t6_bi @@ -177,20 +268,32 @@ prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=9; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 @message; @message t6_bi set @message="none"; set @val=10; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 @message; @message t6_bi @@ -202,20 +305,33 @@ end $$ set @message="none"; set @val=11; +set @expected = @expected + 1; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 select @message; @message t6_bi (2) set @val=12; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 select @message; @message t6_bi (2) @@ -223,20 +339,32 @@ prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=13; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 select @message; @message t6_bi (2) set @message="none"; set @val=14; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 select @message; @message t6_bi (2) @@ -248,21 +376,34 @@ end $$ set @message="none"; set @val=15; +set @expected = @expected + 1; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 select @message; @message t6_bi (2) set @message="none"; set @val=16; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 select @message; @message t6_bi (2) @@ -270,40 +411,65 @@ prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=17; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 select @message; @message t6_bi (2) set @message="none"; set @val=18; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 select @message; @message none set @val=20; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 select @message; @message none @@ -311,38 +477,63 @@ prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=21; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 select @message; @message none set @val=22; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 select @message; @message none drop trigger t6_bd; set @val=23; +set @expected = @expected + 1; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 select @message; @message none set @val=24; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 select @message; @message none @@ -386,9 +577,6 @@ drop table if exists t7_audit; drop procedure if exists audit_proc; drop function if exists audit_func; drop view if exists audit_view; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t7_proc(a int); create table t7_func(a int); create table t7_view(a int); @@ -414,155 +602,294 @@ 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 set @val=102; execute stmt_proc using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 set @val=104; execute stmt_proc using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 prepare stmt_func from 'insert into t7_func(a) value (?)'; set @val=201; execute stmt_func using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 set @val=202; execute stmt_func using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 set @val=204; execute stmt_func using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 prepare stmt_view from 'insert into t7_view(a) value (?)'; set @val=301; execute stmt_view using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 set @val=302; execute stmt_view using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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=304; execute stmt_view using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 prepare stmt_table from 'insert into t7_table(a) value (?)'; set @val=401; execute stmt_table using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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=402; execute stmt_table using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 alter table t7_dependent_table drop column comments; set @val=405; +set @expected = @expected + 1; execute stmt_table using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 set @val=406; execute stmt_table using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 prepare stmt_table_trigger from 'insert into t7_table(a) value (?)'; set @val=501; execute stmt_table_trigger using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 set @val=502; execute stmt_table_trigger using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 set @val=504; execute stmt_table_trigger using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 select * from t7_audit order by new_a; old_a new_a reason NULL 101 proc v1 @@ -601,150 +928,237 @@ drop view audit_view; Testing 8: TABLE -> TEMPORARY TABLE transitions ===================================================================== drop table if exists t8; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t8(a int); prepare stmt from 'select * from t8'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t8; create temporary table t8(a int); +set @expected = @expected + 1; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t8; ===================================================================== Testing 9: TABLE -> VIEW transitions ===================================================================== drop table if exists t9; drop table if exists t9_b; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t9(a int); create table t9_b(a int); prepare stmt from 'select * from t9'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t9; create view t9 as select * from t9_b; +set @expected = @expected + 1; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop view t9; drop table t9_b; ===================================================================== Testing 10: TEMPORARY TABLE -> NOTHING transitions ===================================================================== drop temporary table if exists t10; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create temporary table t10(a int); prepare stmt from 'select * from t10'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop temporary table t10; execute stmt; ERROR 42S02: Table 'test.t10' doesn't exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; ERROR 42S02: Table 'test.t10' doesn't exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 ===================================================================== Testing 11: TEMPORARY TABLE -> TABLE transitions ===================================================================== drop table if exists t11; drop temporary table if exists t11; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t11(a int); insert into t11(a) value (1); create temporary table t11(a int); prepare stmt from 'select * from t11'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop temporary table t11; +set @expected = @expected + 1; execute stmt; a 1 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a 1 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 @@ -753,37 +1167,59 @@ drop table t11; Testing 12: TEMPORARY TABLE -> TEMPORARY TABLE (DDL) transitions ===================================================================== drop temporary table if exists t12; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create temporary table t12(a int); -prepare stmt from 'select * from t12'; +prepare stmt from 'select a from t12'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop temporary table t12; create temporary table t12(a int, b int); +set @expected = @expected + 1; execute stmt; -a b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +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 b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +a +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select * from t12; a b drop table t12; @@ -792,38 +1228,60 @@ Testing 13: TEMPORARY TABLE -> VIEW transitions ===================================================================== drop temporary table if exists t13; drop table if exists t13_b; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create temporary table t13(a int); create table t13_b(a int); prepare stmt from 'select * from t13'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop temporary table t13; create view t13 as select * from t13_b; +set @expected = @expected + 1; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop view t13; drop table t13_b; ===================================================================== @@ -831,75 +1289,120 @@ Testing 14: VIEW -> NOTHING transitions ===================================================================== drop view if exists t14; drop table if exists t14_b; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t14_b(a int); create view t14 as select * from t14_b; prepare stmt from 'select * from t14'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop view t14; +set @expected = @expected + 1; execute stmt; ERROR 42S02: Table 'test.t14' doesn't exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 @expected = @expected + 1; execute stmt; ERROR 42S02: Table 'test.t14' doesn't exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t14_b; ===================================================================== Testing 15: VIEW -> TABLE transitions ===================================================================== drop view if exists t15; drop table if exists t15_b; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t15_b(a int); create view t15 as select * from t15_b; prepare stmt from 'select * from t15'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop view t15; create table t15(a int); +set @expected = @expected + 1; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t15_b; drop table t15; ===================================================================== @@ -907,38 +1410,60 @@ Testing 16: VIEW -> TEMPORARY TABLE transitions ===================================================================== drop view if exists t16; drop table if exists t16_b; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t16_b(a int); create view t16 as select * from t16_b; prepare stmt from 'select * from t16'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop view t16; create temporary table t16(a int); +set @expected = @expected + 1; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t16_b; drop temporary table t16; ===================================================================== @@ -946,9 +1471,6 @@ Testing 17: VIEW -> VIEW (DDL) transitions ===================================================================== drop view if exists t17; drop table if exists t17_b; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; 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; @@ -963,44 +1485,69 @@ a b c 10 20 30 20 40 60 30 60 90 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a b c 10 20 30 20 40 60 30 60 90 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop view t17; -create view t17 as select a, 2*a as b, 10*a as c from t17_b; +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 100 -20 40 200 -30 60 300 +10 20 50 +20 40 100 +30 60 150 +set @expected = @expected + 1; execute stmt; a b c -10 20 100 -20 40 200 -30 60 300 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +10 20 50 +20 40 100 +30 60 150 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a b c -10 20 100 -20 40 200 -30 60 300 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +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; ===================================================================== @@ -1013,9 +1560,6 @@ drop view if exists t18_view; drop view if exists t18_table; drop function if exists view_func; drop view if exists view_view; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t18(a int); insert into t18 values (1), (2), (3); create function view_func(x int) returns int @@ -1031,117 +1575,192 @@ a b 1 2 2 3 3 4 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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_func; a b 1 2 2 3 3 4 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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_func; a b 1 1 2 4 3 9 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 prepare stmt_view from 'select * from t18_view'; execute stmt_view; a b 1 view v1 2 view v1 3 view v1 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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_view; a b 1 view v1 2 view v1 3 view v1 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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_view; a b 1 view v2 2 view v2 3 view v2 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 prepare stmt_table from 'select * from t18_table'; execute stmt_table; a 1 2 3 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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_table; a 1 2 3 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 t18 add column comments varchar(50) default NULL; +set @expected = @expected + 1; execute stmt_table; a 1 2 3 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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_table; a 1 2 3 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 t18; drop table t18_dependent_table; drop view t18_func; @@ -1153,9 +1772,6 @@ drop view view_view; Testing 19: Special tables (INFORMATION_SCHEMA) ===================================================================== drop procedure if exists proc_19; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; prepare stmt from 'select ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE from INFORMATION_SCHEMA.ROUTINES where @@ -1164,115 +1780,178 @@ create procedure proc_19() select "hi there"; execute stmt; ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE test proc_19 PROCEDURE -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE test proc_19 PROCEDURE -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop procedure proc_19; create procedure proc_19() select "hi there, again"; execute stmt; ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE test proc_19 PROCEDURE -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE test proc_19 PROCEDURE -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop procedure proc_19; ===================================================================== Testing 20: Special tables (log tables) ===================================================================== -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; prepare stmt from 'select * from mysql.general_log where argument=\'IMPOSSIBLE QUERY STRING\''; execute stmt; event_time user_host thread_id server_id command_type argument -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; event_time user_host thread_id server_id command_type argument -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; event_time user_host thread_id server_id command_type argument -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; event_time user_host thread_id server_id command_type argument -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 ===================================================================== Testing 21: Special tables (system tables) ===================================================================== drop procedure if exists proc_21; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; prepare stmt from 'select type, db, name from mysql.proc where name=\'proc_21\''; create procedure proc_21() select "hi there"; execute stmt; type db name PROCEDURE test proc_21 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; type db name PROCEDURE test proc_21 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop procedure proc_21; create procedure proc_21() select "hi there, again"; execute stmt; type db name PROCEDURE test proc_21 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; type db name PROCEDURE test proc_21 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop procedure proc_21; ===================================================================== Testing 22: Special tables (views temp tables) ===================================================================== drop table if exists t22_b; drop view if exists t22; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t22_b(a int); create algorithm=temptable view t22 as select a*a as a2 from t22_b; show create view t22; @@ -1285,19 +1964,31 @@ a2 1 4 9 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a2 1 4 9 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 insert into t22_b values (4), (5), (6); execute stmt; a2 @@ -1307,10 +1998,16 @@ a2 16 25 36 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a2 1 @@ -1319,10 +2016,16 @@ a2 16 25 36 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t22_b; drop view t22; ===================================================================== @@ -1330,9 +2033,6 @@ Testing 23: Special tables (internal join tables) ===================================================================== drop table if exists t23_a; drop table if exists t23_b; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t23_a(a int); create table t23_b(b int); prepare stmt from 'select * from t23_a join t23_b'; @@ -1349,10 +2049,16 @@ a b 1 30 2 30 3 30 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a b 1 10 @@ -1364,10 +2070,16 @@ a b 1 30 2 30 3 30 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 insert into t23_a values (4); insert into t23_b values (40); execute stmt; @@ -1388,10 +2100,16 @@ a b 2 40 3 40 4 40 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a b 1 10 @@ -1410,45 +2128,72 @@ a b 2 40 3 40 4 40 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t23_a; drop table t23_b; ===================================================================== Testing 24: Special statements ===================================================================== drop table if exists t24_alter; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t24_alter(a int); prepare stmt from 'alter table t24_alter add column b int'; execute stmt; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t24_alter; create table t24_alter(a1 int, a2 int); execute stmt; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 alter table t24_alter drop column b; execute stmt; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 alter table t24_alter drop column b; execute stmt; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t24_alter; drop table if exists t24_repair; create table t24_repair(a int); @@ -1457,36 +2202,60 @@ prepare stmt from 'repair table t24_repair'; execute stmt; Table Op Msg_type Msg_text test.t24_repair repair status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t24_repair; create table t24_repair(a1 int, a2 int); insert into t24_repair values (1, 10), (2, 20), (3, 30); execute stmt; Table Op Msg_type Msg_text test.t24_repair repair status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 alter table t24_repair add column b varchar(50) default NULL; execute stmt; Table Op Msg_type Msg_text test.t24_repair repair status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 alter table t24_repair drop column b; execute stmt; Table Op Msg_type Msg_text test.t24_repair repair status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t24_repair; drop table if exists t24_analyze; create table t24_analyze(a int); @@ -1495,36 +2264,60 @@ prepare stmt from 'analyze table t24_analyze'; execute stmt; Table Op Msg_type Msg_text test.t24_analyze analyze status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t24_analyze; create table t24_analyze(a1 int, a2 int); insert into t24_analyze values (1, 10), (2, 20), (3, 30); execute stmt; Table Op Msg_type Msg_text test.t24_analyze analyze status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 alter table t24_analyze add column b varchar(50) default NULL; execute stmt; Table Op Msg_type Msg_text test.t24_analyze analyze status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 alter table t24_analyze drop column b; execute stmt; Table Op Msg_type Msg_text test.t24_analyze analyze status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t24_analyze; drop table if exists t24_optimize; create table t24_optimize(a int); @@ -1533,176 +2326,308 @@ prepare stmt from 'optimize table t24_optimize'; execute stmt; Table Op Msg_type Msg_text test.t24_optimize optimize status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t24_optimize; create table t24_optimize(a1 int, a2 int); insert into t24_optimize values (1, 10), (2, 20), (3, 30); execute stmt; Table Op Msg_type Msg_text test.t24_optimize optimize status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 alter table t24_optimize add column b varchar(50) default NULL; execute stmt; Table Op Msg_type Msg_text test.t24_optimize optimize status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 alter table t24_optimize drop column b; execute stmt; Table Op Msg_type Msg_text test.t24_optimize optimize status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t24_optimize; drop procedure if exists changing_proc; prepare stmt from 'show create procedure changing_proc'; execute stmt; ERROR 42000: PROCEDURE changing_proc does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; ERROR 42000: PROCEDURE changing_proc does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 create procedure changing_proc() begin end; execute stmt; Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation changing_proc CREATE DEFINER=`root`@`localhost` PROCEDURE `changing_proc`() begin end latin1 latin1_swedish_ci latin1_swedish_ci -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop procedure changing_proc; execute stmt; ERROR 42000: PROCEDURE changing_proc does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; ERROR 42000: PROCEDURE changing_proc does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop function if exists changing_func; prepare stmt from 'show create function changing_func'; execute stmt; ERROR 42000: FUNCTION changing_func does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; ERROR 42000: FUNCTION changing_func does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 create function changing_func() returns int return 0; execute stmt; Function sql_mode Create Function character_set_client collation_connection Database Collation changing_func CREATE DEFINER=`root`@`localhost` FUNCTION `changing_func`() RETURNS int(11) return 0 latin1 latin1_swedish_ci latin1_swedish_ci -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop function changing_func; execute stmt; ERROR 42000: FUNCTION changing_func does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; ERROR 42000: FUNCTION changing_func does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table if exists t24_trigger; create table t24_trigger(a int); prepare stmt from 'show create trigger t24_bi;'; execute stmt; ERROR HY000: Trigger does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; ERROR HY000: Trigger does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 create trigger t24_bi before insert on t24_trigger for each row begin set @message= "t24_bi"; @@ -1714,239 +2639,427 @@ t24_bi CREATE DEFINER=`root`@`localhost` trigger t24_bi before insert on t24_tr begin set @message= "t24_bi"; end latin1 latin1_swedish_ci latin1_swedish_ci -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop trigger t24_bi; create trigger t24_bi before insert on t24_trigger for each row begin set @message= "t24_bi (2)"; end $$ +set @expected = @expected + 1; execute stmt; Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation t24_bi CREATE DEFINER=`root`@`localhost` trigger t24_bi before insert on t24_trigger for each row begin set @message= "t24_bi (2)"; end latin1 latin1_swedish_ci latin1_swedish_ci -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; 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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop trigger t24_bi; execute stmt; ERROR HY000: Trigger does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; ERROR HY000: Trigger does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table t24_trigger; ===================================================================== Testing 25: Testing the strength of TABLE_SHARE version ===================================================================== drop table if exists t25_num_col; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t25_num_col(a int); -prepare stmt from 'select * from t25_num_col'; +prepare stmt from 'select a from t25_num_col'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 alter table t25_num_col add column b varchar(50) default NULL; +set @expected = @expected + 1; execute stmt; -a b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +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 b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +a +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t25_num_col; drop table if exists t25_col_name; create table t25_col_name(a int); prepare stmt from 'select * from t25_col_name'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 t25_col_name change a b int; +set @expected = @expected + 1; execute stmt; -b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +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; -b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +ERROR HY000: Prepared statement result set has changed, rebind needed +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t25_col_name; drop table if exists t25_col_type; create table t25_col_type(a int); prepare stmt from 'select * from t25_col_type'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 alter table t25_col_type change a a varchar(10); +set @expected = @expected + 1; execute stmt; -a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -3 +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; -a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -3 +ERROR HY000: Prepared statement result set has changed, rebind needed +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t25_col_type; drop table if exists t25_col_type_length; create table t25_col_type_length(a varchar(10)); prepare stmt from 'select * from t25_col_type_length'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 t25_col_type_length change a a varchar(20); +set @expected = @expected + 1; execute stmt; -a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -4 +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; -a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -4 +ERROR HY000: Prepared statement result set has changed, rebind needed +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t25_col_type_length; drop table if exists t25_col_null; create table t25_col_null(a varchar(10)); prepare stmt from 'select * from t25_col_null'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 alter table t25_col_null change a a varchar(10) NOT NULL; +set @expected = @expected + 1; execute stmt; -a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -5 +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; -a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -5 +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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -5 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -5 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -5 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -5 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +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 @@ -1959,29 +3072,54 @@ create table t25_index(a varchar(10)); prepare stmt from 'select * from t25_index'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -5 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -5 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 create index i1 on t25_index(a); +set @expected = @expected + 1; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -6 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -6 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +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)); @@ -1996,16 +3134,28 @@ t25_index_unique CREATE TABLE `t25_index_unique` ( prepare stmt from 'select * from t25_index_unique'; execute stmt; a b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -6 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -6 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +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; @@ -2015,18 +3165,31 @@ t25_index_unique CREATE TABLE `t25_index_unique` ( `b` varchar(10) DEFAULT NULL, UNIQUE KEY `i1` (`a`,`b`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 +set @expected = @expected + 1; execute stmt; a b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -7 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -7 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +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; ===================================================================== Testing reported bugs @@ -2035,9 +3198,6 @@ 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; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table table_12093(a int); create function func_12093() returns int @@ -2055,88 +3215,137 @@ prepare stmt_sp from 'call proc_12093(func_12093())'; execute stmt_sf; func_12093() 0 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop function func_12093_unrelated; drop procedure proc_12093_unrelated; execute stmt_sf; func_12093() 0 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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_sf; func_12093() 0 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 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; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create function func_21294() returns int return 10; prepare stmt from "select func_21294()"; execute stmt; func_21294() 10 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop function func_21294; create function func_21294() returns int return 10; execute stmt; func_21294() 10 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop function func_21294; create function func_21294() returns int return 20; +set @expected = @expected + 1; execute stmt; func_21294() 20 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 deallocate prepare stmt; drop function func_21294; drop table if exists t_27420_100; drop table if exists t_27420_101; drop view if exists v_27420; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t_27420_100(a int); insert into t_27420_100 values (1), (2); create table t_27420_101(a int); @@ -2149,35 +3358,52 @@ execute stmt; X Y 1 1 2 2 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop view v_27420; create table v_27420(X int, Y int); +set @expected = @expected + 1; execute stmt; X Y -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table v_27420; create table v_27420 (a int, b int, filler char(200)); +set @expected = @expected + 1; execute stmt; -a b filler -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +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; drop table t_27420_100; drop table t_27420_101; drop table v_27420; drop table if exists t_27430_1; drop table if exists t_27430_2; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t_27430_1 (a int not null, oref int not null, key(a)); insert into t_27430_1 values (1, 1), @@ -2199,20 +3425,32 @@ oref a Z 2 2 0 3 1234 0 4 1234 0 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 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 @@ -2227,35 +3465,38 @@ insert into t_27430_2 values (2,2), (NULL, 3), (NULL, 4); +set @expected = @expected + 1; execute stmt; -oref a Z -1 1 1 -2 2 0 -3 NULL NULL -4 NULL 0 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +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; -oref a Z -1 1 1 -2 2 0 -3 NULL NULL -4 NULL 0 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +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; drop table t_27430_1; drop table t_27430_2; drop table if exists t_27690_1; drop view if exists v_27690_1; drop table if exists v_27690_2; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; 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; @@ -2267,34 +3508,59 @@ a b a b 2 2 1 1 1 1 2 2 2 2 2 2 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; a b a b 1 1 1 1 2 2 1 1 1 1 2 2 2 2 2 2 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 drop table v_27690_1; execute stmt; ERROR 42S02: Table 'test.v_27690_1' doesn't exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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; ERROR 42S02: Table 'test.v_27690_1' doesn't exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 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 @@ -2305,10 +3571,16 @@ a b a b 2 2 2 2 1 1 2 2 2 2 2 2 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a b a b 1 1 1 1 @@ -2319,10 +3591,16 @@ a b a b 2 2 2 2 1 1 2 2 2 2 2 2 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -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 deallocate prepare stmt; drop table t_27690_1; drop view v_27690_1; diff --git a/mysql-test/t/ps_ddl.test b/mysql-test/t/ps_ddl.test index abb6563f052..c824d17063b 100644 --- a/mysql-test/t/ps_ddl.test +++ b/mysql-test/t/ps_ddl.test @@ -55,8 +55,28 @@ let $base_count = SELECT VARIABLE_VALUE from INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' into @base_count ; -let $reprepared = SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; +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 @@ -66,8 +86,6 @@ INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; drop table if exists t1; --enable_warnings -eval $base_count; - # can not be tested since prepare failed --error ER_NO_SUCH_TABLE prepare stmt from 'select * from t1'; @@ -92,23 +110,21 @@ prepare stmt from 'select * from t1'; drop table if exists t4; --enable_warnings -eval $base_count; - create table t4(a int); prepare stmt from 'select * from t4'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t4; --error ER_NO_SUCH_TABLE execute stmt; -eval $reprepared; +eval $check; --error ER_NO_SUCH_TABLE execute stmt; -eval $reprepared; +eval $check; --echo ===================================================================== --echo Testing 5: TABLE -> TABLE (DDL) transitions @@ -118,23 +134,21 @@ eval $reprepared; drop table if exists t5; --enable_warnings -eval $base_count; - create table t5(a int); -prepare stmt from 'select * from t5'; +prepare stmt from 'select a from t5'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; alter table t5 add column (b int); -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t5; @@ -155,17 +169,15 @@ drop table t5; drop table if exists t6; --enable_warnings -eval $base_count; - create table t6(a int); prepare stmt from 'insert into t6(a) value (?)'; set @val=1; execute stmt using @val; -eval $reprepared; +eval $check; set @val=2; execute stmt using @val; -eval $reprepared; +eval $check; # Relevant trigger: execute should reprepare delimiter $$; @@ -178,25 +190,25 @@ delimiter ;$$ set @message="none"; set @val=3; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @val=4; execute stmt using @val; -eval $reprepared; +eval $check; select @message; prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=5; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @message="none"; set @val=6; execute stmt using @val; -eval $reprepared; +eval $check; select @message; # Unrelated trigger: execute can pass of fail, implementation dependent @@ -210,25 +222,26 @@ delimiter ;$$ set @message="none"; set @val=7; +set @expected = @expected + 1; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @message="none"; set @val=8; execute stmt using @val; -eval $reprepared; +eval $check; select @message; prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=9; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @message="none"; set @val=10; execute stmt using @val; -eval $reprepared; +eval $check; select @message; # Relevant trigger: execute should reprepare @@ -243,25 +256,25 @@ delimiter ;$$ set @message="none"; set @val=11; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @val=12; execute stmt using @val; -eval $reprepared; +eval $check; select @message; prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=13; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @message="none"; set @val=14; execute stmt using @val; -eval $reprepared; +eval $check; select @message; # Unrelated trigger: execute can pass of fail, implementation dependent @@ -276,63 +289,62 @@ delimiter ;$$ set @message="none"; set @val=15; +set @expected = @expected + 1; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @message="none"; set @val=16; execute stmt using @val; -eval $reprepared; +eval $check; select @message; prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=17; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @message="none"; set @val=18; execute stmt using @val; -eval $reprepared; +eval $check; select @message; drop trigger t6_bi; set @message="none"; set @val=19; -# safe to re-execute +set @expected = @expected + 1; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @val=20; -# safe to re-execute execute stmt using @val; -eval $reprepared; +eval $check; select @message; prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=21; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @val=22; execute stmt using @val; -eval $reprepared; +eval $check; select @message; drop trigger t6_bd; set @val=23; -# safe to re-execute +set @expected = @expected + 1; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @val=24; -# safe to re-execute execute stmt using @val; -eval $reprepared; +eval $check; select @message; select * from t6 order by a; @@ -363,8 +375,6 @@ drop function if exists audit_func; drop view if exists audit_view; --enable_warnings -eval $base_count; - create table t7_proc(a int); create table t7_func(a int); create table t7_view(a int); @@ -400,10 +410,10 @@ create trigger t7_table_trigger_bi before insert on t7_dependent_table prepare stmt_proc from 'insert into t7_proc(a) value (?)'; set @val=101; execute stmt_proc using @val; -eval $reprepared; +eval $check; set @val=102; execute stmt_proc using @val; -eval $reprepared; +eval $check; drop procedure audit_proc; @@ -411,20 +421,21 @@ 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 $reprepared; +eval $check; set @val=104; execute stmt_proc using @val; -eval $reprepared; +eval $check; prepare stmt_func from 'insert into t7_func(a) value (?)'; set @val=201; execute stmt_func using @val; -eval $reprepared; +eval $check; set @val=202; execute stmt_func using @val; -eval $reprepared; +eval $check; drop function audit_func; @@ -432,19 +443,20 @@ create function audit_func() returns varchar(50) return "func v2"; set @val=203; +set @expected = @expected + 1; execute stmt_func using @val; -eval $reprepared; +eval $check; set @val=204; execute stmt_func using @val; -eval $reprepared; +eval $check; prepare stmt_view from 'insert into t7_view(a) value (?)'; set @val=301; execute stmt_view using @val; -eval $reprepared; +eval $check; set @val=302; execute stmt_view using @val; -eval $reprepared; +eval $check; drop view audit_view; @@ -455,52 +467,53 @@ create view audit_view as select "view v2" as reason from dual; # This is because the table trigger is cached and is not invalidated. set @val=303; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt_view using @val; -eval $reprepared; +eval $check; set @val=304; execute stmt_view using @val; -eval $reprepared; +eval $check; prepare stmt_table from 'insert into t7_table(a) value (?)'; set @val=401; execute stmt_table using @val; -eval $reprepared; +eval $check; set @val=402; execute stmt_table using @val; -eval $reprepared; +eval $check; alter table t7_dependent_table add column comments varchar(100) default NULL; set @val=403; -# REPREPARED +1 +set @expected = @expected + 1; --error ER_WRONG_VALUE_COUNT_ON_ROW execute stmt_table using @val; -eval $reprepared; +eval $check; set @val=404; +set @expected = @expected + 1; --error ER_WRONG_VALUE_COUNT_ON_ROW execute stmt_table using @val; -eval $reprepared; +eval $check; alter table t7_dependent_table drop column comments; set @val=405; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt_table using @val; -eval $reprepared; +eval $check; set @val=406; execute stmt_table using @val; -eval $reprepared; +eval $check; prepare stmt_table_trigger from 'insert into t7_table(a) value (?)'; set @val=501; execute stmt_table_trigger using @val; -eval $reprepared; +eval $check; set @val=502; execute stmt_table_trigger using @val; -eval $reprepared; +eval $check; drop trigger t7_table_trigger_bi; @@ -508,12 +521,12 @@ create trigger t7_table_trigger_bi before insert on t7_dependent_table for each row set NEW.reason="trigger v2"; set @val=503; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt_table_trigger using @val; -eval $reprepared; +eval $check; set @val=504; execute stmt_table_trigger using @val; -eval $reprepared; +eval $check; select * from t7_audit order by new_a; @@ -538,24 +551,22 @@ drop view audit_view; drop table if exists t8; --enable_warnings -eval $base_count; - create table t8(a int); prepare stmt from 'select * from t8'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t8; create temporary table t8(a int); -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t8; @@ -568,25 +579,23 @@ drop table if exists t9; drop table if exists t9_b; --enable_warnings -eval $base_count; - create table t9(a int); create table t9_b(a int); prepare stmt from 'select * from t9'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t9; create view t9 as select * from t9_b; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop view t9; drop table t9_b; @@ -599,23 +608,21 @@ drop table t9_b; drop temporary table if exists t10; --enable_warnings -eval $base_count; - create temporary table t10(a int); prepare stmt from 'select * from t10'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop temporary table t10; --error ER_NO_SUCH_TABLE execute stmt; -eval $reprepared; +eval $check; --error ER_NO_SUCH_TABLE execute stmt; -eval $reprepared; +eval $check; --echo ===================================================================== --echo Testing 11: TEMPORARY TABLE -> TABLE transitions @@ -626,25 +633,23 @@ drop table if exists t11; drop temporary table if exists t11; --enable_warnings -eval $base_count; - 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 $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop temporary table t11; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; select * from t11; drop table t11; @@ -657,24 +662,22 @@ drop table t11; drop temporary table if exists t12; --enable_warnings -eval $base_count; - create temporary table t12(a int); -prepare stmt from 'select * from t12'; +prepare stmt from 'select a from t12'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop temporary table t12; create temporary table t12(a int, b int); -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; select * from t12; drop table t12; @@ -688,25 +691,23 @@ drop temporary table if exists t13; drop table if exists t13_b; --enable_warnings -eval $base_count; - create temporary table t13(a int); create table t13_b(a int); prepare stmt from 'select * from t13'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop temporary table t13; create view t13 as select * from t13_b; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop view t13; drop table t13_b; @@ -720,26 +721,25 @@ drop view if exists t14; drop table if exists t14_b; --enable_warnings -eval $base_count; - create table t14_b(a int); create view t14 as select * from t14_b; prepare stmt from 'select * from t14'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop view t14; -# REPREPARED +1 +set @expected = @expected + 1; --error ER_NO_SUCH_TABLE execute stmt; -eval $reprepared; +eval $check; +set @expected = @expected + 1; --error ER_NO_SUCH_TABLE execute stmt; -eval $reprepared; +eval $check; drop table t14_b; @@ -752,25 +752,23 @@ drop view if exists t15; drop table if exists t15_b; --enable_warnings -eval $base_count; - create table t15_b(a int); create view t15 as select * from t15_b; prepare stmt from 'select * from t15'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop view t15; create table t15(a int); -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t15_b; drop table t15; @@ -784,25 +782,23 @@ drop view if exists t16; drop table if exists t16_b; --enable_warnings -eval $base_count; - create table t16_b(a int); create view t16 as select * from t16_b; prepare stmt from 'select * from t16'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop view t16; create temporary table t16(a int); -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t16_b; drop temporary table t16; @@ -816,8 +812,6 @@ drop view if exists t17; drop table if exists t17_b; --enable_warnings -eval $base_count; - create table t17_b(a int); insert into t17_b values (10), (20), (30); @@ -826,19 +820,19 @@ select * from t17; prepare stmt from 'select * from t17'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop view t17; -create view t17 as select a, 2*a as b, 10*a as c from t17_b; +create view t17 as select a, 2*a as b, 5*a as c from t17_b; select * from t17; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t17_b; drop view t17; @@ -865,8 +859,6 @@ drop function if exists view_func; drop view if exists view_view; --enable_warnings -eval $base_count; - # TODO: insertable view -> trigger # TODO: insertable view -> trigger -> proc ? @@ -886,47 +878,48 @@ create view t18_table as select * from t18; prepare stmt_func from 'select * from t18_func'; execute stmt_func; -eval $reprepared; +eval $check; execute stmt_func; -eval $reprepared; +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 $reprepared; +eval $check; execute stmt_func; -eval $reprepared; +eval $check; prepare stmt_view from 'select * from t18_view'; execute stmt_view; -eval $reprepared; +eval $check; execute stmt_view; -eval $reprepared; +eval $check; drop view view_view; create view view_view as select "view v2" as reason from dual; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt_view; -eval $reprepared; +eval $check; execute stmt_view; -eval $reprepared; +eval $check; prepare stmt_table from 'select * from t18_table'; execute stmt_table; -eval $reprepared; +eval $check; execute stmt_table; -eval $reprepared; +eval $check; alter table t18 add column comments varchar(50) default NULL; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt_table; -eval $reprepared; +eval $check; execute stmt_table; -eval $reprepared; +eval $check; drop table t18; drop table t18_dependent_table; @@ -944,8 +937,6 @@ drop view view_view; drop procedure if exists proc_19; --enable_warnings -eval $base_count; - # Using a temporary table internally should not confuse the prepared # statement code, and should not raise ER_PS_INVALIDATED errors prepare stmt from @@ -956,17 +947,17 @@ prepare stmt from create procedure proc_19() select "hi there"; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop procedure proc_19; create procedure proc_19() select "hi there, again"; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop procedure proc_19; @@ -974,19 +965,17 @@ drop procedure proc_19; --echo Testing 20: Special tables (log tables) --echo ===================================================================== -eval $base_count; - prepare stmt from 'select * from mysql.general_log where argument=\'IMPOSSIBLE QUERY STRING\''; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; --echo ===================================================================== --echo Testing 21: Special tables (system tables) @@ -996,25 +985,23 @@ eval $reprepared; drop procedure if exists proc_21; --enable_warnings -eval $base_count; - prepare stmt from 'select type, db, name from mysql.proc where name=\'proc_21\''; create procedure proc_21() select "hi there"; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop procedure proc_21; create procedure proc_21() select "hi there, again"; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop procedure proc_21; @@ -1027,8 +1014,6 @@ drop table if exists t22_b; drop view if exists t22; --enable_warnings -eval $base_count; - create table t22_b(a int); create algorithm=temptable view t22 as select a*a as a2 from t22_b; @@ -1041,15 +1026,15 @@ prepare stmt from 'select * from t22'; insert into t22_b values (1), (2), (3); execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; insert into t22_b values (4), (5), (6); execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t22_b; drop view t22; @@ -1063,8 +1048,6 @@ drop table if exists t23_a; drop table if exists t23_b; --enable_warnings -eval $base_count; - create table t23_a(a int); create table t23_b(b int); @@ -1075,16 +1058,16 @@ prepare stmt from 'select * from t23_a join t23_b'; insert into t23_a values (1), (2), (3); insert into t23_b values (10), (20), (30); execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; insert into t23_a values (4); insert into t23_b values (40); execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t23_a; drop table t23_b; @@ -1099,28 +1082,26 @@ drop table t23_b; drop table if exists t24_alter; --enable_warnings -eval $base_count; - create table t24_alter(a int); prepare stmt from 'alter table t24_alter add column b int'; execute stmt; -eval $reprepared; +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 $reprepared; +eval $check; alter table t24_alter drop column b; execute stmt; -eval $reprepared; +eval $check; alter table t24_alter drop column b; execute stmt; -eval $reprepared; +eval $check; drop table t24_alter; @@ -1135,7 +1116,7 @@ insert into t24_repair values (1), (2), (3); prepare stmt from 'repair table t24_repair'; execute stmt; -eval $reprepared; +eval $check; drop table t24_repair; create table t24_repair(a1 int, a2 int); @@ -1143,15 +1124,15 @@ insert into t24_repair values (1, 10), (2, 20), (3, 30); # t24_repair has changed, and it's not a problem execute stmt; -eval $reprepared; +eval $check; alter table t24_repair add column b varchar(50) default NULL; execute stmt; -eval $reprepared; +eval $check; alter table t24_repair drop column b; execute stmt; -eval $reprepared; +eval $check; drop table t24_repair; @@ -1166,7 +1147,7 @@ insert into t24_analyze values (1), (2), (3); prepare stmt from 'analyze table t24_analyze'; execute stmt; -eval $reprepared; +eval $check; drop table t24_analyze; create table t24_analyze(a1 int, a2 int); @@ -1174,15 +1155,15 @@ insert into t24_analyze values (1, 10), (2, 20), (3, 30); # t24_analyze has changed, and it's not a problem execute stmt; -eval $reprepared; +eval $check; alter table t24_analyze add column b varchar(50) default NULL; execute stmt; -eval $reprepared; +eval $check; alter table t24_analyze drop column b; execute stmt; -eval $reprepared; +eval $check; drop table t24_analyze; @@ -1197,7 +1178,7 @@ insert into t24_optimize values (1), (2), (3); prepare stmt from 'optimize table t24_optimize'; execute stmt; -eval $reprepared; +eval $check; drop table t24_optimize; create table t24_optimize(a1 int, a2 int); @@ -1205,15 +1186,15 @@ insert into t24_optimize values (1, 10), (2, 20), (3, 30); # t24_optimize has changed, and it's not a problem execute stmt; -eval $reprepared; +eval $check; alter table t24_optimize add column b varchar(50) default NULL; execute stmt; -eval $reprepared; +eval $check; alter table t24_optimize drop column b; execute stmt; -eval $reprepared; +eval $check; drop table t24_optimize; @@ -1226,35 +1207,35 @@ drop procedure if exists changing_proc; prepare stmt from 'show create procedure changing_proc'; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; create procedure changing_proc() begin end; # changing_proc has changed, and it's not a problem execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop procedure changing_proc; create procedure changing_proc(x int, y int) begin end; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop procedure changing_proc; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; # SQLCOM_SHOW_CREATE_FUNC: @@ -1265,35 +1246,35 @@ drop function if exists changing_func; prepare stmt from 'show create function changing_func'; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; create function changing_func() returns int return 0; # changing_proc has changed, and it's not a problem execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop function changing_func; create function changing_func(x int, y int) returns int return x+y; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop function changing_func; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; # SQLCOM_SHOW_CREATE_TRIGGER: @@ -1306,10 +1287,10 @@ create table t24_trigger(a int); prepare stmt from 'show create trigger t24_bi;'; --error ER_TRG_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; --error ER_TRG_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; delimiter $$; create trigger t24_bi before insert on t24_trigger for each row @@ -1321,9 +1302,9 @@ delimiter ;$$ # t24_bi has changed, and it's not a problem execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop trigger t24_bi; delimiter $$; @@ -1335,19 +1316,20 @@ $$ delimiter ;$$ # t24_bi has changed, and it's not a problem +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop trigger t24_bi; --error ER_TRG_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; --error ER_TRG_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; drop table t24_trigger; @@ -1361,23 +1343,21 @@ drop table t24_trigger; drop table if exists t25_num_col; --enable_warnings -eval $base_count; - create table t25_num_col(a int); -prepare stmt from 'select * from t25_num_col'; +prepare stmt from 'select a from t25_num_col'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; alter table t25_num_col add column b varchar(50) default NULL; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t25_num_col; @@ -1391,17 +1371,20 @@ create table t25_col_name(a int); prepare stmt from 'select * from t25_col_name'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; alter table t25_col_name change a b int; -# REPREPARED +1 +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; drop table t25_col_name; @@ -1415,17 +1398,20 @@ create table t25_col_type(a int); prepare stmt from 'select * from t25_col_type'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; alter table t25_col_type change a a varchar(10); -# REPREPARED +1 +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; drop table t25_col_type; @@ -1439,17 +1425,20 @@ create table t25_col_type_length(a varchar(10)); prepare stmt from 'select * from t25_col_type_length'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; alter table t25_col_type_length change a a varchar(20); -# REPREPARED +1 +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; drop table t25_col_type_length; @@ -1463,17 +1452,20 @@ create table t25_col_null(a varchar(10)); prepare stmt from 'select * from t25_col_null'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; alter table t25_col_null change a a varchar(10) NOT NULL; -# REPREPARED +1 +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; drop table t25_col_null; @@ -1488,22 +1480,23 @@ 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 $reprepared; +eval $check; set @val=2; execute stmt using @val; -eval $reprepared; +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 $reprepared; +eval $check; set @val=4; # Must insert the correct default value for b execute stmt using @val; -eval $reprepared; +eval $check; select * from t25_col_default; @@ -1519,17 +1512,17 @@ create table t25_index(a varchar(10)); prepare stmt from 'select * from t25_index'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; create index i1 on t25_index(a); -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t25_index; @@ -1546,20 +1539,20 @@ show create table t25_index_unique; prepare stmt from 'select * from t25_index_unique'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +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; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t25_index_unique; @@ -1579,8 +1572,6 @@ drop function if exists func_12093_unrelated; drop procedure if exists proc_12093; --enable_warnings -eval $base_count; - connect (con1,localhost,root,,); connection default; @@ -1609,9 +1600,9 @@ prepare stmt_sf from 'select func_12093();'; prepare stmt_sp from 'call proc_12093(func_12093())'; execute stmt_sf; -eval $reprepared; +eval $check; execute stmt_sp; -eval $reprepared; +eval $check; connection con1; @@ -1622,17 +1613,17 @@ connection default; # previously, failed with --error 1305 execute stmt_sf; -eval $reprepared; +eval $check; # previously, failed with --error 1305 execute stmt_sp; -eval $reprepared; +eval $check; # previously, failed with --error 1305 execute stmt_sf; -eval $reprepared; +eval $check; # previously, failed with --error 1305 execute stmt_sp; -eval $reprepared; +eval $check; deallocate prepare stmt_sf; deallocate prepare stmt_sp; @@ -1652,26 +1643,25 @@ drop procedure proc_12093; drop function if exists func_21294; --enable_warnings -eval $base_count; - create function func_21294() returns int return 10; prepare stmt from "select func_21294()"; execute stmt; -eval $reprepared; +eval $check; drop function func_21294; create function func_21294() returns int return 10; # might pass or fail, implementation dependent execute stmt; -eval $reprepared; +eval $check; drop function func_21294; create function func_21294() returns int return 20; +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; deallocate prepare stmt; drop function func_21294; @@ -1687,8 +1677,6 @@ drop table if exists t_27420_101; drop view if exists v_27420; --enable_warnings -eval $base_count; - connect (con1,localhost,root,,); connection default; @@ -1706,7 +1694,7 @@ create view v_27420 as select t_27420_100.a X, t_27420_101.a Y prepare stmt from 'select * from v_27420'; execute stmt; -eval $reprepared; +eval $check; connection con1; @@ -1715,9 +1703,9 @@ create table v_27420(X int, Y int); connection default; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; connection con1; @@ -1727,9 +1715,10 @@ create table v_27420 (a int, b int, filler char(200)); connection default; -# REPREPARED +1 +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; disconnect con1; @@ -1748,8 +1737,6 @@ drop table if exists t_27430_1; drop table if exists t_27430_2; --enable_warnings -eval $base_count; - create table t_27430_1 (a int not null, oref int not null, key(a)); insert into t_27430_1 values (1, 1), @@ -1769,9 +1756,9 @@ prepare stmt from 'select oref, a, a in (select a from t_27430_1 where oref=t_27430_2.oref) Z from t_27430_2'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t_27430_1, t_27430_2; @@ -1790,11 +1777,14 @@ insert into t_27430_2 values (NULL, 3), (NULL, 4); -# REPREPARED +1 +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; deallocate prepare stmt; drop table t_27430_1; @@ -1811,8 +1801,6 @@ drop view if exists v_27690_1; drop table if exists v_27690_2; --enable_warnings -eval $base_count; - create table t_27690_1 (a int, b int); insert into t_27690_1 values (1,1),(2,2); @@ -1822,27 +1810,27 @@ create table v_27690_2 as select * from t_27690_1; prepare stmt from 'select * from v_27690_1, v_27690_2'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table v_27690_1; --error ER_NO_SUCH_TABLE execute stmt; -eval $reprepared; +eval $check; --error ER_NO_SUCH_TABLE execute stmt; -eval $reprepared; +eval $check; create view v_27690_1 as select A.a, A.b from t_27690_1 A, t_27690_1 B; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; deallocate prepare stmt; drop table t_27690_1; From 32ae4aefe6e661dbbb28509fcd2bfe4c487faa54 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Feb 2008 23:52:30 +0300 Subject: [PATCH 40/56] Fix compile warning about undefined rmdir() function. --- client/mysqltest.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/mysqltest.c b/client/mysqltest.c index 0fd83b86502..05c9ced3848 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -51,6 +51,10 @@ #ifdef HAVE_SYS_WAIT_H #include #endif +#ifdef __WIN__ +#include +#endif + #ifndef WEXITSTATUS # ifdef __WIN__ From d9831ae5329d6916667ee9beb885c3e4c35c4018 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Feb 2008 19:58:06 -0200 Subject: [PATCH 41/56] Bug#31891 Meaningful stack trace On crashes generate a user-friendly resolved and demangled stack trace when libc provides the necessary functions (newer libc on i386, x86_64, powerpc, ia64, alpha and s390). Otherwise print a numeric stack trace as before, relying on resolve_stack_dump utility. configure.in: Add check for backtrace headers, backtrace functions and if __cxa_demangle (libstdc++) is available at link time. sql/mysqld.cc: Print the value of the THD::killed variable when dumping. In some circumstances knowing if the thread was killed makes debugging easier. sql/stacktrace.c: Use the glibc backtrace function when available and demangle C++ function names if the __cxa_demangle function is available. sql/stacktrace.h: Locally export and wrap in C linkage the C++ function __cxa_demangle if available. --- configure.in | 21 +++++++++++++--- sql/mysqld.cc | 29 ++++++++++++++++++++++ sql/stacktrace.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ sql/stacktrace.h | 8 ++++++ 4 files changed, 119 insertions(+), 3 deletions(-) diff --git a/configure.in b/configure.in index 1346a87c35a..2e623aacaf7 100644 --- a/configure.in +++ b/configure.in @@ -813,8 +813,8 @@ AC_CHECK_HEADERS(fcntl.h float.h floatingpoint.h ieeefp.h limits.h \ sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \ unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \ sys/ioctl.h malloc.h sys/malloc.h sys/ipc.h sys/shm.h linux/config.h \ - sys/prctl.h \ - sys/resource.h sys/param.h port.h ieeefp.h) + sys/prctl.h sys/resource.h sys/param.h port.h ieeefp.h \ + execinfo.h) AC_CHECK_HEADERS([xfs/xfs.h]) @@ -2041,7 +2041,7 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bsearch bzero \ sighold sigset sigthreadmask port_create sleep \ snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr \ strtol strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr \ - posix_fallocate) + posix_fallocate backtrace backtrace_symbols backtrace_symbols_fd) # # @@ -2331,6 +2331,21 @@ then fi AC_MSG_RESULT("$netinet_inc") +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +AC_CHECK_HEADERS(cxxabi.h) +AC_CACHE_CHECK([checking for abi::__cxa_demangle], mysql_cv_cxa_demangle, +[AC_TRY_LINK([#include ], [ + char *foo= 0; int bar= 0; + foo= abi::__cxa_demangle(foo, foo, 0, &bar); +], [mysql_cv_cxa_demangle=yes], [mysql_cv_cxa_demangle=no])]) +AC_LANG_RESTORE + +if test "x$mysql_cv_cxa_demangle" = xyes; then + AC_DEFINE(HAVE_ABI_CXA_DEMANGLE, 1, + [Define to 1 if you have the `abi::__cxa_demangle' function.]) +fi + #-------------------------------------------------------------------- # Check for requested features #-------------------------------------------------------------------- diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9dc77fb8356..84f7620962e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2182,6 +2182,16 @@ static void check_data_home(const char *path) #define UNSAFE_DEFAULT_LINUX_THREADS 200 #endif + +#if BACKTRACE_DEMANGLE +#include +extern "C" char *my_demangle(const char *mangled_name, int *status) +{ + return abi::__cxa_demangle(mangled_name, NULL, NULL, status); +} +#endif + + extern "C" sig_handler handle_segfault(int sig) { time_t curr_time; @@ -2253,10 +2263,29 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n", } if (thd) { + const char *kreason= "UNKNOWN"; + switch (thd->killed) { + case THD::NOT_KILLED: + kreason= "NOT_KILLED"; + break; + case THD::KILL_BAD_DATA: + kreason= "KILL_BAD_DATA"; + break; + case THD::KILL_CONNECTION: + kreason= "KILL_CONNECTION"; + break; + case THD::KILL_QUERY: + kreason= "KILL_QUERY"; + break; + case THD::KILLED_NO_VALUE: + kreason= "KILLED_NO_VALUE"; + break; + } fprintf(stderr, "Trying to get some variables.\n\ Some pointers may be invalid and cause the dump to abort...\n"); safe_print_str("thd->query", thd->query, 1024); fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id); + fprintf(stderr, "thd->killed=%s\n", kreason); } fprintf(stderr, "\ The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\ diff --git a/sql/stacktrace.c b/sql/stacktrace.c index b1267e20774..3d718dfd9d2 100644 --- a/sql/stacktrace.c +++ b/sql/stacktrace.c @@ -17,11 +17,16 @@ #include "stacktrace.h" #include #include +#include #ifdef HAVE_STACKTRACE #include #include +#if HAVE_EXECINFO_H +#include +#endif + #define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end) char *heap_start; @@ -93,9 +98,68 @@ inline uint32* find_prev_pc(uint32* pc, uchar** fp) } #endif /* defined(__alpha__) && defined(__GNUC__) */ +#if BACKTRACE_DEMANGLE +static void my_demangle_symbols(char **addrs, int n) +{ + int status, i; + char *begin, *end, *demangled; + + for (i= 0; i < n; i++) + { + demangled= NULL; + begin= strchr(addrs[i], '('); + end= begin ? strchr(begin, '+') : NULL; + + if (begin && end) + { + *begin++= *end++= '\0'; + demangled= my_demangle(begin, &status); + if (!demangled || status) + { + demangled= NULL; + begin[-1]= '('; + end[-1]= '+'; + } + } + + if (demangled) + fprintf(stderr, "%s(%s+%s\n", addrs[i], demangled, end); + else + fprintf(stderr, "%s\n", addrs[i]); + } +} +#endif + + +#if HAVE_BACKTRACE +static void backtrace_current_thread(void) +{ + void *addrs[128]; + char **strings= NULL; + int n = backtrace(addrs, array_elements(addrs)); +#if BACKTRACE_DEMANGLE + if ((strings= backtrace_symbols(addrs, n))) + { + my_demangle_symbols(strings, n); + free(strings); + } +#endif +#if HAVE_BACKTRACE_SYMBOLS_FD + if (!strings) + { + backtrace_symbols_fd(addrs, n, fileno(stderr)); + } +#endif +} +#endif + void print_stacktrace(uchar* stack_bottom, ulong thread_stack) { +#if HAVE_BACKTRACE + backtrace_current_thread(); + return; +#endif uchar** fp; uint frame_count = 0, sigreturn_frame_count; #if defined(__alpha__) && defined(__GNUC__) diff --git a/sql/stacktrace.h b/sql/stacktrace.h index 1a0b80c88d3..96c09a21ad6 100644 --- a/sql/stacktrace.h +++ b/sql/stacktrace.h @@ -17,6 +17,14 @@ extern "C" { #endif +#if HAVE_BACKTRACE && HAVE_BACKTRACE_SYMBOLS && HAVE_CXXABI_H && HAVE_ABI_CXA_DEMANGLE +#define BACKTRACE_DEMANGLE 1 +#endif + +#if BACKTRACE_DEMANGLE +char *my_demangle(const char *mangled_name, int *status); +#endif + #ifdef TARGET_OS_LINUX #if defined(HAVE_STACKTRACE) || (defined (__x86_64__) || defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) #undef HAVE_STACKTRACE From ed312cb5790c33d91e1160e9a41eb4d9df2675bd Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Feb 2008 13:35:11 +0300 Subject: [PATCH 42/56] Give a more informative message if we failed to write to mysql.general_log table. --- sql/log.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 3a09acd8fca..06f4e2d7b78 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -73,23 +73,28 @@ static int binlog_prepare(handlerton *hton, THD *thd, bool all); */ class Silence_log_table_errors : public Internal_error_handler { + char m_message[MYSQL_ERRMSG_SIZE]; public: Silence_log_table_errors() - {} + { + m_message[0]= '\0'; + } virtual ~Silence_log_table_errors() {} virtual bool handle_error(uint sql_errno, const char *message, MYSQL_ERROR::enum_warning_level level, THD *thd); + const char *message() const { return m_message; } }; bool Silence_log_table_errors::handle_error(uint /* sql_errno */, - const char * /* message */, + const char *message_arg, MYSQL_ERROR::enum_warning_level /* level */, THD * /* thd */) { + strmake(m_message, message_arg, sizeof(m_message)); return TRUE; } @@ -437,7 +442,8 @@ bool Log_to_csv_event_handler:: err: if (result) - sql_print_error("Failed to write to mysql.general_log"); + sql_print_error("Failed to write to mysql.general_log: %s", + error_handler.message()); if (need_rnd_end) { From 7d98c21cdf4235ebe0d4abc52ae71fa4502e1524 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Feb 2008 08:55:55 -0200 Subject: [PATCH 43/56] Bug#33798 prepared statements improperly handle large unsigned ints The unsignedness of large integer user variables was not being properly preserved when feeded to prepared statements. This was happening because the unsigned flags wasn't being updated when converting the user variable is converted to a parameter. The solution is to copy the unsigned flag when converting the user variable to a parameter and take the unsigned flag into account when converting the integer to a string. mysql-test/r/binlog.result: Add test case result for Bug#33798 mysql-test/r/ps.result: Add test case result for Bug#33798 mysql-test/t/binlog.test: Add test case for Bug#33798 mysql-test/t/ps.test: Add test case for Bug#33798 sql/item.cc: Take the unsigned flag into account when converting the user variable. --- mysql-test/r/binlog.result | 15 +++++++++++++++ mysql-test/r/ps.result | 16 ++++++++++++++++ mysql-test/t/binlog.test | 17 +++++++++++++++++ mysql-test/t/ps.test | 17 +++++++++++++++++ sql/item.cc | 6 +++++- 5 files changed, 70 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/binlog.result b/mysql-test/r/binlog.result index 0a199c87545..e6c5e3222de 100644 --- a/mysql-test/r/binlog.result +++ b/mysql-test/r/binlog.result @@ -567,4 +567,19 @@ master-bin.000001 36585 Rotate 1 36629 master-bin.000002;pos=4 drop table t1; set global binlog_cache_size=@bcs; set session autocommit = @ac; +drop table if exists t1; +reset master; +create table t1 (a bigint unsigned, b bigint(20) unsigned); +prepare stmt from "insert into t1 values (?,?)"; +set @a= 9999999999999999; +set @b= 14632475938453979136; +execute stmt using @a, @b; +deallocate prepare stmt; +drop table t1; +show binlog events from 0; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 4 Format_desc 1 98 Server version, Binlog ver: 4 +master-bin.000001 98 Query 1 219 use `test`; create table t1 (a bigint unsigned, b bigint(20) unsigned) +master-bin.000001 219 Query 1 343 use `test`; insert into t1 values (9999999999999999,14632475938453979136) +master-bin.000001 343 Query 1 419 use `test`; drop table t1 End of 5.0 tests diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index f547654bed1..8845f011971 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1693,4 +1693,20 @@ t1 CREATE TABLE `t1` ( `?` decimal(2,1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +drop table if exists t1; +create table t1 (a bigint unsigned, b bigint(20) unsigned); +prepare stmt from "insert into t1 values (?,?)"; +set @a= 9999999999999999; +set @b= 14632475938453979136; +insert into t1 values (@a, @b); +select * from t1 where a = @a and b = @b; +a b +9999999999999999 14632475938453979136 +execute stmt using @a, @b; +select * from t1 where a = @a and b = @b; +a b +9999999999999999 14632475938453979136 +9999999999999999 14632475938453979136 +deallocate prepare stmt; +drop table t1; End of 5.0 tests. diff --git a/mysql-test/t/binlog.test b/mysql-test/t/binlog.test index 5d1399925c3..b35c81b3b18 100644 --- a/mysql-test/t/binlog.test +++ b/mysql-test/t/binlog.test @@ -106,4 +106,21 @@ drop table t1; set global binlog_cache_size=@bcs; set session autocommit = @ac; +# +# Bug#33798: prepared statements improperly handle large unsigned ints +# +--disable_warnings +drop table if exists t1; +--enable_warnings +reset master; +create table t1 (a bigint unsigned, b bigint(20) unsigned); +prepare stmt from "insert into t1 values (?,?)"; +set @a= 9999999999999999; +set @b= 14632475938453979136; +execute stmt using @a, @b; +deallocate prepare stmt; +drop table t1; +--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/ +show binlog events from 0; + --echo End of 5.0 tests diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index c1505ffd645..3f4b37f13f4 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1807,4 +1807,21 @@ execute stmt using @a; show create table t1; drop table t1; +# +# Bug#33798: prepared statements improperly handle large unsigned ints +# +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (a bigint unsigned, b bigint(20) unsigned); +prepare stmt from "insert into t1 values (?,?)"; +set @a= 9999999999999999; +set @b= 14632475938453979136; +insert into t1 values (@a, @b); +select * from t1 where a = @a and b = @b; +execute stmt using @a, @b; +select * from t1 where a = @a and b = @b; +deallocate prepare stmt; +drop table t1; + --echo End of 5.0 tests. diff --git a/sql/item.cc b/sql/item.cc index 713e7709bcb..ffb18054750 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2580,6 +2580,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry) if (entry && entry->value) { item_result_type= entry->type; + unsigned_flag= entry->unsigned_flag; if (strict_type && required_result_type != item_result_type) DBUG_RETURN(1); switch (item_result_type) { @@ -2875,7 +2876,10 @@ const String *Item_param::query_val_str(String* str) const { switch (state) { case INT_VALUE: - str->set(value.integer, &my_charset_bin); + if (unsigned_flag) + str->set((ulonglong) value.integer, &my_charset_bin); + else + str->set(value.integer, &my_charset_bin); break; case REAL_VALUE: str->set(value.real, NOT_FIXED_DEC, &my_charset_bin); From 0c551b72ded5140e00c0dbe7eadab172f298742f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Feb 2008 10:47:25 -0200 Subject: [PATCH 44/56] Manual merge of Bug 33798 mysql-test/extra/binlog_tests/binlog.test: Manual merge of binlog test case for Bug#33798 mysql-test/suite/binlog/r/binlog_row_binlog.result: Add test case result for Bug#33798 mysql-test/suite/binlog/r/binlog_stm_binlog.result: Add test case result for Bug#33798 sql/item.cc: Use new method which accepts a unsigned flag. --- mysql-test/extra/binlog_tests/binlog.test | 17 +++++++++++++++++ .../suite/binlog/r/binlog_row_binlog.result | 16 ++++++++++++++++ .../suite/binlog/r/binlog_stm_binlog.result | 15 +++++++++++++++ sql/item.cc | 5 +---- 4 files changed, 49 insertions(+), 4 deletions(-) diff --git a/mysql-test/extra/binlog_tests/binlog.test b/mysql-test/extra/binlog_tests/binlog.test index 0d2ed7ad509..48fc5a81c7b 100644 --- a/mysql-test/extra/binlog_tests/binlog.test +++ b/mysql-test/extra/binlog_tests/binlog.test @@ -108,6 +108,23 @@ drop table t1; set global binlog_cache_size=@bcs; set session autocommit = @ac; +# +# Bug#33798: prepared statements improperly handle large unsigned ints +# +--disable_warnings +drop table if exists t1; +--enable_warnings +reset master; +create table t1 (a bigint unsigned, b bigint(20) unsigned); +prepare stmt from "insert into t1 values (?,?)"; +set @a= 9999999999999999; +set @b= 14632475938453979136; +execute stmt using @a, @b; +deallocate prepare stmt; +drop table t1; +--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/ +show binlog events from 0; + --echo End of 5.0 tests # Test of a too big SET INSERT_ID: see if the truncated value goes diff --git a/mysql-test/suite/binlog/r/binlog_row_binlog.result b/mysql-test/suite/binlog/r/binlog_row_binlog.result index fd91f65bbb5..51087d8b2ea 100644 --- a/mysql-test/suite/binlog/r/binlog_row_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result @@ -1072,6 +1072,22 @@ master-bin.000001 30301 Rotate 1 30345 master-bin.000002;pos=4 drop table t1; set global binlog_cache_size=@bcs; set session autocommit = @ac; +drop table if exists t1; +reset master; +create table t1 (a bigint unsigned, b bigint(20) unsigned); +prepare stmt from "insert into t1 values (?,?)"; +set @a= 9999999999999999; +set @b= 14632475938453979136; +execute stmt using @a, @b; +deallocate prepare stmt; +drop table t1; +show binlog events from 0; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 +master-bin.000001 106 Query 1 227 use `test`; create table t1 (a bigint unsigned, b bigint(20) unsigned) +master-bin.000001 227 Table_map 1 269 table_id: # (test.t1) +master-bin.000001 269 Write_rows 1 315 table_id: # flags: STMT_END_F +master-bin.000001 315 Query 1 391 use `test`; drop table t1 End of 5.0 tests reset master; create table t1 (id tinyint auto_increment primary key); diff --git a/mysql-test/suite/binlog/r/binlog_stm_binlog.result b/mysql-test/suite/binlog/r/binlog_stm_binlog.result index 80908e6b450..54a2ceda9b3 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result @@ -579,6 +579,21 @@ master-bin.000001 36593 Rotate 1 36637 master-bin.000002;pos=4 drop table t1; set global binlog_cache_size=@bcs; set session autocommit = @ac; +drop table if exists t1; +reset master; +create table t1 (a bigint unsigned, b bigint(20) unsigned); +prepare stmt from "insert into t1 values (?,?)"; +set @a= 9999999999999999; +set @b= 14632475938453979136; +execute stmt using @a, @b; +deallocate prepare stmt; +drop table t1; +show binlog events from 0; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 +master-bin.000001 106 Query 1 227 use `test`; create table t1 (a bigint unsigned, b bigint(20) unsigned) +master-bin.000001 227 Query 1 351 use `test`; insert into t1 values (9999999999999999,14632475938453979136) +master-bin.000001 351 Query 1 427 use `test`; drop table t1 End of 5.0 tests reset master; create table t1 (id tinyint auto_increment primary key); diff --git a/sql/item.cc b/sql/item.cc index 390e99fbde5..ab9243fcaf5 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2926,10 +2926,7 @@ const String *Item_param::query_val_str(String* str) const { switch (state) { case INT_VALUE: - if (unsigned_flag) - str->set((ulonglong) value.integer, &my_charset_bin); - else - str->set(value.integer, &my_charset_bin); + str->set_int(value.integer, unsigned_flag, &my_charset_bin); break; case REAL_VALUE: str->set_real(value.real, NOT_FIXED_DEC, &my_charset_bin); From ba068d64b414f5e3cb00af291a9a0894c8c70172 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Feb 2008 15:53:57 +0300 Subject: [PATCH 45/56] Silence the slow log errors (they won't make it to the client anyway). --- sql/log.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sql/log.cc b/sql/log.cc index 06f4e2d7b78..1a3c98da60b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -501,11 +501,13 @@ bool Log_to_csv_event_handler:: bool result= TRUE; bool need_close= FALSE; bool need_rnd_end= FALSE; + Silence_log_table_errors error_handler; Open_tables_state open_tables_backup; CHARSET_INFO *client_cs= thd->variables.character_set_client; bool save_time_zone_used; DBUG_ENTER("Log_to_csv_event_handler::log_slow"); + thd->push_internal_handler(& error_handler); /* CSV uses TIME_to_timestamp() internally if table needs to be repaired which will set thd->time_zone_used @@ -635,8 +637,11 @@ bool Log_to_csv_event_handler:: result= FALSE; err: + thd->pop_internal_handler(); + if (result) - sql_print_error("Failed to write to mysql.slow_log"); + sql_print_error("Failed to write to mysql.slow_log: %s", + error_handler.message()); if (need_rnd_end) { From d157f5fd43949d9927ec4683b5e66e32a945e13d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Feb 2008 17:25:20 +0300 Subject: [PATCH 46/56] Don't complain about a failure to write a log message if we were simply killed. sql/log.cc: Don't complain if were simply killed. --- sql/log.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 1a3c98da60b..24dd279cefd 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -441,7 +441,7 @@ bool Log_to_csv_event_handler:: result= FALSE; err: - if (result) + if (result && !thd->killed) sql_print_error("Failed to write to mysql.general_log: %s", error_handler.message()); @@ -639,7 +639,7 @@ bool Log_to_csv_event_handler:: err: thd->pop_internal_handler(); - if (result) + if (result && !thd->killed) sql_print_error("Failed to write to mysql.slow_log: %s", error_handler.message()); From 13e44e30eb4fa588687ae4cc07e675aad08fd2ca Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Feb 2008 19:33:24 +0300 Subject: [PATCH 47/56] Fix -ansi -pedantic compilation error --- sql/set_var.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/set_var.cc b/sql/set_var.cc index 410608f154f..4c77cbfff82 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1021,7 +1021,7 @@ bool sys_var_set::update(THD *thd, set_var *var) { *value= var->save_result.ulong_value; return 0; -}; +} uchar *sys_var_set::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base) From d84f322a978831f015d325ea2df8207ed7e8e6d2 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Feb 2008 20:06:05 +0300 Subject: [PATCH 48/56] Fix create.test: use latin1 instead ucs2. --- mysql-test/r/create.result | 8 ++++---- mysql-test/t/create.test | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 13192dca969..4bdcca81b74 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1759,7 +1759,7 @@ c3 INT NOT NULL COMMENT 'column3', c4 VARCHAR(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a', c5 VARCHAR(255) COLLATE utf8_unicode_ci NULL DEFAULT 'b', c6 VARCHAR(255)) -COLLATE ucs2_unicode_ci; +COLLATE latin1_bin; SHOW CREATE TABLE t1; Table Create Table @@ -1769,8 +1769,8 @@ t1 CREATE TABLE `t1` ( `c3` int(11) NOT NULL COMMENT 'column3', `c4` varchar(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a', `c5` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT 'b', - `c6` varchar(255) COLLATE ucs2_unicode_ci DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=ucs2 COLLATE=ucs2_unicode_ci + `c6` varchar(255) COLLATE latin1_bin DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_bin CREATE TABLE t2 AS SELECT * FROM t1; @@ -1782,7 +1782,7 @@ t2 CREATE TABLE `t2` ( `c3` int(11) NOT NULL COMMENT 'column3', `c4` varchar(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a', `c5` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT 'b', - `c6` varchar(255) CHARACTER SET ucs2 COLLATE ucs2_unicode_ci DEFAULT NULL + `c6` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 1fc61010b8b..09170cbc4f5 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -1363,7 +1363,7 @@ CREATE TABLE t1( c4 VARCHAR(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a', c5 VARCHAR(255) COLLATE utf8_unicode_ci NULL DEFAULT 'b', c6 VARCHAR(255)) - COLLATE ucs2_unicode_ci; + COLLATE latin1_bin; --echo From 1e2a9caf9416f798ed65d744504180301ceedc92 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Feb 2008 20:07:39 +0300 Subject: [PATCH 49/56] Bug#34424: query_cache_debug.test leads to valgrind warnings Disable the test case. mysql-test/t/disabled.def: Disable query_cache_debug.test. --- 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 3f9ec52ca36..2cbfb3cf658 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -23,3 +23,4 @@ wait_timeout : Bug#32801 wait_timeout.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 +query_cache_debug : Bug#34424: query_cache_debug.test leads to valgrind warnings From 5db7ee3ee94fcb4c698221fc5aac7bcefb54a7f6 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Feb 2008 18:17:00 +0100 Subject: [PATCH 50/56] BUG#33247: mysqlbinlog does not clean up after itself on abnormal termination Problem: mysqlbinlog does not free memory if an error happens. Fix: binlog-processing functions do not call exit() anymore. Instead, they print an error and return an error code. Error codes are propagated all the way back to main, and all allocated memory is freed on the way. client/mysqlbinlog.cc: - New error handling policy: functions processing binlogs don't just exit() anymore. Instead, they print a message and return an error status. - New policy for the global `mysql' and `glob_description_event': these are not passed as parameters anymore. The global pointer is used instead. - More error situations are detected and reported. - Better error messages: the program never terminates with exit status 1 without explanation any more. Fixed spelling errors. Use consistent format of messages (a single line beginning with "ERROR: " or "WARNING: " and ending with "." is printed to stderr.) - New memory handling: memory is always freed on program termination. - Better comments: more functions are explained, doxygen is used, and more precise formulations in some existing comments. mysql-test/suite/binlog/r/binlog_base64_flag.result: Result file updated since output format of mysqlbinlog changed while the test was disabled. mysql-test/suite/binlog/t/binlog_killed.test: Mysqlbinlog now works as described when the binlog is open. Hence, the --force-if-open flag must be passed mysql-test/suite/binlog/t/binlog_killed_simulate.test: Mysqlbinlog now works as described when the binlog is open. Hence, the --force-if-open flag must be passed mysql-test/suite/binlog/t/disabled.def: Now that mysqlbinlog cleans up after itself on abnormal termination, we can enable this test again. --- client/mysqlbinlog.cc | 1028 ++++++++++------- .../suite/binlog/r/binlog_base64_flag.result | 7 +- mysql-test/suite/binlog/t/binlog_killed.test | 6 +- .../binlog/t/binlog_killed_simulate.test | 4 +- mysql-test/suite/binlog/t/disabled.def | 1 - 5 files changed, 651 insertions(+), 395 deletions(-) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 790f757a27b..8de096e5ec1 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -59,7 +59,8 @@ static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace"; #endif static const char *load_default_groups[]= { "mysqlbinlog","client",0 }; -void sql_print_error(const char *format, ...); +static void error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); +static void warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0; static bool opt_hexdump= 0; @@ -92,24 +93,33 @@ static ulonglong rec_count= 0; static short binlog_flags = 0; static MYSQL* mysql = NULL; static const char* dirname_for_local_load= 0; -static bool stop_passed= 0; -static my_bool file_not_closed_error= 0; -/* - check_header() will set the pointer below. - Why do we need here a pointer on an event instead of an event ? - This is because the event will be created (alloced) in read_log_event() - (which returns a pointer) in check_header(). +/** + Pointer to the Format_description_log_event of the currently active binlog. + + This will be changed each time a new Format_description_log_event is + found in the binlog. It is finally destroyed at program termination. */ -static Format_description_log_event* glob_description_event; +static Format_description_log_event* glob_description_event= NULL; -static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, - const char* logname); -static int dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, - const char* logname); -static int dump_log_entries(const char* logname); -static void die(const char* fmt, ...) __attribute__ ((__noreturn__)); -static MYSQL* safe_connect(); +/** + Exit status for functions in this file. +*/ +enum Exit_status { + /** No error occurred and execution should continue. */ + OK_CONTINUE= 0, + /** An error occurred and execution should stop. */ + ERROR_STOP, + /** No error occurred but execution should stop. */ + OK_STOP +}; + +static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, + const char* logname); +static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, + const char* logname); +static Exit_status dump_log_entries(const char* logname); +static Exit_status safe_connect(); class Load_log_processor @@ -132,22 +142,29 @@ class Load_log_processor char *fname; Create_file_log_event *event; }; + /* + @todo Should be a map (e.g., a hash map), not an array. With the + present implementation, the number of elements in this array is + about the number of files loaded since the server started, which + may be big after a few years. We should be able to use existing + library data structures for this. /Sven + */ DYNAMIC_ARRAY file_names; - /* - Looking for new uniquie filename that doesn't exist yet by - adding postfix -%x + /** + Looks for a non-existing filename by adding a numerical suffix to + the given base name, creates the generated file, and returns the + filename by modifying the filename argument. - SYNOPSIS - create_unique_file() - - filename buffer for filename - file_name_end tail of buffer that should be changed - should point to a memory enough to printf("-%x",..) + @param[in,out] filename Base filename - RETURN VALUES - values less than 0 - can't find new filename - values great or equal 0 - created file with found filename + @param[in,out] file_name_end Pointer to last character of + filename. The numerical suffix will be written to this position. + Note that there must be a least five bytes of allocated memory + after file_name_end. + + @retval -1 Error (can't find new filename). + @retval >=0 Found file. */ File create_unique_file(char *filename, char *file_name_end) { @@ -201,22 +218,20 @@ public: delete_dynamic(&file_names); } - /* - Obtain Create_file event for LOAD DATA statement by its file_id. + /** + Obtain Create_file event for LOAD DATA statement by its file_id + and remove it from this Load_log_processor's list of events. - SYNOPSIS - grab_event() - file_id - file_id identifiying LOAD DATA statement + Checks whether we have already seen a Create_file_log_event with + the given file_id. If yes, returns a pointer to the event and + removes the event from array describing active temporary files. + From this moment, the caller is responsible for freeing the memory + occupied by the event. - DESCRIPTION - Checks whenever we have already seen Create_file event for this file_id. - If yes then returns pointer to it and removes it from array describing - active temporary files. Since this moment caller is responsible for - freeing memory occupied by this event and associated file name. + @param[in] file_id File id identifying LOAD DATA statement. - RETURN VALUES - Pointer to Create_file event or 0 if there was no such event - with this file_id. + @return Pointer to Create_file_log_event, or NULL if we have not + seen any Create_file_log_event with this file_id. */ Create_file_log_event *grab_event(uint file_id) { @@ -231,23 +246,20 @@ public: return res; } - /* - Obtain file name of temporary file for LOAD DATA statement by its file_id. + /** + Obtain file name of temporary file for LOAD DATA statement by its + file_id and remove it from this Load_log_processor's list of events. - SYNOPSIS - grab_fname() - file_id - file_id identifiying LOAD DATA statement + @param[in] file_id Identifier for the LOAD DATA statement. - DESCRIPTION - Checks whenever we have already seen Begin_load_query event for this - file_id. If yes then returns file name of corresponding temporary file. - Removes record about this file from the array of active temporary files. - Since this moment caller is responsible for freeing memory occupied by - this name. + Checks whether we have already seen Begin_load_query event for + this file_id. If yes, returns the file name of the corresponding + temporary file and removes the filename from the array of active + temporary files. From this moment, the caller is responsible for + freeing the memory occupied by this name. - RETURN VALUES - String with name of temporary file or 0 if we have not seen Begin_load_query - event with this file_id. + @return String with the name of the temporary file, or NULL if we + have not seen any Begin_load_query_event with this file_id. */ char *grab_fname(uint file_id) { @@ -264,19 +276,29 @@ public: } return res; } - int process(Create_file_log_event *ce); - int process(Begin_load_query_log_event *ce); - int process(Append_block_log_event *ae); + Exit_status process(Create_file_log_event *ce); + Exit_status process(Begin_load_query_log_event *ce); + Exit_status process(Append_block_log_event *ae); File prepare_new_file_for_old_format(Load_log_event *le, char *filename); - int load_old_format_file(NET* net, const char *server_fname, - uint server_fname_len, File file); - int process_first_event(const char *bname, uint blen, const uchar *block, - uint block_len, uint file_id, - Create_file_log_event *ce); + Exit_status load_old_format_file(NET* net, const char *server_fname, + uint server_fname_len, File file); + Exit_status process_first_event(const char *bname, uint blen, + const uchar *block, + uint block_len, uint file_id, + Create_file_log_event *ce); }; +/** + Creates and opens a new temporary file in the directory specified by previous call to init_by_dir_name() or init_by_cur_dir(). + @param[in] le The basename of the created file will start with the + basename of the file pointed to by this Load_log_event. + + @param[out] filename Buffer to save the filename in. + + @return File handle >= 0 on success, -1 on error. +*/ File Load_log_processor::prepare_new_file_for_old_format(Load_log_event *le, char *filename) { @@ -284,13 +306,13 @@ File Load_log_processor::prepare_new_file_for_old_format(Load_log_event *le, char *tail; File file; - fn_format(filename, le->fname, target_dir_name, "", 1); + fn_format(filename, le->fname, target_dir_name, "", MY_REPLACE_DIR); len= strlen(filename); tail= filename + len; if ((file= create_unique_file(filename,tail)) < 0) { - sql_print_error("Could not construct local filename %s",filename); + error("Could not construct local filename %s.",filename); return -1; } @@ -300,16 +322,33 @@ File Load_log_processor::prepare_new_file_for_old_format(Load_log_event *le, } -int Load_log_processor::load_old_format_file(NET* net, const char*server_fname, - uint server_fname_len, File file) +/** + Reads a file from a server and saves it locally. + + @param[in,out] net The server to read from. + + @param[in] server_fname The name of the file that the server should + read. + + @param[in] server_fname_len The length of server_fname. + + @param[in,out] file The file to write to. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. +*/ +Exit_status Load_log_processor::load_old_format_file(NET* net, + const char*server_fname, + uint server_fname_len, + File file) { uchar buf[FN_REFLEN+1]; buf[0] = 0; memcpy(buf + 1, server_fname, server_fname_len + 1); if (my_net_write(net, buf, server_fname_len +2) || net_flush(net)) { - sql_print_error("Failed requesting the remote dump of %s", server_fname); - return -1; + error("Failed requesting the remote dump of %s.", server_fname); + return ERROR_STOP; } for (;;) @@ -319,8 +358,8 @@ int Load_log_processor::load_old_format_file(NET* net, const char*server_fname, { if (my_net_write(net, (uchar*) "", 0) || net_flush(net)) { - sql_print_error("Failed sending the ack packet"); - return -1; + error("Failed sending the ack packet."); + return ERROR_STOP; } /* we just need to send something, as the server will read but @@ -331,63 +370,63 @@ int Load_log_processor::load_old_format_file(NET* net, const char*server_fname, } else if (packet_len == packet_error) { - sql_print_error("Failed reading a packet during the dump of %s ", - server_fname); - return -1; + error("Failed reading a packet during the dump of %s.", server_fname); + return ERROR_STOP; } if (packet_len > UINT_MAX) { - sql_print_error("Illegal length of packet read from net"); - return -1; + error("Illegal length of packet read from net."); + return ERROR_STOP; } if (my_write(file, (uchar*) net->read_pos, (uint) packet_len, MYF(MY_WME|MY_NABP))) - return -1; + return ERROR_STOP; } - return 0; + return OK_CONTINUE; } -/* - Process first event in the sequence of events representing LOAD DATA - statement. +/** + Process the first event in the sequence of events representing a + LOAD DATA statement. - SYNOPSIS - process_first_event() - bname - base name for temporary file to be created - blen - base name length - block - first block of data to be loaded - block_len - first block length - file_id - identifies LOAD DATA statement - ce - pointer to Create_file event object if we are processing - this type of event. + Creates a temporary file to be used in LOAD DATA and writes first + block of data to it. Registers its file name (and optional + Create_file event) in the array of active temporary files. - DESCRIPTION - Creates temporary file to be used in LOAD DATA and writes first block of - data to it. Registers its file name (and optional Create_file event) - in the array of active temporary files. + @param bname Base name for temporary file to be created. + @param blen Base name length. + @param block First block of data to be loaded. + @param block_len First block length. + @param file_id Identifies the LOAD DATA statement. + @param ce Pointer to Create_file event object if we are processing + this type of event. - RETURN VALUES - 0 - success - non-0 - error + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. */ - -int Load_log_processor::process_first_event(const char *bname, uint blen, - const uchar *block, uint block_len, - uint file_id, - Create_file_log_event *ce) +Exit_status Load_log_processor::process_first_event(const char *bname, + uint blen, + const uchar *block, + uint block_len, + uint file_id, + Create_file_log_event *ce) { uint full_len= target_dir_name_len + blen + 9 + 9 + 1; - int error= 0; + Exit_status retval= OK_CONTINUE; char *fname, *ptr; File file; File_name_record rec; DBUG_ENTER("Load_log_processor::process_first_event"); if (!(fname= (char*) my_malloc(full_len,MYF(MY_WME)))) - DBUG_RETURN(-1); + { + error("Out of memory."); + delete ce; + DBUG_RETURN(ERROR_STOP); + } memcpy(fname, target_dir_name, target_dir_name_len); ptr= fname + target_dir_name_len; @@ -397,9 +436,10 @@ int Load_log_processor::process_first_event(const char *bname, uint blen, if ((file= create_unique_file(fname,ptr)) < 0) { - sql_print_error("Could not construct local filename %s%s", - target_dir_name,bname); - DBUG_RETURN(-1); + error("Could not construct local filename %s%s.", + target_dir_name,bname); + delete ce; + DBUG_RETURN(ERROR_STOP); } rec.fname= fname; @@ -407,23 +447,39 @@ int Load_log_processor::process_first_event(const char *bname, uint blen, if (set_dynamic(&file_names, (uchar*)&rec, file_id)) { - sql_print_error("Could not construct local filename %s%s", - target_dir_name, bname); - DBUG_RETURN(-1); + error("Out of memory."); + delete ce; + DBUG_RETURN(ERROR_STOP); } if (ce) ce->set_fname_outside_temp_buf(fname, strlen(fname)); if (my_write(file, (uchar*)block, block_len, MYF(MY_WME|MY_NABP))) - error= -1; + { + error("Failed writing to file."); + retval= ERROR_STOP; + } if (my_close(file, MYF(MY_WME))) - error= -1; - DBUG_RETURN(error); + { + error("Failed closing file."); + retval= ERROR_STOP; + } + DBUG_RETURN(retval); } -int Load_log_processor::process(Create_file_log_event *ce) +/** + Process the given Create_file_log_event. + + @see Load_log_processor::process_first_event(const char*,uint,const char*,uint,uint,Create_file_log_event*) + + @param ce Create_file_log_event to process. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. +*/ +Exit_status Load_log_processor::process(Create_file_log_event *ce) { const char *bname= ce->fname + dirname_length(ce->fname); uint blen= ce->fname_len - (bname-ce->fname); @@ -433,14 +489,46 @@ int Load_log_processor::process(Create_file_log_event *ce) } -int Load_log_processor::process(Begin_load_query_log_event *blqe) +/** + Process the given Begin_load_query_log_event. + + @see Load_log_processor::process_first_event(const char*,uint,const char*,uint,uint,Create_file_log_event*) + + @param ce Begin_load_query_log_event to process. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. +*/ +Exit_status Load_log_processor::process(Begin_load_query_log_event *blqe) { return process_first_event("SQL_LOAD_MB", 11, blqe->block, blqe->block_len, blqe->file_id, 0); } -int Load_log_processor::process(Append_block_log_event *ae) +/** + Process the given Append_block_log_event. + + Appends the chunk of the file contents specified by the event to the + file created by a previous Begin_load_query_log_event or + Create_file_log_event. + + If the file_id for the event does not correspond to any file + previously registered through a Begin_load_query_log_event or + Create_file_log_event, this member function will print a warning and + return OK_CONTINUE. It is safe to return OK_CONTINUE, because no + query will be written for this event. We should not print an error + and fail, since the missing file_id could be because a (valid) + --start-position has been specified after the Begin/Create event but + before this Append event. + + @param ae Append_block_log_event to process. + + @retval ERROR_STOP An error occurred - the program should terminate. + + @retval OK_CONTINUE No error, the program should continue. +*/ +Exit_status Load_log_processor::process(Append_block_log_event *ae) { DBUG_ENTER("Load_log_processor::process"); const char* fname= ((ae->file_id < file_names.elements) ? @@ -450,15 +538,24 @@ int Load_log_processor::process(Append_block_log_event *ae) if (fname) { File file; - int error= 0; + Exit_status retval= OK_CONTINUE; if (((file= my_open(fname, O_APPEND|O_BINARY|O_WRONLY,MYF(MY_WME))) < 0)) - DBUG_RETURN(-1); + { + error("Failed opening file %s", fname); + DBUG_RETURN(ERROR_STOP); + } if (my_write(file,(uchar*)ae->block,ae->block_len,MYF(MY_WME|MY_NABP))) - error= -1; + { + error("Failed writing to file %s", fname); + retval= ERROR_STOP; + } if (my_close(file,MYF(MY_WME))) - error= -1; - DBUG_RETURN(error); + { + error("Failed closing file %s", fname); + retval= ERROR_STOP; + } + DBUG_RETURN(retval); } /* @@ -466,13 +563,13 @@ int Load_log_processor::process(Append_block_log_event *ae) --start-position). Assuming it's a big --start-position, we just do nothing and print a warning. */ - fprintf(stderr,"Warning: ignoring Append_block as there is no \ -Create_file event for file_id: %u\n",ae->file_id); - DBUG_RETURN(-1); + warning("Ignoring Append_block as there is no " + "Create_file event for file_id: %u", ae->file_id); + DBUG_RETURN(OK_CONTINUE); } -Load_log_processor load_processor; +static Load_log_processor load_processor; /** @@ -500,7 +597,16 @@ static void convert_path_to_forward_slashes(char *fname) } -static bool check_database(const char *log_dbname) +/** + Indicates whether the given database should be filtered out, + according to the --database=X option. + + @param log_dbname Name of database. + + @return nonzero if the database with the given name should be + filtered out, 0 otherwise. +*/ +static bool shall_skip_database(const char *log_dbname) { return one_database && (log_dbname != NULL) && @@ -508,8 +614,23 @@ static bool check_database(const char *log_dbname) } +/** + Prints the given event in base64 format. -static int + The header is printed to the head cache and the body is printed to + the body cache of the print_event_info structure. This allows all + base64 events corresponding to the same statement to be joined into + one BINLOG statement. + + @param[in] ev Log_event to print. + @param[in,out] result_file FILE to which the output will be written. + @param[in,out] print_event_info Parameters and context state + determining how to print. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. +*/ +static Exit_status write_event_header_and_base64(Log_event *ev, FILE *result_file, PRINT_EVENT_INFO *print_event_info) { @@ -522,35 +643,44 @@ write_event_header_and_base64(Log_event *ev, FILE *result_file, ev->print_base64(body, print_event_info, FALSE); /* Read data from cache and write to result file */ - DBUG_RETURN(copy_event_cache_to_file_and_reinit(head, result_file) || - copy_event_cache_to_file_and_reinit(body, result_file)); + if (copy_event_cache_to_file_and_reinit(head, result_file) || + copy_event_cache_to_file_and_reinit(body, result_file)) + { + error("Error writing event to file."); + DBUG_RETURN(ERROR_STOP); + } + DBUG_RETURN(OK_CONTINUE); } -/* - Process an event +/** + Print the given event, and either delete it or delegate the deletion + to someone else. - SYNOPSIS - process_event() + The deletion may be delegated in two cases: (1) the event is a + Format_description_log_event, and is saved in + glob_description_event; (2) the event is a Create_file_log_event, + and is saved in load_processor. - RETURN - 0 ok and continue - 1 error and terminate - -1 ok and terminate - - TODO - This function returns 0 even in some error cases. This should be changed. + @param[in,out] print_event_info Parameters and context state + determining how to print. + @param[in] ev Log_event to process. + @param[in] pos Offset from beginning of binlog file. + @param[in] logname Name of input binlog. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. + @retval OK_STOP No error, but the end of the specified range of + events to process has been reached and the program should terminate. */ - - - -int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, - my_off_t pos) +Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, + my_off_t pos, const char *logname) { char ll_buff[21]; Log_event_type ev_type= ev->get_type_code(); DBUG_ENTER("process_event"); print_event_info->short_form= short_form; + Exit_status retval= OK_CONTINUE; /* Format events are not concerned by --offset and such, we always need to @@ -570,14 +700,15 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, start_datetime= 0; offset= 0; // print everything and protect against cycling rec_count } - if (server_id && (server_id != ev->server_id)) { - DBUG_RETURN(0); - } + if (server_id && (server_id != ev->server_id)) + /* skip just this event, continue processing the log. */ + goto end; if (((my_time_t)(ev->when) >= stop_datetime) || (pos >= stop_position_mot)) { - stop_passed= 1; // skip all next binlogs - DBUG_RETURN(-1); + /* end the program */ + retval= OK_STOP; + goto end; } if (!short_form) fprintf(result_file, "# at %s\n",llstr(pos,ll_buff)); @@ -593,10 +724,15 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, switch (ev_type) { case QUERY_EVENT: - if (check_database(((Query_log_event*)ev)->db)) + if (shall_skip_database(((Query_log_event*)ev)->db)) goto end; if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) - write_event_header_and_base64(ev, result_file, print_event_info); + { + if ((retval= write_event_header_and_base64(ev, result_file, + print_event_info)) != + OK_CONTINUE) + goto end; + } else ev->print(result_file, print_event_info); break; @@ -610,7 +746,7 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, related Append_block and Exec_load. Note that Load event from 3.23 is not tested. */ - if (check_database(ce->db)) + if (shall_skip_database(ce->db)) goto end; // Next event /* We print the event, but with a leading '#': this is just to inform @@ -621,7 +757,10 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, */ if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) { - write_event_header_and_base64(ce, result_file, print_event_info); + if ((retval= write_event_header_and_base64(ce, result_file, + print_event_info)) != + OK_CONTINUE) + goto end; } else ce->print(result_file, print_event_info, TRUE); @@ -629,17 +768,29 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, // If this binlog is not 3.23 ; why this test?? if (glob_description_event->binlog_version >= 3) { - if (load_processor.process(ce)) - break; // Error - ev= 0; + /* + transfer the responsibility for destroying the event to + load_processor + */ + ev= NULL; + if ((retval= load_processor.process(ce)) != OK_CONTINUE) + goto end; } break; } + case APPEND_BLOCK_EVENT: + /* + Append_block_log_events can safely print themselves even if + the subsequent call load_processor.process fails, because the + output of Append_block_log_event::print is only a comment. + */ ev->print(result_file, print_event_info); - if (load_processor.process((Append_block_log_event*) ev)) - break; // Error + if ((retval= load_processor.process((Append_block_log_event*) ev)) != + OK_CONTINUE) + goto end; break; + case EXEC_LOAD_EVENT: { ev->print(result_file, print_event_info); @@ -662,8 +813,8 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, delete ce; } else - fprintf(stderr,"Warning: ignoring Exec_load as there is no \ -Create_file event for file_id: %u\n",exv->file_id); + warning("Ignoring Execute_load_log_event as there is no " + "Create_file event for file_id: %u", exv->file_id); break; } case FORMAT_DESCRIPTION_EVENT: @@ -683,35 +834,37 @@ Create_file event for file_id: %u\n",exv->file_id); if (!force_if_open_opt && (glob_description_event->flags & LOG_EVENT_BINLOG_IN_USE_F)) { - file_not_closed_error= 1; - DBUG_RETURN(1); + error("Attempting to dump binlog '%s', which was not closed properly. " + "Most probably, mysqld is still writing it, or it crashed. " + "Rerun with --force-if-open to ignore this problem.", logname); + DBUG_RETURN(ERROR_STOP); } break; case BEGIN_LOAD_QUERY_EVENT: ev->print(result_file, print_event_info); - load_processor.process((Begin_load_query_log_event*) ev); + if ((retval= load_processor.process((Begin_load_query_log_event*) ev)) != + OK_CONTINUE) + goto end; break; case EXECUTE_LOAD_QUERY_EVENT: { Execute_load_query_log_event *exlq= (Execute_load_query_log_event*)ev; char *fname= load_processor.grab_fname(exlq->file_id); - if (check_database(exlq->db)) + if (!shall_skip_database(exlq->db)) { if (fname) - my_free(fname, MYF(MY_WME)); - goto end; + { + convert_path_to_forward_slashes(fname); + exlq->print(result_file, print_event_info, fname); + } + else + warning("Ignoring Execute_load_query since there is no " + "Begin_load_query event for file_id: %u", exlq->file_id); } if (fname) - { - convert_path_to_forward_slashes(fname); - exlq->print(result_file, print_event_info, fname); my_free(fname, MYF(MY_WME)); - } - else - fprintf(stderr,"Warning: ignoring Execute_load_query as there is no \ -Begin_load_query event for file_id: %u\n", exlq->file_id); break; } case TABLE_MAP_EVENT: @@ -730,20 +883,18 @@ Begin_load_query event for file_id: %u\n", exlq->file_id); */ if (!print_event_info->printed_fd_event && !short_form) { - /* - todo: a lot to clean up here - */ const char* type_str= ev->get_type_str(); - delete ev; if (opt_base64_output_mode == BASE64_OUTPUT_NEVER) - die("--base64-output=never specified, but binlog contains a " - "%s event which must be printed in base64.", - type_str); + error("--base64-output=never specified, but binlog contains a " + "%s event which must be printed in base64.", + type_str); else - die("malformed binlog: it does not contain any " - "Format_description_log_event. I now found a %s event, which is " - "not safe to process without a Format_description_log_event.", - type_str); + error("malformed binlog: it does not contain any " + "Format_description_log_event. I now found a %s event, which " + "is not safe to process without a " + "Format_description_log_event.", + type_str); + goto err; } /* FALL THROUGH */ default: @@ -751,6 +902,10 @@ Begin_load_query event for file_id: %u\n", exlq->file_id); } } + goto end; + +err: + retval= ERROR_STOP; end: rec_count++; /* @@ -763,7 +918,7 @@ end: ev->temp_buf= 0; delete ev; } - DBUG_RETURN(0); + DBUG_RETURN(retval); } @@ -918,16 +1073,71 @@ that may lead to an endless loop.", }; -void sql_print_error(const char *format,...) +/** + Auxiliary function used by error() and warning(). + + Prints the given text (normally "WARNING: " or "ERROR: "), followed + by the given vprintf-style string, followed by a newline. + + @param format Printf-style format string. + @param args List of arguments for the format string. + @param msg Text to print before the string. +*/ +static void error_or_warning(const char *format, va_list args, const char *msg) +{ + fprintf(stderr, "%s: ", msg); + vfprintf(stderr, format, args); + fprintf(stderr, "\n"); +} + +/** + Prints a message to stderr, prefixed with the text "ERROR: " and + suffixed with a newline. + + @param format Printf-style format string, followed by printf + varargs. +*/ +static void error(const char *format,...) { va_list args; va_start(args, format); - fprintf(stderr, "ERROR: "); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); + error_or_warning(format, args, "ERROR"); va_end(args); } + +/** + This function is used in log_event.cc to report errors. + + @param format Printf-style format string, followed by printf + varargs. +*/ +static void sql_print_error(const char *format,...) +{ + va_list args; + va_start(args, format); + error_or_warning(format, args, "ERROR"); + va_end(args); +} + +/** + Prints a message to stderr, prefixed with the text "WARNING: " and + suffixed with a newline. + + @param format Printf-style format string, followed by printf + varargs. +*/ +static void warning(const char *format,...) +{ + va_list args; + va_start(args, format); + error_or_warning(format, args, "WARNING"); + va_end(args); +} + +/** + Frees memory for global variables in this file. +*/ static void cleanup() { my_free(pass,MYF(MY_ALLOW_ZERO_PTR)); @@ -935,20 +1145,10 @@ static void cleanup() my_free((char*) host, MYF(MY_ALLOW_ZERO_PTR)); my_free((char*) user, MYF(MY_ALLOW_ZERO_PTR)); my_free((char*) dirname_for_local_load, MYF(MY_ALLOW_ZERO_PTR)); -} -static void die(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - fprintf(stderr, "ERROR: "); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); - va_end(args); - cleanup(); - /* We cannot free DBUG, it is used in global destructors after exit(). */ - my_end(my_end_arg | MY_DONT_FREE_DBUG); - exit(1); + delete glob_description_event; + if (mysql) + mysql_close(mysql); } #include @@ -986,7 +1186,7 @@ static my_time_t convert_str_to_timestamp(const char* str) if (str_to_datetime(str, strlen(str), &l_time, 0, &was_cut) != MYSQL_TIMESTAMP_DATETIME || was_cut) { - fprintf(stderr, "Incorrect date and time argument: %s\n", str); + error("Incorrect date and time argument: %s", str); exit(1); } /* @@ -1087,34 +1287,56 @@ static int parse_args(int *argc, char*** argv) return 0; } -static MYSQL* safe_connect() -{ - MYSQL *local_mysql= mysql_init(NULL); - if (!local_mysql) - die("Failed on mysql_init"); +/** + Create and initialize the global mysql object, and connect to the + server. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. +*/ +static Exit_status safe_connect() +{ + mysql= mysql_init(NULL); + + if (!mysql) + { + error("Failed on mysql_init."); + return ERROR_STOP; + } if (opt_protocol) - mysql_options(local_mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol); - if (!mysql_real_connect(local_mysql, host, user, pass, 0, port, sock, 0)) + mysql_options(mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol); + if (!mysql_real_connect(mysql, host, user, pass, 0, port, sock, 0)) { - char errmsg[256]; - strmake(errmsg, mysql_error(local_mysql), sizeof(errmsg)-1); - mysql_close(local_mysql); - die("failed on connect: %s", errmsg); + error("Failed on connect: %s", mysql_error(mysql)); + return ERROR_STOP; } - local_mysql->reconnect= 1; - return local_mysql; + mysql->reconnect= 1; + return OK_CONTINUE; } -static int dump_log_entries(const char* logname) +/** + High-level function for dumping a named binlog. + + This function calls dump_remote_log_entries() or + dump_local_log_entries() to do the job. + + @param[in] logname Name of input binlog. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. + @retval OK_STOP No error, but the end of the specified range of + events to process has been reached and the program should terminate. +*/ +static Exit_status dump_log_entries(const char* logname) { - int rc; + Exit_status rc; PRINT_EVENT_INFO print_event_info; if (!print_event_info.init_ok()) - return 1; + return ERROR_STOP; /* Set safe delimiter, to dump things like CREATE PROCEDURE safely @@ -1132,51 +1354,50 @@ static int dump_log_entries(const char* logname) } -/* - This is not as smart as check_header() (used for local log); it will not work - for a binlog which mixes format. TODO: fix this. +/** + When reading a remote binlog, this function is used to grab the + Format_description_log_event in the beginning of the stream. + + This is not as smart as check_header() (used for local log); it will + not work for a binlog which mixes format. TODO: fix this. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. */ -static int check_master_version(MYSQL *mysql_arg, - Format_description_log_event - **description_event) +static Exit_status check_master_version() { MYSQL_RES* res = 0; MYSQL_ROW row; const char* version; - if (mysql_query(mysql_arg, "SELECT VERSION()") || - !(res = mysql_store_result(mysql_arg))) + if (mysql_query(mysql, "SELECT VERSION()") || + !(res = mysql_store_result(mysql))) { - /* purecov: begin inspected */ - char errmsg[256]; - strmake(errmsg, mysql_error(mysql_arg), sizeof(errmsg)-1); - mysql_close(mysql_arg); - die("Error checking master version: %s", errmsg); - /* purecov: end */ + error("Could not find server version: " + "Query failed when checking master version: %s", mysql_error(mysql)); + return ERROR_STOP; } if (!(row = mysql_fetch_row(res))) { - /* purecov: begin inspected */ - mysql_free_result(res); - mysql_close(mysql); - die("Master returned no rows for SELECT VERSION()"); - /* purecov: end */ - } - if (!(version = row[0])) - { - /* purecov: begin inspected */ - mysql_free_result(res); - mysql_close(mysql_arg); - die("Master reported NULL for the version"); - /* purecov: end */ + error("Could not find server version: " + "Master returned no rows for SELECT VERSION()."); + goto err; } + if (!(version = row[0])) + { + error("Could not find server version: " + "Master reported NULL for the version."); + goto err; + } + + delete glob_description_event; switch (*version) { case '3': - *description_event= new Format_description_log_event(1); + glob_description_event= new Format_description_log_event(1); break; case '4': - *description_event= new Format_description_log_event(3); + glob_description_event= new Format_description_log_event(3); break; case '5': /* @@ -1185,31 +1406,53 @@ static int check_master_version(MYSQL *mysql_arg, So we first assume that this is 4.0 (which is enough to read the Format_desc event if one comes). */ - *description_event= new Format_description_log_event(3); + glob_description_event= new Format_description_log_event(3); break; default: - /* purecov: begin inspected */ - mysql_free_result(res); - mysql_close(mysql_arg); - die("Master reported unrecognized MySQL version '%s'", version); - /* purecov: end */ + glob_description_event= NULL; + error("Could not find server version: " + "Master reported unrecognized MySQL version '%s'.", version); + goto err; } + if (!glob_description_event || !glob_description_event->is_valid()) + { + error("Failed creating Format_description_log_event; out of memory?"); + goto err; + } + mysql_free_result(res); - return 0; + return OK_CONTINUE; + +err: + mysql_free_result(res); + return ERROR_STOP; } -static int dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, - const char* logname) +/** + Requests binlog dump from a remote server and prints the events it + receives. + + @param[in,out] print_event_info Parameters and context state + determining how to print. + @param[in] logname Name of input binlog. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. + @retval OK_STOP No error, but the end of the specified range of + events to process has been reached and the program should terminate. +*/ +static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, + const char* logname) { uchar buf[128]; ulong len; uint logname_len; NET* net; - int error= 0; my_off_t old_off= start_position_mot; char fname[FN_REFLEN+1]; + Exit_status retval= OK_CONTINUE; DBUG_ENTER("dump_remote_log_entries"); /* @@ -1217,20 +1460,12 @@ static int dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, we cannot re-use the same connection as before, because it is now dead (COM_BINLOG_DUMP kills the thread when it finishes). */ - mysql= safe_connect(); + if ((retval= safe_connect()) != OK_CONTINUE) + DBUG_RETURN(retval); net= &mysql->net; - if (check_master_version(mysql, &glob_description_event)) - { - fprintf(stderr, "Could not find server version"); - DBUG_RETURN(1); - } - if (!glob_description_event || !glob_description_event->is_valid()) - { - fprintf(stderr, "Invalid Format_description log event; \ -could be out of memory"); - DBUG_RETURN(1); - } + if ((retval= check_master_version()) != OK_CONTINUE) + DBUG_RETURN(retval); /* COM_BINLOG_DUMP accepts only 4 bytes for the position, so we are forced to @@ -1242,18 +1477,16 @@ could be out of memory"); size_t tlen = strlen(logname); if (tlen > UINT_MAX) { - fprintf(stderr,"Log name too long\n"); - error= 1; - goto err; + error("Log name too long."); + DBUG_RETURN(ERROR_STOP); } logname_len = (uint) tlen; int4store(buf + 6, 0); memcpy(buf + 10, logname, logname_len); if (simple_command(mysql, COM_BINLOG_DUMP, buf, logname_len + 10, 1)) { - fprintf(stderr,"Got fatal error sending the log dump command\n"); - error= 1; - goto err; + error("Got fatal error sending the log dump command."); + DBUG_RETURN(ERROR_STOP); } for (;;) @@ -1264,10 +1497,8 @@ could be out of memory"); len= cli_safe_read(mysql); if (len == packet_error) { - fprintf(stderr, "Got error reading packet from server: %s\n", - mysql_error(mysql)); - error= 1; - goto err; + error("Got error reading packet from server: %s", mysql_error(mysql)); + DBUG_RETURN(ERROR_STOP); } if (len < 8 && net->read_pos[0] == 254) break; // end of data @@ -1277,9 +1508,8 @@ could be out of memory"); len - 1, &error_msg, glob_description_event))) { - fprintf(stderr, "Could not construct log event object\n"); - error= 1; - goto err; + error("Could not construct log event object: %s", error_msg); + DBUG_RETURN(ERROR_STOP); } /* If reading from a remote host, ensure the temp_buf for the @@ -1318,8 +1548,7 @@ could be out of memory"); if ((rev->ident_len != logname_len) || memcmp(rev->new_log_ident, logname, logname_len)) { - error= 0; - goto err; + DBUG_RETURN(OK_CONTINUE); } /* Otherwise, this is a fake Rotate for our log, at the very @@ -1344,11 +1573,9 @@ could be out of memory"); if (old_off != BIN_LOG_HEADER_SIZE) len= 1; // fake event, don't increment old_off } - if ((error= process_event(print_event_info, ev, old_off))) - { - error= ((error < 0) ? 0 : 1); - goto err; - } + Exit_status retval= process_event(print_event_info, ev, old_off, logname); + if (retval != OK_CONTINUE) + DBUG_RETURN(retval); } else { @@ -1356,26 +1583,21 @@ could be out of memory"); const char *old_fname= le->fname; uint old_len= le->fname_len; File file; + Exit_status retval; if ((file= load_processor.prepare_new_file_for_old_format(le,fname)) < 0) - { - error= 1; - goto err; - } + DBUG_RETURN(ERROR_STOP); - if ((error= process_event(print_event_info, ev, old_off))) + retval= process_event(print_event_info, ev, old_off, logname); + if (retval != OK_CONTINUE) { my_close(file,MYF(MY_WME)); - error= ((error < 0) ? 0 : 1); - goto err; + DBUG_RETURN(retval); } - error= load_processor.load_old_format_file(net,old_fname,old_len,file); + retval= load_processor.load_old_format_file(net,old_fname,old_len,file); my_close(file,MYF(MY_WME)); - if (error) - { - error= 1; - goto err; - } + if (retval != OK_CONTINUE) + DBUG_RETURN(retval); } /* Let's adjust offset for remote log as for local log to produce @@ -1384,15 +1606,13 @@ could be out of memory"); old_off+= len-1; } -err: - mysql_close(mysql); - DBUG_RETURN(error); + DBUG_RETURN(OK_CONTINUE); } /** - Reads the @c Format_description_log_event from the beginning of the - input file. + Reads the @c Format_description_log_event from the beginning of a + local input file. The @c Format_description_log_event is only read if it is outside the range specified with @c --start-position; otherwise, it will be @@ -1406,32 +1626,42 @@ err: @param file The file to which a @c Format_description_log_event will be printed. - @param description_event Pointer to the global @c - Format_description_log_event pointer. This will be updated if a new - Format_description_log_event is found. + @param[in,out] print_event_info Parameters and context state + determining how to print. - @param print_event_info Context state needed to print events. + @param[in] logname Name of input binlog. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. + @retval OK_STOP No error, but the end of the specified range of + events to process has been reached and the program should terminate. */ -static void check_header(IO_CACHE* file, - Format_description_log_event **description_event, - PRINT_EVENT_INFO *print_event_info) +static Exit_status check_header(IO_CACHE* file, + PRINT_EVENT_INFO *print_event_info, + const char* logname) { uchar header[BIN_LOG_HEADER_SIZE]; uchar buf[PROBE_HEADER_LEN]; my_off_t tmp_pos, pos; - *description_event= new Format_description_log_event(3); + delete glob_description_event; + if (!(glob_description_event= new Format_description_log_event(3))) + { + error("Failed creating Format_description_log_event; out of memory?"); + return ERROR_STOP; + } + pos= my_b_tell(file); my_b_seek(file, (my_off_t)0); if (my_b_read(file, header, sizeof(header))) { - delete *description_event; - die("Failed reading header; Probably an empty file"); + error("Failed reading header; probably an empty file."); + return ERROR_STOP; } if (memcmp(header, BINLOG_MAGIC, sizeof(header))) { - delete *description_event; - die("File is not a binary log file"); + error("File is not a binary log file."); + return ERROR_STOP; } /* @@ -1454,10 +1684,9 @@ static void check_header(IO_CACHE* file, { if (file->error) { - delete *description_event; - die("\ -Could not read entry at offset %lu : Error in log format or read error", - tmp_pos); + error("Could not read entry at offset %llu: " + "Error in log format or read error.", (ulonglong)tmp_pos); + return ERROR_STOP; } /* Otherwise this is just EOF : this log currently contains 0-2 @@ -1487,8 +1716,13 @@ Could not read entry at offset %lu : Error in log format or read error", (LOG_EVENT_MINIMAL_HEADER_LEN + START_V3_HEADER_LEN)) { /* This is 3.23 (format 1) */ - delete *description_event; - *description_event= new Format_description_log_event(1); + delete glob_description_event; + if (!(glob_description_event= new Format_description_log_event(1))) + { + error("Failed creating Format_description_log_event; " + "out of memory?"); + return ERROR_STOP; + } } break; } @@ -1500,26 +1734,32 @@ Could not read entry at offset %lu : Error in log format or read error", Format_description_log_event *new_description_event; my_b_seek(file, tmp_pos); /* seek back to event's start */ if (!(new_description_event= (Format_description_log_event*) - Log_event::read_log_event(file, *description_event))) + Log_event::read_log_event(file, glob_description_event))) /* EOF can't be hit here normally, so it's a real error */ { - delete *description_event; - die("Could not read a Format_description_log_event event \ -at offset %lu ; this could be a log format error or read error", - tmp_pos); + error("Could not read a Format_description_log_event event at " + "offset %llu; this could be a log format error or read error.", + (ulonglong)tmp_pos); + return ERROR_STOP; } if (opt_base64_output_mode == BASE64_OUTPUT_AUTO || opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) + { /* process_event will delete *description_event and set it to the new one, so we should not do it ourselves in this case. */ - process_event(print_event_info, new_description_event, tmp_pos); + Exit_status retval= process_event(print_event_info, + new_description_event, tmp_pos, + logname); + if (retval != OK_CONTINUE) + return retval; + } else { - delete *description_event; - *description_event= new_description_event; + delete glob_description_event; + glob_description_event= new_description_event; } DBUG_PRINT("info",("Setting description_event")); } @@ -1527,12 +1767,13 @@ at offset %lu ; this could be a log format error or read error", { Log_event *ev; my_b_seek(file, tmp_pos); /* seek back to event's start */ - if (!(ev= Log_event::read_log_event(file, *description_event))) - /* EOF can't be hit here normally, so it's a real error */ + if (!(ev= Log_event::read_log_event(file, glob_description_event))) { - delete *description_event; - die("Could not read a Rotate_log_event event at offset %lu ;" - " this could be a log format error or read error", tmp_pos); + /* EOF can't be hit here normally, so it's a real error */ + error("Could not read a Rotate_log_event event at offset %llu;" + " this could be a log format error or read error.", + (ulonglong)tmp_pos); + return ERROR_STOP; } delete ev; } @@ -1541,31 +1782,48 @@ at offset %lu ; this could be a log format error or read error", } } my_b_seek(file, pos); + return OK_CONTINUE; } -static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, - const char* logname) +/** + Reads a local binlog and prints the events it sees. + + @param[in] logname Name of input binlog. + + @param[in,out] print_event_info Parameters and context state + determining how to print. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. + @retval OK_STOP No error, but the end of the specified range of + events to process has been reached and the program should terminate. +*/ +static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, + const char* logname) { File fd = -1; IO_CACHE cache,*file= &cache; uchar tmp_buff[BIN_LOG_HEADER_SIZE]; - int error= 0; + Exit_status retval= OK_CONTINUE; if (logname && strcmp(logname, "-") != 0) { + /* read from normal file */ if ((fd = my_open(logname, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0) - return 1; + return ERROR_STOP; if (init_io_cache(file, fd, 0, READ_CACHE, start_position_mot, 0, MYF(MY_WME | MY_NABP))) { my_close(fd, MYF(MY_WME)); - return 1; + return ERROR_STOP; } - check_header(file, &glob_description_event, print_event_info); + if ((retval= check_header(file, print_event_info, logname)) != OK_CONTINUE) + goto end; } - else // reading from stdin; + else { + /* read from stdin */ /* Windows opens stdin in text mode by default. Certain characters such as CTRL-Z are interpeted as events and the read() method @@ -1577,14 +1835,18 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, #if defined (__WIN__) || (_WIN64) if (_setmode(fileno(stdin), O_BINARY) == -1) { - fprintf(stderr, "Could not set binary mode on stdin.\n"); - return 1; + error("Could not set binary mode on stdin."); + return ERROR_STOP; } #endif if (init_io_cache(file, fileno(stdin), 0, READ_CACHE, (my_off_t) 0, 0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE))) - return 1; - check_header(file, &glob_description_event, print_event_info); + { + error("Failed to init IO cache."); + return ERROR_STOP; + } + if ((retval= check_header(file, print_event_info, logname)) != OK_CONTINUE) + goto end; if (start_position) { /* skip 'start_position' characters from stdin */ @@ -1595,8 +1857,8 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, tmp=min(length,sizeof(buff)); if (my_b_read(file, buff, (uint) tmp)) { - error= 1; - goto end; + error("Failed reading from file."); + goto err; } } } @@ -1604,14 +1866,14 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, if (!glob_description_event || !glob_description_event->is_valid()) { - delete glob_description_event; - die("Invalid Format_description log event; could be out of memory"); + error("Invalid Format_description log event; could be out of memory."); + goto err; } if (!start_position && my_b_read(file, tmp_buff, BIN_LOG_HEADER_SIZE)) { - error= 1; - goto end; + error("Failed reading from file."); + goto err; } for (;;) { @@ -1629,36 +1891,36 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, file->error= 0; else if (file->error) { - fprintf(stderr, - "Could not read entry at offset %s:" - "Error in log format or read error\n", - llstr(old_off,llbuff)); - error= 1; + error("Could not read entry at offset %s: " + "Error in log format or read error.", + llstr(old_off,llbuff)); + goto err; } // file->error == 0 means EOF, that's OK, we break in this case - break; - } - if ((error= process_event(print_event_info, ev, old_off))) - { - if (error < 0) - error= 0; - break; + goto end; } + if ((retval= process_event(print_event_info, ev, old_off, logname)) != + OK_CONTINUE) + goto end; } + /* NOTREACHED */ + +err: + retval= ERROR_STOP; + end: if (fd >= 0) my_close(fd, MYF(MY_WME)); end_io_cache(file); - delete glob_description_event; - return error; + return retval; } int main(int argc, char** argv) { char **defaults_argv; - int exit_value= 0; + Exit_status retval= OK_CONTINUE; ulonglong save_stop_position; MY_INIT(argv[0]); DBUG_ENTER("main"); @@ -1720,15 +1982,13 @@ int main(int argc, char** argv) "\n/*!40101 SET NAMES %s */;\n", charset); for (save_stop_position= stop_position, stop_position= ~(my_off_t)0 ; - (--argc >= 0) && !stop_passed ; ) + (--argc >= 0) ; ) { if (argc == 0) // last log, --stop-position applies stop_position= save_stop_position; - if (dump_log_entries(*(argv++))) - { - exit_value=1; + if ((retval= dump_log_entries(*argv++)) != OK_CONTINUE) break; - } + // For next log, --start-position does not apply start_position= BIN_LOG_HEADER_SIZE; } @@ -1760,17 +2020,9 @@ int main(int argc, char** argv) /* We cannot free DBUG, it is used in global destructors after exit(). */ my_end(my_end_arg | MY_DONT_FREE_DBUG); - if (file_not_closed_error) - { - fprintf(stderr, -"\nError: attempting to dump binlog '%s' which was not closed properly.\n" -"Most probably mysqld is still writting it, or crashed.\n" -"Your current options specify --disable-force-if-open\n" -"which means to abort on this problem.\n" -"You can rerun using --force-if-open to ignore this problem.\n\n", argv[-1]); - } - exit(exit_value); - DBUG_RETURN(exit_value); // Keep compilers happy + exit(retval == ERROR_STOP ? 1 : 0); + /* Keep compilers happy. */ + DBUG_RETURN(retval == ERROR_STOP ? 1 : 0); } /* diff --git a/mysql-test/suite/binlog/r/binlog_base64_flag.result b/mysql-test/suite/binlog/r/binlog_base64_flag.result index aa801346d9f..8e5d7def823 100644 --- a/mysql-test/suite/binlog/r/binlog_base64_flag.result +++ b/mysql-test/suite/binlog/r/binlog_base64_flag.result @@ -40,8 +40,13 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -create table t1 (a int) engine= myisam/*!*/; +create table t1 (a int) engine= myisam +/*!*/; # at 203 +DELIMITER ; +# End of log file +ROLLBACK /* added by mysqlbinlog */; +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; ==== Test non-matching FD event and Row event ==== BINLOG ' 4CdYRw8BAAAAYgAAAGYAAAAAAAQANS4xLjE1LW5kYi02LjEuMjQtZGVidWctbG9nAAAAAAAAAAAA diff --git a/mysql-test/suite/binlog/t/binlog_killed.test b/mysql-test/suite/binlog/t/binlog_killed.test index e5f7288b17c..ab8a8cd59bd 100644 --- a/mysql-test/suite/binlog/t/binlog_killed.test +++ b/mysql-test/suite/binlog/t/binlog_killed.test @@ -39,7 +39,7 @@ connection con2; reap; let $rows= `select count(*) from t2 /* must be 2 or 0 */`; ---exec $MYSQL_BINLOG --start-position=134 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog +--exec $MYSQL_BINLOG --force-if-open --start-position=134 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval select (@a:=load_file("$MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog")) @@ -250,7 +250,7 @@ source include/show_binlog_events.inc; # a proof the query is binlogged with an error ---exec $MYSQL_BINLOG --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog +--exec $MYSQL_BINLOG --force-if-open --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval select (@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog")) @@ -296,7 +296,7 @@ source include/show_binlog_events.inc; # a proof the query is binlogged with an error ---exec $MYSQL_BINLOG --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog +--exec $MYSQL_BINLOG --force-if-open --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval select (@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog")) diff --git a/mysql-test/suite/binlog/t/binlog_killed_simulate.test b/mysql-test/suite/binlog/t/binlog_killed_simulate.test index 2121a90dc8c..cb3b5a6e827 100644 --- a/mysql-test/suite/binlog/t/binlog_killed_simulate.test +++ b/mysql-test/suite/binlog/t/binlog_killed_simulate.test @@ -23,7 +23,7 @@ update t1 set a=2 /* will be "killed" after work has been done */; #todo: introduce a suite private macro that provides numeric values # for some constants like the offset of the first real event # that is different between severs versions. ---exec $MYSQL_BINLOG --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog +--exec $MYSQL_BINLOG --force-if-open --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval select (@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog")) @@ -51,7 +51,7 @@ load data infile '../std_data_ln/rpl_loaddata.dat' into table t2 /* will be "kil source include/show_binlog_events.inc; ---exec $MYSQL_BINLOG --start-position=98 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog +--exec $MYSQL_BINLOG --force-if-open --start-position=98 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval select (@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog")) diff --git a/mysql-test/suite/binlog/t/disabled.def b/mysql-test/suite/binlog/t/disabled.def index c93bc2a158e..a6e73fa31d8 100644 --- a/mysql-test/suite/binlog/t/disabled.def +++ b/mysql-test/suite/binlog/t/disabled.def @@ -10,4 +10,3 @@ # ############################################################################## binlog_multi_engine : Bug#32663 binlog_multi_engine.test fails randomly -binlog_base64_flag : BUG#33247 2007-12-14 Sven: mysqlbinlog does not clean up after itself on termination. When compiled in debug mode, this test generates lots of warnings for memory leaks. From a7df0e2dc493c5000e7dc61200a64293866c5d55 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Feb 2008 19:37:57 -0700 Subject: [PATCH 51/56] Fixed buffer overflow --- sql/log.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/log.cc b/sql/log.cc index 042eddea5cf..9b5b2ae5a6c 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -94,7 +94,7 @@ Silence_log_table_errors::handle_error(uint /* sql_errno */, MYSQL_ERROR::enum_warning_level /* level */, THD * /* thd */) { - strmake(m_message, message_arg, sizeof(m_message)); + strmake(m_message, message_arg, sizeof(m_message)-1); return TRUE; } From 17af021c36e1ff63705a7cf6f5fe6cbafe1513e6 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 9 Feb 2008 10:31:22 +0300 Subject: [PATCH 52/56] Fix a buffer overflow with strmake(). --- sql/sql_class.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 75376c53f68..5180cafc774 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -406,7 +406,7 @@ Diagnostics_area::set_ok_status(THD *thd, ha_rows affected_rows_arg, m_affected_rows= affected_rows_arg; m_last_insert_id= last_insert_id_arg; if (message_arg) - strmake(m_message, message_arg, sizeof(m_message)); + strmake(m_message, message_arg, sizeof(m_message) - 1); else m_message[0]= '\0'; m_status= DA_OK; @@ -456,7 +456,7 @@ Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg, DBUG_ASSERT(! is_set() || can_overwrite_status); m_sql_errno= sql_errno_arg; - strmake(m_message, message_arg, sizeof(m_message)); + strmake(m_message, message_arg, sizeof(m_message) - 1); m_status= DA_ERROR; } From c2b6e653205d03554d8a7ed8e3e2668ca52c0817 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 9 Feb 2008 19:43:32 +0100 Subject: [PATCH 53/56] Problem: pushbuild fails in embedded mode on test binlog_base64_flag because it uses BINLOG statement, which is not supported in embedded mode. Fix: disable the test in embedded mode. mysql-test/suite/binlog/t/binlog_base64_flag.test: Must disable this test when running embedded, since BINLOG statements don't work. This fixes the pushbuild problem on the debx86-b machine on https://intranet.mysql.com/secure/pushbuild/showpush.pl?dir=mysql-5.1-new-rpl&order=469 --- mysql-test/suite/binlog/t/binlog_base64_flag.test | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mysql-test/suite/binlog/t/binlog_base64_flag.test b/mysql-test/suite/binlog/t/binlog_base64_flag.test index 8f4619e5248..01f98b8a134 100644 --- a/mysql-test/suite/binlog/t/binlog_base64_flag.test +++ b/mysql-test/suite/binlog/t/binlog_base64_flag.test @@ -6,6 +6,10 @@ # See also BUG#32407. +# BINLOG statement does not work in embedded mode. +source include/not_embedded.inc; + + # Test to show BUG#32407. This reads a binlog created with the # mysql-5.1-telco-6.1 tree, specifically at the tag # mysql-5.1.15-ndb-6.1.23, and applies it to the database. The test From 6f6fabb7f97db7e9b8a5efaa2cd337b34fdf9161 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Feb 2008 14:04:30 +0300 Subject: [PATCH 54/56] Patch to eliminate some valgrind warnings in debug printout code. (originally from Mats) sql/rpl_rli.cc: Adding variable to mark an instance of Relay_log_info as fake. sql/rpl_rli.h: Adding variable to mark an instance of Relay_log_info as fake. sql/slave.cc: Not printing debug information if we are working with a fake instance of Relay_log_info. This because the result of calling update is nonsense, and trying to print it generates valgrind warnings. sql/sql_binlog.cc: Marking newly created instance of Relay_log_info as a fake instance. --- sql/rpl_rli.cc | 5 ++++- sql/rpl_rli.h | 4 ++++ sql/slave.cc | 22 ++++++++++++++-------- sql/sql_binlog.cc | 3 +++ 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 3e9a484126a..03f790b934f 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -33,7 +33,10 @@ Relay_log_info::Relay_log_info() :Slave_reporting_capability("SQL"), no_storage(FALSE), replicate_same_server_id(::replicate_same_server_id), info_fd(-1), cur_log_fd(-1), save_temporary_tables(0), - group_relay_log_pos(0), + group_relay_log_pos(0), event_relay_log_pos(0), +#if HAVE_purify + is_fake(FALSE), +#endif cur_log_old_open_count(0), group_master_log_pos(0), log_space_total(0), ignore_log_space_limit(0), last_master_timestamp(0), slave_skip_counter(0), abort_pos_wait(0), slave_run_id(0), sql_thd(0), diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index a3a57ad4ce9..36daffae1af 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -154,6 +154,10 @@ public: ulonglong event_relay_log_pos; ulonglong future_event_relay_log_pos; +#ifdef HAVE_purify + bool is_fake; /* Mark that this is a fake relay log info structure */ +#endif + /* Original log name and position of the group we're currently executing (whose coordinates are group_relay_log_name/pos in the relay log) diff --git a/sql/slave.cc b/sql/slave.cc index 4ffc2023e85..c76e7c75a56 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1892,14 +1892,19 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli, if (exec_res == 0) { int error= ev->update_pos(rli); - char buf[22]; - DBUG_PRINT("info", ("update_pos error = %d", error)); - DBUG_PRINT("info", ("group %s %s", - llstr(rli->group_relay_log_pos, buf), - rli->group_relay_log_name)); - DBUG_PRINT("info", ("event %s %s", - llstr(rli->event_relay_log_pos, buf), - rli->event_relay_log_name)); +#ifdef HAVE_purify + if (!rli->is_fake) +#endif + { + char buf[22]; + DBUG_PRINT("info", ("update_pos error = %d", error)); + DBUG_PRINT("info", ("group %s %s", + llstr(rli->group_relay_log_pos, buf), + rli->group_relay_log_name)); + DBUG_PRINT("info", ("event %s %s", + llstr(rli->event_relay_log_pos, buf), + rli->event_relay_log_name)); + } /* The update should not fail, so print an error message and return an error code. @@ -1909,6 +1914,7 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli, */ if (error) { + char buf[22]; rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR, "It was not possible to update the positions" " of the relay log information: the slave may" diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc index 04f408453ea..f1fbe6eb4b7 100644 --- a/sql/sql_binlog.cc +++ b/sql/sql_binlog.cc @@ -56,6 +56,9 @@ void mysql_client_binlog_statement(THD* thd) if (!thd->rli_fake) { thd->rli_fake= new Relay_log_info; +#ifdef HAVE_purify + thd->rli_fake->is_fake= TRUE; +#endif have_fd_event= FALSE; } if (thd->rli_fake && !thd->rli_fake->relay_log.description_event_for_exec) From c9d0934a8f430d1c89d261be0f0f7cac18501b78 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Feb 2008 14:05:27 +0300 Subject: [PATCH 55/56] Disabling declaration of debug variable for non-debug builds. (originally from Mats) sql/slave.cc: Disabling declaration in non-debug builds. --- sql/slave.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/slave.cc b/sql/slave.cc index c76e7c75a56..9dd52c60dad 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1896,7 +1896,9 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli, if (!rli->is_fake) #endif { +#ifndef DBUG_OFF char buf[22]; +#endif DBUG_PRINT("info", ("update_pos error = %d", error)); DBUG_PRINT("info", ("group %s %s", llstr(rli->group_relay_log_pos, buf), From a0d88ebb0b5f77b30c65152f87aa73363ce93d71 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Feb 2008 14:34:53 +0300 Subject: [PATCH 56/56] Disable sporadically failing test cases (Bug#34454). mysql-test/suite/rpl_ndb/t/disabled.def: Disable sporadically failing test cases. --- mysql-test/suite/rpl_ndb/t/disabled.def | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mysql-test/suite/rpl_ndb/t/disabled.def b/mysql-test/suite/rpl_ndb/t/disabled.def index 0b0ce3df51b..b6bce159c6e 100644 --- a/mysql-test/suite/rpl_ndb/t/disabled.def +++ b/mysql-test/suite/rpl_ndb/t/disabled.def @@ -20,3 +20,8 @@ rpl_ndb_mix_innodb : Bug #32720 Test rpl_ndb_mix_innodb fails on SPARC a # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open #rpl_ndb_dd_advance : Bug#25913 rpl_ndb_dd_advance fails randomly + + +rpl_ndb_innodb_trans : Bug#34454: Some test cases from the 'rpl_ndb' suite fail +rpl_ndb_charset : Bug#34454: Some test cases from the 'rpl_ndb' suite fail +rpl_ndb_multi : Bug#34454: Some test cases from the 'rpl_ndb' suite fail