From 54dcbf2cbe97d8e5274c451bc960ed1b9ab54f54 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 16 Jun 2009 15:26:17 +0200 Subject: [PATCH 001/138] Bug #45298 plugin.test is skipped in PB2 on UNIX platforms Added search for example plugin in lib/mysql/plugin --- mysql-test/mysql-test-run.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 2a6a069d81c..4e89fd899ce 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1763,7 +1763,8 @@ sub environment_setup { if ($mysql_version_id >= 50100) { my $lib_example_plugin= mtr_file_exists(vs_config_dirs('storage/example', 'ha_example.dll'), - "$basedir/storage/example/.libs/ha_example.so",); + "$basedir/storage/example/.libs/ha_example.so", + "$basedir/lib/mysql/plugin/ha_example.so",); $ENV{'EXAMPLE_PLUGIN'}= ($lib_example_plugin ? basename($lib_example_plugin) : ""); $ENV{'EXAMPLE_PLUGIN_OPT'}= "--plugin-dir=". From a9b438b2229a340343055f36528f10f504efb19d Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 22 Jun 2009 16:27:05 +0200 Subject: [PATCH 002/138] Bug #43780 mysql-test-run uses deprecated server options Updated to use general_log[_file] and slow_query_log[_file] --- mysql-test/lib/My/ConfigFactory.pm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mysql-test/lib/My/ConfigFactory.pm b/mysql-test/lib/My/ConfigFactory.pm index 852f706c858..c1e8f7cd826 100644 --- a/mysql-test/lib/My/ConfigFactory.pm +++ b/mysql-test/lib/My/ConfigFactory.pm @@ -204,8 +204,10 @@ my @mysqld_rules= { 'port' => \&fix_port }, { 'socket' => \&fix_socket }, { '#log-error' => \&fix_log_error }, - { 'log' => \&fix_log }, - { 'log-slow-queries' => \&fix_log_slow_queries }, + { 'general_log' => 1 }, + { 'general_log_file' => \&fix_log }, + { 'slow_query_log' => 1 }, + { 'slow_query_log_file' => \&fix_log_slow_queries }, { '#user' => sub { return shift->{ARGS}->{user} || ""; } }, { '#password' => sub { return shift->{ARGS}->{password} || ""; } }, { 'server-id' => \&fix_server_id, }, From 47fa03abe75414040dc5ab96f6dc29f01ed7017b Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 22 Jun 2009 16:29:02 +0200 Subject: [PATCH 003/138] Bug #45532 MTR displays wrong option name 'print_testcases' in usage text Fix the name.... --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 4e89fd899ce..e6e8a77f3ed 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -5113,7 +5113,7 @@ Options to control what test suites or cases to run skip-rpl Skip the replication test cases. big-test Also run tests marked as "big" enable-disabled Run also tests marked as disabled - print_testcases Don't run the tests but print details about all the + print-testcases Don't run the tests but print details about all the selected tests, in the order they would be run. Options that specify ports From 6fed1e15c23dd882ddc8e522a0156269c9424635 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 15 Jul 2009 14:20:56 +0200 Subject: [PATCH 004/138] Bug #43005 main.init_connect fais on Windows in PB2 Server args containing spaces do not work on Windows Fixed my_safe_rprocess-win to re-apply "" around such args --- mysql-test/lib/My/SafeProcess/safe_process_win.cc | 9 ++++++++- mysql-test/suite/rpl/t/disabled.def | 1 - mysql-test/t/disabled.def | 1 - 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/mysql-test/lib/My/SafeProcess/safe_process_win.cc b/mysql-test/lib/My/SafeProcess/safe_process_win.cc index 80c1b7a97f2..d85a9558a62 100755 --- a/mysql-test/lib/My/SafeProcess/safe_process_win.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process_win.cc @@ -188,7 +188,14 @@ int main(int argc, const char** argv ) die("No real args -> nothing to do"); /* Copy the remaining args to child_arg */ for (int j= i+1; j < argc; j++) { - to+= _snprintf(to, child_args + sizeof(child_args) - to, "%s ", argv[j]); + if (strchr (argv[j], ' ')) { + /* Protect with "" if this arg contains a space */ + to+= _snprintf(to, child_args + sizeof(child_args) - to, + "\"%s\" ", argv[j]); + } else { + to+= _snprintf(to, child_args + sizeof(child_args) - to, + "%s ", argv[j]); + } } break; } else { diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index fcc3d56a9f5..38fc9e21322 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -11,4 +11,3 @@ ############################################################################## rpl_cross_version : Bug#42311 2009-03-27 joro rpl_cross_version fails on macosx -rpl_init_slave : Bug#44920 2009-05-18 pcrews MTR2 is not processing master.opt input properly on Windows diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index af4eb44b464..6d8f0af0c28 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -12,4 +12,3 @@ kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild. innodb_bug39438 : Bug#42383 2009-01-28 lsoares "This fails in embedded and on windows. Note that this test is not run on windows and on embedded in PB for main trees currently" query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically -init_connect : Bug#44920 2009-05-18 pcrews MTR2 is not processing master.opt input properly on Windows From 5a2d043f1d8e4c00f98ae33dd009d91ee6a0ec78 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 16 Jul 2009 14:05:46 +0200 Subject: [PATCH 005/138] Bug #45698 MTR_VERSION=1 ./mtr --force does not work General problem: some test cannot run in V1, expect more in future Implement general mechanism for listing incompatible tests --- mysql-test/lib/v1/incompatible.tests | 6 ++++++ mysql-test/lib/v1/mtr_cases.pl | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 mysql-test/lib/v1/incompatible.tests diff --git a/mysql-test/lib/v1/incompatible.tests b/mysql-test/lib/v1/incompatible.tests new file mode 100644 index 00000000000..fefdad9ce4c --- /dev/null +++ b/mysql-test/lib/v1/incompatible.tests @@ -0,0 +1,6 @@ +# This file lists tests that cannot run in MTR v1 for some reason. +# They will be skipped. +# Any text following white space after full test name is ignored +# Only exact test names can be used, no regexp. + +main.fulltext_plugin # Refers to $SIMPLE_PARSER_OPT which is not set diff --git a/mysql-test/lib/v1/mtr_cases.pl b/mysql-test/lib/v1/mtr_cases.pl index 4d7b1f4ec70..bed24bcabfb 100644 --- a/mysql-test/lib/v1/mtr_cases.pl +++ b/mysql-test/lib/v1/mtr_cases.pl @@ -32,6 +32,7 @@ sub mtr_options_from_test_file($$); my $do_test; my $skip_test; +my %incompatible; sub init_pattern { my ($from, $what)= @_; @@ -47,6 +48,15 @@ sub init_pattern { } +sub collect_incomp_tests { + open (INCOMP, "lib/v1/incompatible.tests"); + while () + { + next unless /^\w/; + s/\s.*\n//; # Ignore anything from first white space + $incompatible{$_}= 1; + } +} ############################################################################## # @@ -58,6 +68,8 @@ sub collect_test_cases ($) { $do_test= init_pattern($::opt_do_test, "--do-test"); $skip_test= init_pattern($::opt_skip_test, "--skip-test"); + collect_incomp_tests(); + my $suites= shift; # Semicolon separated list of test suites my $cases = []; # Array of hash @@ -528,6 +540,13 @@ sub collect_one_test_case($$$$$$$$$) { $tinfo->{'component_id'} = $component_id; push(@$cases, $tinfo); + if (exists ($incompatible{$tinfo->{'name'}})) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Test cannot run in mtr v1"; + return; + } + # ---------------------------------------------------------------------- # Skip some tests but include in list, just mark them to skip # ---------------------------------------------------------------------- From b9720c71700ad91b2320750ea72c787338d08810 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Fri, 17 Jul 2009 10:41:04 +0200 Subject: [PATCH 006/138] Bug #45700 MTR v1 --start-and-exit --default-storage-engine=Innodb is froken Change of variable states in Bug 19027 was not backported to v1 Changed ne "TRUE" to eq "OFF" --- mysql-test/lib/v1/mtr_cases.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/lib/v1/mtr_cases.pl b/mysql-test/lib/v1/mtr_cases.pl index bed24bcabfb..906e330282a 100644 --- a/mysql-test/lib/v1/mtr_cases.pl +++ b/mysql-test/lib/v1/mtr_cases.pl @@ -860,7 +860,7 @@ sub collect_one_test_case($$$$$$$$$) { if ( $tinfo->{'innodb_test'} ) { # This is a test that need innodb - if ( $::mysqld_variables{'innodb'} ne "TRUE" ) + if ( $::mysqld_variables{'innodb'} eq "OFF" ) { # innodb is not supported, skip it $tinfo->{'skip'}= 1; From a80bd0b5d7267d420aa876ed7d7edaed2c7e898d Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 23 Jul 2009 19:01:24 +0200 Subject: [PATCH 007/138] Bug #46212 safe_process: FATAL ERROR, Unknown option: --nocore Also fixed mysqld.cc to avoid popup-boxes --- .../lib/My/SafeProcess/safe_process_win.cc | 30 ++++++++++++------- sql/mysqld.cc | 19 ++++++------ 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/mysql-test/lib/My/SafeProcess/safe_process_win.cc b/mysql-test/lib/My/SafeProcess/safe_process_win.cc index d85a9558a62..455262b29f5 100755 --- a/mysql-test/lib/My/SafeProcess/safe_process_win.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process_win.cc @@ -163,6 +163,7 @@ int main(int argc, const char** argv ) HANDLE job_handle; HANDLE wait_handles[NUM_HANDLES]= {0}; PROCESS_INFORMATION process_info= {0}; + BOOL nocore= FALSE; sprintf(safe_process_name, "safe_process[%d]", pid); @@ -199,18 +200,22 @@ int main(int argc, const char** argv ) } break; } else { - if ( strcmp(arg, "--verbose") == 0 ) + if (strcmp(arg, "--verbose") == 0) verbose++; - else if ( strncmp(arg, "--parent-pid", 10) == 0 ) - { - /* Override parent_pid with a value provided by user */ - const char* start; + else if (strncmp(arg, "--parent-pid", 10) == 0) + { + /* Override parent_pid with a value provided by user */ + const char* start; if ((start= strstr(arg, "=")) == NULL) - die("Could not find start of option value in '%s'", arg); - start++; /* Step past = */ - if ((parent_pid= atoi(start)) == 0) - die("Invalid value '%s' passed to --parent-id", start); - } + die("Could not find start of option value in '%s'", arg); + start++; /* Step past = */ + if ((parent_pid= atoi(start)) == 0) + die("Invalid value '%s' passed to --parent-id", start); + } + else if (strcmp(arg, "--nocore") == 0) + { + nocore= TRUE; + } else die("Unknown option: %s", arg); } @@ -248,6 +253,11 @@ int main(int argc, const char** argv ) &jeli, sizeof(jeli)) == 0) message("SetInformationJobObject failed, continue anyway..."); + /* Avoid popup box */ + if (nocore) + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX + | SEM_NOOPENFILEERRORBOX); + #if 0 /* Setup stdin, stdout and stderr redirect */ si.dwFlags= STARTF_USESTDHANDLES; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 080f78993a1..fa8b4a971d7 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2103,15 +2103,14 @@ static void init_signals(void) win_install_sigabrt_handler(); if(opt_console) SetConsoleCtrlHandler(console_event_handler,TRUE); - else - { + /* Avoid MessageBox()es*/ - _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); - _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); - _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); + _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); /* Do not use SEM_NOGPFAULTERRORBOX in the following SetErrorMode (), @@ -2120,8 +2119,8 @@ static void init_signals(void) exception filter is not guaranteed to work in all situation (like heap corruption or stack overflow) */ - SetErrorMode(SetErrorMode(0)|SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); - } + SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS + | SEM_NOOPENFILEERRORBOX); SetUnhandledExceptionFilter(my_unhandler_exception_filter); } From 252c37a6399355a05310f183645373c851a26a56 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Fri, 31 Jul 2009 11:22:57 +0200 Subject: [PATCH 008/138] Bug #45698 MTR_VERSION=1 ./mtr --force does not work Small amendment to original fix, as it did not work in azalea Need to handle combinations, would eventually break in 5.1 too --- mysql-test/lib/v1/mtr_cases.pl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mysql-test/lib/v1/mtr_cases.pl b/mysql-test/lib/v1/mtr_cases.pl index 906e330282a..288e8c22b44 100644 --- a/mysql-test/lib/v1/mtr_cases.pl +++ b/mysql-test/lib/v1/mtr_cases.pl @@ -540,7 +540,11 @@ sub collect_one_test_case($$$$$$$$$) { $tinfo->{'component_id'} = $component_id; push(@$cases, $tinfo); - if (exists ($incompatible{$tinfo->{'name'}})) + # Remove "combinations" part of test name + my $test_base_name= $tinfo->{'name'}; + $test_base_name=~ s/\s.*\n//; + + if (exists ($incompatible{$test_base_name})) { $tinfo->{'skip'}= 1; $tinfo->{'comment'}= "Test cannot run in mtr v1"; From 47227d7f6a064a91034e2571135e76e2ce9b6dd8 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 5 Aug 2009 09:41:40 +0200 Subject: [PATCH 009/138] Bug #45771 AIX and i5/OS Perl bug: check_socket_path_length in MTR fails Bug is actually in Perl Fixed by trapping and ignoring error from IO::Socket::UNIX --- mysql-test/lib/My/Platform.pm | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/mysql-test/lib/My/Platform.pm b/mysql-test/lib/My/Platform.pm index 69ffdfbb4ce..7c7741a5c9e 100644 --- a/mysql-test/lib/My/Platform.pm +++ b/mysql-test/lib/My/Platform.pm @@ -126,13 +126,29 @@ sub check_socket_path_length { die "Could not create UNIX domain socket: $!" unless defined $sock; + my $hostpath = eval {$sock->hostpath()}; + if ($@) { + die unless $@ =~ /^Bad arg length for Socket::unpack_sockaddr_un/; + + # Bug on AIX and i5/OS Perl IO::Socket::UNIX which dies with something + # like: + # Bad arg length for Socket::unpack_sockaddr_un, length is 25, + # should be 106 at /path/to/perl/lib/5.8.0/aix/Socket.pm line 380. + # + # Just fake it that everything is fine + $hostpath = $testfile; + } + die "UNIX domain socket path was truncated" - unless ($testfile eq $sock->hostpath()); + unless ($testfile eq $hostpath); $truncated= 0; # Yes, it worked! }; + die "Unexpected failure when checking socket path length: $@" + if $@ and $@ !~ /^UNIX domain socket path was truncated/; + $sock= undef; # Close socket rmtree($tmpdir); # Remove the tempdir and any socket file created return $truncated; From 6ddeb379fe3b5dec58de5372666a640b1622659f Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 6 Aug 2009 09:30:53 +0200 Subject: [PATCH 010/138] Bug #45771 AIX and i5/OS Perl bug: check_socket_path_length in MTR fails Bug in Perl Scrap attempt to do this smartly on AIX, just drop the test and assume it's OK This commit undoes the previous push and adds a line to ignore on AIX --- mysql-test/lib/My/Platform.pm | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/mysql-test/lib/My/Platform.pm b/mysql-test/lib/My/Platform.pm index 7c7741a5c9e..371120ab644 100644 --- a/mysql-test/lib/My/Platform.pm +++ b/mysql-test/lib/My/Platform.pm @@ -106,10 +106,13 @@ sub check_socket_path_length { my ($path)= @_; return 0 if IS_WINDOWS; + # This may not be true, but we can't test for it on AIX due to Perl bug + # See Bug #45771 + return 0 if ($^O eq 'aix'); require IO::Socket::UNIX; - my $truncated= 1; # Be negative + my $truncated= undef; # Create a tempfile name with same length as "path" my $tmpdir = tempdir( CLEANUP => 0); @@ -122,32 +125,20 @@ sub check_socket_path_length { Local => $testfile, Listen => 1, ); + $truncated= 1; # Be negatvie die "Could not create UNIX domain socket: $!" unless defined $sock; - my $hostpath = eval {$sock->hostpath()}; - if ($@) { - die unless $@ =~ /^Bad arg length for Socket::unpack_sockaddr_un/; - - # Bug on AIX and i5/OS Perl IO::Socket::UNIX which dies with something - # like: - # Bad arg length for Socket::unpack_sockaddr_un, length is 25, - # should be 106 at /path/to/perl/lib/5.8.0/aix/Socket.pm line 380. - # - # Just fake it that everything is fine - $hostpath = $testfile; - } - die "UNIX domain socket path was truncated" - unless ($testfile eq $hostpath); + unless ($testfile eq $sock->hostpath()); $truncated= 0; # Yes, it worked! }; die "Unexpected failure when checking socket path length: $@" - if $@ and $@ !~ /^UNIX domain socket path was truncated/; + if $@ and not defined $truncated; $sock= undef; # Close socket rmtree($tmpdir); # Remove the tempdir and any socket file created From f42fab1b76e8435b5de753a35e047b369e07b60a Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Fri, 7 Aug 2009 15:08:32 +0200 Subject: [PATCH 011/138] Bug#32430: 'show innodb status' causes errors Invalid (old?) table or database name in logs Post push patch. Bug was that a non partitioned table file was not converted to system_charset, (due to table_name_len was not set). Also missing DBUG_RETURN. And Innodb adds quotes after calling the function, so I added one more mode where explain_filename does not add quotes. But it still appends the [sub]partition name as a comment. Also caught a minor quoting bug, the character '`' was not quoted in the identifier. (so 'a`b' was quoted as `a`b` and not `a``b`, this is mulitbyte characters aware.) sql/mysql_priv.h: Bug#32430: 'show innodb status' causes errors Invalid (old?) table or database name in logs Added an unquoted mode sql/share/errmsg.txt: Bug#32430: 'show innodb status' causes errors Invalid (old?) table or database name in logs Removed the quoting of identifier, only leaving the translated word. sql/sql_table.cc: Bug#32430: 'show innodb status' causes errors Invalid (old?) table or database name in logs Fixed quoting of '`' Added DBUG_RETURN. Corrected table_name_len. Added unquoted mode. --- sql/mysql_priv.h | 3 +- sql/share/errmsg.txt | 16 +++++----- sql/sql_table.cc | 76 +++++++++++++++++++++++++++++++++++--------- 3 files changed, 71 insertions(+), 24 deletions(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 03c366a45bf..609254448e3 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2261,7 +2261,8 @@ enum enum_explain_filename_mode { EXPLAIN_ALL_VERBOSE= 0, EXPLAIN_PARTITIONS_VERBOSE, - EXPLAIN_PARTITIONS_AS_COMMENT + EXPLAIN_PARTITIONS_AS_COMMENT, + EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING }; uint explain_filename(const char *from, char *to, uint to_length, enum_explain_filename_mode explain_mode); diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 5531ee71620..3aba434b284 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -6184,17 +6184,17 @@ ER_FUNC_INEXISTENT_NAME_COLLISION 42000 # When updating these, please update EXPLAIN_FILENAME_MAX_EXTRA_LENGTH in # mysql_priv.h with the new maximal additional length for explain_filename. ER_DATABASE_NAME - eng "Database `%s`" - swe "Databas `%s`" + eng "Database" + swe "Databas" ER_TABLE_NAME - eng "Table `%s`" - swe "Tabell `%s`" + eng "Table" + swe "Tabell" ER_PARTITION_NAME - eng "Partition `%s`" - swe "Partition `%s`" + eng "Partition" + swe "Partition" ER_SUBPARTITION_NAME - eng "Subpartition `%s`" - swe "Subpartition `%s`" + eng "Subpartition" + swe "Subpartition" ER_TEMPORARY_NAME eng "Temporary" swe "Temporär" diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0066c66eb59..7e4318b7d16 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -72,7 +72,7 @@ static void wait_for_kill_signal(THD *thd) @brief Helper function for explain_filename */ static char* add_identifier(char *to_p, const char * end_p, - const char* name, uint name_len, int errcode) + const char* name, uint name_len, bool add_quotes) { uint res; uint errors; @@ -92,18 +92,44 @@ static char* add_identifier(char *to_p, const char * end_p, res= strconvert(&my_charset_filename, conv_name, system_charset_info, conv_string, FN_REFLEN, &errors); if (!res || errors) + { + DBUG_PRINT("error", ("strconvert of '%s' failed with %u (errors: %u)", conv_name, res, errors)); conv_name= name; + } else { DBUG_PRINT("info", ("conv '%s' -> '%s'", conv_name, conv_string)); conv_name= conv_string; } - if (errcode) - to_p+= my_snprintf(to_p, end_p - to_p, ER(errcode), conv_name); + if (add_quotes && (end_p - to_p > 2)) + { + *(to_p++)= '`'; + while (*conv_name && (end_p - to_p - 1) > 0) + { + uint length= my_mbcharlen(system_charset_info, *conv_name); + if (!length) + length= 1; + if (length == 1 && *conv_name == '`') + { + if ((end_p - to_p) < 3) + break; + *(to_p++)= '`'; + *(to_p++)= *(conv_name++); + } + else if (length < (end_p - to_p)) + { + to_p= strnmov(to_p, conv_name, length); + conv_name+= length; + } + else + break; /* string already filled */ + } + to_p= strnmov(to_p, "`", end_p - to_p); + } else - to_p+= my_snprintf(to_p, end_p - to_p, "`%s`", conv_name); - return to_p; + to_p= strnmov(to_p, conv_name, end_p - to_p); + DBUG_RETURN(to_p); } @@ -135,6 +161,8 @@ static char* add_identifier(char *to_p, const char * end_p, [,[ Temporary| Renamed] Partition `p` [, Subpartition `sp`]] *| (| is really a /, and it is all in one line) + EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING -> + same as above but no quotes are added. @retval Length of returned string */ @@ -245,28 +273,39 @@ uint explain_filename(const char *from, part_name_len-= 5; } } + else + table_name_len= strlen(table_name); if (db_name) { if (explain_mode == EXPLAIN_ALL_VERBOSE) { - to_p= add_identifier(to_p, end_p, db_name, db_name_len, - ER_DATABASE_NAME); + to_p= strnmov(to_p, ER(ER_DATABASE_NAME), end_p - to_p); + *(to_p++)= ' '; + to_p= add_identifier(to_p, end_p, db_name, db_name_len, 1); to_p= strnmov(to_p, ", ", end_p - to_p); } else { - to_p= add_identifier(to_p, end_p, db_name, db_name_len, 0); + to_p= add_identifier(to_p, end_p, db_name, db_name_len, + (explain_mode != + EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING)); to_p= strnmov(to_p, ".", end_p - to_p); } } if (explain_mode == EXPLAIN_ALL_VERBOSE) - to_p= add_identifier(to_p, end_p, table_name, table_name_len, - ER_TABLE_NAME); + { + to_p= strnmov(to_p, ER(ER_TABLE_NAME), end_p - to_p); + *(to_p++)= ' '; + to_p= add_identifier(to_p, end_p, table_name, table_name_len, 1); + } else - to_p= add_identifier(to_p, end_p, table_name, table_name_len, 0); + to_p= add_identifier(to_p, end_p, table_name, table_name_len, + (explain_mode != + EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING)); if (part_name) { - if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT) + if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT || + explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING) to_p= strnmov(to_p, " /* ", end_p - to_p); else if (explain_mode == EXPLAIN_PARTITIONS_VERBOSE) to_p= strnmov(to_p, " ", end_p - to_p); @@ -280,15 +319,22 @@ uint explain_filename(const char *from, to_p= strnmov(to_p, ER(ER_RENAMED_NAME), end_p - to_p); to_p= strnmov(to_p, " ", end_p - to_p); } + to_p= strnmov(to_p, ER(ER_PARTITION_NAME), end_p - to_p); + *(to_p++)= ' '; to_p= add_identifier(to_p, end_p, part_name, part_name_len, - ER_PARTITION_NAME); + (explain_mode != + EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING)); if (subpart_name) { to_p= strnmov(to_p, ", ", end_p - to_p); + to_p= strnmov(to_p, ER(ER_SUBPARTITION_NAME), end_p - to_p); + *(to_p++)= ' '; to_p= add_identifier(to_p, end_p, subpart_name, subpart_name_len, - ER_SUBPARTITION_NAME); + (explain_mode != + EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING)); } - if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT) + if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT || + explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING) to_p= strnmov(to_p, " */", end_p - to_p); } DBUG_PRINT("exit", ("to '%s'", to)); From 013717d110af5d94eab703567ef72744c0d174e4 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 11 Aug 2009 12:59:43 +0200 Subject: [PATCH 012/138] Bug #44479 mysql-test-run does not detect that external server has Innodb support Variable name mismatch Map variable have_innodb=YES to innodb=ON --- mysql-test/mysql-test-run.pl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index e6e8a77f3ed..06f02afaf5b 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1506,6 +1506,10 @@ sub collect_mysqld_features_from_running_server () } } + # "Convert" innodb flag + $mysqld_variables{'innodb'}= "ON" + if ($mysqld_variables{'have_innodb'} eq "YES"); + # Parse version my $version_str= $mysqld_variables{'version'}; if ( $version_str =~ /^([0-9]*)\.([0-9]*)\.([0-9]*)/ ) From 1d99f9eae5f24b0c60872041ea960985386c4371 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 11 Aug 2009 15:59:05 +0200 Subject: [PATCH 013/138] Bug #45847 make --gdb disable all the timeouts by default Set to one week for testcase and suite timeout Also set one day timeout for PID file creation (not currently needed in 5.1 but might become, and is needed in azalea) --- mysql-test/mysql-test-run.pl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 06f02afaf5b..6a2e84d9c78 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1241,6 +1241,13 @@ sub command_line_setup { { mtr_error("Can't use --extern when using debugger"); } + # Set one week timeout (check-testcase timeout will be 1/10th) + $opt_testcase_timeout= 7 * 24 * 60; + $opt_suite_timeout= 7 * 24 * 60; + # One day to shutdown + $opt_shutdown_timeout= 24 * 60; + # One day for PID file creation (this is given in seconds not minutes) + $opt_start_timeout= 24 * 60 * 60; } # -------------------------------------------------------------------------- From b742c771afac36558d3355172f416381ea96f3da Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 11 Aug 2009 23:41:44 +0200 Subject: [PATCH 014/138] Bug #44012 mtr: test cases that are not supposed to return output always fail Output would match an empty result file but we don't check Allow empty output IFF there is an empty result file. --- client/mysqltest.cc | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index a39cabdc64d..a40ee1cd1d0 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -7987,6 +7987,8 @@ int main(int argc, char **argv) if (parsing_disabled) die("Test ended with parsing disabled"); + my_bool empty_result= FALSE; + /* The whole test has been executed _sucessfully_. Time to compare result or save it to record file. @@ -8027,11 +8029,20 @@ int main(int argc, char **argv) } else { - die("The test didn't produce any output"); + /* Empty output is an error *unless* we also have an empty result file */ + if (! result_file_name || record || + compare_files (log_file.file_name(), result_file_name)) + { + die("The test didn't produce any output"); + } + else + { + empty_result= TRUE; /* Meaning empty was expected */ + } } - if (!command_executed && result_file_name) - die("No queries executed but result file found!"); + if (!command_executed && result_file_name && !empty_result) + die("No queries executed but non-empty result file found!"); verbose_msg("Test has succeeded!"); timer_output(); From 00eec234ee79ae9859a98fe906e78cb3af4e89cc Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Wed, 12 Aug 2009 22:06:44 +0200 Subject: [PATCH 015/138] Apply build fix --- .bzrignore | 1 + storage/innodb_plugin/include/btr0cur.h | 2 +- storage/innodb_plugin/include/trx0types.h | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.bzrignore b/.bzrignore index fad758b54b8..6c6a43dacab 100644 --- a/.bzrignore +++ b/.bzrignore @@ -3063,3 +3063,4 @@ sql/share/slovak sql/share/spanish sql/share/swedish sql/share/ukrainian +libmysqld/examples/mysqltest.cc diff --git a/storage/innodb_plugin/include/btr0cur.h b/storage/innodb_plugin/include/btr0cur.h index b2d43ae3254..480a3877e54 100644 --- a/storage/innodb_plugin/include/btr0cur.h +++ b/storage/innodb_plugin/include/btr0cur.h @@ -618,7 +618,7 @@ enum btr_cur_method { hash_node, and might be necessary to update */ BTR_CUR_BINARY, /*!< success using the binary search */ - BTR_CUR_INSERT_TO_IBUF, /*!< performed the intended insert to + BTR_CUR_INSERT_TO_IBUF /*!< performed the intended insert to the insert buffer */ }; diff --git a/storage/innodb_plugin/include/trx0types.h b/storage/innodb_plugin/include/trx0types.h index 08cc9622d02..24cf57d53d5 100644 --- a/storage/innodb_plugin/include/trx0types.h +++ b/storage/innodb_plugin/include/trx0types.h @@ -70,7 +70,7 @@ typedef struct trx_named_savept_struct trx_named_savept_t; enum trx_rb_ctx { RB_NONE = 0, /*!< no rollback */ RB_NORMAL, /*!< normal rollback */ - RB_RECOVERY, /*!< rolling back an incomplete transaction, + RB_RECOVERY /*!< rolling back an incomplete transaction, in crash recovery */ }; From 2000cef72ab3fbb6afd2f6612ed561bc67da3a92 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 13 Aug 2009 15:29:19 +0200 Subject: [PATCH 016/138] Bug #44979 Enhance MTR --experimental to support platform qualifier Adding @ syntax --- mysql-test/collections/README.experimental | 7 +++++++ mysql-test/collections/default.experimental | 1 + mysql-test/mysql-test-run.pl | 12 ++++++++++++ 3 files changed, 20 insertions(+) diff --git a/mysql-test/collections/README.experimental b/mysql-test/collections/README.experimental index 9eee2394423..2f5ee7b00ab 100644 --- a/mysql-test/collections/README.experimental +++ b/mysql-test/collections/README.experimental @@ -23,3 +23,10 @@ The syntax is as follows: start with the same characters up to the last letter before the asterisk are considered experimental: main.a* # get rid of main.alias, main.alibaba and main.agliolio + +6) Optionally, the test case may be followed by one or more platform + qualifiers beginning with @ or @!. The test will then be considered + experimental only/except on that platform. Basic OS names as + reported by $^O in Perl, or 'windows' are supported, this includes + solaris, linux, windows, aix, darwin, ... Example: + main.alias @aix @windows # Fails on those diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 103069f79cf..161af45f133 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -1 +1,2 @@ funcs_1.charset_collation_1 # depends on compile-time decisions +main.plugin_load @solaris # Bug #42144 diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 6a2e84d9c78..40fc7446c9e 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -984,6 +984,9 @@ sub command_line_setup { if ( $opt_experimental ) { + # $^O on Windows considered not generic enough + my $plat= (IS_WINDOWS) ? 'windows' : $^O; + # read the list of experimental test cases from the file specified on # the command line open(FILE, "<", $opt_experimental) or mtr_error("Can't read experimental file: $opt_experimental"); @@ -994,6 +997,15 @@ sub command_line_setup { # remove comments (# foo) at the beginning of the line, or after a # blank at the end of the line s/( +|^)#.*$//; + # If @ platform specifier given, use this entry only if it contains + # @ or @! where xxx != platform + if (/\@.*/) + { + next if (/\@!$plat/); + next unless (/\@$plat/ or /\@!/); + # Then remove @ and everything after it + s/\@.*$//; + } # remove whitespace s/^ +//; s/ +$//; From a162954858bbffe7f3d11a780183b0ec2606e93a Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Fri, 14 Aug 2009 17:18:52 +0200 Subject: [PATCH 017/138] Build fixes for Windows, AIX, HP/UX and Sun Studio11, from Timothy Smith. --- CMakeLists.txt | 1 + cmd-line-utils/readline/util.c | 9 +++++++-- storage/innodb_plugin/handler/i_s.cc | 18 ++++++++++-------- storage/innodb_plugin/include/univ.i | 3 ++- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 947dc1786ff..7d91e39eb6d 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,6 +137,7 @@ ENDIF(MSVC) IF(WIN32) ADD_DEFINITIONS("-D_WINDOWS -D__WIN__ -D_CRT_SECURE_NO_DEPRECATE") + ADD_DEFINITIONS("-D_WIN32_WINNT=0x0501") ENDIF(WIN32) # default to x86 platform. We'll check for X64 in a bit diff --git a/cmd-line-utils/readline/util.c b/cmd-line-utils/readline/util.c index 50cfea75cb9..342224facd7 100644 --- a/cmd-line-utils/readline/util.c +++ b/cmd-line-utils/readline/util.c @@ -81,8 +81,13 @@ rl_alphabetic (c) #if defined (HANDLE_MULTIBYTE) int -_rl_walphabetic (wc) - wchar_t wc; +/* + Portability issue with VisualAge C++ Professional / C for AIX Compiler, Version 6: + "util.c", line 84.1: 1506-343 (S) Redeclaration of _rl_walphabetic differs + from previous declaration on line 110 of "rlmbutil.h". + So, put type in the function signature here. +*/ +_rl_walphabetic (wchar_t wc) { int c; diff --git a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler/i_s.cc index c0d488d1c49..524fe696de2 100644 --- a/storage/innodb_plugin/handler/i_s.cc +++ b/storage/innodb_plugin/handler/i_s.cc @@ -69,14 +69,16 @@ do { \ #define STRUCT_FLD(name, value) value #endif -static const ST_FIELD_INFO END_OF_ST_FIELD_INFO = - {STRUCT_FLD(field_name, NULL), - STRUCT_FLD(field_length, 0), - STRUCT_FLD(field_type, MYSQL_TYPE_NULL), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}; +/* Don't use a static const variable here, as some C++ compilers (notably +HPUX aCC: HP ANSI C++ B3910B A.03.65) can't handle it. */ +#define END_OF_ST_FIELD_INFO \ + {STRUCT_FLD(field_name, NULL), \ + STRUCT_FLD(field_length, 0), \ + STRUCT_FLD(field_type, MYSQL_TYPE_NULL), \ + STRUCT_FLD(value, 0), \ + STRUCT_FLD(field_flags, 0), \ + STRUCT_FLD(old_name, ""), \ + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)} /* Use the following types mapping: diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i index 6bce6dd765e..023a6c9cd89 100644 --- a/storage/innodb_plugin/include/univ.i +++ b/storage/innodb_plugin/include/univ.i @@ -408,7 +408,8 @@ it is read. */ /* Minimize cache-miss latency by moving data at addr into a cache before it is read or written. */ # define UNIV_PREFETCH_RW(addr) __builtin_prefetch(addr, 1, 3) -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +/* Sun Studio includes sun_prefetch.h as of version 5.9 */ +#elif (defined(__SUNPRO_C) && __SUNPRO_C >= 0x590) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590) # include #if __SUNPRO_C >= 0x550 # undef UNIV_INTERN From e5ae860e32e5536c5c19dc3196199fb0a896b9a8 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 17 Aug 2009 11:21:02 +0200 Subject: [PATCH 018/138] Bug #46755 Wrong grammar in some skip messages: Test need instead of Test needs Fixed in two comments as well --- mysql-test/lib/mtr_cases.pm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index 2a7b07debd0..94a4ab240b4 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -847,14 +847,14 @@ sub collect_one_test_case { if ( $tinfo->{'big_test'} and ! $::opt_big_test ) { $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "Test need 'big-test' option"; + $tinfo->{'comment'}= "Test needs 'big-test' option"; return $tinfo } if ( $tinfo->{'need_debug'} && ! $::debug_compiled_binaries ) { $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "Test need debug binaries"; + $tinfo->{'comment'}= "Test needs debug binaries"; return $tinfo } @@ -890,14 +890,14 @@ sub collect_one_test_case { if ($tinfo->{'federated_test'}) { - # This is a test that need federated, enable it + # This is a test that needs federated, enable it push(@{$tinfo->{'master_opt'}}, "--loose-federated"); push(@{$tinfo->{'slave_opt'}}, "--loose-federated"); } if ( $tinfo->{'innodb_test'} ) { - # This is a test that need innodb + # This is a test that needs innodb if ( $::mysqld_variables{'innodb'} eq "OFF" || ! exists $::mysqld_variables{'innodb'} ) { @@ -918,7 +918,7 @@ sub collect_one_test_case { if (grep(/^--skip-log-bin/, @::opt_extra_mysqld_opt) ) { $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "Test need binlog"; + $tinfo->{'comment'}= "Test needs binlog"; return $tinfo; } } From ca7bf9fad5f13122ae235a94f9299a6659b80686 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 18 Aug 2009 09:38:18 +0200 Subject: [PATCH 019/138] Bug #44222 mysql-test-run --start analyses which tests it would skip. This is redundant. Quicker test collection and better output with --start[-dirty] --- mysql-test/lib/mtr_cases.pm | 15 +++++++++++++-- mysql-test/mysql-test-run.pl | 22 +++++++++++++++++++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index 2a7b07debd0..5ce936352ce 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -41,6 +41,7 @@ our $opt_with_ndbcluster_only; our $defaults_file; our $defaults_extra_file; our $reorder= 1; +our $quick_collect; sub collect_option { my ($opt, $value)= @_; @@ -68,6 +69,9 @@ require "mtr_misc.pl"; my $do_test_reg; my $skip_test_reg; +# If "Quick collect", set to 1 once a test to run has been found. +my $some_test_found; + sub init_pattern { my ($from, $what)= @_; return undef unless defined $from; @@ -102,6 +106,7 @@ sub collect_test_cases ($$) { foreach my $suite (split(",", $suites)) { push(@$cases, collect_one_suite($suite, $opt_cases)); + last if $some_test_found; } if ( @$opt_cases ) @@ -139,7 +144,7 @@ sub collect_test_cases ($$) { } } - if ( $reorder ) + if ( $reorder && !$quick_collect) { # Reorder the test cases in an order that will make them faster to run my %sort_criteria; @@ -386,7 +391,7 @@ sub collect_one_suite($) # Read combinations for this suite and build testcases x combinations # if any combinations exists # ---------------------------------------------------------------------- - if ( ! $skip_combinations ) + if ( ! $skip_combinations && ! $quick_collect ) { my @combinations; my $combination_file= "$suitedir/combinations"; @@ -583,6 +588,12 @@ sub optimize_cases { if ( $default_engine =~ /^innodb/i ); } } + + if ($quick_collect && ! $tinfo->{'skip'}) + { + $some_test_found= 1; + return; + } } } diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 40fc7446c9e..28ddd718f16 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -209,6 +209,7 @@ sub check_timeout { return $opt_testcase_timeout * 6; }; my $opt_start; my $opt_start_dirty; +my $start_only; my $opt_wait_all; my $opt_repeat= 1; my $opt_retry= 3; @@ -1262,11 +1263,19 @@ sub command_line_setup { $opt_start_timeout= 24 * 60 * 60; } + # -------------------------------------------------------------------------- + # Modified behavior with --start options + # -------------------------------------------------------------------------- + if ($opt_start or $opt_start_dirty) { + collect_option ('quick-collect', 1); + $start_only= 1; + } + # -------------------------------------------------------------------------- # Check use of wait-all # -------------------------------------------------------------------------- - if ($opt_wait_all && ! ($opt_start_dirty || $opt_start)) + if ($opt_wait_all && ! $start_only) { mtr_error("--wait-all can only be used with --start or --start-dirty"); } @@ -2824,7 +2833,7 @@ sub run_testcase_check_skip_test($) if ( $tinfo->{'skip'} ) { - mtr_report_test_skipped($tinfo); + mtr_report_test_skipped($tinfo) unless $start_only; return 1; } @@ -3311,9 +3320,16 @@ sub run_testcase ($) { # server exits # ---------------------------------------------------------------------- - if ( $opt_start or $opt_start_dirty ) + if ( $start_only ) { mtr_print("\nStarted", started(all_servers())); + mtr_print("Using config for test", $tinfo->{name}); + mtr_print("Port and socket path for server(s):"); + foreach my $mysqld ( mysqlds() ) + { + mtr_print ($mysqld->name() . " " . $mysqld->value('port') . + " " . $mysqld->value('socket')); + } mtr_print("Waiting for server(s) to exit..."); if ( $opt_wait_all ) { My::SafeProcess->wait_all(); From b9d1c04b79ac63d9116acab774c01abfa2e64934 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 18 Aug 2009 15:26:17 +0200 Subject: [PATCH 020/138] Bug #46164 memory leak in mysqltest after parse error with --debug Moved some dynstr_free() further up --- client/mysqltest.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index a40ee1cd1d0..fb4b9c6ec13 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -7161,6 +7161,10 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) run_query_normal(cn, command, flags, query, query_len, ds, &ds_warnings); + dynstr_free(&ds_warnings); + if (command->type == Q_EVAL) + dynstr_free(&eval_query); + if (display_result_sorted) { /* Sort the result set and append it to result */ @@ -7191,11 +7195,8 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) check_require(ds, command->require_file); } - dynstr_free(&ds_warnings); if (ds == &ds_result) dynstr_free(&ds_result); - if (command->type == Q_EVAL) - dynstr_free(&eval_query); DBUG_VOID_RETURN; } From f0e14f7181be4e68856060280d03f5e32d30ac4d Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 18 Aug 2009 16:23:15 +0200 Subject: [PATCH 021/138] Install innodb_plugin on Windows. --- scripts/make_win_bin_dist | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist index 3360d8459f8..ce89ea28303 100755 --- a/scripts/make_win_bin_dist +++ b/scripts/make_win_bin_dist @@ -279,6 +279,7 @@ cp include/mysql/plugin.h $DESTDIR/include/mysql/ # ---------------------------------------------------------------------- mkdir -p $DESTDIR/lib/opt +mkdir -p $DESTDIR/lib/plugin cp libmysql/$TARGET/libmysql.dll \ libmysql/$TARGET/libmysql.lib \ libmysql/$TARGET/mysqlclient.lib \ @@ -286,6 +287,8 @@ cp libmysql/$TARGET/libmysql.dll \ regex/$TARGET/regex.lib \ strings/$TARGET/strings.lib \ zlib/$TARGET/zlib.lib $DESTDIR/lib/opt/ +cp storage/innodb_plugin/$TARGET/ha_innodb_plugin.dll \ + $DESTDIR/lib/plugin/ if [ x"$TARGET" != x"release" ] ; then cp libmysql/$TARGET/libmysql.pdb \ @@ -294,11 +297,15 @@ if [ x"$TARGET" != x"release" ] ; then regex/$TARGET/regex.pdb \ strings/$TARGET/strings.pdb \ zlib/$TARGET/zlib.pdb $DESTDIR/lib/opt/ + cp storage/innodb_plugin/$TARGET/ha_innodb_plugin.pdb \ + $DESTDIR/lib/plugin/ fi + if [ x"$PACK_DEBUG" = x"" -a -f "libmysql/debug/libmysql.lib" -o \ x"$PACK_DEBUG" = x"yes" ] ; then mkdir -p $DESTDIR/lib/debug + mkdir -p $DESTDIR/lib/plugin/debug cp libmysql/debug/libmysql.dll \ libmysql/debug/libmysql.lib \ libmysql/debug/libmysql.pdb \ @@ -312,6 +319,10 @@ if [ x"$PACK_DEBUG" = x"" -a -f "libmysql/debug/libmysql.lib" -o \ strings/debug/strings.pdb \ zlib/debug/zlib.lib \ zlib/debug/zlib.pdb $DESTDIR/lib/debug/ + cp storage/innodb_plugin/debug/ha_innodb_plugin.dll \ + storage/innodb_plugin/debug/ha_innodb_plugin.lib \ + storage/innodb_plugin/debug/ha_innodb_plugin.pdb \ + $DESTDIR/lib/plugin/debug/ fi # ---------------------------------------------------------------------- From d19eda4a9b59de353c9047376fd513bc0f5d69da Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 19 Aug 2009 13:48:56 +0200 Subject: [PATCH 022/138] Bug #39003 mtr's diff_files command failed in pushbuild without printing a result diff diff was actually called but result never outputted before exiting Added extra code to dump output *unless* failure was expected --- client/mysqltest.cc | 9 +++++++-- mysql-test/t/mysqltest.test | 12 ------------ 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index a40ee1cd1d0..09b31599268 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -3440,12 +3440,17 @@ void do_diff_files(struct st_command *command) die("command \"diff_files\" failed, file '%s' does not exist", ds_filename2.str); - if ((error= compare_files(ds_filename.str, ds_filename2.str))) + if ((error= compare_files(ds_filename.str, ds_filename2.str)) && + match_expected_error(command, error, NULL) < 0) { /* Compare of the two files failed, append them to output - so the failure can be analyzed + so the failure can be analyzed, but only if it was not + expected to fail. */ show_diff(&ds_res, ds_filename.str, ds_filename2.str); + log_file.write(&ds_res); + log_file.flush(); + dynstr_set(&ds_res, 0); } dynstr_free(&ds_filename); diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 578b2bf5c6c..92f39d943b9 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1710,10 +1710,6 @@ EOF --diff_files $MYSQLTEST_VARDIR/tmp/diff1.tmp $MYSQLTEST_VARDIR/tmp/diff2.tmp --diff_files $MYSQLTEST_VARDIR/tmp/diff2.tmp $MYSQLTEST_VARDIR/tmp/diff1.tmp -# Write the below commands to a intermediary file and execute them with -# mysqltest in --exec, since the output will vary depending on what "diff" -# is available it is sent to /dev/null ---write_file $MYSQLTEST_VARDIR/tmp/diff.test # Compare files that differ in size --error 2 --diff_files $MYSQLTEST_VARDIR/tmp/diff1.tmp $MYSQLTEST_VARDIR/tmp/diff3.tmp @@ -1725,13 +1721,6 @@ EOF --diff_files $MYSQLTEST_VARDIR/tmp/diff1.tmp $MYSQLTEST_VARDIR/tmp/diff4.tmp --error 1 --diff_files $MYSQLTEST_VARDIR/tmp/diff4.tmp $MYSQLTEST_VARDIR/tmp/diff1.tmp -exit; -EOF - -# Execute the above diffs, and send their output to /dev/null - only -# interesting to see that it returns correct error codes ---exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/diff.test > /dev/null 2>&1 - # Compare equal files, again... --diff_files $MYSQLTEST_VARDIR/tmp/diff1.tmp $MYSQLTEST_VARDIR/tmp/diff2.tmp @@ -1740,7 +1729,6 @@ EOF --remove_file $MYSQLTEST_VARDIR/tmp/diff2.tmp --remove_file $MYSQLTEST_VARDIR/tmp/diff3.tmp --remove_file $MYSQLTEST_VARDIR/tmp/diff4.tmp ---remove_file $MYSQLTEST_VARDIR/tmp/diff.test # ---------------------------------------------------------------------------- From 152943f39f487795f3d1d6910d1ee9f736feae44 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 19 Aug 2009 17:53:43 +0300 Subject: [PATCH 023/138] Bug #46807: subselect test fails on PB-2 with a crash The check for stack overflow was independent of the size of the structure stored in the heap. Fixed by adding sizeof(PARAM) to the requested free heap size. --- sql/opt_range.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 32f9b0df4c0..d007009d62c 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2063,7 +2063,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, KEY *key_info; PARAM param; - if (check_stack_overrun(thd, 2*STACK_MIN_SIZE, buff)) + if (check_stack_overrun(thd, 2*STACK_MIN_SIZE + sizeof(PARAM), buff)) DBUG_RETURN(0); // Fatal error flag is set /* set up parameter that is passed to all functions */ From 58903aecd310c6470a666fd8bed63a30bece55f0 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Fri, 21 Aug 2009 13:52:30 +0200 Subject: [PATCH 024/138] Add plugins to RPMs. Disable example plugins. --- support-files/mysql.spec.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 778b04b30fe..081489f7053 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -301,6 +301,8 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \ --with-csv-storage-engine \ --with-blackhole-storage-engine \ --with-federated-storage-engine \ + --without-plugin-daemon_example \ + --without-plugin-example \ --with-partition \ --with-big-tables \ --enable-shared \ @@ -693,6 +695,8 @@ fi %attr(755, root, root) %{_bindir}/resolve_stack_dump %attr(755, root, root) %{_bindir}/resolveip +%attr(755, root, root) %{_libdir}/plugin/*.so* + %attr(755, root, root) %{_sbindir}/mysqld %attr(755, root, root) %{_sbindir}/mysqld-debug %attr(755, root, root) %{_sbindir}/mysqlmanager @@ -818,6 +822,8 @@ fi %{_libdir}/mysql/libvio.a %{_libdir}/mysql/libz.a %{_libdir}/mysql/libz.la +%{_libdir}/plugin/*.a +%{_libdir}/plugin/*.la %files shared %defattr(-, root, root, 0755) @@ -847,6 +853,11 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Fri Aug 21 2009 Jonathan Perkin + +- Install plugin libraries in appropriate packages. +- Disable example plugins. + * Fri Nov 07 2008 Joerg Bruehe - Correct yesterday's fix, so that it also works for the last flag, From 769d9f3803ada97d0032944aa1447520957aa73b Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Fri, 21 Aug 2009 13:58:33 +0200 Subject: [PATCH 025/138] Apply patch from bug#46834 to install the test suite in RPMs. --- mysql-test/Makefile.am | 3 ++- mysql-test/lib/My/SafeProcess/Makefile.am | 3 ++- storage/ndb/test/run-test/Makefile.am | 3 ++- support-files/mysql.spec.sh | 6 +++++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 810bead1adc..b1d0e85c70e 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -17,7 +17,8 @@ ## Process this file with automake to create Makefile.in -testdir = $(prefix)/mysql-test +testroot = $(prefix) +testdir = $(testroot)/mysql-test test_SCRIPTS = mtr \ mysql-test-run \ diff --git a/mysql-test/lib/My/SafeProcess/Makefile.am b/mysql-test/lib/My/SafeProcess/Makefile.am index 623c0e9a87a..722331453fe 100644 --- a/mysql-test/lib/My/SafeProcess/Makefile.am +++ b/mysql-test/lib/My/SafeProcess/Makefile.am @@ -13,7 +13,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -safedir = $(prefix)/mysql-test/lib/My/SafeProcess +testroot = $(prefix) +safedir = $(testroot)/mysql-test/lib/My/SafeProcess #nobase_bin_PROGRAMS = ... safe_PROGRAMS = my_safe_process diff --git a/storage/ndb/test/run-test/Makefile.am b/storage/ndb/test/run-test/Makefile.am index 65aa62d11f0..54ca0c009b2 100644 --- a/storage/ndb/test/run-test/Makefile.am +++ b/storage/ndb/test/run-test/Makefile.am @@ -13,7 +13,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -testdir=$(prefix)/mysql-test/ndb +testroot=$(prefix) +testdir=$(testroot)/mysql-test/ndb include $(top_srcdir)/storage/ndb/config/common.mk.am include $(top_srcdir)/storage/ndb/config/type_util.mk.am diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 081489f7053..8a181375cfb 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -428,7 +428,7 @@ install -d $RBR%{_sbindir} # Install all binaries -(cd $MBD && make install DESTDIR=$RBR benchdir_root=%{_datadir}) +(cd $MBD && make install DESTDIR=$RBR testroot=%{_datadir}) # Old packages put shared libs in %{_libdir}/ (not %{_libdir}/mysql), so do # the same here. mv $RBR/%{_libdir}/mysql/*.so* $RBR/%{_libdir}/ @@ -858,6 +858,10 @@ fi - Install plugin libraries in appropriate packages. - Disable example plugins. +* Thu Aug 20 2009 Jonathan Perkin + +- Update variable used for mysql-test suite location to match source. + * Fri Nov 07 2008 Joerg Bruehe - Correct yesterday's fix, so that it also works for the last flag, From 11dd1d6d84a6214eff61e2efd6c73369bb44adbc Mon Sep 17 00:00:00 2001 From: Anurag Shekhar Date: Mon, 24 Aug 2009 13:15:51 +0530 Subject: [PATCH 026/138] Bug #44723 Larger read_buffer_size values can cause performance decrease for INSERTs Bulk inserts (multiple row, CREATE ... SELECT, INSERT ... SELECT) into MyISAM tables were performed inefficiently. This was mainly affecting use cases where read_buffer_size was considerably large (>256K) and low number of rows was inserted (e.g. 30-100). The problem was that during I/O cache initialization (this happens before each bulk insert) allocated I/O buffer was unnecessarily initialized to '\0'. This was happening because of mess in flag values. MyISAM informs I/O cache to wait for free space (if out of disk space) by passing MY_WAIT_IF_FULL flag. Since MY_WAIT_IF_FULL and MY_ZEROFILL have the same values, memory allocator was initializing memory to '\0'. The performance gain provided with this patch may only be visible with non-debug binaries, since safemalloc always initializes allocated memory to 0xA5A5... mysys/mf_iocache.c: Remove MY_WAIT_IF_FULL from myflags before calling my_malloc to prevent conflict with MY_ZEROFILL. --- mysys/mf_iocache.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index d2ace12da4d..3aab904a6e0 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -233,10 +233,13 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, buffer_block = cachesize; if (type == SEQ_READ_APPEND) buffer_block *= 2; - if ((info->buffer= - (byte*) my_malloc(buffer_block, - MYF((cache_myflags & ~ MY_WME) | - (cachesize == min_cache ? MY_WME : 0)))) != 0) + /* + Unset MY_WAIT_IF_FULL bit if it is set, to prevent conflict with + MY_ZEROFILL. + */ + myf flag = MYF((cache_myflags & ~ (MY_WME | MY_WAIT_IF_FULL)) | + (cachesize == min_cache ? MY_WME : 0)); + if ((info->buffer= (byte*) my_malloc(buffer_block, flag)) != 0) { info->write_buffer=info->buffer; if (type == SEQ_READ_APPEND) From df91ff571b36a2428b31d667944eb72a10cf1449 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Mon, 24 Aug 2009 10:50:04 +0200 Subject: [PATCH 027/138] Add conditionals for bundled zlib and innodb plugin --- support-files/mysql.spec.sh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 8a181375cfb..5b8d7a5922d 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -31,6 +31,20 @@ %{?_with_yassl:%define YASSL_BUILD 1} %{!?_with_yassl:%define YASSL_BUILD 0} +# ---------------------------------------------------------------------- +# use "rpmbuild --with bundled_zlib" or "rpm --define '_with_bundled_zlib 1'" +# (for RPM 3.x) to build using the bundled zlib (off by default) +# ---------------------------------------------------------------------- +%{?_with_bundled_zlib:%define WITH_BUNDLED_ZLIB 1} +%{!?_with_bundled_zlib:%define WITH_BUNDLED_ZLIB 0} + +# ---------------------------------------------------------------------- +# use "rpmbuild --without innodb_plugin" or "rpm --define '_without_innodb_plugin 1'" +# (for RPM 3.x) to not build the innodb plugin (on by default with innodb builds) +# ---------------------------------------------------------------------- +%{?_without_innodb_plugin:%define WITHOUT_INNODB_PLUGIN 1} +%{!?_without_innodb_plugin:%define WITHOUT_INNODB_PLUGIN 0} + # use "rpmbuild --with cluster" or "rpm --define '_with_cluster 1'" (for RPM 3.x) # to build with cluster support (off by default) %{?_with_cluster:%define CLUSTER_BUILD 1} @@ -292,6 +306,9 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \ --enable-thread-safe-client \ --with-readline \ --with-innodb \ +%if %{WITHOUT_INNODB_PLUGIN} + --without-plugin-innodb_plugin \ +%endif %if %{CLUSTER_BUILD} --with-ndbcluster \ %else @@ -305,6 +322,9 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \ --without-plugin-example \ --with-partition \ --with-big-tables \ +%if %{WITH_BUNDLED_ZLIB} + --with-zlib-dir=bundled \ +%endif --enable-shared \ " make @@ -853,6 +873,10 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Mon Aug 24 2009 Jonathan Perkin + +- Add conditionals for bundled zlib and innodb plugin + * Fri Aug 21 2009 Jonathan Perkin - Install plugin libraries in appropriate packages. From c2bd07ca9cd848c58dcd243551e4d52e68bbb449 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Mon, 24 Aug 2009 14:06:01 +0200 Subject: [PATCH 028/138] Tidy previous, put example storage engine back as it's used by tests. --- support-files/mysql.spec.sh | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 5b8d7a5922d..fbb569e0c8c 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -319,7 +319,6 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \ --with-blackhole-storage-engine \ --with-federated-storage-engine \ --without-plugin-daemon_example \ - --without-plugin-example \ --with-partition \ --with-big-tables \ %if %{WITH_BUNDLED_ZLIB} @@ -715,7 +714,11 @@ fi %attr(755, root, root) %{_bindir}/resolve_stack_dump %attr(755, root, root) %{_bindir}/resolveip -%attr(755, root, root) %{_libdir}/plugin/*.so* +%attr(755, root, root) %{_libdir}/mysql/plugin/ha_example.so* +%if %{WITHOUT_INNODB_PLUGIN} +%else +%attr(755, root, root) %{_libdir}/mysql/plugin/ha_innodb_plugin.so* +%endif %attr(755, root, root) %{_sbindir}/mysqld %attr(755, root, root) %{_sbindir}/mysqld-debug @@ -842,8 +845,15 @@ fi %{_libdir}/mysql/libvio.a %{_libdir}/mysql/libz.a %{_libdir}/mysql/libz.la -%{_libdir}/plugin/*.a -%{_libdir}/plugin/*.la +%{_libdir}/mysql/plugin/ha_example.a +%{_libdir}/mysql/plugin/ha_example.la +%if %{WITHOUT_INNODB_PLUGIN} +%else +%{_libdir}/mysql/plugin/ha_innodb_plugin.a +%{_libdir}/mysql/plugin/ha_innodb_plugin.la +%endif +%{_libdir}/mysql/plugin/mypluglib.a +%{_libdir}/mysql/plugin/mypluglib.la %files shared %defattr(-, root, root, 0755) @@ -880,7 +890,7 @@ fi * Fri Aug 21 2009 Jonathan Perkin - Install plugin libraries in appropriate packages. -- Disable example plugins. +- Disable libdaemon_example plugin. * Thu Aug 20 2009 Jonathan Perkin From 7492d622e44d7d3fd424bd24fd53131fe06d1c22 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 24 Aug 2009 15:28:03 +0300 Subject: [PATCH 029/138] Bug #37044: Read overflow in opt_range.cc found during "make test" The code was using a special global buffer for the value of IS NULL ranges. This was not always long enough to be copied by a regular memcpy. As a result read buffer overflows may occur. Fixed by setting the null byte to 1 and setting the rest of the field disk image to NULL with a bzero (instead of relying on the buffer and memcpy()). --- sql/opt_range.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index d007009d62c..778fc418392 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -8308,11 +8308,21 @@ get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree, return FALSE; uint field_length= cur_part->store_length; - if ((cur_range->maybe_null && + if (cur_range->maybe_null && cur_range->min_value[0] && cur_range->max_value[0]) - || - (memcmp(cur_range->min_value, cur_range->max_value, field_length) == 0)) - { /* cur_range specifies 'IS NULL' or an equality condition. */ + { + /* + cur_range specifies 'IS NULL'. In this case the argument points to a "null value" (is_null_string) + that may not always be long enough for a direct memcpy to a field. + */ + DBUG_ASSERT (field_length > 0); + *key_ptr= 1; + bzero(key_ptr+1,field_length-1); + key_ptr+= field_length; + *key_infix_len+= field_length; + } + else if (memcmp(cur_range->min_value, cur_range->max_value, field_length) == 0) + { /* cur_range specifies an equality condition. */ memcpy(key_ptr, cur_range->min_value, field_length); key_ptr+= field_length; *key_infix_len+= field_length; From 74092a8e5bfa037e32f2cca266fad0f59b0dbd9a Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 25 Aug 2009 13:00:23 +0200 Subject: [PATCH 030/138] Disable ftexample to match other packages, ride previous changelog entry. --- support-files/mysql.spec.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index fbb569e0c8c..cd8af76faa2 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -319,6 +319,7 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \ --with-blackhole-storage-engine \ --with-federated-storage-engine \ --without-plugin-daemon_example \ + --without-plugin-ftexample \ --with-partition \ --with-big-tables \ %if %{WITH_BUNDLED_ZLIB} @@ -852,8 +853,6 @@ fi %{_libdir}/mysql/plugin/ha_innodb_plugin.a %{_libdir}/mysql/plugin/ha_innodb_plugin.la %endif -%{_libdir}/mysql/plugin/mypluglib.a -%{_libdir}/mysql/plugin/mypluglib.la %files shared %defattr(-, root, root, 0755) @@ -890,7 +889,7 @@ fi * Fri Aug 21 2009 Jonathan Perkin - Install plugin libraries in appropriate packages. -- Disable libdaemon_example plugin. +- Disable libdaemon_example and ftexample plugins. * Thu Aug 20 2009 Jonathan Perkin From 3a766492913ecf1d3642063c1fa57b5d94c182a6 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 25 Aug 2009 15:56:50 +0200 Subject: [PATCH 031/138] Bug #42408 Faulty regex for detecting [Warning] and [ERROR] in mysqld error log Enabled proper pattern for Warnings and ERRORs Added some suppressions --- mysql-test/include/mtr_warnings.sql | 6 +++++- mysql-test/mysql-test-run.pl | 6 ++---- mysql-test/r/almost_full.result | 1 + mysql-test/r/upgrade.result | 4 ---- mysql-test/suite/rpl/r/rpl_idempotency.result | 3 ++- mysql-test/suite/rpl/t/rpl_idempotency.test | 3 ++- mysql-test/t/almost_full.test | 2 ++ mysql-test/t/upgrade.test | 2 ++ 8 files changed, 16 insertions(+), 11 deletions(-) diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql index 73287900f3c..157244a9b0a 100644 --- a/mysql-test/include/mtr_warnings.sql +++ b/mysql-test/include/mtr_warnings.sql @@ -132,7 +132,7 @@ INSERT INTO global_suppressions VALUES ("Error in Log_event::read_log_event\\\(\\\): 'Sanity check failed', data_len: 258, event_type: 49"), - ("Statement is not safe to log in statement format"), + ("Statement may not be safe to log in statement format"), /* test case for Bug#bug29807 copies a stray frm into database */ ("InnoDB: Error: table `test`.`bug29807` does not exist in the InnoDB internal"), @@ -172,6 +172,10 @@ INSERT INTO global_suppressions VALUES */ ("Can't find file: '.\\\\test\\\\\\?{8}.frm'"), + /* Added 2009-08-XX after fixing Bug #42408 */ + + ("Slave: Operation DROP USER failed for '.*'@'localhost' Error_code: 1396"), + ("THE_LAST_SUPPRESSION")|| diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 28ddd718f16..c15f3990ec4 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3624,10 +3624,8 @@ sub extract_warning_lines ($) { # and correcting them shows a few additional harmless warnings. # Thus those patterns are temporarily removed from the list # of patterns. For more info see BUG#42408 - # qr/^Warning:|mysqld: Warning|\[Warning\]/, - # qr/^Error:|\[ERROR\]/, - qr/^Warning:|mysqld: Warning/, - qr/^Error:/, + qr/^Warning:|mysqld: Warning|\[Warning\]/, + qr/^Error:|\[ERROR\]/, qr/^==.* at 0x/, qr/InnoDB: Warning|InnoDB: Error/, qr/^safe_mutex:|allocated at line/, diff --git a/mysql-test/r/almost_full.result b/mysql-test/r/almost_full.result index eb28f12fa51..b2d7092aa51 100644 --- a/mysql-test/r/almost_full.result +++ b/mysql-test/r/almost_full.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("The table 't1' is full"); drop table if exists t1; set global myisam_data_pointer_size=2; CREATE TABLE t1 (a int auto_increment primary key not null, b longtext) ENGINE=MyISAM; diff --git a/mysql-test/r/upgrade.result b/mysql-test/r/upgrade.result index da6201692a9..034242079b1 100644 --- a/mysql-test/r/upgrade.result +++ b/mysql-test/r/upgrade.result @@ -108,11 +108,7 @@ a-b-c show create view `a-b-c`.v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `a`.`f1` AS `f1` from (`a-b-c`.`t1` `a` join `information_schema`.`tables` `b`) where (convert(`a`.`f1` using utf8) = `b`.`TABLE_NAME`) utf8 utf8_general_ci -Warnings: -Note 1600 Creation context of view `a-b-c`.`v1' is invalid select * from `a-b-c`.v1; f1 -Warnings: -Note 1600 Creation context of view `a-b-c`.`v1' is invalid drop database `a-b-c`; use test; diff --git a/mysql-test/suite/rpl/r/rpl_idempotency.result b/mysql-test/suite/rpl/r/rpl_idempotency.result index 3341c03db0f..bfdcbc6fa23 100644 --- a/mysql-test/suite/rpl/r/rpl_idempotency.result +++ b/mysql-test/suite/rpl/r/rpl_idempotency.result @@ -4,7 +4,8 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; -call mtr.add_suppression("Slave: Can\'t find record in \'t1\' Error_code: 1032"); +call mtr.add_suppression("Slave: Can't find record in 't.' Error_code: 1032"); +call mtr.add_suppression("Slave: Cannot delete or update a parent row: a foreign key constraint fails .* Error_code: 1451"); call mtr.add_suppression("Slave: Cannot add or update a child row: a foreign key constraint fails .* Error_code: 1452"); SET @old_slave_exec_mode= @@global.slave_exec_mode; CREATE TABLE t1 (a INT PRIMARY KEY); diff --git a/mysql-test/suite/rpl/t/rpl_idempotency.test b/mysql-test/suite/rpl/t/rpl_idempotency.test index bfd1860759e..c96b88a1b1a 100644 --- a/mysql-test/suite/rpl/t/rpl_idempotency.test +++ b/mysql-test/suite/rpl/t/rpl_idempotency.test @@ -8,7 +8,8 @@ connection slave; source include/have_innodb.inc; # Add suppression for expected warning(s) in slaves error log -call mtr.add_suppression("Slave: Can\'t find record in \'t1\' Error_code: 1032"); +call mtr.add_suppression("Slave: Can't find record in 't.' Error_code: 1032"); +call mtr.add_suppression("Slave: Cannot delete or update a parent row: a foreign key constraint fails .* Error_code: 1451"); call mtr.add_suppression("Slave: Cannot add or update a child row: a foreign key constraint fails .* Error_code: 1452"); SET @old_slave_exec_mode= @@global.slave_exec_mode; diff --git a/mysql-test/t/almost_full.test b/mysql-test/t/almost_full.test index 5c67ab3c088..24801f9cbc3 100644 --- a/mysql-test/t/almost_full.test +++ b/mysql-test/t/almost_full.test @@ -2,6 +2,8 @@ # Some special cases with empty tables # +call mtr.add_suppression("The table 't1' is full"); + --disable_warnings drop table if exists t1; --enable_warnings diff --git a/mysql-test/t/upgrade.test b/mysql-test/t/upgrade.test index d571a2efc7c..e390e8a1253 100644 --- a/mysql-test/t/upgrade.test +++ b/mysql-test/t/upgrade.test @@ -124,6 +124,8 @@ with_check_option=0 timestamp=2009-04-10 11:53:37 create-version=1 source=select f1 from `a-b-c`.t1 a, information_schema.tables b\nwhere a.f1 = b.table_name +client_cs_name=utf8 +connection_cl_name=utf8_general_ci EOF show databases like '%a-b-c%'; From 4655118bea2bcb14a06f01046fb06052fd37214c Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Wed, 26 Aug 2009 12:51:23 +0200 Subject: [PATCH 032/138] Bug#46362: Endpoint should be set to false for TO_DAYS(DATE) There were a problem since pruning uses the field for comparison (while evaluate_join_record uses longlong), resulting in pruning failures when comparing DATE to DATETIME. Fix was to always comparing DATE vs DATETIME as DATETIME, by adding ' 00:00:00' to the DATE string. And adding optimization for comparing with 23:59:59, so that DATETIME_col > '2001-02-03 23:59:59' -> TO_DAYS(DATETIME_col) > TO_DAYS('2001-02-03 23:59:59') instead of '>='. mysql-test/r/partition_pruning.result: Bug#46362: Endpoint should be set to false for TO_DAYS(DATE) Updated result-file mysql-test/t/partition_pruning.test: Bug#46362: Endpoint should be set to false for TO_DAYS(DATE) Added testcases. sql-common/my_time.c: Bug#46362: Endpoint should be set to false for TO_DAYS(DATE) removed duplicate assignment. sql/item.cc: Bug#46362: Endpoint should be set to false for TO_DAYS(DATE) Changed field_is_equal_to_item into field_cmp_to_item, to better handling DATE vs DATETIME comparision. sql/item.h: Bug#46362: Endpoint should be set to false for TO_DAYS(DATE) Updated comment sql/item_timefunc.cc: Bug#46362: Endpoint should be set to false for TO_DAYS(DATE) Added optimization (pruning) of DATETIME where time-part is 23:59:59 sql/opt_range.cc: Bug#46362: Endpoint should be set to false for TO_DAYS(DATE) Using the new stored_field_cmp_to_item for better pruning. --- mysql-test/r/partition_pruning.result | 621 ++++++++++++++++++++++++++ mysql-test/t/partition_pruning.test | 308 +++++++++++++ sql-common/my_time.c | 4 +- sql/item.cc | 50 ++- sql/item.h | 6 +- sql/item_timefunc.cc | 10 +- sql/opt_range.cc | 15 +- 7 files changed, 989 insertions(+), 25 deletions(-) diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result index 26ddc92e97b..abaa37715bf 100644 --- a/mysql-test/r/partition_pruning.result +++ b/mysql-test/r/partition_pruning.result @@ -1,4 +1,625 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +# Test with DATETIME column NOT NULL +CREATE TABLE t1 ( +a int(10) unsigned NOT NULL, +b DATETIME NOT NULL, +PRIMARY KEY (a, b) +) PARTITION BY RANGE (TO_DAYS(b)) +(PARTITION p20090401 VALUES LESS THAN (TO_DAYS('2009-04-02')), +PARTITION p20090402 VALUES LESS THAN (TO_DAYS('2009-04-03')), +PARTITION p20090403 VALUES LESS THAN (TO_DAYS('2009-04-04')), +PARTITION p20090404 VALUES LESS THAN (TO_DAYS('2009-04-05')), +PARTITION p20090405 VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (1, '2009-01-01'), (1, '2009-04-01'), (2, '2009-04-01'), +(1, '2009-04-02'), (2, '2009-04-02'), (1, '2009-04-02 23:59:59'), +(1, '2009-04-03'), (2, '2009-04-03'), (1, '2009-04-04'), (2, '2009-04-04'), +(1, '2009-04-05'), (1, '2009-04-06'), (1, '2009-04-07'); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 6 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 8 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 8 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b < CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b <= CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b = CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b >= CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090402,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b > CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090402,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b < CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b <= CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b = CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b >= CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b > CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b < CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b <= CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b = CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090402 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b >= CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090402,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b > CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090402,p20090403,p20090404,p20090405 index NULL PRIMARY 12 NULL 13 Using where; Using index +DROP TABLE t1; +# Test with DATE column NOT NULL +CREATE TABLE t1 ( +a int(10) unsigned NOT NULL, +b DATE NOT NULL, +PRIMARY KEY (a, b) +) PARTITION BY RANGE (TO_DAYS(b)) +(PARTITION p20090401 VALUES LESS THAN (TO_DAYS('2009-04-02')), +PARTITION p20090402 VALUES LESS THAN (TO_DAYS('2009-04-03')), +PARTITION p20090403 VALUES LESS THAN (TO_DAYS('2009-04-04')), +PARTITION p20090404 VALUES LESS THAN (TO_DAYS('2009-04-05')), +PARTITION p20090405 VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (1, '2009-01-01'), (1, '2009-04-01'), (2, '2009-04-01'), +(1, '2009-04-02'), (2, '2009-04-02'), (1, '2009-04-03'), (2, '2009-04-03'), +(1, '2009-04-04'), (2, '2009-04-04'), (1, '2009-04-05'), (1, '2009-04-06'), +(1, '2009-04-07'); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 5 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 7 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 7 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b < CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b <= CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b = CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b >= CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b > CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b < CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b <= CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b = CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b >= CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b > CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b < CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b <= CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b = CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b >= CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b > CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 index NULL PRIMARY 7 NULL 12 Using where; Using index +DROP TABLE t1; +# Test with DATETIME column NULL +CREATE TABLE t1 ( +a int(10) unsigned NOT NULL, +b DATETIME NULL +) PARTITION BY RANGE (TO_DAYS(b)) +(PARTITION p20090401 VALUES LESS THAN (TO_DAYS('2009-04-02')), +PARTITION p20090402 VALUES LESS THAN (TO_DAYS('2009-04-03')), +PARTITION p20090403 VALUES LESS THAN (TO_DAYS('2009-04-04')), +PARTITION p20090404 VALUES LESS THAN (TO_DAYS('2009-04-05')), +PARTITION p20090405 VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (1, '2009-01-01'), (1, '2009-04-01'), (2, '2009-04-01'), +(1, '2009-04-02'), (2, '2009-04-02'), (1, '2009-04-02 23:59:59'), +(1, '2009-04-03'), (2, '2009-04-03'), (1, '2009-04-04'), (2, '2009-04-04'), +(1, '2009-04-05'), (1, '2009-04-06'), (1, '2009-04-07'); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 6 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 8 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 8 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b < CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b <= CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b = CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090402 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b >= CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090402,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b > CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090402 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090402,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b < CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b <= CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b = CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b >= CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b > CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b < CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b <= CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b = CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090402 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b >= CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090402,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b > CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090402,p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 13 Using where +DROP TABLE t1; +# Test with DATE column NULL +CREATE TABLE t1 ( +a int(10) unsigned NOT NULL, +b DATE NULL +) PARTITION BY RANGE (TO_DAYS(b)) +(PARTITION p20090401 VALUES LESS THAN (TO_DAYS('2009-04-02')), +PARTITION p20090402 VALUES LESS THAN (TO_DAYS('2009-04-03')), +PARTITION p20090403 VALUES LESS THAN (TO_DAYS('2009-04-04')), +PARTITION p20090404 VALUES LESS THAN (TO_DAYS('2009-04-05')), +PARTITION p20090405 VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (1, '2009-01-01'), (1, '2009-04-01'), (2, '2009-04-01'), +(1, '2009-04-02'), (2, '2009-04-02'), (1, '2009-04-03'), (2, '2009-04-03'), +(1, '2009-04-04'), (2, '2009-04-04'), (1, '2009-04-05'), (1, '2009-04-06'), +(1, '2009-04-07'); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 5 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b < CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b <= CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b = CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b >= CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b > CAST('2009-04-02 23:59:59' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATE); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-02 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b < CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b <= CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402,p20090403 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b = CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b >= CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b > CAST('2009-04-03 00:00:01' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b < CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b <= CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090401,p20090402 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b = CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b >= CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 +WHERE b > CAST('2009-04-02 23:59:58' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p20090403,p20090404,p20090405 ALL NULL NULL NULL NULL 12 Using where +DROP TABLE t1; +# For better code coverage of the patch +CREATE TABLE t1 ( +a int(10) unsigned NOT NULL, +b DATE +) PARTITION BY RANGE ( TO_DAYS(b) ) +(PARTITION p20090401 VALUES LESS THAN (TO_DAYS('2009-04-02')), +PARTITION p20090402 VALUES LESS THAN (TO_DAYS('2009-04-03')), +PARTITION p20090403 VALUES LESS THAN (TO_DAYS('2009-04-04')), +PARTITION p20090404 VALUES LESS THAN (TO_DAYS('2009-04-05')), +PARTITION p20090405 VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (1, '2009-01-01'), (2, NULL); +# test with an invalid date, which lead to item->null_value is set. +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-99' AS DATETIME); +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Warning 1292 Incorrect datetime value: '2009-04-99' +Warning 1292 Incorrect datetime value: '2009-04-99' +DROP TABLE t1; CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT, b DATETIME, diff --git a/mysql-test/t/partition_pruning.test b/mysql-test/t/partition_pruning.test index ad102062ef8..ef28820852e 100644 --- a/mysql-test/t/partition_pruning.test +++ b/mysql-test/t/partition_pruning.test @@ -8,6 +8,314 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; --enable_warnings +# +# Bug#46362: Endpoint should be set to false for TO_DAYS(DATE) +# +# There is a problem when comparing DATE with DATETIME. +# In pruning it is converted into the field type +# and in row evaluation it is converted to longlong +# (like a DATETIME). +--echo # Test with DATETIME column NOT NULL +CREATE TABLE t1 ( + a int(10) unsigned NOT NULL, + b DATETIME NOT NULL, + PRIMARY KEY (a, b) +) PARTITION BY RANGE (TO_DAYS(b)) +(PARTITION p20090401 VALUES LESS THAN (TO_DAYS('2009-04-02')), + PARTITION p20090402 VALUES LESS THAN (TO_DAYS('2009-04-03')), + PARTITION p20090403 VALUES LESS THAN (TO_DAYS('2009-04-04')), + PARTITION p20090404 VALUES LESS THAN (TO_DAYS('2009-04-05')), + PARTITION p20090405 VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (1, '2009-01-01'), (1, '2009-04-01'), (2, '2009-04-01'), + (1, '2009-04-02'), (2, '2009-04-02'), (1, '2009-04-02 23:59:59'), + (1, '2009-04-03'), (2, '2009-04-03'), (1, '2009-04-04'), (2, '2009-04-04'), + (1, '2009-04-05'), (1, '2009-04-06'), (1, '2009-04-07'); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b < CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b <= CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b = CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b >= CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b > CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b < CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b <= CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b = CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b >= CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b > CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b < CAST('2009-04-02 23:59:58' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b <= CAST('2009-04-02 23:59:58' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b = CAST('2009-04-02 23:59:58' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b >= CAST('2009-04-02 23:59:58' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b > CAST('2009-04-02 23:59:58' AS DATETIME); +DROP TABLE t1; + +--echo # Test with DATE column NOT NULL +CREATE TABLE t1 ( + a int(10) unsigned NOT NULL, + b DATE NOT NULL, + PRIMARY KEY (a, b) +) PARTITION BY RANGE (TO_DAYS(b)) +(PARTITION p20090401 VALUES LESS THAN (TO_DAYS('2009-04-02')), + PARTITION p20090402 VALUES LESS THAN (TO_DAYS('2009-04-03')), + PARTITION p20090403 VALUES LESS THAN (TO_DAYS('2009-04-04')), + PARTITION p20090404 VALUES LESS THAN (TO_DAYS('2009-04-05')), + PARTITION p20090405 VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (1, '2009-01-01'), (1, '2009-04-01'), (2, '2009-04-01'), + (1, '2009-04-02'), (2, '2009-04-02'), (1, '2009-04-03'), (2, '2009-04-03'), + (1, '2009-04-04'), (2, '2009-04-04'), (1, '2009-04-05'), (1, '2009-04-06'), + (1, '2009-04-07'); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b < CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b <= CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b = CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b >= CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b > CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b < CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b <= CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b = CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b >= CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b > CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b < CAST('2009-04-02 23:59:58' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b <= CAST('2009-04-02 23:59:58' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b = CAST('2009-04-02 23:59:58' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b >= CAST('2009-04-02 23:59:58' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b > CAST('2009-04-02 23:59:58' AS DATETIME); +DROP TABLE t1; + +--echo # Test with DATETIME column NULL +CREATE TABLE t1 ( + a int(10) unsigned NOT NULL, + b DATETIME NULL +) PARTITION BY RANGE (TO_DAYS(b)) +(PARTITION p20090401 VALUES LESS THAN (TO_DAYS('2009-04-02')), + PARTITION p20090402 VALUES LESS THAN (TO_DAYS('2009-04-03')), + PARTITION p20090403 VALUES LESS THAN (TO_DAYS('2009-04-04')), + PARTITION p20090404 VALUES LESS THAN (TO_DAYS('2009-04-05')), + PARTITION p20090405 VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (1, '2009-01-01'), (1, '2009-04-01'), (2, '2009-04-01'), + (1, '2009-04-02'), (2, '2009-04-02'), (1, '2009-04-02 23:59:59'), + (1, '2009-04-03'), (2, '2009-04-03'), (1, '2009-04-04'), (2, '2009-04-04'), + (1, '2009-04-05'), (1, '2009-04-06'), (1, '2009-04-07'); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b < CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b <= CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b = CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b >= CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b > CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b < CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b <= CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b = CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b >= CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b > CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b < CAST('2009-04-02 23:59:58' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b <= CAST('2009-04-02 23:59:58' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b = CAST('2009-04-02 23:59:58' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b >= CAST('2009-04-02 23:59:58' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b > CAST('2009-04-02 23:59:58' AS DATETIME); +DROP TABLE t1; + +--echo # Test with DATE column NULL +CREATE TABLE t1 ( + a int(10) unsigned NOT NULL, + b DATE NULL +) PARTITION BY RANGE (TO_DAYS(b)) +(PARTITION p20090401 VALUES LESS THAN (TO_DAYS('2009-04-02')), + PARTITION p20090402 VALUES LESS THAN (TO_DAYS('2009-04-03')), + PARTITION p20090403 VALUES LESS THAN (TO_DAYS('2009-04-04')), + PARTITION p20090404 VALUES LESS THAN (TO_DAYS('2009-04-05')), + PARTITION p20090405 VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (1, '2009-01-01'), (1, '2009-04-01'), (2, '2009-04-01'), + (1, '2009-04-02'), (2, '2009-04-02'), (1, '2009-04-03'), (2, '2009-04-03'), + (1, '2009-04-04'), (2, '2009-04-04'), (1, '2009-04-05'), (1, '2009-04-06'), + (1, '2009-04-07'); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b < CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b <= CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b = CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b >= CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b > CAST('2009-04-02 23:59:59' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > CAST('2009-04-03' AS DATE); +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03 00:00:00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-02 23:59:59'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b <= '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b = '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b >= '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b > '2009-04-03'; +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b < CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b <= CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b = CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b >= CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b > CAST('2009-04-03 00:00:01' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b < CAST('2009-04-02 23:59:58' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b <= CAST('2009-04-02 23:59:58' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b = CAST('2009-04-02 23:59:58' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b >= CAST('2009-04-02 23:59:58' AS DATETIME); +EXPLAIN PARTITIONS SELECT * FROM t1 + WHERE b > CAST('2009-04-02 23:59:58' AS DATETIME); +DROP TABLE t1; + +--echo # For better code coverage of the patch +CREATE TABLE t1 ( + a int(10) unsigned NOT NULL, + b DATE +) PARTITION BY RANGE ( TO_DAYS(b) ) +(PARTITION p20090401 VALUES LESS THAN (TO_DAYS('2009-04-02')), + PARTITION p20090402 VALUES LESS THAN (TO_DAYS('2009-04-03')), + PARTITION p20090403 VALUES LESS THAN (TO_DAYS('2009-04-04')), + PARTITION p20090404 VALUES LESS THAN (TO_DAYS('2009-04-05')), + PARTITION p20090405 VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (1, '2009-01-01'), (2, NULL); +--echo # test with an invalid date, which lead to item->null_value is set. +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-99' AS DATETIME); +DROP TABLE t1; + # # Bug#40972: some sql execution lead the whole database crashing # diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 747c5797ed4..a1b85049934 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -450,9 +450,7 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, } } - DBUG_RETURN(l_time->time_type= - (number_of_fields <= 3 ? MYSQL_TIMESTAMP_DATE : - MYSQL_TIMESTAMP_DATETIME)); + DBUG_RETURN(l_time->time_type); err: bzero((char*) l_time, sizeof(*l_time)); diff --git a/sql/item.cc b/sql/item.cc index 2640b74851b..79ae4b20f30 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -6846,14 +6846,21 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) } /** - Return true if the value stored in the field is equal to the const - item. + Compare the value stored in field, with the original item. - We need to use this on the range optimizer because in some cases - we can't store the value in the field without some precision/character loss. + @param field field which the item is converted and stored in + @param item original item + + @return Return an integer greater than, equal to, or less than 0 if + the value stored in the field is greater than, equal to, + or less than the original item + + @note We only use this on the range optimizer/partition pruning, + because in some cases we can't store the value in the field + without some precision/character loss. */ -bool field_is_equal_to_item(Field *field,Item *item) +int stored_field_cmp_to_item(Field *field, Item *item) { Item_result res_type=item_cmp_type(field->result_type(), @@ -6864,28 +6871,49 @@ bool field_is_equal_to_item(Field *field,Item *item) char field_buff[MAX_FIELD_WIDTH]; String item_tmp(item_buff,sizeof(item_buff),&my_charset_bin),*item_result; String field_tmp(field_buff,sizeof(field_buff),&my_charset_bin); + enum_field_types field_type; item_result=item->val_str(&item_tmp); if (item->null_value) - return 1; // This must be true + return 0; field->val_str(&field_tmp); - return !stringcmp(&field_tmp,item_result); + + /* + If comparing DATE with DATETIME, append the time-part to the DATE. + So that the strings are equally formatted. + A DATE converted to string is 10 characters, and a DATETIME converted + to string is 19 characters. + */ + field_type= field->type(); + if (field_type == MYSQL_TYPE_DATE && + item_result->length() == 19) + field_tmp.append(" 00:00:00"); + else if (field_type == MYSQL_TYPE_DATETIME && + item_result->length() == 10) + item_result->append(" 00:00:00"); + + return stringcmp(&field_tmp,item_result); } if (res_type == INT_RESULT) - return 1; // Both where of type int + return 0; // Both are of type int if (res_type == DECIMAL_RESULT) { my_decimal item_buf, *item_val, field_buf, *field_val; item_val= item->val_decimal(&item_buf); if (item->null_value) - return 1; // This must be true + return 0; field_val= field->val_decimal(&field_buf); - return !my_decimal_cmp(item_val, field_val); + return my_decimal_cmp(item_val, field_val); } double result= item->val_real(); if (item->null_value) + return 0; + double field_result= field->val_real(); + if (field_result < result) + return -1; + else if (field_result > result) return 1; - return result == field->val_real(); + return 0; } Item_cache* Item_cache::get_cache(const Item *item) diff --git a/sql/item.h b/sql/item.h index 3dfcd7c2612..8b37bd3c26d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -576,8 +576,8 @@ public: left_endp FALSE <=> The interval is "x < const" or "x <= const" TRUE <=> The interval is "x > const" or "x >= const" - incl_endp IN TRUE <=> the comparison is '<' or '>' - FALSE <=> the comparison is '<=' or '>=' + incl_endp IN FALSE <=> the comparison is '<' or '>' + TRUE <=> the comparison is '<=' or '>=' OUT The same but for the "F(x) $CMP$ F(const)" comparison DESCRIPTION @@ -3117,4 +3117,4 @@ void mark_select_range_as_dependent(THD *thd, extern Cached_item *new_Cached_item(THD *thd, Item *item); extern Item_result item_cmp_type(Item_result a,Item_result b); extern void resolve_const_item(THD *thd, Item **ref, Item *cmp_item); -extern bool field_is_equal_to_item(Field *field,Item *item); +extern int stored_field_cmp_to_item(Field *field, Item *item); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index d79b0b02998..eebede32f8d 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -991,15 +991,19 @@ longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp) point to day bound ("strictly less" comparison stays intact): col < '2007-09-15 00:00:00' -> TO_DAYS(col) < TO_DAYS('2007-09-15') + col > '2007-09-15 23:59:59' -> TO_DAYS(col) > TO_DAYS('2007-09-15') which is different from the general case ("strictly less" changes to "less or equal"): col < '2007-09-15 12:34:56' -> TO_DAYS(col) <= TO_DAYS('2007-09-15') */ - if (!left_endp && !(ltime.hour || ltime.minute || ltime.second || - ltime.second_part)) - ; /* do nothing */ + if ((!left_endp && !(ltime.hour || ltime.minute || ltime.second || + ltime.second_part)) || + (left_endp && ltime.hour == 23 && ltime.minute == 59 && + ltime.second == 59)) + /* do nothing */ + ; else *incl_endp= TRUE; return res; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index e3aef02637f..96631a741da 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -5855,7 +5855,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field, but we'll need to convert '>' to '>=' and '<' to '<='. This will be done together with other types at the end of this function - (grep for field_is_equal_to_item) + (grep for stored_field_cmp_to_item) */ } else @@ -5930,7 +5930,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field, switch (type) { case Item_func::LT_FUNC: - if (field_is_equal_to_item(field,value)) + if (stored_field_cmp_to_item(field,value) == 0) tree->max_flag=NEAR_MAX; /* fall through */ case Item_func::LE_FUNC: @@ -5944,11 +5944,16 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field, break; case Item_func::GT_FUNC: /* Don't use open ranges for partial key_segments */ - if (field_is_equal_to_item(field,value) && - !(key_part->flag & HA_PART_KEY_SEG)) + if ((!(key_part->flag & HA_PART_KEY_SEG)) && + (stored_field_cmp_to_item(field, value) <= 0)) tree->min_flag=NEAR_MIN; - /* fall through */ + tree->max_flag= NO_MAX_RANGE; + break; case Item_func::GE_FUNC: + /* Don't use open ranges for partial key_segments */ + if ((!(key_part->flag & HA_PART_KEY_SEG)) && + (stored_field_cmp_to_item(field,value) < 0)) + tree->min_flag= NEAR_MIN; tree->max_flag=NO_MAX_RANGE; break; case Item_func::SP_EQUALS_FUNC: From 67214ef4334deccdd1f1d89c49c4edecd9075962 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Wed, 26 Aug 2009 12:59:49 +0200 Subject: [PATCH 033/138] Bug#20577: Partitions: use of to_days() function leads to selection failures Problem was that the partition containing NULL values was pruned away, since '2001-01-01' < '2001-02-00' but TO_DAYS('2001-02-00') is NULL. Added the NULL partition for RANGE/LIST partitioning on TO_DAYS() function to be scanned too. Also fixed a bug that added ALLOW_INVALID_DATES to sql_mode (SELECT * FROM t WHERE date_col < '1999-99-99' on a RANGE/LIST partitioned table would add it). mysql-test/include/partition_date_range.inc: Bug#20577: Partitions: use of to_days() function leads to selection failures Added include file to decrease test code duplication mysql-test/r/partition_pruning.result: Bug#20577: Partitions: use of to_days() function leads to selection failures Added test results mysql-test/r/partition_range.result: Bug#20577: Partitions: use of to_days() function leads to selection failures Updated test result. This fix adds the partition containing NULL values to the list of partitions to be scanned. mysql-test/t/partition_pruning.test: Bug#20577: Partitions: use of to_days() function leads to selection failures Added test case sql/item.h: Bug#20577: Partitions: use of to_days() function leads to selection failures Added MONOTONIC_*INCREASE_NOT_NULL values to be used by TO_DAYS. sql/item_timefunc.cc: Bug#20577: Partitions: use of to_days() function leads to selection failures Calculate the number of days as return value even for invalid dates. This is so that pruning can be used even for invalid dates. sql/opt_range.cc: Bug#20577: Partitions: use of to_days() function leads to selection failures Fixed a bug that added ALLOW_INVALID_DATES to sql_mode (SELECT * FROM t WHERE date_col < '1999-99-99' on a RANGE/LIST partitioned table would add it). sql/partition_info.h: Bug#20577: Partitions: use of to_days() function leads to selection failures Resetting ret_null_part when a single partition is to be used, this to avoid adding the NULL partition. sql/sql_partition.cc: Bug#20577: Partitions: use of to_days() function leads to selection failures Always include the NULL partition if RANGE or LIST. Use the returned value for the function for pruning, even if it is marked as NULL, so that even '2000-00-00' can be used for pruning, even if TO_DAYS('2000-00-00') is NULL. Changed == to >= in get_next_partition_id_list to avoid crash if part_iter->part_nums is not correctly setup. --- mysql-test/include/partition_date_range.inc | 63 +++ mysql-test/r/partition_pruning.result | 425 ++++++++++++++++++++ mysql-test/r/partition_range.result | 4 +- mysql-test/t/partition_pruning.test | 44 ++ sql/item.h | 9 +- sql/item_timefunc.cc | 21 +- sql/opt_range.cc | 4 + sql/partition_info.h | 1 + sql/sql_partition.cc | 65 ++- 9 files changed, 624 insertions(+), 12 deletions(-) create mode 100644 mysql-test/include/partition_date_range.inc diff --git a/mysql-test/include/partition_date_range.inc b/mysql-test/include/partition_date_range.inc new file mode 100644 index 00000000000..c54396af9cb --- /dev/null +++ b/mysql-test/include/partition_date_range.inc @@ -0,0 +1,63 @@ +# Created for verifying bug#20577. +# expects TABLE t1 (... , a DATE, ...) + +--sorted_result +SELECT * FROM t1 WHERE a < '1001-01-01'; +--sorted_result +SELECT * FROM t1 WHERE a <= '1001-01-01'; +--sorted_result +SELECT * FROM t1 WHERE a >= '1001-01-01'; +--sorted_result +SELECT * FROM t1 WHERE a > '1001-01-01'; +--sorted_result +SELECT * FROM t1 WHERE a = '1001-01-01'; +--sorted_result +SELECT * FROM t1 WHERE a < '1001-00-00'; +--sorted_result +SELECT * FROM t1 WHERE a <= '1001-00-00'; +--sorted_result +SELECT * FROM t1 WHERE a >= '1001-00-00'; +--sorted_result +SELECT * FROM t1 WHERE a > '1001-00-00'; +--sorted_result +SELECT * FROM t1 WHERE a = '1001-00-00'; +--sorted_result +SELECT * FROM t1 WHERE a < '1999-02-31'; +--sorted_result +SELECT * FROM t1 WHERE a <= '1999-02-31'; +--sorted_result +SELECT * FROM t1 WHERE a >= '1999-02-31'; +--sorted_result +SELECT * FROM t1 WHERE a > '1999-02-31'; +--sorted_result +SELECT * FROM t1 WHERE a = '1999-02-31'; +--sorted_result +SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; +--sorted_result +SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; +--sorted_result +SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; +--sorted_result +SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; +if ($explain_partitions) +{ +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-01-01'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-01-01'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-01-01'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-01-01'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-01-01'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-00-00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-00-00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-00-00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-00-00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1999-02-31'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1999-02-31'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1999-02-31'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1999-02-31'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; +} diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result index 26ddc92e97b..7ac1e24cfab 100644 --- a/mysql-test/r/partition_pruning.result +++ b/mysql-test/r/partition_pruning.result @@ -1,4 +1,429 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +# test of RANGE and index +CREATE TABLE t1 (a DATE, KEY(a)) +PARTITION BY RANGE (TO_DAYS(a)) +(PARTITION `pNULL` VALUES LESS THAN (0), +PARTITION `p0001-01-01` VALUES LESS THAN (366 + 1), +PARTITION `p1001-01-01` VALUES LESS THAN (TO_DAYS('1001-01-01') + 1), +PARTITION `p2001-01-01` VALUES LESS THAN (TO_DAYS('2001-01-01') + 1)); +INSERT INTO t1 VALUES ('0000-00-00'), ('0000-01-02'), ('0001-01-01'), +('1001-00-00'), ('1001-01-01'), ('1002-00-00'), ('2001-01-01'); +SELECT * FROM t1 WHERE a < '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +SELECT * FROM t1 WHERE a <= '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +SELECT * FROM t1 WHERE a >= '1001-01-01'; +a +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a > '1001-01-01'; +a +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a = '1001-01-01'; +a +1001-01-01 +SELECT * FROM t1 WHERE a < '1001-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +SELECT * FROM t1 WHERE a <= '1001-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +SELECT * FROM t1 WHERE a >= '1001-00-00'; +a +1001-00-00 +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a > '1001-00-00'; +a +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a = '1001-00-00'; +a +1001-00-00 +SELECT * FROM t1 WHERE a < '1999-02-31'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a <= '1999-02-31'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a >= '1999-02-31'; +a +2001-01-01 +SELECT * FROM t1 WHERE a > '1999-02-31'; +a +2001-01-01 +SELECT * FROM t1 WHERE a = '1999-02-31'; +a +Warning 1292 Incorrect date value: '1999-02-31' for column 'a' at row 1 +Warnings: +SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; +a +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; +a +0001-01-01 +1001-00-00 +1001-01-01 +# test without index +ALTER TABLE t1 DROP KEY a; +SELECT * FROM t1 WHERE a < '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +SELECT * FROM t1 WHERE a <= '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +SELECT * FROM t1 WHERE a >= '1001-01-01'; +a +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a > '1001-01-01'; +a +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a = '1001-01-01'; +a +1001-01-01 +SELECT * FROM t1 WHERE a < '1001-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +SELECT * FROM t1 WHERE a <= '1001-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +SELECT * FROM t1 WHERE a >= '1001-00-00'; +a +1001-00-00 +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a > '1001-00-00'; +a +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a = '1001-00-00'; +a +1001-00-00 +SELECT * FROM t1 WHERE a < '1999-02-31'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a <= '1999-02-31'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a >= '1999-02-31'; +a +2001-01-01 +SELECT * FROM t1 WHERE a > '1999-02-31'; +a +2001-01-01 +SELECT * FROM t1 WHERE a = '1999-02-31'; +a +SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; +a +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; +a +0001-01-01 +1001-00-00 +1001-01-01 +DROP TABLE t1; +# test of LIST and index +CREATE TABLE t1 (a DATE, KEY(a)) +PARTITION BY LIST (TO_DAYS(a)) +(PARTITION `p0001-01-01` VALUES IN (TO_DAYS('0001-01-01')), +PARTITION `p2001-01-01` VALUES IN (TO_DAYS('2001-01-01')), +PARTITION `pNULL` VALUES IN (NULL), +PARTITION `p0000-01-02` VALUES IN (TO_DAYS('0000-01-02')), +PARTITION `p1001-01-01` VALUES IN (TO_DAYS('1001-01-01'))); +INSERT INTO t1 VALUES ('0000-00-00'), ('0000-01-02'), ('0001-01-01'), +('1001-00-00'), ('1001-01-01'), ('1002-00-00'), ('2001-01-01'); +SELECT * FROM t1 WHERE a < '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +SELECT * FROM t1 WHERE a <= '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +SELECT * FROM t1 WHERE a >= '1001-01-01'; +a +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a > '1001-01-01'; +a +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a = '1001-01-01'; +a +1001-01-01 +SELECT * FROM t1 WHERE a < '1001-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +SELECT * FROM t1 WHERE a <= '1001-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +SELECT * FROM t1 WHERE a >= '1001-00-00'; +a +1001-00-00 +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a > '1001-00-00'; +a +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a = '1001-00-00'; +a +1001-00-00 +SELECT * FROM t1 WHERE a < '1999-02-31'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a <= '1999-02-31'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a >= '1999-02-31'; +a +2001-01-01 +SELECT * FROM t1 WHERE a > '1999-02-31'; +a +2001-01-01 +SELECT * FROM t1 WHERE a = '1999-02-31'; +a +Warning 1292 Incorrect date value: '1999-02-31' for column 'a' at row 1 +Warnings: +SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; +a +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; +a +0001-01-01 +1001-00-00 +1001-01-01 +# test without index +ALTER TABLE t1 DROP KEY a; +SELECT * FROM t1 WHERE a < '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +SELECT * FROM t1 WHERE a <= '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +SELECT * FROM t1 WHERE a >= '1001-01-01'; +a +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a > '1001-01-01'; +a +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a = '1001-01-01'; +a +1001-01-01 +SELECT * FROM t1 WHERE a < '1001-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +SELECT * FROM t1 WHERE a <= '1001-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +SELECT * FROM t1 WHERE a >= '1001-00-00'; +a +1001-00-00 +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a > '1001-00-00'; +a +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a = '1001-00-00'; +a +1001-00-00 +SELECT * FROM t1 WHERE a < '1999-02-31'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a <= '1999-02-31'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a >= '1999-02-31'; +a +2001-01-01 +SELECT * FROM t1 WHERE a > '1999-02-31'; +a +2001-01-01 +SELECT * FROM t1 WHERE a = '1999-02-31'; +a +SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; +a +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; +a +0001-01-01 +1001-00-00 +1001-01-01 +DROP TABLE t1; CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT, b DATETIME, diff --git a/mysql-test/r/partition_range.result b/mysql-test/r/partition_range.result index e8fc55b759b..02d2f6359c5 100644 --- a/mysql-test/r/partition_range.result +++ b/mysql-test/r/partition_range.result @@ -745,7 +745,7 @@ a EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '2004-07-01' AND a <= '2004-09-30'; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p407,p408,p409 ALL NULL NULL NULL NULL 9 Using where +1 SIMPLE t1 p3xx,p407,p408,p409 ALL NULL NULL NULL NULL 18 Using where SELECT * from t1 WHERE (a >= '2004-07-01' AND a <= '2004-09-30') OR (a >= '2005-07-01' AND a <= '2005-09-30'); @@ -772,7 +772,7 @@ EXPLAIN PARTITIONS SELECT * from t1 WHERE (a >= '2004-07-01' AND a <= '2004-09-30') OR (a >= '2005-07-01' AND a <= '2005-09-30'); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p407,p408,p409,p507,p508,p509 ALL NULL NULL NULL NULL 18 Using where +1 SIMPLE t1 p3xx,p407,p408,p409,p507,p508,p509 ALL NULL NULL NULL NULL 27 Using where DROP TABLE t1; create table t1 (a int); insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); diff --git a/mysql-test/t/partition_pruning.test b/mysql-test/t/partition_pruning.test index ad102062ef8..511cfa595a4 100644 --- a/mysql-test/t/partition_pruning.test +++ b/mysql-test/t/partition_pruning.test @@ -8,6 +8,50 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; --enable_warnings +# +# Bug#20577: Partitions: use of to_days() function leads to selection failures +# +--let $explain_partitions= 1; +--let $verify_without_partitions= 0; +--echo # test of RANGE and index +CREATE TABLE t1 (a DATE, KEY(a)) +PARTITION BY RANGE (TO_DAYS(a)) +(PARTITION `pNULL` VALUES LESS THAN (0), + PARTITION `p0001-01-01` VALUES LESS THAN (366 + 1), + PARTITION `p1001-01-01` VALUES LESS THAN (TO_DAYS('1001-01-01') + 1), + PARTITION `p2001-01-01` VALUES LESS THAN (TO_DAYS('2001-01-01') + 1)); +if ($verify_without_partitions) +{ +ALTER TABLE t1 REMOVE PARTITIONING; +} +INSERT INTO t1 VALUES ('0000-00-00'), ('0000-01-02'), ('0001-01-01'), + ('1001-00-00'), ('1001-01-01'), ('1002-00-00'), ('2001-01-01'); +--source include/partition_date_range.inc +--echo # test without index +ALTER TABLE t1 DROP KEY a; +--source include/partition_date_range.inc +DROP TABLE t1; + +--echo # test of LIST and index +CREATE TABLE t1 (a DATE, KEY(a)) +PARTITION BY LIST (TO_DAYS(a)) +(PARTITION `p0001-01-01` VALUES IN (TO_DAYS('0001-01-01')), + PARTITION `p2001-01-01` VALUES IN (TO_DAYS('2001-01-01')), + PARTITION `pNULL` VALUES IN (NULL), + PARTITION `p0000-01-02` VALUES IN (TO_DAYS('0000-01-02')), + PARTITION `p1001-01-01` VALUES IN (TO_DAYS('1001-01-01'))); +if ($verify_without_partitions) +{ +ALTER TABLE t1 REMOVE PARTITIONING; +} +INSERT INTO t1 VALUES ('0000-00-00'), ('0000-01-02'), ('0001-01-01'), + ('1001-00-00'), ('1001-01-01'), ('1002-00-00'), ('2001-01-01'); +--source include/partition_date_range.inc +--echo # test without index +ALTER TABLE t1 DROP KEY a; +--source include/partition_date_range.inc +DROP TABLE t1; + # # Bug#40972: some sql execution lead the whole database crashing # diff --git a/sql/item.h b/sql/item.h index 3dfcd7c2612..30478ddf13d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -397,13 +397,20 @@ public: from INT_RESULT, may be NULL, or are unsigned. It will be possible to address this issue once the related partitioning bugs (BUG#16002, BUG#15447, BUG#13436) are fixed. + + The NOT_NULL enums are used in TO_DAYS, since TO_DAYS('2001-00-00') returns + NULL which puts those rows into the NULL partition, but + '2000-12-31' < '2001-00-00' < '2001-01-01'. So special handling is needed + for this (see Bug#20577). */ typedef enum monotonicity_info { NON_MONOTONIC, /* none of the below holds */ MONOTONIC_INCREASING, /* F() is unary and (x < y) => (F(x) <= F(y)) */ - MONOTONIC_STRICT_INCREASING /* F() is unary and (x < y) => (F(x) < F(y)) */ + MONOTONIC_INCREASING_NOT_NULL, /* But only for valid/real x and y */ + MONOTONIC_STRICT_INCREASING,/* F() is unary and (x < y) => (F(x) < F(y)) */ + MONOTONIC_STRICT_INCREASING_NOT_NULL /* But only for valid/real x and y */ } enum_monotonicity_info; /*************************************************************************/ diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index d79b0b02998..eefe47232ae 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -960,9 +960,9 @@ enum_monotonicity_info Item_func_to_days::get_monotonicity_info() const if (args[0]->type() == Item::FIELD_ITEM) { if (args[0]->field_type() == MYSQL_TYPE_DATE) - return MONOTONIC_STRICT_INCREASING; + return MONOTONIC_STRICT_INCREASING_NOT_NULL; if (args[0]->field_type() == MYSQL_TYPE_DATETIME) - return MONOTONIC_INCREASING; + return MONOTONIC_INCREASING_NOT_NULL; } return NON_MONOTONIC; } @@ -973,12 +973,27 @@ longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp) DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; longlong res; - if (get_arg0_date(<ime, TIME_NO_ZERO_DATE)) + int dummy; /* unused */ + if (get_arg0_date(<ime, TIME_FUZZY_DATE)) { /* got NULL, leave the incl_endp intact */ return LONGLONG_MIN; } res=(longlong) calc_daynr(ltime.year,ltime.month,ltime.day); + /* Set to NULL if invalid date, but keep the value */ + null_value= check_date(<ime, + (ltime.year || ltime.month || ltime.day), + (TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE), + &dummy); + if (null_value) + { + /* + Even if the evaluation return NULL, the calc_daynr is useful for pruning + */ + if (args[0]->field_type() != MYSQL_TYPE_DATE) + *incl_endp= TRUE; + return res; + } if (args[0]->field_type() == MYSQL_TYPE_DATE) { diff --git a/sql/opt_range.cc b/sql/opt_range.cc index e3aef02637f..e26d91dcd44 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -5826,6 +5826,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field, { tree= new (alloc) SEL_ARG(field, 0, 0); tree->type= SEL_ARG::IMPOSSIBLE; + field->table->in_use->variables.sql_mode= orig_sql_mode; goto end; } else @@ -5859,7 +5860,10 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field, */ } else + { + field->table->in_use->variables.sql_mode= orig_sql_mode; goto end; + } } } diff --git a/sql/partition_info.h b/sql/partition_info.h index 415f955d5d4..8832b6ee409 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -300,6 +300,7 @@ static inline void init_single_partition_iterator(uint32 part_id, { part_iter->part_nums.start= part_iter->part_nums.cur= part_id; part_iter->part_nums.end= part_id+1; + part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE; part_iter->get_next= get_next_partition_id_range; } diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 61766e5c509..ad24af12087 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -2766,8 +2766,24 @@ uint32 get_list_array_idx_for_endpoint(partition_info *part_info, if (part_info->part_expr->null_value) { - DBUG_RETURN(0); + /* + Special handling for MONOTONIC functions that can return NULL for + values that are comparable. I.e. + '2000-00-00' can be compared to '2000-01-01' but TO_DAYS('2000-00-00') + returns NULL which cannot be compared used <, >, <=, >= etc. + + Otherwise, just return the the first index (lowest value). + */ + enum_monotonicity_info monotonic; + monotonic= part_info->part_expr->get_monotonicity_info(); + if (monotonic != MONOTONIC_INCREASING_NOT_NULL && + monotonic != MONOTONIC_STRICT_INCREASING_NOT_NULL) + { + /* F(col) can not return NULL, return index with lowest value */ + DBUG_RETURN(0); + } } + if (unsigned_flag) part_func_value-= 0x8000000000000000ULL; DBUG_ASSERT(part_info->no_list_values); @@ -2916,11 +2932,29 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info, if (part_info->part_expr->null_value) { - uint32 ret_part_id= 0; - if (!left_endpoint && include_endpoint) - ret_part_id= 1; - DBUG_RETURN(ret_part_id); + /* + Special handling for MONOTONIC functions that can return NULL for + values that are comparable. I.e. + '2000-00-00' can be compared to '2000-01-01' but TO_DAYS('2000-00-00') + returns NULL which cannot be compared used <, >, <=, >= etc. + + Otherwise, just return the first partition + (may be included if not left endpoint) + */ + enum_monotonicity_info monotonic; + monotonic= part_info->part_expr->get_monotonicity_info(); + if (monotonic != MONOTONIC_INCREASING_NOT_NULL && + monotonic != MONOTONIC_STRICT_INCREASING_NOT_NULL) + { + /* F(col) can not return NULL, return partition with lowest value */ + if (!left_endpoint && include_endpoint) + DBUG_RETURN(1); + DBUG_RETURN(0); + + } } + + if (unsigned_flag) part_func_value-= 0x8000000000000000ULL; if (left_endpoint && !include_endpoint) @@ -6733,6 +6767,19 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info, } else assert(0); + + if (part_info->part_type == RANGE_PARTITION || + part_info->has_null_value) + { + enum_monotonicity_info monotonic; + monotonic= part_info->part_expr->get_monotonicity_info(); + if (monotonic == MONOTONIC_INCREASING_NOT_NULL || + monotonic == MONOTONIC_STRICT_INCREASING_NOT_NULL) + { + /* col is NOT NULL, but F(col) can return NULL, add NULL partition */ + part_iter->ret_null_part= part_iter->ret_null_part_orig= TRUE; + } + } /* Find minimum: Do special handling if the interval has left bound in form @@ -6959,7 +7006,13 @@ uint32 get_next_partition_id_range(PARTITION_ITERATOR* part_iter) { if (part_iter->part_nums.cur >= part_iter->part_nums.end) { + if (part_iter->ret_null_part) + { + part_iter->ret_null_part= FALSE; + return 0; /* NULL always in first range partition */ + } part_iter->part_nums.cur= part_iter->part_nums.start; + part_iter->ret_null_part= part_iter->ret_null_part_orig; return NOT_A_PARTITION_ID; } else @@ -6987,7 +7040,7 @@ uint32 get_next_partition_id_range(PARTITION_ITERATOR* part_iter) uint32 get_next_partition_id_list(PARTITION_ITERATOR *part_iter) { - if (part_iter->part_nums.cur == part_iter->part_nums.end) + if (part_iter->part_nums.cur >= part_iter->part_nums.end) { if (part_iter->ret_null_part) { From 6c2b32515e1856b65feedec2ebe47843f416b2ad Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Thu, 27 Aug 2009 00:13:03 +0100 Subject: [PATCH 034/138] BUG#28976 Mixing trans and non-trans tables in one transaction results in incorrect binlog Mixing transactional (T) and non-transactional (N) tables on behalf of a transaction may lead to inconsistencies among masters and slaves in STATEMENT mode. The problem stems from the fact that although modifications done to non-transactional tables on behalf of a transaction become immediately visible to other connections they do not immediately get to the binary log and therefore consistency is broken. Although there may be issues in mixing T and M tables in STATEMENT mode, there are safe combinations that clients find useful. In this bug, we fix the following issue. Mixing N and T tables in multi-level (e.g. a statement that fires a trigger) or multi-table table statements (e.g. update t1, t2...) were not handled correctly. In such cases, it was not possible to distinguish when a T table was updated if the sequence of changes was N and T. In a nutshell, just the flag "modified_non_trans_table" was not enough to reflect that both a N and T tables were changed. To circumvent this issue, we check if an engine is registered in the handler's list and changed something which means that a T table was modified. Check WL 2687 for a full-fledged patch that will make the use of either the MIXED or ROW modes completely safe. mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result: Truncate statement is wrapped in BEGIN/COMMIT. mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result: Truncate statement is wrapped in BEGIN/COMMIT. --- .../extra/rpl_tests/rpl_mixing_engines.test | 727 +++++++++++++++ mysql-test/include/commit.inc | 4 +- mysql-test/r/commit_1innodb.result | 8 +- .../r/binlog_row_mix_innodb_myisam.result | 4 + .../r/binlog_stm_mix_innodb_myisam.result | 6 + .../suite/rpl/r/rpl_innodb_mixed_dml.result | 2 + .../suite/rpl/r/rpl_stm_mixing_engines.result | 871 ++++++++++++++++++ .../suite/rpl/t/rpl_stm_mixing_engines.test | 5 + sql/log.cc | 22 +- 9 files changed, 1642 insertions(+), 7 deletions(-) create mode 100644 mysql-test/extra/rpl_tests/rpl_mixing_engines.test create mode 100644 mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result create mode 100644 mysql-test/suite/rpl/t/rpl_stm_mixing_engines.test diff --git a/mysql-test/extra/rpl_tests/rpl_mixing_engines.test b/mysql-test/extra/rpl_tests/rpl_mixing_engines.test new file mode 100644 index 00000000000..73713b7998b --- /dev/null +++ b/mysql-test/extra/rpl_tests/rpl_mixing_engines.test @@ -0,0 +1,727 @@ +################################################################################### +# This test checks if transactions that mixes transactional and non-transactional +# tables are correctly handled in statement mode. In an nutshell, we have what +# follows: +# +# 1) "B T T C" generates in binlog the "B T T C" entries. +# +# 2) "B T T R" generates in binlog an "empty" entry. +# +# 3) "B T N C" generates in binlog the "B T N C" entries. +# +# 4) "B T N R" generates in binlog the "B T N R" entries. +# +# 5) "T" generates in binlog the "B T C" entry. +# +# 6) "N" generates in binlog the "N" entry. +# +# 7) "M" generates in binglog the "B M C" entries. +# +# 8) "B N N T C" generates in binglog the "N N B T C" entries. +# +# 9) "B N N T R" generates in binlog the "N N B T R" entries. +# +# 10) "B N N C" generates in binglog the "N N" entries. +# +# 11) "B N N R" generates in binlog the "N N" entries. +# +# 12) "B M T C" generates in the binlog the "B M T C" entries. +# +# 13) "B M T R" generates in the binlog the "B M T R" entries. +################################################################################### + +--echo ################################################################################### +--echo # CONFIGURATION +--echo ################################################################################### +connection master; + +SET SQL_LOG_BIN=0; +CREATE TABLE nt_1 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM; +CREATE TABLE nt_2 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM; +CREATE TABLE nt_3 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM; +CREATE TABLE nt_4 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM; +CREATE TABLE tt_1 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb; +CREATE TABLE tt_2 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb; +CREATE TABLE tt_3 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb; +CREATE TABLE tt_4 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb; +SET SQL_LOG_BIN=1; + +connection slave; + +SET SQL_LOG_BIN=0; +CREATE TABLE nt_1 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM; +CREATE TABLE nt_2 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM; +CREATE TABLE nt_3 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM; +CREATE TABLE nt_4 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM; +CREATE TABLE tt_1 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb; +CREATE TABLE tt_2 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb; +CREATE TABLE tt_3 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb; +CREATE TABLE tt_4 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb; +SET SQL_LOG_BIN=1; + +connection master; + +DELIMITER |; + +CREATE FUNCTION f1 () RETURNS VARCHAR(64) +BEGIN + RETURN "Testing..."; +END| + +CREATE FUNCTION f2 () RETURNS VARCHAR(64) +BEGIN + RETURN f1(); +END| + +CREATE PROCEDURE pc_i_tt_3 (IN x INT, IN y VARCHAR(64)) +BEGIN + INSERT INTO tt_3 VALUES (y,x,x); +END| + +CREATE TRIGGER tr_i_tt_3_to_nt_3 BEFORE INSERT ON tt_3 FOR EACH ROW +BEGIN + INSERT INTO nt_3 VALUES (NEW.a, NEW.b, NEW.c); +END| + +CREATE TRIGGER tr_i_nt_4_to_tt_4 BEFORE INSERT ON nt_4 FOR EACH ROW +BEGIN + INSERT INTO tt_4 VALUES (NEW.a, NEW.b, NEW.c); +END| + +DELIMITER ;| + +--echo ################################################################################### +--echo # MIXING TRANSACTIONAL and NON-TRANSACTIONAL TABLES +--echo ################################################################################### +connection master; + +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #1) "B T T C" generates in binlog the "B T T C" entries. +--echo # +BEGIN; +INSERT INTO tt_1 VALUES ("new text 4", 4, "new text 4"); +INSERT INTO tt_2 VALUES ("new text 4", 4, "new text 4"); +COMMIT; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #1.e) "B T T C" with error in T generates in binlog the "B T T C" entries. +--echo # +INSERT INTO tt_1 VALUES ("new text -2", -2, "new text -2"); +BEGIN; +--error ER_DUP_ENTRY +INSERT INTO tt_1 VALUES ("new text -1", -1, "new text -1"), ("new text -2", -2, "new text -2"); +INSERT INTO tt_2 VALUES ("new text -3", -3, "new text -3"); +COMMIT; + +BEGIN; +INSERT INTO tt_2 VALUES ("new text -5", -5, "new text -5"); +--error ER_DUP_ENTRY +INSERT INTO tt_2 VALUES ("new text -4", -4, "new text -4"), ("new text -5", -5, "new text -5"); +COMMIT; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #2) "B T T R" generates in binlog an "empty" entry. +--echo # +BEGIN; +INSERT INTO tt_1 VALUES ("new text 5", 5, "new text 5"); +INSERT INTO tt_2 VALUES ("new text 5", 5, "new text 5"); +ROLLBACK; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #2.e) "B T T R" with error in T generates in binlog an "empty" entry. +--echo # +INSERT INTO tt_1 VALUES ("new text -7", -7, "new text -7"); +BEGIN; +--error ER_DUP_ENTRY +INSERT INTO tt_1 VALUES ("new text -6", -6, "new text -6"), ("new text -7", -7, "new text -7"); +INSERT INTO tt_2 VALUES ("new text -8", -8, "new text -8"); +ROLLBACK; + +BEGIN; +INSERT INTO tt_2 VALUES ("new text -10", -10, "new text -10"); +--error ER_DUP_ENTRY +INSERT INTO tt_2 VALUES ("new text -9", -9, "new text -9"), ("new text -10", -10, "new text -10"); +ROLLBACK; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #3) "B T N C" generates in binlog the "B T N C" entries. +--echo # +BEGIN; +INSERT INTO tt_1 VALUES ("new text 6", 6, "new text 6"); +INSERT INTO nt_1 VALUES ("new text 6", 6, "new text 6"); +COMMIT; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #3.e) "B T N C" with error in either T or N generates in binlog the "B T N C" entries. +--echo # +INSERT INTO tt_1 VALUES ("new text -12", -12, "new text -12"); +BEGIN; +--error ER_DUP_ENTRY +INSERT INTO tt_1 VALUES ("new text -11", -11, "new text -11"), ("new text -12", -12, "new text -12"); +INSERT INTO nt_1 VALUES ("new text -13", -13, "new text -13"); +COMMIT; + +BEGIN; +INSERT INTO tt_1 VALUES ("new text -14", -14, "new text -14"); +INSERT INTO nt_1 VALUES ("new text -16", -16, "new text -16"); +--error ER_DUP_ENTRY +INSERT INTO nt_1 VALUES ("new text -15", -15, "new text -15"), ("new text -16", -16, "new text -16"); +COMMIT; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #4) "B T N R" generates in binlog the "B T N R" entries. +--echo # +BEGIN; +INSERT INTO tt_1 VALUES ("new text 7", 7, "new text 7"); +INSERT INTO nt_1 VALUES ("new text 7", 7, "new text 7"); +ROLLBACK; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #4.e) "B T N R" with error in either T or N generates in binlog the "B T N R" entries. +--echo # +INSERT INTO tt_1 VALUES ("new text -17", -17, "new text -17"); +BEGIN; +--error ER_DUP_ENTRY +INSERT INTO tt_1 VALUES ("new text -16", -16, "new text -16"), ("new text -17", -17, "new text -17"); +INSERT INTO nt_1 VALUES ("new text -18", -18, "new text -18"); +ROLLBACK; + +BEGIN; +INSERT INTO tt_1 VALUES ("new text -19", -19, "new text -19"); +INSERT INTO nt_1 VALUES ("new text -21", -21, "new text -21"); +--error ER_DUP_ENTRY +INSERT INTO nt_1 VALUES ("new text -20", -20, "new text -20"), ("new text -21", -21, "new text -21"); +ROLLBACK; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #5) "T" generates in binlog the "B T C" entry. +--echo # +INSERT INTO tt_1 VALUES ("new text 8", 8, "new text 8"); + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #5.e) "T" with error in T generates in binlog an "empty" entry. +--echo # +INSERT INTO tt_1 VALUES ("new text -1", -1, "new text -1"); +--error ER_DUP_ENTRY +INSERT INTO tt_1 VALUES ("new text -1", -1, "new text -1"), ("new text -22", -22, "new text -22"); +--error ER_DUP_ENTRY +INSERT INTO tt_1 VALUES ("new text -23", -23, "new text -23"), ("new text -1", -1, "new text -1"); + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #6) "N" generates in binlog the "N" entry. +--echo # +INSERT INTO nt_1 VALUES ("new text 9", 9, "new text 9"); + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #6.e) "N" with error in N generates in binlog an empty entry if the error +--echo # happens in the first tuple. Otherwise, generates the "N" entry and +--echo # the error is appended. +--echo # +INSERT INTO nt_1 VALUES ("new text -1", -1, "new text -1"); +--error ER_DUP_ENTRY +INSERT INTO nt_1 VALUES ("new text -1", -1, "new text -1"); +--error ER_DUP_ENTRY +INSERT INTO nt_1 VALUES ("new text -24", -24, "new text -24"), ("new text -1", -1, "new text -1"); + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #7) "M" generates in binglog the "B M C" entries. +--echo # + +DELETE FROM nt_1; + +INSERT INTO nt_1 SELECT * FROM tt_1; + +DELETE FROM tt_1; + +INSERT INTO tt_1 SELECT * FROM nt_1; + +INSERT INTO tt_3 VALUES ("new text 000", 000, ''); + +INSERT INTO tt_3 VALUES("new text 100", 100, f1()); + +INSERT INTO nt_4 VALUES("new text 100", 100, f1()); + +INSERT INTO tt_3 VALUES("new text 200", 200, f2()); + +INSERT INTO nt_4 VALUES ("new text 300", 300, ''); + +INSERT INTO nt_4 VALUES ("new text 400", 400, f1()); + +INSERT INTO nt_4 VALUES ("new text 500", 500, f2()); + +CALL pc_i_tt_3(600, "Testing..."); + +UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a= "new text 1", nt_4.a= "new text 1", tt_3.a= "new text 1", tt_4.a= "new text 1" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; + +UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a= "new text 2", tt_4.a= "new text 2", nt_3.a= "new text 2", nt_4.a = "new text 2" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; + +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 3", nt_3.a= "new text 3", nt_4.a= "new text 3", tt_4.a = "new text 3" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; + +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 4", nt_3.a= "new text 4", nt_4.a= "new text 4", tt_4.a = "new text 4" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #7.e) "M" with error in M generates in binglog the "B M R" entries. +--echo # + +INSERT INTO nt_3 VALUES ("new text -26", -26, ''); +SELECT * FROM tt_3; +--error ER_DUP_ENTRY +INSERT INTO tt_3 VALUES ("new text -25", -25, ''), ("new text -26", -26, ''); +SELECT * FROM tt_3; + +INSERT INTO tt_4 VALUES ("new text -26", -26, ''); +SELECT * FROM nt_4; +--error ER_DUP_ENTRY +INSERT INTO nt_4 VALUES ("new text -25", -25, ''), ("new text -26", -26, ''); +SELECT * FROM nt_4; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #8) "B N N T C" generates in binglog the "N N B T C" entries. +--echo # +BEGIN; +INSERT INTO nt_1 VALUES ("new text 10", 10, "new text 10"); +INSERT INTO nt_2 VALUES ("new text 10", 10, "new text 10"); +INSERT INTO tt_1 VALUES ("new text 10", 10, "new text 10"); +COMMIT; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +--echo # +--echo #8.e) "B N N T R" See 6.e and 9.e. +--echo # + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #9) "B N N T R" generates in binlog the "N N B T R" entries. +--echo # +BEGIN; +INSERT INTO nt_1 VALUES ("new text 11", 11, "new text 11"); +INSERT INTO nt_2 VALUES ("new text 11", 11, "new text 11"); +INSERT INTO tt_1 VALUES ("new text 11", 11, "new text 11"); +ROLLBACK; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #9.e) "B N N T R" with error in N generates in binlog the "N N B T R" entries. +--echo # +BEGIN; +INSERT INTO nt_1 VALUES ("new text -25", -25, "new text -25"); +INSERT INTO nt_2 VALUES ("new text -25", -25, "new text -25"); +--error ER_DUP_ENTRY +INSERT INTO nt_2 VALUES ("new text -26", -26, "new text -26"), ("new text -25", -25, "new text -25"); +INSERT INTO tt_1 VALUES ("new text -27", -27, "new text -27"); +ROLLBACK; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #10) "B N N C" generates in binglog the "N N" entries. +--echo # +BEGIN; +INSERT INTO nt_1 VALUES ("new text 12", 12, "new text 12"); +INSERT INTO nt_2 VALUES ("new text 12", 12, "new text 12"); +COMMIT; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +--echo # +--echo #10.e) "B N N C" See 6.e and 9.e. +--echo # + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #11) "B N N R" generates in binlog the "N N" entries. +--echo # +BEGIN; +INSERT INTO nt_1 VALUES ("new text 13", 13, "new text 13"); +INSERT INTO nt_2 VALUES ("new text 13", 13, "new text 13"); +ROLLBACK; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +--echo # +--echo #11.e) "B N N R" See 6.e and 9.e. +--echo # + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #12) "B M T C" generates in the binlog the "B M T C" entries. +--echo # +DELETE FROM nt_1; +BEGIN; +INSERT INTO nt_1 SELECT * FROM tt_1; +INSERT INTO tt_2 VALUES ("new text 14", 14, "new text 14"); +COMMIT; + +DELETE FROM tt_1; +BEGIN; +INSERT INTO tt_1 SELECT * FROM nt_1; +INSERT INTO tt_2 VALUES ("new text 15", 15, "new text 15"); +COMMIT; + +BEGIN; +INSERT INTO tt_3 VALUES ("new text 700", 700, ''); +INSERT INTO tt_1 VALUES ("new text 800", 800, ''); +COMMIT; + +BEGIN; +INSERT INTO tt_3 VALUES("new text 900", 900, f1()); +INSERT INTO tt_1 VALUES ("new text 1000", 1000, ''); +COMMIT; + +BEGIN; +INSERT INTO tt_3 VALUES(1100, 1100, f2()); +INSERT INTO tt_1 VALUES ("new text 1200", 1200, ''); +COMMIT; + +BEGIN; +INSERT INTO nt_4 VALUES ("new text 1300", 1300, ''); +INSERT INTO tt_1 VALUES ("new text 1400", 1400, ''); +COMMIT; + +BEGIN; +INSERT INTO nt_4 VALUES("new text 1500", 1500, f1()); +INSERT INTO tt_1 VALUES ("new text 1600", 1600, ''); +COMMIT; + +BEGIN; +INSERT INTO nt_4 VALUES("new text 1700", 1700, f2()); +INSERT INTO tt_1 VALUES ("new text 1800", 1800, ''); +COMMIT; + +BEGIN; +CALL pc_i_tt_3(1900, "Testing..."); +INSERT INTO tt_1 VALUES ("new text 2000", 2000, ''); +COMMIT; + +BEGIN; +UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a= "new text 5", nt_4.a= "new text 5", tt_3.a= "new text 5", tt_4.a= "new text 5" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +INSERT INTO tt_1 VALUES ("new text 2100", 2100, ''); +COMMIT; + +BEGIN; +UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a= "new text 6", tt_4.a= "new text 6", nt_3.a= "new text 6", nt_4.a = "new text 6" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +INSERT INTO tt_1 VALUES ("new text 2200", 2200, ''); +COMMIT; + +BEGIN; +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 7", nt_3.a= "new text 7", nt_4.a= "new text 7", tt_4.a = "new text 7" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +INSERT INTO tt_1 VALUES ("new text 2300", 2300, ''); +COMMIT; + +BEGIN; +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 8", nt_3.a= "new text 8", nt_4.a= "new text 8", tt_4.a = "new text 8" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +INSERT INTO tt_1 VALUES ("new text 2400", 2400, ''); +COMMIT; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #12.e) "B M T C" with error in M generates in the binlog the "B M T C" entries. +--echo # + +--echo # There is a bug in the slave that needs to be fixed before enabling +--echo # this part of the test. A bug report will be filed referencing this +--echo # test case. +# +#BEGIN; +#INSERT INTO nt_3 VALUES ("new text -28", -28, ''); +#--error ER_DUP_ENTRY +#INSERT INTO tt_3 VALUES ("new text -27", -27, ''), ("new text -28", -28, ''); +#INSERT INTO tt_1 VALUES ("new text -27", -27, ''); +#COMMIT; +# +#BEGIN; +#INSERT INTO tt_4 VALUES ("new text -28", -28, ''); +#--error ER_DUP_ENTRY +#INSERT INTO nt_4 VALUES ("new text -27", -27, ''), ("new text -28", -28, ''); +#INSERT INTO tt_1 VALUES ("new text -28", -28, ''); +#COMMIT; +# +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #13) "B M T R" generates in the binlog the "B M T R" entries +--echo # + +DELETE FROM nt_1; +BEGIN; +INSERT INTO nt_1 SELECT * FROM tt_1; +INSERT INTO tt_2 VALUES ("new text 17", 17, "new text 17"); +ROLLBACK; + +DELETE FROM tt_1; +BEGIN; +INSERT INTO tt_1 SELECT * FROM nt_1; +INSERT INTO tt_2 VALUES ("new text 18", 18, "new text 18"); +ROLLBACK; +INSERT INTO tt_1 SELECT * FROM nt_1; + +BEGIN; +INSERT INTO tt_3 VALUES ("new text 2500", 2500, ''); +INSERT INTO tt_1 VALUES ("new text 2600", 2600, ''); +ROLLBACK; + +BEGIN; +INSERT INTO tt_3 VALUES("new text 2700", 2700, f1()); +INSERT INTO tt_1 VALUES ("new text 2800", 2800, ''); +ROLLBACK; + +BEGIN; +INSERT INTO tt_3 VALUES(2900, 2900, f2()); +INSERT INTO tt_1 VALUES ("new text 3000", 3000, ''); +ROLLBACK; + +BEGIN; +INSERT INTO nt_4 VALUES ("new text 3100", 3100, ''); +INSERT INTO tt_1 VALUES ("new text 3200", 3200, ''); +ROLLBACK; + +BEGIN; +INSERT INTO nt_4 VALUES("new text 3300", 3300, f1()); +INSERT INTO tt_1 VALUES ("new text 3400", 3400, ''); +ROLLBACK; + +BEGIN; +INSERT INTO nt_4 VALUES("new text 3500", 3500, f2()); +INSERT INTO tt_1 VALUES ("new text 3600", 3600, ''); +ROLLBACK; + +BEGIN; +CALL pc_i_tt_3(3700, "Testing..."); +INSERT INTO tt_1 VALUES ("new text 3700", 3700, ''); +ROLLBACK; + +BEGIN; +UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a= "new text 9", nt_4.a= "new text 9", tt_3.a= "new text 9", tt_4.a= "new text 9" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +INSERT INTO tt_1 VALUES ("new text 3800", 3800, ''); +ROLLBACK; + +BEGIN; +UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a= "new text 10", tt_4.a= "new text 10", nt_3.a= "new text 10", nt_4.a = "new text 10" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +INSERT INTO tt_1 VALUES ("new text 3900", 3900, ''); +ROLLBACK; + +BEGIN; +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 11", nt_3.a= "new text 11", nt_4.a= "new text 11", tt_4.a = "new text 11" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +INSERT INTO tt_1 VALUES ("new text 4000", 4000, ''); +ROLLBACK; + +BEGIN; +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 12", nt_3.a= "new text 12", nt_4.a= "new text 12", tt_4.a = "new text 12" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +INSERT INTO tt_1 VALUES ("new text 4100", 4100, ''); +ROLLBACK; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #13.e) "B M T R" with error in M generates in the binlog the "B M T R" entries. +--echo # + +BEGIN; +INSERT INTO nt_3 VALUES ("new text -30", -30, ''); +--error ER_DUP_ENTRY +INSERT INTO tt_3 VALUES ("new text -29", -29, ''), ("new text -30", -30, ''); +INSERT INTO tt_1 VALUES ("new text -30", -30, ''); +ROLLBACK; + +BEGIN; +INSERT INTO tt_4 VALUES ("new text -30", -30, ''); +--error ER_DUP_ENTRY +INSERT INTO nt_4 VALUES ("new text -29", -29, ''), ("new text -30", -30, ''); +INSERT INTO tt_1 VALUES ("new text -31", -31, ''); +ROLLBACK; + +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +--echo # +--echo #14) "B M T R" with error in M generates in the binlog the "B M T R" entries. +--echo # + +BEGIN; +INSERT INTO tt_4 VALUES ("new text -32", -32, ''); +TRUNCATE TABLE tt_4; +INSERT INTO tt_4 VALUES ("new text -33", -33, ''); +ROLLBACK; + +--source include/show_binlog_events.inc + +connection master; +sync_slave_with_master; + +--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-master.sql +--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-slave.sql +--diff_files $MYSQLTEST_VARDIR/tmp/test-master.sql $MYSQLTEST_VARDIR/tmp/test-slave.sql + +--echo ################################################################################### +--echo # CLEAN +--echo ################################################################################### + +connection master; +DROP TABLE tt_1; +DROP TABLE tt_2; +DROP TABLE tt_3; +DROP TABLE tt_4; +DROP TABLE nt_1; +DROP TABLE nt_2; +DROP TABLE nt_3; +DROP TABLE nt_4; +DROP PROCEDURE pc_i_tt_3; +DROP FUNCTION f1; +DROP FUNCTION f2; + +sync_slave_with_master; diff --git a/mysql-test/include/commit.inc b/mysql-test/include/commit.inc index d412eae8364..d91ba8291fd 100644 --- a/mysql-test/include/commit.inc +++ b/mysql-test/include/commit.inc @@ -725,9 +725,9 @@ call p_verify_status_increment(4, 4, 4, 4); alter table t3 add column (b int); call p_verify_status_increment(2, 0, 2, 0); alter table t3 rename t4; -call p_verify_status_increment(1, 0, 1, 0); +call p_verify_status_increment(2, 2, 2, 2); rename table t4 to t3; -call p_verify_status_increment(1, 0, 1, 0); +call p_verify_status_increment(2, 2, 2, 2); truncate table t3; call p_verify_status_increment(4, 4, 4, 4); create view v1 as select * from t2; diff --git a/mysql-test/r/commit_1innodb.result b/mysql-test/r/commit_1innodb.result index cabd4c29c1d..51c4ac3002c 100644 --- a/mysql-test/r/commit_1innodb.result +++ b/mysql-test/r/commit_1innodb.result @@ -841,17 +841,17 @@ call p_verify_status_increment(2, 0, 2, 0); SUCCESS alter table t3 rename t4; -call p_verify_status_increment(1, 0, 1, 0); +call p_verify_status_increment(2, 2, 2, 2); SUCCESS rename table t4 to t3; -call p_verify_status_increment(1, 0, 1, 0); +call p_verify_status_increment(2, 2, 2, 2); SUCCESS truncate table t3; call p_verify_status_increment(4, 4, 4, 4); -ERROR -Expected commit increment: 4 actual: 2 +SUCCESS + create view v1 as select * from t2; call p_verify_status_increment(1, 0, 1, 0); SUCCESS diff --git a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result index 4d639c3da68..9ae5121f618 100644 --- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result @@ -379,7 +379,9 @@ master-bin.000001 # Query # # BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; TRUNCATE table t2 +master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F @@ -838,8 +840,10 @@ UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */; ERROR 23000: Duplicate entry '2' for key 'PRIMARY' show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN master-bin.000001 # Intvar # # INSERT_ID=6 master-bin.000001 # Query # # use `test`; UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */ +master-bin.000001 # Query # # ROLLBACK select count(*) from t1 /* must be 4 */; count(*) 4 diff --git a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result index 95773a247b9..1ded5c8b622 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result @@ -346,7 +346,9 @@ master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (3,3) master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t2 master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (a int, b int, primary key (a)) engine=innodb master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (4,4) +master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; TRUNCATE table t2 +master-bin.000001 # Xid # # COMMIT /* XID */ master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (5,5) master-bin.000001 # Query # # use `test`; DROP TABLE t2 master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (6,6) @@ -545,8 +547,10 @@ UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */; ERROR 23000: Duplicate entry '2' for key 'PRIMARY' show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN master-bin.000001 # Intvar # # INSERT_ID=6 master-bin.000001 # Query # # use `test`; UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */ +master-bin.000001 # Query # # ROLLBACK /* the output must denote there is the query */; select count(*) from t1 /* must be 4 */; count(*) @@ -782,8 +786,10 @@ UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */; ERROR 23000: Duplicate entry '2' for key 'PRIMARY' show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN master-bin.000001 # Intvar # # INSERT_ID=6 master-bin.000001 # Query # # use `test`; UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */ +master-bin.000001 # Query # # ROLLBACK select count(*) from t1 /* must be 4 */; count(*) 4 diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result index 033f71c16b7..6c5ab43da5f 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result @@ -963,7 +963,9 @@ master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 't1, text 1') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Query 1 # use `test_rpl`; TRUNCATE t1 +master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Xid 1 # # diff --git a/mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result b/mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result new file mode 100644 index 00000000000..f8510b3a85e --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result @@ -0,0 +1,871 @@ +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; +################################################################################### +# CONFIGURATION +################################################################################### +SET SQL_LOG_BIN=0; +CREATE TABLE nt_1 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM; +CREATE TABLE nt_2 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM; +CREATE TABLE nt_3 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM; +CREATE TABLE nt_4 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM; +CREATE TABLE tt_1 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb; +CREATE TABLE tt_2 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb; +CREATE TABLE tt_3 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb; +CREATE TABLE tt_4 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb; +SET SQL_LOG_BIN=1; +SET SQL_LOG_BIN=0; +CREATE TABLE nt_1 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM; +CREATE TABLE nt_2 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM; +CREATE TABLE nt_3 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM; +CREATE TABLE nt_4 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM; +CREATE TABLE tt_1 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb; +CREATE TABLE tt_2 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb; +CREATE TABLE tt_3 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb; +CREATE TABLE tt_4 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb; +SET SQL_LOG_BIN=1; +CREATE FUNCTION f1 () RETURNS VARCHAR(64) +BEGIN +RETURN "Testing..."; +END| +CREATE FUNCTION f2 () RETURNS VARCHAR(64) +BEGIN +RETURN f1(); +END| +CREATE PROCEDURE pc_i_tt_3 (IN x INT, IN y VARCHAR(64)) +BEGIN +INSERT INTO tt_3 VALUES (y,x,x); +END| +CREATE TRIGGER tr_i_tt_3_to_nt_3 BEFORE INSERT ON tt_3 FOR EACH ROW +BEGIN +INSERT INTO nt_3 VALUES (NEW.a, NEW.b, NEW.c); +END| +CREATE TRIGGER tr_i_nt_4_to_tt_4 BEFORE INSERT ON nt_4 FOR EACH ROW +BEGIN +INSERT INTO tt_4 VALUES (NEW.a, NEW.b, NEW.c); +END| +################################################################################### +# MIXING TRANSACTIONAL and NON-TRANSACTIONAL TABLES +################################################################################### +# +#1) "B T T C" generates in binlog the "B T T C" entries. +# +BEGIN; +INSERT INTO tt_1 VALUES ("new text 4", 4, "new text 4"); +INSERT INTO tt_2 VALUES ("new text 4", 4, "new text 4"); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 4", 4, "new text 4") +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 4", 4, "new text 4") +master-bin.000001 # Xid # # COMMIT /* XID */ + + + + +# +#1.e) "B T T C" with error in T generates in binlog the "B T T C" entries. +# +INSERT INTO tt_1 VALUES ("new text -2", -2, "new text -2"); +BEGIN; +INSERT INTO tt_1 VALUES ("new text -1", -1, "new text -1"), ("new text -2", -2, "new text -2"); +ERROR 23000: Duplicate entry '-2' for key 'PRIMARY' +INSERT INTO tt_2 VALUES ("new text -3", -3, "new text -3"); +COMMIT; +BEGIN; +INSERT INTO tt_2 VALUES ("new text -5", -5, "new text -5"); +INSERT INTO tt_2 VALUES ("new text -4", -4, "new text -4"), ("new text -5", -5, "new text -5"); +ERROR 23000: Duplicate entry '-5' for key 'PRIMARY' +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text -2", -2, "new text -2") +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text -3", -3, "new text -3") +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text -5", -5, "new text -5") +master-bin.000001 # Xid # # COMMIT /* XID */ + + + + +# +#2) "B T T R" generates in binlog an "empty" entry. +# +BEGIN; +INSERT INTO tt_1 VALUES ("new text 5", 5, "new text 5"); +INSERT INTO tt_2 VALUES ("new text 5", 5, "new text 5"); +ROLLBACK; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info + + + + +# +#2.e) "B T T R" with error in T generates in binlog an "empty" entry. +# +INSERT INTO tt_1 VALUES ("new text -7", -7, "new text -7"); +BEGIN; +INSERT INTO tt_1 VALUES ("new text -6", -6, "new text -6"), ("new text -7", -7, "new text -7"); +ERROR 23000: Duplicate entry '-7' for key 'PRIMARY' +INSERT INTO tt_2 VALUES ("new text -8", -8, "new text -8"); +ROLLBACK; +BEGIN; +INSERT INTO tt_2 VALUES ("new text -10", -10, "new text -10"); +INSERT INTO tt_2 VALUES ("new text -9", -9, "new text -9"), ("new text -10", -10, "new text -10"); +ERROR 23000: Duplicate entry '-10' for key 'PRIMARY' +ROLLBACK; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text -7", -7, "new text -7") +master-bin.000001 # Xid # # COMMIT /* XID */ + + + + +# +#3) "B T N C" generates in binlog the "B T N C" entries. +# +BEGIN; +INSERT INTO tt_1 VALUES ("new text 6", 6, "new text 6"); +INSERT INTO nt_1 VALUES ("new text 6", 6, "new text 6"); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 6", 6, "new text 6") +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 6", 6, "new text 6") +master-bin.000001 # Xid # # COMMIT /* XID */ + + + + +# +#3.e) "B T N C" with error in either T or N generates in binlog the "B T N C" entries. +# +INSERT INTO tt_1 VALUES ("new text -12", -12, "new text -12"); +BEGIN; +INSERT INTO tt_1 VALUES ("new text -11", -11, "new text -11"), ("new text -12", -12, "new text -12"); +ERROR 23000: Duplicate entry '-12' for key 'PRIMARY' +INSERT INTO nt_1 VALUES ("new text -13", -13, "new text -13"); +COMMIT; +BEGIN; +INSERT INTO tt_1 VALUES ("new text -14", -14, "new text -14"); +INSERT INTO nt_1 VALUES ("new text -16", -16, "new text -16"); +INSERT INTO nt_1 VALUES ("new text -15", -15, "new text -15"), ("new text -16", -16, "new text -16"); +ERROR 23000: Duplicate entry '-16' for key 'PRIMARY' +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text -12", -12, "new text -12") +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text -13", -13, "new text -13") +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text -14", -14, "new text -14") +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text -16", -16, "new text -16") +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text -15", -15, "new text -15"), ("new text -16", -16, "new text -16") +master-bin.000001 # Xid # # COMMIT /* XID */ + + + + +# +#4) "B T N R" generates in binlog the "B T N R" entries. +# +BEGIN; +INSERT INTO tt_1 VALUES ("new text 7", 7, "new text 7"); +INSERT INTO nt_1 VALUES ("new text 7", 7, "new text 7"); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 7", 7, "new text 7") +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 7", 7, "new text 7") +master-bin.000001 # Query # # ROLLBACK + + + + +# +#4.e) "B T N R" with error in either T or N generates in binlog the "B T N R" entries. +# +INSERT INTO tt_1 VALUES ("new text -17", -17, "new text -17"); +BEGIN; +INSERT INTO tt_1 VALUES ("new text -16", -16, "new text -16"), ("new text -17", -17, "new text -17"); +ERROR 23000: Duplicate entry '-17' for key 'PRIMARY' +INSERT INTO nt_1 VALUES ("new text -18", -18, "new text -18"); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +BEGIN; +INSERT INTO tt_1 VALUES ("new text -19", -19, "new text -19"); +INSERT INTO nt_1 VALUES ("new text -21", -21, "new text -21"); +INSERT INTO nt_1 VALUES ("new text -20", -20, "new text -20"), ("new text -21", -21, "new text -21"); +ERROR 23000: Duplicate entry '-21' for key 'PRIMARY' +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text -17", -17, "new text -17") +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text -18", -18, "new text -18") +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text -19", -19, "new text -19") +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text -21", -21, "new text -21") +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text -20", -20, "new text -20"), ("new text -21", -21, "new text -21") +master-bin.000001 # Query # # ROLLBACK + + + + +# +#5) "T" generates in binlog the "B T C" entry. +# +INSERT INTO tt_1 VALUES ("new text 8", 8, "new text 8"); +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 8", 8, "new text 8") +master-bin.000001 # Xid # # COMMIT /* XID */ + + + + +# +#5.e) "T" with error in T generates in binlog an "empty" entry. +# +INSERT INTO tt_1 VALUES ("new text -1", -1, "new text -1"); +INSERT INTO tt_1 VALUES ("new text -1", -1, "new text -1"), ("new text -22", -22, "new text -22"); +ERROR 23000: Duplicate entry '-1' for key 'PRIMARY' +INSERT INTO tt_1 VALUES ("new text -23", -23, "new text -23"), ("new text -1", -1, "new text -1"); +ERROR 23000: Duplicate entry '-1' for key 'PRIMARY' +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text -1", -1, "new text -1") +master-bin.000001 # Xid # # COMMIT /* XID */ + + + + +# +#6) "N" generates in binlog the "N" entry. +# +INSERT INTO nt_1 VALUES ("new text 9", 9, "new text 9"); +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 9", 9, "new text 9") + + + + +# +#6.e) "N" with error in N generates in binlog an empty entry if the error +# happens in the first tuple. Otherwise, generates the "N" entry and +# the error is appended. +# +INSERT INTO nt_1 VALUES ("new text -1", -1, "new text -1"); +INSERT INTO nt_1 VALUES ("new text -1", -1, "new text -1"); +ERROR 23000: Duplicate entry '-1' for key 'PRIMARY' +INSERT INTO nt_1 VALUES ("new text -24", -24, "new text -24"), ("new text -1", -1, "new text -1"); +ERROR 23000: Duplicate entry '-1' for key 'PRIMARY' +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text -1", -1, "new text -1") +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text -24", -24, "new text -24"), ("new text -1", -1, "new text -1") + + + + +# +#7) "M" generates in binglog the "B M C" entries. +# +DELETE FROM nt_1; +INSERT INTO nt_1 SELECT * FROM tt_1; +DELETE FROM tt_1; +INSERT INTO tt_1 SELECT * FROM nt_1; +INSERT INTO tt_3 VALUES ("new text 000", 000, ''); +INSERT INTO tt_3 VALUES("new text 100", 100, f1()); +INSERT INTO nt_4 VALUES("new text 100", 100, f1()); +INSERT INTO tt_3 VALUES("new text 200", 200, f2()); +INSERT INTO nt_4 VALUES ("new text 300", 300, ''); +INSERT INTO nt_4 VALUES ("new text 400", 400, f1()); +INSERT INTO nt_4 VALUES ("new text 500", 500, f2()); +CALL pc_i_tt_3(600, "Testing..."); +UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a= "new text 1", nt_4.a= "new text 1", tt_3.a= "new text 1", tt_4.a= "new text 1" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a= "new text 2", tt_4.a= "new text 2", nt_3.a= "new text 2", nt_4.a = "new text 2" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 3", nt_3.a= "new text 3", nt_4.a= "new text 3", tt_4.a = "new text 3" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 4", nt_3.a= "new text 4", nt_4.a= "new text 4", tt_4.a = "new text 4" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; DELETE FROM nt_1 +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 SELECT * FROM tt_1 +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; DELETE FROM tt_1 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 SELECT * FROM nt_1 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES ("new text 000", 000, '') +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES("new text 100", 100, f1()) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES("new text 100", 100, f1()) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES("new text 200", 200, f2()) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text 300", 300, '') +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text 400", 400, f1()) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text 500", 500, f2()) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES ( NAME_CONST('y',_latin1'Testing...' COLLATE 'latin1_swedish_ci'), NAME_CONST('x',600), NAME_CONST('x',600)) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a= "new text 1", nt_4.a= "new text 1", tt_3.a= "new text 1", tt_4.a= "new text 1" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a= "new text 2", tt_4.a= "new text 2", nt_3.a= "new text 2", nt_4.a = "new text 2" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 3", nt_3.a= "new text 3", nt_4.a= "new text 3", tt_4.a = "new text 3" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 4", nt_3.a= "new text 4", nt_4.a= "new text 4", tt_4.a = "new text 4" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100 +master-bin.000001 # Xid # # COMMIT /* XID */ + + + + +# +#7.e) "M" with error in M generates in binglog the "B M R" entries. +# +INSERT INTO nt_3 VALUES ("new text -26", -26, ''); +SELECT * FROM tt_3; +a b c +new text 000 0 +new text 4 100 Testing... +new text 200 200 Testing... +Testing... 600 600 +INSERT INTO tt_3 VALUES ("new text -25", -25, ''), ("new text -26", -26, ''); +ERROR 23000: Duplicate entry '-26' for key 'PRIMARY' +SELECT * FROM tt_3; +a b c +new text 000 0 +new text 4 100 Testing... +new text 200 200 Testing... +Testing... 600 600 +INSERT INTO tt_4 VALUES ("new text -26", -26, ''); +SELECT * FROM nt_4; +a b c +new text 4 100 Testing... +new text 300 300 +new text 400 400 Testing... +new text 500 500 Testing... +INSERT INTO nt_4 VALUES ("new text -25", -25, ''), ("new text -26", -26, ''); +ERROR 23000: Duplicate entry '-26' for key 'PRIMARY' +SELECT * FROM nt_4; +a b c +new text 4 100 Testing... +new text 300 300 +new text 400 400 Testing... +new text 500 500 Testing... +new text -25 -25 +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_3 VALUES ("new text -26", -26, '') +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES ("new text -25", -25, ''), ("new text -26", -26, '') +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_4 VALUES ("new text -26", -26, '') +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text -25", -25, ''), ("new text -26", -26, '') +master-bin.000001 # Query # # ROLLBACK + + + + +# +#8) "B N N T C" generates in binglog the "N N B T C" entries. +# +BEGIN; +INSERT INTO nt_1 VALUES ("new text 10", 10, "new text 10"); +INSERT INTO nt_2 VALUES ("new text 10", 10, "new text 10"); +INSERT INTO tt_1 VALUES ("new text 10", 10, "new text 10"); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 10", 10, "new text 10") +master-bin.000001 # Query # # use `test`; INSERT INTO nt_2 VALUES ("new text 10", 10, "new text 10") +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 10", 10, "new text 10") +master-bin.000001 # Xid # # COMMIT /* XID */ + + + + +# +#8.e) "B N N T R" See 6.e and 9.e. +# + + + + +# +#9) "B N N T R" generates in binlog the "N N B T R" entries. +# +BEGIN; +INSERT INTO nt_1 VALUES ("new text 11", 11, "new text 11"); +INSERT INTO nt_2 VALUES ("new text 11", 11, "new text 11"); +INSERT INTO tt_1 VALUES ("new text 11", 11, "new text 11"); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 11", 11, "new text 11") +master-bin.000001 # Query # # use `test`; INSERT INTO nt_2 VALUES ("new text 11", 11, "new text 11") +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 11", 11, "new text 11") +master-bin.000001 # Query # # ROLLBACK + + + + +# +#9.e) "B N N T R" with error in N generates in binlog the "N N B T R" entries. +# +BEGIN; +INSERT INTO nt_1 VALUES ("new text -25", -25, "new text -25"); +INSERT INTO nt_2 VALUES ("new text -25", -25, "new text -25"); +INSERT INTO nt_2 VALUES ("new text -26", -26, "new text -26"), ("new text -25", -25, "new text -25"); +ERROR 23000: Duplicate entry '-25' for key 'PRIMARY' +INSERT INTO tt_1 VALUES ("new text -27", -27, "new text -27"); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text -25", -25, "new text -25") +master-bin.000001 # Query # # use `test`; INSERT INTO nt_2 VALUES ("new text -25", -25, "new text -25") +master-bin.000001 # Query # # use `test`; INSERT INTO nt_2 VALUES ("new text -26", -26, "new text -26"), ("new text -25", -25, "new text -25") +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text -27", -27, "new text -27") +master-bin.000001 # Query # # ROLLBACK + + + + +# +#10) "B N N C" generates in binglog the "N N" entries. +# +BEGIN; +INSERT INTO nt_1 VALUES ("new text 12", 12, "new text 12"); +INSERT INTO nt_2 VALUES ("new text 12", 12, "new text 12"); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 12", 12, "new text 12") +master-bin.000001 # Query # # use `test`; INSERT INTO nt_2 VALUES ("new text 12", 12, "new text 12") + + + + +# +#10.e) "B N N C" See 6.e and 9.e. +# + + + + +# +#11) "B N N R" generates in binlog the "N N" entries. +# +BEGIN; +INSERT INTO nt_1 VALUES ("new text 13", 13, "new text 13"); +INSERT INTO nt_2 VALUES ("new text 13", 13, "new text 13"); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 13", 13, "new text 13") +master-bin.000001 # Query # # use `test`; INSERT INTO nt_2 VALUES ("new text 13", 13, "new text 13") + + + + +# +#11.e) "B N N R" See 6.e and 9.e. +# + + + + +# +#12) "B M T C" generates in the binlog the "B M T C" entries. +# +DELETE FROM nt_1; +BEGIN; +INSERT INTO nt_1 SELECT * FROM tt_1; +INSERT INTO tt_2 VALUES ("new text 14", 14, "new text 14"); +COMMIT; +DELETE FROM tt_1; +BEGIN; +INSERT INTO tt_1 SELECT * FROM nt_1; +INSERT INTO tt_2 VALUES ("new text 15", 15, "new text 15"); +COMMIT; +BEGIN; +INSERT INTO tt_3 VALUES ("new text 700", 700, ''); +INSERT INTO tt_1 VALUES ("new text 800", 800, ''); +COMMIT; +BEGIN; +INSERT INTO tt_3 VALUES("new text 900", 900, f1()); +INSERT INTO tt_1 VALUES ("new text 1000", 1000, ''); +COMMIT; +BEGIN; +INSERT INTO tt_3 VALUES(1100, 1100, f2()); +INSERT INTO tt_1 VALUES ("new text 1200", 1200, ''); +COMMIT; +BEGIN; +INSERT INTO nt_4 VALUES ("new text 1300", 1300, ''); +INSERT INTO tt_1 VALUES ("new text 1400", 1400, ''); +COMMIT; +BEGIN; +INSERT INTO nt_4 VALUES("new text 1500", 1500, f1()); +INSERT INTO tt_1 VALUES ("new text 1600", 1600, ''); +COMMIT; +BEGIN; +INSERT INTO nt_4 VALUES("new text 1700", 1700, f2()); +INSERT INTO tt_1 VALUES ("new text 1800", 1800, ''); +COMMIT; +BEGIN; +CALL pc_i_tt_3(1900, "Testing..."); +INSERT INTO tt_1 VALUES ("new text 2000", 2000, ''); +COMMIT; +BEGIN; +UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a= "new text 5", nt_4.a= "new text 5", tt_3.a= "new text 5", tt_4.a= "new text 5" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +INSERT INTO tt_1 VALUES ("new text 2100", 2100, ''); +COMMIT; +BEGIN; +UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a= "new text 6", tt_4.a= "new text 6", nt_3.a= "new text 6", nt_4.a = "new text 6" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +INSERT INTO tt_1 VALUES ("new text 2200", 2200, ''); +COMMIT; +BEGIN; +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 7", nt_3.a= "new text 7", nt_4.a= "new text 7", tt_4.a = "new text 7" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +INSERT INTO tt_1 VALUES ("new text 2300", 2300, ''); +COMMIT; +BEGIN; +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 8", nt_3.a= "new text 8", nt_4.a= "new text 8", tt_4.a = "new text 8" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +INSERT INTO tt_1 VALUES ("new text 2400", 2400, ''); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; DELETE FROM nt_1 +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 SELECT * FROM tt_1 +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 14", 14, "new text 14") +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; DELETE FROM tt_1 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 SELECT * FROM nt_1 +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 15", 15, "new text 15") +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES ("new text 700", 700, '') +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 800", 800, '') +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES("new text 900", 900, f1()) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 1000", 1000, '') +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES(1100, 1100, f2()) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 1200", 1200, '') +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text 1300", 1300, '') +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 1400", 1400, '') +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES("new text 1500", 1500, f1()) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 1600", 1600, '') +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES("new text 1700", 1700, f2()) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 1800", 1800, '') +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES ( NAME_CONST('y',_latin1'Testing...' COLLATE 'latin1_swedish_ci'), NAME_CONST('x',1900), NAME_CONST('x',1900)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 2000", 2000, '') +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a= "new text 5", nt_4.a= "new text 5", tt_3.a= "new text 5", tt_4.a= "new text 5" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100 +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 2100", 2100, '') +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a= "new text 6", tt_4.a= "new text 6", nt_3.a= "new text 6", nt_4.a = "new text 6" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100 +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 2200", 2200, '') +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 7", nt_3.a= "new text 7", nt_4.a= "new text 7", tt_4.a = "new text 7" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100 +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 2300", 2300, '') +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 8", nt_3.a= "new text 8", nt_4.a= "new text 8", tt_4.a = "new text 8" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100 +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 2400", 2400, '') +master-bin.000001 # Xid # # COMMIT /* XID */ + + + + +# +#12.e) "B M T C" with error in M generates in the binlog the "B M T C" entries. +# +# There is a bug in the slave that needs to be fixed before enabling +# this part of the test. A bug report will be filed referencing this +# test case. +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info + + + + +# +#13) "B M T R" generates in the binlog the "B M T R" entries +# +DELETE FROM nt_1; +BEGIN; +INSERT INTO nt_1 SELECT * FROM tt_1; +INSERT INTO tt_2 VALUES ("new text 17", 17, "new text 17"); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +DELETE FROM tt_1; +BEGIN; +INSERT INTO tt_1 SELECT * FROM nt_1; +INSERT INTO tt_2 VALUES ("new text 18", 18, "new text 18"); +ROLLBACK; +INSERT INTO tt_1 SELECT * FROM nt_1; +BEGIN; +INSERT INTO tt_3 VALUES ("new text 2500", 2500, ''); +INSERT INTO tt_1 VALUES ("new text 2600", 2600, ''); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +BEGIN; +INSERT INTO tt_3 VALUES("new text 2700", 2700, f1()); +INSERT INTO tt_1 VALUES ("new text 2800", 2800, ''); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +BEGIN; +INSERT INTO tt_3 VALUES(2900, 2900, f2()); +INSERT INTO tt_1 VALUES ("new text 3000", 3000, ''); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +BEGIN; +INSERT INTO nt_4 VALUES ("new text 3100", 3100, ''); +INSERT INTO tt_1 VALUES ("new text 3200", 3200, ''); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +BEGIN; +INSERT INTO nt_4 VALUES("new text 3300", 3300, f1()); +INSERT INTO tt_1 VALUES ("new text 3400", 3400, ''); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +BEGIN; +INSERT INTO nt_4 VALUES("new text 3500", 3500, f2()); +INSERT INTO tt_1 VALUES ("new text 3600", 3600, ''); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +BEGIN; +CALL pc_i_tt_3(3700, "Testing..."); +INSERT INTO tt_1 VALUES ("new text 3700", 3700, ''); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +BEGIN; +UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a= "new text 9", nt_4.a= "new text 9", tt_3.a= "new text 9", tt_4.a= "new text 9" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +INSERT INTO tt_1 VALUES ("new text 3800", 3800, ''); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +BEGIN; +UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a= "new text 10", tt_4.a= "new text 10", nt_3.a= "new text 10", nt_4.a = "new text 10" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +INSERT INTO tt_1 VALUES ("new text 3900", 3900, ''); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +BEGIN; +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 11", nt_3.a= "new text 11", nt_4.a= "new text 11", tt_4.a = "new text 11" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +INSERT INTO tt_1 VALUES ("new text 4000", 4000, ''); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +BEGIN; +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 12", nt_3.a= "new text 12", nt_4.a= "new text 12", tt_4.a = "new text 12" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100; +INSERT INTO tt_1 VALUES ("new text 4100", 4100, ''); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; DELETE FROM nt_1 +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 SELECT * FROM tt_1 +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 17", 17, "new text 17") +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; DELETE FROM tt_1 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 SELECT * FROM nt_1 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES ("new text 2500", 2500, '') +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 2600", 2600, '') +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES("new text 2700", 2700, f1()) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 2800", 2800, '') +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES(2900, 2900, f2()) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 3000", 3000, '') +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text 3100", 3100, '') +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 3200", 3200, '') +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES("new text 3300", 3300, f1()) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 3400", 3400, '') +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES("new text 3500", 3500, f2()) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 3600", 3600, '') +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES ( NAME_CONST('y',_latin1'Testing...' COLLATE 'latin1_swedish_ci'), NAME_CONST('x',3700), NAME_CONST('x',3700)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 3700", 3700, '') +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a= "new text 9", nt_4.a= "new text 9", tt_3.a= "new text 9", tt_4.a= "new text 9" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100 +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 3800", 3800, '') +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a= "new text 10", tt_4.a= "new text 10", nt_3.a= "new text 10", nt_4.a = "new text 10" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100 +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 3900", 3900, '') +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 11", nt_3.a= "new text 11", nt_4.a= "new text 11", tt_4.a = "new text 11" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100 +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 4000", 4000, '') +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 12", nt_3.a= "new text 12", nt_4.a= "new text 12", tt_4.a = "new text 12" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100 +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 4100", 4100, '') +master-bin.000001 # Query # # ROLLBACK + + + + +# +#13.e) "B M T R" with error in M generates in the binlog the "B M T R" entries. +# +BEGIN; +INSERT INTO nt_3 VALUES ("new text -30", -30, ''); +INSERT INTO tt_3 VALUES ("new text -29", -29, ''), ("new text -30", -30, ''); +ERROR 23000: Duplicate entry '-30' for key 'PRIMARY' +INSERT INTO tt_1 VALUES ("new text -30", -30, ''); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +BEGIN; +INSERT INTO tt_4 VALUES ("new text -30", -30, ''); +INSERT INTO nt_4 VALUES ("new text -29", -29, ''), ("new text -30", -30, ''); +ERROR 23000: Duplicate entry '-30' for key 'PRIMARY' +INSERT INTO tt_1 VALUES ("new text -31", -31, ''); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_3 VALUES ("new text -30", -30, '') +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES ("new text -29", -29, ''), ("new text -30", -30, '') +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text -30", -30, '') +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_4 VALUES ("new text -30", -30, '') +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text -29", -29, ''), ("new text -30", -30, '') +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text -31", -31, '') +master-bin.000001 # Query # # ROLLBACK + + + + +# +#14) "B M T R" with error in M generates in the binlog the "B M T R" entries. +# +BEGIN; +INSERT INTO tt_4 VALUES ("new text -32", -32, ''); +TRUNCATE TABLE tt_4; +INSERT INTO tt_4 VALUES ("new text -33", -33, ''); +ROLLBACK; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_4 VALUES ("new text -32", -32, '') +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_4 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_4 VALUES ("new text -33", -33, '') +master-bin.000001 # Xid # # COMMIT /* XID */ +################################################################################### +# CLEAN +################################################################################### +DROP TABLE tt_1; +DROP TABLE tt_2; +DROP TABLE tt_3; +DROP TABLE tt_4; +DROP TABLE nt_1; +DROP TABLE nt_2; +DROP TABLE nt_3; +DROP TABLE nt_4; +DROP PROCEDURE pc_i_tt_3; +DROP FUNCTION f1; +DROP FUNCTION f2; diff --git a/mysql-test/suite/rpl/t/rpl_stm_mixing_engines.test b/mysql-test/suite/rpl/t/rpl_stm_mixing_engines.test new file mode 100644 index 00000000000..0097fde874a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_stm_mixing_engines.test @@ -0,0 +1,5 @@ +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc +--source include/have_innodb.inc + +--source extra/rpl_tests/rpl_mixing_engines.test diff --git a/sql/log.cc b/sql/log.cc index bb81d0c723e..282312d28e2 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1264,6 +1264,25 @@ int LOGGER::set_handlers(uint error_log_printer, return 0; } +/** + This function checks if a transactional talbe was updated by the + current statement. + + @param thd The client thread that executed the current statement. + @return + @c true if a transactional table was updated, @false otherwise. +*/ +static bool stmt_has_updated_trans_table(THD *thd) +{ + Ha_trx_info *ha_info; + + for (ha_info= thd->transaction.stmt.ha_list; ha_info; ha_info= ha_info->next()) + { + if (ha_info->is_trx_read_write() && ha_info->ht() != binlog_hton) + return (TRUE); + } + return (FALSE); +} /* Save position of binary log transaction cache. @@ -4060,7 +4079,8 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton); IO_CACHE *trans_log= &trx_data->trans_log; my_off_t trans_log_pos= my_b_tell(trans_log); - if (event_info->get_cache_stmt() || trans_log_pos != 0) + if (event_info->get_cache_stmt() || trans_log_pos != 0 || + stmt_has_updated_trans_table(thd)) { DBUG_PRINT("info", ("Using trans_log: cache: %d, trans_log_pos: %lu", event_info->get_cache_stmt(), From 1759f9ecb4a8ba67804410a8902c00ebbe12545a Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Thu, 27 Aug 2009 10:32:27 +0100 Subject: [PATCH 035/138] Post-fix for BUG#28976. Updated main.mysqlbinlog_row_trans's result file as TRUNCATE statements are wrapped in BEGIN...COMMIT. --- mysql-test/r/mysqlbinlog_row_trans.result | 34 ++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/mysqlbinlog_row_trans.result b/mysql-test/r/mysqlbinlog_row_trans.result index d0180e4a7a3..9c3348a9e76 100644 --- a/mysql-test/r/mysqlbinlog_row_trans.result +++ b/mysql-test/r/mysqlbinlog_row_trans.result @@ -215,7 +215,7 @@ COMMIT/*!*/; # at # #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 SET TIMESTAMP=1000000000/*!*/; -TRUNCATE TABLE t1 +BEGIN /*!*/; # at # #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 @@ -223,6 +223,22 @@ SET TIMESTAMP=1000000000/*!*/; TRUNCATE TABLE t1 /*!*/; # at # +#010909 4:46:40 server id 1 end_log_pos # Xid = # +COMMIT/*!*/; +# at # +#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +TRUNCATE TABLE t1 +/*!*/; +# at # +#010909 4:46:40 server id 1 end_log_pos # Xid = # +COMMIT/*!*/; +# at # #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 SET TIMESTAMP=1000000000/*!*/; BEGIN @@ -331,9 +347,17 @@ COMMIT/*!*/; # at # #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; TRUNCATE TABLE t1 /*!*/; # at # +#010909 4:46:40 server id 1 end_log_pos # Xid = # +COMMIT/*!*/; +# at # #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 SET TIMESTAMP=1000000000/*!*/; TRUNCATE TABLE t2 @@ -449,9 +473,17 @@ ROLLBACK # at # #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; TRUNCATE TABLE t1 /*!*/; # at # +#010909 4:46:40 server id 1 end_log_pos # Xid = # +COMMIT/*!*/; +# at # #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 SET TIMESTAMP=1000000000/*!*/; TRUNCATE TABLE t2 From 367c14b854f4afe6cfd41b9f56bf8fbf3c337b65 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 27 Aug 2009 15:22:19 +0500 Subject: [PATCH 036/138] Bug#46184 Crash, SELECT ... FROM derived table procedure analyze The crash happens because select_union object is used as result set for queries which have derived tables. select_union use temporary table as data storage and if fields count exceeds 10(count of values for procedure ANALYSE()) then we get a crash on fill_record() function. mysql-test/r/analyse.result: test result mysql-test/r/subselect.result: result fix mysql-test/t/analyse.test: test case mysql-test/t/subselect.test: test fix sql/sql_yacc.yy: The crash happens because select_union object is used as result set for queries which have derived tables. select_union use temporary table as data storage and if fields count exceeds 10(count of values for procedure ANALYSE()) then we get a crash on fill_record() function. --- mysql-test/r/analyse.result | 9 ++++++--- mysql-test/r/subselect.result | 2 +- mysql-test/t/analyse.test | 10 ++++++++++ mysql-test/t/subselect.test | 2 +- sql/sql_yacc.yy | 3 ++- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/analyse.result b/mysql-test/r/analyse.result index 49722d5b0ab..1e3a2985f74 100644 --- a/mysql-test/r/analyse.result +++ b/mysql-test/r/analyse.result @@ -28,9 +28,7 @@ test.t1.bool N Y 1 1 0 0 1.0000 NULL ENUM('N','Y') NOT NULL test.t1.d 2002-03-03 2002-03-05 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL drop table t1,t2; EXPLAIN SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(); -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used +ERROR HY000: Incorrect usage of PROCEDURE and subquery create table t1 (a int not null); create table t2 select * from t1 where 0=1 procedure analyse(); show create table t2; @@ -153,4 +151,9 @@ select f3 from t1 procedure analyse(1, 1); Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype test.t1.f3 5.99999 9.55555 7 7 0 0 7.77777 1.77778 FLOAT(6,5) NOT NULL drop table t1; +CREATE TABLE t1(a INT,b INT,c INT,d INT,e INT,f INT,g INT,h INT,i INT,j INT,k INT); +INSERT INTO t1 VALUES (); +SELECT * FROM (SELECT * FROM t1) d PROCEDURE ANALYSE(); +ERROR HY000: Incorrect usage of PROCEDURE and subquery +DROP TABLE t1; End of 4.1 tests diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 324a6073426..3f6e82fb57e 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -75,7 +75,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a)); select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1)); ERROR HY000: Incorrect usage of PROCEDURE and subquery SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1)); -ERROR HY000: Incorrect parameters to procedure 'ANALYSE' +ERROR HY000: Incorrect usage of PROCEDURE and subquery SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL; ERROR 42S22: Unknown column 'a' in 'field list' SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL; diff --git a/mysql-test/t/analyse.test b/mysql-test/t/analyse.test index efcf5f6421c..d8466df14bf 100644 --- a/mysql-test/t/analyse.test +++ b/mysql-test/t/analyse.test @@ -14,6 +14,7 @@ create table t2 select * from t1 procedure analyse(); select * from t2; drop table t1,t2; +--error ER_WRONG_USAGE EXPLAIN SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(); # @@ -102,4 +103,13 @@ select f2 from t1 procedure analyse(1, 1); select f3 from t1 procedure analyse(1, 1); drop table t1; +# +# Bug#46184 Crash, SELECT ... FROM derived table procedure analyze +# +CREATE TABLE t1(a INT,b INT,c INT,d INT,e INT,f INT,g INT,h INT,i INT,j INT,k INT); +INSERT INTO t1 VALUES (); +--error ER_WRONG_USAGE +SELECT * FROM (SELECT * FROM t1) d PROCEDURE ANALYSE(); +DROP TABLE t1; + --echo End of 4.1 tests diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 9d4fc9030f2..36a885350f6 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -30,7 +30,7 @@ SELECT 1 IN (SELECT 1); SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a)); -- error ER_WRONG_USAGE select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1)); --- error ER_WRONG_PARAMETERS_TO_PROCEDURE +-- error ER_WRONG_USAGE SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1)); -- error ER_BAD_FIELD_ERROR SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index b38b6e96890..09a0a4b2f12 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7334,7 +7334,8 @@ procedure_clause: MYSQL_YYABORT; } - if (&lex->select_lex != lex->current_select) + if (&lex->select_lex != lex->current_select || + lex->select_lex.get_table_list()->derived) { my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery"); MYSQL_YYABORT; From a22c29d5e49fddf8cf55f3b1bf51e02b03696b7f Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 27 Aug 2009 14:40:42 +0300 Subject: [PATCH 037/138] Bug #46749: Segfault in add_key_fields() with outer subquery level field references This error requires a combination of factors : 1. An "impossible where" in the outermost SELECT 2. An aggregate in the outermost SELECT 3. A correlated subquery with a WHERE clause that includes an outer field reference as a top level WHERE sargable predicate When JOIN::optimize detects an "impossible WHERE" it will bail out without doing the rest of the work and initializations. It will not call make_join_statistics() as well. And make_join_statistics fills in various structures for each table referenced. When processing the result of the "impossible WHERE" the query must send a single row of data if there are aggregate functions in it. In this case the server marks all the aggregates as having received no rows and calls the relevant Item::val_xxx() method on the SELECT list. However if this SELECT list happens to contain a correlated subquery this subquery is evaluated in a normal evaluation mode. And if this correlated subquery has a reference to a field from the outermost "impossible where" SELECT the add_key_fields will mistakenly consider the outer field reference as a "local" field reference when looking for sargable predicates. But since the SELECT where the outer field reference refers to is not completely initialized due to the "impossible WHERE" in this level we'll get a NULL pointer reference. Fixed by making a better condition for discovering if a field is "local" to the SELECT level being processed. It's not enough to look for OUTER_REF_TABLE_BIT in this case since for outer references to constant tables the Item_field::used_tables() will return 0 regardless of whether the field reference is from the local SELECT or not. --- mysql-test/r/subselect.result | 28 ++++++++++++++++++++++++ mysql-test/t/subselect.test | 31 ++++++++++++++++++++++++++ sql/sql_select.cc | 41 +++++++++++++++++++++++++---------- 3 files changed, 88 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 3f6e82fb57e..eacde19ab1c 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4474,4 +4474,32 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY C ALL NULL NULL NULL NULL 20 Using where DROP TABLE C; # End of test for bug#45061. +# +# Bug #46749: Segfault in add_key_fields() with outer subquery level +# field references +# +CREATE TABLE t1 ( +a int, +b int, +UNIQUE (a), KEY (b) +); +INSERT INTO t1 VALUES (1,1), (2,1); +CREATE TABLE st1 like t1; +INSERT INTO st1 VALUES (1,1), (2,1); +CREATE TABLE st2 like t1; +INSERT INTO st2 VALUES (1,1), (2,1); +EXPLAIN +SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b) +FROM t1 +WHERE a = 230; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 DEPENDENT SUBQUERY st1 index NULL a 5 NULL 2 Using index +2 DEPENDENT SUBQUERY st2 index b b 5 NULL 2 Using where; Using index +SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b) +FROM t1 +WHERE a = 230; +MAX(b) (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b) +NULL 0 +DROP TABLE t1, st1, st2; End of 5.0 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 36a885350f6..79918ca78a2 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3450,4 +3450,35 @@ DROP TABLE C; --echo # End of test for bug#45061. +--echo # +--echo # Bug #46749: Segfault in add_key_fields() with outer subquery level +--echo # field references +--echo # + +CREATE TABLE t1 ( + a int, + b int, + UNIQUE (a), KEY (b) +); +INSERT INTO t1 VALUES (1,1), (2,1); + +CREATE TABLE st1 like t1; +INSERT INTO st1 VALUES (1,1), (2,1); + +CREATE TABLE st2 like t1; +INSERT INTO st2 VALUES (1,1), (2,1); + +# should have "impossible where" +EXPLAIN +SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b) +FROM t1 +WHERE a = 230; + +# should not crash +SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b) +FROM t1 +WHERE a = 230; + +DROP TABLE t1, st1, st2; + --echo End of 5.0 tests. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0a5706ee989..ff179c432a8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3207,6 +3207,28 @@ add_key_equal_fields(KEY_FIELD **key_fields, uint and_level, } } + +/** + Check if an expression is a non-outer field. + + Checks if an expression is a field and belongs to the current select. + + @param field Item expression to check + + @return boolean + @retval TRUE the expression is a local field + @retval FALSE it's something else +*/ + +inline static bool +is_local_field (Item *field) +{ + field= field->real_item(); + return field->type() == Item::FIELD_ITEM && + !((Item_field *)field)->depended_from; +} + + static void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, COND *cond, table_map usable_tables, @@ -3282,13 +3304,12 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, { Item **values; // BETWEEN, IN, NE - if (cond_func->key_item()->real_item()->type() == Item::FIELD_ITEM && + if (is_local_field (cond_func->key_item()) && !(cond_func->used_tables() & OUTER_REF_TABLE_BIT)) { values= cond_func->arguments()+1; if (cond_func->functype() == Item_func::NE_FUNC && - cond_func->arguments()[1]->real_item()->type() == Item::FIELD_ITEM && - !(cond_func->arguments()[0]->used_tables() & OUTER_REF_TABLE_BIT)) + is_local_field (cond_func->arguments()[1])) values--; DBUG_ASSERT(cond_func->functype() != Item_func::IN_FUNC || cond_func->argument_count() != 2); @@ -3304,9 +3325,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, for (uint i= 1 ; i < cond_func->argument_count() ; i++) { Item_field *field_item; - if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM - && - !(cond_func->arguments()[i]->used_tables() & OUTER_REF_TABLE_BIT)) + if (is_local_field (cond_func->arguments()[i])) { field_item= (Item_field *) (cond_func->arguments()[i]->real_item()); add_key_equal_fields(key_fields, *and_level, cond_func, @@ -3322,8 +3341,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, bool equal_func=(cond_func->functype() == Item_func::EQ_FUNC || cond_func->functype() == Item_func::EQUAL_FUNC); - if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM && - !(cond_func->arguments()[0]->used_tables() & OUTER_REF_TABLE_BIT)) + if (is_local_field (cond_func->arguments()[0])) { add_key_equal_fields(key_fields, *and_level, cond_func, (Item_field*) (cond_func->arguments()[0])->real_item(), @@ -3331,9 +3349,8 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, cond_func->arguments()+1, 1, usable_tables, sargables); } - if (cond_func->arguments()[1]->real_item()->type() == Item::FIELD_ITEM && - cond_func->functype() != Item_func::LIKE_FUNC && - !(cond_func->arguments()[1]->used_tables() & OUTER_REF_TABLE_BIT)) + if (is_local_field (cond_func->arguments()[1]) && + cond_func->functype() != Item_func::LIKE_FUNC) { add_key_equal_fields(key_fields, *and_level, cond_func, (Item_field*) (cond_func->arguments()[1])->real_item(), @@ -3345,7 +3362,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, } case Item_func::OPTIMIZE_NULL: /* column_name IS [NOT] NULL */ - if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM && + if (is_local_field (cond_func->arguments()[0]) && !(cond_func->used_tables() & OUTER_REF_TABLE_BIT)) { Item *tmp=new Item_null; From 354f5f7bac16a688f8c851cbf866120871713105 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Thu, 27 Aug 2009 13:46:29 +0100 Subject: [PATCH 038/138] BUG#46864 Incorrect update of InnoDB table on slave when using trigger with myisam table Slave does not correctly handle "expected errors" leading to inconsistencies between the mater and slave. Specifically, when a statement changes both transactional and non-transactional tables, the transactional changes are automatically rolled back on the master but the slave ignores the error and does not roll them back thus leading to inconsistencies. To fix the problem, we automatically roll back a statement that fails on the slave but note that the transaction is not rolled back unless a "rollback" command is in the relay log file. mysql-test/extra/rpl_tests/rpl_mixing_engines.test: Enabled item 13.e which was disabled because of the bug fixed by the current and removed item 14 which was introduced by mistake. --- .../extra/rpl_tests/rpl_mixing_engines.test | 47 ++++++------------- .../suite/rpl/r/rpl_stm_mixing_engines.result | 45 +++++++++--------- sql/log_event.cc | 9 ++++ 3 files changed, 46 insertions(+), 55 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_mixing_engines.test b/mysql-test/extra/rpl_tests/rpl_mixing_engines.test index 73713b7998b..cbda85527f1 100644 --- a/mysql-test/extra/rpl_tests/rpl_mixing_engines.test +++ b/mysql-test/extra/rpl_tests/rpl_mixing_engines.test @@ -562,21 +562,21 @@ let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); --echo # There is a bug in the slave that needs to be fixed before enabling --echo # this part of the test. A bug report will be filed referencing this --echo # test case. -# -#BEGIN; -#INSERT INTO nt_3 VALUES ("new text -28", -28, ''); -#--error ER_DUP_ENTRY -#INSERT INTO tt_3 VALUES ("new text -27", -27, ''), ("new text -28", -28, ''); -#INSERT INTO tt_1 VALUES ("new text -27", -27, ''); -#COMMIT; -# -#BEGIN; -#INSERT INTO tt_4 VALUES ("new text -28", -28, ''); -#--error ER_DUP_ENTRY -#INSERT INTO nt_4 VALUES ("new text -27", -27, ''), ("new text -28", -28, ''); -#INSERT INTO tt_1 VALUES ("new text -28", -28, ''); -#COMMIT; -# + +BEGIN; +INSERT INTO nt_3 VALUES ("new text -28", -28, ''); +--error ER_DUP_ENTRY +INSERT INTO tt_3 VALUES ("new text -27", -27, ''), ("new text -28", -28, ''); +INSERT INTO tt_1 VALUES ("new text -27", -27, ''); +COMMIT; + +BEGIN; +INSERT INTO tt_4 VALUES ("new text -28", -28, ''); +--error ER_DUP_ENTRY +INSERT INTO nt_4 VALUES ("new text -27", -27, ''), ("new text -28", -28, ''); +INSERT INTO tt_1 VALUES ("new text -28", -28, ''); +COMMIT; + --source include/show_binlog_events.inc --echo @@ -683,23 +683,6 @@ ROLLBACK; --source include/show_binlog_events.inc ---echo ---echo ---echo ---echo -let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); ---echo # ---echo #14) "B M T R" with error in M generates in the binlog the "B M T R" entries. ---echo # - -BEGIN; -INSERT INTO tt_4 VALUES ("new text -32", -32, ''); -TRUNCATE TABLE tt_4; -INSERT INTO tt_4 VALUES ("new text -33", -33, ''); -ROLLBACK; - ---source include/show_binlog_events.inc - connection master; sync_slave_with_master; diff --git a/mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result b/mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result index f8510b3a85e..03223166f44 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result +++ b/mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result @@ -652,8 +652,30 @@ master-bin.000001 # Xid # # COMMIT /* XID */ # There is a bug in the slave that needs to be fixed before enabling # this part of the test. A bug report will be filed referencing this # test case. +BEGIN; +INSERT INTO nt_3 VALUES ("new text -28", -28, ''); +INSERT INTO tt_3 VALUES ("new text -27", -27, ''), ("new text -28", -28, ''); +ERROR 23000: Duplicate entry '-28' for key 'PRIMARY' +INSERT INTO tt_1 VALUES ("new text -27", -27, ''); +COMMIT; +BEGIN; +INSERT INTO tt_4 VALUES ("new text -28", -28, ''); +INSERT INTO nt_4 VALUES ("new text -27", -27, ''), ("new text -28", -28, ''); +ERROR 23000: Duplicate entry '-28' for key 'PRIMARY' +INSERT INTO tt_1 VALUES ("new text -28", -28, ''); +COMMIT; show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_3 VALUES ("new text -28", -28, '') +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES ("new text -27", -27, ''), ("new text -28", -28, '') +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text -27", -27, '') +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_4 VALUES ("new text -28", -28, '') +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text -27", -27, ''), ("new text -28", -28, '') +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text -28", -28, '') +master-bin.000001 # Xid # # COMMIT /* XID */ @@ -832,29 +854,6 @@ master-bin.000001 # Query # # use `test`; INSERT INTO tt_4 VALUES ("new text -30 master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text -29", -29, ''), ("new text -30", -30, '') master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text -31", -31, '') master-bin.000001 # Query # # ROLLBACK - - - - -# -#14) "B M T R" with error in M generates in the binlog the "B M T R" entries. -# -BEGIN; -INSERT INTO tt_4 VALUES ("new text -32", -32, ''); -TRUNCATE TABLE tt_4; -INSERT INTO tt_4 VALUES ("new text -33", -33, ''); -ROLLBACK; -show binlog events from ; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `test`; INSERT INTO tt_4 VALUES ("new text -32", -32, '') -master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_4 -master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `test`; INSERT INTO tt_4 VALUES ("new text -33", -33, '') -master-bin.000001 # Xid # # COMMIT /* XID */ ################################################################################### # CLEAN ################################################################################### diff --git a/sql/log_event.cc b/sql/log_event.cc index 375f9cf1859..0cda724b698 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3202,6 +3202,15 @@ Default database: '%s'. Query: '%s'", DBUG_PRINT("info",("error ignored")); clear_all_errors(thd, const_cast(rli)); thd->killed= THD::NOT_KILLED; + /* + When an error is expected and matches the actual error the + slave does not report any error and by consequence changes + on transactional tables are not rolled back in the function + close_thread_tables(). For that reason, we explicitly roll + them back here. + */ + if (expected_error && expected_error == actual_error) + ha_autocommit_or_rollback(thd, TRUE); } /* If we expected a non-zero error code and get nothing and, it is a concurrency From 9a8ef8f7a4f3a1bf88be69526763a667843e6870 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 27 Aug 2009 15:17:09 +0200 Subject: [PATCH 039/138] Bug #46322 Sporadic timeout in mysql_upgrade.test Apparently caused by logging to table Turn on logging to file only, add to .opt file for tests needing log to table --- mysql-test/mysql-test-run.pl | 4 ++-- mysql-test/t/events_logs_tests-master.opt | 2 +- mysql-test/t/log_tables-master.opt | 2 +- mysql-test/t/ps-master.opt | 2 +- mysql-test/t/show_check-master.opt | 2 +- mysql-test/t/status-master.opt | 1 + 6 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 mysql-test/t/status-master.opt diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index c15f3990ec4..429fbfe41c6 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -4105,8 +4105,8 @@ sub mysqld_arguments ($$$) { if ( $mysql_version_id >= 50106 ) { - # Turn on logging to both tables and file - mtr_add_arg($args, "--log-output=table,file"); + # Turn on logging to file + mtr_add_arg($args, "--log-output=file"); } # Check if "extra_opt" contains skip-log-bin diff --git a/mysql-test/t/events_logs_tests-master.opt b/mysql-test/t/events_logs_tests-master.opt index 35ff7911705..3ece9710a45 100644 --- a/mysql-test/t/events_logs_tests-master.opt +++ b/mysql-test/t/events_logs_tests-master.opt @@ -1 +1 @@ ---log-slow-queries +--log-output=table,file --log-slow-queries diff --git a/mysql-test/t/log_tables-master.opt b/mysql-test/t/log_tables-master.opt index 35ff7911705..3ece9710a45 100644 --- a/mysql-test/t/log_tables-master.opt +++ b/mysql-test/t/log_tables-master.opt @@ -1 +1 @@ ---log-slow-queries +--log-output=table,file --log-slow-queries diff --git a/mysql-test/t/ps-master.opt b/mysql-test/t/ps-master.opt index 3eb98fc3d6b..31c287d2bb5 100644 --- a/mysql-test/t/ps-master.opt +++ b/mysql-test/t/ps-master.opt @@ -1 +1 @@ ---log-slow-queries --log-long-format --log-queries-not-using-indexes +--log-output=table,file --log-slow-queries --log-long-format --log-queries-not-using-indexes diff --git a/mysql-test/t/show_check-master.opt b/mysql-test/t/show_check-master.opt index 7a438da06cc..aab832e2848 100644 --- a/mysql-test/t/show_check-master.opt +++ b/mysql-test/t/show_check-master.opt @@ -1 +1 @@ ---log-slow-queries --log-long-format --log-queries-not-using-indexes --myisam-recover="" +--log-output=table,file --log-slow-queries --log-long-format --log-queries-not-using-indexes --myisam-recover="" diff --git a/mysql-test/t/status-master.opt b/mysql-test/t/status-master.opt new file mode 100644 index 00000000000..eb3bb4fe50d --- /dev/null +++ b/mysql-test/t/status-master.opt @@ -0,0 +1 @@ +--log-output=table,file From ea06bbd2b0cc4e33b3350ef0bff25b0c1d1c2e95 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Thu, 27 Aug 2009 17:28:09 +0100 Subject: [PATCH 040/138] BUG#46861 Auto-closing of temporary tables broken by replicate-rewrite-db When a connection is dropped any remaining temporary table is also automatically dropped and the SQL statement of this operation is written to the binary log in order to drop such tables on the slave and keep the slave in sync. Specifically, the current code base creates the following type of statement: DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `db`.`table`; Unfortunately, appending the database to the table name in this manner circumvents the replicate-rewrite-db option (and any options that check the current database). To solve the issue, we started writing the statement to the binary as follows: use `db`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `table`; --- mysql-test/r/drop_temp_table.result | 2 +- mysql-test/r/mix_innodb_myisam_binlog.result | 2 +- mysql-test/r/rpl_drop_temp.result | 7 + mysql-test/r/rpl_rewrite_db.result | 127 +++++++++++++++ mysql-test/t/rpl_drop_temp.test | 15 +- mysql-test/t/rpl_rewrite_db-slave.opt | 2 +- mysql-test/t/rpl_rewrite_db.test | 155 +++++++++++++++++++ sql/sql_base.cc | 19 ++- 8 files changed, 315 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/drop_temp_table.result b/mysql-test/r/drop_temp_table.result index 96481341bd6..ff200d09de4 100644 --- a/mysql-test/r/drop_temp_table.result +++ b/mysql-test/r/drop_temp_table.result @@ -18,5 +18,5 @@ master-bin.000001 # Query 1 # create database `drop-temp+table-test` master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table shortn1 (a int) master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table `table:name` (a int) master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table shortn2 (a int) -master-bin.000001 # Query 1 # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `drop-temp+table-test`.`shortn2`,`drop-temp+table-test`.`table:name`,`drop-temp+table-test`.`shortn1` +master-bin.000001 # Query 1 # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `shortn2`,`table:name`,`shortn1` drop database `drop-temp+table-test`; diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result index eda3ff41c89..21bc6501dac 100644 --- a/mysql-test/r/mix_innodb_myisam_binlog.result +++ b/mysql-test/r/mix_innodb_myisam_binlog.result @@ -260,7 +260,7 @@ master-bin.000001 # Query # # use `test`; create table t0 (n int) master-bin.000001 # Query # # use `test`; insert t0 select * from t1 master-bin.000001 # Query # # use `test`; insert into t0 select GET_LOCK("lock1",null) master-bin.000001 # Query # # use `test`; create table t2 (n int) engine=innodb -master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `test`.`t1`,`test`.`ti` +master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t1`,`ti` do release_lock("lock1"); drop table t0,t2; reset master; diff --git a/mysql-test/r/rpl_drop_temp.result b/mysql-test/r/rpl_drop_temp.result index 04fe094ea26..fff179d7056 100644 --- a/mysql-test/r/rpl_drop_temp.result +++ b/mysql-test/r/rpl_drop_temp.result @@ -5,8 +5,15 @@ reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; create database if not exists mysqltest; +use mysqltest; create temporary table mysqltest.t1 (n int); create temporary table mysqltest.t2 (n int); +select get_lock("con_temp",10); +get_lock("con_temp",10) +1 +select get_lock("con_temp",10); +get_lock("con_temp",10) +1 show status like 'Slave_open_temp_tables'; Variable_name Value Slave_open_temp_tables 0 diff --git a/mysql-test/r/rpl_rewrite_db.result b/mysql-test/r/rpl_rewrite_db.result index 1b843bffdca..46e12bc166b 100644 --- a/mysql-test/r/rpl_rewrite_db.result +++ b/mysql-test/r/rpl_rewrite_db.result @@ -90,5 +90,132 @@ a b 2 row 2 3 row 3 0 +set sql_log_bin= 0; drop database rewrite; +set sql_log_bin= 1; +set sql_log_bin= 0; drop table t1; +set sql_log_bin= 1; + +**** +**** Bug #46861 Auto-closing of temporary tables broken by replicate-rewrite-db +**** + +**** +**** Preparing the environment +**** +SET sql_log_bin= 0; +CREATE DATABASE database_master_temp_01; +CREATE DATABASE database_master_temp_02; +CREATE DATABASE database_master_temp_03; +SET sql_log_bin= 1; +SET sql_log_bin= 0; +CREATE DATABASE database_slave_temp_01; +CREATE DATABASE database_slave_temp_02; +CREATE DATABASE database_slave_temp_03; +SET sql_log_bin= 1; + +**** +**** Creating temporary tables on different databases with different connections +**** +**** con_temp_01 --> creates +**** t_01_01_temp on database_master_temp_01 +**** +**** con_temp_02 --> creates +**** t_01_01_temp on database_master_temp_01 +**** t_02_01_temp, t_02_02_temp on database_master_temp_02 +**** +**** con_temp_02 --> creates +**** t_01_01_temp on database_master_temp_01 +**** t_02_01_temp, t_02_02_temp on database_master_temp_02 +**** t_03_01_temp, t_03_02_temp, t_03_03_temp on database_master_temp_03 +**** + +con_temp_01 + +USE database_master_temp_01; +CREATE TEMPORARY TABLE t_01_01_temp(a int); +INSERT INTO t_01_01_temp VALUES(1); + +con_temp_02 + +USE database_master_temp_01; +CREATE TEMPORARY TABLE t_01_01_temp(a int); +INSERT INTO t_01_01_temp VALUES(1); +USE database_master_temp_02; +CREATE TEMPORARY TABLE t_02_01_temp(a int); +INSERT INTO t_02_01_temp VALUES(1); +CREATE TEMPORARY TABLE t_02_02_temp(a int); +INSERT INTO t_02_02_temp VALUES(1); + +con_temp_03 + +USE database_master_temp_01; +CREATE TEMPORARY TABLE t_01_01_temp(a int); +INSERT INTO t_01_01_temp VALUES(1); +USE database_master_temp_02; +CREATE TEMPORARY TABLE t_02_01_temp(a int); +INSERT INTO t_02_01_temp VALUES(1); +CREATE TEMPORARY TABLE t_02_02_temp(a int); +INSERT INTO t_02_02_temp VALUES(1); +USE database_master_temp_03; +CREATE TEMPORARY TABLE t_03_01_temp(a int); +INSERT INTO t_03_01_temp VALUES(1); +CREATE TEMPORARY TABLE t_03_02_temp(a int); +INSERT INTO t_03_02_temp VALUES(1); +CREATE TEMPORARY TABLE t_03_03_temp(a int); +INSERT INTO t_03_03_temp VALUES(1); + +**** Dropping the connections +**** We want to SHOW BINLOG EVENTS, to know what was logged. But there is no +**** guarantee that logging of the terminated con1 has been done yet.a To be +**** sure that logging has been done, we use a user lock. + +show status like 'Slave_open_temp_tables'; +Variable_name Value +Slave_open_temp_tables 10 +select get_lock("con_01",10); +get_lock("con_01",10) +1 +select get_lock("con_01",10); +get_lock("con_01",10) +1 +select get_lock("con_02",10); +get_lock("con_02",10) +1 +select get_lock("con_02",10); +get_lock("con_02",10) +1 +select get_lock("con_03",10); +get_lock("con_03",10) +1 +select get_lock("con_03",10); +get_lock("con_03",10) +1 + +**** Checking the binary log and temporary tables + +show status like 'Slave_open_temp_tables'; +Variable_name Value +Slave_open_temp_tables 0 +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `database_master_temp_01`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t_01_01_temp` +master-bin.000001 # Query # # use `database_master_temp_02`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t_02_02_temp`,`t_02_01_temp` +master-bin.000001 # Query # # use `database_master_temp_01`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t_01_01_temp` +master-bin.000001 # Query # # use `database_master_temp_03`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t_03_03_temp`,`t_03_02_temp`,`t_03_01_temp` +master-bin.000001 # Query # # use `database_master_temp_02`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t_02_02_temp`,`t_02_01_temp` +master-bin.000001 # Query # # use `database_master_temp_01`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t_01_01_temp` +**** +**** Cleaning up the test case +**** +SET sql_log_bin= 0; +DROP DATABASE database_master_temp_01; +DROP DATABASE database_master_temp_02; +DROP DATABASE database_master_temp_03; +SET sql_log_bin= 1; +SET sql_log_bin= 0; +DROP DATABASE database_slave_temp_01; +DROP DATABASE database_slave_temp_02; +DROP DATABASE database_slave_temp_03; +SET sql_log_bin= 1; diff --git a/mysql-test/t/rpl_drop_temp.test b/mysql-test/t/rpl_drop_temp.test index 55a4e741d7c..c22bcbe63d0 100644 --- a/mysql-test/t/rpl_drop_temp.test +++ b/mysql-test/t/rpl_drop_temp.test @@ -3,15 +3,22 @@ source include/master-slave.inc; create database if not exists mysqltest; --enable_warnings +connect (con_temp,127.0.0.1,root,,test,$MASTER_MYPORT,); + +connection con_temp; +use mysqltest; create temporary table mysqltest.t1 (n int); create temporary table mysqltest.t2 (n int); -sync_slave_with_master; +select get_lock("con_temp",10); + connection master; -disconnect master; +disconnect con_temp; +select get_lock("con_temp",10); +sync_slave_with_master; + connection slave; ---real_sleep 3 # time for DROP to be written show status like 'Slave_open_temp_tables'; -connection default; +connection master; drop database mysqltest; # End of 4.1 tests diff --git a/mysql-test/t/rpl_rewrite_db-slave.opt b/mysql-test/t/rpl_rewrite_db-slave.opt index a462ad19ba0..290b92e0a3e 100644 --- a/mysql-test/t/rpl_rewrite_db-slave.opt +++ b/mysql-test/t/rpl_rewrite_db-slave.opt @@ -1 +1 @@ -"--replicate-rewrite-db=test->rewrite" "--replicate-rewrite-db=mysqltest1->test" +"--replicate-rewrite-db=test->rewrite" "--replicate-rewrite-db=mysqltest1->test" "--replicate-rewrite-db=database_master_temp_01->database_slave_temp_01" "--replicate-rewrite-db=database_master_temp_02->database_slave_temp_02" "--replicate-rewrite-db=database_master_temp_03->database_slave_temp_03" diff --git a/mysql-test/t/rpl_rewrite_db.test b/mysql-test/t/rpl_rewrite_db.test index 6b8624aff39..a9742f252be 100644 --- a/mysql-test/t/rpl_rewrite_db.test +++ b/mysql-test/t/rpl_rewrite_db.test @@ -73,9 +73,164 @@ connection slave; # The empty line last comes from the end line field in the file select * from rewrite.t1; +set sql_log_bin= 0; drop database rewrite; +set sql_log_bin= 1; connection master; +set sql_log_bin= 0; drop table t1; +set sql_log_bin= 1; # End of 4.1 tests + +--echo +--echo **** +--echo **** Bug #46861 Auto-closing of temporary tables broken by replicate-rewrite-db +--echo **** +--echo + +--echo **** +--echo **** Preparing the environment +--echo **** +connection master; + +connect (con_temp_03,127.0.0.1,root,,test,$MASTER_MYPORT,); +connect (con_temp_02,127.0.0.1,root,,test,$MASTER_MYPORT,); +connect (con_temp_01,127.0.0.1,root,,test,$MASTER_MYPORT,); + +connection master; +SET sql_log_bin= 0; +CREATE DATABASE database_master_temp_01; +CREATE DATABASE database_master_temp_02; +CREATE DATABASE database_master_temp_03; +SET sql_log_bin= 1; + +connection slave; +SET sql_log_bin= 0; +CREATE DATABASE database_slave_temp_01; +CREATE DATABASE database_slave_temp_02; +CREATE DATABASE database_slave_temp_03; +SET sql_log_bin= 1; + +--echo +--echo **** +--echo **** Creating temporary tables on different databases with different connections +--echo **** +--echo **** con_temp_01 --> creates +--echo **** t_01_01_temp on database_master_temp_01 +--echo **** +--echo **** con_temp_02 --> creates +--echo **** t_01_01_temp on database_master_temp_01 +--echo **** t_02_01_temp, t_02_02_temp on database_master_temp_02 +--echo **** +--echo **** con_temp_02 --> creates +--echo **** t_01_01_temp on database_master_temp_01 +--echo **** t_02_01_temp, t_02_02_temp on database_master_temp_02 +--echo **** t_03_01_temp, t_03_02_temp, t_03_03_temp on database_master_temp_03 +--echo **** + +--echo +--echo con_temp_01 +--echo +connection con_temp_01; +USE database_master_temp_01; +CREATE TEMPORARY TABLE t_01_01_temp(a int); +INSERT INTO t_01_01_temp VALUES(1); + +--echo +--echo con_temp_02 +--echo +connection con_temp_02; +USE database_master_temp_01; +CREATE TEMPORARY TABLE t_01_01_temp(a int); +INSERT INTO t_01_01_temp VALUES(1); +USE database_master_temp_02; +CREATE TEMPORARY TABLE t_02_01_temp(a int); +INSERT INTO t_02_01_temp VALUES(1); +CREATE TEMPORARY TABLE t_02_02_temp(a int); +INSERT INTO t_02_02_temp VALUES(1); + +--echo +--echo con_temp_03 +--echo +connection con_temp_03; +USE database_master_temp_01; +CREATE TEMPORARY TABLE t_01_01_temp(a int); +INSERT INTO t_01_01_temp VALUES(1); +USE database_master_temp_02; +CREATE TEMPORARY TABLE t_02_01_temp(a int); +INSERT INTO t_02_01_temp VALUES(1); +CREATE TEMPORARY TABLE t_02_02_temp(a int); +INSERT INTO t_02_02_temp VALUES(1); +USE database_master_temp_03; +CREATE TEMPORARY TABLE t_03_01_temp(a int); +INSERT INTO t_03_01_temp VALUES(1); +CREATE TEMPORARY TABLE t_03_02_temp(a int); +INSERT INTO t_03_02_temp VALUES(1); +CREATE TEMPORARY TABLE t_03_03_temp(a int); +INSERT INTO t_03_03_temp VALUES(1); + +--echo +--echo **** Dropping the connections +--echo **** We want to SHOW BINLOG EVENTS, to know what was logged. But there is no +--echo **** guarantee that logging of the terminated con1 has been done yet.a To be +--echo **** sure that logging has been done, we use a user lock. +--echo +connection master; +sync_slave_with_master; +connection slave; +show status like 'Slave_open_temp_tables'; + +connection master; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +connection con_temp_01; +select get_lock("con_01",10); +connection master; +disconnect con_temp_01; +select get_lock("con_01",10); + +connection con_temp_02; +select get_lock("con_02",10); +connection master; +disconnect con_temp_02; +select get_lock("con_02",10); + +connection con_temp_03; +select get_lock("con_03",10); +connection master; +disconnect con_temp_03; +select get_lock("con_03",10); + +--echo +--echo **** Checking the binary log and temporary tables +--echo +connection master; +sync_slave_with_master; +connection slave; +show status like 'Slave_open_temp_tables'; + +connection master; +--source include/show_binlog_events.inc + +--echo **** +--echo **** Cleaning up the test case +--echo **** +connection master; +SET sql_log_bin= 0; +DROP DATABASE database_master_temp_01; +DROP DATABASE database_master_temp_02; +DROP DATABASE database_master_temp_03; +SET sql_log_bin= 1; + +connection slave; +SET sql_log_bin= 0; +DROP DATABASE database_slave_temp_01; +DROP DATABASE database_slave_temp_02; +DROP DATABASE database_slave_temp_03; +SET sql_log_bin= 1; + +connection master; +sync_slave_with_master; + +# end of 5.0 tests diff --git a/sql/sql_base.cc b/sql/sql_base.cc index d969c837891..bc9aa50cb82 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -769,19 +769,23 @@ void close_temporary_tables(THD *thd) { /* Set pseudo_thread_id to be that of the processed table */ thd->variables.pseudo_thread_id= tmpkeyval(thd, table); - /* Loop forward through all tables within the sublist of - common pseudo_thread_id to create single DROP query */ + String db; + db.append(table->s->db); + /* Loop forward through all tables that belong to a common database + within the sublist of common pseudo_thread_id to create single + DROP query + */ for (s_query.length(stub_len); table && is_user_table(table) && - tmpkeyval(thd, table) == thd->variables.pseudo_thread_id; + tmpkeyval(thd, table) == thd->variables.pseudo_thread_id && + strlen(table->s->db) == db.length() && + strcmp(table->s->db, db.ptr()) == 0; table= next) { /* - We are going to add 4 ` around the db/table names and possible more - due to special characters in the names + We are going to add ` around the table names and possible more + due to special characters */ - append_identifier(thd, &s_query, table->s->db, strlen(table->s->db)); - s_query.q_append('.'); append_identifier(thd, &s_query, table->s->table_name, strlen(table->s->table_name)); s_query.q_append(','); @@ -794,6 +798,7 @@ void close_temporary_tables(THD *thd) Query_log_event qinfo(thd, s_query.ptr(), s_query.length() - 1 /* to remove trailing ',' */, 0, FALSE); + qinfo.db= db.ptr(); thd->variables.character_set_client= cs_save; /* Imagine the thread had created a temp table, then was doing a SELECT, and From de5ab42de65abb375a9c6cebdc2e490340816b96 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Fri, 28 Aug 2009 15:02:48 +0200 Subject: [PATCH 041/138] Bug #46973 MTR: extract_warning_lines does not check it's extracting lines for current test Rewrote logic (first commit was incomplete, sorry) --- mysql-test/mysql-test-run.pl | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 429fbfe41c6..5a5d063c105 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3571,8 +3571,8 @@ sub run_testcase ($) { # error log and write all lines that look # suspicious into $error_log.warnings # -sub extract_warning_lines ($) { - my ($error_log) = @_; +sub extract_warning_lines ($$) { + my ($error_log, $tname) = @_; # Open the servers .err log file and read all lines # belonging to current tets into @lines @@ -3580,14 +3580,27 @@ sub extract_warning_lines ($) { or mtr_error("Could not open file '$error_log' for reading: $!"); my @lines; + my $found_test= 0; # Set once we've found the log of this test while ( my $line = <$Ferr> ) { - if ( $line =~ /^CURRENT_TEST:/ ) + if ($found_test) { - # Throw away lines from previous tests - @lines = (); + # If test wasn't last after all, discard what we found, test again. + if ( $line =~ /^CURRENT_TEST:/) + { + @lines= (); + $found_test= $line =~ /^CURRENT_TEST: $tname/; + } + else + { + push(@lines, $line); + } + } + else + { + # Search for beginning of test, until found + $found_test= 1 if ($line =~ /^CURRENT_TEST: $tname/); } - push(@lines, $line); } $Ferr = undef; # Close error log file @@ -3665,7 +3678,7 @@ sub start_check_warnings ($$) { my $log_error= $mysqld->value('#log-error'); # To be communicated to the test $ENV{MTR_LOG_ERROR}= $log_error; - extract_warning_lines($log_error); + extract_warning_lines($log_error, $tinfo->{name}); my $args; mtr_init_args(\$args); From fa4f05139d0de6dc827cb72dd62a615e9365bc94 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Fri, 28 Aug 2009 16:13:27 +0200 Subject: [PATCH 042/138] Bug #42408 Faulty regex for detecting [Warning] and [ERROR] in mysqld error log Some follow-up test fixes after seeing effect in PB2 --- mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test | 2 ++ mysql-test/r/lowercase_table3.result | 2 +- mysql-test/suite/rpl/r/rpl_bug33931.result | 2 +- mysql-test/suite/rpl/r/rpl_extraCol_innodb.result | 1 + mysql-test/suite/rpl/r/rpl_extraCol_myisam.result | 1 + mysql-test/suite/rpl/r/rpl_init_slave_errors.result | 1 + mysql-test/suite/rpl/t/rpl_bug33931.test | 2 +- mysql-test/suite/rpl/t/rpl_init_slave_errors.test | 1 + mysql-test/t/lowercase_table3.test | 2 +- 9 files changed, 10 insertions(+), 4 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test b/mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test index 6890913b7d1..a7b02065144 100644 --- a/mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test +++ b/mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test @@ -22,6 +22,8 @@ DROP TABLE IF EXISTS t1, t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t14a,t15,t1 # should stop the slave. # ################################################# +call mtr.add_suppression("Slave: Unknown table 't6' Error_code: 1051"); + --echo **** Diff Table Def Start **** ############################################## diff --git a/mysql-test/r/lowercase_table3.result b/mysql-test/r/lowercase_table3.result index 1ef7d04bb1d..22e80aaeb26 100644 --- a/mysql-test/r/lowercase_table3.result +++ b/mysql-test/r/lowercase_table3.result @@ -1,4 +1,4 @@ -call mtr.add_suppression("Cannot find or open table test/BUG29839 from .*"); +call mtr.add_suppression("Cannot find or open table test/BUG29839 from"); DROP TABLE IF EXISTS t1,T1; CREATE TABLE t1 (a INT); SELECT * FROM T1; diff --git a/mysql-test/suite/rpl/r/rpl_bug33931.result b/mysql-test/suite/rpl/r/rpl_bug33931.result index 85c8fb0da9c..a17941f6ba9 100644 --- a/mysql-test/suite/rpl/r/rpl_bug33931.result +++ b/mysql-test/suite/rpl/r/rpl_bug33931.result @@ -1,5 +1,5 @@ reset master; -call mtr.add_suppression("Failed during slave thread initialization"); +call mtr.add_suppression("Failed during slave I/O thread initialization"); stop slave; reset slave; SET GLOBAL debug="d,simulate_io_slave_error_on_init,simulate_sql_slave_error_on_init"; diff --git a/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result b/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result index e57daad3342..e2ec78e7adc 100644 --- a/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result @@ -4,6 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +call mtr.add_suppression("Slave: Unknown table 't6' Error_code: 1051"); **** Diff Table Def Start **** *** On Slave *** STOP SLAVE; diff --git a/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result b/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result index 6696ddc7789..ed5b4eac27d 100644 --- a/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result +++ b/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result @@ -4,6 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +call mtr.add_suppression("Slave: Unknown table 't6' Error_code: 1051"); **** Diff Table Def Start **** *** On Slave *** STOP SLAVE; diff --git a/mysql-test/suite/rpl/r/rpl_init_slave_errors.result b/mysql-test/suite/rpl/r/rpl_init_slave_errors.result index ab957e6d9bc..c6ee82b13f3 100644 --- a/mysql-test/suite/rpl/r/rpl_init_slave_errors.result +++ b/mysql-test/suite/rpl/r/rpl_init_slave_errors.result @@ -9,6 +9,7 @@ reset slave; SET GLOBAL debug= "d,simulate_io_slave_error_on_init,simulate_sql_slave_error_on_init"; start slave; Reporting the following error: Failed during slave thread initialization +call mtr.add_suppression("Failed during slave I/O thread initialization"); SET GLOBAL debug= ""; stop slave; reset slave; diff --git a/mysql-test/suite/rpl/t/rpl_bug33931.test b/mysql-test/suite/rpl/t/rpl_bug33931.test index 13f781c644b..1316ddb7401 100644 --- a/mysql-test/suite/rpl/t/rpl_bug33931.test +++ b/mysql-test/suite/rpl/t/rpl_bug33931.test @@ -15,7 +15,7 @@ reset master; connection slave; # Add suppression for expected warnings in slaves error log -call mtr.add_suppression("Failed during slave thread initialization"); +call mtr.add_suppression("Failed during slave I/O thread initialization"); --disable_warnings stop slave; diff --git a/mysql-test/suite/rpl/t/rpl_init_slave_errors.test b/mysql-test/suite/rpl/t/rpl_init_slave_errors.test index 4ca0de6ec66..180821730ec 100644 --- a/mysql-test/suite/rpl/t/rpl_init_slave_errors.test +++ b/mysql-test/suite/rpl/t/rpl_init_slave_errors.test @@ -57,6 +57,7 @@ source include/wait_for_slave_to_stop.inc; let $error= query_get_value(SHOW SLAVE STATUS, Last_Error, 1); echo Reporting the following error: $error; +call mtr.add_suppression("Failed during slave I/O thread initialization"); SET GLOBAL debug= ""; diff --git a/mysql-test/t/lowercase_table3.test b/mysql-test/t/lowercase_table3.test index 4748953fe95..f7ca8211288 100644 --- a/mysql-test/t/lowercase_table3.test +++ b/mysql-test/t/lowercase_table3.test @@ -9,7 +9,7 @@ --source include/have_case_insensitive_file_system.inc --source include/not_windows.inc -call mtr.add_suppression("Cannot find or open table test/BUG29839 from .*"); +call mtr.add_suppression("Cannot find or open table test/BUG29839 from"); --disable_warnings DROP TABLE IF EXISTS t1,T1; From 169f7da04c4ffc43355d5a632a8013bc4caea39b Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 28 Aug 2009 12:06:59 -0300 Subject: [PATCH 043/138] Fix for a few assorted compiler warnings. client/mysql.cc: Remove leading whitespace. Remove extra text after #else directive. client/mysqldump.c: Function does not take a parameter. mysys/array.c: buffer is a uchar pointer. sql/item.cc: Assert if it should not happen. storage/myisam/mi_check.c: Cast to expected type. This is probably a bug, but it is casted in a similar way in another part of the code. storage/ndb/include/mgmapi/ndb_logevent.h: Apply fix from cluster team. tests/mysql_client_test.c: Remove extraneous slash. --- client/mysql.cc | 18 +- client/mysqldump.c | 6 +- mysys/array.c | 2 +- sql/item.cc | 3 +- storage/myisam/mi_check.c | 2 +- storage/ndb/include/mgmapi/ndb_logevent.h | 683 +++++++++++----------- tests/mysql_client_test.c | 2 +- 7 files changed, 371 insertions(+), 345 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index dc7022a0ffa..1491ff1b059 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -86,7 +86,7 @@ extern "C" { #endif #undef bcmp // Fix problem with new readline -#if defined( __WIN__) +#if defined(__WIN__) #include #elif !defined(__NETWARE__) #include @@ -106,7 +106,7 @@ extern "C" { #define cmp_database(cs,A,B) strcmp((A),(B)) #endif -#if !defined( __WIN__) && !defined(__NETWARE__) && !defined(THREAD) +#if !defined(__WIN__) && !defined(__NETWARE__) && !defined(THREAD) #define USE_POPEN #endif @@ -1862,7 +1862,7 @@ static int read_and_execute(bool interactive) if (opt_outfile && glob_buffer.is_empty()) fflush(OUTFILE); -#if defined( __WIN__) || defined(__NETWARE__) +#if defined(__WIN__) || defined(__NETWARE__) tee_fputs(prompt, stdout); #if defined(__NETWARE__) line=fgets(linebuffer, sizeof(linebuffer)-1, stdin); @@ -1873,7 +1873,7 @@ static int read_and_execute(bool interactive) if (p != NULL) *p = '\0'; } -#else defined(__WIN__) +#else if (!tmpbuf.is_alloced()) tmpbuf.alloc(65535); tmpbuf.length(0); @@ -1899,7 +1899,7 @@ static int read_and_execute(bool interactive) if (opt_outfile) fputs(prompt, OUTFILE); line= readline(prompt); -#endif /* defined( __WIN__) || defined(__NETWARE__) */ +#endif /* defined(__WIN__) || defined(__NETWARE__) */ /* When Ctrl+d or Ctrl+z is pressed, the line may be NULL on some OS @@ -1947,10 +1947,10 @@ static int read_and_execute(bool interactive) } } -#if defined( __WIN__) || defined(__NETWARE__) +#if defined(__WIN__) || defined(__NETWARE__) buffer.free(); #endif -#if defined( __WIN__) +#if defined(__WIN__) tmpbuf.free(); #endif @@ -4602,7 +4602,7 @@ void tee_putc(int c, FILE *file) putc(c, OUTFILE); } -#if defined( __WIN__) || defined(__NETWARE__) +#if defined(__WIN__) || defined(__NETWARE__) #include #else #include @@ -4614,7 +4614,7 @@ void tee_putc(int c, FILE *file) static ulong start_timer(void) { -#if defined( __WIN__) || defined(__NETWARE__) +#if defined(__WIN__) || defined(__NETWARE__) return clock(); #else struct tms tms_tmp; diff --git a/client/mysqldump.c b/client/mysqldump.c index cac27424d6e..e9e3124b9cb 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -5008,7 +5008,7 @@ int main(int argc, char **argv) exit_code= get_options(&argc, &argv); if (exit_code) { - free_resources(0); + free_resources(); exit(exit_code); } @@ -5016,14 +5016,14 @@ int main(int argc, char **argv) { if(!(stderror_file= freopen(log_error_file, "a+", stderr))) { - free_resources(0); + free_resources(); exit(EX_MYSQLERR); } } if (connect_to_db(current_host, current_user, opt_password)) { - free_resources(0); + free_resources(); exit(EX_MYSQLERR); } if (!path) diff --git a/mysys/array.c b/mysys/array.c index b65bd28616d..a1c49c2589d 100644 --- a/mysys/array.c +++ b/mysys/array.c @@ -67,7 +67,7 @@ my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size, Since the dynamic array is usable even if allocation fails here malloc should not throw an error */ - if (!(array->buffer= (char*) my_malloc_ci(element_size*init_alloc, MYF(0)))) + if (!(array->buffer= (uchar*) my_malloc_ci(element_size*init_alloc, MYF(0)))) array->max_element=0; DBUG_RETURN(FALSE); } diff --git a/sql/item.cc b/sql/item.cc index 0ebb1d61a28..c1ba6fe77a3 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3305,8 +3305,7 @@ Item_copy *Item_copy::create (Item *item) new Item_copy_uint (item) : new Item_copy_int (item); case DECIMAL_RESULT: return new Item_copy_decimal (item); - - case ROW_RESULT: + default: DBUG_ASSERT (0); } /* should not happen */ diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index 535b4f7f537..1cb0613331d 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -1549,7 +1549,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, if (!param->using_global_keycache) VOID(init_key_cache(dflt_key_cache, param->key_cache_block_size, - param->use_buffers, 0, 0)); + (size_t) param->use_buffers, 0, 0)); if (init_io_cache(¶m->read_cache,info->dfile, (uint) param->read_buffer_length, diff --git a/storage/ndb/include/mgmapi/ndb_logevent.h b/storage/ndb/include/mgmapi/ndb_logevent.h index 70691f6fd28..519c13b2ca9 100644 --- a/storage/ndb/include/mgmapi/ndb_logevent.h +++ b/storage/ndb/include/mgmapi/ndb_logevent.h @@ -272,6 +272,300 @@ extern "C" { #endif }; + struct ndb_logevent_Connected { + unsigned node; + }; + + struct ndb_logevent_Disconnected { + unsigned node; + }; + + struct ndb_logevent_CommunicationClosed { + unsigned node; + }; + + struct ndb_logevent_CommunicationOpened { + unsigned node; + }; + + struct ndb_logevent_ConnectedApiVersion { + unsigned node; + unsigned version; + }; + + /* CHECKPOINT */ + struct ndb_logevent_GlobalCheckpointStarted { + unsigned gci; + }; + struct ndb_logevent_GlobalCheckpointCompleted { + unsigned gci; + }; + struct ndb_logevent_LocalCheckpointStarted { + unsigned lci; + unsigned keep_gci; + unsigned restore_gci; + }; + struct ndb_logevent_LocalCheckpointCompleted { + unsigned lci; + }; + struct ndb_logevent_LCPStoppedInCalcKeepGci { + unsigned data; + }; + struct ndb_logevent_LCPFragmentCompleted { + unsigned node; + unsigned table_id; + unsigned fragment_id; + }; + struct ndb_logevent_UndoLogBlocked { + unsigned acc_count; + unsigned tup_count; + }; + + /* STARTUP */ + struct ndb_logevent_NDBStartStarted { + unsigned version; + }; + struct ndb_logevent_NDBStartCompleted { + unsigned version; + }; + struct ndb_logevent_STTORRYRecieved { + }; + struct ndb_logevent_StartPhaseCompleted { + unsigned phase; + unsigned starttype; + }; + struct ndb_logevent_CM_REGCONF { + unsigned own_id; + unsigned president_id; + unsigned dynamic_id; + }; + struct ndb_logevent_CM_REGREF { + unsigned own_id; + unsigned other_id; + unsigned cause; + }; + struct ndb_logevent_FIND_NEIGHBOURS { + unsigned own_id; + unsigned left_id; + unsigned right_id; + unsigned dynamic_id; + }; + struct ndb_logevent_NDBStopStarted { + unsigned stoptype; + }; + struct ndb_logevent_NDBStopCompleted { + unsigned action; + unsigned signum; + }; + struct ndb_logevent_NDBStopForced { + unsigned action; + unsigned signum; + unsigned error; + unsigned sphase; + unsigned extra; + }; + struct ndb_logevent_NDBStopAborted { + }; + struct ndb_logevent_StartREDOLog { + unsigned node; + unsigned keep_gci; + unsigned completed_gci; + unsigned restorable_gci; + }; + struct ndb_logevent_StartLog { + unsigned log_part; + unsigned start_mb; + unsigned stop_mb; + unsigned gci; + }; + struct ndb_logevent_UNDORecordsExecuted { + unsigned block; + unsigned data1; + unsigned data2; + unsigned data3; + unsigned data4; + unsigned data5; + unsigned data6; + unsigned data7; + unsigned data8; + unsigned data9; + unsigned data10; + }; + + /* NODERESTART */ + struct ndb_logevent_NR_CopyDict { + }; + struct ndb_logevent_NR_CopyDistr { + }; + struct ndb_logevent_NR_CopyFragsStarted { + unsigned dest_node; + }; + struct ndb_logevent_NR_CopyFragDone { + unsigned dest_node; + unsigned table_id; + unsigned fragment_id; + }; + struct ndb_logevent_NR_CopyFragsCompleted { + unsigned dest_node; + }; + + struct ndb_logevent_NodeFailCompleted { + unsigned block; /* 0 = all */ + unsigned failed_node; + unsigned completing_node; /* 0 = all */ + }; + struct ndb_logevent_NODE_FAILREP { + unsigned failed_node; + unsigned failure_state; + }; + struct ndb_logevent_ArbitState { + unsigned code; /* code & state << 16 */ + unsigned arbit_node; + unsigned ticket_0; + unsigned ticket_1; + /* TODO */ + }; + struct ndb_logevent_ArbitResult { + unsigned code; /* code & state << 16 */ + unsigned arbit_node; + unsigned ticket_0; + unsigned ticket_1; + /* TODO */ + }; + struct ndb_logevent_GCP_TakeoverStarted { + }; + struct ndb_logevent_GCP_TakeoverCompleted { + }; + struct ndb_logevent_LCP_TakeoverStarted { + }; + struct ndb_logevent_LCP_TakeoverCompleted { + unsigned state; + }; + + /* STATISTIC */ + struct ndb_logevent_TransReportCounters { + unsigned trans_count; + unsigned commit_count; + unsigned read_count; + unsigned simple_read_count; + unsigned write_count; + unsigned attrinfo_count; + unsigned conc_op_count; + unsigned abort_count; + unsigned scan_count; + unsigned range_scan_count; + }; + struct ndb_logevent_OperationReportCounters { + unsigned ops; + }; + struct ndb_logevent_TableCreated { + unsigned table_id; + }; + struct ndb_logevent_JobStatistic { + unsigned mean_loop_count; + }; + struct ndb_logevent_SendBytesStatistic { + unsigned to_node; + unsigned mean_sent_bytes; + }; + struct ndb_logevent_ReceiveBytesStatistic { + unsigned from_node; + unsigned mean_received_bytes; + }; + struct ndb_logevent_MemoryUsage { + int gth; + /* union is for compatibility backward. + * page_size_kb member variable should be removed in the future + */ + union { + unsigned page_size_kb; + unsigned page_size_bytes; + }; + unsigned pages_used; + unsigned pages_total; + unsigned block; + }; + + /* ERROR */ + struct ndb_logevent_TransporterError { + unsigned to_node; + unsigned code; + }; + struct ndb_logevent_TransporterWarning { + unsigned to_node; + unsigned code; + }; + struct ndb_logevent_MissedHeartbeat { + unsigned node; + unsigned count; + }; + struct ndb_logevent_DeadDueToHeartbeat { + unsigned node; + }; + struct ndb_logevent_WarningEvent { + /* TODO */ + }; + + /* INFO */ + struct ndb_logevent_SentHeartbeat { + unsigned node; + }; + struct ndb_logevent_CreateLogBytes { + unsigned node; + }; + struct ndb_logevent_InfoEvent { + /* TODO */ + }; + struct ndb_logevent_EventBufferStatus { + unsigned usage; + unsigned alloc; + unsigned max; + unsigned apply_gci_l; + unsigned apply_gci_h; + unsigned latest_gci_l; + unsigned latest_gci_h; + }; + + /** Log event data for @ref NDB_LE_BackupStarted */ + struct ndb_logevent_BackupStarted { + unsigned starting_node; + unsigned backup_id; + }; + /** Log event data @ref NDB_LE_BackupFailedToStart */ + struct ndb_logevent_BackupFailedToStart { + unsigned starting_node; + unsigned error; + }; + /** Log event data @ref NDB_LE_BackupCompleted */ + struct ndb_logevent_BackupCompleted { + unsigned starting_node; + unsigned backup_id; + unsigned start_gci; + unsigned stop_gci; + unsigned n_records; + unsigned n_log_records; + unsigned n_bytes; + unsigned n_log_bytes; + }; + /** Log event data @ref NDB_LE_BackupAborted */ + struct ndb_logevent_BackupAborted { + unsigned starting_node; + unsigned backup_id; + unsigned error; + }; + /** Log event data @ref NDB_LE_SingleUser */ + struct ndb_logevent_SingleUser { + unsigned type; + unsigned node_id; + }; + /** Log even data @ref NDB_LE_StartReport */ + struct ndb_logevent_StartReport { + unsigned report_type; + unsigned remaining_time; + unsigned bitmask_size; + unsigned bitmask_data[1]; + }; + /** * Structure to store and retrieve log event information. * @see @ref secSLogEvents @@ -305,354 +599,87 @@ extern "C" { */ union { /* CONNECT */ - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned node; - } Connected; - - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned node; - } Disconnected; - - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned node; - } CommunicationClosed; - - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned node; - } CommunicationOpened; - - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned node; - unsigned version; - } ConnectedApiVersion; + struct ndb_logevent_Connected Connected; + struct ndb_logevent_Disconnected Disconnected; + struct ndb_logevent_CommunicationClosed CommunicationClosed; + struct ndb_logevent_CommunicationOpened CommunicationOpened; + struct ndb_logevent_ConnectedApiVersion ConnectedApiVersion; /* CHECKPOINT */ - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned gci; - } GlobalCheckpointStarted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned gci; - } GlobalCheckpointCompleted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned lci; - unsigned keep_gci; - unsigned restore_gci; - } LocalCheckpointStarted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned lci; - } LocalCheckpointCompleted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned data; - } LCPStoppedInCalcKeepGci; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned node; - unsigned table_id; - unsigned fragment_id; - } LCPFragmentCompleted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned acc_count; - unsigned tup_count; - } UndoLogBlocked; + struct ndb_logevent_GlobalCheckpointStarted GlobalCheckpointStarted; + struct ndb_logevent_GlobalCheckpointCompleted GlobalCheckpointCompleted; + struct ndb_logevent_LocalCheckpointStarted LocalCheckpointStarted; + struct ndb_logevent_LocalCheckpointCompleted LocalCheckpointCompleted; + struct ndb_logevent_LCPStoppedInCalcKeepGci LCPStoppedInCalcKeepGci; + struct ndb_logevent_LCPFragmentCompleted LCPFragmentCompleted; + struct ndb_logevent_UndoLogBlocked UndoLogBlocked; /* STARTUP */ - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned version; - } NDBStartStarted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned version; - } NDBStartCompleted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - } STTORRYRecieved; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned phase; - unsigned starttype; - } StartPhaseCompleted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned own_id; - unsigned president_id; - unsigned dynamic_id; - } CM_REGCONF; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned own_id; - unsigned other_id; - unsigned cause; - } CM_REGREF; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned own_id; - unsigned left_id; - unsigned right_id; - unsigned dynamic_id; - } FIND_NEIGHBOURS; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned stoptype; - } NDBStopStarted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned action; - unsigned signum; - } NDBStopCompleted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned action; - unsigned signum; - unsigned error; - unsigned sphase; - unsigned extra; - } NDBStopForced; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - } NDBStopAborted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned node; - unsigned keep_gci; - unsigned completed_gci; - unsigned restorable_gci; - } StartREDOLog; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned log_part; - unsigned start_mb; - unsigned stop_mb; - unsigned gci; - } StartLog; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned block; - unsigned data1; - unsigned data2; - unsigned data3; - unsigned data4; - unsigned data5; - unsigned data6; - unsigned data7; - unsigned data8; - unsigned data9; - unsigned data10; - } UNDORecordsExecuted; + struct ndb_logevent_NDBStartStarted NDBStartStarted; + struct ndb_logevent_NDBStartCompleted NDBStartCompleted; + struct ndb_logevent_STTORRYRecieved STTORRYRecieved; + struct ndb_logevent_StartPhaseCompleted StartPhaseCompleted; + struct ndb_logevent_CM_REGCONF CM_REGCONF; + struct ndb_logevent_CM_REGREF CM_REGREF; + struct ndb_logevent_FIND_NEIGHBOURS FIND_NEIGHBOURS; + struct ndb_logevent_NDBStopStarted NDBStopStarted; + struct ndb_logevent_NDBStopCompleted NDBStopCompleted; + struct ndb_logevent_NDBStopForced NDBStopForced; + struct ndb_logevent_NDBStopAborted NDBStopAborted; + struct ndb_logevent_StartREDOLog StartREDOLog; + struct ndb_logevent_StartLog StartLog; + struct ndb_logevent_UNDORecordsExecuted UNDORecordsExecuted; /* NODERESTART */ - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - } NR_CopyDict; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - } NR_CopyDistr; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned dest_node; - } NR_CopyFragsStarted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned dest_node; - unsigned table_id; - unsigned fragment_id; - } NR_CopyFragDone; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned dest_node; - } NR_CopyFragsCompleted; + struct ndb_logevent_NR_CopyDict NR_CopyDict; + struct ndb_logevent_NR_CopyDistr NR_CopyDistr; + struct ndb_logevent_NR_CopyFragsStarted NR_CopyFragsStarted; + struct ndb_logevent_NR_CopyFragDone NR_CopyFragDone; + struct ndb_logevent_NR_CopyFragsCompleted NR_CopyFragsCompleted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned block; /* 0 = all */ - unsigned failed_node; - unsigned completing_node; /* 0 = all */ - } NodeFailCompleted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned failed_node; - unsigned failure_state; - } NODE_FAILREP; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned code; /* code & state << 16 */ - unsigned arbit_node; - unsigned ticket_0; - unsigned ticket_1; - /* TODO */ - } ArbitState; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned code; /* code & state << 16 */ - unsigned arbit_node; - unsigned ticket_0; - unsigned ticket_1; - /* TODO */ - } ArbitResult; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - } GCP_TakeoverStarted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - } GCP_TakeoverCompleted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - } LCP_TakeoverStarted; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned state; - } LCP_TakeoverCompleted; + struct ndb_logevent_NodeFailCompleted NodeFailCompleted; + struct ndb_logevent_NODE_FAILREP NODE_FAILREP; + struct ndb_logevent_ArbitState ArbitState; + struct ndb_logevent_ArbitResult ArbitResult; + struct ndb_logevent_GCP_TakeoverStarted GCP_TakeoverStarted; + struct ndb_logevent_GCP_TakeoverCompleted GCP_TakeoverCompleted; + struct ndb_logevent_LCP_TakeoverStarted LCP_TakeoverStarted; + struct ndb_logevent_LCP_TakeoverCompleted LCP_TakeoverCompleted; /* STATISTIC */ - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned trans_count; - unsigned commit_count; - unsigned read_count; - unsigned simple_read_count; - unsigned write_count; - unsigned attrinfo_count; - unsigned conc_op_count; - unsigned abort_count; - unsigned scan_count; - unsigned range_scan_count; - } TransReportCounters; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned ops; - } OperationReportCounters; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned table_id; - } TableCreated; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned mean_loop_count; - } JobStatistic; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned to_node; - unsigned mean_sent_bytes; - } SendBytesStatistic; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned from_node; - unsigned mean_received_bytes; - } ReceiveBytesStatistic; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - int gth; - /* union is for compatibility backward. - * page_size_kb member variable should be removed in the future - */ - union { - unsigned page_size_kb; - unsigned page_size_bytes; - }; - unsigned pages_used; - unsigned pages_total; - unsigned block; - } MemoryUsage; + struct ndb_logevent_TransReportCounters TransReportCounters; + struct ndb_logevent_OperationReportCounters OperationReportCounters; + struct ndb_logevent_TableCreated TableCreated; + struct ndb_logevent_JobStatistic JobStatistic; + struct ndb_logevent_SendBytesStatistic SendBytesStatistic; + struct ndb_logevent_ReceiveBytesStatistic ReceiveBytesStatistic; + struct ndb_logevent_MemoryUsage MemoryUsage; /* ERROR */ - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned to_node; - unsigned code; - } TransporterError; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned to_node; - unsigned code; - } TransporterWarning; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned node; - unsigned count; - } MissedHeartbeat; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned node; - } DeadDueToHeartbeat; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - /* TODO */ - } WarningEvent; + struct ndb_logevent_TransporterError TransporterError; + struct ndb_logevent_TransporterWarning TransporterWarning; + struct ndb_logevent_MissedHeartbeat MissedHeartbeat; + struct ndb_logevent_DeadDueToHeartbeat DeadDueToHeartbeat; + struct ndb_logevent_WarningEvent WarningEvent; /* INFO */ - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned node; - } SentHeartbeat; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned node; - } CreateLogBytes; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - /* TODO */ - } InfoEvent; - /** Log event specific data for for corresponding NDB_LE_ log event */ - struct { - unsigned usage; - unsigned alloc; - unsigned max; - unsigned apply_gci_l; - unsigned apply_gci_h; - unsigned latest_gci_l; - unsigned latest_gci_h; - } EventBufferStatus; + struct ndb_logevent_SentHeartbeat SentHeartbeat; + struct ndb_logevent_CreateLogBytes CreateLogBytes; + struct ndb_logevent_InfoEvent InfoEvent; + struct ndb_logevent_EventBufferStatus EventBufferStatus; /** Log event data for @ref NDB_LE_BackupStarted */ - struct { - unsigned starting_node; - unsigned backup_id; - } BackupStarted; + struct ndb_logevent_BackupStarted BackupStarted; /** Log event data @ref NDB_LE_BackupFailedToStart */ - struct { - unsigned starting_node; - unsigned error; - } BackupFailedToStart; + struct ndb_logevent_BackupFailedToStart BackupFailedToStart; /** Log event data @ref NDB_LE_BackupCompleted */ - struct { - unsigned starting_node; - unsigned backup_id; - unsigned start_gci; - unsigned stop_gci; - unsigned n_records; - unsigned n_log_records; - unsigned n_bytes; - unsigned n_log_bytes; - } BackupCompleted; + struct ndb_logevent_BackupCompleted BackupCompleted; /** Log event data @ref NDB_LE_BackupAborted */ - struct { - unsigned starting_node; - unsigned backup_id; - unsigned error; - } BackupAborted; + struct ndb_logevent_BackupAborted BackupAborted; /** Log event data @ref NDB_LE_SingleUser */ - struct { - unsigned type; - unsigned node_id; - } SingleUser; + struct ndb_logevent_SingleUser SingleUser; /** Log even data @ref NDB_LE_StartReport */ - struct { - unsigned report_type; - unsigned remaining_time; - unsigned bitmask_size; - unsigned bitmask_data[1]; - } StartReport; + struct ndb_logevent_StartReport StartReport; #ifndef DOXYGEN_FIX }; #else diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 9d61d6edd3e..300b0347233 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -4262,7 +4262,7 @@ static void test_fetch_date() myheader("test_fetch_date"); - /* Will not work if sql_mode is NO_ZERO_DATE (implicit if TRADITIONAL) /*/ + /* Will not work if sql_mode is NO_ZERO_DATE (implicit if TRADITIONAL) */ rc= mysql_query(mysql, "SET SQL_MODE=''"); myquery(rc); From 1ba25ae47caace207cda0be2b7994a1a845e6cce Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Fri, 28 Aug 2009 17:51:31 +0200 Subject: [PATCH 044/138] Bug #43414 Parenthesis (and other) warnings compiling MySQL with gcc 4.3.2 This patch fixes a number of GCC warnings about variables used before initialized. A new macro UNINIT_VAR() is introduced for use in the variable declaration, and LINT_INIT() usage will be gradually deprecated. (A workaround is used for g++, pending a patch for a g++ bug.) GCC warnings for unused results (attribute warn_unused_result) for a number of system calls (present at least in later Ubuntus, where the usual void cast trick doesn't work) are also fixed. client/mysqlmanager-pwgen.c: A fix for warn_unused_result, adding fallback to use of srand()/rand() if /dev/random cannot be used. Also actually adds calls to rand() in the second branch so that it actually creates a random password. --- client/mysql.cc | 3 ++- client/mysql_upgrade.c | 3 ++- client/mysqladmin.cc | 6 ++++-- client/mysqlmanager-pwgen.c | 19 ++++++++++++------- client/mysqltest.c | 15 +++++++-------- cmd-line-utils/readline/bind.c | 6 ++---- cmd-line-utils/readline/histfile.c | 7 ++++--- cmd-line-utils/readline/undo.c | 3 ++- heap/hp_test2.c | 3 +-- include/my_global.h | 13 +++++++++++++ libmysql/libmysql.c | 3 +-- myisam/ft_boolean_search.c | 4 +--- myisam/mi_check.c | 18 +++++++----------- myisam/mi_create.c | 2 +- myisam/mi_delete.c | 2 +- myisam/mi_dynrec.c | 9 +++------ myisam/mi_open.c | 2 +- myisam/mi_packrec.c | 2 +- myisam/mi_search.c | 5 ++--- myisam/mi_update.c | 5 +---- myisam/sort.c | 4 ++-- myisammrg/myrg_open.c | 4 +--- myisammrg/myrg_rkey.c | 9 +++------ mysys/mf_pack.c | 3 +-- mysys/my_copy.c | 5 +++-- mysys/my_getopt.c | 2 +- mysys/my_redel.c | 3 ++- mysys/typelib.c | 4 ++-- regex/regcomp.c | 6 +++--- sql-common/client.c | 5 ++--- sql-common/my_time.c | 3 +-- sql/field.cc | 19 ++++++------------- sql/ha_myisammrg.cc | 2 +- sql/item.cc | 7 ++----- sql/item_cmpfunc.cc | 17 +++++------------ sql/item_create.cc | 6 ++++-- sql/item_func.cc | 12 ++++-------- sql/lock.cc | 3 +-- sql/log.cc | 3 ++- sql/opt_range.cc | 8 ++++---- sql/spatial.cc | 13 +++---------- sql/sql_acl.cc | 10 +++------- sql/sql_base.cc | 6 ++---- sql/sql_parse.cc | 4 ++-- sql/sql_prepare.cc | 3 +-- sql/sql_show.cc | 7 ++----- sql/sql_update.cc | 4 +--- sql/sql_view.cc | 3 +-- strings/ctype-ucs2.c | 9 +++------ strings/ctype-utf8.c | 6 ++---- strings/decimal.c | 13 ++++--------- 51 files changed, 142 insertions(+), 191 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 0d61ed4ec88..d103a3eec17 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -3728,7 +3728,8 @@ com_edit(String *buffer,char *line __attribute__((unused))) !(editor = (char *)getenv("VISUAL"))) editor = "vi"; strxmov(buff,editor," ",filename,NullS); - (void) system(buff); + if(system(buff) == -1) + goto err; MY_STAT stat_arg; if (!my_stat(filename,&stat_arg,MYF(MY_WME))) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index ff414fff592..efa23610574 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -526,6 +526,7 @@ static int upgrade_already_done(void) FILE *in; char upgrade_info_file[FN_REFLEN]= {0}; char buf[sizeof(MYSQL_SERVER_VERSION)+1]; + char *res; if (get_upgrade_info_file_name(upgrade_info_file)) return 0; /* Could not get filename => not sure */ @@ -538,7 +539,7 @@ static int upgrade_already_done(void) will be detected by the strncmp */ bzero(buf, sizeof(buf)); - fgets(buf, sizeof(buf), in); + res= fgets(buf, sizeof(buf), in); my_fclose(in, MYF(0)); diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 24b95be8626..699c2081b86 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -1050,14 +1050,16 @@ static void usage(void) static int drop_db(MYSQL *mysql, const char *db) { char name_buff[FN_REFLEN+20], buf[10]; + char *input; + if (!option_force) { puts("Dropping the database is potentially a very bad thing to do."); puts("Any data stored in the database will be destroyed.\n"); printf("Do you really want to drop the '%s' database [y/N] ",db); fflush(stdout); - VOID(fgets(buf,sizeof(buf)-1,stdin)); - if ((*buf != 'y') && (*buf != 'Y')) + input= fgets(buf, sizeof(buf)-1, stdin); + if (!input || ((*input != 'y') && (*input != 'Y'))) { puts("\nOK, aborting database drop!"); return -1; diff --git a/client/mysqlmanager-pwgen.c b/client/mysqlmanager-pwgen.c index 568358b1cda..1be4d8b6970 100644 --- a/client/mysqlmanager-pwgen.c +++ b/client/mysqlmanager-pwgen.c @@ -104,29 +104,34 @@ void get_pass(char* pw, int len) { FILE* fp; char* pw_end=pw+len; + size_t elements_read= 0; /* /dev/random is more secure than rand() because the seed is easy to predict, so we resort to rand() only if /dev/random is not available */ if ((fp=fopen("/dev/random","r"))) { - fread(pw,len,1,fp); - fclose(fp); - while (pwmysql; for (;;) { - MYSQL_RES *res; + MYSQL_RES *UNINIT_VAR(res); MYSQL_ROW row; int done; - LINT_INIT(res); if (mysql_query(mysql,"show status like 'Slave_running'") || !(res=mysql_store_result(mysql))) @@ -4710,13 +4711,12 @@ my_bool end_of_query(int c) int read_line(char *buf, int size) { - char c, last_quote; + char c, UNINIT_VAR(last_quote); char *p= buf, *buf_end= buf + size - 1; int skip_char= 0; enum {R_NORMAL, R_Q, R_SLASH_IN_Q, R_COMMENT, R_LINE_START} state= R_LINE_START; DBUG_ENTER("read_line"); - LINT_INIT(last_quote); start_lineno= cur_file->lineno; DBUG_PRINT("info", ("Starting to read at lineno: %d", start_lineno)); @@ -5978,8 +5978,7 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, if (!disable_result_log) { - ulonglong affected_rows; /* Ok to be undef if 'disable_info' is set */ - LINT_INIT(affected_rows); + ulonglong UNINIT_VAR(affected_rows); /* Ok to be undef if 'disable_info' is set */ if (res) { diff --git a/cmd-line-utils/readline/bind.c b/cmd-line-utils/readline/bind.c index aa5bd3d829a..85f6b432bf8 100644 --- a/cmd-line-utils/readline/bind.c +++ b/cmd-line-utils/readline/bind.c @@ -339,9 +339,7 @@ rl_generic_bind (type, keyseq, data, map) char *keys; int keys_len; register int i; - KEYMAP_ENTRY k; - - k.function = 0; + KEYMAP_ENTRY k= { 0, NULL }; /* If no keys to bind to, exit right away. */ if (keyseq == 0 || *keyseq == 0) @@ -776,7 +774,7 @@ _rl_read_file (filename, sizep) file_size = (size_t)finfo.st_size; /* check for overflow on very large files */ -if ((sizeof(off_t) > sizeof(size_t) && finfo.st_size > (off_t)(size_t)~0) || + if ((sizeof(off_t) > sizeof(size_t) && finfo.st_size > (off_t)(size_t)~0) || file_size + 1 < file_size) { if (file >= 0) diff --git a/cmd-line-utils/readline/histfile.c b/cmd-line-utils/readline/histfile.c index 118c5ebd328..cbd367542ce 100644 --- a/cmd-line-utils/readline/histfile.c +++ b/cmd-line-utils/readline/histfile.c @@ -186,7 +186,7 @@ read_history_range (filename, from, to) file_size = (size_t)finfo.st_size; /* check for overflow on very large files */ -if ((sizeof(off_t) > sizeof(size_t) && finfo.st_size > (off_t)(size_t)~0) || + if ((sizeof(off_t) > sizeof(size_t) && finfo.st_size > (off_t)(size_t)~0) || file_size + 1 < file_size) { errno = overflow_errno; @@ -311,6 +311,7 @@ history_truncate_file (fname, lines) int file, chars_read, rv; struct stat finfo; size_t file_size; + size_t bytes_written; buffer = (char *)NULL; filename = history_filename (fname); @@ -340,7 +341,7 @@ history_truncate_file (fname, lines) file_size = (size_t)finfo.st_size; /* check for overflow on very large files */ -if ((sizeof(off_t) > sizeof(size_t) && finfo.st_size > (off_t)(size_t)~0) || + if ((sizeof(off_t) > sizeof(size_t) && finfo.st_size > (off_t)(size_t)~0) || file_size + 1 < file_size) { close (file); @@ -400,7 +401,7 @@ if ((sizeof(off_t) > sizeof(size_t) && finfo.st_size > (off_t)(size_t)~0) || truncate to. */ if (bp > buffer && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1)) { - write (file, bp, chars_read - (bp - buffer)); + bytes_written= write (file, bp, chars_read - (bp - buffer)); #if defined (__BEOS__) /* BeOS ignores O_TRUNC. */ diff --git a/cmd-line-utils/readline/undo.c b/cmd-line-utils/readline/undo.c index 79846c26024..c6bd044c3a3 100644 --- a/cmd-line-utils/readline/undo.c +++ b/cmd-line-utils/readline/undo.c @@ -137,7 +137,8 @@ UNDO_LIST * _rl_copy_undo_list (head) UNDO_LIST *head; { - UNDO_LIST *list, *new, *roving, *c; + UNDO_LIST *list, *new, *c; + UNDO_LIST *roving= NULL; list = head; new = 0; diff --git a/heap/hp_test2.c b/heap/hp_test2.c index 73cad6c2043..dc4ad316d24 100644 --- a/heap/hp_test2.c +++ b/heap/hp_test2.c @@ -61,11 +61,10 @@ int main(int argc, char *argv[]) HP_INFO *file,*file2; HP_KEYDEF keyinfo[MAX_KEYS]; HA_KEYSEG keyseg[MAX_KEYS*5]; - HEAP_PTR position; + HEAP_PTR UNINIT_VAR(position); HP_CREATE_INFO hp_create_info; CHARSET_INFO *cs= &my_charset_latin1; MY_INIT(argv[0]); /* init my_sys library & pthreads */ - LINT_INIT(position); filename= "test2"; filename2= "test2_2"; diff --git a/include/my_global.h b/include/my_global.h index 5c07aa00b32..0b5458215c6 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -464,6 +464,19 @@ int __void__; #define PURIFY_OR_LINT_INIT(var) #endif +/* + Suppress uninitialized variable warning without generating code. + + The _cplusplus is a temporary workaround for C++ code pending a fix + for a g++ bug (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34772). +*/ +#if defined(_lint) || defined(FORCE_INIT_OF_VARS) || defined(__cplusplus) || \ + !defined(__GNUC__) +#define UNINIT_VAR(x) x= 0 +#else +#define UNINIT_VAR(x) x= x +#endif + /* Define some useful general macros */ #if !defined(max) #define max(a, b) ((a) > (b) ? (a) : (b)) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index d18ed04e273..1fa3181b1be 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -1619,8 +1619,7 @@ myodbc_remove_escape(MYSQL *mysql,char *name) char *to; #ifdef USE_MB my_bool use_mb_flag=use_mb(mysql->charset); - char *end; - LINT_INIT(end); + char *UNINIT_VAR(end); if (use_mb_flag) for (end=name; *end ; end++) ; #endif diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c index 255c51fd33a..50f2cd52b3d 100644 --- a/myisam/ft_boolean_search.c +++ b/myisam/ft_boolean_search.c @@ -218,11 +218,9 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) int subkeys=1; my_bool can_go_down; MI_INFO *info=ftb->info; - uint off, extra=HA_FT_WLEN+info->s->base.rec_reflength; + uint UNINIT_VAR(off), extra=HA_FT_WLEN+info->s->base.rec_reflength; byte *lastkey_buf=ftbw->word+ftbw->off; - LINT_INIT(off); - LINT_INIT(off); if (ftbw->flags & FTB_FLAG_TRUNC) lastkey_buf+=ftbw->len; diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 285a31d34c6..80a90977609 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -140,11 +140,10 @@ int chk_del(MI_CHECK *param, register MI_INFO *info, uint test_flag) { reg2 ha_rows i; uint delete_link_length; - my_off_t empty,next_link,old_link; + my_off_t empty,next_link,UNINIT_VAR(old_link); char buff[22],buff2[22]; DBUG_ENTER("chk_del"); - LINT_INIT(old_link); param->record_checksum=0; delete_link_length=((info->s->options & HA_OPTION_PACK_RECORD) ? 20 : info->s->rec_reflength+1); @@ -936,11 +935,11 @@ static uint isam_key_length(MI_INFO *info, register MI_KEYDEF *keyinfo) int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend) { int error,got_error,flag; - uint key,left_length,b_type,field; + uint key,UNINIT_VAR(left_length),b_type,field; ha_rows records,del_blocks; - my_off_t used,empty,pos,splits,start_recpos, + my_off_t used,empty,pos,splits,UNINIT_VAR(start_recpos), del_length,link_used,start_block; - byte *record= 0, *to; + byte *record= 0, *UNINIT_VAR(to); char llbuff[22],llbuff2[22],llbuff3[22]; ha_checksum intern_record_checksum; ha_checksum key_checksum[MI_MAX_POSSIBLE_KEY]; @@ -965,7 +964,6 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend) records=del_blocks=0; used=link_used=splits=del_length=0; intern_record_checksum=param->glob_crc=0; - LINT_INIT(left_length); LINT_INIT(start_recpos); LINT_INIT(to); got_error=error=0; empty=info->s->pack.header_length; @@ -2222,9 +2220,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, ulong *rec_per_key_part; char llbuff[22]; SORT_INFO sort_info; - ulonglong key_map; + ulonglong UNINIT_VAR(key_map); DBUG_ENTER("mi_repair_by_sort"); - LINT_INIT(key_map); start_records=info->state->records; got_error=1; @@ -2620,11 +2617,10 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, IO_CACHE new_data_cache; /* For non-quick repair. */ IO_CACHE_SHARE io_share; SORT_INFO sort_info; - ulonglong key_map; + ulonglong UNINIT_VAR(key_map); pthread_attr_t thr_attr; ulong max_pack_reclength; DBUG_ENTER("mi_repair_parallel"); - LINT_INIT(key_map); start_records=info->state->records; got_error=1; @@ -3206,7 +3202,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) int parallel_flag; uint found_record,b_type,left_length; my_off_t pos; - byte *to; + byte *UNINIT_VAR(to); MI_BLOCK_INFO block_info; SORT_INFO *sort_info=sort_param->sort_info; MI_CHECK *param=sort_info->param; diff --git a/myisam/mi_create.c b/myisam/mi_create.c index bb53393c345..43639409014 100644 --- a/myisam/mi_create.c +++ b/myisam/mi_create.c @@ -37,7 +37,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, MI_CREATE_INFO *ci,uint flags) { register uint i,j; - File dfile,file; + File UNINIT_VAR(dfile),file; int errpos,save_errno, create_mode= O_RDWR | O_TRUNC; myf create_flag; uint fields,length,max_key_length,packed,pointer,real_length_diff, diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c index e08e5097e33..327a977dcca 100644 --- a/myisam/mi_delete.c +++ b/myisam/mi_delete.c @@ -220,7 +220,7 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, uint length,nod_flag,search_key_length; my_bool last_key; uchar *leaf_buff,*keypos; - my_off_t leaf_page,next_block; + my_off_t UNINIT_VAR(leaf_page),next_block; uchar lastkey[MI_MAX_KEY_BUFF]; DBUG_ENTER("d_search"); DBUG_DUMP("page",(uchar*) anc_buff,mi_getint(anc_buff)); diff --git a/myisam/mi_dynrec.c b/myisam/mi_dynrec.c index 3542a82be59..af911428d11 100644 --- a/myisam/mi_dynrec.c +++ b/myisam/mi_dynrec.c @@ -1234,16 +1234,14 @@ void _my_store_blob_length(byte *pos,uint pack_length,uint length) int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf) { int block_of_record; - uint b_type,left_length; - byte *to; + uint b_type,UNINIT_VAR(left_length); + byte *UNINIT_VAR(to); MI_BLOCK_INFO block_info; File file; DBUG_ENTER("mi_read_dynamic_record"); if (filepos != HA_OFFSET_ERROR) { - LINT_INIT(to); - LINT_INIT(left_length); file=info->dfile; block_of_record= 0; /* First block of record is numbered as zero. */ block_info.second_read= 0; @@ -1506,13 +1504,12 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf, { int block_of_record, info_read, save_errno; uint left_len,b_type; - byte *to; + byte *UNINIT_VAR(to); MI_BLOCK_INFO block_info; MYISAM_SHARE *share=info->s; DBUG_ENTER("_mi_read_rnd_dynamic_record"); info_read=0; - LINT_INIT(to); if (info->lock_type == F_UNLCK) { diff --git a/myisam/mi_open.c b/myisam/mi_open.c index d9b7f6453db..285e295d999 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -678,7 +678,7 @@ err: byte *mi_alloc_rec_buff(MI_INFO *info, ulong length, byte **buf) { uint extra; - uint32 old_length; + uint32 UNINIT_VAR(old_length); LINT_INIT(old_length); if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf))) diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c index 68911d7f129..75cf45d5434 100644 --- a/myisam/mi_packrec.c +++ b/myisam/mi_packrec.c @@ -1362,7 +1362,7 @@ uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BIT_BUFF *bit_buff, File file, my_off_t filepos) { uchar *header=info->header; - uint head_length,ref_length; + uint head_length, UNINIT_VAR(ref_length); LINT_INIT(ref_length); if (file >= 0) diff --git a/myisam/mi_search.c b/myisam/mi_search.c index 795c7ee55c3..3b1cd6158f2 100644 --- a/myisam/mi_search.c +++ b/myisam/mi_search.c @@ -240,12 +240,11 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, uchar *key, uint key_len, uint comp_flag, uchar **ret_pos, uchar *buff, my_bool *last_key) { - int flag; - uint nod_flag,length,not_used[2]; + int UNINIT_VAR(flag); + uint nod_flag,UNINIT_VAR(length),not_used[2]; uchar t_buff[MI_MAX_KEY_BUFF],*end; DBUG_ENTER("_mi_seq_search"); - LINT_INIT(flag); LINT_INIT(length); end= page+mi_getint(page); nod_flag=mi_test_if_nod(page); page+=2+nod_flag; diff --git a/myisam/mi_update.c b/myisam/mi_update.c index bea457d2e9a..fa0797b1d61 100644 --- a/myisam/mi_update.c +++ b/myisam/mi_update.c @@ -27,11 +27,8 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec) bool auto_key_changed=0; ulonglong changed; MYISAM_SHARE *share=info->s; - ha_checksum old_checksum; + ha_checksum UNINIT_VAR(old_checksum); DBUG_ENTER("mi_update"); - LINT_INIT(new_key); - LINT_INIT(changed); - LINT_INIT(old_checksum); DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_usage", mi_print_error(info->s, HA_ERR_CRASHED); diff --git a/myisam/sort.c b/myisam/sort.c index 2465227a449..f418be6a72d 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -489,7 +489,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) { SORT_INFO *sort_info=sort_param->sort_info; MI_CHECK *param=sort_info->param; - ulong length, keys; + ulong UNINIT_VAR(length), keys; ulong *rec_per_key_part=param->rec_per_key_part; int got_error=sort_info->got_error; uint i; @@ -896,7 +896,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file, int error; uint sort_length,maxcount; ha_rows count; - my_off_t to_start_filepos; + my_off_t UNINIT_VAR(to_start_filepos); uchar *strpos; BUFFPEK *buffpek,**refpek; QUEUE queue; diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c index 4e61f42efce..8cccb81f6c7 100644 --- a/myisammrg/myrg_open.c +++ b/myisammrg/myrg_open.c @@ -32,7 +32,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) { int save_errno,errpos=0; - uint files= 0, i, dir_length, length, key_parts, min_keys= 0; + uint files= 0, i, dir_length, length, UNINIT_VAR(key_parts), min_keys= 0; ulonglong file_offset=0; char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end; MYRG_INFO *m_info=0; @@ -43,8 +43,6 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) my_bool bad_children= FALSE; DBUG_ENTER("myrg_open"); - LINT_INIT(key_parts); - bzero((char*) &file,sizeof(file)); if ((fd=my_open(fn_format(name_buff,name,"",MYRG_NAME_EXT,4), O_RDONLY | O_SHARE,MYF(0))) < 0) diff --git a/myisammrg/myrg_rkey.c b/myisammrg/myrg_rkey.c index 627839331c6..2b8091cb43a 100644 --- a/myisammrg/myrg_rkey.c +++ b/myisammrg/myrg_rkey.c @@ -38,16 +38,13 @@ int myrg_rkey(MYRG_INFO *info,byte *buf,int inx, const byte *key, uint key_len, enum ha_rkey_function search_flag) { - byte *key_buff; - uint pack_key_length; - uint16 last_used_keyseg; + byte *UNINIT_VAR(key_buff); + uint UNINIT_VAR(pack_key_length); + uint16 UNINIT_VAR(last_used_keyseg); MYRG_TABLE *table; MI_INFO *mi; int err; DBUG_ENTER("myrg_rkey"); - LINT_INIT(key_buff); - LINT_INIT(pack_key_length); - LINT_INIT(last_used_keyseg); if (_myrg_init_queue(info,inx,search_flag)) DBUG_RETURN(my_errno); diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c index 0157a65311a..d2bac95b391 100644 --- a/mysys/mf_pack.c +++ b/mysys/mf_pack.c @@ -33,12 +33,11 @@ static my_string NEAR_F expand_tilde(my_string *path); void pack_dirname(my_string to, const char *from) { int cwd_err; - uint d_length,length,buff_length; + uint d_length,length,UNINIT_VAR(buff_length); my_string start; char buff[FN_REFLEN]; DBUG_ENTER("pack_dirname"); - LINT_INIT(buff_length); (void) intern_filename(to,from); /* Change to intern name */ #ifdef FN_DEVCHAR diff --git a/mysys/my_copy.c b/mysys/my_copy.c index ec642b4083c..b6bb925e898 100644 --- a/mysys/my_copy.c +++ b/mysys/my_copy.c @@ -57,6 +57,7 @@ int my_copy(const char *from, const char *to, myf MyFlags) File from_file,to_file; char buff[IO_SIZE]; MY_STAT stat_buff,new_stat_buff; + int res; DBUG_ENTER("my_copy"); DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags)); @@ -93,9 +94,9 @@ int my_copy(const char *from, const char *to, myf MyFlags) if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat) DBUG_RETURN(0); /* File copyed but not stat */ - VOID(chmod(to, stat_buff.st_mode & 07777)); /* Copy modes */ + res= chmod(to, stat_buff.st_mode & 07777); /* Copy modes */ #if !defined(MSDOS) && !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) && !defined(__NETWARE__) - VOID(chown(to, stat_buff.st_uid,stat_buff.st_gid)); /* Copy ownership */ + res= chown(to, stat_buff.st_uid,stat_buff.st_gid); /* Copy ownership */ #endif #if !defined(VMS) && !defined(__ZTC__) if (MyFlags & MY_COPYTIME) diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 3bb500616a1..22b404bdd25 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -100,7 +100,7 @@ int handle_options(int *argc, char ***argv, uint opt_found, argvpos= 0, length, i; my_bool end_of_options= 0, must_be_var, set_maximum_value, option_is_loose; - char **pos, **pos_end, *optend, *prev_found, + char **pos, **pos_end, *optend, *UNINIT_VAR(prev_found), *opt_str, key_name[FN_REFLEN]; const struct my_option *optp; gptr *value; diff --git a/mysys/my_redel.c b/mysys/my_redel.c index 0aec395cf65..03c1021a954 100644 --- a/mysys/my_redel.c +++ b/mysys/my_redel.c @@ -77,6 +77,7 @@ end: int my_copystat(const char *from, const char *to, int MyFlags) { struct stat statbuf; + int res; if (stat((char*) from, &statbuf)) { @@ -95,7 +96,7 @@ int my_copystat(const char *from, const char *to, int MyFlags) if (MyFlags & MY_LINK_WARNING) my_error(EE_LINK_WARNING,MYF(ME_BELL+ME_WAITTANG),from,statbuf.st_nlink); } - VOID(chown(to, statbuf.st_uid, statbuf.st_gid)); /* Copy ownership */ + res= chown(to, statbuf.st_uid, statbuf.st_gid); /* Copy ownership */ #endif /* MSDOS */ #ifndef VMS diff --git a/mysys/typelib.c b/mysys/typelib.c index 4fab6f20493..7416738ece7 100644 --- a/mysys/typelib.c +++ b/mysys/typelib.c @@ -44,7 +44,8 @@ int find_type(my_string x, TYPELIB *typelib, uint full_name) { - int find,pos,findpos; + int find,pos; + int UNINIT_VAR(findpos); /* guarded by find */ reg1 my_string i; reg2 const char *j; DBUG_ENTER("find_type"); @@ -55,7 +56,6 @@ int find_type(my_string x, TYPELIB *typelib, uint full_name) DBUG_PRINT("exit",("no count")); DBUG_RETURN(0); } - LINT_INIT(findpos); find=0; for (pos=0 ; (j=typelib->type_names[pos]) ; pos++) { diff --git a/regex/regcomp.c b/regex/regcomp.c index 9cba56a97dd..0a65c5021fb 100644 --- a/regex/regcomp.c +++ b/regex/regcomp.c @@ -213,11 +213,11 @@ register struct parse *p; int stop; /* character this ERE should end at */ { register char c; - register sopno prevback; - register sopno prevfwd; + register sopno UNINIT_VAR(prevback); + register sopno UNINIT_VAR(prevfwd); register sopno conc; register int first = 1; /* is this the first alternative? */ - LINT_INIT(prevback); LINT_INIT(prevfwd); + for (;;) { /* do a bunch of concatenated expressions */ conc = HERE(); diff --git a/sql-common/client.c b/sql-common/client.c index 0cd7ef78478..8f1f4a1fd5a 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1633,7 +1633,7 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused))) */ const char * STDCALL -mysql_get_ssl_cipher(MYSQL *mysql) +mysql_get_ssl_cipher(MYSQL *mysql __attribute__((unused))) { DBUG_ENTER("mysql_get_ssl_cipher"); #ifdef HAVE_OPENSSL @@ -1829,7 +1829,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, uint port, const char *unix_socket,ulong client_flag) { char buff[NAME_LEN+USERNAME_LENGTH+100]; - char *end,*host_info; + char *end,*host_info= NULL; my_socket sock; in_addr_t ip_addr; struct sockaddr_in sock_addr; @@ -1847,7 +1847,6 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, #endif init_sigpipe_variables DBUG_ENTER("mysql_real_connect"); - LINT_INIT(host_info); DBUG_PRINT("enter",("host: %s db: %s user: %s", host ? host : "(Null)", diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 16a64ebd947..d2ef9da25f5 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -160,7 +160,7 @@ enum enum_mysql_timestamp_type str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, uint flags, int *was_cut) { - uint field_length, year_length, digits, i, number_of_fields; + uint field_length, UNINIT_VAR(year_length), digits, i, number_of_fields; uint date[MAX_DATE_PARTS], date_len[MAX_DATE_PARTS]; uint add_hours= 0, start_loop; ulong not_zero_date, allow_space; @@ -174,7 +174,6 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, DBUG_PRINT("ENTER",("str: %.*s",length,str)); LINT_INIT(field_length); - LINT_INIT(year_length); LINT_INIT(last_field_pos); *was_cut= 0; diff --git a/sql/field.cc b/sql/field.cc index 2322c5d7b9d..b61e5fd2d79 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1736,16 +1736,16 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs) Pointers used when digits move from the left of the '.' to the right of the '.' (explained below) */ - const char *int_digits_tail_from; + const char *UNINIT_VAR(int_digits_tail_from); /* Number of 0 that need to be added at the left of the '.' (1E3: 3 zeros) */ - uint int_digits_added_zeros; + uint UNINIT_VAR(int_digits_added_zeros); /* Pointer used when digits move from the right of the '.' to the left of the '.' */ - const char *frac_digits_head_end; + const char *UNINIT_VAR(frac_digits_head_end); /* Number of 0 that need to be added at the right of the '.' (for 1E-3) */ - uint frac_digits_added_zeros; + uint UNINIT_VAR(frac_digits_added_zeros); char *pos,*tmp_left_pos,*tmp_right_pos; /* Pointers that are used as limits (begin and end of the field buffer) */ char *left_wall,*right_wall; @@ -1756,11 +1756,6 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs) */ bool is_cuted_fields_incr=0; - LINT_INIT(int_digits_tail_from); - LINT_INIT(int_digits_added_zeros); - LINT_INIT(frac_digits_head_end); - LINT_INIT(frac_digits_added_zeros); - /* There are three steps in this function : - parse the input string @@ -8854,10 +8849,8 @@ Field *make_field(char *ptr, uint32 field_length, const char *field_name, struct st_table *table) { - uchar *bit_ptr; - uchar bit_offset; - LINT_INIT(bit_ptr); - LINT_INIT(bit_offset); + uchar *UNINIT_VAR(bit_ptr); + uchar UNINIT_VAR(bit_offset); if (field_type == FIELD_TYPE_BIT && !f_bit_as_char(pack_flag)) { bit_ptr= null_pos; diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index fef2e21d271..7983ffbc6c8 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -78,7 +78,7 @@ static void split_file_name(const char *file_name, extern "C" void myrg_print_wrong_table(const char *table_name) { - LEX_STRING db, name; + LEX_STRING db= {NULL, 0}, name; char buf[FN_REFLEN]; split_file_name(table_name, &db, &name); memcpy(buf, db.str, db.length); diff --git a/sql/item.cc b/sql/item.cc index eecb48aa16f..03d752a85d9 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1635,7 +1635,7 @@ bool agg_item_collations_for_comparison(DTCollation &c, const char *fname, bool agg_item_set_converter(DTCollation &coll, const char *fname, Item **args, uint nargs, uint flags, int item_sep) { - Item **arg, *safe_args[2]; + Item **arg, *safe_args[2]= {NULL, NULL}; /* For better error reporting: save the first and the second argument. @@ -1644,8 +1644,6 @@ bool agg_item_set_converter(DTCollation &coll, const char *fname, doesn't display each argument's characteristics. - if nargs is 1, then this error cannot happen. */ - LINT_INIT(safe_args[0]); - LINT_INIT(safe_args[1]); if (nargs >=2 && nargs <= 3) { safe_args[0]= args[0]; @@ -5122,9 +5120,8 @@ bool Item_null::send(Protocol *protocol, String *packet) bool Item::send(Protocol *protocol, String *buffer) { - bool result; + bool UNINIT_VAR(result); // Will be set if null_value == 0 enum_field_types f_type; - LINT_INIT(result); // Will be set if null_value == 0 switch ((f_type=field_type())) { default: diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index c940c4ab3c0..8c655cdc369 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -352,8 +352,7 @@ static bool convert_constant_item(THD *thd, Item_field *field_item, /* For comparison purposes allow invalid dates like 2000-01-32 */ ulong orig_sql_mode= thd->variables.sql_mode; enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields; - ulonglong orig_field_val; /* original field value if valid */ - LINT_INIT(orig_field_val); + ulonglong UNINIT_VAR(orig_field_val); /* original field value if valid */ thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | MODE_INVALID_DATES; thd->count_cuted_fields= CHECK_FIELD_IGNORE; @@ -2453,19 +2452,13 @@ Item_func_nullif::is_null() Item *Item_func_case::find_item(String *str) { - String *first_expr_str, *tmp; - my_decimal *first_expr_dec, first_expr_dec_val; - longlong first_expr_int; - double first_expr_real; + String *UNINIT_VAR(first_expr_str), *tmp; + my_decimal *UNINIT_VAR(first_expr_dec), first_expr_dec_val; + longlong UNINIT_VAR(first_expr_int); + double UNINIT_VAR(first_expr_real); char buff[MAX_FIELD_WIDTH]; String buff_str(buff,sizeof(buff),default_charset()); - /* These will be initialized later */ - LINT_INIT(first_expr_str); - LINT_INIT(first_expr_int); - LINT_INIT(first_expr_real); - LINT_INIT(first_expr_dec); - if (first_expr_num != -1) { switch (cmp_type) diff --git a/sql/item_create.cc b/sql/item_create.cc index c897b7aef79..cbd015f300b 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -451,10 +451,9 @@ Item *create_func_cast(Item *a, Cast_target cast_type, const char *c_len, const char *c_dec, CHARSET_INFO *cs) { - Item *res; + Item *UNINIT_VAR(res); ulong len; uint dec; - LINT_INIT(res); switch (cast_type) { case ITEM_CAST_BINARY: res= new Item_func_binary(a); break; @@ -542,6 +541,9 @@ Item *create_func_cast(Item *a, Cast_target cast_type, res= new Item_char_typecast(a, len, cs ? cs : current_thd->variables.collation_connection); break; + + default: + DBUG_ASSERT(0); } return res; } diff --git a/sql/item_func.cc b/sql/item_func.cc index 6193ab285f2..3c1e2126008 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2275,9 +2275,8 @@ void Item_func_min_max::fix_length_and_dec() uint Item_func_min_max::cmp_datetimes(ulonglong *value) { - longlong min_max; + longlong UNINIT_VAR(min_max); uint min_max_idx= 0; - LINT_INIT(min_max); for (uint i=0; i < arg_count ; i++) { @@ -2345,8 +2344,7 @@ String *Item_func_min_max::val_str(String *str) } case STRING_RESULT: { - String *res; - LINT_INIT(res); + String *UNINIT_VAR(res); for (uint i=0; i < arg_count ; i++) { if (i == 0) @@ -2435,8 +2433,7 @@ longlong Item_func_min_max::val_int() my_decimal *Item_func_min_max::val_decimal(my_decimal *dec) { DBUG_ASSERT(fixed == 1); - my_decimal tmp_buf, *tmp, *res; - LINT_INIT(res); + my_decimal tmp_buf, *tmp, *UNINIT_VAR(res); if (compare_as_dates) { @@ -4974,8 +4971,7 @@ void Item_func_match::init_search(bool no_order) bool Item_func_match::fix_fields(THD *thd, Item **ref) { DBUG_ASSERT(fixed == 0); - Item *item; - LINT_INIT(item); // Safe as arg_count is > 1 + Item *UNINIT_VAR(item); // Safe as arg_count is > 1 maybe_null=1; join_key=0; diff --git a/sql/lock.cc b/sql/lock.cc index 3102497576f..97abd76b7c2 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -1216,11 +1216,10 @@ void unlock_global_read_lock(THD *thd) bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, bool is_not_commit) { - const char *old_message; + const char *UNINIT_VAR(old_message); bool result= 0, need_exit_cond; DBUG_ENTER("wait_if_global_read_lock"); - LINT_INIT(old_message); /* Assert that we do not own LOCK_open. If we would own it, other threads could not close their tables. This would make a pretty diff --git a/sql/log.cc b/sql/log.cc index ec8f5fe820b..c042651216c 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2635,9 +2635,10 @@ bool flush_error_log() else result= 1; #else + FILE *reopen; my_rename(log_error_file,err_renamed,MYF(0)); if (freopen(log_error_file,"a+",stdout)) - freopen(log_error_file,"a+",stderr); + reopen= freopen(log_error_file,"a+",stderr); else result= 1; #endif diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 778fc418392..fdf6cc03a44 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3514,11 +3514,10 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, { int idx; SEL_ARG **key,**end, **key_to_read= NULL; - ha_rows best_records; + ha_rows UNINIT_VAR(best_records); /* protected by key_to_read */ TRP_RANGE* read_plan= NULL; bool pk_is_clustered= param->table->file->primary_key_is_clustered(); DBUG_ENTER("get_key_scans_params"); - LINT_INIT(best_records); /* protected by key_to_read */ /* Note that there may be trees that have type SEL_TREE::KEY but contain no key reads at all, e.g. tree for expression "key1 is not null" where key1 @@ -5370,8 +5369,7 @@ static bool eq_tree(SEL_ARG* a,SEL_ARG *b) SEL_ARG * SEL_ARG::insert(SEL_ARG *key) { - SEL_ARG *element,**par,*last_element; - LINT_INIT(par); LINT_INIT(last_element); + SEL_ARG *element,**UNINIT_VAR(par),*UNINIT_VAR(last_element); for (element= this; element != &null_element ; ) { @@ -7918,7 +7916,9 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) goto next_index; } else + { DBUG_ASSERT(FALSE); + } /* Check (SA2). */ if (min_max_arg_item) diff --git a/sql/spatial.cc b/sql/spatial.cc index 80506f16d0f..6e1da589527 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -935,13 +935,10 @@ int Gis_polygon::interior_ring_n(uint32 num, String *result) const int Gis_polygon::centroid_xy(double *x, double *y) const { uint32 n_linear_rings; - double res_area; - double res_cx, res_cy; + double UNINIT_VAR(res_area); + double UNINIT_VAR(res_cx), UNINIT_VAR(res_cy); const char *data= m_data; bool first_loop= 1; - LINT_INIT(res_area); - LINT_INIT(res_cx); - LINT_INIT(res_cy); if (no_data(data, 4)) return 1; @@ -1634,14 +1631,10 @@ int Gis_multi_polygon::centroid(String *result) const uint32 n_polygons; bool first_loop= 1; Gis_polygon p; - double res_area, res_cx, res_cy; + double UNINIT_VAR(res_area), UNINIT_VAR(res_cx), UNINIT_VAR(res_cy); double cur_area, cur_cx, cur_cy; const char *data= m_data; - LINT_INIT(res_area); - LINT_INIT(res_cx); - LINT_INIT(res_cy); - if (no_data(data, 4)) return 1; n_polygons= uint4korr(data); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index ab4e518d5dd..ea17a4227ef 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -5067,17 +5067,13 @@ static int handle_grant_struct(uint struct_no, bool drop, uint elements; const char *user; const char *host; - ACL_USER *acl_user; - ACL_DB *acl_db; - GRANT_NAME *grant_name; + ACL_USER *UNINIT_VAR(acl_user); + ACL_DB *UNINIT_VAR(acl_db); + GRANT_NAME *UNINIT_VAR(grant_name); DBUG_ENTER("handle_grant_struct"); DBUG_PRINT("info",("scan struct: %u search: '%s'@'%s'", struct_no, user_from->user.str, user_from->host.str)); - LINT_INIT(acl_user); - LINT_INIT(acl_db); - LINT_INIT(grant_name); - safe_mutex_assert_owner(&acl_cache->lock); /* Get the number of elements in the in-memory structure. */ diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 6a99d5d1541..db4ab29d6de 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -706,7 +706,7 @@ void close_temporary_tables(THD *thd) return; } - TABLE *next, + TABLE *UNINIT_VAR(next), *prev_table /* prev link is not maintained in TABLE's double-linked list */; bool was_quote_show= true; /* to assume thd->options has OPTION_QUOTE_SHOW_CREATE */ // Better add "if exists", in case a RESET MASTER has been done @@ -716,7 +716,6 @@ void close_temporary_tables(THD *thd) memcpy(buf, stub, stub_len); String s_query= String(buf, sizeof(buf), system_charset_info); bool found_user_tables= false; - LINT_INIT(next); /* insertion sort of temp tables by pseudo_thread_id to build ordered list @@ -4142,8 +4141,7 @@ find_item_in_list(Item *find, List &items, uint *counter, (and not an item that happens to have a name). */ bool is_ref_by_name= 0; - uint unaliased_counter; - LINT_INIT(unaliased_counter); // Dependent on found_unaliased + uint UNINIT_VAR(unaliased_counter); // Dependent on found_unaliased *resolution= NOT_RESOLVED; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 45f70964f50..65b2a9d60b0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1325,7 +1325,7 @@ pthread_handler_t handle_bootstrap(void *arg) thd->init_for_queries(); while (fgets(buff, thd->net.max_packet, file)) { - char *query; + char *query, *res; ulong length= (ulong) strlen(buff); while (buff[length-1] != '\n' && !feof(file)) { @@ -1340,7 +1340,7 @@ pthread_handler_t handle_bootstrap(void *arg) break; } buff= (char*) thd->net.buff; - fgets(buff + length, thd->net.max_packet - length, file); + res= fgets(buff + length, thd->net.max_packet - length, file); length+= (ulong) strlen(buff + length); } if (thd->is_fatal_error) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index d14f14b526e..06f77f9689c 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2072,10 +2072,9 @@ void mysql_sql_stmt_prepare(THD *thd) LEX_STRING *name= &lex->prepared_stmt_name; Prepared_statement *stmt; const char *query; - uint query_len; + uint UNINIT_VAR(query_len); DBUG_ENTER("mysql_sql_stmt_prepare"); DBUG_ASSERT(thd->protocol == &thd->protocol_simple); - LINT_INIT(query_len); if ((stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name))) { diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 9eac750c22e..13045280c5f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2172,8 +2172,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) ST_SCHEMA_TABLE *schema_table= tables->schema_table; SELECT_LEX sel; INDEX_FIELD_VALUES idx_field_vals; - char path[FN_REFLEN], *end, *base_name, *orig_base_name, *file_name; - uint len; + char path[FN_REFLEN], *UNINIT_VAR(end), *base_name, *orig_base_name, *file_name; + uint UNINIT_VAR(len); bool with_i_schema; enum enum_schema_tables schema_table_idx; List bases; @@ -2190,9 +2190,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) #endif DBUG_ENTER("get_all_tables"); - LINT_INIT(end); - LINT_INIT(len); - lex->view_prepare_mode= TRUE; lex->reset_n_backup_query_tables_list(&query_tables_list_backup); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index c18c34fc1d1..06d1bcaa8fb 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -125,7 +125,7 @@ int mysql_update(THD *thd, uint want_privilege; #endif uint table_count= 0; - query_id_t query_id=thd->query_id, timestamp_query_id; + query_id_t query_id=thd->query_id, UNINIT_VAR(timestamp_query_id); ha_rows updated, found; key_map old_used_keys; TABLE *table; @@ -137,8 +137,6 @@ int mysql_update(THD *thd, THD::killed_state killed_status= THD::NOT_KILLED; DBUG_ENTER("mysql_update"); - LINT_INIT(timestamp_query_id); - for ( ; ; ) { if (open_tables(thd, &table_list, &table_count, 0)) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 96077aeeb12..8cf25e9d88c 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -955,7 +955,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, TABLE_LIST *top_view= table->top_table(); int res; bool result, view_is_mergeable; - TABLE_LIST *view_main_select_tables; + TABLE_LIST *UNINIT_VAR(view_main_select_tables); DBUG_ENTER("mysql_make_view"); DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name)); @@ -1218,7 +1218,6 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, view_is_mergeable= (table->algorithm != VIEW_ALGORITHM_TMPTABLE && lex->can_be_merged()); - LINT_INIT(view_main_select_tables); if (view_is_mergeable) { diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 65e4182d564..6657ef01785 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -202,11 +202,10 @@ static int my_strnncoll_ucs2(CHARSET_INFO *cs, my_bool t_is_prefix) { int s_res,t_res; - my_wc_t s_wc,t_wc; + my_wc_t UNINIT_VAR(s_wc),t_wc; const uchar *se=s+slen; const uchar *te=t+tlen; MY_UNICASE_INFO **uni_plane= cs->caseinfo; - LINT_INIT(s_wc); while ( s < se && t < te ) { @@ -317,11 +316,10 @@ static int my_strncasecmp_ucs2(CHARSET_INFO *cs, const char *s, const char *t, uint len) { int s_res,t_res; - my_wc_t s_wc,t_wc; + my_wc_t UNINIT_VAR(s_wc),t_wc; const char *se=s+len; const char *te=t+len; MY_UNICASE_INFO **uni_plane= cs->caseinfo; - LINT_INIT(s_wc); while ( s < se && t < te ) { @@ -1385,10 +1383,9 @@ int my_strnncoll_ucs2_bin(CHARSET_INFO *cs, my_bool t_is_prefix) { int s_res,t_res; - my_wc_t s_wc,t_wc; + my_wc_t UNINIT_VAR(s_wc),t_wc; const uchar *se=s+slen; const uchar *te=t+tlen; - LINT_INIT(s_wc); while ( s < se && t < te ) { diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 4682868562f..3fcde4aca64 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -2306,11 +2306,10 @@ static int my_strnncoll_utf8(CHARSET_INFO *cs, my_bool t_is_prefix) { int s_res,t_res; - my_wc_t s_wc,t_wc; + my_wc_t UNINIT_VAR(s_wc), t_wc; const uchar *se=s+slen; const uchar *te=t+tlen; MY_UNICASE_INFO **uni_plane= cs->caseinfo; - LINT_INIT(s_wc); while ( s < se && t < te ) { @@ -2377,10 +2376,9 @@ static int my_strnncollsp_utf8(CHARSET_INFO *cs, my_bool diff_if_only_endspace_difference) { int s_res, t_res, res; - my_wc_t s_wc,t_wc; + my_wc_t UNINIT_VAR(s_wc),t_wc; const uchar *se= s+slen, *te= t+tlen; MY_UNICASE_INFO **uni_plane= cs->caseinfo; - LINT_INIT(s_wc); #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE diff_if_only_endspace_difference= 0; diff --git a/strings/decimal.c b/strings/decimal.c index c535d0f73dc..7c2c2999fb8 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -1359,8 +1359,7 @@ int bin2decimal(char *from, decimal_t *to, int precision, int scale) if (intg0x) { int i=dig2bytes[intg0x]; - dec1 x; - LINT_INIT(x); + dec1 UNINIT_VAR(x); switch (i) { case 1: x=mi_sint1korr(from); break; @@ -1401,8 +1400,7 @@ int bin2decimal(char *from, decimal_t *to, int precision, int scale) if (frac0x) { int i=dig2bytes[frac0x]; - dec1 x; - LINT_INIT(x); + dec1 UNINIT_VAR(x); switch (i) { case 1: x=mi_sint1korr(from); break; @@ -1480,7 +1478,7 @@ decimal_round(decimal_t *from, decimal_t *to, int scale, decimal_round_mode mode) { int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1, - frac1=ROUND_UP(from->frac), round_digit, + frac1=ROUND_UP(from->frac), UNINIT_VAR(round_digit), intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len, intg1=ROUND_UP(from->intg + (((intg0 + frac0)>0) && (from->buf[0] == DIG_MAX))); @@ -1489,7 +1487,6 @@ decimal_round(decimal_t *from, decimal_t *to, int scale, sanity(to); - LINT_INIT(round_digit); switch (mode) { case HALF_UP: case HALF_EVEN: round_digit=5; break; @@ -2117,13 +2114,11 @@ static int do_div_mod(decimal_t *from1, decimal_t *from2, { int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1, frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2, - error, i, intg0, frac0, len1, len2, dintg, div_mod=(!mod); + UNINIT_VAR(error), i, intg0, frac0, len1, len2, dintg, div_mod=(!mod); dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1, *start2, *stop2, *stop1, *stop0, norm2, carry, *start1, dcarry; dec2 norm_factor, x, guess, y; - LINT_INIT(error); - if (mod) to=mod; From dc7106f5cae48d59ec6d30ad289d085e82f4bd7c Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 28 Aug 2009 18:49:16 -0300 Subject: [PATCH 045/138] Reduce test case runtime. mysql-test/r/lock_multi_bug38499.result: Update test case result. mysql-test/r/lock_multi_bug38691.result: Update test case result. mysql-test/t/lock_multi_bug38499.test: Do not sync .frm files. mysql-test/t/lock_multi_bug38691.test: Do not sync .frm files. --- mysql-test/r/lock_multi_bug38499.result | 3 +++ mysql-test/r/lock_multi_bug38691.result | 3 +++ mysql-test/t/lock_multi_bug38499.test | 5 +++++ mysql-test/t/lock_multi_bug38691.test | 5 +++++ 4 files changed, 16 insertions(+) diff --git a/mysql-test/r/lock_multi_bug38499.result b/mysql-test/r/lock_multi_bug38499.result index fd0f2138a8d..9b3f57c8e53 100644 --- a/mysql-test/r/lock_multi_bug38499.result +++ b/mysql-test/r/lock_multi_bug38499.result @@ -1,3 +1,5 @@ +SET @odl_sync_frm = @@global.sync_frm; +SET @@global.sync_frm = OFF; DROP TABLE IF EXISTS t1; CREATE TABLE t1( a INT, b INT ); INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4); @@ -17,3 +19,4 @@ ALTER TABLE t1 ADD COLUMN a INT; # 2.2.1. normal mode # 2.2.2. PS mode DROP TABLE t1; +SET @@global.sync_frm = @odl_sync_frm; diff --git a/mysql-test/r/lock_multi_bug38691.result b/mysql-test/r/lock_multi_bug38691.result index 74b9603d8e3..d0aa1c0277c 100644 --- a/mysql-test/r/lock_multi_bug38691.result +++ b/mysql-test/r/lock_multi_bug38691.result @@ -1,3 +1,5 @@ +SET @odl_sync_frm = @@global.sync_frm; +SET @@global.sync_frm = OFF; DROP TABLE IF EXISTS t1,t2,t3; CREATE TABLE t1 ( a int(11) unsigned default NULL, @@ -15,3 +17,4 @@ CREATE TABLE t3 SELECT * FROM t1; # normal mode # PS mode DROP TABLE t1, t2, t3; +SET @@global.sync_frm = @odl_sync_frm; diff --git a/mysql-test/t/lock_multi_bug38499.test b/mysql-test/t/lock_multi_bug38499.test index 8178987e802..3d3f084ba5f 100644 --- a/mysql-test/t/lock_multi_bug38499.test +++ b/mysql-test/t/lock_multi_bug38499.test @@ -5,6 +5,9 @@ # Save the initial number of concurrent sessions --source include/count_sessions.inc +SET @odl_sync_frm = @@global.sync_frm; +SET @@global.sync_frm = OFF; + connect (locker,localhost,root,,); connect (writer,localhost,root,,); @@ -214,6 +217,8 @@ DROP TABLE t1; --disconnect locker --disconnect writer +SET @@global.sync_frm = @odl_sync_frm; + # End of 5.0 tests # Wait till all disconnects are completed diff --git a/mysql-test/t/lock_multi_bug38691.test b/mysql-test/t/lock_multi_bug38691.test index 0458f31579e..881a0d8e502 100644 --- a/mysql-test/t/lock_multi_bug38691.test +++ b/mysql-test/t/lock_multi_bug38691.test @@ -8,6 +8,9 @@ # Save the initial number of concurrent sessions --source include/count_sessions.inc +SET @odl_sync_frm = @@global.sync_frm; +SET @@global.sync_frm = OFF; + # Test to see if select will get the lock ahead of low priority update connect (locker,localhost,root,,); @@ -136,6 +139,8 @@ DROP TABLE t1, t2, t3; --disconnect locker --disconnect writer +SET @@global.sync_frm = @odl_sync_frm; + # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc From abe47a0ebebf6ced1f71e8a79760d254962b52d4 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Sat, 29 Aug 2009 10:30:59 +0200 Subject: [PATCH 046/138] A few more suppression fixes after 42408 --- mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result | 1 + mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test | 3 +++ mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result | 1 + 3 files changed, 5 insertions(+) diff --git a/mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result b/mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result index 777f7d8427b..71c17321117 100644 --- a/mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result +++ b/mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("Slave: Error writing file 'UNKNOWN' (Errcode: 9) Error_code: 3"); stop slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; diff --git a/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test b/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test index 39f3b700f94..3a1fbe04e17 100644 --- a/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test +++ b/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test @@ -7,6 +7,9 @@ # 1 - Creates a table and populates it through "LOAD DATA INFILE". # 2 - Catches error. ########################################################################## + +call mtr.add_suppression("Slave: Error writing file 'UNKNOWN' (Errcode: 9) Error_code: 3"); + --source include/have_binlog_format_mixed_or_statement.inc --source include/have_innodb.inc --source include/have_debug.inc diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result index d51599fd18b..f812509de6f 100644 --- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result +++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result @@ -4,6 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +call mtr.add_suppression("Slave: Unknown table 't6' Error_code: 1051"); **** Diff Table Def Start **** *** On Slave *** STOP SLAVE; From f32c08bd0ca20d23e95ca46912044d48282cfd6f Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 29 Aug 2009 16:52:22 +0800 Subject: [PATCH 047/138] Bug #44331 Restore of database with events produces warning in replication If an EVENT is created without the DEFINER clause set explicitly or with it set to CURRENT_USER, the master and slaves become inconsistent. This issue stems from the fact that in both cases, the DEFINER is set to the CURRENT_USER of the current thread. On the master, the CURRENT_USER is the mysqld's user, while on the slave, the CURRENT_USER is empty for the SQL Thread which is responsible for executing the statement. To fix the problem, we do what follows. If the definer is not set explicitly, a DEFINER clause is added when writing the query into binlog; if 'CURRENT_USER' is used as the DEFINER, it is replaced with the value of the current user before writing to binlog. mysql-test/suite/rpl/r/rpl_create_if_not_exists.result: Updated the result file after fixing bug#44331 mysql-test/suite/rpl/r/rpl_drop_if_exists.result: Updated the result file after fixing bug#44331 mysql-test/suite/rpl/r/rpl_events.result: Test result of Bug#44331 mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result: Updated the result file after fixing bug#44331 mysql-test/suite/rpl/t/rpl_events.test: Added test to verify if the definer is consistent between master and slave when the event is created without the DEFINER clause set explicitly or the DEFINER is set to CURRENT_USER sql/events.cc: The "create_query_string" function is added to create a new query string for removing executable comments. sql/sql_yacc.yy: The remember_name token was added for recording the offset of EVENT_SYM. --- .../rpl/r/rpl_create_if_not_exists.result | 2 +- .../suite/rpl/r/rpl_drop_if_exists.result | 4 +- mysql-test/suite/rpl/r/rpl_events.result | 42 +++++++++++++++++ .../suite/rpl/r/rpl_innodb_mixed_dml.result | 4 +- mysql-test/suite/rpl/t/rpl_events.test | 46 +++++++++++++++++-- sql/events.cc | 38 ++++++++++++++- sql/sql_yacc.yy | 7 +-- 7 files changed, 131 insertions(+), 12 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result b/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result index 536f40dc7f1..12a956a6ce6 100644 --- a/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result +++ b/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result @@ -29,5 +29,5 @@ t1 t2 SHOW EVENTS in mysqltest; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation -mysqltest e @ SYSTEM ONE TIME # NULL NULL NULL NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci +mysqltest e root@localhost SYSTEM ONE TIME # NULL NULL NULL NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci DROP DATABASE IF EXISTS mysqltest; diff --git a/mysql-test/suite/rpl/r/rpl_drop_if_exists.result b/mysql-test/suite/rpl/r/rpl_drop_if_exists.result index 59a2470cfdb..e2d4c727c98 100644 --- a/mysql-test/suite/rpl/r/rpl_drop_if_exists.result +++ b/mysql-test/suite/rpl/r/rpl_drop_if_exists.result @@ -43,7 +43,7 @@ master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS db_bug_13684.t master-bin.000001 # Query # # DROP DATABASE IF EXISTS db_bug_13684 master-bin.000001 # Query # # CREATE DATABASE db_bug_13684 master-bin.000001 # Query # # use `test`; CREATE TABLE db_bug_13684.t (a int) -master-bin.000001 # Query # # use `test`; CREATE EVENT db_bug_13684.e +master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` EVENT db_bug_13684.e ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO UPDATE db_bug_13684.t SET a = a + 1 @@ -75,7 +75,7 @@ master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS db_bug_13684.t master-bin.000001 # Query # # DROP DATABASE IF EXISTS db_bug_13684 master-bin.000001 # Query # # CREATE DATABASE db_bug_13684 master-bin.000001 # Query # # use `test`; CREATE TABLE db_bug_13684.t (a int) -master-bin.000001 # Query # # use `test`; CREATE EVENT db_bug_13684.e +master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` EVENT db_bug_13684.e ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO UPDATE db_bug_13684.t SET a = a + 1 diff --git a/mysql-test/suite/rpl/r/rpl_events.result b/mysql-test/suite/rpl/r/rpl_events.result index b797183f9d2..8538d2ca373 100644 --- a/mysql-test/suite/rpl/r/rpl_events.result +++ b/mysql-test/suite/rpl/r/rpl_events.result @@ -191,5 +191,47 @@ select * from t28953; END;| ALTER EVENT event1 RENAME TO event2; DROP EVENT event2; +CREATE TABLE test.t1(details CHAR(30)); +CREATE EVENT /*!50000 event44331_1 */ +ON SCHEDULE AT CURRENT_TIMESTAMP +ON COMPLETION PRESERVE DISABLE +DO INSERT INTO test.t1 VALUES('event event44331_1 fired - no definer'); +CREATE DEFINER=CURRENT_USER /*!50000 EVENT event44331_2 */ +ON SCHEDULE AT CURRENT_TIMESTAMP +ON COMPLETION PRESERVE DISABLE +DO INSERT INTO test.t1 VALUES('event event44331_2 fired - DEFINER=CURRENT_USER'); +CREATE DEFINER=CURRENT_USER() EVENT event44331_3 +ON SCHEDULE AT CURRENT_TIMESTAMP +ON COMPLETION PRESERVE DISABLE +DO INSERT INTO test.t1 VALUES('event event44331_3 fired - DEFINER=CURRENT_USER() function'); +CREATE /*!50000 DEFINER='user44331' */ EVENT event44331_4 +ON SCHEDULE AT CURRENT_TIMESTAMP +ON COMPLETION PRESERVE DISABLE +DO INSERT INTO test.t1 VALUES('event event44331_4 fired - DEFINER=user1'); +Warnings: +Note 1449 The user specified as a definer ('user44331'@'%') does not exist +#on master +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events +where EVENT_NAME='event44331_1' || EVENT_NAME='event44331_2' || +EVENT_NAME='event44331_3' || EVENT_NAME='event44331_4'; +EVENT_SCHEMA EVENT_NAME DEFINER +test event44331_1 root@localhost +test event44331_2 root@localhost +test event44331_3 root@localhost +test event44331_4 user44331@% +#on slave +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events +where EVENT_NAME='event44331_1' || EVENT_NAME='event44331_2' || +EVENT_NAME='event44331_3' || EVENT_NAME='event44331_4'; +EVENT_SCHEMA EVENT_NAME DEFINER +test event44331_1 root@localhost +test event44331_2 root@localhost +test event44331_3 root@localhost +test event44331_4 user44331@% SET @@global.event_scheduler= @old_event_scheduler; DROP TABLE t28953; +DROP TABLE t1; +DROP EVENT event44331_1; +DROP EVENT event44331_2; +DROP EVENT event44331_3; +DROP EVENT event44331_4; diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result index 6c5ab43da5f..81c486cb43c 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result @@ -690,7 +690,7 @@ test_rpl e1 root@localhost SYSTEM RECURRING NULL 1 # # NULL ENABLED 1 latin1 lat USE test_rpl; SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation -test_rpl e1 @ SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci +test_rpl e1 root@localhost SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci ==========MASTER========== SELECT COUNT(*) FROM t1; COUNT(*) @@ -1078,7 +1078,7 @@ master-bin.000001 # Query 1 # use `test_rpl`; GRANT EVENT ON *.* TO 'root'@'loca master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 'test1') master-bin.000001 # Xid 1 # # -master-bin.000001 # Query 1 # use `test_rpl`; CREATE EVENT e1 ON SCHEDULE EVERY '1' SECOND COMMENT 'e_second_comment' DO DELETE FROM t1 +master-bin.000001 # Query 1 # use `test_rpl`; CREATE DEFINER=`root`@`localhost` EVENT e1 ON SCHEDULE EVERY '1' SECOND COMMENT 'e_second_comment' DO DELETE FROM t1 master-bin.000001 # Query 1 # use `test_rpl`; ALTER EVENT e1 RENAME TO e2 master-bin.000001 # Query 1 # use `test_rpl`; DROP EVENT e2 master-bin.000001 # Query 1 # BEGIN diff --git a/mysql-test/suite/rpl/t/rpl_events.test b/mysql-test/suite/rpl/t/rpl_events.test index d06a3118389..f306fb10972 100644 --- a/mysql-test/suite/rpl/t/rpl_events.test +++ b/mysql-test/suite/rpl/t/rpl_events.test @@ -46,12 +46,52 @@ connection master; DROP EVENT event2; -sync_slave_with_master; +# +# BUG#44331 +# This test verifies if the definer is consistent between master and slave, +# when the event is created without the DEFINER clause set explicitly or the +# DEFINER is set to CURRENT_USER +# +CREATE TABLE test.t1(details CHAR(30)); -# Doing cleanup of the table referred to in the event to guarantee -# that there is no bad timing cauing it to try to access the table. +CREATE EVENT /*!50000 event44331_1 */ + ON SCHEDULE AT CURRENT_TIMESTAMP + ON COMPLETION PRESERVE DISABLE + DO INSERT INTO test.t1 VALUES('event event44331_1 fired - no definer'); + +CREATE DEFINER=CURRENT_USER /*!50000 EVENT event44331_2 */ + ON SCHEDULE AT CURRENT_TIMESTAMP + ON COMPLETION PRESERVE DISABLE + DO INSERT INTO test.t1 VALUES('event event44331_2 fired - DEFINER=CURRENT_USER'); + +CREATE DEFINER=CURRENT_USER() EVENT event44331_3 + ON SCHEDULE AT CURRENT_TIMESTAMP + ON COMPLETION PRESERVE DISABLE + DO INSERT INTO test.t1 VALUES('event event44331_3 fired - DEFINER=CURRENT_USER() function'); + +CREATE /*!50000 DEFINER='user44331' */ EVENT event44331_4 + ON SCHEDULE AT CURRENT_TIMESTAMP + ON COMPLETION PRESERVE DISABLE + DO INSERT INTO test.t1 VALUES('event event44331_4 fired - DEFINER=user1'); + +--echo #on master +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events + where EVENT_NAME='event44331_1' || EVENT_NAME='event44331_2' || + EVENT_NAME='event44331_3' || EVENT_NAME='event44331_4'; + +sync_slave_with_master; +connection slave; +--echo #on slave +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events + where EVENT_NAME='event44331_1' || EVENT_NAME='event44331_2' || + EVENT_NAME='event44331_3' || EVENT_NAME='event44331_4'; connection master; SET @@global.event_scheduler= @old_event_scheduler; DROP TABLE t28953; +DROP TABLE t1; +DROP EVENT event44331_1; +DROP EVENT event44331_2; +DROP EVENT event44331_3; +DROP EVENT event44331_4; sync_slave_with_master; diff --git a/sql/events.cc b/sql/events.cc index 10edfff2402..34da0e185b7 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -341,6 +341,33 @@ common_1_lev_code: } +/** + Create a new query string for removing executable comments + for avoiding leak and keeping consistency of the execution + on master and slave. + + @param[in] thd Thread handler + @param[in] buf Query string + + @return + 0 ok + 1 error +*/ +static int +create_query_string(THD *thd, String *buf) +{ + /* Append the "CREATE" part of the query */ + if (buf->append(STRING_WITH_LEN("CREATE "))) + return 1; + /* Append definer */ + append_definer(thd, buf, &(thd->lex->definer->user), &(thd->lex->definer->host)); + /* Append the left part of thd->query after "DEFINER" part */ + if (buf->append(thd->lex->stmt_definition_begin)) + return 1; + + return 0; +} + /** Create a new event. @@ -439,7 +466,16 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, { /* Binlog the create event. */ DBUG_ASSERT(thd->query && thd->query_length); - write_bin_log(thd, TRUE, thd->query, thd->query_length); + String log_query; + if (create_query_string(thd, &log_query)) + { + sql_print_error("Event Error: An error occurred while creating query string, " + "before writing it into binary log."); + DBUG_RETURN(TRUE); + } + /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER + will be written into the binary log as the definer for the SQL thread. */ + write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length()); } } pthread_mutex_unlock(&LOCK_event_metadata); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c7e955d122d..a18f57bf9cf 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1809,15 +1809,16 @@ server_option: ; event_tail: - EVENT_SYM opt_if_not_exists sp_name + remember_name EVENT_SYM opt_if_not_exists sp_name { THD *thd= YYTHD; LEX *lex=Lex; - lex->create_info.options= $2; + lex->stmt_definition_begin= $1; + lex->create_info.options= $3; if (!(lex->event_parse_data= Event_parse_data::new_instance(thd))) MYSQL_YYABORT; - lex->event_parse_data->identifier= $3; + lex->event_parse_data->identifier= $4; lex->event_parse_data->on_completion= Event_parse_data::ON_COMPLETION_DROP; From aa7e21c68fd36c66ac0603c416a29b1ca5d59b71 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Sat, 29 Aug 2009 23:29:47 +0200 Subject: [PATCH 048/138] even more suppression fixes --- mysql-test/suite/parts/r/partition_recover_myisam.result | 2 ++ mysql-test/suite/parts/t/partition_recover_myisam.test | 4 ++++ mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result | 2 +- mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test | 4 ++-- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/parts/r/partition_recover_myisam.result b/mysql-test/suite/parts/r/partition_recover_myisam.result index df737ec2853..49775ee498e 100644 --- a/mysql-test/suite/parts/r/partition_recover_myisam.result +++ b/mysql-test/suite/parts/r/partition_recover_myisam.result @@ -1,3 +1,5 @@ +call mtr.add_suppression("./test/t1_will_crash"); +call mtr.add_suppression("Got an error from unknown thread, ha_myisam.cc"); CREATE TABLE t1_will_crash (a INT, KEY (a)) ENGINE=MyISAM; INSERT INTO t1_will_crash VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11); FLUSH TABLES; diff --git a/mysql-test/suite/parts/t/partition_recover_myisam.test b/mysql-test/suite/parts/t/partition_recover_myisam.test index 14604bfeb15..64bc821ac37 100644 --- a/mysql-test/suite/parts/t/partition_recover_myisam.test +++ b/mysql-test/suite/parts/t/partition_recover_myisam.test @@ -1,4 +1,8 @@ # test the auto-recover (--myisam-recover) of partitioned myisam tables + +call mtr.add_suppression("./test/t1_will_crash"); +call mtr.add_suppression("Got an error from unknown thread, ha_myisam.cc"); + --source include/have_partition.inc --disable_warnings --disable_query_log diff --git a/mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result b/mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result index 71c17321117..bc6fa377dc3 100644 --- a/mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result +++ b/mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result @@ -1,4 +1,3 @@ -call mtr.add_suppression("Slave: Error writing file 'UNKNOWN' (Errcode: 9) Error_code: 3"); stop slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; @@ -52,3 +51,4 @@ Last_SQL_Errno 9 Last_SQL_Error Error in Begin_load_query event: write to '../../tmp/SQL_LOAD.data' failed drop table t1; drop table t1; +call mtr.add_suppression("Slave: Error writing file 'UNKNOWN' (Errcode: 9) Error_code: 3"); diff --git a/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test b/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test index 3a1fbe04e17..fe1fc730ba8 100644 --- a/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test +++ b/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test @@ -8,8 +8,6 @@ # 2 - Catches error. ########################################################################## -call mtr.add_suppression("Slave: Error writing file 'UNKNOWN' (Errcode: 9) Error_code: 3"); - --source include/have_binlog_format_mixed_or_statement.inc --source include/have_innodb.inc --source include/have_debug.inc @@ -50,3 +48,5 @@ drop table t1; connection slave; drop table t1; + +call mtr.add_suppression("Slave: Error writing file 'UNKNOWN' (Errcode: 9) Error_code: 3"); From 6ce48392ea410ecb9937ea07943cc6434a5ac378 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Sun, 30 Aug 2009 11:03:37 +0400 Subject: [PATCH 049/138] Bug #46607: Assertion failed: (cond_type == Item::FUNC_ITEM) results in server crash check_group_min_max_predicates() assumed the input condition item to be one of COND_ITEM, SUBSELECT_ITEM, or FUNC_ITEM. Since a condition of the form "field" is also a valid condition equivalent to "field <> 0", using such a condition in a query where the loose index scan was chosen resulted in a debug assertion failure. Fixed by handling conditions of the FIELD_ITEM type in check_group_min_max_predicates(). mysql-test/r/group_min_max.result: Added a test case for bug #46607. mysql-test/t/group_min_max.test: Added a test case for bug #46607. sql/opt_range.cc: Handle conditions of the FUNC_ITEM type in check_group_mix_max_predicates(). --- mysql-test/r/group_min_max.result | 12 ++++++++++++ mysql-test/t/group_min_max.test | 15 +++++++++++++++ sql/opt_range.cc | 12 +++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index 27448d3e949..ac9a53ca238 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2502,3 +2502,15 @@ a MAX(b) 2 1 DROP TABLE t; End of 5.0 tests +# +# Bug #46607: Assertion failed: (cond_type == Item::FUNC_ITEM) results in +# server crash +# +CREATE TABLE t (a INT, b INT, INDEX (a,b)); +INSERT INTO t VALUES (2,0), (2,0), (2,1), (2,1); +INSERT INTO t SELECT * FROM t; +SELECT a, MAX(b) FROM t WHERE b GROUP BY a; +a MAX(b) +2 1 +DROP TABLE t; +End of 5.1 tests diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index 981be3efece..c09a4fbf490 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -1018,3 +1018,18 @@ DROP TABLE t; --echo End of 5.0 tests + +--echo # +--echo # Bug #46607: Assertion failed: (cond_type == Item::FUNC_ITEM) results in +--echo # server crash +--echo # + +CREATE TABLE t (a INT, b INT, INDEX (a,b)); +INSERT INTO t VALUES (2,0), (2,0), (2,1), (2,1); +INSERT INTO t SELECT * FROM t; + +SELECT a, MAX(b) FROM t WHERE b GROUP BY a; + +DROP TABLE t; + +--echo End of 5.1 tests diff --git a/sql/opt_range.cc b/sql/opt_range.cc index e3aef02637f..d7438b7b9cc 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -9628,7 +9628,17 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item, */ if (cond_type == Item::SUBSELECT_ITEM) DBUG_RETURN(FALSE); - + + /* + Condition of the form 'field' is equivalent to 'field <> 0' and thus + satisfies the SA3 condition. + */ + if (cond_type == Item::FIELD_ITEM) + { + DBUG_PRINT("info", ("Analyzing: %s", cond->full_name())); + DBUG_RETURN(TRUE); + } + /* We presume that at this point there are no other Items than functions. */ DBUG_ASSERT(cond_type == Item::FUNC_ITEM); From 02f67d5b1f484ffd7e363ab8f3b108ea7b27e26c Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Sun, 30 Aug 2009 12:01:08 +0200 Subject: [PATCH 050/138] yet another 42408 followup --- mysql-test/suite/rpl/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index 38fc9e21322..cb7a2a98925 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -11,3 +11,4 @@ ############################################################################## rpl_cross_version : Bug#42311 2009-03-27 joro rpl_cross_version fails on macosx +rpl_slave_load_remove_tmpfile Bug#46996, unable to suppress warning From a00ba9ebea078f7dc12f7cd298782d1ada4bb4e9 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 31 Aug 2009 10:26:01 +0800 Subject: [PATCH 051/138] Bug #44331 Restore of database with events produces warning in replication Update the test case for BUG#44331 to fix the push build failure. --- mysql-test/suite/rpl/r/rpl_events.result | 24 ++++++++++++++++++++---- mysql-test/suite/rpl/t/rpl_events.test | 18 ++++++++++++++---- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_events.result b/mysql-test/suite/rpl/r/rpl_events.result index 8538d2ca373..b3fd85d7e28 100644 --- a/mysql-test/suite/rpl/r/rpl_events.result +++ b/mysql-test/suite/rpl/r/rpl_events.result @@ -212,21 +212,37 @@ Warnings: Note 1449 The user specified as a definer ('user44331'@'%') does not exist #on master select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events -where EVENT_NAME='event44331_1' || EVENT_NAME='event44331_2' || -EVENT_NAME='event44331_3' || EVENT_NAME='event44331_4'; +where EVENT_NAME='event44331_1'; EVENT_SCHEMA EVENT_NAME DEFINER test event44331_1 root@localhost +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events +where EVENT_NAME='event44331_2'; +EVENT_SCHEMA EVENT_NAME DEFINER test event44331_2 root@localhost +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events +where EVENT_NAME='event44331_3'; +EVENT_SCHEMA EVENT_NAME DEFINER test event44331_3 root@localhost +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events +where EVENT_NAME='event44331_4'; +EVENT_SCHEMA EVENT_NAME DEFINER test event44331_4 user44331@% #on slave select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events -where EVENT_NAME='event44331_1' || EVENT_NAME='event44331_2' || -EVENT_NAME='event44331_3' || EVENT_NAME='event44331_4'; +where EVENT_NAME='event44331_1'; EVENT_SCHEMA EVENT_NAME DEFINER test event44331_1 root@localhost +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events +where EVENT_NAME='event44331_2'; +EVENT_SCHEMA EVENT_NAME DEFINER test event44331_2 root@localhost +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events +where EVENT_NAME='event44331_3'; +EVENT_SCHEMA EVENT_NAME DEFINER test event44331_3 root@localhost +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events +where EVENT_NAME='event44331_4'; +EVENT_SCHEMA EVENT_NAME DEFINER test event44331_4 user44331@% SET @@global.event_scheduler= @old_event_scheduler; DROP TABLE t28953; diff --git a/mysql-test/suite/rpl/t/rpl_events.test b/mysql-test/suite/rpl/t/rpl_events.test index f306fb10972..7720ad6658c 100644 --- a/mysql-test/suite/rpl/t/rpl_events.test +++ b/mysql-test/suite/rpl/t/rpl_events.test @@ -76,15 +76,25 @@ CREATE /*!50000 DEFINER='user44331' */ EVENT event44331_4 --echo #on master select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events - where EVENT_NAME='event44331_1' || EVENT_NAME='event44331_2' || - EVENT_NAME='event44331_3' || EVENT_NAME='event44331_4'; + where EVENT_NAME='event44331_1'; +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events + where EVENT_NAME='event44331_2'; +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events + where EVENT_NAME='event44331_3'; +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events + where EVENT_NAME='event44331_4'; sync_slave_with_master; connection slave; --echo #on slave select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events - where EVENT_NAME='event44331_1' || EVENT_NAME='event44331_2' || - EVENT_NAME='event44331_3' || EVENT_NAME='event44331_4'; + where EVENT_NAME='event44331_1'; +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events + where EVENT_NAME='event44331_2'; +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events + where EVENT_NAME='event44331_3'; +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events + where EVENT_NAME='event44331_4'; connection master; SET @@global.event_scheduler= @old_event_scheduler; From 5166a56d0406fe6ab51e0b3cb91202497c888b8c Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 31 Aug 2009 09:24:59 +0200 Subject: [PATCH 052/138] forgot : in rpl's disabled.def --- mysql-test/suite/rpl/t/disabled.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index cb7a2a98925..546c0e6b194 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -11,4 +11,4 @@ ############################################################################## rpl_cross_version : Bug#42311 2009-03-27 joro rpl_cross_version fails on macosx -rpl_slave_load_remove_tmpfile Bug#46996, unable to suppress warning +rpl_slave_load_remove_tmpfile : Bug#46996, unable to suppress warning From d85148d84c88adebddbe4983efffdb5101d7963d Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Mon, 31 Aug 2009 10:01:13 -0700 Subject: [PATCH 053/138] Bug#35132: MySQLadmin --wait ping always crashes on Windows systems Failing to connect would release parts of the MYSQL struct. We would then proceed to try again to connect without re- initializing the struct. We prevent the unwanted freeing of data we'll still need now. client/mysqladmin.cc: Losing a connection (or not even getting on in the first place) should not trash the MYSQL-struct. Add a lot of comments. Rewrite re-connection fu. sql-common/client.c: Assert against bad parameters usually caused by de-initing a MYSQL-struct without re-initing it again before re-use. --- client/mysqladmin.cc | 128 +++++++++++++++++++++++++++++++++---------- sql-common/client.c | 9 +++ 2 files changed, 108 insertions(+), 29 deletions(-) diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 699c2081b86..1ff9012780e 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -22,6 +22,7 @@ #endif #include #include +#include #ifdef LATER_HAVE_NDBCLUSTER_DB #include "../ndb/src/mgmclient/ndb_mgmclient.h" @@ -358,6 +359,11 @@ int main(int argc,char *argv[]) mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset); if (sql_connect(&mysql, option_wait)) { + /* + We couldn't get an initial connection and will definitely exit. + The following just determines the exit-code we'll give. + */ + unsigned int err= mysql_errno(&mysql); if (err >= CR_MIN_ERROR && err <= CR_MAX_ERROR) error= 1; @@ -376,30 +382,69 @@ int main(int argc,char *argv[]) } else { + /* + --count=0 aborts right here. Otherwise iff --sleep=t ("interval") + is given a t!=0, we get an endless loop, or n iterations if --count=n + was given an n!=0. If --sleep wasn't given, we get one iteration. + + To wit, --wait loops the connection-attempts, while --sleep loops + the command execution (endlessly if no --count is given). + */ + while (!interrupted && (!opt_count_iterations || nr_iterations)) { new_line = 0; - if ((error=execute_commands(&mysql,argc,commands))) + + if ((error= execute_commands(&mysql,argc,commands))) { + /* + Unknown/malformed command always aborts and can't be --forced. + If the user got confused about the syntax, proceeding would be + dangerous ... + */ if (error > 0) - break; /* Wrong command error */ - if (!option_force) + break; + + /* + Command was well-formed, but failed on the server. Might succeed + on retry (if conditions on server change etc.), but needs --force + to retry. + */ + if (!option_force) + break; + } /* if((error= ... */ + + if (interval) /* --sleep=interval given */ + { + /* + If connection was dropped (unintentionally, or due to SHUTDOWN), + re-establish it if --wait ("retry-connect") was given and user + didn't signal for us to die. Otherwise, signal failure. + */ + + if (mysql.net.vio == 0) { if (option_wait && !interrupted) { - mysql_close(&mysql); - if (!sql_connect(&mysql, option_wait)) - { - sleep(1); /* Don't retry too rapidly */ - continue; /* Retry */ - } + sleep(1); + sql_connect(&mysql, option_wait); + /* + continue normally and decrease counters so that + "mysqladmin --count=1 --wait=1 shutdown" + cannot loop endlessly. + */ } - error=1; - break; - } - } - if (interval) - { + else + { + /* + connexion broke, and we have no order to re-establish it. fail. + */ + if (!option_force) + error= 1; + break; + } + } /* lost connection */ + sleep(interval); if (new_line) puts(""); @@ -407,10 +452,11 @@ int main(int argc,char *argv[]) nr_iterations--; } else - break; - } - mysql_close(&mysql); - } + break; /* no --sleep, done looping */ + } /* command-loop */ + } /* got connection */ + + mysql_close(&mysql); my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR)); my_free(user,MYF(MY_ALLOW_ZERO_PTR)); #ifdef HAVE_SMEM @@ -428,6 +474,17 @@ static sig_handler endprog(int signal_number __attribute__((unused))) interrupted=1; } +/** + @brief connect to server, optionally waiting for same to come up + + @param mysql connection struct + @param wait wait for server to come up? + (0: no, ~0: forever, n: cycles) + + @return Operation result + @retval 0 success + @retval 1 failure +*/ static my_bool sql_connect(MYSQL *mysql, uint wait) { @@ -436,7 +493,7 @@ static my_bool sql_connect(MYSQL *mysql, uint wait) for (;;) { if (mysql_real_connect(mysql,host,user,opt_password,NullS,tcp_port, - unix_port, 0)) + unix_port, CLIENT_REMEMBER_OPTIONS)) { mysql->reconnect= 1; if (info) @@ -447,9 +504,9 @@ static my_bool sql_connect(MYSQL *mysql, uint wait) return 0; } - if (!wait) + if (!wait) // was or reached 0, fail { - if (!option_silent) + if (!option_silent) // print diagnostics { if (!host) host= (char*) LOCAL_HOST; @@ -473,11 +530,18 @@ static my_bool sql_connect(MYSQL *mysql, uint wait) } return 1; } + if (wait != (uint) ~0) - wait--; /* One less retry */ + wait--; /* count down, one less retry */ + if ((mysql_errno(mysql) != CR_CONN_HOST_ERROR) && (mysql_errno(mysql) != CR_CONNECTION_ERROR)) { + /* + Error is worse than "server doesn't answer (yet?)"; + fail even if we still have "wait-coins" unless --force + was also given. + */ fprintf(stderr,"Got error: %s\n", mysql_error(mysql)); if (!option_force) return 1; @@ -501,11 +565,18 @@ static my_bool sql_connect(MYSQL *mysql, uint wait) } -/* - Execute a command. - Return 0 on ok - -1 on retryable error - 1 on fatal error +/** + @brief Execute all commands + + @details We try to execute all commands we were given, in the order + given, but return with non-zero as soon as we encounter trouble. + By that token, individual commands can be considered a conjunction + with boolean short-cut. + + @return success? + @retval 0 Yes! ALL commands worked! + @retval 1 No, one failed and will never work (malformed): fatal error! + @retval -1 No, one failed on the server, may work next time! */ static int execute_commands(MYSQL *mysql,int argc, char **argv) @@ -575,7 +646,6 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) mysql_error(mysql)); return -1; } - mysql_close(mysql); /* Close connection to avoid error messages */ argc=1; /* force SHUTDOWN to be the last command */ if (got_pidfile) { diff --git a/sql-common/client.c b/sql-common/client.c index 8f1f4a1fd5a..89de74ebd58 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -416,6 +416,15 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout) const char *prefix; int i; + /* + If this is NULL, somebody freed the MYSQL* options. mysql_close() + is a good candidate. We don't just silently (re)set it to + def_shared_memory_base_name as that would create really confusing/buggy + behavior if the user passed in a different name on the command-line or + in a my.cnf. + */ + DBUG_ASSERT(shared_memory_base_name != NULL); + /* get enough space base-name + '_' + longest suffix we might ever send */ From 71f4bfd6c7dba0ea4b00469d48e458f0e5eeaf67 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Tue, 1 Sep 2009 08:40:13 +0200 Subject: [PATCH 054/138] Only install the innodb plugin if the plugin directory exists. --- scripts/make_win_bin_dist | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist index ce89ea28303..9c17c26b445 100755 --- a/scripts/make_win_bin_dist +++ b/scripts/make_win_bin_dist @@ -287,8 +287,10 @@ cp libmysql/$TARGET/libmysql.dll \ regex/$TARGET/regex.lib \ strings/$TARGET/strings.lib \ zlib/$TARGET/zlib.lib $DESTDIR/lib/opt/ -cp storage/innodb_plugin/$TARGET/ha_innodb_plugin.dll \ - $DESTDIR/lib/plugin/ +if [ -d storage/innodb_plugin ]; then + cp storage/innodb_plugin/$TARGET/ha_innodb_plugin.dll \ + $DESTDIR/lib/plugin/ +fi if [ x"$TARGET" != x"release" ] ; then cp libmysql/$TARGET/libmysql.pdb \ @@ -297,8 +299,10 @@ if [ x"$TARGET" != x"release" ] ; then regex/$TARGET/regex.pdb \ strings/$TARGET/strings.pdb \ zlib/$TARGET/zlib.pdb $DESTDIR/lib/opt/ - cp storage/innodb_plugin/$TARGET/ha_innodb_plugin.pdb \ - $DESTDIR/lib/plugin/ + if [ -d storage/innodb_plugin ]; then + cp storage/innodb_plugin/$TARGET/ha_innodb_plugin.pdb \ + $DESTDIR/lib/plugin/ + fi fi @@ -319,10 +323,12 @@ if [ x"$PACK_DEBUG" = x"" -a -f "libmysql/debug/libmysql.lib" -o \ strings/debug/strings.pdb \ zlib/debug/zlib.lib \ zlib/debug/zlib.pdb $DESTDIR/lib/debug/ - cp storage/innodb_plugin/debug/ha_innodb_plugin.dll \ - storage/innodb_plugin/debug/ha_innodb_plugin.lib \ - storage/innodb_plugin/debug/ha_innodb_plugin.pdb \ - $DESTDIR/lib/plugin/debug/ + if [ -d storage/innodb_plugin ]; then + cp storage/innodb_plugin/debug/ha_innodb_plugin.dll \ + storage/innodb_plugin/debug/ha_innodb_plugin.lib \ + storage/innodb_plugin/debug/ha_innodb_plugin.pdb \ + $DESTDIR/lib/plugin/debug/ + fi fi # ---------------------------------------------------------------------- From 82a5cfa5ab5eb62b5de3d440cc842a07643cb0bb Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Tue, 1 Sep 2009 13:04:56 +0200 Subject: [PATCH 055/138] Post fix patch for bug#20577 and bug#46362. On 64-bits machines the calculation gets the wrong types and results in very large numbers. Fixed by explicitly cast month to (int) --- sql-common/my_time.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 18358519023..2ec1fc253a7 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -775,11 +775,12 @@ long calc_daynr(uint year,uint month,uint day) if (y == 0 && month == 0 && day == 0) DBUG_RETURN(0); /* Skip errors */ - delsum= (long) (365L * y+ 31*(month-1) +day); + /* Cast to int to be able to handle month == 0 */ + delsum= (long) (365 * y + 31 *((int) month - 1) + (int) day); if (month <= 2) y--; else - delsum-= (long) (month*4+23)/10; + delsum-= (long) ((int) month * 4 + 23) / 10; temp=(int) ((y/100+1)*3)/4; DBUG_PRINT("exit",("year: %d month: %d day: %d -> daynr: %ld", y+(month <= 2),month,day,delsum+y/4-temp)); From 3a78dbe48208e786f0e8ad81c78a0a09a1cf191a Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 1 Sep 2009 13:38:17 +0200 Subject: [PATCH 056/138] 46996 workaruond --- mysql-test/include/mtr_warnings.sql | 4 ---- mysql-test/suite/rpl/r/rpl_do_grant.result | 3 +++ .../suite/rpl/r/rpl_slave_load_remove_tmpfile.result | 2 +- mysql-test/suite/rpl/t/disabled.def | 1 - mysql-test/suite/rpl/t/rpl_do_grant.test | 7 ++++++- mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test | 2 +- 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql index 157244a9b0a..b73234e6142 100644 --- a/mysql-test/include/mtr_warnings.sql +++ b/mysql-test/include/mtr_warnings.sql @@ -172,10 +172,6 @@ INSERT INTO global_suppressions VALUES */ ("Can't find file: '.\\\\test\\\\\\?{8}.frm'"), - /* Added 2009-08-XX after fixing Bug #42408 */ - - ("Slave: Operation DROP USER failed for '.*'@'localhost' Error_code: 1396"), - ("THE_LAST_SUPPRESSION")|| diff --git a/mysql-test/suite/rpl/r/rpl_do_grant.result b/mysql-test/suite/rpl/r/rpl_do_grant.result index 69bcfad4347..0913b1afdbf 100644 --- a/mysql-test/suite/rpl/r/rpl_do_grant.result +++ b/mysql-test/suite/rpl/r/rpl_do_grant.result @@ -166,4 +166,7 @@ DROP FUNCTION upgrade_del_func; DROP FUNCTION upgrade_alter_func; DROP DATABASE bug42217_db; DROP USER 'create_rout_db'@'localhost'; +call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396"); +USE mtr; +call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396"); "End of test" diff --git a/mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result b/mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result index bc6fa377dc3..e2efcf08d7a 100644 --- a/mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result +++ b/mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result @@ -51,4 +51,4 @@ Last_SQL_Errno 9 Last_SQL_Error Error in Begin_load_query event: write to '../../tmp/SQL_LOAD.data' failed drop table t1; drop table t1; -call mtr.add_suppression("Slave: Error writing file 'UNKNOWN' (Errcode: 9) Error_code: 3"); +call mtr.add_suppression("Slave: Error writing file 'UNKNOWN' .Errcode: 9. Error_code: 3"); diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index 546c0e6b194..38fc9e21322 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -11,4 +11,3 @@ ############################################################################## rpl_cross_version : Bug#42311 2009-03-27 joro rpl_cross_version fails on macosx -rpl_slave_load_remove_tmpfile : Bug#46996, unable to suppress warning diff --git a/mysql-test/suite/rpl/t/rpl_do_grant.test b/mysql-test/suite/rpl/t/rpl_do_grant.test index 806de780086..a8b15516682 100644 --- a/mysql-test/suite/rpl/t/rpl_do_grant.test +++ b/mysql-test/suite/rpl/t/rpl_do_grant.test @@ -207,5 +207,10 @@ DROP FUNCTION upgrade_del_func; DROP FUNCTION upgrade_alter_func; DROP DATABASE bug42217_db; DROP USER 'create_rout_db'@'localhost'; - + +call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396"); +connection slave; +USE mtr; +call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396"); + --echo "End of test" diff --git a/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test b/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test index fe1fc730ba8..437e1ebb92d 100644 --- a/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test +++ b/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test @@ -49,4 +49,4 @@ connection slave; drop table t1; -call mtr.add_suppression("Slave: Error writing file 'UNKNOWN' (Errcode: 9) Error_code: 3"); +call mtr.add_suppression("Slave: Error writing file 'UNKNOWN' .Errcode: 9. Error_code: 3"); From 8c7c09cc636a745fb88e00a5e0a2b2738ab5945e Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 1 Sep 2009 09:32:26 -0300 Subject: [PATCH 057/138] Bug#45611: Minor code cleanup Remove a self assignment. Rework a few constructs to avoid a potential overflow. Based upon patch contributed by Michal Hrusecky storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp: Remove self assignment, the object is being initialized. storage/ndb/src/mgmsrv/InitConfigFileParser.cpp: Setup the string in a single snprintf. --- storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp | 4 ++-- storage/ndb/src/mgmsrv/InitConfigFileParser.cpp | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index a61a5bc035c..8f8d4aad9ab 100644 --- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -7521,8 +7521,8 @@ void Dbdict::execGET_TABINFOREQ(Signal* signal) return; } releaseSections(signal); - - DictObject * old_ptr_p = old_ptr_p = get_object(tableName, len); + + DictObject * old_ptr_p = get_object(tableName, len); if(old_ptr_p) obj_id = old_ptr_p->m_id; } else { diff --git a/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp b/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp index 569cb1eb654..560a9559999 100644 --- a/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp +++ b/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp @@ -208,11 +208,10 @@ InitConfigFileParser::run_config_rules(Context& ctx) ctx.m_config->put("NoOfNodes", nNodes); char tmpLine[MAX_LINE_LENGTH]; - BaseString::snprintf(tmpLine, MAX_LINE_LENGTH, "EXTERNAL SYSTEM_"); - strncat(tmpLine, system, MAX_LINE_LENGTH); - strncat(tmpLine, ":NoOfConnections", MAX_LINE_LENGTH); + BaseString::snprintf(tmpLine, MAX_LINE_LENGTH, + "EXTERNAL SYSTEM_%s:NoOfConnections", system); ctx.m_config->put(tmpLine, nExtConnections); - + Config * ret = new Config(); ret->m_configValues = (struct ndb_mgm_configuration*)ctx.m_configValues.getConfigValues(); ret->m_oldConfig = ctx.m_config; ctx.m_config = 0; From 2c6789aa3bcfcd21dd3c913ffe567e352b0a9280 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Tue, 1 Sep 2009 14:53:27 +0200 Subject: [PATCH 058/138] post push fix for bug#20577 and bug#46362, disabling warnings --- mysql-test/include/partition_date_range.inc | 6 ++++++ mysql-test/r/partition_pruning.result | 12 ++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/mysql-test/include/partition_date_range.inc b/mysql-test/include/partition_date_range.inc index c54396af9cb..5093cb3701d 100644 --- a/mysql-test/include/partition_date_range.inc +++ b/mysql-test/include/partition_date_range.inc @@ -21,6 +21,8 @@ SELECT * FROM t1 WHERE a >= '1001-00-00'; SELECT * FROM t1 WHERE a > '1001-00-00'; --sorted_result SELECT * FROM t1 WHERE a = '1001-00-00'; +--echo # Disabling warnings for the invalid date +--disable_warnings --sorted_result SELECT * FROM t1 WHERE a < '1999-02-31'; --sorted_result @@ -31,6 +33,7 @@ SELECT * FROM t1 WHERE a >= '1999-02-31'; SELECT * FROM t1 WHERE a > '1999-02-31'; --sorted_result SELECT * FROM t1 WHERE a = '1999-02-31'; +--enable_warnings --sorted_result SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; --sorted_result @@ -51,11 +54,14 @@ EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-00-00'; EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-00-00'; EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-00-00'; EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00'; +--echo # Disabling warnings for the invalid date +--disable_warnings EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31'; EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1999-02-31'; EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1999-02-31'; EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1999-02-31'; EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1999-02-31'; +--enable_warnings EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result index 86aa89be8a7..769d499fc0a 100644 --- a/mysql-test/r/partition_pruning.result +++ b/mysql-test/r/partition_pruning.result @@ -58,6 +58,7 @@ a SELECT * FROM t1 WHERE a = '1001-00-00'; a 1001-00-00 +# Disabling warnings for the invalid date SELECT * FROM t1 WHERE a < '1999-02-31'; a 0000-00-00 @@ -82,8 +83,6 @@ a 2001-01-01 SELECT * FROM t1 WHERE a = '1999-02-31'; a -Warning 1292 Incorrect date value: '1999-02-31' for column 'a' at row 1 -Warnings: SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; a 0000-00-00 @@ -139,6 +138,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL ref a a 4 const 1 Using where; Using index +# Disabling warnings for the invalid date EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 5 Using where; Using index @@ -218,6 +218,7 @@ a SELECT * FROM t1 WHERE a = '1001-00-00'; a 1001-00-00 +# Disabling warnings for the invalid date SELECT * FROM t1 WHERE a < '1999-02-31'; a 0000-00-00 @@ -297,6 +298,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 7 Using where +# Disabling warnings for the invalid date EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 ALL NULL NULL NULL NULL 7 Using where @@ -385,6 +387,7 @@ a SELECT * FROM t1 WHERE a = '1001-00-00'; a 1001-00-00 +# Disabling warnings for the invalid date SELECT * FROM t1 WHERE a < '1999-02-31'; a 0000-00-00 @@ -409,8 +412,6 @@ a 2001-01-01 SELECT * FROM t1 WHERE a = '1999-02-31'; a -Warning 1292 Incorrect date value: '1999-02-31' for column 'a' at row 1 -Warnings: SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; a 0000-00-00 @@ -466,6 +467,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL ref a a 4 const 1 Using where; Using index +# Disabling warnings for the invalid date EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index @@ -545,6 +547,7 @@ a SELECT * FROM t1 WHERE a = '1001-00-00'; a 1001-00-00 +# Disabling warnings for the invalid date SELECT * FROM t1 WHERE a < '1999-02-31'; a 0000-00-00 @@ -624,6 +627,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 7 Using where +# Disabling warnings for the invalid date EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where From c001f9cc16a345a08e51a4bf1a6b2642038aacfc Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 1 Sep 2009 16:39:13 +0300 Subject: [PATCH 059/138] Fixed a problem in how BUILD/check_cpu handles Core 2 Duo processors. This fixes the regression introduced in 5.1 that prevents 64 bit builds on Intel while still keeping the core2 hack operational so the cluster can build. --- BUILD/check-cpu | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/BUILD/check-cpu b/BUILD/check-cpu index 9fa48adfb5f..c0e87a675cb 100755 --- a/BUILD/check-cpu +++ b/BUILD/check-cpu @@ -70,6 +70,11 @@ check_cpu () { Alpha*EV6*) cpu_arg="ev6"; ;; + #Core 2 Duo + *Intel*Core\(TM\)2*) + cpu_arg="nocona" + core2="yes" + ;; # Intel ia32 *Intel*Core*|*X[eE][oO][nN]*) # a Xeon is just another pentium4 ... @@ -134,10 +139,6 @@ check_cpu () { *i386*) cpu_arg="i386" ;; - #Core 2 Duo - *Intel*Core\(TM\)2*) - cpu_arg="nocona" - ;; # Intel ia64 *Itanium*) cpu_arg="itanium" From fe3ea31d9310e14ffce99d23a9b5979864e96fe2 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 2 Sep 2009 11:17:33 +0200 Subject: [PATCH 060/138] Bug #32296 mysqltest fails to parse "append_file" inside a "while", it works inside a "if" Bug #41913 mysqltest cannot source files from if inside while Some commands require additional processing which only works first time Keep content for write_file or append_file with the st_command struct Add tests for those cases to mysqltest.test --- client/mysqltest.cc | 56 ++++++++++++++++++++++++++++------- mysql-test/r/mysqltest.result | 19 ++++-------- mysql-test/t/mysqltest.test | 26 ++++++++++++---- 3 files changed, 73 insertions(+), 28 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 0cf7e62ac8c..7965dafb863 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -417,6 +417,7 @@ static struct st_expected_errors saved_expected_errors; struct st_command { char *query, *query_buf,*first_argument,*last_argument,*end; + DYNAMIC_STRING content; int first_word_len, query_len; my_bool abort_on_error; struct st_expected_errors expected_errors; @@ -1138,6 +1139,8 @@ void free_used_memory() { struct st_command **q= dynamic_element(&q_lines, i, struct st_command**); my_free((*q)->query_buf,MYF(MY_ALLOW_ZERO_PTR)); + if ((*q)->content.str) + dynstr_free(&(*q)->content); my_free((*q),MYF(0)); } for (i= 0; i < 10; i++) @@ -3283,21 +3286,30 @@ void do_write_file_command(struct st_command *command, my_bool append) sizeof(write_file_args)/sizeof(struct command_arg), ' '); - /* If no delimiter was provided, use EOF */ - if (ds_delimiter.length == 0) - dynstr_set(&ds_delimiter, "EOF"); - if (!append && access(ds_filename.str, F_OK) == 0) { /* The file should not be overwritten */ die("File already exist: '%s'", ds_filename.str); } - init_dynamic_string(&ds_content, "", 1024, 1024); - read_until_delimiter(&ds_content, &ds_delimiter); - DBUG_PRINT("info", ("Writing to file: %s", ds_filename.str)); - str_to_file2(ds_filename.str, ds_content.str, ds_content.length, append); - dynstr_free(&ds_content); + ds_content= command->content; + /* If it hasn't been done already by a loop iteration, fill it in */ + if (! ds_content.str) + { + /* If no delimiter was provided, use EOF */ + if (ds_delimiter.length == 0) + dynstr_set(&ds_delimiter, "EOF"); + + init_dynamic_string(&ds_content, "", 1024, 1024); + read_until_delimiter(&ds_content, &ds_delimiter); + command->content= ds_content; + } + /* This function could be called even if "false", so check before printing */ + if (cur_block->ok) + { + DBUG_PRINT("info", ("Writing to file: %s", ds_filename.str)); + str_to_file2(ds_filename.str, ds_content.str, ds_content.length, append); + } dynstr_free(&ds_filename); dynstr_free(&ds_delimiter); DBUG_VOID_RETURN; @@ -7684,7 +7696,31 @@ int main(int argc, char **argv) command->type= Q_COMMENT; } - if (cur_block->ok) + my_bool ok_to_do= cur_block->ok; + /* + Some commands need to be "done" the first time if they may get + re-iterated over in a true context. This can only happen if there's + a while loop at some level above the current block. + */ + if (!ok_to_do) + { + if (command->type == Q_SOURCE || + command->type == Q_WRITE_FILE || + command->type == Q_APPEND_FILE || + command->type == Q_PERL) + { + for (struct st_block *stb= cur_block-1; stb >= block_stack; stb--) + { + if (stb->cmd == cmd_while) + { + ok_to_do= 1; + break; + } + } + } + } + + if (ok_to_do) { command->last_argument= command->first_argument; processed = 1; diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 52a1734ea54..f68413264e4 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -314,21 +314,10 @@ here is the sourced script 1 = outer loop variable before dec 0 = outer loop variable after dec - -2 = outer loop variable after while +outer=2 ifval=0 +outer=1 ifval=1 here is the sourced script -2 = outer loop variable before dec - -1 = outer loop variable after dec - -1 = outer loop variable after while -here is the sourced script - -1 = outer loop variable before dec - -0 = outer loop variable after dec - In loop here is the sourced script @@ -538,6 +527,10 @@ mysqltest: At line 1: Missing required argument 'filename' to command 'write_fil mysqltest: At line 1: End of file encountered before 'EOF' delimiter was found Content for test_file1 mysqltest: At line 1: File already exist: 'MYSQLTEST_VARDIR/tmp/test_file1.tmp' +These lines should be repeated, +if things work as expected +These lines should be repeated, +if things work as expected Some data for cat_file command of mysqltest diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 92f39d943b9..9859e73cfae 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -853,16 +853,18 @@ while ($outer) eval SELECT '$outer = outer loop variable after dec' AS ""; } +# Test source in an if in a while which is false on 1st iteration let $outer= 2; # Number of outer loops +let $ifval= 0; # false 1st time while ($outer) { - eval SELECT '$outer = outer loop variable after while' AS ""; + echo outer=$outer ifval=$ifval; - echo here is the sourced script; - - eval SELECT '$outer = outer loop variable before dec' AS ""; + if ($ifval) { + --source $MYSQLTEST_VARDIR/tmp/sourced.inc + } dec $outer; - eval SELECT '$outer = outer loop variable after dec' AS ""; + inc $ifval; } @@ -1663,6 +1665,20 @@ EOF remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +# Test append_file within while +let $outer= 2; # Number of outer loops +while ($outer) +{ + append_file $MYSQLTEST_VARDIR/tmp/app_while.tmp; +These lines should be repeated, +if things work as expected +EOF + dec $outer; +} + +cat_file $MYSQLTEST_VARDIR/tmp/app_while.tmp; +remove_file $MYSQLTEST_VARDIR/tmp/app_while.tmp; + # ---------------------------------------------------------------------------- # test for cat_file # ---------------------------------------------------------------------------- From 27065edafbe0bfaa2a0fab4b230d910a21014c90 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 2 Sep 2009 13:09:01 +0300 Subject: [PATCH 061/138] fixed compilation warnings --- tests/mysql_client_test.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 300b0347233..9394b0df40b 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16997,7 +16997,7 @@ static void test_bug20023() { MYSQL con; - int sql_big_selects_orig; + int sql_big_selects_orig= 0; /* Type of max_join_size is ha_rows, which might be ulong or off_t depending on the platform or configure options. Preserve the string @@ -17005,10 +17005,10 @@ static void test_bug20023() */ char max_join_size_orig[32]; - int sql_big_selects_2; - int sql_big_selects_3; - int sql_big_selects_4; - int sql_big_selects_5; + int sql_big_selects_2= 0; + int sql_big_selects_3= 0; + int sql_big_selects_4= 0; + int sql_big_selects_5= 0; char query_buffer[MAX_TEST_QUERY_LENGTH]; @@ -17147,7 +17147,7 @@ static void bug31418_impl() MYSQL con; my_bool is_null; - int rc; + int rc= 0; /* Create a new connection. */ From f0720480dc641195999086b5c36d3d6a03b1a935 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 2 Sep 2009 13:22:47 +0300 Subject: [PATCH 062/138] Fixed win32 compilation warnings --- mysys/my_redel.c | 2 ++ sql/sql_table.cc | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/mysys/my_redel.c b/mysys/my_redel.c index c03d1bc7c25..6521253f949 100644 --- a/mysys/my_redel.c +++ b/mysys/my_redel.c @@ -76,7 +76,9 @@ end: int my_copystat(const char *from, const char *to, int MyFlags) { struct stat statbuf; +#if !defined(__WIN__) && !defined(__NETWARE__) int res; +#endif if (stat((char*) from, &statbuf)) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9f88fa93c06..4ec104aedc3 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -117,7 +117,7 @@ static char* add_identifier(char *to_p, const char * end_p, *(to_p++)= '`'; *(to_p++)= *(conv_name++); } - else if (length < (end_p - to_p)) + else if (((long) length) < (end_p - to_p)) { to_p= strnmov(to_p, conv_name, length); conv_name+= length; From 453a941d50dc8ad60539812736021d74598f9ba7 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 2 Sep 2009 13:23:37 +0300 Subject: [PATCH 063/138] moved version to 5.0-main --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 557df1b1ffe..f79c1cd6319 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.0-bugteam" +tree_name = "mysql-5.0" From 32c7efa6b420b09e00d42b99f29a790064694d3b Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 2 Sep 2009 16:19:28 +0500 Subject: [PATCH 064/138] BUG#46483 - drop table of partitioned table may leave extraneous file Online/fast ALTER TABLE of a partitioned table may leave temporary file in database directory. Fixed by removing unnecessary call to handler::ha_create_handler_files(), which was creating partitioning definition file. mysql-test/r/partition_innodb.result: A test case for BUG#46483. mysql-test/t/partition_innodb.test: A test case for BUG#46483. sql/unireg.cc: Do not call ha_create_handler_files() when we were requested to create only dot-frm file. --- mysql-test/r/partition_innodb.result | 4 ++++ mysql-test/t/partition_innodb.test | 12 ++++++++++++ sql/unireg.cc | 8 ++++---- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result index ad4d08e89ff..8af9133ab3f 100644 --- a/mysql-test/r/partition_innodb.result +++ b/mysql-test/r/partition_innodb.result @@ -256,3 +256,7 @@ SUBPARTITION BY KEY (char_column) SUBPARTITIONS 2 (PARTITION p1 VALUES LESS THAN (5) ENGINE = MyISAM) */ drop table t1; +CREATE TABLE t1 (a INT) ENGINE=InnoDB +PARTITION BY list(a) (PARTITION p1 VALUES IN (1)); +CREATE INDEX i1 ON t1 (a); +DROP TABLE t1; diff --git a/mysql-test/t/partition_innodb.test b/mysql-test/t/partition_innodb.test index 2abbceffbb0..c2e98ab59b8 100644 --- a/mysql-test/t/partition_innodb.test +++ b/mysql-test/t/partition_innodb.test @@ -270,3 +270,15 @@ PARTITION BY RANGE (int_column) (PARTITION p1 VALUES LESS THAN (5)); show create table t1; drop table t1; + +# +# BUG#46483 - drop table of partitioned table may leave extraneous file +# Note: was only repeatable with InnoDB plugin +# +CREATE TABLE t1 (a INT) ENGINE=InnoDB + PARTITION BY list(a) (PARTITION p1 VALUES IN (1)); +CREATE INDEX i1 ON t1 (a); +DROP TABLE t1; +let $MYSQLD_DATADIR= `SELECT @@datadir`; +# Before the fix it should show extra file like #sql-2405_2.par +--list_files $MYSQLD_DATADIR/test/ * diff --git a/sql/unireg.cc b/sql/unireg.cc index 68a352e4a44..60674b8390b 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -412,10 +412,10 @@ int rea_create_table(THD *thd, const char *path, DBUG_ASSERT(*fn_rext(frm_name)); if (thd->variables.keep_files_on_create) create_info->options|= HA_CREATE_KEEP_FILES; - if (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG, create_info)) - goto err_handler; - if (!create_info->frm_only && ha_create_table(thd, path, db, table_name, - create_info,0)) + if (!create_info->frm_only && + (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG, + create_info) || + ha_create_table(thd, path, db, table_name, create_info, 0))) goto err_handler; DBUG_RETURN(0); From 3668f8a5be32bc273d0ae29c85be3ab7ec5b3cd0 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 2 Sep 2009 08:45:48 -0300 Subject: [PATCH 065/138] Increase thread stack size on HP-UX when built with debug. --- storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp b/storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp index 5300d5bbfd9..c107baca39f 100644 --- a/storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp +++ b/storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp @@ -106,8 +106,13 @@ void AsyncFile::doStart() { // Stacksize for filesystem threads - // An 8k stack should be enough +#if !defined(DBUG_OFF) && defined (__hpux) + // Empirical evidence indicates at least 32k + const NDB_THREAD_STACKSIZE stackSize = 32768; +#else + // Otherwise an 8k stack should be enough const NDB_THREAD_STACKSIZE stackSize = 8192; +#endif char buf[16]; numAsyncFiles++; From e512d6943447aae62c77b98bc75512387b991cdc Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 2 Sep 2009 09:02:22 -0300 Subject: [PATCH 066/138] Post-merge fix. Observe C declaration placement rules. --- mysys/mf_iocache.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index 3aab904a6e0..c4c48f9c121 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -228,18 +228,20 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, for (;;) { uint buffer_block; + /* + Unset MY_WAIT_IF_FULL bit if it is set, to prevent conflict with + MY_ZEROFILL. + */ + myf flags= (myf) (cache_myflags & ~(MY_WME | MY_WAIT_IF_FULL)); + if (cachesize < min_cache) cachesize = min_cache; buffer_block = cachesize; if (type == SEQ_READ_APPEND) buffer_block *= 2; - /* - Unset MY_WAIT_IF_FULL bit if it is set, to prevent conflict with - MY_ZEROFILL. - */ - myf flag = MYF((cache_myflags & ~ (MY_WME | MY_WAIT_IF_FULL)) | - (cachesize == min_cache ? MY_WME : 0)); - if ((info->buffer= (byte*) my_malloc(buffer_block, flag)) != 0) + if (cachesize == min_cache) + flags|= (myf) MY_WME; + if ((info->buffer= (byte*) my_malloc(buffer_block, flags)) != 0) { info->write_buffer=info->buffer; if (type == SEQ_READ_APPEND) From 7c9e39f5c5a57c1d68c146b3982d643f93750eda Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 2 Sep 2009 15:20:47 +0300 Subject: [PATCH 067/138] fixed a valgrind warning in partitioning code --- sql/sql_partition.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index d433ba0b0cc..08ff2daacb9 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -6909,6 +6909,7 @@ int get_part_iter_for_interval_via_walking(partition_info *part_info, Field *field; uint total_parts; partition_iter_func get_next_func; + part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE; if (is_subpart) { field= part_info->subpart_field_array[0]; From 183607b8c864684a67fea2c11fa2755abd11f6ab Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 2 Sep 2009 16:36:52 +0300 Subject: [PATCH 068/138] Backported the --parallel=str option from mtr2 for backward compatibility with the newer pb2 testing environments --- mysql-test/mysql-test-run.pl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index f60701b7b49..e98e05eadb1 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -302,6 +302,7 @@ our $debug_compiled_binaries; our %mysqld_variables; +our $opt_parallel; my $source_dist= 0; our $opt_max_save_core= 5; @@ -645,6 +646,7 @@ sub command_line_setup () { 'testcase-timeout=i' => \$opt_testcase_timeout, 'suite-timeout=i' => \$opt_suite_timeout, 'warnings|log-warnings' => \$opt_warnings, + 'parallel=s' => \$opt_parallel, # Options which are no longer used (map { $_ => \&warn_about_removed_option } @removed_options), @@ -5278,6 +5280,7 @@ Misc options the specified test case (if any) fast Don't try to clean up from earlier runs reorder Reorder tests to get fewer server restarts + parallel=STR Compatibility slot. Ignored. help Get this help text testcase-timeout=MINUTES Max test case run time (default $default_testcase_timeout) From b64e7fb5befaee89f1db90db05e80e4249feba77 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 2 Sep 2009 18:42:08 +0300 Subject: [PATCH 069/138] fixed a valgrind warning in partition_pruning --- sql/partition_info.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/partition_info.h b/sql/partition_info.h index 8832b6ee409..9f438e8260b 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -311,5 +311,6 @@ void init_all_partitions_iterator(partition_info *part_info, { part_iter->part_nums.start= part_iter->part_nums.cur= 0; part_iter->part_nums.end= part_info->no_parts; + part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE; part_iter->get_next= get_next_partition_id_range; } From 9d82084d20b172c68fc84f2f1d0bc3a7b2ee2c2e Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 2 Sep 2009 19:42:46 +0300 Subject: [PATCH 070/138] back to -bugteam --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index f044f8e62da..e613cefc614 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.1" +tree_name = "mysql-5.1-bugteam" From 4d676f314c5f41d3060b1326e677dc92487dcbcc Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 3 Sep 2009 08:19:54 +0200 Subject: [PATCH 071/138] Bug #47075 Wildcards in experimental test names destroyed when tested first time Extract substr into local variable --- mysql-test/lib/mtr_report.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index a246c5bbef6..f2131b9bd76 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -134,8 +134,8 @@ sub mtr_report_test ($) { # an asterisk at the end, determine if the characters up to # but excluding the asterisk are the same if ( $exp ne "" && substr($exp, -1, 1) eq "*" ) { - $exp = substr($exp, 0, length($exp) - 1); - if ( substr($test_name, 0, length($exp)) ne $exp ) { + my $nexp = substr($exp, 0, length($exp) - 1); + if ( substr($test_name, 0, length($nexp)) ne $nexp ) { # no match, try next entry next; } From b5e3f4a35837b8fc924b54cc26a803cfe770d2f5 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 3 Sep 2009 08:38:06 +0200 Subject: [PATCH 072/138] A few suppression follow-ups --- mysql-test/r/bug46080.result | 2 ++ mysql-test/r/partition_csv.result | 1 + mysql-test/t/bug46080.test | 3 +++ mysql-test/t/partition_csv.test | 2 ++ 4 files changed, 8 insertions(+) diff --git a/mysql-test/r/bug46080.result b/mysql-test/r/bug46080.result index 18c7c22829a..2173768cdad 100644 --- a/mysql-test/r/bug46080.result +++ b/mysql-test/r/bug46080.result @@ -2,6 +2,8 @@ # Bug #46080: group_concat(... order by) crashes server when # sort_buffer_size cannot allocate # +call mtr.add_suppression("Out of memory at line .*, 'my_alloc.c'"); +call mtr.add_suppression("needed .* byte .*k., memory in use: .* bytes .*k"); CREATE TABLE t1(a CHAR(255)); INSERT INTO t1 VALUES ('a'); SET @@SESSION.sort_buffer_size=5*16*1000000; diff --git a/mysql-test/r/partition_csv.result b/mysql-test/r/partition_csv.result index 07651f29da4..18e28d4670a 100644 --- a/mysql-test/r/partition_csv.result +++ b/mysql-test/r/partition_csv.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("Failed to write to mysql.general_log"); drop table if exists t1; create table t1 (a int) engine = csv diff --git a/mysql-test/t/bug46080.test b/mysql-test/t/bug46080.test index 7e56e3ce421..8b4cee4d8b0 100644 --- a/mysql-test/t/bug46080.test +++ b/mysql-test/t/bug46080.test @@ -3,6 +3,9 @@ --echo # sort_buffer_size cannot allocate --echo # +call mtr.add_suppression("Out of memory at line .*, 'my_alloc.c'"); +call mtr.add_suppression("needed .* byte .*k., memory in use: .* bytes .*k"); + CREATE TABLE t1(a CHAR(255)); INSERT INTO t1 VALUES ('a'); diff --git a/mysql-test/t/partition_csv.test b/mysql-test/t/partition_csv.test index dd2ef7c1d1f..44013dd4b0a 100644 --- a/mysql-test/t/partition_csv.test +++ b/mysql-test/t/partition_csv.test @@ -10,6 +10,8 @@ --source include/have_partition.inc --source include/have_csv.inc +call mtr.add_suppression("Failed to write to mysql.general_log"); + # # Bug#19307: Partitions: csv delete failure # = CSV engine crashes From 76b8bd35898ea74734b4c57c10bdb2928dd7dd55 Mon Sep 17 00:00:00 2001 From: Kristofer Pettersson Date: Thu, 3 Sep 2009 12:08:55 +0200 Subject: [PATCH 073/138] Bug#46486 warnings produced when running mysql_install_db During start up some plugins are disabled by default. This caused an additional warning level message to be emitted as a result of a previous bug patch. Since there is risk of unnecessary confusion regarding the operation level of the server the redundant information is removed. --- sql/sql_plugin.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index da168d36429..f00e1f72390 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1565,9 +1565,6 @@ void plugin_shutdown(void) } } - if (count > free_slots) - sql_print_warning("Forcing shutdown of %d plugins", count - free_slots); - plugins= (struct st_plugin_int **) my_alloca(sizeof(void*) * (count+1)); /* From 2fc9c5d19993f4af526b97153ee7363ac108831b Mon Sep 17 00:00:00 2001 From: Satya B Date: Thu, 3 Sep 2009 16:02:03 +0530 Subject: [PATCH 074/138] Fix for BUG#46591 - .frm file isn't sync'd with sync_frm enabled for CREATE TABLE...LIKE... The mysql server option 'sync_frm' is ignored when table is created with syntax CREATE TABLE .. LIKE.. Fixed by adding the MY_SYNC flag and calling my_sync() from my_copy() when the flag is set. In mysql_create_table(), when the 'sync_frm' is set, MY_SYNC flag is passed to my_copy(). Note: TestCase is not attached and can be tested manually using debugger. client/Makefile.am: BUG#46591 - .frm file isn't sync'd with sync_frm enabled for CREATE TABLE...LIKE... add my_sync to sources as it is used in my_copy() method include/my_sys.h: BUG#46591 - .frm file isn't sync'd with sync_frm enabled for CREATE TABLE...LIKE... MY_SYNC flag is added to call my_sync() method mysys/my_copy.c: BUG#46591 - .frm file isn't sync'd with sync_frm enabled for CREATE TABLE...LIKE... my_sync() is method is called when MY_SYNC is set in my_copy() sql/sql_table.cc: BUG#46591 - .frm file isn't sync'd with sync_frm enabled for CREATE TABLE...LIKE... Fixed mysql_create_like_table() to call my_sync() when opt_sync_frm variable is set --- client/Makefile.am | 1 + include/my_sys.h | 1 + mysys/my_copy.c | 7 +++++++ sql/sql_table.cc | 7 ++++++- 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/client/Makefile.am b/client/Makefile.am index e77d294b0ac..192b89f8a2c 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -35,6 +35,7 @@ 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_sync.c \ $(top_srcdir)/mysys/my_mkdir.c mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD) diff --git a/include/my_sys.h b/include/my_sys.h index 4254ec3dbcb..4ec4846f528 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -68,6 +68,7 @@ extern int NEAR my_errno; /* Last error in mysys */ #define MY_HOLD_ON_ERROR 256 /* my_realloc() ; Return old ptr on error */ #define MY_DONT_OVERWRITE_FILE 1024 /* my_copy: Don't overwrite file */ #define MY_THREADSAFE 2048 /* my_seek(): lock fd mutex */ +#define MY_SYNC 4096 /* my_copy(): sync dst file */ #define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */ #define MY_GIVE_INFO 2 /* Give time info about process*/ diff --git a/mysys/my_copy.c b/mysys/my_copy.c index b6bb925e898..f44a497fbc8 100644 --- a/mysys/my_copy.c +++ b/mysys/my_copy.c @@ -87,6 +87,13 @@ int my_copy(const char *from, const char *to, myf MyFlags) my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP))) goto err; + /* sync the destination file */ + if (MyFlags & MY_SYNC) + { + if (my_sync(to_file, MyFlags)) + goto err; + } + if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags)) DBUG_RETURN(-1); /* Error on close */ diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 84370873054..5a3100685e0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2773,6 +2773,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST *src_table, int err; bool res= TRUE; db_type not_used; + myf flags= MY_DONT_OVERWRITE_FILE; DBUG_ENTER("mysql_create_like_table"); /* @@ -2859,10 +2860,14 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST *src_table, DBUG_EXECUTE_IF("sleep_create_like_before_copy", my_sleep(6000000);); + if (opt_sync_frm && !(create_info->options & HA_LEX_CREATE_TMP_TABLE)) + flags|= MY_SYNC; + /* Create a new table by copying from source table + and sync the new table if the flag MY_SYNC is set */ - if (my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE))) + if (my_copy(src_path, dst_path, flags)) { if (my_errno == ENOENT) my_error(ER_BAD_DB_ERROR,MYF(0),db); From 629557ff13e28e3422dfa1c354c44ef2fd62e4d0 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 3 Sep 2009 18:03:46 +0300 Subject: [PATCH 075/138] Bug #46791: Assertion failed:(table->key_read==0),function unknown function,file sql_base.cc When uncacheable queries are written to a temp table the optimizer must preserve the original JOIN structure, because it is re-using the JOIN structure to read from the resulting temporary table. This was done only for uncacheable sub-queries. But top level queries can also benefit from this mechanism, specially if they're using index access and need a reset. Fixed by not limiting the saving of JOIN structure to subqueries exclusively. Added a new test file to extend the existing (large) subquery.test. --- mysql-test/r/subselect4.result | 30 ++++++++++++++++++++++++++++++ mysql-test/t/subselect4.test | 32 ++++++++++++++++++++++++++++++++ sql/sql_select.cc | 8 ++------ 3 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 mysql-test/r/subselect4.result create mode 100644 mysql-test/t/subselect4.test diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result new file mode 100644 index 00000000000..68577cb2a4c --- /dev/null +++ b/mysql-test/r/subselect4.result @@ -0,0 +1,30 @@ +# +# Bug #46791: Assertion failed:(table->key_read==0),function unknown +# function,file sql_base.cc +# +CREATE TABLE t1 (a INT, b INT, KEY(a)); +INSERT INTO t1 VALUES (1,1),(2,2); +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES (1,1),(2,2); +CREATE TABLE t3 LIKE t1; +# should have 1 impossible where and 2 dependent subqueries +EXPLAIN +SELECT 1 FROM t1 +WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3)) +ORDER BY count(*); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index NULL a 5 NULL 2 Using index; Using temporary +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where +3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table +# should not crash the next statement +SELECT 1 FROM t1 +WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3)) +ORDER BY count(*); +1 +1 +# should not crash: the crash is caused by the previous statement +SELECT 1; +1 +1 +DROP TABLE t1,t2,t3; +End of 5.0 tests. diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test new file mode 100644 index 00000000000..ff4cdf3c439 --- /dev/null +++ b/mysql-test/t/subselect4.test @@ -0,0 +1,32 @@ +# General purpose bug fix tests go here : subselect.test too large + + +--echo # +--echo # Bug #46791: Assertion failed:(table->key_read==0),function unknown +--echo # function,file sql_base.cc +--echo # + +CREATE TABLE t1 (a INT, b INT, KEY(a)); +INSERT INTO t1 VALUES (1,1),(2,2); +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES (1,1),(2,2); +CREATE TABLE t3 LIKE t1; + +--echo # should have 1 impossible where and 2 dependent subqueries +EXPLAIN +SELECT 1 FROM t1 +WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3)) +ORDER BY count(*); + +--echo # should not crash the next statement +SELECT 1 FROM t1 +WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3)) +ORDER BY count(*); + +--echo # should not crash: the crash is caused by the previous statement +SELECT 1; + +DROP TABLE t1,t2,t3; + + +--echo End of 5.0 tests. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b670e6e3637..9d5e67c9532 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1474,12 +1474,8 @@ JOIN::optimize() } } - /* - If this join belongs to an uncacheable subquery save - the original join - */ - if (select_lex->uncacheable && !is_top_level_join() && - init_save_join_tab()) + /* If this join belongs to an uncacheable query save the original join */ + if (select_lex->uncacheable && init_save_join_tab()) DBUG_RETURN(-1); /* purecov: inspected */ } From 19d0529819c65dc4662b6a388fea7fbc7323b2f1 Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Thu, 3 Sep 2009 18:20:43 +0200 Subject: [PATCH 076/138] Raise version number after cloning 5.1.39 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 5b9f3e0f200..b974d7076d7 100644 --- a/configure.in +++ b/configure.in @@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM # # When changing major version number please also check switch statement # in mysqlbinlog::check_master_version(). -AM_INIT_AUTOMAKE(mysql, 5.1.39) +AM_INIT_AUTOMAKE(mysql, 5.1.40) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 From fe79cb53853b9b0cdd81b21d144c9faaba586421 Mon Sep 17 00:00:00 2001 From: Satya B Date: Thu, 3 Sep 2009 23:34:42 +0530 Subject: [PATCH 077/138] Fix for Bug#33785 - myisamchk show warning message myisamchk tool generates warnings when run on an myisam files (.MYI or .MYD) This is because of the conversion of max_value for certain options in myisamchk from singed long to unsigned long The max value for the options key_buffer_size, read_buffer_size, write_buffer _size and sort_buffer_size is given as (long) ~0L which becomes -1 when casted from signed long to longlong and then casted to ulonglong. When (ulonglong) -1 is compared with maximal value for GET_ULONG data type, we adjust it to (ulonglong) ULONG_MAX and throw the warning. Fixed by using the right max size. Max values for the variables (from mysqld.cc) ---------------------------- 1. key_buffer_size 5.0: ULONG_MAX 5.1: SIZE_T_MAX 6.0: SIZE_T_MAX 2. read_buffer_size and write_buffer_size 5.0: INT_MAX32 5.1: INT_MAX32 6.0: INT_MAX32 3. sort_buffer_size (aka myisam_sort_buffer_size) 5.0: UINT_MAX32 5.1: ULONG_MAX 6.0: ULONG_MAX Note: testcase not attached myisam/myisamchk.c: Bug#33785 - myisamchk show warning message Fixed the Max value for key_buffer_size, read_buffer_size, write_buffer_size and sort_buffer_size options --- myisam/myisamchk.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index b1a61f2f373..11d3ac2e430 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -295,7 +295,7 @@ static struct my_option my_long_options[] = { "key_buffer_size", OPT_KEY_BUFFER_SIZE, "", (gptr*) &check_param.use_buffers, (gptr*) &check_param.use_buffers, 0, GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD, - (long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0}, + ULONG_MAX, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0}, { "key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE, "", (gptr*) &opt_key_cache_block_size, (gptr*) &opt_key_cache_block_size, 0, @@ -309,17 +309,17 @@ static struct my_option my_long_options[] = (gptr*) &check_param.read_buffer_length, (gptr*) &check_param.read_buffer_length, 0, GET_ULONG, REQUIRED_ARG, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, - (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0}, + INT_MAX32, (long) MALLOC_OVERHEAD, (long) 1L, 0}, { "write_buffer_size", OPT_WRITE_BUFFER_SIZE, "", (gptr*) &check_param.write_buffer_length, (gptr*) &check_param.write_buffer_length, 0, GET_ULONG, REQUIRED_ARG, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, - (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0}, + INT_MAX32, (long) MALLOC_OVERHEAD, (long) 1L, 0}, { "sort_buffer_size", OPT_SORT_BUFFER_SIZE, "", (gptr*) &check_param.sort_buffer_length, (gptr*) &check_param.sort_buffer_length, 0, GET_ULONG, REQUIRED_ARG, (long) SORT_BUFFER_INIT, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), - (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0}, + UINT_MAX32, (long) MALLOC_OVERHEAD, (long) 1L, 0}, { "sort_key_blocks", OPT_SORT_KEY_BLOCKS, "", (gptr*) &check_param.sort_key_blocks, (gptr*) &check_param.sort_key_blocks, 0, GET_ULONG, REQUIRED_ARG, From 1eb40ce319411cf0f06a6115210b5475593cef7f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 4 Sep 2009 09:33:45 +0800 Subject: [PATCH 078/138] BUG#45581 Test rpl_row_sp006_InnoDB fails randomly: Unknown database 'mysqltest1' Essentially, Bug#45574 results in this bug. The 'CREATE DATABASE IF NOT EXISTS' statement was not binlogged, when the database has existed. Sometimes, the master and slaves become inconsistent. The "CREATE DATABASE IF NOT EXISTS mysqltest1" statement is not binlogged if the db 'mysqltest1' existed before the test case is executed. So the db 'mysqltest1' can't be created on slave. Patch of Bug#45574 has resolved this problem. But I think it is better to replace 'mysqltest1' by default db 'test'. --- mysql-test/extra/rpl_tests/rpl_row_sp006.test | 41 +++++++++---------- .../suite/rpl/r/rpl_row_sp006_InnoDB.result | 36 ++++++++-------- 2 files changed, 36 insertions(+), 41 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_row_sp006.test b/mysql-test/extra/rpl_tests/rpl_row_sp006.test index 897d7e492bf..16a8374ae7f 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_sp006.test +++ b/mysql-test/extra/rpl_tests/rpl_row_sp006.test @@ -9,29 +9,27 @@ ############################################################################# # Begin clean up test section -connection master; --disable_warnings -create database if not exists mysqltest1; -DROP PROCEDURE IF EXISTS mysqltest1.p1; -DROP PROCEDURE IF EXISTS mysqltest1.p2; -DROP TABLE IF EXISTS mysqltest1.t2; -DROP TABLE IF EXISTS mysqltest1.t1; +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; --enable_warnings # End of cleanup # Begin test section 1 -eval CREATE TABLE IF NOT EXISTS mysqltest1.t1(name CHAR(16), birth DATE,PRIMARY KEY(name))ENGINE=$engine_type; -eval CREATE TABLE IF NOT EXISTS mysqltest1.t2(name CHAR(16), age INT ,PRIMARY KEY(name))ENGINE=$engine_type; +eval CREATE TABLE IF NOT EXISTS t1(name CHAR(16), birth DATE,PRIMARY KEY(name))ENGINE=$engine_type; +eval CREATE TABLE IF NOT EXISTS t2(name CHAR(16), age INT ,PRIMARY KEY(name))ENGINE=$engine_type; delimiter |; -CREATE PROCEDURE mysqltest1.p1() +CREATE PROCEDURE p1() BEGIN DECLARE done INT DEFAULT 0; DECLARE spa CHAR(16); DECLARE spb INT; DECLARE cur1 CURSOR FOR SELECT name, (YEAR(CURDATE())-YEAR(birth))-(RIGHT(CURDATE(),5) $MYSQLTEST_VARDIR/tmp/sp006_master.sql ---exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > $MYSQLTEST_VARDIR/tmp/sp006_slave.sql +--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/sp006_master.sql +--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/sp006_slave.sql -DROP PROCEDURE IF EXISTS mysqltest1.p1; -DROP PROCEDURE IF EXISTS mysqltest1.p2; -DROP TABLE IF EXISTS mysqltest1.t1; -DROP TABLE IF EXISTS mysqltest1.t2; -DROP DATABASE mysqltest1; +DROP TABLE t1; +DROP TABLE t2; +DROP PROCEDURE p1; +DROP PROCEDURE p2; # Lets compare. Note: If they match test will pass, if they do not match # the test will show that the diff statement failed and not reject file diff --git a/mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result b/mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result index 8339e77d3a0..6792a701577 100644 --- a/mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result +++ b/mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result @@ -4,21 +4,20 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; -create database if not exists mysqltest1; -DROP PROCEDURE IF EXISTS mysqltest1.p1; -DROP PROCEDURE IF EXISTS mysqltest1.p2; -DROP TABLE IF EXISTS mysqltest1.t2; -DROP TABLE IF EXISTS mysqltest1.t1; -CREATE TABLE IF NOT EXISTS mysqltest1.t1(name CHAR(16), birth DATE,PRIMARY KEY(name))ENGINE=InnoDB; -CREATE TABLE IF NOT EXISTS mysqltest1.t2(name CHAR(16), age INT ,PRIMARY KEY(name))ENGINE=InnoDB; -CREATE PROCEDURE mysqltest1.p1() +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; +CREATE TABLE IF NOT EXISTS t1(name CHAR(16), birth DATE,PRIMARY KEY(name))ENGINE=InnoDB; +CREATE TABLE IF NOT EXISTS t2(name CHAR(16), age INT ,PRIMARY KEY(name))ENGINE=InnoDB; +CREATE PROCEDURE p1() BEGIN DECLARE done INT DEFAULT 0; DECLARE spa CHAR(16); DECLARE spb INT; DECLARE cur1 CURSOR FOR SELECT name, (YEAR(CURDATE())-YEAR(birth))-(RIGHT(CURDATE(),5) Date: Fri, 4 Sep 2009 09:27:11 +0530 Subject: [PATCH 079/138] Bug#45823 Assertion failure in file row/row0mysql.c line 1386 Inserting a negative value in the autoincrement column of a partitioned innodb table was causing the value of the auto increment counter to wrap around into a very large positive value. The consequences are the same as if a very large positive value was inserted into a column, e.g. reduced autoincrement range, failure to read autoincrement counter. The current patch ensures that before calculating the next auto increment value, the current value is within the positive maximum allowed limit. mysql-test/suite/parts/inc/partition_auto_increment.inc: Bug#45823 Assertion failure in file row/row0mysql.c line 1386 Adds tests for performing insert,update and delete on a partition table with negative auto_increment values. mysql-test/suite/parts/r/partition_auto_increment_innodb.result: Bug#45823 Assertion failure in file row/row0mysql.c line 1386 Result file for the innodb engine. mysql-test/suite/parts/r/partition_auto_increment_memory.result: Bug#45823 Assertion failure in file row/row0mysql.c line 1386 Result file for the memory engine. mysql-test/suite/parts/r/partition_auto_increment_myisam.result: Bug#45823 Assertion failure in file row/row0mysql.c line 1386 Result file for the myisam engine. mysql-test/suite/parts/r/partition_auto_increment_ndb.result: Bug#45823 Assertion failure in file row/row0mysql.c line 1386 Result file for the ndb engine. mysql-test/suite/parts/t/partition_auto_increment_archive.test: Bug#45823 Assertion failure in file row/row0mysql.c line 1386 Adds a variable that allows the Archive engine to skip tests that involve insertion of negative auto increment values. mysql-test/suite/parts/t/partition_auto_increment_blackhole.test: Bug#45823 Assertion failure in file row/row0mysql.c line 1386 Adds a variable that allows the Blackhole engine to skip tests that involve insertion of negative auto increment values. sql/ha_partition.cc: Bug#45823 Assertion failure in file row/row0mysql.c line 1386 Ensures that the current value is lesser than the upper limit for the type of the field before setting the next auto increment value to be calculated. sql/ha_partition.h: Bug#45823 Assertion failure in file row/row0mysql.c line 1386 Modifies the set_auto_increment_if_higher function, to take into account negative auto increment values when doing a comparison. --- .../parts/inc/partition_auto_increment.inc | 192 ++++++++++++++++++ .../r/partition_auto_increment_innodb.result | 191 +++++++++++++++++ .../r/partition_auto_increment_memory.result | 191 +++++++++++++++++ .../r/partition_auto_increment_myisam.result | 191 +++++++++++++++++ .../r/partition_auto_increment_ndb.result | 191 +++++++++++++++++ .../t/partition_auto_increment_archive.test | 3 + .../t/partition_auto_increment_blackhole.test | 3 + sql/ha_partition.cc | 4 +- sql/ha_partition.h | 4 +- 9 files changed, 967 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/parts/inc/partition_auto_increment.inc b/mysql-test/suite/parts/inc/partition_auto_increment.inc index 6963de90c83..2c615e58ef9 100644 --- a/mysql-test/suite/parts/inc/partition_auto_increment.inc +++ b/mysql-test/suite/parts/inc/partition_auto_increment.inc @@ -623,3 +623,195 @@ SHOW CREATE TABLE t1; SELECT * FROM t1 ORDER BY c1; DROP TABLE t1; +if (!$skip_negative_auto_inc) +{ +--echo ############################################################################# +--echo # Bug #45823 - Assertion failure in file row/row0mysql.c line 1386 +--echo # Bug #43988 - AUTO_INCREMENT errors with partitioned InnoDB tables in 5.1.31 +--echo ############################################################################## + +--echo # Inserting negative autoincrement values into a partition table (partitions >= 4) + +eval CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), + c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 4; + +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +INSERT INTO t(c2) VALUES (30); +INSERT INTO t(c2) VALUES (40); + +SELECT * FROM t ORDER BY c1 ASC; + +DROP TABLE t; + +--echo # Reading from a partition table (partitions >= 2 ) after inserting a negative +--echo # value into the auto increment column + + +eval CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), + c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 2; + +INSERT INTO t VALUES (-2,-20); +INSERT INTO t(c2) VALUES (30); + +SELECT * FROM t ORDER BY c1 ASC; + +DROP TABLE t; + +--echo # Inserting negative auto increment value into a partition table (partitions >= 2) +--echo # auto increment value > 2. + +eval CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), + c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 2; + +INSERT INTO t VALUES (-4,-20); +INSERT INTO t(c2) VALUES (30); +INSERT INTO t(c2) VALUES (40); + +SELECT * FROM t ORDER BY c1 ASC; + +DROP TABLE t; + +--echo # Inserting -1 into autoincrement column of a partition table (partition >= 4) + +eval CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), + c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 4; + +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); + +SELECT * FROM t ORDER BY c1 ASC; + +INSERT INTO t(c2) VALUES (30); + +SELECT * FROM t ORDER BY c1 ASC; + +DROP TABLE t; + +--echo # Deleting from an auto increment table after inserting negative values + +eval CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), + c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 4; + +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +INSERT INTO t(c2) VALUES (30); +INSERT INTO t VALUES (-3,-20); +INSERT INTO t(c2) VALUES (40); + +SELECT * FROM t ORDER BY c1 ASC; + +if (!$skip_delete) +{ +DELETE FROM t WHERE c1 > 1; +} + +SELECT * FROM t ORDER BY c1 ASC; + +DROP TABLE t; + +--echo # Inserting a positive value that exceeds maximum allowed value for an +--echo # Auto Increment column (positive maximum) + +eval CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), + c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 4; + +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (126,30); +INSERT INTO t VALUES (127,40); + +--error ER_DUP_ENTRY +INSERT INTO t VALUES (128,50); +--error ER_DUP_ENTRY +INSERT INTO t VALUES (129,60); + +SELECT * FROM t ORDER BY c1 ASC; + +DROP TABLE t; + +--echo # Inserting a negative value that goes below minimum allowed value for an +--echo # Auto Increment column (negative minimum) + +eval CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), + c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 4; + +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-127,30); +INSERT INTO t VALUES (-128,40); + +--error ER_DUP_ENTRY +INSERT INTO t VALUES (-129,50); +--error ER_DUP_ENTRY +INSERT INTO t VALUES (-130,60); + +SELECT * FROM t ORDER BY c1 ASC; + +DROP TABLE t; + +--echo # Updating the partition table with a negative Auto Increment value + +eval CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), + c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 4; + +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +INSERT INTO t(c2) VALUES (30); + +SELECT * FROM t ORDER BY c1 ASC; + +if (!$skip_update) +{ +UPDATE t SET c1 = -6 WHERE c1 = 2; +} + +SELECT * FROM t ORDER BY c1 ASC; + +INSERT INTO t(c2) VALUES (40); +INSERT INTO t(c2) VALUES (50); + +if (!$skip_update) +{ +UPDATE t SET c1 = -6 WHERE c1 = 2; +} + +SELECT * FROM t ORDER BY c1 ASC; + +DROP TABLE t; + +--echo # Updating the partition table with a value that crosses the upper limits +--echo # on both the positive and the negative side. + +eval CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), + c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 4; + +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (126,30); +INSERT INTO t VALUES (127,40); + +SELECT * FROM t ORDER BY c1 ASC; + +if (!$skip_update) +{ +UPDATE t SET c1 = 130 where c1 = 127; +} + +SELECT * FROM t ORDER BY c1 ASC; + +if (!$skip_update) +{ +UPDATE t SET c1 = -140 where c1 = 126; +} + +SELECT * FROM t ORDER BY c1 ASC; + +DROP TABLE t; + +--echo ############################################################################## +} diff --git a/mysql-test/suite/parts/r/partition_auto_increment_innodb.result b/mysql-test/suite/parts/r/partition_auto_increment_innodb.result index 9a23cd4364e..6295d14d98f 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_innodb.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_innodb.result @@ -825,3 +825,194 @@ c1 4 5 DROP TABLE t1; +############################################################################# +# Bug #45823 - Assertion failure in file row/row0mysql.c line 1386 +# Bug #43988 - AUTO_INCREMENT errors with partitioned InnoDB tables in 5.1.31 +############################################################################## +# Inserting negative autoincrement values into a partition table (partitions >= 4) +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +INSERT INTO t(c2) VALUES (30); +INSERT INTO t(c2) VALUES (40); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-1 -10 +1 10 +2 20 +3 30 +4 40 +DROP TABLE t; +# Reading from a partition table (partitions >= 2 ) after inserting a negative +# value into the auto increment column +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 2; +INSERT INTO t VALUES (-2,-20); +INSERT INTO t(c2) VALUES (30); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-2 -20 +1 30 +DROP TABLE t; +# Inserting negative auto increment value into a partition table (partitions >= 2) +# auto increment value > 2. +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 2; +INSERT INTO t VALUES (-4,-20); +INSERT INTO t(c2) VALUES (30); +INSERT INTO t(c2) VALUES (40); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-4 -20 +1 30 +2 40 +DROP TABLE t; +# Inserting -1 into autoincrement column of a partition table (partition >= 4) +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-1 -10 +1 10 +2 20 +INSERT INTO t(c2) VALUES (30); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-1 -10 +1 10 +2 20 +3 30 +DROP TABLE t; +# Deleting from an auto increment table after inserting negative values +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +INSERT INTO t(c2) VALUES (30); +INSERT INTO t VALUES (-3,-20); +INSERT INTO t(c2) VALUES (40); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-3 -20 +-1 -10 +1 10 +2 20 +3 30 +4 40 +DELETE FROM t WHERE c1 > 1; +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-3 -20 +-1 -10 +1 10 +DROP TABLE t; +# Inserting a positive value that exceeds maximum allowed value for an +# Auto Increment column (positive maximum) +CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (126,30); +INSERT INTO t VALUES (127,40); +INSERT INTO t VALUES (128,50); +ERROR 23000: Duplicate entry '127' for key 'PRIMARY' +INSERT INTO t VALUES (129,60); +ERROR 23000: Duplicate entry '127' for key 'PRIMARY' +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +1 10 +2 20 +126 30 +127 40 +DROP TABLE t; +# Inserting a negative value that goes below minimum allowed value for an +# Auto Increment column (negative minimum) +CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-127,30); +INSERT INTO t VALUES (-128,40); +INSERT INTO t VALUES (-129,50); +ERROR 23000: Duplicate entry '-128' for key 'PRIMARY' +INSERT INTO t VALUES (-130,60); +ERROR 23000: Duplicate entry '-128' for key 'PRIMARY' +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-128 40 +-127 30 +1 10 +2 20 +DROP TABLE t; +# Updating the partition table with a negative Auto Increment value +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +INSERT INTO t(c2) VALUES (30); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-1 -10 +1 10 +2 20 +3 30 +UPDATE t SET c1 = -6 WHERE c1 = 2; +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-6 20 +-1 -10 +1 10 +3 30 +INSERT INTO t(c2) VALUES (40); +INSERT INTO t(c2) VALUES (50); +UPDATE t SET c1 = -6 WHERE c1 = 2; +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-6 20 +-1 -10 +1 10 +3 30 +4 40 +5 50 +DROP TABLE t; +# Updating the partition table with a value that crosses the upper limits +# on both the positive and the negative side. +CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (126,30); +INSERT INTO t VALUES (127,40); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +1 10 +2 20 +126 30 +127 40 +UPDATE t SET c1 = 130 where c1 = 127; +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +1 10 +2 20 +126 30 +127 40 +UPDATE t SET c1 = -140 where c1 = 126; +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-128 30 +1 10 +2 20 +127 40 +DROP TABLE t; +############################################################################## diff --git a/mysql-test/suite/parts/r/partition_auto_increment_memory.result b/mysql-test/suite/parts/r/partition_auto_increment_memory.result index f4d783825f4..6e3b990dc0f 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_memory.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_memory.result @@ -851,3 +851,194 @@ c1 4 5 DROP TABLE t1; +############################################################################# +# Bug #45823 - Assertion failure in file row/row0mysql.c line 1386 +# Bug #43988 - AUTO_INCREMENT errors with partitioned InnoDB tables in 5.1.31 +############################################################################## +# Inserting negative autoincrement values into a partition table (partitions >= 4) +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +INSERT INTO t(c2) VALUES (30); +INSERT INTO t(c2) VALUES (40); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-1 -10 +1 10 +2 20 +3 30 +4 40 +DROP TABLE t; +# Reading from a partition table (partitions >= 2 ) after inserting a negative +# value into the auto increment column +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 2; +INSERT INTO t VALUES (-2,-20); +INSERT INTO t(c2) VALUES (30); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-2 -20 +1 30 +DROP TABLE t; +# Inserting negative auto increment value into a partition table (partitions >= 2) +# auto increment value > 2. +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 2; +INSERT INTO t VALUES (-4,-20); +INSERT INTO t(c2) VALUES (30); +INSERT INTO t(c2) VALUES (40); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-4 -20 +1 30 +2 40 +DROP TABLE t; +# Inserting -1 into autoincrement column of a partition table (partition >= 4) +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-1 -10 +1 10 +2 20 +INSERT INTO t(c2) VALUES (30); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-1 -10 +1 10 +2 20 +3 30 +DROP TABLE t; +# Deleting from an auto increment table after inserting negative values +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +INSERT INTO t(c2) VALUES (30); +INSERT INTO t VALUES (-3,-20); +INSERT INTO t(c2) VALUES (40); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-3 -20 +-1 -10 +1 10 +2 20 +3 30 +4 40 +DELETE FROM t WHERE c1 > 1; +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-3 -20 +-1 -10 +1 10 +DROP TABLE t; +# Inserting a positive value that exceeds maximum allowed value for an +# Auto Increment column (positive maximum) +CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (126,30); +INSERT INTO t VALUES (127,40); +INSERT INTO t VALUES (128,50); +ERROR 23000: Duplicate entry '127' for key 'PRIMARY' +INSERT INTO t VALUES (129,60); +ERROR 23000: Duplicate entry '127' for key 'PRIMARY' +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +1 10 +2 20 +126 30 +127 40 +DROP TABLE t; +# Inserting a negative value that goes below minimum allowed value for an +# Auto Increment column (negative minimum) +CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-127,30); +INSERT INTO t VALUES (-128,40); +INSERT INTO t VALUES (-129,50); +ERROR 23000: Duplicate entry '-128' for key 'PRIMARY' +INSERT INTO t VALUES (-130,60); +ERROR 23000: Duplicate entry '-128' for key 'PRIMARY' +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-128 40 +-127 30 +1 10 +2 20 +DROP TABLE t; +# Updating the partition table with a negative Auto Increment value +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +INSERT INTO t(c2) VALUES (30); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-1 -10 +1 10 +2 20 +3 30 +UPDATE t SET c1 = -6 WHERE c1 = 2; +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-6 20 +-1 -10 +1 10 +3 30 +INSERT INTO t(c2) VALUES (40); +INSERT INTO t(c2) VALUES (50); +UPDATE t SET c1 = -6 WHERE c1 = 2; +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-6 20 +-1 -10 +1 10 +3 30 +4 40 +5 50 +DROP TABLE t; +# Updating the partition table with a value that crosses the upper limits +# on both the positive and the negative side. +CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (126,30); +INSERT INTO t VALUES (127,40); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +1 10 +2 20 +126 30 +127 40 +UPDATE t SET c1 = 130 where c1 = 127; +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +1 10 +2 20 +126 30 +127 40 +UPDATE t SET c1 = -140 where c1 = 126; +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-128 30 +1 10 +2 20 +127 40 +DROP TABLE t; +############################################################################## diff --git a/mysql-test/suite/parts/r/partition_auto_increment_myisam.result b/mysql-test/suite/parts/r/partition_auto_increment_myisam.result index 6abf08b68a0..047b974f0a3 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_myisam.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_myisam.result @@ -870,3 +870,194 @@ c1 4 5 DROP TABLE t1; +############################################################################# +# Bug #45823 - Assertion failure in file row/row0mysql.c line 1386 +# Bug #43988 - AUTO_INCREMENT errors with partitioned InnoDB tables in 5.1.31 +############################################################################## +# Inserting negative autoincrement values into a partition table (partitions >= 4) +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +INSERT INTO t(c2) VALUES (30); +INSERT INTO t(c2) VALUES (40); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-1 -10 +1 10 +2 20 +3 30 +4 40 +DROP TABLE t; +# Reading from a partition table (partitions >= 2 ) after inserting a negative +# value into the auto increment column +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 2; +INSERT INTO t VALUES (-2,-20); +INSERT INTO t(c2) VALUES (30); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-2 -20 +1 30 +DROP TABLE t; +# Inserting negative auto increment value into a partition table (partitions >= 2) +# auto increment value > 2. +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 2; +INSERT INTO t VALUES (-4,-20); +INSERT INTO t(c2) VALUES (30); +INSERT INTO t(c2) VALUES (40); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-4 -20 +1 30 +2 40 +DROP TABLE t; +# Inserting -1 into autoincrement column of a partition table (partition >= 4) +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-1 -10 +1 10 +2 20 +INSERT INTO t(c2) VALUES (30); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-1 -10 +1 10 +2 20 +3 30 +DROP TABLE t; +# Deleting from an auto increment table after inserting negative values +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +INSERT INTO t(c2) VALUES (30); +INSERT INTO t VALUES (-3,-20); +INSERT INTO t(c2) VALUES (40); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-3 -20 +-1 -10 +1 10 +2 20 +3 30 +4 40 +DELETE FROM t WHERE c1 > 1; +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-3 -20 +-1 -10 +1 10 +DROP TABLE t; +# Inserting a positive value that exceeds maximum allowed value for an +# Auto Increment column (positive maximum) +CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (126,30); +INSERT INTO t VALUES (127,40); +INSERT INTO t VALUES (128,50); +ERROR 23000: Duplicate entry '127' for key 'PRIMARY' +INSERT INTO t VALUES (129,60); +ERROR 23000: Duplicate entry '127' for key 'PRIMARY' +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +1 10 +2 20 +126 30 +127 40 +DROP TABLE t; +# Inserting a negative value that goes below minimum allowed value for an +# Auto Increment column (negative minimum) +CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-127,30); +INSERT INTO t VALUES (-128,40); +INSERT INTO t VALUES (-129,50); +ERROR 23000: Duplicate entry '-128' for key 'PRIMARY' +INSERT INTO t VALUES (-130,60); +ERROR 23000: Duplicate entry '-128' for key 'PRIMARY' +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-128 40 +-127 30 +1 10 +2 20 +DROP TABLE t; +# Updating the partition table with a negative Auto Increment value +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +INSERT INTO t(c2) VALUES (30); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-1 -10 +1 10 +2 20 +3 30 +UPDATE t SET c1 = -6 WHERE c1 = 2; +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-6 20 +-1 -10 +1 10 +3 30 +INSERT INTO t(c2) VALUES (40); +INSERT INTO t(c2) VALUES (50); +UPDATE t SET c1 = -6 WHERE c1 = 2; +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-6 20 +-1 -10 +1 10 +3 30 +4 40 +5 50 +DROP TABLE t; +# Updating the partition table with a value that crosses the upper limits +# on both the positive and the negative side. +CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (126,30); +INSERT INTO t VALUES (127,40); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +1 10 +2 20 +126 30 +127 40 +UPDATE t SET c1 = 130 where c1 = 127; +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +1 10 +2 20 +126 30 +127 40 +UPDATE t SET c1 = -140 where c1 = 126; +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-128 30 +1 10 +2 20 +127 40 +DROP TABLE t; +############################################################################## diff --git a/mysql-test/suite/parts/r/partition_auto_increment_ndb.result b/mysql-test/suite/parts/r/partition_auto_increment_ndb.result index 5a1c5b06b36..317669be7ad 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_ndb.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_ndb.result @@ -846,3 +846,194 @@ c1 4 5 DROP TABLE t1; +############################################################################# +# Bug #45823 - Assertion failure in file row/row0mysql.c line 1386 +# Bug #43988 - AUTO_INCREMENT errors with partitioned InnoDB tables in 5.1.31 +############################################################################## +# Inserting negative autoincrement values into a partition table (partitions >= 4) +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +INSERT INTO t(c2) VALUES (30); +INSERT INTO t(c2) VALUES (40); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-1 -10 +1 10 +2 20 +3 30 +4 40 +DROP TABLE t; +# Reading from a partition table (partitions >= 2 ) after inserting a negative +# value into the auto increment column +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 2; +INSERT INTO t VALUES (-2,-20); +INSERT INTO t(c2) VALUES (30); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-2 -20 +1 30 +DROP TABLE t; +# Inserting negative auto increment value into a partition table (partitions >= 2) +# auto increment value > 2. +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 2; +INSERT INTO t VALUES (-4,-20); +INSERT INTO t(c2) VALUES (30); +INSERT INTO t(c2) VALUES (40); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-4 -20 +1 30 +2 40 +DROP TABLE t; +# Inserting -1 into autoincrement column of a partition table (partition >= 4) +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-1 -10 +1 10 +2 20 +INSERT INTO t(c2) VALUES (30); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-1 -10 +1 10 +2 20 +3 30 +DROP TABLE t; +# Deleting from an auto increment table after inserting negative values +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +INSERT INTO t(c2) VALUES (30); +INSERT INTO t VALUES (-3,-20); +INSERT INTO t(c2) VALUES (40); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-3 -20 +-1 -10 +1 10 +2 20 +3 30 +4 40 +DELETE FROM t WHERE c1 > 1; +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-3 -20 +-1 -10 +1 10 +DROP TABLE t; +# Inserting a positive value that exceeds maximum allowed value for an +# Auto Increment column (positive maximum) +CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (126,30); +INSERT INTO t VALUES (127,40); +INSERT INTO t VALUES (128,50); +ERROR 23000: Duplicate entry '127' for key 'PRIMARY' +INSERT INTO t VALUES (129,60); +ERROR 23000: Duplicate entry '127' for key 'PRIMARY' +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +1 10 +2 20 +126 30 +127 40 +DROP TABLE t; +# Inserting a negative value that goes below minimum allowed value for an +# Auto Increment column (negative minimum) +CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-127,30); +INSERT INTO t VALUES (-128,40); +INSERT INTO t VALUES (-129,50); +ERROR 23000: Duplicate entry '-128' for key 'PRIMARY' +INSERT INTO t VALUES (-130,60); +ERROR 23000: Duplicate entry '-128' for key 'PRIMARY' +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-128 40 +-127 30 +1 10 +2 20 +DROP TABLE t; +# Updating the partition table with a negative Auto Increment value +CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (-1,-10); +INSERT INTO t(c2) VALUES (30); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-1 -10 +1 10 +2 20 +3 30 +UPDATE t SET c1 = -6 WHERE c1 = 2; +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-6 20 +-1 -10 +1 10 +3 30 +INSERT INTO t(c2) VALUES (40); +INSERT INTO t(c2) VALUES (50); +UPDATE t SET c1 = -6 WHERE c1 = 2; +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-6 20 +-1 -10 +1 10 +3 30 +4 40 +5 50 +DROP TABLE t; +# Updating the partition table with a value that crosses the upper limits +# on both the positive and the negative side. +CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1), +c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 4; +INSERT INTO t(c2) VALUES (10); +INSERT INTO t(c2) VALUES (20); +INSERT INTO t VALUES (126,30); +INSERT INTO t VALUES (127,40); +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +1 10 +2 20 +126 30 +127 40 +UPDATE t SET c1 = 130 where c1 = 127; +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +1 10 +2 20 +126 30 +127 40 +UPDATE t SET c1 = -140 where c1 = 126; +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +SELECT * FROM t ORDER BY c1 ASC; +c1 c2 +-128 30 +1 10 +2 20 +127 40 +DROP TABLE t; +############################################################################## diff --git a/mysql-test/suite/parts/t/partition_auto_increment_archive.test b/mysql-test/suite/parts/t/partition_auto_increment_archive.test index fb09557204f..e99a0b23b36 100644 --- a/mysql-test/suite/parts/t/partition_auto_increment_archive.test +++ b/mysql-test/suite/parts/t/partition_auto_increment_archive.test @@ -30,6 +30,9 @@ let $skip_delete= 1; let $skip_truncate= 1; let $skip_update= 1; let $only_ai_pk= 1; +# Bug#45823 Assertion failure in file row/row0mysql.c line 1386 +# Archive does not handle negative autoincrement values correctly +let $skip_negative_auto_inc= 1; ##### Storage engine to be tested let $engine= 'Archive'; diff --git a/mysql-test/suite/parts/t/partition_auto_increment_blackhole.test b/mysql-test/suite/parts/t/partition_auto_increment_blackhole.test index 64cd96c6173..f92dc33f263 100644 --- a/mysql-test/suite/parts/t/partition_auto_increment_blackhole.test +++ b/mysql-test/suite/parts/t/partition_auto_increment_blackhole.test @@ -25,6 +25,9 @@ #------------------------------------------------------------------------------# # Engine specific settings and requirements --source include/have_blackhole.inc +# Bug#45823 Assertion failure in file row/row0mysql.c line 1386 +# Blackhole does not handle negative autoincrement values correctly +let $skip_negative_auto_inc= 1; ##### Storage engine to be tested let $engine= 'Blackhole'; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index ac8c46ec4e3..63f8271cca1 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -3024,7 +3024,7 @@ int ha_partition::write_row(uchar * buf) tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */ error= m_file[part_id]->ha_write_row(buf); if (have_auto_increment && !table->s->next_number_keypart) - set_auto_increment_if_higher(table->next_number_field->val_int()); + set_auto_increment_if_higher(table->next_number_field); reenable_binlog(thd); exit: table->timestamp_field_type= orig_timestamp_type; @@ -3128,7 +3128,7 @@ exit: HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data; if (!ha_data->auto_inc_initialized) info(HA_STATUS_AUTO); - set_auto_increment_if_higher(table->found_next_number_field->val_int()); + set_auto_increment_if_higher(table->found_next_number_field); } table->timestamp_field_type= orig_timestamp_type; DBUG_RETURN(error); diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 8a81a759e2a..d0301e24a93 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -936,9 +936,11 @@ private: auto_increment_lock= FALSE; } } - virtual void set_auto_increment_if_higher(const ulonglong nr) + virtual void set_auto_increment_if_higher(Field *field) { HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data; + ulonglong nr= (((Field_num*) field)->unsigned_flag || + field->val_int() > 0) ? field->val_int() : 0; lock_auto_increment(); DBUG_ASSERT(ha_data->auto_inc_initialized == TRUE); /* must check when the mutex is taken */ From 482fdb5fc703e502a0cbb17ed035487e2b034fb7 Mon Sep 17 00:00:00 2001 From: Satya B Date: Fri, 4 Sep 2009 11:19:44 +0530 Subject: [PATCH 080/138] Addition to Fix for BUG#46591 - .frm file isn't sync'd with sync_frm enabled for CREATE TABLE...LIKE... Add my_sync.c to mysqltest sources list in CMakeLists.txt client/CMakeLists.txt: BUG#46591 - .frm file isn't sync'd with sync_frm enabled for CREATE TABLE...LIKE... Add my_sync.c to mysqltest sources list --- client/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index a419da5eabf..7426384f0cf 100755 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -33,7 +33,8 @@ ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../my TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32) ADD_EXECUTABLE(mysqltest mysqltest.c ../mysys/my_getsystime.c - ../mysys/my_copy.c ../mysys/my_mkdir.c) + ../mysys/my_copy.c ../mysys/my_mkdir.c + ../mysys/my_sync.c) TARGET_LINK_LIBRARIES(mysqltest mysqlclient_notls regex wsock32) ADD_EXECUTABLE(mysqlcheck mysqlcheck.c) From 6e27ef435e3863382295f1a1d41424c9b8d4c197 Mon Sep 17 00:00:00 2001 From: Satya B Date: Fri, 4 Sep 2009 12:21:54 +0530 Subject: [PATCH 081/138] Fix for BUG#46384 - mysqld segfault when trying to create table with same name as existing view When trying to create a table with the same name as existing view with join, mysql server crashes. The problem is when create table is issued with the same name as view, while verifying with the existing tables, we assume that base table object is created always. In this case, since it is a view over multiple tables, we don't have the mysql derived table object. Fixed the logic which checks if there is an existing table to not to assume that table object is created when the base table is view over multiple tables. mysql-test/r/create.result: BUG#46384 - mysqld segfault when trying to create table with same name as existing view Testcase for the bug mysql-test/t/create.test: BUG#46384 - mysqld segfault when trying to create table with same name as existing view Testcase for the bug sql/sql_insert.cc: BUG#46384 - mysqld segfault when trying to create table with same name as existing view Fixed create_table_from_items() method to properly check, if the base table is a view over multiple tables. --- mysql-test/r/create.result | 13 +++++++++++++ mysql-test/t/create.test | 17 +++++++++++++++++ sql/sql_insert.cc | 2 +- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index d37c1a04daa..dfd376a6bde 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1559,4 +1559,17 @@ CREATE TABLE IF NOT EXISTS t2 (a INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY) SELECT a FROM t1; ERROR 23000: Duplicate entry '1' for key 1 DROP TABLE t1, t2; +# +# BUG#46384 - mysqld segfault when trying to create table with same +# name as existing view +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t2 VALUES (1),(2),(3); +CREATE VIEW v1 AS SELECT t1.a FROM t1, t2; +CREATE TABLE v1 AS SELECT * FROM t1; +ERROR 42S01: Table 'v1' already exists +DROP VIEW v1; +DROP TABLE t1,t2; End of 5.0 tests diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index a837653d618..2ec416cfc87 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -1194,5 +1194,22 @@ CREATE TABLE IF NOT EXISTS t2 (a INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY) DROP TABLE t1, t2; +--echo # +--echo # BUG#46384 - mysqld segfault when trying to create table with same +--echo # name as existing view +--echo # + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); + +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t2 VALUES (1),(2),(3); + +CREATE VIEW v1 AS SELECT t1.a FROM t1, t2; +--error ER_TABLE_EXISTS_ERROR +CREATE TABLE v1 AS SELECT * FROM t1; + +DROP VIEW v1; +DROP TABLE t1,t2; --echo End of 5.0 tests diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index d2a0f47f1a9..b0958201795 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -3217,7 +3217,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, DBUG_EXECUTE_IF("sleep_create_select_before_check_if_exists", my_sleep(6000000);); if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE) && - create_table->table->db_stat) + (create_table->table && create_table->table->db_stat)) { /* Table already exists and was open at open_and_lock_tables() stage. */ if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) From 643fbe4234a06e51746c8912223652a3b41fe133 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Fri, 4 Sep 2009 12:20:53 +0500 Subject: [PATCH 082/138] Bug#45989 memory leak after explain encounters an error in the query Memory allocated in TMP_TABLE_PARAM::copy_field is not cleaned up. The fix is to clean up TMP_TABLE_PARAM::copy_field array in JOIN::destroy. mysql-test/r/explain.result: test result mysql-test/t/explain.test: test case sql/sql_select.cc: Memory allocated in TMP_TABLE_PARAM::copy_field is not cleaned up. The fix is to clean up TMP_TABLE_PARAM::copy_field array in JOIN::destroy. --- mysql-test/r/explain.result | 8 ++++++++ mysql-test/t/explain.test | 11 +++++++++++ sql/sql_select.cc | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result index b0adc428e4c..8d3859fd68e 100644 --- a/mysql-test/r/explain.result +++ b/mysql-test/r/explain.result @@ -159,3 +159,11 @@ CREATE TABLE t1 (a INT PRIMARY KEY); EXPLAIN EXTENDED SELECT COUNT(a) FROM t1 USE KEY(a); ERROR HY000: Key 'a' doesn't exist in table 't1' DROP TABLE t1; +CREATE TABLE t1(a LONGTEXT); +INSERT INTO t1 VALUES (repeat('a',@@global.max_allowed_packet)); +INSERT INTO t1 VALUES (repeat('b',@@global.max_allowed_packet)); +EXPLAIN SELECT DISTINCT 1 FROM t1, +(SELECT DISTINCTROW a AS away FROM t1 GROUP BY a WITH ROLLUP) as d1 +WHERE t1.a = d1.a; +ERROR 42S22: Unknown column 'd1.a' in 'where clause' +DROP TABLE t1; diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test index 1bc98a8acb1..7b7bdd3563c 100644 --- a/mysql-test/t/explain.test +++ b/mysql-test/t/explain.test @@ -135,5 +135,16 @@ EXPLAIN EXTENDED SELECT COUNT(a) FROM t1 USE KEY(a); DROP TABLE t1; +# +# Bug#45989 memory leak after explain encounters an error in the query +# +CREATE TABLE t1(a LONGTEXT); +INSERT INTO t1 VALUES (repeat('a',@@global.max_allowed_packet)); +INSERT INTO t1 VALUES (repeat('b',@@global.max_allowed_packet)); +--error ER_BAD_FIELD_ERROR +EXPLAIN SELECT DISTINCT 1 FROM t1, + (SELECT DISTINCTROW a AS away FROM t1 GROUP BY a WITH ROLLUP) as d1 + WHERE t1.a = d1.a; +DROP TABLE t1; # End of 5.0 tests. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ff179c432a8..b670e6e3637 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2176,7 +2176,7 @@ JOIN::destroy() } } tmp_join->tmp_join= 0; - tmp_table_param.copy_field=0; + tmp_table_param.cleanup(); DBUG_RETURN(tmp_join->destroy()); } cond_equal= 0; From a7de20574749ececbe8492f340f6ddc7be1544fa Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 4 Sep 2009 12:29:18 +0500 Subject: [PATCH 083/138] BUG#46961 - archive engine loses rows during self joining select! SELECT with join (not only self-join) from archive table may return incomplete result set, when result set size exceeds join buffer size. The problem was that archive row counter was initialzed too early, when ha_archive::info() method was called. Later, when optimizer exceeds join buffer, it attempts to reuse handler without calling ha_archive::info() again (which is correct). Fixed by moving row counter initialization from ha_archive::info() to ha_archive::rnd_init(). mysql-test/r/archive.result: A test case for BUG#46961. mysql-test/t/archive.test: A test case for BUG#46961. storage/archive/ha_archive.cc: Since a cursor may get reused without a call to ::info(), move assignment of scan_rows to a proper place, that is ::rnd_init(). --- mysql-test/r/archive.result | 11 +++++++++++ mysql-test/t/archive.test | 13 +++++++++++++ storage/archive/ha_archive.cc | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index 8c26ea1ff82..9a6edbaa85c 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -12695,3 +12695,14 @@ a b 1 NULL 2 NULL DROP TABLE t1; +SET @save_join_buffer_size= @@join_buffer_size; +SET @@join_buffer_size= 8228; +CREATE TABLE t1(a CHAR(255)) ENGINE=archive; +INSERT INTO t1 VALUES('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'), +('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'), +('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'); +SELECT COUNT(t1.a) FROM t1, t1 a, t1 b, t1 c, t1 d, t1 e; +COUNT(t1.a) +729 +DROP TABLE t1; +SET @@join_buffer_size= @save_join_buffer_size; diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index 7139d95ab49..663f7faf208 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1599,3 +1599,16 @@ INSERT INTO t1 VALUES (NULL, NULL),(NULL, NULL); FLUSH TABLE t1; SELECT * FROM t1 ORDER BY a; DROP TABLE t1; + +# +# BUG#46961 - archive engine loses rows during self joining select! +# +SET @save_join_buffer_size= @@join_buffer_size; +SET @@join_buffer_size= 8228; +CREATE TABLE t1(a CHAR(255)) ENGINE=archive; +INSERT INTO t1 VALUES('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'), + ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'), + ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'); +SELECT COUNT(t1.a) FROM t1, t1 a, t1 b, t1 c, t1 d, t1 e; +DROP TABLE t1; +SET @@join_buffer_size= @save_join_buffer_size; diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 1146b2eb73a..f1b9c26dfd6 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -993,6 +993,7 @@ int ha_archive::rnd_init(bool scan) /* We rewind the file so that we can read from the beginning if scan */ if (scan) { + scan_rows= stats.records; DBUG_PRINT("info", ("archive will retrieve %llu rows", (unsigned long long) scan_rows)); @@ -1461,7 +1462,6 @@ int ha_archive::info(uint flag) stats.records= share->rows_recorded; pthread_mutex_unlock(&share->mutex); - scan_rows= stats.records; stats.deleted= 0; DBUG_PRINT("ha_archive", ("Stats rows is %d\n", (int)stats.records)); From 2a6ac469fc7cd940d7864babafb72798b7643bf3 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 4 Sep 2009 13:14:54 +0500 Subject: [PATCH 084/138] Fix for bug#46629: Item_in_subselect::val_int(): Assertion `0' on subquery inside a SP Problem: repeated call of a SP containing an incorrect query with a subselect may lead to failed ASSERT(). Fix: set proper sublelect's state in case of error occured during subquery transformation. mysql-test/r/sp.result: Fix for bug#46629: Item_in_subselect::val_int(): Assertion `0' on subquery inside a SP - test result. mysql-test/t/sp.test: Fix for bug#46629: Item_in_subselect::val_int(): Assertion `0' on subquery inside a SP - test case. sql/item_subselect.cc: Fix for bug#46629: Item_in_subselect::val_int(): Assertion `0' on subquery inside a SP - don't set Item_subselect::changed in the Item_subselect::fix_fields() if an error occured during subquery transformation. That prevents us of further processing incorrect subqueries after Item_in_subselect::select_in_like_transformer(). --- mysql-test/r/sp.result | 16 ++++++++++++++++ mysql-test/t/sp.test | 22 ++++++++++++++++++++++ sql/item_subselect.cc | 10 ++++------ 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 3ad556b8c30..67514c314f4 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6963,6 +6963,22 @@ CALL p1(); CALL p1(); DROP PROCEDURE p1; DROP TABLE t1; +# +# Bug #46629: Item_in_subselect::val_int(): Assertion `0' +# on subquery inside a SP +# +CREATE TABLE t1(a INT); +CREATE TABLE t2(a INT, b INT PRIMARY KEY); +CREATE PROCEDURE p1 () +BEGIN +SELECT a FROM t1 A WHERE A.b IN (SELECT b FROM t2 AS B); +END| +CALL p1; +ERROR 42S22: Unknown column 'A.b' in 'IN/ALL/ANY subquery' +CALL p1; +ERROR 42S22: Unknown column 'A.b' in 'IN/ALL/ANY subquery' +DROP PROCEDURE p1; +DROP TABLE t1, t2; # ------------------------------------------------------------------ # -- End of 5.1 tests # ------------------------------------------------------------------ diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 5eeac457958..44c4556340e 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -8242,6 +8242,28 @@ while ($tab_count) DROP PROCEDURE p1; DROP TABLE t1; + +--echo # +--echo # Bug #46629: Item_in_subselect::val_int(): Assertion `0' +--echo # on subquery inside a SP +--echo # +CREATE TABLE t1(a INT); +CREATE TABLE t2(a INT, b INT PRIMARY KEY); + +DELIMITER |; +CREATE PROCEDURE p1 () +BEGIN + SELECT a FROM t1 A WHERE A.b IN (SELECT b FROM t2 AS B); +END| +DELIMITER ;| +--error ER_BAD_FIELD_ERROR +CALL p1; +--error ER_BAD_FIELD_ERROR +CALL p1; +DROP PROCEDURE p1; +DROP TABLE t1, t2; + + --echo # ------------------------------------------------------------------ --echo # -- End of 5.1 tests --echo # ------------------------------------------------------------------ diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index cdb091fa07e..da651cec70c 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -155,13 +155,11 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res)) return TRUE; - res= engine->prepare(); - - // all transformation is done (used by prepared statements) - changed= 1; - - if (!res) + if (!(res= engine->prepare())) { + // all transformation is done (used by prepared statements) + changed= 1; + if (substitution) { int ret= 0; From 0c4c2d7b8db1fead32aa48b12d538b5a8b522c59 Mon Sep 17 00:00:00 2001 From: Kristofer Pettersson Date: Fri, 4 Sep 2009 12:32:21 +0200 Subject: [PATCH 085/138] Bug#46486 warnings produced when running mysql_install_db Incremental patch part 2 Removing dead code and changing a note level message to a warning. sql/sql_plugin.cc: * Remove free_slots. The only purpose for this variable was to trigger a redundant warning message and it failed. * Change the note level message about shutting down plugins which didn't end nicely to a warning level message. (If this shutdown fails and there still are reference counts in the plugin an additional error level message is emitted) --- sql/sql_plugin.cc | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index f00e1f72390..025c8a8248d 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1520,7 +1520,7 @@ error: void plugin_shutdown(void) { - uint i, count= plugin_array.elements, free_slots= 0; + uint i, count= plugin_array.elements; struct st_plugin_int **plugins, *plugin; struct st_plugin_dl **dl; DBUG_ENTER("plugin_shutdown"); @@ -1541,18 +1541,13 @@ void plugin_shutdown(void) while (reap_needed && (count= plugin_array.elements)) { reap_plugins(); - for (i= free_slots= 0; i < count; i++) + for (i= 0; i < count; i++) { plugin= *dynamic_element(&plugin_array, i, struct st_plugin_int **); - switch (plugin->state) { - case PLUGIN_IS_READY: + if (plugin->state == PLUGIN_IS_READY) + { plugin->state= PLUGIN_IS_DELETED; reap_needed= true; - break; - case PLUGIN_IS_FREED: - case PLUGIN_IS_UNINITIALIZED: - free_slots++; - break; } } if (!reap_needed) @@ -1586,8 +1581,8 @@ void plugin_shutdown(void) if (!(plugins[i]->state & (PLUGIN_IS_UNINITIALIZED | PLUGIN_IS_FREED | PLUGIN_IS_DISABLED))) { - sql_print_information("Plugin '%s' will be forced to shutdown", - plugins[i]->name.str); + sql_print_warning("Plugin '%s' will be forced to shutdown", + plugins[i]->name.str); /* We are forcing deinit on plugins so we don't want to do a ref_count check until we have processed all the plugins. From 35d6911b283b3cf7720af9a7edb8c7ed3b3726db Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Fri, 4 Sep 2009 15:02:15 +0200 Subject: [PATCH 086/138] Bug#35845: unneccesary call to ha_start_bulk_insert for not used partitions (Backport) Problem is that when insert (ha_start_bulk_insert) in i partitioned table, it will call ha_start_bulk_insert for every partition, used or not. Solution is to delay the call to the partitions ha_start_bulk_insert until the first row is to be inserted into that partition sql/ha_partition.cc: Bug#35845: unneccesary call to ha_start_bulk_insert for not used partitions Using a bitmap for keeping record of which partitions for which ha_start_bulk_insert has been called, and check against that if one should call it before continue with the insert/update, or if it has already been called. This way it will only call ha_start_bulk_insert for the used partitions. There is also a little prediction on how many rows that will be inserted into the current partition, it will guess on equal distribution of the records across all partitions, accept for the first used partition, which will guess at 50% of the given estimate, if it is a monotonic partitioning function. sql/ha_partition.h: Bug#35845: unneccesary call to ha_start_bulk_insert for not used partitions Added help variables and function for delaying ha_bulk_insert until it has to be called. Fixed a comment. --- sql/ha_partition.cc | 95 ++++++++++++++++++++++++++++++++++++++------- sql/ha_partition.h | 10 ++++- 2 files changed, 91 insertions(+), 14 deletions(-) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 63f8271cca1..c849bbd12c5 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -239,6 +239,7 @@ void ha_partition::init_handler_variables() m_curr_key_info[0]= NULL; m_curr_key_info[1]= NULL; is_clone= FALSE, + m_part_func_monotonicity_info= NON_MONOTONIC; auto_increment_lock= FALSE; auto_increment_safe_stmt_log_lock= FALSE; /* @@ -2464,11 +2465,18 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) } } + /* Initialize the bitmap we use to minimize ha_start_bulk_insert calls */ + if (bitmap_init(&m_bulk_insert_started, NULL, m_tot_parts + 1, FALSE)) + DBUG_RETURN(1); + bitmap_clear_all(&m_bulk_insert_started); /* Initialize the bitmap we use to determine what partitions are used */ if (!is_clone) { if (bitmap_init(&(m_part_info->used_partitions), NULL, m_tot_parts, TRUE)) + { + bitmap_free(&m_bulk_insert_started); DBUG_RETURN(1); + } bitmap_set_all(&(m_part_info->used_partitions)); } @@ -2552,12 +2560,18 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) calling open on all individual handlers. */ m_handler_status= handler_opened; + if (m_part_info->part_expr) + m_part_func_monotonicity_info= + m_part_info->part_expr->get_monotonicity_info(); + else if (m_part_info->list_of_part_fields) + m_part_func_monotonicity_info= MONOTONIC_STRICT_INCREASING; info(HA_STATUS_VARIABLE | HA_STATUS_CONST); DBUG_RETURN(0); err_handler: while (file-- != m_file) (*file)->close(); + bitmap_free(&m_bulk_insert_started); if (!is_clone) bitmap_free(&(m_part_info->used_partitions)); @@ -2605,6 +2619,7 @@ int ha_partition::close(void) DBUG_ASSERT(table->s == table_share); delete_queue(&m_queue); + bitmap_free(&m_bulk_insert_started); if (!is_clone) bitmap_free(&(m_part_info->used_partitions)); file= m_file; @@ -3021,6 +3036,8 @@ int ha_partition::write_row(uchar * buf) } m_last_part= part_id; DBUG_PRINT("info", ("Insert in partition %d", part_id)); + start_part_bulk_insert(part_id); + tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */ error= m_file[part_id]->ha_write_row(buf); if (have_auto_increment && !table->s->next_number_keypart) @@ -3083,6 +3100,7 @@ int ha_partition::update_row(const uchar *old_data, uchar *new_data) } m_last_part= new_part_id; + start_part_bulk_insert(new_part_id); if (new_part_id == old_part_id) { DBUG_PRINT("info", ("Update in partition %d", new_part_id)); @@ -3247,22 +3265,65 @@ int ha_partition::delete_all_rows() DESCRIPTION rows == 0 means we will probably insert many rows */ - void ha_partition::start_bulk_insert(ha_rows rows) { - handler **file; DBUG_ENTER("ha_partition::start_bulk_insert"); - rows= rows ? rows/m_tot_parts + 1 : 0; - file= m_file; - do - { - (*file)->ha_start_bulk_insert(rows); - } while (*(++file)); + m_bulk_inserted_rows= 0; + bitmap_clear_all(&m_bulk_insert_started); + /* use the last bit for marking if bulk_insert_started was called */ + bitmap_set_bit(&m_bulk_insert_started, m_tot_parts); DBUG_VOID_RETURN; } +/* + Check if start_bulk_insert has been called for this partition, + if not, call it and mark it called +*/ +void ha_partition::start_part_bulk_insert(uint part_id) +{ + if (!bitmap_is_set(&m_bulk_insert_started, part_id) && + bitmap_is_set(&m_bulk_insert_started, m_tot_parts)) + { + m_file[part_id]->ha_start_bulk_insert(guess_bulk_insert_rows()); + bitmap_set_bit(&m_bulk_insert_started, part_id); + } + m_bulk_inserted_rows++; +} + + +/* + Try to predict the number of inserts into this partition. + + If less than 10 rows (including 0 which means Unknown) + just give that as a guess + If monotonic partitioning function was used + guess that 50 % of the inserts goes to the first partition + For all other cases, guess on equal distribution between the partitions +*/ +ha_rows ha_partition::guess_bulk_insert_rows() +{ + DBUG_ENTER("guess_bulk_insert_rows"); + + if (estimation_rows_to_insert < 10) + DBUG_RETURN(estimation_rows_to_insert); + + /* If first insert/partition and monotonic partition function, guess 50%. */ + if (!m_bulk_inserted_rows && + m_part_func_monotonicity_info != NON_MONOTONIC && + m_tot_parts > 1) + DBUG_RETURN(estimation_rows_to_insert / 2); + + /* Else guess on equal distribution (+1 is to avoid returning 0/Unknown) */ + if (m_bulk_inserted_rows < estimation_rows_to_insert) + DBUG_RETURN(((estimation_rows_to_insert - m_bulk_inserted_rows) + / m_tot_parts) + 1); + /* The estimation was wrong, must say 'Unknown' */ + DBUG_RETURN(0); +} + + /* Finish a large batch of insert rows @@ -3272,21 +3333,29 @@ void ha_partition::start_bulk_insert(ha_rows rows) RETURN VALUE >0 Error code 0 Success + + Note: end_bulk_insert can be called without start_bulk_insert + being called, see bug¤44108. + */ int ha_partition::end_bulk_insert() { int error= 0; - handler **file; + uint i; DBUG_ENTER("ha_partition::end_bulk_insert"); - file= m_file; - do + if (!bitmap_is_set(&m_bulk_insert_started, m_tot_parts)) + DBUG_RETURN(error); + + for (i= 0; i < m_tot_parts; i++) { int tmp; - if ((tmp= (*file)->ha_end_bulk_insert())) + if (bitmap_is_set(&m_bulk_insert_started, i) && + (tmp= m_file[i]->ha_end_bulk_insert())) error= tmp; - } while (*(++file)); + } + bitmap_clear_all(&m_bulk_insert_started); DBUG_RETURN(error); } diff --git a/sql/ha_partition.h b/sql/ha_partition.h index d0301e24a93..f47dfe8f621 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -176,6 +176,11 @@ private: This to ensure it will work with statement based replication. */ bool auto_increment_safe_stmt_log_lock; + /** For optimizing ha_start_bulk_insert calls */ + MY_BITMAP m_bulk_insert_started; + ha_rows m_bulk_inserted_rows; + /** used for prediction of start_bulk_insert rows */ + enum_monotonicity_info m_part_func_monotonicity_info; public: handler *clone(MEM_ROOT *mem_root); virtual void set_part_info(partition_info *part_info) @@ -353,7 +358,6 @@ public: Bulk inserts are supported if all underlying handlers support it. start_bulk_insert and end_bulk_insert is called before and after a number of calls to write_row. - Not yet though. */ virtual int write_row(uchar * buf); virtual int update_row(const uchar * old_data, uchar * new_data); @@ -361,6 +365,10 @@ public: virtual int delete_all_rows(void); virtual void start_bulk_insert(ha_rows rows); virtual int end_bulk_insert(); +private: + ha_rows guess_bulk_insert_rows(); + void start_part_bulk_insert(uint part_id); +public: virtual bool is_fatal_error(int error, uint flags) { From c7d32876f345785580a7cf286542ccf390b4e1fa Mon Sep 17 00:00:00 2001 From: Jonathan Perkin Date: Fri, 4 Sep 2009 17:45:07 +0200 Subject: [PATCH 087/138] Install mysqld.lib --- scripts/make_win_bin_dist | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist index 9c17c26b445..fdb34f2f48d 100755 --- a/scripts/make_win_bin_dist +++ b/scripts/make_win_bin_dist @@ -280,6 +280,7 @@ cp include/mysql/plugin.h $DESTDIR/include/mysql/ mkdir -p $DESTDIR/lib/opt mkdir -p $DESTDIR/lib/plugin +cp sql/$TARGET/mysqld.lib $DESTDIR/lib/ cp libmysql/$TARGET/libmysql.dll \ libmysql/$TARGET/libmysql.lib \ libmysql/$TARGET/mysqlclient.lib \ From e49a210c8c47dedb2fd384f3f5c170506e580ba7 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 4 Sep 2009 17:02:17 -0300 Subject: [PATCH 088/138] Bug#45605: ps_not_windows.test fails: The plugin feature is disabled, you need HAVE_DLOPEN Selectively skip tests that require dynamic loading (ie: static builds). mysql-test/include/have_dynamic_loading.inc: Add require file. mysql-test/t/ps_not_windows.test: Test requires dynamic loading support. --- mysql-test/include/have_dynamic_loading.inc | 7 +++++++ mysql-test/include/have_example_plugin.inc | 5 +---- mysql-test/include/have_simple_parser.inc | 5 +---- mysql-test/include/have_udf.inc | 5 +---- mysql-test/t/ps_not_windows.test | 2 ++ 5 files changed, 12 insertions(+), 12 deletions(-) create mode 100644 mysql-test/include/have_dynamic_loading.inc diff --git a/mysql-test/include/have_dynamic_loading.inc b/mysql-test/include/have_dynamic_loading.inc new file mode 100644 index 00000000000..1b2c85b3904 --- /dev/null +++ b/mysql-test/include/have_dynamic_loading.inc @@ -0,0 +1,7 @@ +# +# Whether server supports dynamic loading. +# +--require r/have_dynamic_loading.require +disable_query_log; +show variables like 'have_dynamic_loading'; +enable_query_log; diff --git a/mysql-test/include/have_example_plugin.inc b/mysql-test/include/have_example_plugin.inc index 8e57c725eb5..a2fffc17b97 100644 --- a/mysql-test/include/have_example_plugin.inc +++ b/mysql-test/include/have_example_plugin.inc @@ -2,10 +2,7 @@ # Check if server has support for loading udf's # i.e it will support dlopen # ---require r/have_dynamic_loading.require -disable_query_log; -show variables like 'have_dynamic_loading'; -enable_query_log; +--source include/have_dynamic_loading.inc # # Check if the variable EXAMPLE_PLUGIN is set diff --git a/mysql-test/include/have_simple_parser.inc b/mysql-test/include/have_simple_parser.inc index c85786bd524..5a4dc93ec81 100644 --- a/mysql-test/include/have_simple_parser.inc +++ b/mysql-test/include/have_simple_parser.inc @@ -2,10 +2,7 @@ # Check if server has support for loading udf's # i.e it will support dlopen # ---require r/have_dynamic_loading.require -disable_query_log; -show variables like 'have_dynamic_loading'; -enable_query_log; +--source include/have_dynamic_loading.inc # # Check if the variable SIMPLE_PARSER is set diff --git a/mysql-test/include/have_udf.inc b/mysql-test/include/have_udf.inc index 3f7e260c5ba..7be57bbb7a9 100644 --- a/mysql-test/include/have_udf.inc +++ b/mysql-test/include/have_udf.inc @@ -2,10 +2,7 @@ # Check if server has support for loading udf's # i.e it will support dlopen # ---require r/have_dynamic_loading.require -disable_query_log; -show variables like 'have_dynamic_loading'; -enable_query_log; +--source include/have_dynamic_loading.inc # # Check if the variable UDF_EXAMPLE_LIB is set diff --git a/mysql-test/t/ps_not_windows.test b/mysql-test/t/ps_not_windows.test index 6d85f737b32..0ab08b59f1e 100644 --- a/mysql-test/t/ps_not_windows.test +++ b/mysql-test/t/ps_not_windows.test @@ -2,6 +2,8 @@ --source include/not_embedded.inc # Non-windows specific ps tests. --source include/not_windows.inc +# requires dynamic loading +--source include/have_dynamic_loading.inc # # Bug #20665: All commands supported in Stored Procedures should work in From 645f7841cf09294eb70838eaee58928a10f615a8 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Sat, 5 Sep 2009 09:40:18 +0200 Subject: [PATCH 089/138] followup fixes after merge to -trunk --- mysql-test/collections/default.experimental | 4 +++- mysql-test/r/bug46080.result | 2 ++ .../suite/rpl/r/rpl_get_master_version_and_clock.result | 2 ++ mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test | 4 ++++ mysql-test/t/bug46080.test | 3 +++ 5 files changed, 14 insertions(+), 1 deletion(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 69176a47a5e..e4e65ad555f 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -4,5 +4,7 @@ main.ctype_gbk_binlog @solaris # Bug#46010: main.ctype_gbk_binlog fail rpl.rpl_row_create_table* # Bug#45576: rpl_row_create_table fails on PB2 rpl_ndb.rpl_ndb_log # Bug#38998 rpl.rpl_innodb_bug28430* @solaris # Bug#46029 -main.plugin_load @solaris # Bug #42144 +main.plugin_load @solaris # Bug#42144 rpl.rpl_get_master_version_and_clock* # Bug#46931 2009-08-26 alik rpl.rpl_get_master_version_and_clock fails on hpux11.31 +main.plugin* @solaris # Bug#47146 Linking problem with example plugin when dtrace enabled +rpl.rpl_plugin_load* @solaris # Bug#47146 diff --git a/mysql-test/r/bug46080.result b/mysql-test/r/bug46080.result index 18c7c22829a..2173768cdad 100644 --- a/mysql-test/r/bug46080.result +++ b/mysql-test/r/bug46080.result @@ -2,6 +2,8 @@ # Bug #46080: group_concat(... order by) crashes server when # sort_buffer_size cannot allocate # +call mtr.add_suppression("Out of memory at line .*, 'my_alloc.c'"); +call mtr.add_suppression("needed .* byte .*k., memory in use: .* bytes .*k"); CREATE TABLE t1(a CHAR(255)); INSERT INTO t1 VALUES ('a'); SET @@SESSION.sort_buffer_size=5*16*1000000; diff --git a/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result b/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result index 263896b884a..4b90cf3e8cc 100644 --- a/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result +++ b/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result @@ -4,6 +4,8 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +call mtr.add_suppression("Slave I/O: Get master clock failed with error: Lost connection to MySQL server at 'reading initial communication packet'"); +call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again"); SELECT IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP"); IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP") 1 diff --git a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test index 40d11f2cec2..db20a808b09 100644 --- a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test +++ b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test @@ -16,6 +16,10 @@ source include/master-slave.inc; source include/have_debug.inc; + +call mtr.add_suppression("Slave I/O: Get master clock failed with error: Lost connection to MySQL server at 'reading initial communication packet'"); +call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again"); + #Test case 1: Try to get the value of the UNIX_TIMESTAMP from master under network disconnection connection slave; let $debug_saved= `select @@global.debug`; diff --git a/mysql-test/t/bug46080.test b/mysql-test/t/bug46080.test index 7e56e3ce421..8b4cee4d8b0 100644 --- a/mysql-test/t/bug46080.test +++ b/mysql-test/t/bug46080.test @@ -3,6 +3,9 @@ --echo # sort_buffer_size cannot allocate --echo # +call mtr.add_suppression("Out of memory at line .*, 'my_alloc.c'"); +call mtr.add_suppression("needed .* byte .*k., memory in use: .* bytes .*k"); + CREATE TABLE t1(a CHAR(255)); INSERT INTO t1 VALUES ('a'); From c18e4b42b32e89307f5c903566b6ee43da12466f Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Sat, 5 Sep 2009 18:50:31 +0200 Subject: [PATCH 090/138] suppression for rpl.rpl_get_master_version_and_clock was incomplete --- mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result | 2 +- mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result b/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result index 4b90cf3e8cc..99a0fd21f66 100644 --- a/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result +++ b/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result @@ -4,7 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; -call mtr.add_suppression("Slave I/O: Get master clock failed with error: Lost connection to MySQL server at 'reading initial communication packet'"); +call mtr.add_suppression("Slave I/O: .* failed with error: Lost connection to MySQL server at 'reading initial communication packet'"); call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again"); SELECT IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP"); IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP") diff --git a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test index db20a808b09..c7c66bfde71 100644 --- a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test +++ b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test @@ -17,7 +17,7 @@ source include/master-slave.inc; source include/have_debug.inc; -call mtr.add_suppression("Slave I/O: Get master clock failed with error: Lost connection to MySQL server at 'reading initial communication packet'"); +call mtr.add_suppression("Slave I/O: .* failed with error: Lost connection to MySQL server at 'reading initial communication packet'"); call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again"); #Test case 1: Try to get the value of the UNIX_TIMESTAMP from master under network disconnection From 505346028f975d26f1353c46bdb3db618b1e306c Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Sun, 6 Sep 2009 00:42:17 +0400 Subject: [PATCH 091/138] Bug #46159: simple query that never returns The external 'for' loop in remove_dup_with_compare() handled HA_ERR_RECORD_DELETED by just starting over without advancing to the next record which caused an infinite loop. This condition could be triggered on certain data by a SELECT query containing DISTINCT, GROUP BY and HAVING clauses. Fixed remove_dup_with_compare() so that we always advance to the next record when receiving HA_ERR_RECORD_DELETED from rnd_next(). mysql-test/r/distinct.result: Added a test case for bug #46159. mysql-test/t/distinct.test: Added a test case for bug #46159. sql/sql_select.cc: Fixed remove_dup_with_compare() so that we always advance to the next record when receiving HA_ERR_RECORD_DELETED from rnd_next(). --- mysql-test/r/distinct.result | 30 +++++++++++++++++++++++++++ mysql-test/t/distinct.test | 40 ++++++++++++++++++++++++++++++++++++ sql/sql_select.cc | 5 ++++- 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index e0324af8cfd..b1cb70fa43c 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -763,4 +763,34 @@ a b d c 1 2 0 2 1 2 0 3 DROP TABLE t1; +# +# Bug #46159: simple query that never returns +# +SET @old_max_heap_table_size = @@max_heap_table_size; +SET @@max_heap_table_size = 16384; +SET @old_sort_buffer_size = @@sort_buffer_size; +SET @@sort_buffer_size = 32804; +CREATE TABLE t1(c1 int, c2 VARCHAR(20)); +INSERT INTO t1 VALUES (1, '1'), (1, '1'), (2, '2'), (3, '1'), (3, '1'), (4, '4'); +INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1; +INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1; +INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1; +INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1; +INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1; +INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1; +INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1; +INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1; +SELECT c1, c2, COUNT(*) FROM t1 GROUP BY c1 LIMIT 4; +c1 c2 COUNT(*) +1 1 2 +2 2 1 +3 1 2 +4 4 1 +SELECT DISTINCT c2 FROM t1 GROUP BY c1 HAVING COUNT(*) > 1; +c2 +1 +5 +DROP TABLE t1; +SET @@sort_buffer_size = @old_sort_buffer_size; +SET @@max_heap_table_size = @old_max_heap_table_size; End of 5.1 tests diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test index a77d1136840..bf4c23562cf 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -573,4 +573,44 @@ SELECT DISTINCT a, b, d, c FROM t1; DROP TABLE t1; +--echo # +--echo # Bug #46159: simple query that never returns +--echo # + +# Set max_heap_table_size to the minimum value so that GROUP BY table in the +# SELECT query below gets converted to MyISAM +SET @old_max_heap_table_size = @@max_heap_table_size; +SET @@max_heap_table_size = 16384; + +# Set sort_buffer_size to the mininum value so that remove_duplicates() calls +# remove_dup_with_compare() +SET @old_sort_buffer_size = @@sort_buffer_size; +SET @@sort_buffer_size = 32804; + +CREATE TABLE t1(c1 int, c2 VARCHAR(20)); +INSERT INTO t1 VALUES (1, '1'), (1, '1'), (2, '2'), (3, '1'), (3, '1'), (4, '4'); +# Now we just need to pad the table with random data so we have enough unique +# values to force conversion of the GROUP BY table to MyISAM +INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1; +INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1; +INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1; +INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1; +INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1; +INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1; +INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1; +INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1; + +# First rows of the GROUP BY table that will be processed by +# remove_dup_with_compare() +SELECT c1, c2, COUNT(*) FROM t1 GROUP BY c1 LIMIT 4; + +# The actual test case +SELECT DISTINCT c2 FROM t1 GROUP BY c1 HAVING COUNT(*) > 1; + +# Cleanup + +DROP TABLE t1; +SET @@sort_buffer_size = @old_sort_buffer_size; +SET @@max_heap_table_size = @old_max_heap_table_size; + --echo End of 5.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5cb0de1ba5c..a02430446d1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13665,7 +13665,10 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, if (error) { if (error == HA_ERR_RECORD_DELETED) - continue; + { + error= file->rnd_next(record); + continue; + } if (error == HA_ERR_END_OF_FILE) break; goto err; From 5210d5a9a6bb30d1158ea0b0de934f7dddde854c Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 7 Sep 2009 13:01:03 +0800 Subject: [PATCH 092/138] Bug#45581 Test rpl_row_sp006_InnoDB fails randomly: Unknown database 'mysqltest1' Postfix. extra/rpl_tests/rpl_row_sp006.test had changed to fix this bug. extra/rpl_tests/rpl_row_sp006.test is also referenced by rpl_ndb_sp006, So rpl_row_sp006.result must be changed too. --- .../suite/rpl_ndb/r/rpl_ndb_sp006.result | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_sp006.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_sp006.result index 482d43c8f10..047402f826f 100644 --- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_sp006.result +++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_sp006.result @@ -4,21 +4,20 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; -create database if not exists mysqltest1; -DROP PROCEDURE IF EXISTS mysqltest1.p1; -DROP PROCEDURE IF EXISTS mysqltest1.p2; -DROP TABLE IF EXISTS mysqltest1.t2; -DROP TABLE IF EXISTS mysqltest1.t1; -CREATE TABLE IF NOT EXISTS mysqltest1.t1(name CHAR(16), birth DATE,PRIMARY KEY(name))ENGINE=NDBCLUSTER; -CREATE TABLE IF NOT EXISTS mysqltest1.t2(name CHAR(16), age INT ,PRIMARY KEY(name))ENGINE=NDBCLUSTER; -CREATE PROCEDURE mysqltest1.p1() +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; +CREATE TABLE IF NOT EXISTS t1(name CHAR(16), birth DATE,PRIMARY KEY(name))ENGINE=NDBCLUSTER; +CREATE TABLE IF NOT EXISTS t2(name CHAR(16), age INT ,PRIMARY KEY(name))ENGINE=NDBCLUSTER; +CREATE PROCEDURE p1() BEGIN DECLARE done INT DEFAULT 0; DECLARE spa CHAR(16); DECLARE spb INT; DECLARE cur1 CURSOR FOR SELECT name, (YEAR(CURDATE())-YEAR(birth))-(RIGHT(CURDATE(),5) Date: Mon, 7 Sep 2009 13:42:54 +0800 Subject: [PATCH 093/138] Bug#46010 main.ctype_gbk_binlog fails sporadically : Table 't2' already exists This test case uses mysqlbinlog to dump the content of master-bin.000001, but the content of master-bin.000001 is not that this test needs. MTR runs a lot of test cases on one server, so when this test starts, the current binlog file might not be master-bin.000001, or there are other events are written by tests before. 'RESET MASTER' command must be called at the begin, it ensures that binlog of this test is wrote to master-bin.000001 correctly. Three other tests have the same problem, They were fixed together. mysqlbinlog-cp932 binlog_incident binlog_tmp_table --- mysql-test/r/ctype_gbk_binlog.result | 1 + mysql-test/r/mysqlbinlog-cp932.result | 2 +- mysql-test/suite/binlog/r/binlog_incident.result | 1 + mysql-test/suite/binlog/r/binlog_tmp_table.result | 1 + mysql-test/suite/binlog/t/binlog_incident.test | 3 ++- mysql-test/suite/binlog/t/binlog_tmp_table.test | 1 + mysql-test/t/ctype_gbk_binlog.test | 1 + mysql-test/t/mysqlbinlog-cp932.test | 5 +++-- 8 files changed, 11 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/ctype_gbk_binlog.result b/mysql-test/r/ctype_gbk_binlog.result index a49e170ff19..df927af9a6b 100644 --- a/mysql-test/r/ctype_gbk_binlog.result +++ b/mysql-test/r/ctype_gbk_binlog.result @@ -1,3 +1,4 @@ +RESET MASTER; SET NAMES gbk; CREATE TABLE t1 ( f1 BLOB diff --git a/mysql-test/r/mysqlbinlog-cp932.result b/mysql-test/r/mysqlbinlog-cp932.result index 1640a3b1642..cbf6159516a 100644 --- a/mysql-test/r/mysqlbinlog-cp932.result +++ b/mysql-test/r/mysqlbinlog-cp932.result @@ -1,4 +1,4 @@ -flush logs; +RESET MASTER; create table t3 (f text character set utf8); create table t4 (f text character set cp932); flush logs; diff --git a/mysql-test/suite/binlog/r/binlog_incident.result b/mysql-test/suite/binlog/r/binlog_incident.result index d8b0357b8c4..7a555743723 100644 --- a/mysql-test/suite/binlog/r/binlog_incident.result +++ b/mysql-test/suite/binlog/r/binlog_incident.result @@ -1,3 +1,4 @@ +RESET MASTER; CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(2),(3); SELECT * FROM t1; diff --git a/mysql-test/suite/binlog/r/binlog_tmp_table.result b/mysql-test/suite/binlog/r/binlog_tmp_table.result index e4928432324..14b1963ffd9 100644 --- a/mysql-test/suite/binlog/r/binlog_tmp_table.result +++ b/mysql-test/suite/binlog/r/binlog_tmp_table.result @@ -1,3 +1,4 @@ +RESET MASTER; create table foo (a int); flush logs; create temporary table tmp1_foo like foo; diff --git a/mysql-test/suite/binlog/t/binlog_incident.test b/mysql-test/suite/binlog/t/binlog_incident.test index 208c7f24df2..901ac49ea24 100644 --- a/mysql-test/suite/binlog/t/binlog_incident.test +++ b/mysql-test/suite/binlog/t/binlog_incident.test @@ -6,6 +6,7 @@ source include/have_log_bin.inc; source include/have_debug.inc; let $MYSQLD_DATADIR= `select @@datadir`; +RESET MASTER; CREATE TABLE t1 (a INT); @@ -24,4 +25,4 @@ exec $MYSQL_BINLOG --start-position=106 $MYSQLD_DATADIR/master-bin.000001 >$MYSQ eval SELECT cont LIKE '%RELOAD DATABASE; # Shall generate syntax error%' AS `Contain RELOAD DATABASE` FROM (SELECT load_file('$MYSQLTEST_VARDIR/tmp/binlog_incident-bug44442.sql') AS cont) AS tbl; --enable_query_log -remove_file $MYSQLTEST_VARDIR/tmp/binlog_incident-bug44442.sql; \ No newline at end of file +remove_file $MYSQLTEST_VARDIR/tmp/binlog_incident-bug44442.sql; diff --git a/mysql-test/suite/binlog/t/binlog_tmp_table.test b/mysql-test/suite/binlog/t/binlog_tmp_table.test index 6947959a5e0..54af8a8cb68 100644 --- a/mysql-test/suite/binlog/t/binlog_tmp_table.test +++ b/mysql-test/suite/binlog/t/binlog_tmp_table.test @@ -30,6 +30,7 @@ source include/have_binlog_format_mixed_or_statement.inc; connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,); connect (master1,127.0.0.1,root,,test,$MASTER_MYPORT,); +RESET MASTER; create table foo (a int); diff --git a/mysql-test/t/ctype_gbk_binlog.test b/mysql-test/t/ctype_gbk_binlog.test index a8f653d1b1e..e4c1bee19af 100644 --- a/mysql-test/t/ctype_gbk_binlog.test +++ b/mysql-test/t/ctype_gbk_binlog.test @@ -1,6 +1,7 @@ -- source include/have_binlog_format_mixed_or_statement.inc -- source include/have_gbk.inc +RESET MASTER; SET NAMES gbk; --character_set gbk diff --git a/mysql-test/t/mysqlbinlog-cp932.test b/mysql-test/t/mysqlbinlog-cp932.test index a7055bfc8ca..2a210bea0e0 100644 --- a/mysql-test/t/mysqlbinlog-cp932.test +++ b/mysql-test/t/mysqlbinlog-cp932.test @@ -5,8 +5,9 @@ -- source include/have_cp932.inc -- source include/have_log_bin.inc +RESET MASTER; + # Bug#16217 (mysql client did not know how not switch its internal charset) -flush logs; create table t3 (f text character set utf8); create table t4 (f text character set cp932); --exec $MYSQL --default-character-set=utf8 test -e "insert into t3 values(_utf8'ソ')" @@ -14,7 +15,7 @@ create table t4 (f text character set cp932); flush logs; rename table t3 to t03, t4 to t04; let $MYSQLD_DATADIR= `select @@datadir`; ---exec $MYSQL_BINLOG --short-form $MYSQLD_DATADIR/master-bin.000002 | $MYSQL --default-character-set=utf8 +--exec $MYSQL_BINLOG --short-form $MYSQLD_DATADIR/master-bin.000001 | $MYSQL --default-character-set=utf8 # original and recovered data must be equal select HEX(f) from t03; select HEX(f) from t3; From dd407c5228df80a7ef6086c412940084e7498627 Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Mon, 7 Sep 2009 10:37:54 +0200 Subject: [PATCH 094/138] Fix to ensure that all subpartitions gets deleted before renaming starts, BUG#47029 --- mysql-test/r/partition_innodb.result | 14 ++++++++++++++ mysql-test/t/partition_innodb.test | 17 +++++++++++++++++ sql/ha_partition.cc | 1 + 3 files changed, 32 insertions(+) diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result index ad4d08e89ff..9c5675c0c75 100644 --- a/mysql-test/r/partition_innodb.result +++ b/mysql-test/r/partition_innodb.result @@ -1,4 +1,18 @@ drop table if exists t1; +create table t1 (a int not null, +b datetime not null, +primary key (a,b)) +engine=innodb +partition by range (to_days(b)) +subpartition by hash (a) +subpartitions 2 +( partition p0 values less than (to_days('2009-01-01')), +partition p1 values less than (to_days('2009-02-01')), +partition p2 values less than (to_days('2009-03-01')), +partition p3 values less than maxvalue); +alter table t1 reorganize partition p1,p2 into +( partition p2 values less than (to_days('2009-03-01'))); +drop table t1; CREATE TABLE t1 (id INT PRIMARY KEY, data INT) ENGINE = InnoDB PARTITION BY RANGE(id) ( PARTITION p0 VALUES LESS THAN (5), diff --git a/mysql-test/t/partition_innodb.test b/mysql-test/t/partition_innodb.test index 2abbceffbb0..b29ce289811 100644 --- a/mysql-test/t/partition_innodb.test +++ b/mysql-test/t/partition_innodb.test @@ -5,6 +5,23 @@ drop table if exists t1; --enable_warnings +# +# Bug#47029: Crash when reorganize partition with subpartition +# +create table t1 (a int not null, + b datetime not null, + primary key (a,b)) +engine=innodb +partition by range (to_days(b)) +subpartition by hash (a) +subpartitions 2 +( partition p0 values less than (to_days('2009-01-01')), + partition p1 values less than (to_days('2009-02-01')), + partition p2 values less than (to_days('2009-03-01')), + partition p3 values less than maxvalue); +alter table t1 reorganize partition p1,p2 into +( partition p2 values less than (to_days('2009-03-01'))); +drop table t1; # # Bug#40595: Non-matching rows not released with READ-COMMITTED on tables # with partitions diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index ac8c46ec4e3..2e303744c1a 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -705,6 +705,7 @@ int ha_partition::rename_partitions(const char *path) if (m_is_sub_partitioned) { List_iterator sub_it(part_elem->subpartitions); + j= 0; do { sub_elem= sub_it++; From 2cb3a131f47a8bcf0398a28e4a6a16d1c30c9708 Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Mon, 7 Sep 2009 11:57:22 +0200 Subject: [PATCH 095/138] Bug#46259: 5.0.83 -> 5.1.36, query doesn't work The parser rule for expressions in a udf parameter list contains two hacks: First, the parser input stream is read verbatim, bypassing the lexer. Second, the Item::name field is overwritten. If the argument to a udf was a field, the field's name as seen by name resolution was overwritten this way. If the field name was quoted or escaped, it would appear as e.g. "`field`". Fixed by not overwriting field names. mysql-test/r/udf.result: Bug#46259: Test result. mysql-test/t/udf.test: Bug#46259: Test case. sql/sql_yacc.yy: Bug#46259: Fix. --- mysql-test/r/udf.result | 16 ++++++++++++++++ mysql-test/t/udf.test | 12 ++++++++++++ sql/sql_yacc.yy | 8 +++++++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result index 15410ac2039..601b364fbbe 100644 --- a/mysql-test/r/udf.result +++ b/mysql-test/r/udf.result @@ -392,4 +392,20 @@ a 4 DROP FUNCTION sequence; DROP TABLE t1,t2; +# +# Bug#46259: 5.0.83 -> 5.1.36, query doesn't work +# +CREATE TABLE t1 ( a INT ); +INSERT INTO t1 VALUES (1), (2), (3); +SELECT IF( a = 1, a, a ) AS `b` FROM t1 ORDER BY field( `b` + 1, 1 ); +b +1 +2 +3 +SELECT IF( a = 1, a, a ) AS `b` FROM t1 ORDER BY field( `b`, 1 ); +b +2 +3 +1 +DROP TABLE t1; End of 5.0 tests. diff --git a/mysql-test/t/udf.test b/mysql-test/t/udf.test index e9ae1a31079..7bf252040e5 100644 --- a/mysql-test/t/udf.test +++ b/mysql-test/t/udf.test @@ -436,4 +436,16 @@ SELECT * FROM t2 WHERE a = sequence(); DROP FUNCTION sequence; DROP TABLE t1,t2; +--echo # +--echo # Bug#46259: 5.0.83 -> 5.1.36, query doesn't work +--echo # +CREATE TABLE t1 ( a INT ); + +INSERT INTO t1 VALUES (1), (2), (3); + +SELECT IF( a = 1, a, a ) AS `b` FROM t1 ORDER BY field( `b` + 1, 1 ); +SELECT IF( a = 1, a, a ) AS `b` FROM t1 ORDER BY field( `b`, 1 ); + +DROP TABLE t1; + --echo End of 5.0 tests. diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a18f57bf9cf..db97e77bbd0 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7921,7 +7921,13 @@ udf_expr: $2->is_autogenerated_name= FALSE; $2->set_name($4.str, $4.length, system_charset_info); } - else + /* + A field has to have its proper name in order for name + resolution to work, something we are only guaranteed if we + parse it out. If we hijack the input stream with + remember_name we may get quoted or escaped names. + */ + else if ($2->type() != Item::FIELD_ITEM) $2->set_name($1, (uint) ($3 - $1), YYTHD->charset()); $$= $2; } From 540b2dc0041c292220d389bbb5b87a8410aef3f4 Mon Sep 17 00:00:00 2001 From: Ingo Struewing Date: Mon, 7 Sep 2009 18:35:37 +0200 Subject: [PATCH 096/138] Bug#17332 - changing key_buffer_size on a running server can crash under load Backport from 5.1. Does also include key cache fixes from: Bug 44068 (RESTORE can disable the MyISAM Key Cache) Bug 40944 (Backup: crash after myisampack) include/keycache.h: Bug#17332 - changing key_buffer_size on a running server can crash under load Added KEY_CACHE components in_resize and waiting_for_resize_cnt. myisam/mi_preload.c: Bug#17332 - changing key_buffer_size on a running server can crash under load Added code to allow LOAD INDEX to load indexes of different block size. mysys/mf_keycache.c: Bug#17332 - changing key_buffer_size on a running server can crash under load . Changed resize_key_cache() to not disable the key cache after the flush phase. Changed queue handling to use standard functions. Wake all threads waiting on resize_queue. We can now have read/write threads waiting there (see below). . Combined add_to_queue() and the wait loops that were always following it to the new function wait_on_queue(). Combined release_queue() and the condition that was always preceding it to the new function release_whole_queue(). . Added code to flag and respect the exceptional situation BLOCK_IN_EVICTION. . Rewrote the resize branch of find_key_block(). . Added code to the eviction handling in find_key_block() to catch more exceptional cases. . Changed key_cache_read(), key_cache_insert() and key_cache_write() so that they lock keycache->cache_lock whenever the key cache is initialized. Checking for a disabled cache and incrementing and decrementing the "resize counter" is always done within the lock. Locking and unlocking as well as counting the "resize counter" is now done once outside the loop. All three functions can now handle a NULL return from find_key_block. This happens in the flush phase of a resize and demands direct file I/O. Care is taken for secondary requests (PAGE_WAIT_TO_BE_READ) to wait in any case. Moved block status changes behind the copying of buffer data. key_cache_insert() does now read the block if the caller did supply less data than a full cache block. key_cache_write() does now take care of parallel running flushes (BLOCK_FOR_UPDATE, BLOCK_IN_FLUSHWRITE). . Changed free_block() to un-initialize block variables in the correct order and respect an exceptional BLOCK_IN_EVICTION state. . Changed flushing to take care for parallel running writes. Changed flushing to avoid freeing blocks in eviction. Changed flushing to consider that parallel writes can move blocks from the file_blocks hash to the changed_blocks hash. Changed flushing to take care for other parallel flushes. Changed flushing to assure that it ends with everything flushed. Optimized normal flush at end of statement (FLUSH_KEEP), but let other flush types be stringent. . Added some comments and debugging statements. mysys/my_static.c: Bug#17332 - changing key_buffer_size on a running server can crash under load Removed an unused global variable. sql/ha_myisam.cc: Bug#17332 - changing key_buffer_size on a running server can crash under load Moved an automatic (stack) variable to the scope where it is used. sql/sql_table.cc: Bug#17332 - changing key_buffer_size on a running server can crash under load Changed TL_READ to TL_READ_NO_INSERT in mysql_preload_keys. --- include/keycache.h | 6 + myisam/mi_preload.c | 13 +- mysys/mf_keycache.c | 2687 +++++++++++++++++++++++++++++++++++-------- mysys/my_static.c | 3 - sql/ha_myisam.cc | 2 +- sql/sql_table.cc | 7 +- 6 files changed, 2210 insertions(+), 508 deletions(-) diff --git a/include/keycache.h b/include/keycache.h index 424b4086cb4..b2e959955d0 100644 --- a/include/keycache.h +++ b/include/keycache.h @@ -44,6 +44,7 @@ typedef struct st_keycache_wqueue typedef struct st_key_cache { my_bool key_cache_inited; + my_bool in_resize; /* true during resize operation */ my_bool resize_in_flush; /* true during flush of resize operation */ my_bool can_be_used; /* usage of cache for read/write is allowed */ size_t key_cache_mem_size; /* specified size of the cache memory */ @@ -71,6 +72,11 @@ typedef struct st_key_cache BLOCK_LINK *used_ins; /* ptr to the insertion block in LRU chain */ pthread_mutex_t cache_lock; /* to lock access to the cache structure */ KEYCACHE_WQUEUE resize_queue; /* threads waiting during resize operation */ + /* + Waiting for a zero resize count. Using a queue for symmetry though + only one thread can wait here. + */ + KEYCACHE_WQUEUE waiting_for_resize_cnt; KEYCACHE_WQUEUE waiting_for_hash_link; /* waiting for a free hash link */ KEYCACHE_WQUEUE waiting_for_block; /* requests waiting for a free block */ BLOCK_LINK *changed_blocks[CHANGED_BLOCKS_HASH]; /* hash for dirty file bl.*/ diff --git a/myisam/mi_preload.c b/myisam/mi_preload.c index 78729f18424..06c66c06bf4 100644 --- a/myisam/mi_preload.c +++ b/myisam/mi_preload.c @@ -55,12 +55,17 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves) block_length= keyinfo[0].block_length; - /* Check whether all indexes use the same block size */ - for (i= 1 ; i < keys ; i++) + if (ignore_leaves) { - if (keyinfo[i].block_length != block_length) - DBUG_RETURN(my_errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE); + /* Check whether all indexes use the same block size */ + for (i= 1 ; i < keys ; i++) + { + if (keyinfo[i].block_length != block_length) + DBUG_RETURN(my_errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE); + } } + else + block_length= share->key_cache->key_cache_block_size; length= info->preload_buff_size/block_length * block_length; set_if_bigger(length, block_length); diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 0720d172317..f9898e263aa 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -13,7 +13,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* +/** + @file These functions handle keyblock cacheing for ISAM and MyISAM tables. One cache can handle many files. @@ -38,7 +39,73 @@ as such gives the maximum number of in-use blocks at any time. */ +/* + Key Cache Locking + ================= + + All key cache locking is done with a single mutex per key cache: + keycache->cache_lock. This mutex is locked almost all the time + when executing code in this file (mf_keycache.c). + However it is released for I/O and some copy operations. + + The cache_lock is also released when waiting for some event. Waiting + and signalling is done via condition variables. In most cases the + thread waits on its thread->suspend condition variable. Every thread + has a my_thread_var structure, which contains this variable and a + '*next' and '**prev' pointer. These pointers are used to insert the + thread into a wait queue. + + A thread can wait for one block and thus be in one wait queue at a + time only. + + Before starting to wait on its condition variable with + pthread_cond_wait(), the thread enters itself to a specific wait queue + with link_into_queue() (double linked with '*next' + '**prev') or + wait_on_queue() (single linked with '*next'). + + Another thread, when releasing a resource, looks up the waiting thread + in the related wait queue. It sends a signal with + pthread_cond_signal() to the waiting thread. + + NOTE: Depending on the particular wait situation, either the sending + thread removes the waiting thread from the wait queue with + unlink_from_queue() or release_whole_queue() respectively, or the waiting + thread removes itself. + + There is one exception from this locking scheme when one thread wants + to reuse a block for some other address. This works by first marking + the block reserved (status= BLOCK_IN_SWITCH) and then waiting for all + threads that are reading the block to finish. Each block has a + reference to a condition variable (condvar). It holds a reference to + the thread->suspend condition variable for the waiting thread (if such + a thread exists). When that thread is signaled, the reference is + cleared. The number of readers of a block is registered in + block->hash_link->requests. See wait_for_readers() / remove_reader() + for details. This is similar to the above, but it clearly means that + only one thread can wait for a particular block. There is no queue in + this case. Strangely enough block->convar is used for waiting for the + assigned hash_link only. More precisely it is used to wait for all + requests to be unregistered from the assigned hash_link. + + The resize_queue serves two purposes: + 1. Threads that want to do a resize wait there if in_resize is set. + This is not used in the server. The server refuses a second resize + request if one is already active. keycache->in_init is used for the + synchronization. See set_var.cc. + 2. Threads that want to access blocks during resize wait here during + the re-initialization phase. + When the resize is done, all threads on the queue are signalled. + Hypothetical resizers can compete for resizing, and read/write + requests will restart to request blocks from the freshly resized + cache. If the cache has been resized too small, it is disabled and + 'can_be_used' is false. In this case read/write requests bypass the + cache. Since they increment and decrement 'cnt_for_resize_op', the + next resizer can wait on the queue 'waiting_for_resize_cnt' until all + I/O finished. +*/ + #include "mysys_priv.h" +#include "mysys_err.h" #include #include "my_static.h" #include @@ -119,12 +186,16 @@ struct st_hash_link }; /* simple states of a block */ -#define BLOCK_ERROR 1 /* an error occured when performing disk i/o */ -#define BLOCK_READ 2 /* the is page in the block buffer */ -#define BLOCK_IN_SWITCH 4 /* block is preparing to read new page */ -#define BLOCK_REASSIGNED 8 /* block does not accept requests for old page */ -#define BLOCK_IN_FLUSH 16 /* block is in flush operation */ -#define BLOCK_CHANGED 32 /* block buffer contains a dirty page */ +#define BLOCK_ERROR 1 /* an error occured when performing file i/o */ +#define BLOCK_READ 2 /* file block is in the block buffer */ +#define BLOCK_IN_SWITCH 4 /* block is preparing to read new page */ +#define BLOCK_REASSIGNED 8 /* blk does not accept requests for old page */ +#define BLOCK_IN_FLUSH 16 /* block is selected for flush */ +#define BLOCK_CHANGED 32 /* block buffer contains a dirty page */ +#define BLOCK_IN_USE 64 /* block is not free */ +#define BLOCK_IN_EVICTION 128 /* block is selected for eviction */ +#define BLOCK_IN_FLUSHWRITE 256 /* block is in write to file */ +#define BLOCK_FOR_UPDATE 512 /* block is selected for buffer modification */ /* page status, returned by find_key_block */ #define PAGE_READ 0 @@ -161,13 +232,15 @@ KEY_CACHE *dflt_key_cache= &dflt_key_cache_var; static int flush_all_key_blocks(KEY_CACHE *keycache); #ifdef THREAD -static void link_into_queue(KEYCACHE_WQUEUE *wqueue, - struct st_my_thread_var *thread); -static void unlink_from_queue(KEYCACHE_WQUEUE *wqueue, - struct st_my_thread_var *thread); +static void wait_on_queue(KEYCACHE_WQUEUE *wqueue, + pthread_mutex_t *mutex); +static void release_whole_queue(KEYCACHE_WQUEUE *wqueue); +#else +#define wait_on_queue(wqueue, mutex) do {} while (0) +#define release_whole_queue(wqueue) do {} while (0) #endif static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block); -#ifndef DBUG_OFF +#if !defined(DBUG_OFF) static void test_key_cache(KEY_CACHE *keycache, const char *where, my_bool lock); #endif @@ -263,6 +336,16 @@ static int keycache_pthread_cond_signal(pthread_cond_t *cond); #define keycache_pthread_cond_signal pthread_cond_signal #endif /* defined(KEYCACHE_DEBUG) */ +#if !defined(DBUG_OFF) +#if defined(inline) +#undef inline +#endif +#define inline /* disabled inline for easier debugging */ +static int fail_block(BLOCK_LINK *block); +static int fail_hlink(HASH_LINK *hlink); +static int cache_empty(KEY_CACHE *keycache); +#endif + static uint next_power(uint value) { uint old_value= 1; @@ -323,6 +406,14 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, if (! keycache->key_cache_inited) { keycache->key_cache_inited= 1; + /* + Initialize these variables once only. + Their value must survive re-initialization during resizing. + */ + keycache->in_resize= 0; + keycache->resize_in_flush= 0; + keycache->cnt_for_resize_op= 0; + keycache->waiting_for_resize_cnt.last_thread= NULL; keycache->in_init= 0; pthread_mutex_init(&keycache->cache_lock, MY_MUTEX_INIT_FAST); keycache->resize_queue.last_thread= NULL; @@ -336,7 +427,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, blocks= (ulong) (use_mem / (sizeof(BLOCK_LINK) + 2 * sizeof(HASH_LINK) + sizeof(HASH_LINK*) * 5/4 + key_cache_block_size)); /* It doesn't make sense to have too few blocks (less than 8) */ - if (blocks >= 8 && keycache->disk_blocks < 0) + if (blocks >= 8) { for ( ; ; ) { @@ -356,8 +447,8 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, blocks--; /* Allocate memory for cache page buffers */ if ((keycache->block_mem= - my_large_malloc((size_t) blocks * keycache->key_cache_block_size, - MYF(MY_WME)))) + my_large_malloc((size_t) blocks * keycache->key_cache_block_size, + MYF(0)))) { /* Allocate memory for blocks, hash_links and hash entries; @@ -372,6 +463,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, if (blocks < 8) { my_errno= ENOMEM; + my_error(EE_OUTOFMEMORY, MYF(0), blocks * keycache->key_cache_block_size); goto err; } blocks= blocks / 4*3; @@ -410,8 +502,6 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, blocks * age_threshold / 100 : blocks); - keycache->cnt_for_resize_op= 0; - keycache->resize_in_flush= 0; keycache->can_be_used= 1; keycache->waiting_for_hash_link.last_thread= NULL; @@ -427,6 +517,11 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, bzero((gptr) keycache->file_blocks, sizeof(keycache->file_blocks[0]) * CHANGED_BLOCKS_HASH); } + else + { + /* key_buffer_size is specified too small. Disable the cache. */ + keycache->can_be_used= 0; + } keycache->blocks= keycache->disk_blocks > 0 ? keycache->disk_blocks : 0; DBUG_RETURN((int) keycache->disk_blocks); @@ -485,8 +580,6 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, uint age_threshold) { int blocks; - struct st_my_thread_var *thread; - KEYCACHE_WQUEUE *wqueue; DBUG_ENTER("resize_key_cache"); if (!keycache->key_cache_inited) @@ -502,54 +595,86 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, keycache_pthread_mutex_lock(&keycache->cache_lock); #ifdef THREAD - wqueue= &keycache->resize_queue; - thread= my_thread_var; - link_into_queue(wqueue, thread); - - while (wqueue->last_thread->next != thread) + /* + We may need to wait for another thread which is doing a resize + already. This cannot happen in the MySQL server though. It allows + one resizer only. In set_var.cc keycache->in_init is used to block + multiple attempts. + */ + while (keycache->in_resize) { - keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock); + /* purecov: begin inspected */ + wait_on_queue(&keycache->resize_queue, &keycache->cache_lock); + /* purecov: end */ } #endif - keycache->resize_in_flush= 1; - if (flush_all_key_blocks(keycache)) + /* + Mark the operation in progress. This blocks other threads from doing + a resize in parallel. It prohibits new blocks to enter the cache. + Read/write requests can bypass the cache during the flush phase. + */ + keycache->in_resize= 1; + + /* Need to flush only if keycache is enabled. */ + if (keycache->can_be_used) { - /* TODO: if this happens, we should write a warning in the log file ! */ + /* Start the flush phase. */ + keycache->resize_in_flush= 1; + + if (flush_all_key_blocks(keycache)) + { + /* TODO: if this happens, we should write a warning in the log file ! */ + keycache->resize_in_flush= 0; + blocks= 0; + keycache->can_be_used= 0; + goto finish; + } + DBUG_ASSERT(cache_empty(keycache)); + + /* End the flush phase. */ keycache->resize_in_flush= 0; - blocks= 0; - keycache->can_be_used= 0; - goto finish; } - keycache->resize_in_flush= 0; - keycache->can_be_used= 0; + #ifdef THREAD + /* + Some direct read/write operations (bypassing the cache) may still be + unfinished. Wait until they are done. If the key cache can be used, + direct I/O is done in increments of key_cache_block_size. That is, + every block is checked if it is in the cache. We need to wait for + pending I/O before re-initializing the cache, because we may change + the block size. Otherwise they could check for blocks at file + positions where the new block division has none. We do also want to + wait for I/O done when (if) the cache was disabled. It must not + run in parallel with normal cache operation. + */ while (keycache->cnt_for_resize_op) - { - KEYCACHE_DBUG_PRINT("resize_key_cache: wait", - ("suspend thread %ld", thread->id)); - keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock); - } + wait_on_queue(&keycache->waiting_for_resize_cnt, &keycache->cache_lock); #else KEYCACHE_DBUG_ASSERT(keycache->cnt_for_resize_op == 0); #endif + /* + Free old cache structures, allocate new structures, and initialize + them. Note that the cache_lock mutex and the resize_queue are left + untouched. We do not lose the cache_lock and will release it only at + the end of this function. + */ end_key_cache(keycache, 0); /* Don't free mutex */ /* The following will work even if use_mem is 0 */ blocks= init_key_cache(keycache, key_cache_block_size, use_mem, division_limit, age_threshold); finish: -#ifdef THREAD - unlink_from_queue(wqueue, thread); - /* Signal for the next resize request to proceeed if any */ - if (wqueue->last_thread) - { - KEYCACHE_DBUG_PRINT("resize_key_cache: signal", - ("thread %ld", wqueue->last_thread->next->id)); - keycache_pthread_cond_signal(&wqueue->last_thread->next->suspend); - } -#endif + /* + Mark the resize finished. This allows other threads to start a + resize or to request new cache blocks. + */ + keycache->in_resize= 0; + + /* Signal waiting threads. */ + release_whole_queue(&keycache->resize_queue); + keycache_pthread_mutex_unlock(&keycache->cache_lock); DBUG_RETURN(blocks); } @@ -570,18 +695,8 @@ static inline void inc_counter_for_resize_op(KEY_CACHE *keycache) */ static inline void dec_counter_for_resize_op(KEY_CACHE *keycache) { -#ifdef THREAD - struct st_my_thread_var *last_thread; - if (!--keycache->cnt_for_resize_op && - (last_thread= keycache->resize_queue.last_thread)) - { - KEYCACHE_DBUG_PRINT("dec_counter_for_resize_op: signal", - ("thread %ld", last_thread->next->id)); - keycache_pthread_cond_signal(&last_thread->next->suspend); - } -#else - keycache->cnt_for_resize_op--; -#endif + if (!--keycache->cnt_for_resize_op) + release_whole_queue(&keycache->waiting_for_resize_cnt); } /* @@ -661,6 +776,13 @@ void end_key_cache(KEY_CACHE *keycache, my_bool cleanup) (ulong) keycache->global_cache_r_requests, (ulong) keycache->global_cache_read)); + /* + Reset these values to be able to detect a disabled key cache. + See Bug#44068 (RESTORE can disable the MyISAM Key Cache). + */ + keycache->blocks_used= 0; + keycache->blocks_unused= 0; + if (cleanup) { pthread_mutex_destroy(&keycache->cache_lock); @@ -672,6 +794,7 @@ void end_key_cache(KEY_CACHE *keycache, my_bool cleanup) #ifdef THREAD + /* Link a thread into double-linked queue of waiting threads. @@ -693,6 +816,8 @@ static void link_into_queue(KEYCACHE_WQUEUE *wqueue, struct st_my_thread_var *thread) { struct st_my_thread_var *last; + + DBUG_ASSERT(!thread->next && !thread->prev); if (! (last= wqueue->last_thread)) { /* Queue is empty */ @@ -728,6 +853,7 @@ static void unlink_from_queue(KEYCACHE_WQUEUE *wqueue, struct st_my_thread_var *thread) { KEYCACHE_DBUG_PRINT("unlink_from_queue", ("thread %ld", thread->id)); + DBUG_ASSERT(thread->next && thread->prev); if (thread->next == thread) /* The queue contains only one member */ wqueue->last_thread= NULL; @@ -740,6 +866,13 @@ static void unlink_from_queue(KEYCACHE_WQUEUE *wqueue, thread->prev); } thread->next= NULL; +#if !defined(DBUG_OFF) + /* + This makes it easier to see it's not in a chain during debugging. + And some DBUG_ASSERT() rely on it. + */ + thread->prev= NULL; +#endif } @@ -747,9 +880,9 @@ static void unlink_from_queue(KEYCACHE_WQUEUE *wqueue, Add a thread to single-linked queue of waiting threads SYNOPSIS - add_to_queue() - wqueue pointer to the queue structure - thread pointer to the thread to be added to the queue + wait_on_queue() + wqueue Pointer to the queue structure. + mutex Cache_lock to acquire after awake. RETURN VALUE none @@ -758,12 +891,23 @@ static void unlink_from_queue(KEYCACHE_WQUEUE *wqueue, Queue is represented by a circular list of the thread structures The list is single-linked of the type (*next), accessed by a pointer to the last element. + + The function protects against stray signals by verifying that the + current thread is unlinked from the queue when awaking. However, + since several threads can wait for the same event, it might be + necessary for the caller of the function to check again if the + condition for awake is indeed matched. */ -static inline void add_to_queue(KEYCACHE_WQUEUE *wqueue, - struct st_my_thread_var *thread) +static void wait_on_queue(KEYCACHE_WQUEUE *wqueue, + pthread_mutex_t *mutex) { struct st_my_thread_var *last; + struct st_my_thread_var *thread= my_thread_var; + + /* Add to queue. */ + DBUG_ASSERT(!thread->next); + DBUG_ASSERT(!thread->prev); /* Not required, but must be true anyway. */ if (! (last= wqueue->last_thread)) thread->next= thread; else @@ -772,6 +916,17 @@ static inline void add_to_queue(KEYCACHE_WQUEUE *wqueue, last->next= thread; } wqueue->last_thread= thread; + + /* + Wait until thread is removed from queue by the signalling thread. + The loop protects against stray signals. + */ + do + { + KEYCACHE_DBUG_PRINT("wait", ("suspend thread %ld", thread->id)); + keycache_pthread_cond_wait(&thread->suspend, mutex); + } + while (thread->next); } @@ -779,36 +934,47 @@ static inline void add_to_queue(KEYCACHE_WQUEUE *wqueue, Remove all threads from queue signaling them to proceed SYNOPSIS - realease_queue() - wqueue pointer to the queue structure - thread pointer to the thread to be added to the queue + release_whole_queue() + wqueue pointer to the queue structure RETURN VALUE none NOTES. - See notes for add_to_queue + See notes for wait_on_queue(). When removed from the queue each thread is signaled via condition variable thread->suspend. */ -static void release_queue(KEYCACHE_WQUEUE *wqueue) +static void release_whole_queue(KEYCACHE_WQUEUE *wqueue) { - struct st_my_thread_var *last= wqueue->last_thread; - struct st_my_thread_var *next= last->next; + struct st_my_thread_var *last; + struct st_my_thread_var *next; struct st_my_thread_var *thread; + + /* Queue may be empty. */ + if (!(last= wqueue->last_thread)) + return; + + next= last->next; do { thread=next; - KEYCACHE_DBUG_PRINT("release_queue: signal", ("thread %ld", thread->id)); + KEYCACHE_DBUG_PRINT("release_whole_queue: signal", + ("thread %ld", thread->id)); + /* Signal the thread. */ keycache_pthread_cond_signal(&thread->suspend); + /* Take thread from queue. */ next=thread->next; thread->next= NULL; } while (thread != last); + + /* Now queue is definitely empty. */ wqueue->last_thread= NULL; } -#endif + +#endif /* THREAD */ /* @@ -817,9 +983,19 @@ static void release_queue(KEYCACHE_WQUEUE *wqueue) static inline void unlink_changed(BLOCK_LINK *block) { + DBUG_ASSERT(block->prev_changed && *block->prev_changed == block); if (block->next_changed) block->next_changed->prev_changed= block->prev_changed; *block->prev_changed= block->next_changed; + +#if !defined(DBUG_OFF) + /* + This makes it easier to see it's not in a chain during debugging. + And some DBUG_ASSERT() rely on it. + */ + block->next_changed= NULL; + block->prev_changed= NULL; +#endif } @@ -829,6 +1005,8 @@ static inline void unlink_changed(BLOCK_LINK *block) static inline void link_changed(BLOCK_LINK *block, BLOCK_LINK **phead) { + DBUG_ASSERT(!block->next_changed); + DBUG_ASSERT(!block->prev_changed); block->prev_changed= phead; if ((block->next_changed= *phead)) (*phead)->prev_changed= &block->next_changed; @@ -837,14 +1015,37 @@ static inline void link_changed(BLOCK_LINK *block, BLOCK_LINK **phead) /* - Unlink a block from the chain of dirty/clean blocks, if it's asked for, - and link it to the chain of clean blocks for the specified file + Link a block in a chain of clean blocks of a file. + + SYNOPSIS + link_to_file_list() + keycache Key cache handle + block Block to relink + file File to be linked to + unlink If to unlink first + + DESCRIPTION + Unlink a block from whichever chain it is linked in, if it's + asked for, and link it to the chain of clean blocks of the + specified file. + + NOTE + Please do never set/clear BLOCK_CHANGED outside of + link_to_file_list() or link_to_changed_list(). + You would risk to damage correct counting of changed blocks + and to find blocks in the wrong hash. + + RETURN + void */ static void link_to_file_list(KEY_CACHE *keycache, BLOCK_LINK *block, int file, my_bool unlink_block) { + DBUG_ASSERT(block->status & BLOCK_IN_USE); + DBUG_ASSERT(block->hash_link && block->hash_link->block == block); + DBUG_ASSERT(block->hash_link->file == file); if (unlink_block) unlink_changed(block); link_changed(block, &keycache->file_blocks[FILE_HASH(file)]); @@ -858,13 +1059,34 @@ static void link_to_file_list(KEY_CACHE *keycache, /* - Unlink a block from the chain of clean blocks for the specified - file and link it to the chain of dirty blocks for this file + Re-link a block from the clean chain to the dirty chain of a file. + + SYNOPSIS + link_to_changed_list() + keycache key cache handle + block block to relink + + DESCRIPTION + Unlink a block from the chain of clean blocks of a file + and link it to the chain of dirty blocks of the same file. + + NOTE + Please do never set/clear BLOCK_CHANGED outside of + link_to_file_list() or link_to_changed_list(). + You would risk to damage correct counting of changed blocks + and to find blocks in the wrong hash. + + RETURN + void */ -static inline void link_to_changed_list(KEY_CACHE *keycache, - BLOCK_LINK *block) +static void link_to_changed_list(KEY_CACHE *keycache, + BLOCK_LINK *block) { + DBUG_ASSERT(block->status & BLOCK_IN_USE); + DBUG_ASSERT(!(block->status & BLOCK_CHANGED)); + DBUG_ASSERT(block->hash_link && block->hash_link->block == block); + unlink_changed(block); link_changed(block, &keycache->changed_blocks[FILE_HASH(block->hash_link->file)]); @@ -889,13 +1111,13 @@ static inline void link_to_changed_list(KEY_CACHE *keycache, none NOTES. - The LRU chain is represented by a curcular list of block structures. + The LRU ring is represented by a circular list of block structures. The list is double-linked of the type (**prev,*next) type. - The LRU chain is divided into two parts - hot and warm. + The LRU ring is divided into two parts - hot and warm. There are two pointers to access the last blocks of these two parts. The beginning of the warm part follows right after the end of the hot part. - Only blocks of the warm part can be used for replacement. + Only blocks of the warm part can be used for eviction. The first block from the beginning of this subchain is always taken for eviction (keycache->last_used->next) @@ -908,6 +1130,9 @@ static inline void link_to_changed_list(KEY_CACHE *keycache, +----| beg |---->...----| end |----+ +------+ +------+ins first for eviction + + It is also possible that the block is selected for eviction and thus + not linked in the LRU ring. */ static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot, @@ -916,7 +1141,12 @@ static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot, BLOCK_LINK *ins; BLOCK_LINK **pins; - KEYCACHE_DBUG_ASSERT(! (block->hash_link && block->hash_link->requests)); + DBUG_ASSERT((block->status & ~BLOCK_CHANGED) == (BLOCK_READ | BLOCK_IN_USE)); + DBUG_ASSERT(block->hash_link); /*backptr to block NULL from free_block()*/ + DBUG_ASSERT(!block->requests); + DBUG_ASSERT(block->prev_changed && *block->prev_changed == block); + DBUG_ASSERT(!block->next_used); + DBUG_ASSERT(!block->prev_used); #ifdef THREAD if (!hot && keycache->waiting_for_block.last_thread) { @@ -945,6 +1175,29 @@ static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot, } while (thread != last_thread); hash_link->block= block; + /* + NOTE: We assigned the block to the hash_link and signalled the + requesting thread(s). But it is possible that other threads runs + first. These threads see the hash_link assigned to a block which + is assigned to another hash_link and not marked BLOCK_IN_SWITCH. + This can be a problem for functions that do not select the block + via its hash_link: flush and free. They do only see a block which + is in a "normal" state and don't know that it will be evicted soon. + + We cannot set BLOCK_IN_SWITCH here because only one of the + requesting threads must handle the eviction. All others must wait + for it to complete. If we set the flag here, the threads would not + know who is in charge of the eviction. Without the flag, the first + thread takes the stick and sets the flag. + + But we need to note in the block that is has been selected for + eviction. It must not be freed. The evicting thread will not + expect the block in the free list. Before freeing we could also + check if block->requests > 1. But I think including another flag + in the check of block->status is slightly more efficient and + probably easier to read. + */ + block->status|= BLOCK_IN_EVICTION; KEYCACHE_THREAD_TRACE("link_block: after signaling"); #if defined(KEYCACHE_DEBUG) KEYCACHE_DBUG_PRINT("link_block", @@ -971,7 +1224,7 @@ static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot, } else { - /* The LRU chain is empty */ + /* The LRU ring is empty. Let the block point to itself. */ keycache->used_last= keycache->used_ins= block->next_used= block; block->prev_used= &block->next_used; } @@ -1005,6 +1258,13 @@ static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot, static void unlink_block(KEY_CACHE *keycache, BLOCK_LINK *block) { + DBUG_ASSERT((block->status & ~BLOCK_CHANGED) == (BLOCK_READ | BLOCK_IN_USE)); + DBUG_ASSERT(block->hash_link); /*backptr to block NULL from free_block()*/ + DBUG_ASSERT(!block->requests); + DBUG_ASSERT(block->prev_changed && *block->prev_changed == block); + DBUG_ASSERT(block->next_used && block->prev_used && + (block->next_used->prev_used == &block->next_used) && + (*block->prev_used == block)); if (block->next_used == block) /* The list contains only one member */ keycache->used_last= keycache->used_ins= NULL; @@ -1018,26 +1278,48 @@ static void unlink_block(KEY_CACHE *keycache, BLOCK_LINK *block) keycache->used_ins=STRUCT_PTR(BLOCK_LINK, next_used, block->prev_used); } block->next_used= NULL; +#if !defined(DBUG_OFF) + /* + This makes it easier to see it's not in a chain during debugging. + And some DBUG_ASSERT() rely on it. + */ + block->prev_used= NULL; +#endif KEYCACHE_THREAD_TRACE("unlink_block"); #if defined(KEYCACHE_DEBUG) + KEYCACHE_DBUG_ASSERT(keycache->blocks_available != 0); keycache->blocks_available--; KEYCACHE_DBUG_PRINT("unlink_block", ("unlinked block %u status=%x #requests=%u #available=%u", BLOCK_NUMBER(block), block->status, block->requests, keycache->blocks_available)); - KEYCACHE_DBUG_ASSERT(keycache->blocks_available >= 0); #endif } /* - Register requests for a block + Register requests for a block. + + SYNOPSIS + reg_requests() + keycache Pointer to a key cache data structure. + block Pointer to the block to register a request on. + count Number of requests. Always 1. + + NOTE + The first request unlinks the block from the LRU ring. This means + that it is protected against eveiction. + + RETURN + void */ static void reg_requests(KEY_CACHE *keycache, BLOCK_LINK *block, int count) { - if (! block->requests) - /* First request for the block unlinks it */ + DBUG_ASSERT(block->status & BLOCK_IN_USE); + DBUG_ASSERT(block->hash_link); + + if (!block->requests) unlink_block(keycache, block); block->requests+=count; } @@ -1057,7 +1339,7 @@ static void reg_requests(KEY_CACHE *keycache, BLOCK_LINK *block, int count) none NOTES. - Every linking to the LRU chain decrements by one a special block + Every linking to the LRU ring decrements by one a special block counter (if it's positive). If the at_end parameter is TRUE the block is added either at the end of warm sub-chain or at the end of hot sub-chain. It is added to the hot subchain if its counter is zero and number of @@ -1070,12 +1352,25 @@ static void reg_requests(KEY_CACHE *keycache, BLOCK_LINK *block, int count) At the same time the block at the very beginning of the hot subchain might be moved to the beginning of the warm subchain if it stays untouched for a too long time (this time is determined by parameter age_threshold). + + It is also possible that the block is selected for eviction and thus + not linked in the LRU ring. */ static void unreg_request(KEY_CACHE *keycache, BLOCK_LINK *block, int at_end) { - if (! --block->requests) + DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE)); + DBUG_ASSERT(block->hash_link); /*backptr to block NULL from free_block()*/ + DBUG_ASSERT(block->requests); + DBUG_ASSERT(block->prev_changed && *block->prev_changed == block); + DBUG_ASSERT(!block->next_used); + DBUG_ASSERT(!block->prev_used); + /* + Unregister the request, but do not link erroneous blocks into the + LRU ring. + */ + if (!--block->requests && !(block->status & BLOCK_ERROR)) { my_bool hot; if (block->hits_left) @@ -1093,9 +1388,22 @@ static void unreg_request(KEY_CACHE *keycache, link_block(keycache, block, hot, (my_bool)at_end); block->last_hit_time= keycache->keycache_time; keycache->keycache_time++; + /* + At this place, the block might be in the LRU ring or not. If an + evicter was waiting for a block, it was selected for eviction and + not linked in the LRU ring. + */ + /* + Check if we should link a hot block to the warm block sub-chain. + It is possible that we select the same block as above. But it can + also be another block. In any case a block from the LRU ring is + selected. In other words it works even if the above block was + selected for eviction and not linked in the LRU ring. Since this + happens only if the LRU ring is empty, the block selected below + would be NULL and the rest of the function skipped. + */ block= keycache->used_ins; - /* Check if we should link a hot block to the warm block */ if (block && keycache->keycache_time - block->last_hit_time > keycache->age_threshold) { @@ -1116,10 +1424,20 @@ static void unreg_request(KEY_CACHE *keycache, Remove a reader of the page in block */ -static inline void remove_reader(BLOCK_LINK *block) +static void remove_reader(BLOCK_LINK *block) { + DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE)); + DBUG_ASSERT(block->hash_link && block->hash_link->block == block); + DBUG_ASSERT(block->prev_changed && *block->prev_changed == block); + DBUG_ASSERT(!block->next_used); + DBUG_ASSERT(!block->prev_used); + DBUG_ASSERT(block->hash_link->requests); +#ifdef THREAD if (! --block->hash_link->requests && block->condvar) keycache_pthread_cond_signal(block->condvar); +#else + --block->hash_link->requests; +#endif } @@ -1128,15 +1446,27 @@ static inline void remove_reader(BLOCK_LINK *block) signals on its termination */ -static inline void wait_for_readers(KEY_CACHE *keycache, BLOCK_LINK *block) +static void wait_for_readers(KEY_CACHE *keycache, + BLOCK_LINK *block) { #ifdef THREAD struct st_my_thread_var *thread= my_thread_var; + DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE)); + DBUG_ASSERT(!(block->status & (BLOCK_IN_FLUSH | BLOCK_CHANGED))); + DBUG_ASSERT(block->hash_link); + DBUG_ASSERT(block->hash_link->block == block); + /* Linked in file_blocks or changed_blocks hash. */ + DBUG_ASSERT(block->prev_changed && *block->prev_changed == block); + /* Not linked in LRU ring. */ + DBUG_ASSERT(!block->next_used); + DBUG_ASSERT(!block->prev_used); while (block->hash_link->requests) { KEYCACHE_DBUG_PRINT("wait_for_readers: wait", ("suspend thread %ld block %u", thread->id, BLOCK_NUMBER(block))); + /* There must be no other waiter. We have no queue here. */ + DBUG_ASSERT(!block->condvar); block->condvar= &thread->suspend; keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock); block->condvar= NULL; @@ -1225,7 +1555,6 @@ static HASH_LINK *get_hash_link(KEY_CACHE *keycache, int file, my_off_t filepos) { reg1 HASH_LINK *hash_link, **start; - KEYCACHE_PAGE page; #if defined(KEYCACHE_DEBUG) int cnt; #endif @@ -1280,6 +1609,7 @@ restart: #ifdef THREAD /* Wait for a free hash link */ struct st_my_thread_var *thread= my_thread_var; + KEYCACHE_PAGE page; KEYCACHE_DBUG_PRINT("get_hash_link", ("waiting")); page.file= file; page.filepos= filepos; @@ -1365,77 +1695,308 @@ static BLOCK_LINK *find_key_block(KEY_CACHE *keycache, #endif restart: - /* Find the hash link for the requested page (file, filepos) */ + /* + If the flush phase of a resize operation fails, the cache is left + unusable. This will be detected only after "goto restart". + */ + if (!keycache->can_be_used) + DBUG_RETURN(0); + + /* + Find the hash_link for the requested file block (file, filepos). We + do always get a hash_link here. It has registered our request so + that no other thread can use it for another file block until we + release the request (which is done by remove_reader() usually). The + hash_link can have a block assigned to it or not. If there is a + block, it may be assigned to this hash_link or not. In cases where a + block is evicted from the cache, it is taken from the LRU ring and + referenced by the new hash_link. But the block can still be assigned + to its old hash_link for some time if it needs to be flushed first, + or if there are other threads still reading it. + + Summary: + hash_link is always returned. + hash_link->block can be: + - NULL or + - not assigned to this hash_link or + - assigned to this hash_link. If assigned, the block can have + - invalid data (when freshly assigned) or + - valid data. Valid data can be + - changed over the file contents (dirty) or + - not changed (clean). + */ hash_link= get_hash_link(keycache, file, filepos); + DBUG_ASSERT((hash_link->file == file) && (hash_link->diskpos == filepos)); page_status= -1; if ((block= hash_link->block) && block->hash_link == hash_link && (block->status & BLOCK_READ)) - page_status= PAGE_READ; - - if (wrmode && keycache->resize_in_flush) { - /* This is a write request during the flush phase of a resize operation */ + /* Assigned block with valid (changed or unchanged) contents. */ + page_status= PAGE_READ; + } + /* + else (page_status == -1) + - block == NULL or + - block not assigned to this hash_link or + - block assigned but not yet read from file (invalid data). + */ - if (page_status != PAGE_READ) + if (keycache->in_resize) + { + /* This is a request during a resize operation */ + + if (!block) { - /* We don't need the page in the cache: we are going to write on disk */ - hash_link->requests--; - unlink_hash(keycache, hash_link); - DBUG_RETURN(0); - } - if (!(block->status & BLOCK_IN_FLUSH)) - { - hash_link->requests--; + struct st_my_thread_var *thread; + /* - Remove block to invalidate the page in the block buffer - as we are going to write directly on disk. - Although we have an exlusive lock for the updated key part - the control can be yieded by the current thread as we might - have unfinished readers of other key parts in the block - buffer. Still we are guaranteed not to have any readers - of the key part we are writing into until the block is - removed from the cache as we set the BLOCL_REASSIGNED - flag (see the code below that handles reading requests). + The file block is not in the cache. We don't need it in the + cache: we are going to read or write directly to file. Cancel + the request. We can simply decrement hash_link->requests because + we did not release cache_lock since increasing it. So no other + thread can wait for our request to become released. */ - free_block(keycache, block); - DBUG_RETURN(0); - } - /* Wait intil the page is flushed on disk */ - hash_link->requests--; - { -#ifdef THREAD - struct st_my_thread_var *thread= my_thread_var; - add_to_queue(&block->wqueue[COND_FOR_SAVED], thread); + if (hash_link->requests == 1) + { + /* + We are the only one to request this hash_link (this file/pos). + Free the hash_link. + */ + hash_link->requests--; + unlink_hash(keycache, hash_link); + DBUG_RETURN(0); + } + + /* + More requests on the hash_link. Someone tries to evict a block + for this hash_link (could have started before resizing started). + This means that the LRU ring is empty. Otherwise a block could + be assigned immediately. Behave like a thread that wants to + evict a block for this file/pos. Add to the queue of threads + waiting for a block. Wait until there is one assigned. + + Refresh the request on the hash-link so that it cannot be reused + for another file/pos. + */ + thread= my_thread_var; + thread->opt_info= (void *) hash_link; + link_into_queue(&keycache->waiting_for_block, thread); do { KEYCACHE_DBUG_PRINT("find_key_block: wait", ("suspend thread %ld", thread->id)); keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock); - } - while(thread->next); -#else - KEYCACHE_DBUG_ASSERT(0); + } while (thread->next); + thread->opt_info= NULL; /* - Given the use of "resize_in_flush", it seems impossible - that this whole branch is ever entered in single-threaded case - because "(wrmode && keycache->resize_in_flush)" cannot be true. - TODO: Check this, and then put the whole branch into the - "#ifdef THREAD" guard. + A block should now be assigned to the hash_link. But it may + still need to be evicted. Anyway, we should re-check the + situation. page_status must be set correctly. */ -#endif + hash_link->requests--; + goto restart; + } /* end of if (!block) */ + + /* + There is a block for this file/pos in the cache. Register a + request on it. This unlinks it from the LRU ring (if it is there) + and hence protects it against eviction (if not already in + eviction). We need this for returning the block to the caller, for + calling remove_reader() (for debugging purposes), and for calling + free_block(). The only case where we don't need the request is if + the block is in eviction. In that case we have to unregister the + request later. + */ + reg_requests(keycache, block, 1); + + if (page_status != PAGE_READ) + { + /* + - block not assigned to this hash_link or + - block assigned but not yet read from file (invalid data). + + This must be a block in eviction. It will be read soon. We need + to wait here until this happened. Otherwise the caller could + access a wrong block or a block which is in read. While waiting + we cannot lose hash_link nor block. We have registered a request + on the hash_link. Everything can happen to the block but changes + in the hash_link -> block relationship. In other words: + everything can happen to the block but free or another completed + eviction. + + Note that we bahave like a secondary requestor here. We just + cannot return with PAGE_WAIT_TO_BE_READ. This would work for + read requests and writes on dirty blocks that are not in flush + only. Waiting here on COND_FOR_REQUESTED works in all + situations. + */ + DBUG_ASSERT(((block->hash_link != hash_link) && + (block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH))) || + ((block->hash_link == hash_link) && + !(block->status & BLOCK_READ))); + wait_on_queue(&block->wqueue[COND_FOR_REQUESTED], &keycache->cache_lock); + /* + Here we can trust that the block has been assigned to this + hash_link (block->hash_link == hash_link) and read into the + buffer (BLOCK_READ). The worst things possible here are that the + block is in free (BLOCK_REASSIGNED). But the block is still + assigned to the hash_link. The freeing thread waits until we + release our request on the hash_link. The block must not be + again in eviction because we registered an request on it before + starting to wait. + */ + DBUG_ASSERT(block->hash_link == hash_link); + DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE)); + DBUG_ASSERT(!(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH))); } - /* Invalidate page in the block if it has not been done yet */ - if (block->status) + /* + The block is in the cache. Assigned to the hash_link. Valid data. + Note that in case of page_st == PAGE_READ, the block can be marked + for eviction. In any case it can be marked for freeing. + */ + + if (!wrmode) + { + /* A reader can just read the block. */ + *page_st= PAGE_READ; + DBUG_ASSERT((hash_link->file == file) && + (hash_link->diskpos == filepos) && + (block->hash_link == hash_link)); + DBUG_RETURN(block); + } + + /* + This is a writer. No two writers for the same block can exist. + This must be assured by locks outside of the key cache. + */ + DBUG_ASSERT(!(block->status & BLOCK_FOR_UPDATE) || fail_block(block)); + + while (block->status & BLOCK_IN_FLUSH) + { + /* + Wait until the block is flushed to file. Do not release the + request on the hash_link yet to prevent that the block is freed + or reassigned while we wait. While we wait, several things can + happen to the block, including another flush. But the block + cannot be reassigned to another hash_link until we release our + request on it. But it can be marked BLOCK_REASSIGNED from free + or eviction, while they wait for us to release the hash_link. + */ + wait_on_queue(&block->wqueue[COND_FOR_SAVED], &keycache->cache_lock); + /* + If the flush phase failed, the resize could have finished while + we waited here. + */ + if (!keycache->in_resize) + { + remove_reader(block); + unreg_request(keycache, block, 1); + goto restart; + } + DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE)); + DBUG_ASSERT(!(block->status & BLOCK_FOR_UPDATE) || fail_block(block)); + DBUG_ASSERT(block->hash_link == hash_link); + } + + if (block->status & BLOCK_CHANGED) + { + /* + We want to write a block with changed contents. If the cache + block size is bigger than the callers block size (e.g. MyISAM), + the caller may replace part of the block only. Changes of the + other part of the block must be preserved. Since the block has + not yet been selected for flush, we can still add our changes. + */ + *page_st= PAGE_READ; + DBUG_ASSERT((hash_link->file == file) && + (hash_link->diskpos == filepos) && + (block->hash_link == hash_link)); + DBUG_RETURN(block); + } + + /* + This is a write request for a clean block. We do not want to have + new dirty blocks in the cache while resizing. We will free the + block and write directly to file. If the block is in eviction or + in free, we just let it go. + + Unregister from the hash_link. This must be done before freeing + the block. And it must be done if not freeing the block. Because + we could have waited above, we need to call remove_reader(). Other + threads could wait for us to release our request on the hash_link. + */ + remove_reader(block); + + /* If the block is not in eviction and not in free, we can free it. */ + if (!(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH | + BLOCK_REASSIGNED))) + { + /* + Free block as we are going to write directly to file. + Although we have an exlusive lock for the updated key part, + the control can be yielded by the current thread as we might + have unfinished readers of other key parts in the block + buffer. Still we are guaranteed not to have any readers + of the key part we are writing into until the block is + removed from the cache as we set the BLOCK_REASSIGNED + flag (see the code below that handles reading requests). + */ free_block(keycache, block); + } + else + { + /* + The block will be evicted/freed soon. Don't touch it in any way. + Unregister the request that we registered above. + */ + unreg_request(keycache, block, 1); + + /* + The block is still assigned to the hash_link (the file/pos that + we are going to write to). Wait until the eviction/free is + complete. Otherwise the direct write could complete before all + readers are done with the block. So they could read outdated + data. + + Since we released our request on the hash_link, it can be reused + for another file/pos. Hence we cannot just check for + block->hash_link == hash_link. As long as the resize is + proceeding the block cannot be reassigned to the same file/pos + again. So we can terminate the loop when the block is no longer + assigned to this file/pos. + */ + do + { + wait_on_queue(&block->wqueue[COND_FOR_SAVED], + &keycache->cache_lock); + /* + If the flush phase failed, the resize could have finished + while we waited here. + */ + if (!keycache->in_resize) + goto restart; + } while (block->hash_link && + (block->hash_link->file == file) && + (block->hash_link->diskpos == filepos)); + } DBUG_RETURN(0); } if (page_status == PAGE_READ && - (block->status & (BLOCK_IN_SWITCH | BLOCK_REASSIGNED))) + (block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH | + BLOCK_REASSIGNED))) { - /* This is a request for a page to be removed from cache */ + /* + This is a request for a block to be removed from cache. The block + is assigned to this hash_link and contains valid data, but is + marked for eviction or to be freed. Possible reasons why it has + not yet been evicted/freed can be a flush before reassignment + (BLOCK_IN_SWITCH), readers of the block have not finished yet + (BLOCK_REASSIGNED), or the evicting thread did not yet awake after + the block has been selected for it (BLOCK_IN_EVICTION). + */ KEYCACHE_DBUG_PRINT("find_key_block", ("request for old page in block %u " @@ -1446,43 +2007,58 @@ restart: all others are to be suspended, then resubmitted */ if (!wrmode && !(block->status & BLOCK_REASSIGNED)) + { + /* + This is a read request and the block not yet reassigned. We can + register our request and proceed. This unlinks the block from + the LRU ring and protects it against eviction. + */ reg_requests(keycache, block, 1); + } else { + /* + Either this is a write request for a block that is in eviction + or in free. We must not use it any more. Instead we must evict + another block. But we cannot do this before the eviction/free is + done. Otherwise we would find the same hash_link + block again + and again. + + Or this is a read request for a block in eviction/free that does + not require a flush, but waits for readers to finish with the + block. We do not read this block to let the eviction/free happen + as soon as possible. Again we must wait so that we don't find + the same hash_link + block again and again. + */ + DBUG_ASSERT(hash_link->requests); hash_link->requests--; KEYCACHE_DBUG_PRINT("find_key_block", ("request waiting for old page to be saved")); - { -#ifdef THREAD - struct st_my_thread_var *thread= my_thread_var; - /* Put the request into the queue of those waiting for the old page */ - add_to_queue(&block->wqueue[COND_FOR_SAVED], thread); - /* Wait until the request can be resubmitted */ - do - { - KEYCACHE_DBUG_PRINT("find_key_block: wait", - ("suspend thread %ld", thread->id)); - keycache_pthread_cond_wait(&thread->suspend, - &keycache->cache_lock); - } - while(thread->next); -#else - KEYCACHE_DBUG_ASSERT(0); - /* No parallel requests in single-threaded case */ -#endif - } + wait_on_queue(&block->wqueue[COND_FOR_SAVED], &keycache->cache_lock); KEYCACHE_DBUG_PRINT("find_key_block", ("request for old page resubmitted")); - /* Resubmit the request */ + /* + The block is no longer assigned to this hash_link. + Get another one. + */ goto restart; } } else { - /* This is a request for a new page or for a page not to be removed */ + /* + This is a request for a new block or for a block not to be removed. + Either + - block == NULL or + - block not assigned to this hash_link or + - block assigned but not yet read from file, + or + - block assigned with valid (changed or unchanged) data and + - it will not be reassigned/freed. + */ if (! block) { - /* No block is assigned for the page yet */ + /* No block is assigned to the hash_link yet. */ if (keycache->blocks_unused) { if (keycache->free_block_list) @@ -1494,25 +2070,36 @@ restart: } else { + size_t block_mem_offset; /* There are some never used blocks, take first of them */ + DBUG_ASSERT(keycache->blocks_used < + (ulong) keycache->disk_blocks); block= &keycache->block_root[keycache->blocks_used]; + block_mem_offset= + ((size_t) keycache->blocks_used) * keycache->key_cache_block_size; block->buffer= ADD_TO_PTR(keycache->block_mem, - ((ulong) keycache->blocks_used* - keycache->key_cache_block_size), + block_mem_offset, byte*); keycache->blocks_used++; + DBUG_ASSERT(!block->next_used); } + DBUG_ASSERT(!block->prev_used); + DBUG_ASSERT(!block->next_changed); + DBUG_ASSERT(!block->prev_changed); + DBUG_ASSERT(!block->hash_link); + DBUG_ASSERT(!block->status); + DBUG_ASSERT(!block->requests); keycache->blocks_unused--; - block->status= 0; + block->status= BLOCK_IN_USE; block->length= 0; block->offset= keycache->key_cache_block_size; block->requests= 1; block->temperature= BLOCK_COLD; block->hits_left= init_hits_left; block->last_hit_time= 0; - link_to_file_list(keycache, block, file, 0); block->hash_link= hash_link; hash_link->block= block; + link_to_file_list(keycache, block, file, 0); page_status= PAGE_TO_BE_READ; KEYCACHE_DBUG_PRINT("find_key_block", ("got free or never used block %u", @@ -1520,17 +2107,26 @@ restart: } else { - /* There are no never used blocks, use a block from the LRU chain */ - - /* - Wait until a new block is added to the LRU chain; - several threads might wait here for the same page, - all of them must get the same block + /* + There are no free blocks and no never used blocks, use a block + from the LRU ring. */ #ifdef THREAD if (! keycache->used_last) { + /* + The LRU ring is empty. Wait until a new block is added to + it. Several threads might wait here for the same hash_link, + all of them must get the same block. While waiting for a + block, after a block is selected for this hash_link, other + threads can run first before this one awakes. During this + time interval other threads find this hash_link pointing to + the block, which is still assigned to another hash_link. In + this case the block is not marked BLOCK_IN_SWITCH yet, but + it is marked BLOCK_IN_EVICTION. + */ + struct st_my_thread_var *thread= my_thread_var; thread->opt_info= (void *) hash_link; link_into_queue(&keycache->waiting_for_block, thread); @@ -1543,24 +2139,50 @@ restart: } while (thread->next); thread->opt_info= NULL; + /* Assert that block has a request registered. */ + DBUG_ASSERT(hash_link->block->requests); + /* Assert that block is not in LRU ring. */ + DBUG_ASSERT(!hash_link->block->next_used); + DBUG_ASSERT(!hash_link->block->prev_used); } #else KEYCACHE_DBUG_ASSERT(keycache->used_last); #endif + /* + If we waited above, hash_link->block has been assigned by + link_block(). Otherwise it is still NULL. In the latter case + we need to grab a block from the LRU ring ourselves. + */ block= hash_link->block; if (! block) { - /* - Take the first block from the LRU chain - unlinking it from the chain - */ + /* Select the last block from the LRU ring. */ block= keycache->used_last->next_used; block->hits_left= init_hits_left; block->last_hit_time= 0; - reg_requests(keycache, block,1); hash_link->block= block; + /* + Register a request on the block. This unlinks it from the + LRU ring and protects it against eviction. + */ + DBUG_ASSERT(!block->requests); + reg_requests(keycache, block,1); + /* + We do not need to set block->status|= BLOCK_IN_EVICTION here + because we will set block->status|= BLOCK_IN_SWITCH + immediately without releasing the lock in between. This does + also support debugging. When looking at the block, one can + see if the block has been selected by link_block() after the + LRU ring was empty, or if it was grabbed directly from the + LRU ring in this branch. + */ } + /* + If we had to wait above, there is a small chance that another + thread grabbed this block for the same file block already. But + in most cases the first condition is true. + */ if (block->hash_link != hash_link && ! (block->status & BLOCK_IN_SWITCH) ) { @@ -1575,44 +2197,117 @@ restart: /* The block contains a dirty page - push it out of the cache */ KEYCACHE_DBUG_PRINT("find_key_block", ("block is dirty")); + if (block->status & BLOCK_IN_FLUSH) + { + /* + The block is marked for flush. If we do not wait here, + it could happen that we write the block, reassign it to + another file block, then, before the new owner can read + the new file block, the flusher writes the cache block + (which still has the old contents) to the new file block! + */ + wait_on_queue(&block->wqueue[COND_FOR_SAVED], + &keycache->cache_lock); + /* + The block is marked BLOCK_IN_SWITCH. It should be left + alone except for reading. No free, no write. + */ + DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE)); + DBUG_ASSERT(!(block->status & (BLOCK_REASSIGNED | + BLOCK_CHANGED | + BLOCK_FOR_UPDATE))); + } + else + { + block->status|= BLOCK_IN_FLUSH | BLOCK_IN_FLUSHWRITE; + /* + BLOCK_IN_EVICTION may be true or not. Other flags must + have a fixed value. + */ + DBUG_ASSERT((block->status & ~BLOCK_IN_EVICTION) == + (BLOCK_READ | BLOCK_IN_SWITCH | + BLOCK_IN_FLUSH | BLOCK_IN_FLUSHWRITE | + BLOCK_CHANGED | BLOCK_IN_USE)); + DBUG_ASSERT(block->hash_link); - keycache_pthread_mutex_unlock(&keycache->cache_lock); - /* - The call is thread safe because only the current - thread might change the block->hash_link value - */ - error= my_pwrite(block->hash_link->file, - block->buffer+block->offset, - block->length - block->offset, - block->hash_link->diskpos+ block->offset, - MYF(MY_NABP | MY_WAIT_IF_FULL)); - keycache_pthread_mutex_lock(&keycache->cache_lock); - keycache->global_cache_write++; + keycache_pthread_mutex_unlock(&keycache->cache_lock); + /* + The call is thread safe because only the current + thread might change the block->hash_link value + */ + error= my_pwrite(block->hash_link->file, + block->buffer + block->offset, + block->length - block->offset, + block->hash_link->diskpos + block->offset, + MYF(MY_NABP | MY_WAIT_IF_FULL)); + keycache_pthread_mutex_lock(&keycache->cache_lock); + + /* Block status must not have changed. */ + DBUG_ASSERT((block->status & ~BLOCK_IN_EVICTION) == + (BLOCK_READ | BLOCK_IN_SWITCH | + BLOCK_IN_FLUSH | BLOCK_IN_FLUSHWRITE | + BLOCK_CHANGED | BLOCK_IN_USE) || fail_block(block)); + keycache->global_cache_write++; + } } block->status|= BLOCK_REASSIGNED; + /* + The block comes from the LRU ring. It must have a hash_link + assigned. + */ + DBUG_ASSERT(block->hash_link); if (block->hash_link) { /* + All pending requests for this page must be resubmitted. + This must be done before waiting for readers. They could + wait for the flush to complete. And we must also do it + after the wait. Flushers might try to free the block while + we wait. They would wait until the reassignment is + complete. Also the block status must reflect the correct + situation: The block is not changed nor in flush any more. + Note that we must not change the BLOCK_CHANGED flag + outside of link_to_file_list() so that it is always in the + correct queue and the *blocks_changed counters are + correct. + */ + block->status&= ~(BLOCK_IN_FLUSH | BLOCK_IN_FLUSHWRITE); + link_to_file_list(keycache, block, block->hash_link->file, 1); + release_whole_queue(&block->wqueue[COND_FOR_SAVED]); + /* + The block is still assigned to its old hash_link. Wait until all pending read requests for this page are executed (we could have avoided this waiting, if we had read a page in the cache in a sweep, without yielding control) */ wait_for_readers(keycache, block); + DBUG_ASSERT(block->hash_link && block->hash_link->block == block && + block->prev_changed); + /* The reader must not have been a writer. */ + DBUG_ASSERT(!(block->status & BLOCK_CHANGED)); - /* Remove the hash link for this page from the hash table */ + /* Wake flushers that might have found the block in between. */ + release_whole_queue(&block->wqueue[COND_FOR_SAVED]); + + /* Remove the hash link for the old file block from the hash. */ unlink_hash(keycache, block->hash_link); - /* All pending requests for this page must be resubmitted */ - if (block->wqueue[COND_FOR_SAVED].last_thread) - release_queue(&block->wqueue[COND_FOR_SAVED]); + + /* + For sanity checks link_to_file_list() asserts that block + and hash_link refer to each other. Hence we need to assign + the hash_link first, but then we would not know if it was + linked before. Hence we would not know if to unlink it. So + unlink it here and call link_to_file_list(..., FALSE). + */ + unlink_changed(block); } - link_to_file_list(keycache, block, file, - (my_bool)(block->hash_link ? 1 : 0)); - block->status= error? BLOCK_ERROR : 0; + block->status= error ? BLOCK_ERROR : BLOCK_IN_USE ; block->length= 0; block->offset= keycache->key_cache_block_size; block->hash_link= hash_link; + link_to_file_list(keycache, block, file, 0); page_status= PAGE_TO_BE_READ; KEYCACHE_DBUG_ASSERT(block->hash_link->block == block); @@ -1620,7 +2315,20 @@ restart: } else { - /* This is for secondary requests for a new page only */ + /* + Either (block->hash_link == hash_link), + or (block->status & BLOCK_IN_SWITCH). + + This is for secondary requests for a new file block only. + Either it is already assigned to the new hash_link meanwhile + (if we had to wait due to empty LRU), or it is already in + eviction by another thread. Since this block has been + grabbed from the LRU ring and attached to this hash_link, + another thread cannot grab the same block from the LRU ring + anymore. If the block is in eviction already, it must become + attached to the same hash_link and as such destined for the + same file block. + */ KEYCACHE_DBUG_PRINT("find_key_block", ("block->hash_link: %p hash_link: %p " "block->status: %u", block->hash_link, @@ -1630,10 +2338,35 @@ restart: PAGE_READ : PAGE_WAIT_TO_BE_READ); } } - keycache->global_cache_read++; } else { + /* + Block is not NULL. This hash_link points to a block. + Either + - block not assigned to this hash_link (yet) or + - block assigned but not yet read from file, + or + - block assigned with valid (changed or unchanged) data and + - it will not be reassigned/freed. + + The first condition means hash_link points to a block in + eviction. This is not necessarily marked by BLOCK_IN_SWITCH yet. + But then it is marked BLOCK_IN_EVICTION. See the NOTE in + link_block(). In both cases it is destined for this hash_link + and its file block address. When this hash_link got its block + address, the block was removed from the LRU ring and cannot be + selected for eviction (for another hash_link) again. + + Register a request on the block. This is another protection + against eviction. + */ + DBUG_ASSERT(((block->hash_link != hash_link) && + (block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH))) || + ((block->hash_link == hash_link) && + !(block->status & BLOCK_READ)) || + ((block->status & BLOCK_READ) && + !(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH)))); reg_requests(keycache, block, 1); KEYCACHE_DBUG_PRINT("find_key_block", ("block->hash_link: %p hash_link: %p " @@ -1646,11 +2379,21 @@ restart: } KEYCACHE_DBUG_ASSERT(page_status != -1); + /* Same assert basically, but be very sure. */ + KEYCACHE_DBUG_ASSERT(block); + /* Assert that block has a request and is not in LRU ring. */ + DBUG_ASSERT(block->requests); + DBUG_ASSERT(!block->next_used); + DBUG_ASSERT(!block->prev_used); + /* Assert that we return the correct block. */ + DBUG_ASSERT((page_status == PAGE_WAIT_TO_BE_READ) || + ((block->hash_link->file == file) && + (block->hash_link->diskpos == filepos))); *page_st=page_status; KEYCACHE_DBUG_PRINT("find_key_block", - ("fd: %d pos: %lu block->status: %u page_status: %u", + ("fd: %d pos: %lu block->status: %u page_status: %d", file, (ulong) filepos, block->status, - (uint) page_status)); + page_status)); #if !defined(DBUG_OFF) && defined(EXTRA_DEBUG) DBUG_EXECUTE("check_keycache2", @@ -1697,13 +2440,22 @@ static void read_block(KEY_CACHE *keycache, if (primary) { /* - This code is executed only by threads - that submitted primary requests + This code is executed only by threads that submitted primary + requests. Until block->status contains BLOCK_READ, all other + request for the block become secondary requests. For a primary + request the block must be properly initialized. */ + DBUG_ASSERT(((block->status & ~BLOCK_FOR_UPDATE) == BLOCK_IN_USE) || + fail_block(block)); + DBUG_ASSERT((block->length == 0) || fail_block(block)); + DBUG_ASSERT((block->offset == keycache->key_cache_block_size) || + fail_block(block)); + DBUG_ASSERT((block->requests > 0) || fail_block(block)); KEYCACHE_DBUG_PRINT("read_block", ("page to be read by primary request")); + keycache->global_cache_read++; /* Page is not in buffer yet, is to be read from disk */ keycache_pthread_mutex_unlock(&keycache->cache_lock); /* @@ -1713,45 +2465,50 @@ static void read_block(KEY_CACHE *keycache, got_length= my_pread(block->hash_link->file, block->buffer, read_length, block->hash_link->diskpos, MYF(0)); keycache_pthread_mutex_lock(&keycache->cache_lock); + /* + The block can now have been marked for free (in case of + FLUSH_RELEASE). Otherwise the state must be unchanged. + */ + DBUG_ASSERT(((block->status & ~(BLOCK_REASSIGNED | + BLOCK_FOR_UPDATE)) == BLOCK_IN_USE) || + fail_block(block)); + DBUG_ASSERT((block->length == 0) || fail_block(block)); + DBUG_ASSERT((block->offset == keycache->key_cache_block_size) || + fail_block(block)); + DBUG_ASSERT((block->requests > 0) || fail_block(block)); + if (got_length < min_length) block->status|= BLOCK_ERROR; else { - block->status= BLOCK_READ; + block->status|= BLOCK_READ; block->length= got_length; + /* + Do not set block->offset here. If this block is marked + BLOCK_CHANGED later, we want to flush only the modified part. So + only a writer may set block->offset down from + keycache->key_cache_block_size. + */ } KEYCACHE_DBUG_PRINT("read_block", ("primary request: new page in cache")); /* Signal that all pending requests for this page now can be processed */ - if (block->wqueue[COND_FOR_REQUESTED].last_thread) - release_queue(&block->wqueue[COND_FOR_REQUESTED]); + release_whole_queue(&block->wqueue[COND_FOR_REQUESTED]); } else { /* - This code is executed only by threads - that submitted secondary requests + This code is executed only by threads that submitted secondary + requests. At this point it could happen that the cache block is + not yet assigned to the hash_link for the requested file block. + But at awake from the wait this should be the case. Unfortunately + we cannot assert this here because we do not know the hash_link + for the requested file block nor the file and position. So we have + to assert this in the caller. */ KEYCACHE_DBUG_PRINT("read_block", ("secondary request waiting for new page to be read")); - { -#ifdef THREAD - struct st_my_thread_var *thread= my_thread_var; - /* Put the request into a queue and wait until it can be processed */ - add_to_queue(&block->wqueue[COND_FOR_REQUESTED], thread); - do - { - KEYCACHE_DBUG_PRINT("read_block: wait", - ("suspend thread %ld", thread->id)); - keycache_pthread_cond_wait(&thread->suspend, - &keycache->cache_lock); - } - while (thread->next); -#else - KEYCACHE_DBUG_ASSERT(0); - /* No parallel requests in single-threaded case */ -#endif - } + wait_on_queue(&block->wqueue[COND_FOR_REQUESTED], &keycache->cache_lock); KEYCACHE_DBUG_PRINT("read_block", ("secondary request: new page in cache")); } @@ -1792,32 +2549,61 @@ byte *key_cache_read(KEY_CACHE *keycache, uint block_length __attribute__((unused)), int return_buffer __attribute__((unused))) { + my_bool locked_and_incremented= FALSE; int error=0; - uint offset= 0; byte *start= buff; DBUG_ENTER("key_cache_read"); DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u", (uint) file, (ulong) filepos, length)); - if (keycache->can_be_used) + if (keycache->key_cache_inited) { /* Key cache is used */ reg1 BLOCK_LINK *block; uint read_length; - uint status; + uint offset; int page_st; + /* + When the key cache is once initialized, we use the cache_lock to + reliably distinguish the cases of normal operation, resizing, and + disabled cache. We always increment and decrement + 'cnt_for_resize_op' so that a resizer can wait for pending I/O. + */ + keycache_pthread_mutex_lock(&keycache->cache_lock); + /* + Cache resizing has two phases: Flushing and re-initializing. In + the flush phase read requests are allowed to bypass the cache for + blocks not in the cache. find_key_block() returns NULL in this + case. + + After the flush phase new I/O requests must wait until the + re-initialization is done. The re-initialization can be done only + if no I/O request is in progress. The reason is that + key_cache_block_size can change. With enabled cache, I/O is done + in chunks of key_cache_block_size. Every chunk tries to use a + cache block first. If the block size changes in the middle, a + block could be missed and old data could be read. + */ + while (keycache->in_resize && !keycache->resize_in_flush) + wait_on_queue(&keycache->resize_queue, &keycache->cache_lock); + /* Register the I/O for the next resize. */ + inc_counter_for_resize_op(keycache); + locked_and_incremented= TRUE; + /* Requested data may not always be aligned to cache blocks. */ offset= (uint) (filepos % keycache->key_cache_block_size); /* Read data in key_cache_block_size increments */ do { - keycache_pthread_mutex_lock(&keycache->cache_lock); + /* Cache could be disabled in a later iteration. */ if (!keycache->can_be_used) { - keycache_pthread_mutex_unlock(&keycache->cache_lock); - goto no_key_cache; + KEYCACHE_DBUG_PRINT("key_cache_read", ("keycache cannot be used")); + goto no_key_cache; } + /* Start reading at the beginning of the cache block. */ filepos-= offset; + /* Do not read beyond the end of the cache block. */ read_length= length; set_if_smaller(read_length, keycache->key_cache_block_size-offset); KEYCACHE_DBUG_ASSERT(read_length > 0); @@ -1827,34 +2613,61 @@ byte *key_cache_read(KEY_CACHE *keycache, return_buffer=0; #endif - inc_counter_for_resize_op(keycache); + /* Request the cache block that matches file/pos. */ keycache->global_cache_r_requests++; block=find_key_block(keycache, file, filepos, level, 0, &page_st); - if (block->status != BLOCK_ERROR && page_st != PAGE_READ) - { - /* The requested page is to be read into the block buffer */ - read_block(keycache, block, - keycache->key_cache_block_size, read_length+offset, - (my_bool)(page_st == PAGE_TO_BE_READ)); - } - else if (! (block->status & BLOCK_ERROR) && - block->length < read_length + offset) + if (!block) { /* - Impossible if nothing goes wrong: - this could only happen if we are using a file with - small key blocks and are trying to read outside the file + This happens only for requests submitted during key cache + resize. The block is not in the cache and shall not go in. + Read directly from file. */ - my_errno= -1; - block->status|= BLOCK_ERROR; + keycache->global_cache_read++; + keycache_pthread_mutex_unlock(&keycache->cache_lock); + error= (my_pread(file, (byte*) buff, read_length, + filepos + offset, MYF(MY_NABP)) != 0); + keycache_pthread_mutex_lock(&keycache->cache_lock); + goto next_block; + } + if (!(block->status & BLOCK_ERROR)) + { + if (page_st != PAGE_READ) + { + /* The requested page is to be read into the block buffer */ + read_block(keycache, block, + keycache->key_cache_block_size, read_length+offset, + (my_bool)(page_st == PAGE_TO_BE_READ)); + /* + A secondary request must now have the block assigned to the + requested file block. It does not hurt to check it for + primary requests too. + */ + DBUG_ASSERT(keycache->can_be_used); + DBUG_ASSERT(block->hash_link->file == file); + DBUG_ASSERT(block->hash_link->diskpos == filepos); + DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE)); + } + else if (block->length < read_length + offset) + { + /* + Impossible if nothing goes wrong: + this could only happen if we are using a file with + small key blocks and are trying to read outside the file + */ + my_errno= -1; + block->status|= BLOCK_ERROR; + } } - if (! ((status= block->status) & BLOCK_ERROR)) + /* block status may have added BLOCK_ERROR in the above 'if'. */ + if (!(block->status & BLOCK_ERROR)) { #ifndef THREAD if (! return_buffer) #endif { + DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE)); #if !defined(SERIALIZED_READ_FROM_CACHE) keycache_pthread_mutex_unlock(&keycache->cache_lock); #endif @@ -1867,44 +2680,68 @@ byte *key_cache_read(KEY_CACHE *keycache, #if !defined(SERIALIZED_READ_FROM_CACHE) keycache_pthread_mutex_lock(&keycache->cache_lock); + DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE)); #endif } } remove_reader(block); - /* - Link the block into the LRU chain - if it's the last submitted request for the block - */ - unreg_request(keycache, block, 1); - dec_counter_for_resize_op(keycache); + /* Error injection for coverage testing. */ + DBUG_EXECUTE_IF("key_cache_read_block_error", + block->status|= BLOCK_ERROR;); - keycache_pthread_mutex_unlock(&keycache->cache_lock); - - if (status & BLOCK_ERROR) - DBUG_RETURN((byte *) 0); + /* Do not link erroneous blocks into the LRU ring, but free them. */ + if (!(block->status & BLOCK_ERROR)) + { + /* + Link the block into the LRU ring if it's the last submitted + request for the block. This enables eviction for the block. + */ + unreg_request(keycache, block, 1); + } + else + { + free_block(keycache, block); + error= 1; + break; + } #ifndef THREAD /* This is only true if we where able to read everything in one block */ if (return_buffer) DBUG_RETURN(block->buffer); #endif + next_block: buff+= read_length; filepos+= read_length+offset; offset= 0; } while ((length-= read_length)); - DBUG_RETURN(start); + goto end; } + KEYCACHE_DBUG_PRINT("key_cache_read", ("keycache not initialized")); -no_key_cache: /* Key cache is not used */ +no_key_cache: + /* Key cache is not used */ - /* We can't use mutex here as the key cache may not be initialized */ keycache->global_cache_r_requests++; keycache->global_cache_read++; - if (my_pread(file, (byte*) buff, length, filepos+offset, MYF(MY_NABP))) + + if (locked_and_incremented) + keycache_pthread_mutex_unlock(&keycache->cache_lock); + if (my_pread(file, (byte*) buff, length, filepos, MYF(MY_NABP))) error= 1; + if (locked_and_incremented) + keycache_pthread_mutex_lock(&keycache->cache_lock); + +end: + if (locked_and_incremented) + { + dec_counter_for_resize_op(keycache); + keycache_pthread_mutex_unlock(&keycache->cache_lock); + } + DBUG_PRINT("exit", ("error: %d", error )); DBUG_RETURN(error ? (byte*) 0 : start); } @@ -1933,90 +2770,220 @@ int key_cache_insert(KEY_CACHE *keycache, File file, my_off_t filepos, int level, byte *buff, uint length) { + int error= 0; DBUG_ENTER("key_cache_insert"); DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u", (uint) file,(ulong) filepos, length)); - if (keycache->can_be_used) + if (keycache->key_cache_inited) { /* Key cache is used */ reg1 BLOCK_LINK *block; uint read_length; - int page_st; - int error; uint offset; + int page_st; + my_bool locked_and_incremented= FALSE; + /* + When the keycache is once initialized, we use the cache_lock to + reliably distinguish the cases of normal operation, resizing, and + disabled cache. We always increment and decrement + 'cnt_for_resize_op' so that a resizer can wait for pending I/O. + */ + keycache_pthread_mutex_lock(&keycache->cache_lock); + /* + We do not load index data into a disabled cache nor into an + ongoing resize. + */ + if (!keycache->can_be_used || keycache->in_resize) + goto no_key_cache; + /* Register the pseudo I/O for the next resize. */ + inc_counter_for_resize_op(keycache); + locked_and_incremented= TRUE; + /* Loaded data may not always be aligned to cache blocks. */ offset= (uint) (filepos % keycache->key_cache_block_size); + /* Load data in key_cache_block_size increments. */ do { - keycache_pthread_mutex_lock(&keycache->cache_lock); - if (!keycache->can_be_used) - { - keycache_pthread_mutex_unlock(&keycache->cache_lock); - DBUG_RETURN(0); - } - /* Read data into key cache from buff in key_cache_block_size incr. */ + /* Cache could be disabled or resizing in a later iteration. */ + if (!keycache->can_be_used || keycache->in_resize) + goto no_key_cache; + /* Start loading at the beginning of the cache block. */ filepos-= offset; + /* Do not load beyond the end of the cache block. */ read_length= length; set_if_smaller(read_length, keycache->key_cache_block_size-offset); KEYCACHE_DBUG_ASSERT(read_length > 0); - inc_counter_for_resize_op(keycache); + /* The block has been read by the caller already. */ + keycache->global_cache_read++; + /* Request the cache block that matches file/pos. */ keycache->global_cache_r_requests++; block= find_key_block(keycache, file, filepos, level, 0, &page_st); - if (block->status != BLOCK_ERROR && page_st != PAGE_READ) + if (!block) { - /* The requested page is to be read into the block buffer */ -#if !defined(SERIALIZED_READ_FROM_CACHE) - keycache_pthread_mutex_unlock(&keycache->cache_lock); /* - Here other threads may step in and register as secondary readers. - They will register in block->wqueue[COND_FOR_REQUESTED]. + This happens only for requests submitted during key cache + resize. The block is not in the cache and shall not go in. + Stop loading index data. */ -#endif + goto no_key_cache; + } + if (!(block->status & BLOCK_ERROR)) + { + if ((page_st == PAGE_WAIT_TO_BE_READ) || + ((page_st == PAGE_TO_BE_READ) && + (offset || (read_length < keycache->key_cache_block_size)))) + { + /* + Either - /* Copy data from buff */ - if (!(read_length & 511)) - bmove512(block->buffer+offset, buff, read_length); - else - memcpy(block->buffer+offset, buff, (size_t) read_length); + this is a secondary request for a block to be read into the + cache. The block is in eviction. It is not yet assigned to + the requested file block (It does not point to the right + hash_link). So we cannot call remove_reader() on the block. + And we cannot access the hash_link directly here. We need to + wait until the assignment is complete. read_block() executes + the correct wait when called with primary == FALSE. + + Or + + this is a primary request for a block to be read into the + cache and the supplied data does not fill the whole block. + + This function is called on behalf of a LOAD INDEX INTO CACHE + statement, which is a read-only task and allows other + readers. It is possible that a parallel running reader tries + to access this block. If it needs more data than has been + supplied here, it would report an error. To be sure that we + have all data in the block that is available in the file, we + read the block ourselves. + + Though reading again what the caller did read already is an + expensive operation, we need to do this for correctness. + */ + read_block(keycache, block, keycache->key_cache_block_size, + read_length + offset, (page_st == PAGE_TO_BE_READ)); + /* + A secondary request must now have the block assigned to the + requested file block. It does not hurt to check it for + primary requests too. + */ + DBUG_ASSERT(keycache->can_be_used); + DBUG_ASSERT(block->hash_link->file == file); + DBUG_ASSERT(block->hash_link->diskpos == filepos); + DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE)); + } + else if (page_st == PAGE_TO_BE_READ) + { + /* + This is a new block in the cache. If we come here, we have + data for the whole block. + */ + DBUG_ASSERT(block->hash_link->requests); + DBUG_ASSERT(block->status & BLOCK_IN_USE); + DBUG_ASSERT((page_st == PAGE_TO_BE_READ) || + (block->status & BLOCK_READ)); #if !defined(SERIALIZED_READ_FROM_CACHE) - keycache_pthread_mutex_lock(&keycache->cache_lock); - /* Here we are alone again. */ + keycache_pthread_mutex_unlock(&keycache->cache_lock); + /* + Here other threads may step in and register as secondary readers. + They will register in block->wqueue[COND_FOR_REQUESTED]. + */ #endif - block->status= BLOCK_READ; - block->length= read_length+offset; - KEYCACHE_DBUG_PRINT("key_cache_insert", - ("primary request: new page in cache")); - /* Signal that all pending requests for this now can be processed. */ - if (block->wqueue[COND_FOR_REQUESTED].last_thread) - release_queue(&block->wqueue[COND_FOR_REQUESTED]); - } + + /* Copy data from buff */ + if (!(read_length & 511)) + bmove512(block->buffer+offset, buff, read_length); + else + memcpy(block->buffer+offset, buff, (size_t) read_length); + +#if !defined(SERIALIZED_READ_FROM_CACHE) + keycache_pthread_mutex_lock(&keycache->cache_lock); + DBUG_ASSERT(block->status & BLOCK_IN_USE); + DBUG_ASSERT((page_st == PAGE_TO_BE_READ) || + (block->status & BLOCK_READ)); +#endif + /* + After the data is in the buffer, we can declare the block + valid. Now other threads do not need to register as + secondary readers any more. They can immediately access the + block. + */ + block->status|= BLOCK_READ; + block->length= read_length+offset; + /* + Do not set block->offset here. If this block is marked + BLOCK_CHANGED later, we want to flush only the modified part. So + only a writer may set block->offset down from + keycache->key_cache_block_size. + */ + KEYCACHE_DBUG_PRINT("key_cache_insert", + ("primary request: new page in cache")); + /* Signal all pending requests. */ + release_whole_queue(&block->wqueue[COND_FOR_REQUESTED]); + } + else + { + /* + page_st == PAGE_READ. The block is in the buffer. All data + must already be present. Blocks are always read with all + data available on file. Assert that the block does not have + less contents than the preloader supplies. If the caller has + data beyond block->length, it means that a file write has + been done while this block was in cache and not extended + with the new data. If the condition is met, we can simply + ignore the block. + */ + DBUG_ASSERT((page_st == PAGE_READ) && + (read_length + offset <= block->length)); + } + + /* + A secondary request must now have the block assigned to the + requested file block. It does not hurt to check it for primary + requests too. + */ + DBUG_ASSERT(block->hash_link->file == file); + DBUG_ASSERT(block->hash_link->diskpos == filepos); + DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE)); + } /* end of if (!(block->status & BLOCK_ERROR)) */ remove_reader(block); - /* - Link the block into the LRU chain - if it's the last submitted request for the block - */ - unreg_request(keycache, block, 1); - error= (block->status & BLOCK_ERROR); + /* Error injection for coverage testing. */ + DBUG_EXECUTE_IF("key_cache_insert_block_error", + block->status|= BLOCK_ERROR; errno=EIO;); - dec_counter_for_resize_op(keycache); - - keycache_pthread_mutex_unlock(&keycache->cache_lock); - - if (error) - DBUG_RETURN(1); + /* Do not link erroneous blocks into the LRU ring, but free them. */ + if (!(block->status & BLOCK_ERROR)) + { + /* + Link the block into the LRU ring if it's the last submitted + request for the block. This enables eviction for the block. + */ + unreg_request(keycache, block, 1); + } + else + { + free_block(keycache, block); + error= 1; + break; + } buff+= read_length; filepos+= read_length+offset; offset= 0; } while ((length-= read_length)); + + no_key_cache: + if (locked_and_incremented) + dec_counter_for_resize_op(keycache); + keycache_pthread_mutex_unlock(&keycache->cache_lock); } - DBUG_RETURN(0); + DBUG_RETURN(error); } @@ -2045,6 +3012,8 @@ int key_cache_insert(KEY_CACHE *keycache, It ensures that this data is flushed to the file if dont_write is FALSE. Filepos must be a multiple of 'block_length', but it doesn't have to be a multiple of key_cache_block_size; + + dont_write is always TRUE in the server (info->lock_type is never F_UNLCK). */ int key_cache_write(KEY_CACHE *keycache, @@ -2053,20 +3022,25 @@ int key_cache_write(KEY_CACHE *keycache, uint block_length __attribute__((unused)), int dont_write) { - reg1 BLOCK_LINK *block; + my_bool locked_and_incremented= FALSE; int error=0; DBUG_ENTER("key_cache_write"); DBUG_PRINT("enter", - ("fd: %u pos: %lu length: %u block_length: %u key_block_length: %u", - (uint) file, (ulong) filepos, length, block_length, - keycache ? keycache->key_cache_block_size : 0)); + ("fd: %u pos: %lu length: %u block_length: %u" + " key_block_length: %u", + (uint) file, (ulong) filepos, length, block_length, + keycache ? keycache->key_cache_block_size : 0)); if (!dont_write) { - /* Force writing from buff into disk */ + /* purecov: begin inspected */ + /* Not used in the server. */ + /* Force writing from buff into disk. */ + keycache->global_cache_w_requests++; keycache->global_cache_write++; if (my_pwrite(file, buff, length, filepos, MYF(MY_NABP | MY_WAIT_IF_FULL))) DBUG_RETURN(1); + /* purecov: end */ } #if !defined(DBUG_OFF) && defined(EXTRA_DEBUG) @@ -2074,92 +3048,231 @@ int key_cache_write(KEY_CACHE *keycache, test_key_cache(keycache, "start of key_cache_write", 1);); #endif - if (keycache->can_be_used) + if (keycache->key_cache_inited) { /* Key cache is used */ + reg1 BLOCK_LINK *block; uint read_length; - int page_st; uint offset; + int page_st; + /* + When the key cache is once initialized, we use the cache_lock to + reliably distinguish the cases of normal operation, resizing, and + disabled cache. We always increment and decrement + 'cnt_for_resize_op' so that a resizer can wait for pending I/O. + */ + keycache_pthread_mutex_lock(&keycache->cache_lock); + /* + Cache resizing has two phases: Flushing and re-initializing. In + the flush phase write requests can modify dirty blocks that are + not yet in flush. Otherwise they are allowed to bypass the cache. + find_key_block() returns NULL in both cases (clean blocks and + non-cached blocks). + + After the flush phase new I/O requests must wait until the + re-initialization is done. The re-initialization can be done only + if no I/O request is in progress. The reason is that + key_cache_block_size can change. With enabled cache I/O is done in + chunks of key_cache_block_size. Every chunk tries to use a cache + block first. If the block size changes in the middle, a block + could be missed and data could be written below a cached block. + */ + while (keycache->in_resize && !keycache->resize_in_flush) + wait_on_queue(&keycache->resize_queue, &keycache->cache_lock); + /* Register the I/O for the next resize. */ + inc_counter_for_resize_op(keycache); + locked_and_incremented= TRUE; + /* Requested data may not always be aligned to cache blocks. */ offset= (uint) (filepos % keycache->key_cache_block_size); + /* Write data in key_cache_block_size increments. */ do { - keycache_pthread_mutex_lock(&keycache->cache_lock); + /* Cache could be disabled in a later iteration. */ if (!keycache->can_be_used) - { - keycache_pthread_mutex_unlock(&keycache->cache_lock); goto no_key_cache; - } - /* Write data in key_cache_block_size increments */ + /* Start writing at the beginning of the cache block. */ filepos-= offset; + /* Do not write beyond the end of the cache block. */ read_length= length; set_if_smaller(read_length, keycache->key_cache_block_size-offset); KEYCACHE_DBUG_ASSERT(read_length > 0); - inc_counter_for_resize_op(keycache); + /* Request the cache block that matches file/pos. */ keycache->global_cache_w_requests++; block= find_key_block(keycache, file, filepos, level, 1, &page_st); if (!block) { - /* It happens only for requests submitted during resize operation */ - dec_counter_for_resize_op(keycache); - keycache_pthread_mutex_unlock(&keycache->cache_lock); - if (dont_write) + /* + This happens only for requests submitted during key cache + resize. The block is not in the cache and shall not go in. + Write directly to file. + */ + if (dont_write) { - keycache->global_cache_w_requests++; + /* Used in the server. */ keycache->global_cache_write++; - if (my_pwrite(file, (byte*) buff, length, filepos, - MYF(MY_NABP | MY_WAIT_IF_FULL))) + keycache_pthread_mutex_unlock(&keycache->cache_lock); + if (my_pwrite(file, (uchar*) buff, read_length, filepos + offset, + MYF(MY_NABP | MY_WAIT_IF_FULL))) error=1; - } + keycache_pthread_mutex_lock(&keycache->cache_lock); + } goto next_block; } + /* + Prevent block from flushing and from being selected for to be + freed. This must be set when we release the cache_lock. + However, we must not set the status of the block before it is + assigned to this file/pos. + */ + if (page_st != PAGE_WAIT_TO_BE_READ) + block->status|= BLOCK_FOR_UPDATE; + /* + We must read the file block first if it is not yet in the cache + and we do not replace all of its contents. - if (block->status != BLOCK_ERROR && page_st != PAGE_READ && - (offset || read_length < keycache->key_cache_block_size)) + In cases where the cache block is big enough to contain (parts + of) index blocks of different indexes, our request can be + secondary (PAGE_WAIT_TO_BE_READ). In this case another thread is + reading the file block. If the read completes after us, it + overwrites our new contents with the old contents. So we have to + wait for the other thread to complete the read of this block. + read_block() takes care for the wait. + */ + if (!(block->status & BLOCK_ERROR) && + ((page_st == PAGE_TO_BE_READ && + (offset || read_length < keycache->key_cache_block_size)) || + (page_st == PAGE_WAIT_TO_BE_READ))) + { read_block(keycache, block, offset + read_length >= keycache->key_cache_block_size? offset : keycache->key_cache_block_size, - offset,(my_bool)(page_st == PAGE_TO_BE_READ)); + offset, (page_st == PAGE_TO_BE_READ)); + DBUG_ASSERT(keycache->can_be_used); + DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE)); + /* + Prevent block from flushing and from being selected for to be + freed. This must be set when we release the cache_lock. + Here we set it in case we could not set it above. + */ + block->status|= BLOCK_FOR_UPDATE; + } + /* + The block should always be assigned to the requested file block + here. It need not be BLOCK_READ when overwriting the whole block. + */ + DBUG_ASSERT(block->hash_link->file == file); + DBUG_ASSERT(block->hash_link->diskpos == filepos); + DBUG_ASSERT(block->status & BLOCK_IN_USE); + DBUG_ASSERT((page_st == PAGE_TO_BE_READ) || (block->status & BLOCK_READ)); + /* + The block to be written must not be marked BLOCK_REASSIGNED. + Otherwise it could be freed in dirty state or reused without + another flush during eviction. It must also not be in flush. + Otherwise the old contens may have been flushed already and + the flusher could clear BLOCK_CHANGED without flushing the + new changes again. + */ + DBUG_ASSERT(!(block->status & BLOCK_REASSIGNED)); + + while (block->status & BLOCK_IN_FLUSHWRITE) + { + /* + Another thread is flushing the block. It was dirty already. + Wait until the block is flushed to file. Otherwise we could + modify the buffer contents just while it is written to file. + An unpredictable file block contents would be the result. + While we wait, several things can happen to the block, + including another flush. But the block cannot be reassigned to + another hash_link until we release our request on it. + */ + wait_on_queue(&block->wqueue[COND_FOR_SAVED], &keycache->cache_lock); + DBUG_ASSERT(keycache->can_be_used); + DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE)); + /* Still must not be marked for free. */ + DBUG_ASSERT(!(block->status & BLOCK_REASSIGNED)); + DBUG_ASSERT(block->hash_link && (block->hash_link->block == block)); + } + + /* + We could perhaps release the cache_lock during access of the + data like in the other functions. Locks outside of the key cache + assure that readers and a writer do not access the same range of + data. Parallel accesses should happen only if the cache block + contains multiple index block(fragment)s. So different parts of + the buffer would be read/written. An attempt to flush during + memcpy() is prevented with BLOCK_FOR_UPDATE. + */ + if (!(block->status & BLOCK_ERROR)) + { +#if !defined(SERIALIZED_READ_FROM_CACHE) + keycache_pthread_mutex_unlock(&keycache->cache_lock); +#endif + if (!(read_length & 511)) + bmove512(block->buffer+offset, buff, read_length); + else + memcpy(block->buffer+offset, buff, (size_t) read_length); + +#if !defined(SERIALIZED_READ_FROM_CACHE) + keycache_pthread_mutex_lock(&keycache->cache_lock); +#endif + } if (!dont_write) { - /* buff has been written to disk at start */ + /* Not used in the server. buff has been written to disk at start. */ if ((block->status & BLOCK_CHANGED) && (!offset && read_length >= keycache->key_cache_block_size)) link_to_file_list(keycache, block, block->hash_link->file, 1); } else if (! (block->status & BLOCK_CHANGED)) link_to_changed_list(keycache, block); - + block->status|=BLOCK_READ; + /* + Allow block to be selected for to be freed. Since it is marked + BLOCK_CHANGED too, it won't be selected for to be freed without + a flush. + */ + block->status&= ~BLOCK_FOR_UPDATE; set_if_smaller(block->offset, offset); set_if_bigger(block->length, read_length+offset); - if (! (block->status & BLOCK_ERROR)) + /* Threads may be waiting for the changes to be complete. */ + release_whole_queue(&block->wqueue[COND_FOR_REQUESTED]); + + /* + If only a part of the cache block is to be replaced, and the + rest has been read from file, then the cache lock has been + released for I/O and it could be possible that another thread + wants to evict or free the block and waits for it to be + released. So we must not just decrement hash_link->requests, but + also wake a waiting thread. + */ + remove_reader(block); + + /* Error injection for coverage testing. */ + DBUG_EXECUTE_IF("key_cache_write_block_error", + block->status|= BLOCK_ERROR;); + + /* Do not link erroneous blocks into the LRU ring, but free them. */ + if (!(block->status & BLOCK_ERROR)) { - if (!(read_length & 511)) - bmove512(block->buffer+offset, buff, read_length); - else - memcpy(block->buffer+offset, buff, (size_t) read_length); + /* + Link the block into the LRU ring if it's the last submitted + request for the block. This enables eviction for the block. + */ + unreg_request(keycache, block, 1); } - - block->status|=BLOCK_READ; - - /* Unregister the request */ - block->hash_link->requests--; - unreg_request(keycache, block, 1); - - if (block->status & BLOCK_ERROR) + else { - keycache_pthread_mutex_unlock(&keycache->cache_lock); + /* Pretend a "clean" block to avoid complications. */ + block->status&= ~(BLOCK_CHANGED); + free_block(keycache, block); error= 1; break; } - dec_counter_for_resize_op(keycache); - - keycache_pthread_mutex_unlock(&keycache->cache_lock); - next_block: buff+= read_length; filepos+= read_length+offset; @@ -2173,14 +3286,24 @@ no_key_cache: /* Key cache is not used */ if (dont_write) { + /* Used in the server. */ keycache->global_cache_w_requests++; keycache->global_cache_write++; + if (locked_and_incremented) + keycache_pthread_mutex_unlock(&keycache->cache_lock); if (my_pwrite(file, (byte*) buff, length, filepos, MYF(MY_NABP | MY_WAIT_IF_FULL))) error=1; + if (locked_and_incremented) + keycache_pthread_mutex_lock(&keycache->cache_lock); } end: + if (locked_and_incremented) + { + dec_counter_for_resize_op(keycache); + keycache_pthread_mutex_unlock(&keycache->cache_lock); + } #if !defined(DBUG_OFF) && defined(EXTRA_DEBUG) DBUG_EXECUTE("exec", test_key_cache(keycache, "end of key_cache_write", 1);); @@ -2190,17 +3313,64 @@ end: /* - Free block: remove reference to it from hash table, - remove it from the chain file of dirty/clean blocks - and add it to the free list. + Free block. + + SYNOPSIS + free_block() + keycache Pointer to a key cache data structure + block Pointer to the block to free + + DESCRIPTION + Remove reference to block from hash table. + Remove block from the chain of clean blocks. + Add block to the free list. + + NOTE + Block must not be free (status == 0). + Block must not be in free_block_list. + Block must not be in the LRU ring. + Block must not be in eviction (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH). + Block must not be in free (BLOCK_REASSIGNED). + Block must not be in flush (BLOCK_IN_FLUSH). + Block must not be dirty (BLOCK_CHANGED). + Block must not be in changed_blocks (dirty) hash. + Block must be in file_blocks (clean) hash. + Block must refer to a hash_link. + Block must have a request registered on it. */ static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block) { KEYCACHE_THREAD_TRACE("free block"); KEYCACHE_DBUG_PRINT("free_block", - ("block %u to be freed, hash_link %p", - BLOCK_NUMBER(block), block->hash_link)); + ("block %u to be freed, hash_link %p status: %u", + BLOCK_NUMBER(block), block->hash_link, + block->status)); + /* + Assert that the block is not free already. And that it is in a clean + state. Note that the block might just be assigned to a hash_link and + not yet read (BLOCK_READ may not be set here). In this case a reader + is registered in the hash_link and free_block() will wait for it + below. + */ + DBUG_ASSERT((block->status & BLOCK_IN_USE) && + !(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH | + BLOCK_REASSIGNED | BLOCK_IN_FLUSH | + BLOCK_CHANGED | BLOCK_FOR_UPDATE))); + /* Assert that the block is in a file_blocks chain. */ + DBUG_ASSERT(block->prev_changed && *block->prev_changed == block); + /* Assert that the block is not in the LRU ring. */ + DBUG_ASSERT(!block->next_used && !block->prev_used); + /* + IMHO the below condition (if()) makes no sense. I can't see how it + could be possible that free_block() is entered with a NULL hash_link + pointer. The only place where it can become NULL is in free_block() + (or before its first use ever, but for those blocks free_block() is + not called). I don't remove the conditional as it cannot harm, but + place an DBUG_ASSERT to confirm my hypothesis. Eventually the + condition (if()) can be removed. + */ + DBUG_ASSERT(block->hash_link && block->hash_link->block == block); if (block->hash_link) { /* @@ -2211,24 +3381,81 @@ static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block) */ block->status|= BLOCK_REASSIGNED; wait_for_readers(keycache, block); - unlink_hash(keycache, block->hash_link); + /* + The block must not have been freed by another thread. Repeat some + checks. An additional requirement is that it must be read now + (BLOCK_READ). + */ + DBUG_ASSERT(block->hash_link && block->hash_link->block == block); + DBUG_ASSERT((block->status & (BLOCK_READ | BLOCK_IN_USE | + BLOCK_REASSIGNED)) && + !(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH | + BLOCK_IN_FLUSH | BLOCK_CHANGED | + BLOCK_FOR_UPDATE))); + DBUG_ASSERT(block->prev_changed && *block->prev_changed == block); + DBUG_ASSERT(!block->prev_used); + /* + Unset BLOCK_REASSIGNED again. If we hand the block to an evicting + thread (through unreg_request() below), other threads must not see + this flag. They could become confused. + */ + block->status&= ~BLOCK_REASSIGNED; + /* + Do not release the hash_link until the block is off all lists. + At least not if we hand it over for eviction in unreg_request(). + */ } + /* + Unregister the block request and link the block into the LRU ring. + This enables eviction for the block. If the LRU ring was empty and + threads are waiting for a block, then the block wil be handed over + for eviction immediately. Otherwise we will unlink it from the LRU + ring again, without releasing the lock in between. So decrementing + the request counter and updating statistics are the only relevant + operation in this case. Assert that there are no other requests + registered. + */ + DBUG_ASSERT(block->requests == 1); + unreg_request(keycache, block, 0); + /* + Note that even without releasing the cache lock it is possible that + the block is immediately selected for eviction by link_block() and + thus not added to the LRU ring. In this case we must not touch the + block any more. + */ + if (block->status & BLOCK_IN_EVICTION) + return; + + /* Error blocks are not put into the LRU ring. */ + if (!(block->status & BLOCK_ERROR)) + { + /* Here the block must be in the LRU ring. Unlink it again. */ + DBUG_ASSERT(block->next_used && block->prev_used && + *block->prev_used == block); + unlink_block(keycache, block); + } + if (block->temperature == BLOCK_WARM) + keycache->warm_blocks--; + block->temperature= BLOCK_COLD; + + /* Remove from file_blocks hash. */ unlink_changed(block); + + /* Remove reference to block from hash table. */ + unlink_hash(keycache, block->hash_link); + block->hash_link= NULL; + block->status= 0; block->length= 0; block->offset= keycache->key_cache_block_size; KEYCACHE_THREAD_TRACE("free block"); - KEYCACHE_DBUG_PRINT("free_block", - ("block is freed")); - unreg_request(keycache, block, 0); - block->hash_link= NULL; + KEYCACHE_DBUG_PRINT("free_block", ("block is freed")); - /* Remove the free block from the LRU ring. */ - unlink_block(keycache, block); - if (block->temperature == BLOCK_WARM) - keycache->warm_blocks--; - block->temperature= BLOCK_COLD; + /* Enforced by unlink_changed(), but just to be sure. */ + DBUG_ASSERT(!block->next_changed && !block->prev_changed); + /* Enforced by unlink_block(): not in LRU ring nor in free_block_list. */ + DBUG_ASSERT(!block->next_used && !block->prev_used); /* Insert the free block in the free list. */ block->next_used= keycache->free_block_list; keycache->free_block_list= block; @@ -2236,8 +3463,7 @@ static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block) keycache->blocks_unused++; /* All pending requests for this page must be resubmitted. */ - if (block->wqueue[COND_FOR_SAVED].last_thread) - release_queue(&block->wqueue[COND_FOR_SAVED]); + release_whole_queue(&block->wqueue[COND_FOR_SAVED]); } @@ -2271,54 +3497,97 @@ static int flush_cached_blocks(KEY_CACHE *keycache, my_qsort((byte*) cache, count, sizeof(*cache), (qsort_cmp) cmp_sec_link); keycache_pthread_mutex_lock(&keycache->cache_lock); + /* + Note: Do not break the loop. We have registered a request on every + block in 'cache'. These must be unregistered by free_block() or + unreg_request(). + */ for ( ; cache != end ; cache++) { BLOCK_LINK *block= *cache; KEYCACHE_DBUG_PRINT("flush_cached_blocks", ("block %u to be flushed", BLOCK_NUMBER(block))); - keycache_pthread_mutex_unlock(&keycache->cache_lock); - error= my_pwrite(file, - block->buffer+block->offset, - block->length - block->offset, - block->hash_link->diskpos+ block->offset, - MYF(MY_NABP | MY_WAIT_IF_FULL)); - keycache_pthread_mutex_lock(&keycache->cache_lock); - keycache->global_cache_write++; - if (error) + /* + If the block contents is going to be changed, we abandon the flush + for this block. flush_key_blocks_int() will restart its search and + handle the block properly. + */ + if (!(block->status & BLOCK_FOR_UPDATE)) { - block->status|= BLOCK_ERROR; - if (!last_errno) - last_errno= errno ? errno : -1; + /* Blocks coming here must have a certain status. */ + DBUG_ASSERT(block->hash_link); + DBUG_ASSERT(block->hash_link->block == block); + DBUG_ASSERT(block->hash_link->file == file); + DBUG_ASSERT((block->status & ~BLOCK_IN_EVICTION) == + (BLOCK_READ | BLOCK_IN_FLUSH | BLOCK_CHANGED | BLOCK_IN_USE)); + block->status|= BLOCK_IN_FLUSHWRITE; + keycache_pthread_mutex_unlock(&keycache->cache_lock); + error= my_pwrite(file, block->buffer+block->offset, + block->length - block->offset, + block->hash_link->diskpos+ block->offset, + MYF(MY_NABP | MY_WAIT_IF_FULL)); + keycache_pthread_mutex_lock(&keycache->cache_lock); + keycache->global_cache_write++; + if (error) + { + block->status|= BLOCK_ERROR; + if (!last_errno) + last_errno= errno ? errno : -1; + } + block->status&= ~BLOCK_IN_FLUSHWRITE; + /* Block must not have changed status except BLOCK_FOR_UPDATE. */ + DBUG_ASSERT(block->hash_link); + DBUG_ASSERT(block->hash_link->block == block); + DBUG_ASSERT(block->hash_link->file == file); + DBUG_ASSERT((block->status & ~(BLOCK_FOR_UPDATE | BLOCK_IN_EVICTION)) == + (BLOCK_READ | BLOCK_IN_FLUSH | BLOCK_CHANGED | BLOCK_IN_USE)); + /* + Set correct status and link in right queue for free or later use. + free_block() must not see BLOCK_CHANGED and it may need to wait + for readers of the block. These should not see the block in the + wrong hash. If not freeing the block, we need to have it in the + right queue anyway. + */ + link_to_file_list(keycache, block, file, 1); } + block->status&= ~BLOCK_IN_FLUSH; /* Let to proceed for possible waiting requests to write to the block page. It might happen only during an operation to resize the key cache. */ - if (block->wqueue[COND_FOR_SAVED].last_thread) - release_queue(&block->wqueue[COND_FOR_SAVED]); + release_whole_queue(&block->wqueue[COND_FOR_SAVED]); /* type will never be FLUSH_IGNORE_CHANGED here */ - if (! (type == FLUSH_KEEP || type == FLUSH_FORCE_WRITE)) + if (!(type == FLUSH_KEEP || type == FLUSH_FORCE_WRITE) && + !(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH | + BLOCK_FOR_UPDATE))) { - keycache->blocks_changed--; - keycache->global_blocks_changed--; + /* + Note that a request has been registered against the block in + flush_key_blocks_int(). + */ free_block(keycache, block); } else { - block->status&= ~BLOCK_IN_FLUSH; - link_to_file_list(keycache, block, file, 1); + /* + Link the block into the LRU ring if it's the last submitted + request for the block. This enables eviction for the block. + Note that a request has been registered against the block in + flush_key_blocks_int(). + */ unreg_request(keycache, block, 1); } - } + } /* end of for ( ; cache != end ; cache++) */ return last_errno; } /* - flush all key blocks for a file to disk, but don't do any mutex locks + Flush all key blocks for a file to disk, but don't do any mutex locks. + SYNOPSIS flush_key_blocks_int() keycache pointer to a key cache data structure file handler for the file to flush to @@ -2329,6 +3598,10 @@ static int flush_cached_blocks(KEY_CACHE *keycache, from flush_key_blocks and flush_all_key_blocks (the later one does the mutex lock in the resize_key_cache() function). + We do only care about changed blocks that exist when the function is + entered. We do not guarantee that all changed blocks of the file are + flushed if more blocks change while this function is running. + RETURN 0 ok 1 error @@ -2339,13 +3612,14 @@ static int flush_key_blocks_int(KEY_CACHE *keycache, { BLOCK_LINK *cache_buff[FLUSH_CACHE],**cache; int last_errno= 0; + int last_errcnt= 0; DBUG_ENTER("flush_key_blocks_int"); DBUG_PRINT("enter",("file: %d blocks_used: %lu blocks_changed: %lu", file, keycache->blocks_used, keycache->blocks_changed)); #if !defined(DBUG_OFF) && defined(EXTRA_DEBUG) - DBUG_EXECUTE("check_keycache", - test_key_cache(keycache, "start of flush_key_blocks", 0);); + DBUG_EXECUTE("check_keycache", + test_key_cache(keycache, "start of flush_key_blocks", 0);); #endif cache= cache_buff; @@ -2354,9 +3628,11 @@ static int flush_key_blocks_int(KEY_CACHE *keycache, { /* Key cache exists and flush is not disabled */ int error= 0; - uint count= 0; + uint count= FLUSH_CACHE; BLOCK_LINK **pos,**end; BLOCK_LINK *first_in_switch= NULL; + BLOCK_LINK *last_in_flush; + BLOCK_LINK *last_for_update; BLOCK_LINK *block, *next; #if defined(KEYCACHE_DEBUG) uint cnt=0; @@ -2368,28 +3644,39 @@ static int flush_key_blocks_int(KEY_CACHE *keycache, Count how many key blocks we have to cache to be able to flush all dirty pages with minimum seek moves */ + count= 0; for (block= keycache->changed_blocks[FILE_HASH(file)] ; block ; block= block->next_changed) { - if (block->hash_link->file == file) + if ((block->hash_link->file == file) && + !(block->status & BLOCK_IN_FLUSH)) { count++; KEYCACHE_DBUG_ASSERT(count<= keycache->blocks_used); } } - /* Allocate a new buffer only if its bigger than the one we have */ - if (count > FLUSH_CACHE && + /* + Allocate a new buffer only if its bigger than the one we have. + Assure that we always have some entries for the case that new + changed blocks appear while we need to wait for something. + */ + if ((count > FLUSH_CACHE) && !(cache= (BLOCK_LINK**) my_malloc(sizeof(BLOCK_LINK*)*count, MYF(0)))) - { cache= cache_buff; + /* + After a restart there could be more changed blocks than now. + So we should not let count become smaller than the fixed buffer. + */ + if (cache == cache_buff) count= FLUSH_CACHE; - } } /* Retrieve the blocks and write them to a buffer to be flushed */ restart: + last_in_flush= NULL; + last_for_update= NULL; end= (pos= cache)+count; for (block= keycache->changed_blocks[FILE_HASH(file)] ; block ; @@ -2402,121 +3689,350 @@ restart: next= block->next_changed; if (block->hash_link->file == file) { - /* - Mark the block with BLOCK_IN_FLUSH in order not to let - other threads to use it for new pages and interfere with - our sequence ot flushing dirty file pages - */ - block->status|= BLOCK_IN_FLUSH; - - if (! (block->status & BLOCK_IN_SWITCH)) + if (!(block->status & (BLOCK_IN_FLUSH | BLOCK_FOR_UPDATE))) { - /* - We care only for the blocks for which flushing was not - initiated by other threads as a result of page swapping + /* + Note: The special handling of BLOCK_IN_SWITCH is obsolete + since we set BLOCK_IN_FLUSH if the eviction includes a + flush. It can be removed in a later version. */ - reg_requests(keycache, block, 1); - if (type != FLUSH_IGNORE_CHANGED) + if (!(block->status & BLOCK_IN_SWITCH)) { - /* It's not a temporary file */ - if (pos == end) + /* + We care only for the blocks for which flushing was not + initiated by another thread and which are not in eviction. + Registering a request on the block unlinks it from the LRU + ring and protects against eviction. + */ + reg_requests(keycache, block, 1); + if (type != FLUSH_IGNORE_CHANGED) { - /* - This happens only if there is not enough - memory for the big block - */ - if ((error= flush_cached_blocks(keycache, file, cache, - end,type))) - last_errno=error; + /* It's not a temporary file */ + if (pos == end) + { + /* + This should happen relatively seldom. Remove the + request because we won't do anything with the block + but restart and pick it again in the next iteration. + */ + unreg_request(keycache, block, 0); + /* + This happens only if there is not enough + memory for the big block + */ + if ((error= flush_cached_blocks(keycache, file, cache, + end,type))) + { + /* Do not loop infinitely trying to flush in vain. */ + if ((last_errno == error) && (++last_errcnt > 5)) + goto err; + last_errno= error; + } + /* + Restart the scan as some other thread might have changed + the changed blocks chain: the blocks that were in switch + state before the flush started have to be excluded + */ + goto restart; + } /* - Restart the scan as some other thread might have changed - the changed blocks chain: the blocks that were in switch - state before the flush started have to be excluded + Mark the block with BLOCK_IN_FLUSH in order not to let + other threads to use it for new pages and interfere with + our sequence of flushing dirty file pages. We must not + set this flag before actually putting the block on the + write burst array called 'cache'. */ - goto restart; + block->status|= BLOCK_IN_FLUSH; + /* Add block to the array for a write burst. */ + *pos++= block; + } + else + { + /* It's a temporary file */ + DBUG_ASSERT(!(block->status & BLOCK_REASSIGNED)); + /* + free_block() must not be called with BLOCK_CHANGED. Note + that we must not change the BLOCK_CHANGED flag outside of + link_to_file_list() so that it is always in the correct + queue and the *blocks_changed counters are correct. + */ + link_to_file_list(keycache, block, file, 1); + if (!(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH))) + { + /* A request has been registered against the block above. */ + free_block(keycache, block); + } + else + { + /* + Link the block into the LRU ring if it's the last + submitted request for the block. This enables eviction + for the block. A request has been registered against + the block above. + */ + unreg_request(keycache, block, 1); + } } - *pos++= block; } else { - /* It's a temporary file */ - keycache->blocks_changed--; - keycache->global_blocks_changed--; - free_block(keycache, block); + /* + Link the block into a list of blocks 'in switch'. + + WARNING: Here we introduce a place where a changed block + is not in the changed_blocks hash! This is acceptable for + a BLOCK_IN_SWITCH. Never try this for another situation. + Other parts of the key cache code rely on changed blocks + being in the changed_blocks hash. + */ + unlink_changed(block); + link_changed(block, &first_in_switch); } } - else + else if (type != FLUSH_KEEP) { - /* Link the block into a list of blocks 'in switch' */ - unlink_changed(block); - link_changed(block, &first_in_switch); + /* + During the normal flush at end of statement (FLUSH_KEEP) we + do not need to ensure that blocks in flush or update by + other threads are flushed. They will be flushed by them + later. In all other cases we must assure that we do not have + any changed block of this file in the cache when this + function returns. + */ + if (block->status & BLOCK_IN_FLUSH) + { + /* Remember the last block found to be in flush. */ + last_in_flush= block; + } + else + { + /* Remember the last block found to be selected for update. */ + last_for_update= block; + } } } } if (pos != cache) { if ((error= flush_cached_blocks(keycache, file, cache, pos, type))) + { + /* Do not loop inifnitely trying to flush in vain. */ + if ((last_errno == error) && (++last_errcnt > 5)) + goto err; last_errno= error; + } + /* + Do not restart here during the normal flush at end of statement + (FLUSH_KEEP). We have now flushed at least all blocks that were + changed when entering this function. In all other cases we must + assure that we do not have any changed block of this file in the + cache when this function returns. + */ + if (type != FLUSH_KEEP) + goto restart; } - /* Wait until list of blocks in switch is empty */ + if (last_in_flush) + { + /* + There are no blocks to be flushed by this thread, but blocks in + flush by other threads. Wait until one of the blocks is flushed. + Re-check the condition for last_in_flush. We may have unlocked + the cache_lock in flush_cached_blocks(). The state of the block + could have changed. + */ + if (last_in_flush->status & BLOCK_IN_FLUSH) + wait_on_queue(&last_in_flush->wqueue[COND_FOR_SAVED], + &keycache->cache_lock); + /* Be sure not to lose a block. They may be flushed in random order. */ + goto restart; + } + if (last_for_update) + { + /* + There are no blocks to be flushed by this thread, but blocks for + update by other threads. Wait until one of the blocks is updated. + Re-check the condition for last_for_update. We may have unlocked + the cache_lock in flush_cached_blocks(). The state of the block + could have changed. + */ + if (last_for_update->status & BLOCK_FOR_UPDATE) + wait_on_queue(&last_for_update->wqueue[COND_FOR_REQUESTED], + &keycache->cache_lock); + /* The block is now changed. Flush it. */ + goto restart; + } + + /* + Wait until the list of blocks in switch is empty. The threads that + are switching these blocks will relink them to clean file chains + while we wait and thus empty the 'first_in_switch' chain. + */ while (first_in_switch) { #if defined(KEYCACHE_DEBUG) cnt= 0; #endif - block= first_in_switch; - { -#ifdef THREAD - struct st_my_thread_var *thread= my_thread_var; - add_to_queue(&block->wqueue[COND_FOR_SAVED], thread); - do - { - KEYCACHE_DBUG_PRINT("flush_key_blocks_int: wait", - ("suspend thread %ld", thread->id)); - keycache_pthread_cond_wait(&thread->suspend, - &keycache->cache_lock); - } - while (thread->next); -#else - KEYCACHE_DBUG_ASSERT(0); - /* No parallel requests in single-threaded case */ -#endif - } + wait_on_queue(&first_in_switch->wqueue[COND_FOR_SAVED], + &keycache->cache_lock); #if defined(KEYCACHE_DEBUG) cnt++; KEYCACHE_DBUG_ASSERT(cnt <= keycache->blocks_used); #endif + /* + Do not restart here. We have flushed all blocks that were + changed when entering this function and were not marked for + eviction. Other threads have now flushed all remaining blocks in + the course of their eviction. + */ } - /* The following happens very seldom */ + if (! (type == FLUSH_KEEP || type == FLUSH_FORCE_WRITE)) { -#if defined(KEYCACHE_DEBUG) - cnt=0; -#endif - for (block= keycache->file_blocks[FILE_HASH(file)] ; - block ; - block= next) + BLOCK_LINK *last_for_update= NULL; + BLOCK_LINK *last_in_switch= NULL; + uint total_found= 0; + uint found; + + /* + Finally free all clean blocks for this file. + During resize this may be run by two threads in parallel. + */ + do { -#if defined(KEYCACHE_DEBUG) - cnt++; - KEYCACHE_DBUG_ASSERT(cnt <= keycache->blocks_used); -#endif - next= block->next_changed; - if (block->hash_link->file == file && - (! (block->status & BLOCK_CHANGED) - || type == FLUSH_IGNORE_CHANGED)) + found= 0; + for (block= keycache->file_blocks[FILE_HASH(file)] ; + block ; + block= next) { - reg_requests(keycache, block, 1); - free_block(keycache, block); - } + /* Remember the next block. After freeing we cannot get at it. */ + next= block->next_changed; + + /* Changed blocks cannot appear in the file_blocks hash. */ + DBUG_ASSERT(!(block->status & BLOCK_CHANGED)); + if (block->hash_link->file == file) + { + /* We must skip blocks that will be changed. */ + if (block->status & BLOCK_FOR_UPDATE) + { + last_for_update= block; + continue; + } + + /* + We must not free blocks in eviction (BLOCK_IN_EVICTION | + BLOCK_IN_SWITCH) or blocks intended to be freed + (BLOCK_REASSIGNED). + */ + if (!(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH | + BLOCK_REASSIGNED))) + { + struct st_hash_link *next_hash_link; + my_off_t next_diskpos; + File next_file; + uint next_status; + uint hash_requests; + + total_found++; + found++; + KEYCACHE_DBUG_ASSERT(found <= keycache->blocks_used); + + /* + Register a request. This unlinks the block from the LRU + ring and protects it against eviction. This is required + by free_block(). + */ + reg_requests(keycache, block, 1); + + /* + free_block() may need to wait for readers of the block. + This is the moment where the other thread can move the + 'next' block from the chain. free_block() needs to wait + if there are requests for the block pending. + */ + if (next && (hash_requests= block->hash_link->requests)) + { + /* Copy values from the 'next' block and its hash_link. */ + next_status= next->status; + next_hash_link= next->hash_link; + next_diskpos= next_hash_link->diskpos; + next_file= next_hash_link->file; + DBUG_ASSERT(next == next_hash_link->block); + } + + free_block(keycache, block); + /* + If we had to wait and the state of the 'next' block + changed, break the inner loop. 'next' may no longer be + part of the current chain. + + We do not want to break the loop after every free_block(), + not even only after waits. The chain might be quite long + and contain blocks for many files. Traversing it again and + again to find more blocks for this file could become quite + inefficient. + */ + if (next && hash_requests && + ((next_status != next->status) || + (next_hash_link != next->hash_link) || + (next_file != next_hash_link->file) || + (next_diskpos != next_hash_link->diskpos) || + (next != next_hash_link->block))) + break; + } + else + { + last_in_switch= block; + } + } + } /* end for block in file_blocks */ + } while (found); + + /* + If any clean block has been found, we may have waited for it to + become free. In this case it could be possible that another clean + block became dirty. This is possible if the write request existed + before the flush started (BLOCK_FOR_UPDATE). Re-check the hashes. + */ + if (total_found) + goto restart; + + /* + To avoid an infinite loop, wait until one of the blocks marked + for update is updated. + */ + if (last_for_update) + { + /* We did not wait. Block must not have changed status. */ + DBUG_ASSERT(last_for_update->status & BLOCK_FOR_UPDATE); + wait_on_queue(&last_for_update->wqueue[COND_FOR_REQUESTED], + &keycache->cache_lock); + goto restart; } - } - } + + /* + To avoid an infinite loop wait until one of the blocks marked + for eviction is switched. + */ + if (last_in_switch) + { + /* We did not wait. Block must not have changed status. */ + DBUG_ASSERT(last_in_switch->status & (BLOCK_IN_EVICTION | + BLOCK_IN_SWITCH | + BLOCK_REASSIGNED)); + wait_on_queue(&last_in_switch->wqueue[COND_FOR_SAVED], + &keycache->cache_lock); + goto restart; + } + + } /* if (! (type == FLUSH_KEEP || type == FLUSH_FORCE_WRITE)) */ + + } /* if (keycache->disk_blocks > 0 */ #ifndef DBUG_OFF DBUG_EXECUTE("check_keycache", test_key_cache(keycache, "end of flush_key_blocks", 0);); #endif +err: if (cache != cache_buff) my_free((gptr) cache, MYF(0)); if (last_errno) @@ -2543,51 +4059,157 @@ restart: int flush_key_blocks(KEY_CACHE *keycache, File file, enum flush_type type) { - int res; + int res= 0; DBUG_ENTER("flush_key_blocks"); DBUG_PRINT("enter", ("keycache: 0x%lx", (long) keycache)); - if (keycache->disk_blocks <= 0) + if (!keycache->key_cache_inited) DBUG_RETURN(0); + keycache_pthread_mutex_lock(&keycache->cache_lock); - inc_counter_for_resize_op(keycache); - res= flush_key_blocks_int(keycache, file, type); - dec_counter_for_resize_op(keycache); + /* While waiting for lock, keycache could have been ended. */ + if (keycache->disk_blocks > 0) + { + inc_counter_for_resize_op(keycache); + res= flush_key_blocks_int(keycache, file, type); + dec_counter_for_resize_op(keycache); + } keycache_pthread_mutex_unlock(&keycache->cache_lock); DBUG_RETURN(res); } /* - Flush all blocks in the key cache to disk + Flush all blocks in the key cache to disk. + + SYNOPSIS + flush_all_key_blocks() + keycache pointer to key cache root structure + + DESCRIPTION + + Flushing of the whole key cache is done in two phases. + + 1. Flush all changed blocks, waiting for them if necessary. Loop + until there is no changed block left in the cache. + + 2. Free all clean blocks. Normally this means free all blocks. The + changed blocks were flushed in phase 1 and became clean. However we + may need to wait for blocks that are read by other threads. While we + wait, a clean block could become changed if that operation started + before the resize operation started. To be safe we must restart at + phase 1. + + When we can run through the changed_blocks and file_blocks hashes + without finding a block any more, then we are done. + + Note that we hold keycache->cache_lock all the time unless we need + to wait for something. + + RETURN + 0 OK + != 0 Error */ static int flush_all_key_blocks(KEY_CACHE *keycache) { -#if defined(KEYCACHE_DEBUG) - uint cnt=0; -#endif - while (keycache->blocks_changed > 0) + BLOCK_LINK *block; + uint total_found; + uint found; + uint idx; + DBUG_ENTER("flush_all_key_blocks"); + + do { - BLOCK_LINK *block; - for (block= keycache->used_last->next_used ; ; block=block->next_used) + safe_mutex_assert_owner(&keycache->cache_lock); + total_found= 0; + + /* + Phase1: Flush all changed blocks, waiting for them if necessary. + Loop until there is no changed block left in the cache. + */ + do { - if (block->hash_link) + found= 0; + /* Step over the whole changed_blocks hash array. */ + for (idx= 0; idx < CHANGED_BLOCKS_HASH; idx++) { -#if defined(KEYCACHE_DEBUG) - cnt++; - KEYCACHE_DBUG_ASSERT(cnt <= keycache->blocks_used); -#endif - if (flush_key_blocks_int(keycache, block->hash_link->file, - FLUSH_RELEASE)) - return 1; - break; + /* + If an array element is non-empty, use the first block from its + chain to find a file for flush. All changed blocks for this + file are flushed. So the same block will not appear at this + place again with the next iteration. New writes for blocks are + not accepted during the flush. If multiple files share the + same hash bucket, one of them will be flushed per iteration + of the outer loop of phase 1. + */ + if ((block= keycache->changed_blocks[idx])) + { + found++; + /* + Flush dirty blocks but do not free them yet. They can be used + for reading until all other blocks are flushed too. + */ + if (flush_key_blocks_int(keycache, block->hash_link->file, + FLUSH_FORCE_WRITE)) + DBUG_RETURN(1); + } } - if (block == keycache->used_last) - break; - } + + } while (found); + + /* + Phase 2: Free all clean blocks. Normally this means free all + blocks. The changed blocks were flushed in phase 1 and became + clean. However we may need to wait for blocks that are read by + other threads. While we wait, a clean block could become changed + if that operation started before the resize operation started. To + be safe we must restart at phase 1. + */ + do + { + found= 0; + /* Step over the whole file_blocks hash array. */ + for (idx= 0; idx < CHANGED_BLOCKS_HASH; idx++) + { + /* + If an array element is non-empty, use the first block from its + chain to find a file for flush. All blocks for this file are + freed. So the same block will not appear at this place again + with the next iteration. If multiple files share the + same hash bucket, one of them will be flushed per iteration + of the outer loop of phase 2. + */ + if ((block= keycache->file_blocks[idx])) + { + total_found++; + found++; + if (flush_key_blocks_int(keycache, block->hash_link->file, + FLUSH_RELEASE)) + DBUG_RETURN(1); + } + } + + } while (found); + + /* + If any clean block has been found, we may have waited for it to + become free. In this case it could be possible that another clean + block became dirty. This is possible if the write request existed + before the resize started (BLOCK_FOR_UPDATE). Re-check the hashes. + */ + } while (total_found); + +#ifndef DBUG_OFF + /* Now there should not exist any block any more. */ + for (idx= 0; idx < CHANGED_BLOCKS_HASH; idx++) + { + DBUG_ASSERT(!keycache->changed_blocks[idx]); + DBUG_ASSERT(!keycache->file_blocks[idx]); } - return 0; +#endif + + DBUG_RETURN(0); } @@ -2838,8 +4460,8 @@ static void keycache_debug_print(const char * fmt,...) va_start(args,fmt); if (keycache_debug_log) { - VOID(vfprintf(keycache_debug_log, fmt, args)); - VOID(fputc('\n',keycache_debug_log)); + (void) vfprintf(keycache_debug_log, fmt, args); + (void) fputc('\n',keycache_debug_log); } va_end(args); } @@ -2856,3 +4478,70 @@ void keycache_debug_log_close(void) #endif /* defined(KEYCACHE_DEBUG_LOG) */ #endif /* defined(KEYCACHE_DEBUG) */ + +#if !defined(DBUG_OFF) +#define F_B_PRT(_f_, _v_) DBUG_PRINT("assert_fail", (_f_, _v_)) + +static int fail_block(BLOCK_LINK *block) +{ + F_B_PRT("block->next_used: %lx\n", (ulong) block->next_used); + F_B_PRT("block->prev_used: %lx\n", (ulong) block->prev_used); + F_B_PRT("block->next_changed: %lx\n", (ulong) block->next_changed); + F_B_PRT("block->prev_changed: %lx\n", (ulong) block->prev_changed); + F_B_PRT("block->hash_link: %lx\n", (ulong) block->hash_link); + F_B_PRT("block->status: %u\n", block->status); + F_B_PRT("block->length: %u\n", block->length); + F_B_PRT("block->offset: %u\n", block->offset); + F_B_PRT("block->requests: %u\n", block->requests); + F_B_PRT("block->temperature: %u\n", block->temperature); + return 0; /* Let the assert fail. */ +} + +static int fail_hlink(HASH_LINK *hlink) +{ + F_B_PRT("hlink->next: %lx\n", (ulong) hlink->next); + F_B_PRT("hlink->prev: %lx\n", (ulong) hlink->prev); + F_B_PRT("hlink->block: %lx\n", (ulong) hlink->block); + F_B_PRT("hlink->diskpos: %lu\n", (ulong) hlink->diskpos); + F_B_PRT("hlink->file: %d\n", hlink->file); + return 0; /* Let the assert fail. */ +} + +static int cache_empty(KEY_CACHE *keycache) +{ + int errcnt= 0; + int idx; + if (keycache->disk_blocks <= 0) + return 1; + for (idx= 0; idx < keycache->disk_blocks; idx++) + { + BLOCK_LINK *block= keycache->block_root + idx; + if (block->status || block->requests || block->hash_link) + { + fprintf(stderr, "block index: %u\n", idx); + fail_block(block); + errcnt++; + } + } + for (idx= 0; idx < keycache->hash_links; idx++) + { + HASH_LINK *hash_link= keycache->hash_link_root + idx; + if (hash_link->requests || hash_link->block) + { + fprintf(stderr, "hash_link index: %u\n", idx); + fail_hlink(hash_link); + errcnt++; + } + } + if (errcnt) + { + fprintf(stderr, "blocks: %d used: %lu\n", + keycache->disk_blocks, keycache->blocks_used); + fprintf(stderr, "hash_links: %d used: %d\n", + keycache->hash_links, keycache->hash_links_used); + fprintf(stderr, "\n"); + } + return !errcnt; +} +#endif + diff --git a/mysys/my_static.c b/mysys/my_static.c index 1858d830f41..23e37c53f98 100644 --- a/mysys/my_static.c +++ b/mysys/my_static.c @@ -48,9 +48,6 @@ struct st_remember _my_sig_remember[MAX_SIGNALS]={{0,0}}; sigset_t my_signals; /* signals blocked by mf_brkhant */ #endif - /* from mf_keycache.c */ -my_bool key_cache_inited=0; - /* from mf_reccache.c */ ulong my_default_record_cache_size=RECORD_CACHE_SIZE; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index dfd739f6db8..a92e7bbb9fd 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1189,6 +1189,7 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt) ulonglong map= ~(ulonglong) 0; TABLE_LIST *table_list= table->pos_in_table_list; my_bool ignore_leaves= table_list->ignore_leaves; + char buf[ERRMSGSIZE+20]; DBUG_ENTER("ha_myisam::preload_keys"); @@ -1216,7 +1217,6 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt) errmsg= "Failed to allocate buffer"; break; default: - char buf[ERRMSGSIZE+20]; my_snprintf(buf, ERRMSGSIZE, "Failed to read from index file (errno: %d)", my_errno); errmsg= buf; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 5a3100685e0..e32c17bc678 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2741,8 +2741,13 @@ int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache, bool mysql_preload_keys(THD* thd, TABLE_LIST* tables) { DBUG_ENTER("mysql_preload_keys"); + /* + We cannot allow concurrent inserts. The storage engine reads + directly from the index file, bypassing the cache. It could read + outdated information if parallel inserts into cache blocks happen. + */ DBUG_RETURN(mysql_admin_table(thd, tables, 0, - "preload_keys", TL_READ, 0, 0, 0, 0, + "preload_keys", TL_READ_NO_INSERT, 0, 0, 0, 0, &handler::preload_keys, 0)); } From 29d0fa12f7770b67c4df00ab1b4de13e0bfdf8bb Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Tue, 8 Sep 2009 15:35:01 +0200 Subject: [PATCH 097/138] This is the 5.4 version of the fix for bug#47007 Unresolved reference to 'innodb_system_libs' in "mysql_config" In 5.4.2, we use InnoDB 1.0.4 which does file IO via separate threads, opposed to the use of asynchronous IO previously. So there is no InnoDB call to "aio_read()" which was searched in "librt", causing a "-lrt" value of "innodb_system_libs", that whole variable is gone. This fix was applied in the build of 5.4.2-beta. scripts/Makefile.am: There is no "innodb_system_libs" variable any more, so it cannot be replaced by its value. scripts/mysql_config.pl.in: InnoDB does not need any platform-specific libraries any more, "innodb_system_libs" may go. scripts/mysql_config.sh: InnoDB does not need any platform-specific libraries any more, "innodb_system_libs" may go. --- scripts/Makefile.am | 1 - scripts/mysql_config.pl.in | 2 +- scripts/mysql_config.sh | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/Makefile.am b/scripts/Makefile.am index e493c68827c..cd758370388 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -169,7 +169,6 @@ SUFFIXES = .sh -e 's!@''ZLIB_LIBS''@!@ZLIB_LIBS@!' \ -e 's!@''LIBS''@!@LIBS@!' \ -e 's!@''WRAPLIBS''@!@WRAPLIBS@!' \ - -e 's!@''innodb_system_libs''@!@innodb_system_libs@!' \ -e 's!@''openssl_libs''@!@openssl_libs@!' \ -e 's!@''VERSION''@!@VERSION@!' \ -e 's!@''MYSQL_BASE_VERSION''@!@MYSQL_BASE_VERSION@!' \ diff --git a/scripts/mysql_config.pl.in b/scripts/mysql_config.pl.in index 21896711fa8..415c0d3040e 100644 --- a/scripts/mysql_config.pl.in +++ b/scripts/mysql_config.pl.in @@ -202,7 +202,7 @@ $flags->{libs} = $flags->{libs_r} = [@ldflags,@lib_r_opts,'@ZLIB_DEPS@','@LIBS@','@openssl_libs@']; $flags->{embedded_libs} = - [@ldflags,@lib_e_opts,'@LIBDL@','@ZLIB_DEPS@','@LIBS@','@WRAPLIBS@','@innodb_system_libs@','@openssl_libs@']; + [@ldflags,@lib_e_opts,'@LIBDL@','@ZLIB_DEPS@','@LIBS@','@WRAPLIBS@','@openssl_libs@']; $flags->{include} = ["-I$pkgincludedir"]; $flags->{cflags} = [@{$flags->{include}},split(" ",'@CFLAGS@')]; diff --git a/scripts/mysql_config.sh b/scripts/mysql_config.sh index efc82544bc0..4118856af19 100644 --- a/scripts/mysql_config.sh +++ b/scripts/mysql_config.sh @@ -107,7 +107,7 @@ fi libs=" $ldflags -L$pkglibdir -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@" libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ " libs_r=" $ldflags -L$pkglibdir -lmysqlclient_r @ZLIB_DEPS@ @LIBS@ @openssl_libs@ " -embedded_libs=" $ldflags -L$pkglibdir -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @innodb_system_libs@ @openssl_libs@ " +embedded_libs=" $ldflags -L$pkglibdir -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ " if [ -r "$pkglibdir/libmygcc.a" ]; then # When linking against the static library with a different version of GCC From deab1e9ce3dc073927f57ed62bc0fdcd2c663cc3 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Tue, 8 Sep 2009 15:38:40 +0200 Subject: [PATCH 098/138] Some fixes to make 5.4.2-beta compile on the less common platforms like AIX, HP-UX, and Solaris 8. All these are upmerges from 5.1 which came too late to be included when 5.4.2-beta was cloned, so they were applied during the build phase. --- storage/innobase/handler/i_s.cc | 18 ++++++++++-------- storage/innobase/include/btr0cur.h | 2 +- storage/innobase/include/trx0types.h | 2 +- storage/innobase/include/univ.i | 3 ++- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index c0d488d1c49..524fe696de2 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -69,14 +69,16 @@ do { \ #define STRUCT_FLD(name, value) value #endif -static const ST_FIELD_INFO END_OF_ST_FIELD_INFO = - {STRUCT_FLD(field_name, NULL), - STRUCT_FLD(field_length, 0), - STRUCT_FLD(field_type, MYSQL_TYPE_NULL), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}; +/* Don't use a static const variable here, as some C++ compilers (notably +HPUX aCC: HP ANSI C++ B3910B A.03.65) can't handle it. */ +#define END_OF_ST_FIELD_INFO \ + {STRUCT_FLD(field_name, NULL), \ + STRUCT_FLD(field_length, 0), \ + STRUCT_FLD(field_type, MYSQL_TYPE_NULL), \ + STRUCT_FLD(value, 0), \ + STRUCT_FLD(field_flags, 0), \ + STRUCT_FLD(old_name, ""), \ + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)} /* Use the following types mapping: diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h index b2d43ae3254..8e66dd50783 100644 --- a/storage/innobase/include/btr0cur.h +++ b/storage/innobase/include/btr0cur.h @@ -618,7 +618,7 @@ enum btr_cur_method { hash_node, and might be necessary to update */ BTR_CUR_BINARY, /*!< success using the binary search */ - BTR_CUR_INSERT_TO_IBUF, /*!< performed the intended insert to + BTR_CUR_INSERT_TO_IBUF /*!< performed the intended insert to the insert buffer */ }; diff --git a/storage/innobase/include/trx0types.h b/storage/innobase/include/trx0types.h index 08cc9622d02..e312efd0b50 100644 --- a/storage/innobase/include/trx0types.h +++ b/storage/innobase/include/trx0types.h @@ -70,7 +70,7 @@ typedef struct trx_named_savept_struct trx_named_savept_t; enum trx_rb_ctx { RB_NONE = 0, /*!< no rollback */ RB_NORMAL, /*!< normal rollback */ - RB_RECOVERY, /*!< rolling back an incomplete transaction, + RB_RECOVERY /*!< rolling back an incomplete transaction, in crash recovery */ }; diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 6bce6dd765e..023a6c9cd89 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -408,7 +408,8 @@ it is read. */ /* Minimize cache-miss latency by moving data at addr into a cache before it is read or written. */ # define UNIV_PREFETCH_RW(addr) __builtin_prefetch(addr, 1, 3) -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +/* Sun Studio includes sun_prefetch.h as of version 5.9 */ +#elif (defined(__SUNPRO_C) && __SUNPRO_C >= 0x590) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590) # include #if __SUNPRO_C >= 0x550 # undef UNIV_INTERN From eb26de2356fd53a7a799bf0d512dfe96766222cb Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Tue, 8 Sep 2009 15:48:55 +0200 Subject: [PATCH 099/138] The former "Instance Manager" (program "mysqlmanager") is not being built in 5.4.2-beta, so it cannot be included in a RPM: Remove both the program and the man page from the spec file. This patch was applied during the build of 5.4.2-beta. --- support-files/mysql.spec.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 778b04b30fe..6a0679bcfb3 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -453,11 +453,9 @@ rm -fr $RBR%{_datadir}/sql-bench # will appreciate that, as all services usually offer this. ln -s %{_sysconfdir}/init.d/mysql $RPM_BUILD_ROOT%{_sbindir}/rcmysql -# Touch the place where the my.cnf config file and mysqlmanager.passwd -# (MySQL Instance Manager password file) might be located +# Touch the place where the my.cnf config file might be located # Just to make sure it's in the file list and marked as a config file touch $RBR%{_sysconfdir}/my.cnf -touch $RBR%{_sysconfdir}/mysqlmanager.passwd %pre server # Check if we can safely upgrade. An upgrade is only safe if it's from one @@ -655,7 +653,6 @@ fi %doc %attr(644, root, man) %{_mandir}/man1/mysql_upgrade.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqlhotcopy.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqlman.1* -%doc %attr(644, root, man) %{_mandir}/man8/mysqlmanager.8* %doc %attr(644, root, man) %{_mandir}/man1/mysql.server.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqltest.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql_tzinfo_to_sql.1* @@ -665,7 +662,6 @@ fi %doc %attr(644, root, man) %{_mandir}/man1/replace.1* %ghost %config(noreplace,missingok) %{_sysconfdir}/my.cnf -%ghost %config(noreplace,missingok) %{_sysconfdir}/mysqlmanager.passwd %attr(755, root, root) %{_bindir}/innochecksum %attr(755, root, root) %{_bindir}/my_print_defaults @@ -695,7 +691,6 @@ fi %attr(755, root, root) %{_sbindir}/mysqld %attr(755, root, root) %{_sbindir}/mysqld-debug -%attr(755, root, root) %{_sbindir}/mysqlmanager %attr(755, root, root) %{_sbindir}/rcmysql %attr(644, root, root) %config(noreplace,missingok) %{_sysconfdir}/logrotate.d/mysql @@ -847,6 +842,11 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Thu Aug 27 2009 Joerg Bruehe + +- This version does not contain the "Instance manager", "mysqlmanager": + Remove it from the spec file so that packaging succeeds. + * Fri Nov 07 2008 Joerg Bruehe - Correct yesterday's fix, so that it also works for the last flag, From 36703050e8e5ef12dde3440864bc84cc0099944d Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Tue, 8 Sep 2009 16:10:06 +0200 Subject: [PATCH 100/138] Make sure that variables which are (or may be) used in an ".opt" file are defined to some value (even if it is empty). Without this, a test suite run aborted on Windows for "embedded". This fix was applied dusing the build of 5.4.2-beta. mysql-test/mysql-test-run.pl: From the code (function "envsubst()"), it is obvious that any variable which is used in an ".opt" file needs to be defined. If the value is wrong, starting the server may fail - but if the variable is undefined, the whole test suite will abort. So variables which are used in an ".opt" file should always be defined to some value, even if it is blank. This fix may be overkill, I did not check in detail whether all these variables are really used in an ".opt" file - but some are. --- mysql-test/mysql-test-run.pl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 7591e091992..cdc7dbb01cd 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1781,6 +1781,14 @@ sub environment_setup { $ENV{'HA_EXAMPLE_SO'}="'".$plugin_filename."'"; $ENV{'EXAMPLE_PLUGIN_LOAD'}="--plugin_load=;EXAMPLE=".$plugin_filename.";"; } + else + { + # Some ".opt" files use some of these variables, so they must be defined + $ENV{'EXAMPLE_PLUGIN'}= ""; + $ENV{'EXAMPLE_PLUGIN_OPT'}= ""; + $ENV{'HA_EXAMPLE_SO'}= ""; + $ENV{'EXAMPLE_PLUGIN_LOAD'}= ""; + } # ---------------------------------------------------- # Add the path where mysqld will find mypluglib.so From 24f103e39c100d0ca4fa4a4777fe82cd6d69034b Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 9 Sep 2009 12:06:15 +0300 Subject: [PATCH 101/138] Bug #45159 Part 1 : rejuvenate the jp test suite using normal run. Updates the results of all the out-dated test suites and adds the special mysqltest command to enable innodb for the tests that need it. --- mysql-test/suite/jp/r/jp_alter_sjis.result | 78 ++--- mysql-test/suite/jp/r/jp_alter_ucs2.result | 78 ++--- mysql-test/suite/jp/r/jp_alter_ujis.result | 78 ++--- mysql-test/suite/jp/r/jp_alter_utf8.result | 78 ++--- mysql-test/suite/jp/r/jp_convert_sjis.result | 12 + .../suite/jp/r/jp_create_db_sjis.result | 1 + .../suite/jp/r/jp_create_db_ucs2.result | 1 + .../suite/jp/r/jp_create_db_ujis.result | 1 + .../suite/jp/r/jp_create_db_utf8.result | 1 + .../suite/jp/r/jp_create_tbl_sjis.result | 78 ++++- .../suite/jp/r/jp_create_tbl_ucs2.result | 78 ++++- .../suite/jp/r/jp_create_tbl_ujis.result | 78 ++++- .../suite/jp/r/jp_create_tbl_utf8.result | 78 ++++- mysql-test/suite/jp/r/jp_enum_sjis.result | 60 ++-- mysql-test/suite/jp/r/jp_enum_ucs2.result | 6 +- mysql-test/suite/jp/r/jp_enum_ujis.result | 60 ++-- mysql-test/suite/jp/r/jp_enum_utf8.result | 60 ++-- mysql-test/suite/jp/r/jp_join_sjis.result | 288 +++++++++--------- mysql-test/suite/jp/r/jp_join_ucs2.result | 288 +++++++++--------- mysql-test/suite/jp/r/jp_join_ujis.result | 288 +++++++++--------- mysql-test/suite/jp/r/jp_join_utf8.result | 288 +++++++++--------- mysql-test/suite/jp/r/jp_select_sjis.result | 4 + mysql-test/suite/jp/t/jp_alter_sjis.test | 2 + mysql-test/suite/jp/t/jp_alter_ucs2.test | 2 + mysql-test/suite/jp/t/jp_alter_ujis.test | 2 + mysql-test/suite/jp/t/jp_alter_utf8.test | 2 + mysql-test/suite/jp/t/jp_charlength_sjis.test | 2 + mysql-test/suite/jp/t/jp_charlength_ucs2.test | 2 + mysql-test/suite/jp/t/jp_charlength_ujis.test | 2 + mysql-test/suite/jp/t/jp_charlength_utf8.test | 2 + mysql-test/suite/jp/t/jp_charset_sjis.test | 2 + mysql-test/suite/jp/t/jp_charset_ucs2.test | 2 + mysql-test/suite/jp/t/jp_charset_ujis.test | 2 + mysql-test/suite/jp/t/jp_charset_utf8.test | 2 + mysql-test/suite/jp/t/jp_convert_sjis.test | 2 + mysql-test/suite/jp/t/jp_convert_ucs2.test | 2 + mysql-test/suite/jp/t/jp_convert_ujis.test | 2 + mysql-test/suite/jp/t/jp_convert_utf8.test | 2 + mysql-test/suite/jp/t/jp_create_tbl_sjis.test | 2 + mysql-test/suite/jp/t/jp_create_tbl_ucs2.test | 2 + mysql-test/suite/jp/t/jp_create_tbl_ujis.test | 2 + mysql-test/suite/jp/t/jp_create_tbl_utf8.test | 2 + mysql-test/suite/jp/t/jp_enum_sjis.test | 2 + mysql-test/suite/jp/t/jp_enum_ucs2.test | 2 + mysql-test/suite/jp/t/jp_enum_ujis.test | 2 + mysql-test/suite/jp/t/jp_enum_utf8.test | 2 + mysql-test/suite/jp/t/jp_insert_sjis.test | 2 + mysql-test/suite/jp/t/jp_insert_ucs2.test | 2 + mysql-test/suite/jp/t/jp_insert_ujis.test | 2 + mysql-test/suite/jp/t/jp_insert_utf8.test | 2 + mysql-test/suite/jp/t/jp_instr_sjis.test | 2 + mysql-test/suite/jp/t/jp_instr_ucs2.test | 2 + mysql-test/suite/jp/t/jp_instr_ujis.test | 2 + mysql-test/suite/jp/t/jp_instr_utf8.test | 2 + mysql-test/suite/jp/t/jp_join_sjis.test | 1 + mysql-test/suite/jp/t/jp_join_ucs2.test | 1 + mysql-test/suite/jp/t/jp_join_ujis.test | 1 + mysql-test/suite/jp/t/jp_join_utf8.test | 1 + mysql-test/suite/jp/t/jp_left_sjis.test | 2 + mysql-test/suite/jp/t/jp_left_ucs2.test | 2 + mysql-test/suite/jp/t/jp_left_ujis.test | 2 + mysql-test/suite/jp/t/jp_left_utf8.test | 2 + mysql-test/suite/jp/t/jp_length_sjis.test | 2 + mysql-test/suite/jp/t/jp_length_ucs2.test | 2 + mysql-test/suite/jp/t/jp_length_ujis.test | 2 + mysql-test/suite/jp/t/jp_length_utf8.test | 2 + mysql-test/suite/jp/t/jp_like_sjis.test | 2 + mysql-test/suite/jp/t/jp_like_ucs2.test | 2 + mysql-test/suite/jp/t/jp_like_ujis.test | 2 + mysql-test/suite/jp/t/jp_like_utf8.test | 2 + mysql-test/suite/jp/t/jp_locate_sjis.test | 2 + mysql-test/suite/jp/t/jp_locate_ucs2.test | 2 + mysql-test/suite/jp/t/jp_locate_ujis.test | 2 + mysql-test/suite/jp/t/jp_locate_utf8.test | 2 + mysql-test/suite/jp/t/jp_lpad_sjis.test | 2 + mysql-test/suite/jp/t/jp_lpad_ucs2.test | 2 + mysql-test/suite/jp/t/jp_lpad_ujis.test | 2 + mysql-test/suite/jp/t/jp_lpad_utf8.test | 2 + mysql-test/suite/jp/t/jp_ltrim_sjis.test | 2 + mysql-test/suite/jp/t/jp_ltrim_ucs2.test | 2 + mysql-test/suite/jp/t/jp_ltrim_ujis.test | 2 + mysql-test/suite/jp/t/jp_ltrim_utf8.test | 2 + mysql-test/suite/jp/t/jp_ps_sjis.test | 2 + mysql-test/suite/jp/t/jp_ps_ujis.test | 2 + mysql-test/suite/jp/t/jp_replace_sjis.test | 2 + mysql-test/suite/jp/t/jp_replace_ucs2.test | 2 + mysql-test/suite/jp/t/jp_replace_ujis.test | 2 + mysql-test/suite/jp/t/jp_replace_utf8.test | 2 + mysql-test/suite/jp/t/jp_reverse_sjis.test | 2 + mysql-test/suite/jp/t/jp_reverse_ucs2.test | 2 + mysql-test/suite/jp/t/jp_reverse_ujis.test | 2 + mysql-test/suite/jp/t/jp_reverse_utf8.test | 2 + mysql-test/suite/jp/t/jp_right_sjis.test | 2 + mysql-test/suite/jp/t/jp_right_ucs2.test | 2 + mysql-test/suite/jp/t/jp_right_ujis.test | 2 + mysql-test/suite/jp/t/jp_right_utf8.test | 2 + mysql-test/suite/jp/t/jp_rpad_sjis.test | 2 + mysql-test/suite/jp/t/jp_rpad_ucs2.test | 2 + mysql-test/suite/jp/t/jp_rpad_ujis.test | 2 + mysql-test/suite/jp/t/jp_rpad_utf8.test | 2 + mysql-test/suite/jp/t/jp_rtrim_sjis.test | 2 + mysql-test/suite/jp/t/jp_rtrim_ucs2.test | 2 + mysql-test/suite/jp/t/jp_rtrim_ujis.test | 2 + mysql-test/suite/jp/t/jp_rtrim_utf8.test | 2 + mysql-test/suite/jp/t/jp_select_sjis.test | 2 + mysql-test/suite/jp/t/jp_select_ucs2.test | 2 + mysql-test/suite/jp/t/jp_select_ujis.test | 2 + mysql-test/suite/jp/t/jp_select_utf8.test | 2 + mysql-test/suite/jp/t/jp_subquery_sjis.test | 1 + mysql-test/suite/jp/t/jp_subquery_ucs2.test | 1 + mysql-test/suite/jp/t/jp_subquery_ujis.test | 1 + mysql-test/suite/jp/t/jp_subquery_utf8.test | 1 + mysql-test/suite/jp/t/jp_substring_sjis.test | 2 + mysql-test/suite/jp/t/jp_substring_ucs2.test | 2 + mysql-test/suite/jp/t/jp_substring_ujis.test | 2 + mysql-test/suite/jp/t/jp_substring_utf8.test | 2 + mysql-test/suite/jp/t/jp_trim_sjis.test | 2 + mysql-test/suite/jp/t/jp_trim_ucs2.test | 2 + mysql-test/suite/jp/t/jp_trim_ujis.test | 2 + mysql-test/suite/jp/t/jp_trim_utf8.test | 2 + mysql-test/suite/jp/t/jp_union_ujis.test | 2 + mysql-test/suite/jp/t/jp_update_sjis.test | 2 + mysql-test/suite/jp/t/jp_update_ucs2.test | 2 + mysql-test/suite/jp/t/jp_update_ujis.test | 2 + mysql-test/suite/jp/t/jp_update_utf8.test | 2 + mysql-test/suite/jp/t/jp_where_sjis.test | 2 + mysql-test/suite/jp/t/jp_where_ucs2.test | 2 + mysql-test/suite/jp/t/jp_where_ujis.test | 2 + mysql-test/suite/jp/t/jp_where_utf8.test | 2 + 129 files changed, 1303 insertions(+), 885 deletions(-) diff --git a/mysql-test/suite/jp/r/jp_alter_sjis.result b/mysql-test/suite/jp/r/jp_alter_sjis.result index f970508229a..32ae7d5729d 100644 --- a/mysql-test/suite/jp/r/jp_alter_sjis.result +++ b/mysql-test/suite/jp/r/jp_alter_sjis.result @@ -31,8 +31,8 @@ NULL DESC `±±±`; Field Type Null Key Default Extra ¶¶ char(1) YES MUL NULL -··· char(6) PRI -¸¸¸ char(1) YES MUL NULL +··· char(6) NO PRI +¸¸¸ char(1) YES UNI NULL ¹¹¹ char(1) YES NULL SHOW CREATE TABLE `±±±`; Table Create Table @@ -58,7 +58,7 @@ SELECT * FROM ` ³³³³³ DESC `±±±`; Field Type Null Key Default Extra -··· char(6) +··· char(6) NO SHOW CREATE TABLE `±±±`; Table Create Table ±±± CREATE TABLE `±±±` ( @@ -80,8 +80,8 @@ NULL DESC `‚ ‚ ‚ `; Field Type Null Key Default Extra ‚©‚© char(1) YES MUL NULL -‚«‚«‚« char(6) PRI -‚­‚­‚­ char(1) YES MUL NULL +‚«‚«‚« char(6) NO PRI +‚­‚­‚­ char(1) YES UNI NULL ‚¯‚¯‚¯ char(1) YES NULL SHOW CREATE TABLE `‚ ‚ ‚ `; Table Create Table @@ -107,7 +107,7 @@ SELECT * FROM ` ‚¤‚¤‚¤‚¤‚¤ DESC `‚ ‚ ‚ `; Field Type Null Key Default Extra -‚«‚«‚« char(6) +‚«‚«‚« char(6) NO SHOW CREATE TABLE `‚ ‚ ‚ `; Table Create Table ‚ ‚ ‚  CREATE TABLE `‚ ‚ ‚ ` ( @@ -129,8 +129,8 @@ NULL DESC `ƒ\ƒ\ƒ\`; Field Type Null Key Default Extra \\ char(1) YES MUL NULL -•\•\•\ char(6) PRI -”\”\”\ char(1) YES MUL NULL +•\•\•\ char(6) NO PRI +”\”\”\ char(1) YES UNI NULL —\—\—\ char(1) YES NULL SHOW CREATE TABLE `ƒ\ƒ\ƒ\`; Table Create Table @@ -156,7 +156,7 @@ SELECT * FROM ` •\•\•\•\•\ DESC `ƒ\ƒ\ƒ\`; Field Type Null Key Default Extra -•\•\•\ char(6) +•\•\•\ char(6) NO SHOW CREATE TABLE `ƒ\ƒ\ƒ\`; Table Create Table ƒ\ƒ\ƒ\ CREATE TABLE `ƒ\ƒ\ƒ\` ( @@ -193,8 +193,8 @@ NULL DESC `±±±`; Field Type Null Key Default Extra ¶¶ char(1) YES MUL NULL -··· char(6) PRI -¸¸¸ char(1) YES MUL NULL +··· char(6) NO PRI +¸¸¸ char(1) YES UNI NULL ¹¹¹ char(1) YES NULL SHOW CREATE TABLE `±±±`; Table Create Table @@ -220,7 +220,7 @@ SELECT * FROM ` ³³³³³ DESC `±±±`; Field Type Null Key Default Extra -··· char(6) +··· char(6) NO SHOW CREATE TABLE `±±±`; Table Create Table ±±± CREATE TABLE `±±±` ( @@ -242,8 +242,8 @@ NULL DESC `‚ ‚ ‚ `; Field Type Null Key Default Extra ‚©‚© char(1) YES MUL NULL -‚«‚«‚« char(6) PRI -‚­‚­‚­ char(1) YES MUL NULL +‚«‚«‚« char(6) NO PRI +‚­‚­‚­ char(1) YES UNI NULL ‚¯‚¯‚¯ char(1) YES NULL SHOW CREATE TABLE `‚ ‚ ‚ `; Table Create Table @@ -269,7 +269,7 @@ SELECT * FROM ` ‚¤‚¤‚¤‚¤‚¤ DESC `‚ ‚ ‚ `; Field Type Null Key Default Extra -‚«‚«‚« char(6) +‚«‚«‚« char(6) NO SHOW CREATE TABLE `‚ ‚ ‚ `; Table Create Table ‚ ‚ ‚  CREATE TABLE `‚ ‚ ‚ ` ( @@ -291,8 +291,8 @@ NULL DESC `ƒ\ƒ\ƒ\`; Field Type Null Key Default Extra \\ char(1) YES MUL NULL -•\•\•\ char(6) PRI -”\”\”\ char(1) YES MUL NULL +•\•\•\ char(6) NO PRI +”\”\”\ char(1) YES UNI NULL —\—\—\ char(1) YES NULL SHOW CREATE TABLE `ƒ\ƒ\ƒ\`; Table Create Table @@ -318,7 +318,7 @@ SELECT * FROM ` ”\”\”\”\”\ DESC `ƒ\ƒ\ƒ\`; Field Type Null Key Default Extra -•\•\•\ char(6) +•\•\•\ char(6) NO SHOW CREATE TABLE `ƒ\ƒ\ƒ\`; Table Create Table ƒ\ƒ\ƒ\ CREATE TABLE `ƒ\ƒ\ƒ\` ( @@ -355,8 +355,8 @@ NULL DESC `±±±`; Field Type Null Key Default Extra ¶¶ char(1) YES MUL NULL -··· char(6) PRI -¸¸¸ char(1) YES MUL NULL +··· char(6) NO PRI +¸¸¸ char(1) YES UNI NULL ¹¹¹ char(1) YES NULL SHOW CREATE TABLE `±±±`; Table Create Table @@ -368,7 +368,7 @@ Table Create Table PRIMARY KEY (`···`), UNIQUE KEY `¸¸¸` (`¸¸¸`), KEY `¶¶¶` (`¶¶`) -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis ALTER TABLE `±±±` DROP INDEX `¶¶¶`; ALTER TABLE `±±±` DROP PRIMARY KEY; ALTER TABLE `±±±` DROP INDEX `¸¸¸`; @@ -382,12 +382,12 @@ SELECT * FROM ` ³³³³³ DESC `±±±`; Field Type Null Key Default Extra -··· char(6) +··· char(6) NO SHOW CREATE TABLE `±±±`; Table Create Table ±±± CREATE TABLE `±±±` ( `···` char(6) NOT NULL default '' -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis ALTER TABLE `‚ ‚ ‚ ` ADD `‚©‚©‚©` char(1) FIRST; ALTER TABLE `‚ ‚ ‚ ` ADD `‚­‚­‚­` char(1) AFTER `‚«‚«‚«`; ALTER TABLE `‚ ‚ ‚ ` ADD `‚¯‚¯‚¯` char(1); @@ -404,8 +404,8 @@ NULL DESC `‚ ‚ ‚ `; Field Type Null Key Default Extra ‚©‚© char(1) YES MUL NULL -‚«‚«‚« char(6) PRI -‚­‚­‚­ char(1) YES MUL NULL +‚«‚«‚« char(6) NO PRI +‚­‚­‚­ char(1) YES UNI NULL ‚¯‚¯‚¯ char(1) YES NULL SHOW CREATE TABLE `‚ ‚ ‚ `; Table Create Table @@ -417,7 +417,7 @@ Table Create Table PRIMARY KEY (`‚«‚«‚«`), UNIQUE KEY `‚­‚­‚­` (`‚­‚­‚­`), KEY `‚©‚©‚©` (`‚©‚©`) -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis ALTER TABLE `‚ ‚ ‚ ` DROP INDEX `‚©‚©‚©`; ALTER TABLE `‚ ‚ ‚ ` DROP PRIMARY KEY; ALTER TABLE `‚ ‚ ‚ ` DROP INDEX `‚­‚­‚­`; @@ -431,12 +431,12 @@ SELECT * FROM ` ‚¤‚¤‚¤‚¤‚¤ DESC `‚ ‚ ‚ `; Field Type Null Key Default Extra -‚«‚«‚« char(6) +‚«‚«‚« char(6) NO SHOW CREATE TABLE `‚ ‚ ‚ `; Table Create Table ‚ ‚ ‚  CREATE TABLE `‚ ‚ ‚ ` ( `‚«‚«‚«` char(6) NOT NULL default '' -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis ALTER TABLE `ƒ\ƒ\ƒ\` ADD `\\\` char(1) FIRST; ALTER TABLE `ƒ\ƒ\ƒ\` ADD `”\”\”\` char(1) AFTER `•\•\•\`; ALTER TABLE `ƒ\ƒ\ƒ\` ADD `—\—\—\` char(1); @@ -453,8 +453,8 @@ NULL DESC `ƒ\ƒ\ƒ\`; Field Type Null Key Default Extra \\ char(1) YES MUL NULL -•\•\•\ char(6) PRI -”\”\”\ char(1) YES MUL NULL +•\•\•\ char(6) NO PRI +”\”\”\ char(1) YES UNI NULL —\—\—\ char(1) YES NULL SHOW CREATE TABLE `ƒ\ƒ\ƒ\`; Table Create Table @@ -466,7 +466,7 @@ Table Create Table PRIMARY KEY (`•\•\•\`), UNIQUE KEY `”\”\”\` (`”\”\”\`), KEY `\\\` (`\\`) -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis ALTER TABLE `ƒ\ƒ\ƒ\` DROP INDEX `\\\`; ALTER TABLE `ƒ\ƒ\ƒ\` DROP PRIMARY KEY; ALTER TABLE `ƒ\ƒ\ƒ\` DROP INDEX `”\”\”\`; @@ -480,12 +480,12 @@ SELECT * FROM ` ”\”\”\”\”\ DESC `ƒ\ƒ\ƒ\`; Field Type Null Key Default Extra -•\•\•\ char(6) +•\•\•\ char(6) NO SHOW CREATE TABLE `ƒ\ƒ\ƒ\`; Table Create Table ƒ\ƒ\ƒ\ CREATE TABLE `ƒ\ƒ\ƒ\` ( `•\•\•\` char(6) NOT NULL default '' -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis DROP TABLE `±±±`; DROP TABLE `²²²`; DROP TABLE `‚ ‚ ‚ `; @@ -516,7 +516,7 @@ NULL DESC `±±±`; Field Type Null Key Default Extra ¶¶ char(1) YES MUL NULL -··· char(6) PRI +··· char(6) NO PRI ¸¸¸ char(1) YES NULL ¹¹¹ char(1) YES NULL SHOW CREATE TABLE `±±±`; @@ -541,7 +541,7 @@ SELECT * FROM ` ³³³³³ DESC `±±±`; Field Type Null Key Default Extra -··· char(6) +··· char(6) NO SHOW CREATE TABLE `±±±`; Table Create Table ±±± CREATE TABLE `±±±` ( @@ -562,7 +562,7 @@ NULL DESC `‚ ‚ ‚ `; Field Type Null Key Default Extra ‚©‚© char(1) YES MUL NULL -‚«‚«‚« char(6) PRI +‚«‚«‚« char(6) NO PRI ‚­‚­‚­ char(1) YES NULL ‚¯‚¯‚¯ char(1) YES NULL SHOW CREATE TABLE `‚ ‚ ‚ `; @@ -587,7 +587,7 @@ SELECT * FROM ` ‚¤‚¤‚¤‚¤‚¤ DESC `‚ ‚ ‚ `; Field Type Null Key Default Extra -‚«‚«‚« char(6) +‚«‚«‚« char(6) NO SHOW CREATE TABLE `‚ ‚ ‚ `; Table Create Table ‚ ‚ ‚  CREATE TABLE `‚ ‚ ‚ ` ( @@ -608,7 +608,7 @@ NULL DESC `ƒ\ƒ\ƒ\`; Field Type Null Key Default Extra \\ char(1) YES MUL NULL -•\•\•\ char(6) PRI +•\•\•\ char(6) NO PRI ”\”\”\ char(1) YES NULL —\—\—\ char(1) YES NULL SHOW CREATE TABLE `ƒ\ƒ\ƒ\`; @@ -633,7 +633,7 @@ SELECT * FROM ` •\•\•\•\•\ DESC `ƒ\ƒ\ƒ\`; Field Type Null Key Default Extra -•\•\•\ char(6) +•\•\•\ char(6) NO SHOW CREATE TABLE `ƒ\ƒ\ƒ\`; Table Create Table ƒ\ƒ\ƒ\ CREATE TABLE `ƒ\ƒ\ƒ\` ( diff --git a/mysql-test/suite/jp/r/jp_alter_ucs2.result b/mysql-test/suite/jp/r/jp_alter_ucs2.result index 2756e5a758d..746dfdd62cc 100644 --- a/mysql-test/suite/jp/r/jp_alter_ucs2.result +++ b/mysql-test/suite/jp/r/jp_alter_ucs2.result @@ -32,8 +32,8 @@ NULL DESC `ޱޱޱ`; Field Type Null Key Default Extra ޶޶ char(1) YES MUL NULL -Ž·Ž·Ž· char(6) PRI -ޏޏޏ char(1) YES MUL NULL +Ž·Ž·Ž· char(6) NO PRI +ޏޏޏ char(1) YES UNI NULL ޹޹޹ char(1) YES NULL SHOW CREATE TABLE `ޱޱޱ`; Table Create Table @@ -59,7 +59,7 @@ SELECT * FROM ` ޳޳޳޳޳ DESC `ޱޱޱ`; Field Type Null Key Default Extra -Ž·Ž·Ž· char(6) +Ž·Ž·Ž· char(6) NO SHOW CREATE TABLE `ޱޱޱ`; Table Create Table ޱޱޱ CREATE TABLE `ޱޱޱ` ( @@ -81,8 +81,8 @@ NULL DESC `¤¢¤¢¤¢`; Field Type Null Key Default Extra ¤«¤« char(1) YES MUL NULL -¤­¤­¤­ char(6) PRI -¤¯¤¯¤¯ char(1) YES MUL NULL +¤­¤­¤­ char(6) NO PRI +¤¯¤¯¤¯ char(1) YES UNI NULL ¤±¤±¤± char(1) YES NULL SHOW CREATE TABLE `¤¢¤¢¤¢`; Table Create Table @@ -108,7 +108,7 @@ SELECT * FROM ` ¤¦¤¦¤¦¤¦¤¦ DESC `¤¢¤¢¤¢`; Field Type Null Key Default Extra -¤­¤­¤­ char(6) +¤­¤­¤­ char(6) NO SHOW CREATE TABLE `¤¢¤¢¤¢`; Table Create Table ¤¢¤¢¤¢ CREATE TABLE `¤¢¤¢¤¢` ( @@ -130,8 +130,8 @@ NULL DESC `íÝíÝíÝ`; Field Type Null Key Default Extra °¢°¢ char(1) YES MUL NULL -°¡°¡°¡ char(6) PRI -°£°£°£ char(1) YES MUL NULL +°¡°¡°¡ char(6) NO PRI +°£°£°£ char(1) YES UNI NULL °´°´°´ char(1) YES NULL SHOW CREATE TABLE `íÝíÝíÝ`; Table Create Table @@ -157,7 +157,7 @@ SELECT * FROM ` °£°£°£°£°£ DESC `íÝíÝíÝ`; Field Type Null Key Default Extra -°¡°¡°¡ char(6) +°¡°¡°¡ char(6) NO SHOW CREATE TABLE `íÝíÝíÝ`; Table Create Table íÝíÝíÝ CREATE TABLE `íÝíÝíÝ` ( @@ -194,8 +194,8 @@ NULL DESC `ޱޱޱ`; Field Type Null Key Default Extra ޶޶ char(1) YES MUL NULL -Ž·Ž·Ž· char(6) PRI -ޏޏޏ char(1) YES MUL NULL +Ž·Ž·Ž· char(6) NO PRI +ޏޏޏ char(1) YES UNI NULL ޹޹޹ char(1) YES NULL SHOW CREATE TABLE `ޱޱޱ`; Table Create Table @@ -221,7 +221,7 @@ SELECT * FROM ` ޳޳޳޳޳ DESC `ޱޱޱ`; Field Type Null Key Default Extra -Ž·Ž·Ž· char(6) +Ž·Ž·Ž· char(6) NO SHOW CREATE TABLE `ޱޱޱ`; Table Create Table ޱޱޱ CREATE TABLE `ޱޱޱ` ( @@ -243,8 +243,8 @@ NULL DESC `¤¢¤¢¤¢`; Field Type Null Key Default Extra ¤«¤« char(1) YES MUL NULL -¤­¤­¤­ char(6) PRI -¤¯¤¯¤¯ char(1) YES MUL NULL +¤­¤­¤­ char(6) NO PRI +¤¯¤¯¤¯ char(1) YES UNI NULL ¤±¤±¤± char(1) YES NULL SHOW CREATE TABLE `¤¢¤¢¤¢`; Table Create Table @@ -270,7 +270,7 @@ SELECT * FROM ` ¤¦¤¦¤¦¤¦¤¦ DESC `¤¢¤¢¤¢`; Field Type Null Key Default Extra -¤­¤­¤­ char(6) +¤­¤­¤­ char(6) NO SHOW CREATE TABLE `¤¢¤¢¤¢`; Table Create Table ¤¢¤¢¤¢ CREATE TABLE `¤¢¤¢¤¢` ( @@ -292,8 +292,8 @@ NULL DESC `íÝíÝíÝ`; Field Type Null Key Default Extra °¢°¢ char(1) YES MUL NULL -°¡°¡°¡ char(6) PRI -°£°£°£ char(1) YES MUL NULL +°¡°¡°¡ char(6) NO PRI +°£°£°£ char(1) YES UNI NULL °´°´°´ char(1) YES NULL SHOW CREATE TABLE `íÝíÝíÝ`; Table Create Table @@ -319,7 +319,7 @@ SELECT * FROM ` °£°£°£°£°£ DESC `íÝíÝíÝ`; Field Type Null Key Default Extra -°¡°¡°¡ char(6) +°¡°¡°¡ char(6) NO SHOW CREATE TABLE `íÝíÝíÝ`; Table Create Table íÝíÝíÝ CREATE TABLE `íÝíÝíÝ` ( @@ -356,8 +356,8 @@ NULL DESC `ޱޱޱ`; Field Type Null Key Default Extra ޶޶ char(1) YES MUL NULL -Ž·Ž·Ž· char(6) PRI -ޏޏޏ char(1) YES MUL NULL +Ž·Ž·Ž· char(6) NO PRI +ޏޏޏ char(1) YES UNI NULL ޹޹޹ char(1) YES NULL SHOW CREATE TABLE `ޱޱޱ`; Table Create Table @@ -369,7 +369,7 @@ Table Create Table PRIMARY KEY (`Ž·Ž·Ž·`), UNIQUE KEY `ޏޏޏ` (`ޏޏޏ`), KEY `޶޶޶` (`޶޶`) -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 ALTER TABLE `ޱޱޱ` DROP INDEX `޶޶޶`; ALTER TABLE `ޱޱޱ` DROP PRIMARY KEY; ALTER TABLE `ޱޱޱ` DROP INDEX `ޏޏޏ`; @@ -383,12 +383,12 @@ SELECT * FROM ` ޳޳޳޳޳ DESC `ޱޱޱ`; Field Type Null Key Default Extra -Ž·Ž·Ž· char(6) +Ž·Ž·Ž· char(6) NO SHOW CREATE TABLE `ޱޱޱ`; Table Create Table ޱޱޱ CREATE TABLE `ޱޱޱ` ( `Ž·Ž·Ž·` char(6) NOT NULL default '' -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 ALTER TABLE `¤¢¤¢¤¢` ADD `¤«¤«¤«` char(1) FIRST; ALTER TABLE `¤¢¤¢¤¢` ADD `¤¯¤¯¤¯` char(1) AFTER `¤­¤­¤­`; ALTER TABLE `¤¢¤¢¤¢` ADD `¤±¤±¤±` char(1); @@ -405,8 +405,8 @@ NULL DESC `¤¢¤¢¤¢`; Field Type Null Key Default Extra ¤«¤« char(1) YES MUL NULL -¤­¤­¤­ char(6) PRI -¤¯¤¯¤¯ char(1) YES MUL NULL +¤­¤­¤­ char(6) NO PRI +¤¯¤¯¤¯ char(1) YES UNI NULL ¤±¤±¤± char(1) YES NULL SHOW CREATE TABLE `¤¢¤¢¤¢`; Table Create Table @@ -418,7 +418,7 @@ Table Create Table PRIMARY KEY (`¤­¤­¤­`), UNIQUE KEY `¤¯¤¯¤¯` (`¤¯¤¯¤¯`), KEY `¤«¤«¤«` (`¤«¤«`) -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 ALTER TABLE `¤¢¤¢¤¢` DROP INDEX `¤«¤«¤«`; ALTER TABLE `¤¢¤¢¤¢` DROP PRIMARY KEY; ALTER TABLE `¤¢¤¢¤¢` DROP INDEX `¤¯¤¯¤¯`; @@ -432,12 +432,12 @@ SELECT * FROM ` ¤¦¤¦¤¦¤¦¤¦ DESC `¤¢¤¢¤¢`; Field Type Null Key Default Extra -¤­¤­¤­ char(6) +¤­¤­¤­ char(6) NO SHOW CREATE TABLE `¤¢¤¢¤¢`; Table Create Table ¤¢¤¢¤¢ CREATE TABLE `¤¢¤¢¤¢` ( `¤­¤­¤­` char(6) NOT NULL default '' -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 ALTER TABLE `íÝíÝíÝ` ADD `°¢°¢°¢` char(1) FIRST; ALTER TABLE `íÝíÝíÝ` ADD `°£°£°£` char(1) AFTER `°¡°¡°¡`; ALTER TABLE `íÝíÝíÝ` ADD `°´°´°´` char(1); @@ -454,8 +454,8 @@ NULL DESC `íÝíÝíÝ`; Field Type Null Key Default Extra °¢°¢ char(1) YES MUL NULL -°¡°¡°¡ char(6) PRI -°£°£°£ char(1) YES MUL NULL +°¡°¡°¡ char(6) NO PRI +°£°£°£ char(1) YES UNI NULL °´°´°´ char(1) YES NULL SHOW CREATE TABLE `íÝíÝíÝ`; Table Create Table @@ -467,7 +467,7 @@ Table Create Table PRIMARY KEY (`°¡°¡°¡`), UNIQUE KEY `°£°£°£` (`°£°£°£`), KEY `°¢°¢°¢` (`°¢°¢`) -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 ALTER TABLE `íÝíÝíÝ` DROP INDEX `°¢°¢°¢`; ALTER TABLE `íÝíÝíÝ` DROP PRIMARY KEY; ALTER TABLE `íÝíÝíÝ` DROP INDEX `°£°£°£`; @@ -481,12 +481,12 @@ SELECT * FROM ` °£°£°£°£°£ DESC `íÝíÝíÝ`; Field Type Null Key Default Extra -°¡°¡°¡ char(6) +°¡°¡°¡ char(6) NO SHOW CREATE TABLE `íÝíÝíÝ`; Table Create Table íÝíÝíÝ CREATE TABLE `íÝíÝíÝ` ( `°¡°¡°¡` char(6) NOT NULL default '' -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 DROP TABLE `ޱޱޱ`; DROP TABLE `޲޲޲`; DROP TABLE `¤¢¤¢¤¢`; @@ -517,7 +517,7 @@ NULL DESC `ޱޱޱ`; Field Type Null Key Default Extra ޶޶ char(1) YES MUL NULL -Ž·Ž·Ž· char(6) PRI +Ž·Ž·Ž· char(6) NO PRI ޏޏޏ char(1) YES NULL ޹޹޹ char(1) YES NULL SHOW CREATE TABLE `ޱޱޱ`; @@ -542,7 +542,7 @@ SELECT * FROM ` ޳޳޳޳޳ DESC `ޱޱޱ`; Field Type Null Key Default Extra -Ž·Ž·Ž· char(6) +Ž·Ž·Ž· char(6) NO SHOW CREATE TABLE `ޱޱޱ`; Table Create Table ޱޱޱ CREATE TABLE `ޱޱޱ` ( @@ -563,7 +563,7 @@ NULL DESC `¤¢¤¢¤¢`; Field Type Null Key Default Extra ¤«¤« char(1) YES MUL NULL -¤­¤­¤­ char(6) PRI +¤­¤­¤­ char(6) NO PRI ¤¯¤¯¤¯ char(1) YES NULL ¤±¤±¤± char(1) YES NULL SHOW CREATE TABLE `¤¢¤¢¤¢`; @@ -588,7 +588,7 @@ SELECT * FROM ` ¤¦¤¦¤¦¤¦¤¦ DESC `¤¢¤¢¤¢`; Field Type Null Key Default Extra -¤­¤­¤­ char(6) +¤­¤­¤­ char(6) NO SHOW CREATE TABLE `¤¢¤¢¤¢`; Table Create Table ¤¢¤¢¤¢ CREATE TABLE `¤¢¤¢¤¢` ( @@ -609,7 +609,7 @@ NULL DESC `íÝíÝíÝ`; Field Type Null Key Default Extra °¢°¢ char(1) YES MUL NULL -°¡°¡°¡ char(6) PRI +°¡°¡°¡ char(6) NO PRI °£°£°£ char(1) YES NULL °´°´°´ char(1) YES NULL SHOW CREATE TABLE `íÝíÝíÝ`; @@ -634,7 +634,7 @@ SELECT * FROM ` °£°£°£°£°£ DESC `íÝíÝíÝ`; Field Type Null Key Default Extra -°¡°¡°¡ char(6) +°¡°¡°¡ char(6) NO SHOW CREATE TABLE `íÝíÝíÝ`; Table Create Table íÝíÝíÝ CREATE TABLE `íÝíÝíÝ` ( diff --git a/mysql-test/suite/jp/r/jp_alter_ujis.result b/mysql-test/suite/jp/r/jp_alter_ujis.result index afa3c79cbce..daea68caa3f 100644 --- a/mysql-test/suite/jp/r/jp_alter_ujis.result +++ b/mysql-test/suite/jp/r/jp_alter_ujis.result @@ -31,8 +31,8 @@ NULL DESC `ޱޱޱ`; Field Type Null Key Default Extra ޶޶ char(1) YES MUL NULL -Ž·Ž·Ž· char(6) PRI -ޏޏޏ char(1) YES MUL NULL +Ž·Ž·Ž· char(6) NO PRI +ޏޏޏ char(1) YES UNI NULL ޹޹޹ char(1) YES NULL SHOW CREATE TABLE `ޱޱޱ`; Table Create Table @@ -58,7 +58,7 @@ SELECT * FROM ` ޳޳޳޳޳ DESC `ޱޱޱ`; Field Type Null Key Default Extra -Ž·Ž·Ž· char(6) +Ž·Ž·Ž· char(6) NO SHOW CREATE TABLE `ޱޱޱ`; Table Create Table ޱޱޱ CREATE TABLE `ޱޱޱ` ( @@ -80,8 +80,8 @@ NULL DESC `¤¢¤¢¤¢`; Field Type Null Key Default Extra ¤«¤« char(1) YES MUL NULL -¤­¤­¤­ char(6) PRI -¤¯¤¯¤¯ char(1) YES MUL NULL +¤­¤­¤­ char(6) NO PRI +¤¯¤¯¤¯ char(1) YES UNI NULL ¤±¤±¤± char(1) YES NULL SHOW CREATE TABLE `¤¢¤¢¤¢`; Table Create Table @@ -107,7 +107,7 @@ SELECT * FROM ` ¤¦¤¦¤¦¤¦¤¦ DESC `¤¢¤¢¤¢`; Field Type Null Key Default Extra -¤­¤­¤­ char(6) +¤­¤­¤­ char(6) NO SHOW CREATE TABLE `¤¢¤¢¤¢`; Table Create Table ¤¢¤¢¤¢ CREATE TABLE `¤¢¤¢¤¢` ( @@ -129,8 +129,8 @@ NULL DESC `íÝíÝíÝ`; Field Type Null Key Default Extra °¢°¢ char(1) YES MUL NULL -°¡°¡°¡ char(6) PRI -°£°£°£ char(1) YES MUL NULL +°¡°¡°¡ char(6) NO PRI +°£°£°£ char(1) YES UNI NULL °´°´°´ char(1) YES NULL SHOW CREATE TABLE `íÝíÝíÝ`; Table Create Table @@ -156,7 +156,7 @@ SELECT * FROM ` °£°£°£°£°£ DESC `íÝíÝíÝ`; Field Type Null Key Default Extra -°¡°¡°¡ char(6) +°¡°¡°¡ char(6) NO SHOW CREATE TABLE `íÝíÝíÝ`; Table Create Table íÝíÝíÝ CREATE TABLE `íÝíÝíÝ` ( @@ -193,8 +193,8 @@ NULL DESC `ޱޱޱ`; Field Type Null Key Default Extra ޶޶ char(1) YES MUL NULL -Ž·Ž·Ž· char(6) PRI -ޏޏޏ char(1) YES MUL NULL +Ž·Ž·Ž· char(6) NO PRI +ޏޏޏ char(1) YES UNI NULL ޹޹޹ char(1) YES NULL SHOW CREATE TABLE `ޱޱޱ`; Table Create Table @@ -220,7 +220,7 @@ SELECT * FROM ` ޳޳޳޳޳ DESC `ޱޱޱ`; Field Type Null Key Default Extra -Ž·Ž·Ž· char(6) +Ž·Ž·Ž· char(6) NO SHOW CREATE TABLE `ޱޱޱ`; Table Create Table ޱޱޱ CREATE TABLE `ޱޱޱ` ( @@ -242,8 +242,8 @@ NULL DESC `¤¢¤¢¤¢`; Field Type Null Key Default Extra ¤«¤« char(1) YES MUL NULL -¤­¤­¤­ char(6) PRI -¤¯¤¯¤¯ char(1) YES MUL NULL +¤­¤­¤­ char(6) NO PRI +¤¯¤¯¤¯ char(1) YES UNI NULL ¤±¤±¤± char(1) YES NULL SHOW CREATE TABLE `¤¢¤¢¤¢`; Table Create Table @@ -269,7 +269,7 @@ SELECT * FROM ` ¤¦¤¦¤¦¤¦¤¦ DESC `¤¢¤¢¤¢`; Field Type Null Key Default Extra -¤­¤­¤­ char(6) +¤­¤­¤­ char(6) NO SHOW CREATE TABLE `¤¢¤¢¤¢`; Table Create Table ¤¢¤¢¤¢ CREATE TABLE `¤¢¤¢¤¢` ( @@ -291,8 +291,8 @@ NULL DESC `íÝíÝíÝ`; Field Type Null Key Default Extra °¢°¢ char(1) YES MUL NULL -°¡°¡°¡ char(6) PRI -°£°£°£ char(1) YES MUL NULL +°¡°¡°¡ char(6) NO PRI +°£°£°£ char(1) YES UNI NULL °´°´°´ char(1) YES NULL SHOW CREATE TABLE `íÝíÝíÝ`; Table Create Table @@ -318,7 +318,7 @@ SELECT * FROM ` °£°£°£°£°£ DESC `íÝíÝíÝ`; Field Type Null Key Default Extra -°¡°¡°¡ char(6) +°¡°¡°¡ char(6) NO SHOW CREATE TABLE `íÝíÝíÝ`; Table Create Table íÝíÝíÝ CREATE TABLE `íÝíÝíÝ` ( @@ -355,8 +355,8 @@ NULL DESC `ޱޱޱ`; Field Type Null Key Default Extra ޶޶ char(1) YES MUL NULL -Ž·Ž·Ž· char(6) PRI -ޏޏޏ char(1) YES MUL NULL +Ž·Ž·Ž· char(6) NO PRI +ޏޏޏ char(1) YES UNI NULL ޹޹޹ char(1) YES NULL SHOW CREATE TABLE `ޱޱޱ`; Table Create Table @@ -368,7 +368,7 @@ Table Create Table PRIMARY KEY (`Ž·Ž·Ž·`), UNIQUE KEY `ޏޏޏ` (`ޏޏޏ`), KEY `޶޶޶` (`޶޶`) -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis ALTER TABLE `ޱޱޱ` DROP INDEX `޶޶޶`; ALTER TABLE `ޱޱޱ` DROP PRIMARY KEY; ALTER TABLE `ޱޱޱ` DROP INDEX `ޏޏޏ`; @@ -382,12 +382,12 @@ SELECT * FROM ` ޳޳޳޳޳ DESC `ޱޱޱ`; Field Type Null Key Default Extra -Ž·Ž·Ž· char(6) +Ž·Ž·Ž· char(6) NO SHOW CREATE TABLE `ޱޱޱ`; Table Create Table ޱޱޱ CREATE TABLE `ޱޱޱ` ( `Ž·Ž·Ž·` char(6) NOT NULL default '' -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis ALTER TABLE `¤¢¤¢¤¢` ADD `¤«¤«¤«` char(1) FIRST; ALTER TABLE `¤¢¤¢¤¢` ADD `¤¯¤¯¤¯` char(1) AFTER `¤­¤­¤­`; ALTER TABLE `¤¢¤¢¤¢` ADD `¤±¤±¤±` char(1); @@ -404,8 +404,8 @@ NULL DESC `¤¢¤¢¤¢`; Field Type Null Key Default Extra ¤«¤« char(1) YES MUL NULL -¤­¤­¤­ char(6) PRI -¤¯¤¯¤¯ char(1) YES MUL NULL +¤­¤­¤­ char(6) NO PRI +¤¯¤¯¤¯ char(1) YES UNI NULL ¤±¤±¤± char(1) YES NULL SHOW CREATE TABLE `¤¢¤¢¤¢`; Table Create Table @@ -417,7 +417,7 @@ Table Create Table PRIMARY KEY (`¤­¤­¤­`), UNIQUE KEY `¤¯¤¯¤¯` (`¤¯¤¯¤¯`), KEY `¤«¤«¤«` (`¤«¤«`) -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis ALTER TABLE `¤¢¤¢¤¢` DROP INDEX `¤«¤«¤«`; ALTER TABLE `¤¢¤¢¤¢` DROP PRIMARY KEY; ALTER TABLE `¤¢¤¢¤¢` DROP INDEX `¤¯¤¯¤¯`; @@ -431,12 +431,12 @@ SELECT * FROM ` ¤¦¤¦¤¦¤¦¤¦ DESC `¤¢¤¢¤¢`; Field Type Null Key Default Extra -¤­¤­¤­ char(6) +¤­¤­¤­ char(6) NO SHOW CREATE TABLE `¤¢¤¢¤¢`; Table Create Table ¤¢¤¢¤¢ CREATE TABLE `¤¢¤¢¤¢` ( `¤­¤­¤­` char(6) NOT NULL default '' -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis ALTER TABLE `íÝíÝíÝ` ADD `°¢°¢°¢` char(1) FIRST; ALTER TABLE `íÝíÝíÝ` ADD `°£°£°£` char(1) AFTER `°¡°¡°¡`; ALTER TABLE `íÝíÝíÝ` ADD `°´°´°´` char(1); @@ -453,8 +453,8 @@ NULL DESC `íÝíÝíÝ`; Field Type Null Key Default Extra °¢°¢ char(1) YES MUL NULL -°¡°¡°¡ char(6) PRI -°£°£°£ char(1) YES MUL NULL +°¡°¡°¡ char(6) NO PRI +°£°£°£ char(1) YES UNI NULL °´°´°´ char(1) YES NULL SHOW CREATE TABLE `íÝíÝíÝ`; Table Create Table @@ -466,7 +466,7 @@ Table Create Table PRIMARY KEY (`°¡°¡°¡`), UNIQUE KEY `°£°£°£` (`°£°£°£`), KEY `°¢°¢°¢` (`°¢°¢`) -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis ALTER TABLE `íÝíÝíÝ` DROP INDEX `°¢°¢°¢`; ALTER TABLE `íÝíÝíÝ` DROP PRIMARY KEY; ALTER TABLE `íÝíÝíÝ` DROP INDEX `°£°£°£`; @@ -480,12 +480,12 @@ SELECT * FROM ` °£°£°£°£°£ DESC `íÝíÝíÝ`; Field Type Null Key Default Extra -°¡°¡°¡ char(6) +°¡°¡°¡ char(6) NO SHOW CREATE TABLE `íÝíÝíÝ`; Table Create Table íÝíÝíÝ CREATE TABLE `íÝíÝíÝ` ( `°¡°¡°¡` char(6) NOT NULL default '' -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis DROP TABLE `ޱޱޱ`; DROP TABLE `޲޲޲`; DROP TABLE `¤¢¤¢¤¢`; @@ -516,7 +516,7 @@ NULL DESC `ޱޱޱ`; Field Type Null Key Default Extra ޶޶ char(1) YES MUL NULL -Ž·Ž·Ž· char(6) PRI +Ž·Ž·Ž· char(6) NO PRI ޏޏޏ char(1) YES NULL ޹޹޹ char(1) YES NULL SHOW CREATE TABLE `ޱޱޱ`; @@ -541,7 +541,7 @@ SELECT * FROM ` ޳޳޳޳޳ DESC `ޱޱޱ`; Field Type Null Key Default Extra -Ž·Ž·Ž· char(6) +Ž·Ž·Ž· char(6) NO SHOW CREATE TABLE `ޱޱޱ`; Table Create Table ޱޱޱ CREATE TABLE `ޱޱޱ` ( @@ -562,7 +562,7 @@ NULL DESC `¤¢¤¢¤¢`; Field Type Null Key Default Extra ¤«¤« char(1) YES MUL NULL -¤­¤­¤­ char(6) PRI +¤­¤­¤­ char(6) NO PRI ¤¯¤¯¤¯ char(1) YES NULL ¤±¤±¤± char(1) YES NULL SHOW CREATE TABLE `¤¢¤¢¤¢`; @@ -587,7 +587,7 @@ SELECT * FROM ` ¤¦¤¦¤¦¤¦¤¦ DESC `¤¢¤¢¤¢`; Field Type Null Key Default Extra -¤­¤­¤­ char(6) +¤­¤­¤­ char(6) NO SHOW CREATE TABLE `¤¢¤¢¤¢`; Table Create Table ¤¢¤¢¤¢ CREATE TABLE `¤¢¤¢¤¢` ( @@ -608,7 +608,7 @@ NULL DESC `íÝíÝíÝ`; Field Type Null Key Default Extra °¢°¢ char(1) YES MUL NULL -°¡°¡°¡ char(6) PRI +°¡°¡°¡ char(6) NO PRI °£°£°£ char(1) YES NULL °´°´°´ char(1) YES NULL SHOW CREATE TABLE `íÝíÝíÝ`; @@ -633,7 +633,7 @@ SELECT * FROM ` °£°£°£°£°£ DESC `íÝíÝíÝ`; Field Type Null Key Default Extra -°¡°¡°¡ char(6) +°¡°¡°¡ char(6) NO SHOW CREATE TABLE `íÝíÝíÝ`; Table Create Table íÝíÝíÝ CREATE TABLE `íÝíÝíÝ` ( diff --git a/mysql-test/suite/jp/r/jp_alter_utf8.result b/mysql-test/suite/jp/r/jp_alter_utf8.result index 19475e06a87..f2f374eed87 100644 --- a/mysql-test/suite/jp/r/jp_alter_utf8.result +++ b/mysql-test/suite/jp/r/jp_alter_utf8.result @@ -31,8 +31,8 @@ NULL ウウウウウ NULL NULL DESC `アアア`; Field Type Null Key Default Extra ï½¶ï½¶ char(1) YES MUL NULL -ï½·ï½·ï½· char(6) PRI -ククク char(1) YES MUL NULL +ï½·ï½·ï½· char(6) NO PRI +ククク char(1) YES UNI NULL ケケケ char(1) YES NULL SHOW CREATE TABLE `アアア`; Table Create Table @@ -58,7 +58,7 @@ SELECT * FROM `アアア`; ウウウウウ DESC `アアア`; Field Type Null Key Default Extra -ï½·ï½·ï½· char(6) +ï½·ï½·ï½· char(6) NO SHOW CREATE TABLE `アアア`; Table Create Table アアア CREATE TABLE `アアア` ( @@ -80,8 +80,8 @@ NULL ã†ã†ã†ã†ã† NULL NULL DESC `ã‚ã‚ã‚`; Field Type Null Key Default Extra ã‹ã‹ char(1) YES MUL NULL -ããã char(6) PRI -ããã char(1) YES MUL NULL +ããã char(6) NO PRI +ããã char(1) YES UNI NULL ã‘ã‘ã‘ char(1) YES NULL SHOW CREATE TABLE `ã‚ã‚ã‚`; Table Create Table @@ -107,7 +107,7 @@ SELECT * FROM `ã‚ã‚ã‚`; ã†ã†ã†ã†ã† DESC `ã‚ã‚ã‚`; Field Type Null Key Default Extra -ããã char(6) +ããã char(6) NO SHOW CREATE TABLE `ã‚ã‚ã‚`; Table Create Table ã‚ã‚ã‚ CREATE TABLE `ã‚ã‚ã‚` ( @@ -129,8 +129,8 @@ NULL 丅丅丅丅丅 NULL NULL DESC `é¾–é¾–é¾–`; Field Type Null Key Default Extra 丄丄 char(1) YES MUL NULL -丂丂丂 char(6) PRI -丅丅丅 char(1) YES MUL NULL +丂丂丂 char(6) NO PRI +丅丅丅 char(1) YES UNI NULL 乚乚乚 char(1) YES NULL SHOW CREATE TABLE `é¾–é¾–é¾–`; Table Create Table @@ -156,7 +156,7 @@ SELECT * FROM `é¾–é¾–é¾–`; 丅丅丅丅丅 DESC `é¾–é¾–é¾–`; Field Type Null Key Default Extra -丂丂丂 char(6) +丂丂丂 char(6) NO SHOW CREATE TABLE `é¾–é¾–é¾–`; Table Create Table é¾–é¾–é¾– CREATE TABLE `é¾–é¾–é¾–` ( @@ -193,8 +193,8 @@ NULL ウウウウウ NULL NULL DESC `アアア`; Field Type Null Key Default Extra ï½¶ï½¶ char(1) YES MUL NULL -ï½·ï½·ï½· char(6) PRI -ククク char(1) YES MUL NULL +ï½·ï½·ï½· char(6) NO PRI +ククク char(1) YES UNI NULL ケケケ char(1) YES NULL SHOW CREATE TABLE `アアア`; Table Create Table @@ -220,7 +220,7 @@ SELECT * FROM `アアア`; ウウウウウ DESC `アアア`; Field Type Null Key Default Extra -ï½·ï½·ï½· char(6) +ï½·ï½·ï½· char(6) NO SHOW CREATE TABLE `アアア`; Table Create Table アアア CREATE TABLE `アアア` ( @@ -242,8 +242,8 @@ NULL ã†ã†ã†ã†ã† NULL NULL DESC `ã‚ã‚ã‚`; Field Type Null Key Default Extra ã‹ã‹ char(1) YES MUL NULL -ããã char(6) PRI -ããã char(1) YES MUL NULL +ããã char(6) NO PRI +ããã char(1) YES UNI NULL ã‘ã‘ã‘ char(1) YES NULL SHOW CREATE TABLE `ã‚ã‚ã‚`; Table Create Table @@ -269,7 +269,7 @@ SELECT * FROM `ã‚ã‚ã‚`; ã†ã†ã†ã†ã† DESC `ã‚ã‚ã‚`; Field Type Null Key Default Extra -ããã char(6) +ããã char(6) NO SHOW CREATE TABLE `ã‚ã‚ã‚`; Table Create Table ã‚ã‚ã‚ CREATE TABLE `ã‚ã‚ã‚` ( @@ -291,8 +291,8 @@ NULL 丅丅丅丅丅 NULL NULL DESC `é¾–é¾–é¾–`; Field Type Null Key Default Extra 丄丄 char(1) YES MUL NULL -丂丂丂 char(6) PRI -丅丅丅 char(1) YES MUL NULL +丂丂丂 char(6) NO PRI +丅丅丅 char(1) YES UNI NULL 乚乚乚 char(1) YES NULL SHOW CREATE TABLE `é¾–é¾–é¾–`; Table Create Table @@ -318,7 +318,7 @@ SELECT * FROM `é¾–é¾–é¾–`; 丅丅丅丅丅 DESC `é¾–é¾–é¾–`; Field Type Null Key Default Extra -丂丂丂 char(6) +丂丂丂 char(6) NO SHOW CREATE TABLE `é¾–é¾–é¾–`; Table Create Table é¾–é¾–é¾– CREATE TABLE `é¾–é¾–é¾–` ( @@ -355,8 +355,8 @@ NULL ウウウウウ NULL NULL DESC `アアア`; Field Type Null Key Default Extra ï½¶ï½¶ char(1) YES MUL NULL -ï½·ï½·ï½· char(6) PRI -ククク char(1) YES MUL NULL +ï½·ï½·ï½· char(6) NO PRI +ククク char(1) YES UNI NULL ケケケ char(1) YES NULL SHOW CREATE TABLE `アアア`; Table Create Table @@ -368,7 +368,7 @@ Table Create Table PRIMARY KEY (`ï½·ï½·ï½·`), UNIQUE KEY `ククク` (`ククク`), KEY `ï½¶ï½¶ï½¶` (`ï½¶ï½¶`) -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 ALTER TABLE `アアア` DROP INDEX `ï½¶ï½¶ï½¶`; ALTER TABLE `アアア` DROP PRIMARY KEY; ALTER TABLE `アアア` DROP INDEX `ククク`; @@ -382,12 +382,12 @@ SELECT * FROM `アアア`; ウウウウウ DESC `アアア`; Field Type Null Key Default Extra -ï½·ï½·ï½· char(6) +ï½·ï½·ï½· char(6) NO SHOW CREATE TABLE `アアア`; Table Create Table アアア CREATE TABLE `アアア` ( `ï½·ï½·ï½·` char(6) NOT NULL default '' -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 ALTER TABLE `ã‚ã‚ã‚` ADD `ã‹ã‹ã‹` char(1) FIRST; ALTER TABLE `ã‚ã‚ã‚` ADD `ããã` char(1) AFTER `ããã`; ALTER TABLE `ã‚ã‚ã‚` ADD `ã‘ã‘ã‘` char(1); @@ -404,8 +404,8 @@ NULL ã†ã†ã†ã†ã† NULL NULL DESC `ã‚ã‚ã‚`; Field Type Null Key Default Extra ã‹ã‹ char(1) YES MUL NULL -ããã char(6) PRI -ããã char(1) YES MUL NULL +ããã char(6) NO PRI +ããã char(1) YES UNI NULL ã‘ã‘ã‘ char(1) YES NULL SHOW CREATE TABLE `ã‚ã‚ã‚`; Table Create Table @@ -417,7 +417,7 @@ Table Create Table PRIMARY KEY (`ããã`), UNIQUE KEY `ããã` (`ããã`), KEY `ã‹ã‹ã‹` (`ã‹ã‹`) -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 ALTER TABLE `ã‚ã‚ã‚` DROP INDEX `ã‹ã‹ã‹`; ALTER TABLE `ã‚ã‚ã‚` DROP PRIMARY KEY; ALTER TABLE `ã‚ã‚ã‚` DROP INDEX `ããã`; @@ -431,12 +431,12 @@ SELECT * FROM `ã‚ã‚ã‚`; ã†ã†ã†ã†ã† DESC `ã‚ã‚ã‚`; Field Type Null Key Default Extra -ããã char(6) +ããã char(6) NO SHOW CREATE TABLE `ã‚ã‚ã‚`; Table Create Table ã‚ã‚ã‚ CREATE TABLE `ã‚ã‚ã‚` ( `ããã` char(6) NOT NULL default '' -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 ALTER TABLE `é¾–é¾–é¾–` ADD `丄丄丄` char(1) FIRST; ALTER TABLE `é¾–é¾–é¾–` ADD `丅丅丅` char(1) AFTER `丂丂丂`; ALTER TABLE `é¾–é¾–é¾–` ADD `乚乚乚` char(1); @@ -453,8 +453,8 @@ NULL 丅丅丅丅丅 NULL NULL DESC `é¾–é¾–é¾–`; Field Type Null Key Default Extra 丄丄 char(1) YES MUL NULL -丂丂丂 char(6) PRI -丅丅丅 char(1) YES MUL NULL +丂丂丂 char(6) NO PRI +丅丅丅 char(1) YES UNI NULL 乚乚乚 char(1) YES NULL SHOW CREATE TABLE `é¾–é¾–é¾–`; Table Create Table @@ -466,7 +466,7 @@ Table Create Table PRIMARY KEY (`丂丂丂`), UNIQUE KEY `丅丅丅` (`丅丅丅`), KEY `丄丄丄` (`丄丄`) -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 ALTER TABLE `é¾–é¾–é¾–` DROP INDEX `丄丄丄`; ALTER TABLE `é¾–é¾–é¾–` DROP PRIMARY KEY; ALTER TABLE `é¾–é¾–é¾–` DROP INDEX `丅丅丅`; @@ -480,12 +480,12 @@ SELECT * FROM `é¾–é¾–é¾–`; 丅丅丅丅丅 DESC `é¾–é¾–é¾–`; Field Type Null Key Default Extra -丂丂丂 char(6) +丂丂丂 char(6) NO SHOW CREATE TABLE `é¾–é¾–é¾–`; Table Create Table é¾–é¾–é¾– CREATE TABLE `é¾–é¾–é¾–` ( `丂丂丂` char(6) NOT NULL default '' -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 DROP TABLE `アアア`; DROP TABLE `イイイ`; DROP TABLE `ã‚ã‚ã‚`; @@ -516,7 +516,7 @@ NULL ウウウウウ NULL NULL DESC `アアア`; Field Type Null Key Default Extra ï½¶ï½¶ char(1) YES MUL NULL -ï½·ï½·ï½· char(6) PRI +ï½·ï½·ï½· char(6) NO PRI ククク char(1) YES NULL ケケケ char(1) YES NULL SHOW CREATE TABLE `アアア`; @@ -541,7 +541,7 @@ SELECT * FROM `アアア`; ウウウウウ DESC `アアア`; Field Type Null Key Default Extra -ï½·ï½·ï½· char(6) +ï½·ï½·ï½· char(6) NO SHOW CREATE TABLE `アアア`; Table Create Table アアア CREATE TABLE `アアア` ( @@ -562,7 +562,7 @@ NULL ã†ã†ã†ã†ã† NULL NULL DESC `ã‚ã‚ã‚`; Field Type Null Key Default Extra ã‹ã‹ char(1) YES MUL NULL -ããã char(6) PRI +ããã char(6) NO PRI ããã char(1) YES NULL ã‘ã‘ã‘ char(1) YES NULL SHOW CREATE TABLE `ã‚ã‚ã‚`; @@ -587,7 +587,7 @@ SELECT * FROM `ã‚ã‚ã‚`; ã†ã†ã†ã†ã† DESC `ã‚ã‚ã‚`; Field Type Null Key Default Extra -ããã char(6) +ããã char(6) NO SHOW CREATE TABLE `ã‚ã‚ã‚`; Table Create Table ã‚ã‚ã‚ CREATE TABLE `ã‚ã‚ã‚` ( @@ -608,7 +608,7 @@ NULL 丅丅丅丅丅 NULL NULL DESC `é¾–é¾–é¾–`; Field Type Null Key Default Extra 丄丄 char(1) YES MUL NULL -丂丂丂 char(6) PRI +丂丂丂 char(6) NO PRI 丅丅丅 char(1) YES NULL 乚乚乚 char(1) YES NULL SHOW CREATE TABLE `é¾–é¾–é¾–`; @@ -633,7 +633,7 @@ SELECT * FROM `é¾–é¾–é¾–`; 丅丅丅丅丅 DESC `é¾–é¾–é¾–`; Field Type Null Key Default Extra -丂丂丂 char(6) +丂丂丂 char(6) NO SHOW CREATE TABLE `é¾–é¾–é¾–`; Table Create Table é¾–é¾–é¾– CREATE TABLE `é¾–é¾–é¾–` ( diff --git a/mysql-test/suite/jp/r/jp_convert_sjis.result b/mysql-test/suite/jp/r/jp_convert_sjis.result index 8c9df3606c8..ff8a3fb2cd9 100644 --- a/mysql-test/suite/jp/r/jp_convert_sjis.result +++ b/mysql-test/suite/jp/r/jp_convert_sjis.result @@ -278,12 +278,15 @@ SELECT ` êê‘ê’ê“ê”ê•ê–ê—ê˜ê™êšê›êœêêžEEEEE êê‘ê’ê“ê”ê•ê–ê—ê˜ê™êšê›êœêêžEEEEE SELECT `‚b‚P`, CONVERT(`‚b‚P` using utf8) FROM `‚s‚R`; ‚b‚P CONVERT(`‚b‚P` using utf8) + ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ SELECT `‚b‚P`, CONVERT(`‚b‚P` using ucs2) FROM `‚s‚R`; ‚b‚P CONVERT(`‚b‚P` using ucs2) + ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ SELECT `‚b‚P`, CONVERT(`‚b‚P` using ujis) FROM `‚s‚R`; ‚b‚P CONVERT(`‚b‚P` using ujis) + ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ SELECT `‚b‚P`, CONVERT(`‚b‚P` using utf8) FROM `‚s‚S`; ‚b‚P CONVERT(`‚b‚P` using utf8) @@ -527,12 +530,15 @@ SELECT ` êê‘ê’ê“ê”ê•ê–ê—ê˜ê™êšê›êœêêžEEEEE êê‘ê’ê“ê”ê•ê–ê—ê˜ê™êšê›êœêêžEEEEE SELECT `‚b‚P`, CONVERT(`‚b‚P` using utf8) FROM `‚s‚U`; ‚b‚P CONVERT(`‚b‚P` using utf8) + ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ SELECT `‚b‚P`, CONVERT(`‚b‚P` using ucs2) FROM `‚s‚U`; ‚b‚P CONVERT(`‚b‚P` using ucs2) + ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ SELECT `‚b‚P`, CONVERT(`‚b‚P` using ujis) FROM `‚s‚U`; ‚b‚P CONVERT(`‚b‚P` using ujis) + ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ SELECT `‚b‚P`, CONVERT(`‚b‚P` using utf8) FROM `‚s‚V`; ‚b‚P CONVERT(`‚b‚P` using utf8) @@ -777,12 +783,15 @@ SELECT ` SELECT `‚b‚P`, CONVERT(`‚b‚P` using utf8) FROM `‚s‚X`; ‚b‚P CONVERT(`‚b‚P` using utf8) ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ + SELECT `‚b‚P`, CONVERT(`‚b‚P` using ucs2) FROM `‚s‚X`; ‚b‚P CONVERT(`‚b‚P` using ucs2) ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ + SELECT `‚b‚P`, CONVERT(`‚b‚P` using ujis) FROM `‚s‚X`; ‚b‚P CONVERT(`‚b‚P` using ujis) ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ + SELECT `‚b‚P`, CONVERT(`‚b‚P` using utf8) FROM `‚s‚P‚O`; ‚b‚P CONVERT(`‚b‚P` using utf8) !"#$%&'()*+,-./ !"#$%&'()*+,-./ @@ -1026,12 +1035,15 @@ SELECT ` SELECT `‚b‚P`, CONVERT(`‚b‚P` using utf8) FROM `‚s‚P‚Q`; ‚b‚P CONVERT(`‚b‚P` using utf8) ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ + SELECT `‚b‚P`, CONVERT(`‚b‚P` using ucs2) FROM `‚s‚P‚Q`; ‚b‚P CONVERT(`‚b‚P` using ucs2) ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ + SELECT `‚b‚P`, CONVERT(`‚b‚P` using ujis) FROM `‚s‚P‚Q`; ‚b‚P CONVERT(`‚b‚P` using ujis) ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ + drop table `‚s‚P`; drop table `‚s‚Q`; drop table `‚s‚R`; diff --git a/mysql-test/suite/jp/r/jp_create_db_sjis.result b/mysql-test/suite/jp/r/jp_create_db_sjis.result index 1ce0b7228d5..5d13cf74a39 100644 --- a/mysql-test/suite/jp/r/jp_create_db_sjis.result +++ b/mysql-test/suite/jp/r/jp_create_db_sjis.result @@ -8,6 +8,7 @@ CREATE DATABASE ` CREATE DATABASE `ƒ\\•\`; SHOW DATABASES; Database +information_schema mysql test ƒ\\•\ diff --git a/mysql-test/suite/jp/r/jp_create_db_ucs2.result b/mysql-test/suite/jp/r/jp_create_db_ucs2.result index 8fd921ea8e6..f03baadf707 100644 --- a/mysql-test/suite/jp/r/jp_create_db_ucs2.result +++ b/mysql-test/suite/jp/r/jp_create_db_ucs2.result @@ -9,6 +9,7 @@ CREATE DATABASE ` CREATE DATABASE `íÜíÝíÞ`; SHOW DATABASES; Database +information_schema mysql test ÆüËܸì diff --git a/mysql-test/suite/jp/r/jp_create_db_ujis.result b/mysql-test/suite/jp/r/jp_create_db_ujis.result index 45fdb34717b..627381bbacb 100644 --- a/mysql-test/suite/jp/r/jp_create_db_ujis.result +++ b/mysql-test/suite/jp/r/jp_create_db_ujis.result @@ -8,6 +8,7 @@ CREATE DATABASE ` CREATE DATABASE `íÜíÝíÞ`; SHOW DATABASES; Database +information_schema mysql test ÆüËܸì diff --git a/mysql-test/suite/jp/r/jp_create_db_utf8.result b/mysql-test/suite/jp/r/jp_create_db_utf8.result index c0e996040de..1813259bdc9 100644 --- a/mysql-test/suite/jp/r/jp_create_db_utf8.result +++ b/mysql-test/suite/jp/r/jp_create_db_utf8.result @@ -8,6 +8,7 @@ CREATE DATABASE `日本語`; CREATE DATABASE `龔龖龗`; SHOW DATABASES; Database +information_schema mysql test 日本語 diff --git a/mysql-test/suite/jp/r/jp_create_tbl_sjis.result b/mysql-test/suite/jp/r/jp_create_tbl_sjis.result index ecc72f9d91b..763a25bc127 100644 --- a/mysql-test/suite/jp/r/jp_create_tbl_sjis.result +++ b/mysql-test/suite/jp/r/jp_create_tbl_sjis.result @@ -22,11 +22,23 @@ CREATE TABLE ` CREATE TABLE `ƒ\ƒ\ƒ\`(`‰\‰\‰\` char(1)) DEFAULT CHARSET = sjis engine=INNODB; CREATE TABLE `\\\`(`Ž\Ž\Ž\` char(1)) DEFAULT CHARSET = sjis engine=INNODB; CREATE TABLE IF NOT EXISTS `±±±`(`¶¶¶` char(1)) DEFAULT CHARSET = sjis engine=INNODB; +Warnings: +Note 1050 Table '±±±' already exists CREATE TABLE IF NOT EXISTS `²²²`(`···` char(1)) DEFAULT CHARSET = sjis engine=INNODB; +Warnings: +Note 1050 Table '²²²' already exists CREATE TABLE IF NOT EXISTS `‚ ‚ ‚ `(`‚©‚©‚©` char(1)) DEFAULT CHARSET = sjis engine=INNODB; +Warnings: +Note 1050 Table '‚ ‚ ‚ ' already exists CREATE TABLE IF NOT EXISTS `‚¢‚¢‚¢`(`‚«‚«‚«` char(1)) DEFAULT CHARSET = sjis engine=INNODB; +Warnings: +Note 1050 Table '‚¢‚¢‚¢' already exists CREATE TABLE IF NOT EXISTS `ƒ\ƒ\ƒ\`(`‰\‰\‰\` char(1)) DEFAULT CHARSET = sjis engine=INNODB; +Warnings: +Note 1050 Table 'ƒ\ƒ\ƒ\' already exists CREATE TABLE IF NOT EXISTS `\\\`(`Ž\Ž\Ž\` char(1)) DEFAULT CHARSET = sjis engine=INNODB; +Warnings: +Note 1050 Table '\\\' already exists CREATE TABLE IF NOT EXISTS `³³³`(`¸¸¸` char(1)) DEFAULT CHARSET = sjis engine=INNODB; CREATE TABLE IF NOT EXISTS `‚¤‚¤‚¤`(`‚­‚­‚­` char(1)) DEFAULT CHARSET = sjis engine=INNODB; CREATE TABLE IF NOT EXISTS `•\•\•\`(`\\\`char(1)) DEFAULT CHARSET = sjis engine=INNODB; @@ -178,11 +190,23 @@ CREATE TABLE ` CREATE TABLE `ƒ\ƒ\ƒ\`(`‰\‰\‰\` char(1)) DEFAULT CHARSET = sjis engine=MyISAM; CREATE TABLE `\\\`(`Ž\Ž\Ž\` char(1)) DEFAULT CHARSET = sjis engine=MyISAM; CREATE TABLE IF NOT EXISTS `±±±`(`¶¶¶` char(1)) DEFAULT CHARSET = sjis engine=MyISAM; +Warnings: +Note 1050 Table '±±±' already exists CREATE TABLE IF NOT EXISTS `²²²`(`···` char(1)) DEFAULT CHARSET = sjis engine=MyISAM; +Warnings: +Note 1050 Table '²²²' already exists CREATE TABLE IF NOT EXISTS `‚ ‚ ‚ `(`‚©‚©‚©` char(1)) DEFAULT CHARSET = sjis engine=MyISAM; +Warnings: +Note 1050 Table '‚ ‚ ‚ ' already exists CREATE TABLE IF NOT EXISTS `‚¢‚¢‚¢`(`‚«‚«‚«` char(1)) DEFAULT CHARSET = sjis engine=MyISAM; +Warnings: +Note 1050 Table '‚¢‚¢‚¢' already exists CREATE TABLE IF NOT EXISTS `ƒ\ƒ\ƒ\`(`‰\‰\‰\` char(1)) DEFAULT CHARSET = sjis engine=MyISAM; +Warnings: +Note 1050 Table 'ƒ\ƒ\ƒ\' already exists CREATE TABLE IF NOT EXISTS `\\\`(`Ž\Ž\Ž\` char(1)) DEFAULT CHARSET = sjis engine=MyISAM; +Warnings: +Note 1050 Table '\\\' already exists CREATE TABLE IF NOT EXISTS `³³³`(`¸¸¸` char(1)) DEFAULT CHARSET = sjis engine=MyISAM; CREATE TABLE IF NOT EXISTS `‚¤‚¤‚¤`(`‚­‚­‚­` char(1)) DEFAULT CHARSET = sjis engine=MyISAM; CREATE TABLE IF NOT EXISTS `•\•\•\`(`\\\`char(1)) DEFAULT CHARSET = sjis engine=MyISAM; @@ -334,11 +358,23 @@ CREATE TABLE ` CREATE TABLE `ƒ\ƒ\ƒ\`(`‰\‰\‰\` char(1)) DEFAULT CHARSET = sjis engine=HEAP; CREATE TABLE `\\\`(`Ž\Ž\Ž\` char(1)) DEFAULT CHARSET = sjis engine=HEAP; CREATE TABLE IF NOT EXISTS `±±±`(`¶¶¶` char(1)) DEFAULT CHARSET = sjis engine=HEAP; +Warnings: +Note 1050 Table '±±±' already exists CREATE TABLE IF NOT EXISTS `²²²`(`···` char(1)) DEFAULT CHARSET = sjis engine=HEAP; +Warnings: +Note 1050 Table '²²²' already exists CREATE TABLE IF NOT EXISTS `‚ ‚ ‚ `(`‚©‚©‚©` char(1)) DEFAULT CHARSET = sjis engine=HEAP; +Warnings: +Note 1050 Table '‚ ‚ ‚ ' already exists CREATE TABLE IF NOT EXISTS `‚¢‚¢‚¢`(`‚«‚«‚«` char(1)) DEFAULT CHARSET = sjis engine=HEAP; +Warnings: +Note 1050 Table '‚¢‚¢‚¢' already exists CREATE TABLE IF NOT EXISTS `ƒ\ƒ\ƒ\`(`‰\‰\‰\` char(1)) DEFAULT CHARSET = sjis engine=HEAP; +Warnings: +Note 1050 Table 'ƒ\ƒ\ƒ\' already exists CREATE TABLE IF NOT EXISTS `\\\`(`Ž\Ž\Ž\` char(1)) DEFAULT CHARSET = sjis engine=HEAP; +Warnings: +Note 1050 Table '\\\' already exists CREATE TABLE IF NOT EXISTS `³³³`(`¸¸¸` char(1)) DEFAULT CHARSET = sjis engine=HEAP; CREATE TABLE IF NOT EXISTS `‚¤‚¤‚¤`(`‚­‚­‚­` char(1)) DEFAULT CHARSET = sjis engine=HEAP; CREATE TABLE IF NOT EXISTS `•\•\•\`(`\\\`char(1)) DEFAULT CHARSET = sjis engine=HEAP; @@ -397,77 +433,77 @@ SHOW CREATE TABLE ` Table Create Table ±±± CREATE TABLE `±±±` ( `¶¶¶` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `²²²`; Table Create Table ²²² CREATE TABLE `²²²` ( `···` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `³³³`; Table Create Table ³³³ CREATE TABLE `³³³` ( `¸¸¸` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `´´´`; Table Create Table ´´´ CREATE TEMPORARY TABLE `´´´` ( `¹¹¹` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `µµµ`; Table Create Table µµµ CREATE TEMPORARY TABLE `µµµ` ( `ººº` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚ ‚ ‚ `; Table Create Table ‚ ‚ ‚  CREATE TABLE `‚ ‚ ‚ ` ( `‚©‚©‚©` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚¢‚¢‚¢`; Table Create Table ‚¢‚¢‚¢ CREATE TABLE `‚¢‚¢‚¢` ( `‚«‚«‚«` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚¤‚¤‚¤`; Table Create Table ‚¤‚¤‚¤ CREATE TABLE `‚¤‚¤‚¤` ( `‚­‚­‚­` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚¦‚¦‚¦`; Table Create Table ‚¦‚¦‚¦ CREATE TEMPORARY TABLE `‚¦‚¦‚¦` ( `‚¯‚¯‚¯` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚¨‚¨‚¨`; Table Create Table ‚¨‚¨‚¨ CREATE TEMPORARY TABLE `‚¨‚¨‚¨` ( `‚±‚±‚±` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `ƒ\ƒ\ƒ\`; Table Create Table ƒ\ƒ\ƒ\ CREATE TABLE `ƒ\ƒ\ƒ\` ( `‰\‰\‰\` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `\\\`; Table Create Table \\\ CREATE TABLE `\\\` ( `Ž\Ž\Ž\` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `•\•\•\`; Table Create Table •\•\•\ CREATE TABLE `•\•\•\` ( `\\\` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `—\—\—\`; Table Create Table —\—\—\ CREATE TEMPORARY TABLE `—\—\—\` ( `“\“\“\` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `\\\`; Table Create Table \\\ CREATE TEMPORARY TABLE `\\\` ( `”\”\”\` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis DROP TABLE `±±±`; DROP TABLE `²²²`; DROP TABLE `³³³`; @@ -490,11 +526,23 @@ CREATE TABLE ` CREATE TABLE `ƒ\ƒ\ƒ\`(`‰\‰\‰\` char(1)) DEFAULT CHARSET = sjis engine=BDB; CREATE TABLE `\\\`(`Ž\Ž\Ž\` char(1)) DEFAULT CHARSET = sjis engine=BDB; CREATE TABLE IF NOT EXISTS `±±±`(`¶¶¶` char(1)) DEFAULT CHARSET = sjis engine=BDB; +Warnings: +Note 1050 Table '±±±' already exists CREATE TABLE IF NOT EXISTS `²²²`(`···` char(1)) DEFAULT CHARSET = sjis engine=BDB; +Warnings: +Note 1050 Table '²²²' already exists CREATE TABLE IF NOT EXISTS `‚ ‚ ‚ `(`‚©‚©‚©` char(1)) DEFAULT CHARSET = sjis engine=BDB; +Warnings: +Note 1050 Table '‚ ‚ ‚ ' already exists CREATE TABLE IF NOT EXISTS `‚¢‚¢‚¢`(`‚«‚«‚«` char(1)) DEFAULT CHARSET = sjis engine=BDB; +Warnings: +Note 1050 Table '‚¢‚¢‚¢' already exists CREATE TABLE IF NOT EXISTS `ƒ\ƒ\ƒ\`(`‰\‰\‰\` char(1)) DEFAULT CHARSET = sjis engine=BDB; +Warnings: +Note 1050 Table 'ƒ\ƒ\ƒ\' already exists CREATE TABLE IF NOT EXISTS `\\\`(`Ž\Ž\Ž\` char(1)) DEFAULT CHARSET = sjis engine=BDB; +Warnings: +Note 1050 Table '\\\' already exists CREATE TABLE IF NOT EXISTS `³³³`(`¸¸¸` char(1)) DEFAULT CHARSET = sjis engine=BDB; CREATE TABLE IF NOT EXISTS `‚¤‚¤‚¤`(`‚­‚­‚­` char(1)) DEFAULT CHARSET = sjis engine=BDB; CREATE TABLE IF NOT EXISTS `•\•\•\`(`\\\`char(1)) DEFAULT CHARSET = sjis engine=BDB; diff --git a/mysql-test/suite/jp/r/jp_create_tbl_ucs2.result b/mysql-test/suite/jp/r/jp_create_tbl_ucs2.result index 0bf5a6891b0..d6616f66d9f 100644 --- a/mysql-test/suite/jp/r/jp_create_tbl_ucs2.result +++ b/mysql-test/suite/jp/r/jp_create_tbl_ucs2.result @@ -22,11 +22,23 @@ CREATE TABLE ` CREATE TABLE `íÝíÝíÝ`(`°¡°¡°¡` char(1)) DEFAULT CHARSET = ucs2 engine=INNODB; CREATE TABLE `íÞíÞíÞ`(`°¢°¢°¢` char(1)) DEFAULT CHARSET = ucs2 engine=INNODB; CREATE TABLE IF NOT EXISTS `ޱޱޱ`(`޶޶޶` char(1)) DEFAULT CHARSET = ucs2 engine=INNODB; +Warnings: +Note 1050 Table 'ޱޱޱ' already exists CREATE TABLE IF NOT EXISTS `޲޲޲`(`Ž·Ž·Ž·` char(1)) DEFAULT CHARSET = ucs2 engine=INNODB; +Warnings: +Note 1050 Table '޲޲޲' already exists CREATE TABLE IF NOT EXISTS `¤¢¤¢¤¢`(`¤«¤«¤«` char(1)) DEFAULT CHARSET = ucs2 engine=INNODB; +Warnings: +Note 1050 Table '¤¢¤¢¤¢' already exists CREATE TABLE IF NOT EXISTS `¤¤¤¤¤¤`(`¤­¤­¤­` char(1)) DEFAULT CHARSET = ucs2 engine=INNODB; +Warnings: +Note 1050 Table '¤¤¤¤¤¤' already exists CREATE TABLE IF NOT EXISTS `íÝíÝíÝ`(`°¡°¡°¡` char(1)) DEFAULT CHARSET = ucs2 engine=INNODB; +Warnings: +Note 1050 Table 'íÝíÝíÝ' already exists CREATE TABLE IF NOT EXISTS `íÞíÞíÞ`(`°¢°¢°¢` char(1)) DEFAULT CHARSET = ucs2 engine=INNODB; +Warnings: +Note 1050 Table 'íÞíÞíÞ' already exists CREATE TABLE IF NOT EXISTS `޳޳޳`(`ޏޏޏ` char(1)) DEFAULT CHARSET = ucs2 engine=INNODB; CREATE TABLE IF NOT EXISTS `¤¦¤¦¤¦`(`¤¯¤¯¤¯` char(1)) DEFAULT CHARSET = ucs2 engine=INNODB; CREATE TABLE IF NOT EXISTS `íßíßíß`(`°£°£°£`char(1)) DEFAULT CHARSET = ucs2 engine=INNODB; @@ -178,11 +190,23 @@ CREATE TABLE ` CREATE TABLE `íÝíÝíÝ`(`°¡°¡°¡` char(1)) DEFAULT CHARSET = ucs2 engine=MyISAM; CREATE TABLE `íÞíÞíÞ`(`°¢°¢°¢` char(1)) DEFAULT CHARSET = ucs2 engine=MyISAM; CREATE TABLE IF NOT EXISTS `ޱޱޱ`(`޶޶޶` char(1)) DEFAULT CHARSET = ucs2 engine=MyISAM; +Warnings: +Note 1050 Table 'ޱޱޱ' already exists CREATE TABLE IF NOT EXISTS `޲޲޲`(`Ž·Ž·Ž·` char(1)) DEFAULT CHARSET = ucs2 engine=MyISAM; +Warnings: +Note 1050 Table '޲޲޲' already exists CREATE TABLE IF NOT EXISTS `¤¢¤¢¤¢`(`¤«¤«¤«` char(1)) DEFAULT CHARSET = ucs2 engine=MyISAM; +Warnings: +Note 1050 Table '¤¢¤¢¤¢' already exists CREATE TABLE IF NOT EXISTS `¤¤¤¤¤¤`(`¤­¤­¤­` char(1)) DEFAULT CHARSET = ucs2 engine=MyISAM; +Warnings: +Note 1050 Table '¤¤¤¤¤¤' already exists CREATE TABLE IF NOT EXISTS `íÝíÝíÝ`(`°¡°¡°¡` char(1)) DEFAULT CHARSET = ucs2 engine=MyISAM; +Warnings: +Note 1050 Table 'íÝíÝíÝ' already exists CREATE TABLE IF NOT EXISTS `íÞíÞíÞ`(`°¢°¢°¢` char(1)) DEFAULT CHARSET = ucs2 engine=MyISAM; +Warnings: +Note 1050 Table 'íÞíÞíÞ' already exists CREATE TABLE IF NOT EXISTS `޳޳޳`(`ޏޏޏ` char(1)) DEFAULT CHARSET = ucs2 engine=MyISAM; CREATE TABLE IF NOT EXISTS `¤¦¤¦¤¦`(`¤¯¤¯¤¯` char(1)) DEFAULT CHARSET = ucs2 engine=MyISAM; CREATE TABLE IF NOT EXISTS `íßíßíß`(`°£°£°£`char(1)) DEFAULT CHARSET = ucs2 engine=MyISAM; @@ -334,11 +358,23 @@ CREATE TABLE ` CREATE TABLE `íÝíÝíÝ`(`°¡°¡°¡` char(1)) DEFAULT CHARSET = ucs2 engine=HEAP; CREATE TABLE `íÞíÞíÞ`(`°¢°¢°¢` char(1)) DEFAULT CHARSET = ucs2 engine=HEAP; CREATE TABLE IF NOT EXISTS `ޱޱޱ`(`޶޶޶` char(1)) DEFAULT CHARSET = ucs2 engine=HEAP; +Warnings: +Note 1050 Table 'ޱޱޱ' already exists CREATE TABLE IF NOT EXISTS `޲޲޲`(`Ž·Ž·Ž·` char(1)) DEFAULT CHARSET = ucs2 engine=HEAP; +Warnings: +Note 1050 Table '޲޲޲' already exists CREATE TABLE IF NOT EXISTS `¤¢¤¢¤¢`(`¤«¤«¤«` char(1)) DEFAULT CHARSET = ucs2 engine=HEAP; +Warnings: +Note 1050 Table '¤¢¤¢¤¢' already exists CREATE TABLE IF NOT EXISTS `¤¤¤¤¤¤`(`¤­¤­¤­` char(1)) DEFAULT CHARSET = ucs2 engine=HEAP; +Warnings: +Note 1050 Table '¤¤¤¤¤¤' already exists CREATE TABLE IF NOT EXISTS `íÝíÝíÝ`(`°¡°¡°¡` char(1)) DEFAULT CHARSET = ucs2 engine=HEAP; +Warnings: +Note 1050 Table 'íÝíÝíÝ' already exists CREATE TABLE IF NOT EXISTS `íÞíÞíÞ`(`°¢°¢°¢` char(1)) DEFAULT CHARSET = ucs2 engine=HEAP; +Warnings: +Note 1050 Table 'íÞíÞíÞ' already exists CREATE TABLE IF NOT EXISTS `޳޳޳`(`ޏޏޏ` char(1)) DEFAULT CHARSET = ucs2 engine=HEAP; CREATE TABLE IF NOT EXISTS `¤¦¤¦¤¦`(`¤¯¤¯¤¯` char(1)) DEFAULT CHARSET = ucs2 engine=HEAP; CREATE TABLE IF NOT EXISTS `íßíßíß`(`°£°£°£`char(1)) DEFAULT CHARSET = ucs2 engine=HEAP; @@ -397,77 +433,77 @@ SHOW CREATE TABLE ` Table Create Table ޱޱޱ CREATE TABLE `ޱޱޱ` ( `޶޶޶` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `޲޲޲`; Table Create Table ޲޲޲ CREATE TABLE `޲޲޲` ( `Ž·Ž·Ž·` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `޳޳޳`; Table Create Table ޳޳޳ CREATE TABLE `޳޳޳` ( `ޏޏޏ` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `Ž´Ž´Ž´`; Table Create Table Ž´Ž´Ž´ CREATE TEMPORARY TABLE `Ž´Ž´Ž´` ( `޹޹޹` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `޵޵޵`; Table Create Table ޵޵޵ CREATE TEMPORARY TABLE `޵޵޵` ( `ŽºŽºŽº` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `¤¢¤¢¤¢`; Table Create Table ¤¢¤¢¤¢ CREATE TABLE `¤¢¤¢¤¢` ( `¤«¤«¤«` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `¤¤¤¤¤¤`; Table Create Table ¤¤¤¤¤¤ CREATE TABLE `¤¤¤¤¤¤` ( `¤­¤­¤­` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `¤¦¤¦¤¦`; Table Create Table ¤¦¤¦¤¦ CREATE TABLE `¤¦¤¦¤¦` ( `¤¯¤¯¤¯` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `¤¨¤¨¤¨`; Table Create Table ¤¨¤¨¤¨ CREATE TEMPORARY TABLE `¤¨¤¨¤¨` ( `¤±¤±¤±` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `¤ª¤ª¤ª`; Table Create Table ¤ª¤ª¤ª CREATE TEMPORARY TABLE `¤ª¤ª¤ª` ( `¤³¤³¤³` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `íÝíÝíÝ`; Table Create Table íÝíÝíÝ CREATE TABLE `íÝíÝíÝ` ( `°¡°¡°¡` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `íÞíÞíÞ`; Table Create Table íÞíÞíÞ CREATE TABLE `íÞíÞíÞ` ( `°¢°¢°¢` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `íßíßíß`; Table Create Table íßíßíß CREATE TABLE `íßíßíß` ( `°£°£°£` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `íàíàíà`; Table Create Table íàíàíà CREATE TEMPORARY TABLE `íàíàíà` ( `°¤°¤°¤` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `íáíáíá`; Table Create Table íáíáíá CREATE TEMPORARY TABLE `íáíáíá` ( `°¥°¥°¥` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 DROP TABLE `ޱޱޱ`; DROP TABLE `޲޲޲`; DROP TABLE `޳޳޳`; @@ -490,11 +526,23 @@ CREATE TABLE ` CREATE TABLE `íÝíÝíÝ`(`°¡°¡°¡` char(1)) DEFAULT CHARSET = ucs2 engine=BDB; CREATE TABLE `íÞíÞíÞ`(`°¢°¢°¢` char(1)) DEFAULT CHARSET = ucs2 engine=BDB; CREATE TABLE IF NOT EXISTS `ޱޱޱ`(`޶޶޶` char(1)) DEFAULT CHARSET = ucs2 engine=BDB; +Warnings: +Note 1050 Table 'ޱޱޱ' already exists CREATE TABLE IF NOT EXISTS `޲޲޲`(`Ž·Ž·Ž·` char(1)) DEFAULT CHARSET = ucs2 engine=BDB; +Warnings: +Note 1050 Table '޲޲޲' already exists CREATE TABLE IF NOT EXISTS `¤¢¤¢¤¢`(`¤«¤«¤«` char(1)) DEFAULT CHARSET = ucs2 engine=BDB; +Warnings: +Note 1050 Table '¤¢¤¢¤¢' already exists CREATE TABLE IF NOT EXISTS `¤¤¤¤¤¤`(`¤­¤­¤­` char(1)) DEFAULT CHARSET = ucs2 engine=BDB; +Warnings: +Note 1050 Table '¤¤¤¤¤¤' already exists CREATE TABLE IF NOT EXISTS `íÝíÝíÝ`(`°¡°¡°¡` char(1)) DEFAULT CHARSET = ucs2 engine=BDB; +Warnings: +Note 1050 Table 'íÝíÝíÝ' already exists CREATE TABLE IF NOT EXISTS `íÞíÞíÞ`(`°¢°¢°¢` char(1)) DEFAULT CHARSET = ucs2 engine=BDB; +Warnings: +Note 1050 Table 'íÞíÞíÞ' already exists CREATE TABLE IF NOT EXISTS `޳޳޳`(`ޏޏޏ` char(1)) DEFAULT CHARSET = ucs2 engine=BDB; CREATE TABLE IF NOT EXISTS `¤¦¤¦¤¦`(`¤¯¤¯¤¯` char(1)) DEFAULT CHARSET = ucs2 engine=BDB; CREATE TABLE IF NOT EXISTS `íßíßíß`(`°£°£°£`char(1)) DEFAULT CHARSET = ucs2 engine=BDB; diff --git a/mysql-test/suite/jp/r/jp_create_tbl_ujis.result b/mysql-test/suite/jp/r/jp_create_tbl_ujis.result index ae555e5af15..f53e1e58793 100644 --- a/mysql-test/suite/jp/r/jp_create_tbl_ujis.result +++ b/mysql-test/suite/jp/r/jp_create_tbl_ujis.result @@ -22,11 +22,23 @@ CREATE TABLE ` CREATE TABLE `íÝíÝíÝ`(`°¡°¡°¡` char(1)) DEFAULT CHARSET = ujis engine=INNODB; CREATE TABLE `íÞíÞíÞ`(`°¢°¢°¢` char(1)) DEFAULT CHARSET = ujis engine=INNODB; CREATE TABLE IF NOT EXISTS `ޱޱޱ`(`޶޶޶` char(1)) DEFAULT CHARSET = ujis engine=INNODB; +Warnings: +Note 1050 Table 'ޱޱޱ' already exists CREATE TABLE IF NOT EXISTS `޲޲޲`(`Ž·Ž·Ž·` char(1)) DEFAULT CHARSET = ujis engine=INNODB; +Warnings: +Note 1050 Table '޲޲޲' already exists CREATE TABLE IF NOT EXISTS `¤¢¤¢¤¢`(`¤«¤«¤«` char(1)) DEFAULT CHARSET = ujis engine=INNODB; +Warnings: +Note 1050 Table '¤¢¤¢¤¢' already exists CREATE TABLE IF NOT EXISTS `¤¤¤¤¤¤`(`¤­¤­¤­` char(1)) DEFAULT CHARSET = ujis engine=INNODB; +Warnings: +Note 1050 Table '¤¤¤¤¤¤' already exists CREATE TABLE IF NOT EXISTS `íÝíÝíÝ`(`°¡°¡°¡` char(1)) DEFAULT CHARSET = ujis engine=INNODB; +Warnings: +Note 1050 Table 'íÝíÝíÝ' already exists CREATE TABLE IF NOT EXISTS `íÞíÞíÞ`(`°¢°¢°¢` char(1)) DEFAULT CHARSET = ujis engine=INNODB; +Warnings: +Note 1050 Table 'íÞíÞíÞ' already exists CREATE TABLE IF NOT EXISTS `޳޳޳`(`ޏޏޏ` char(1)) DEFAULT CHARSET = ujis engine=INNODB; CREATE TABLE IF NOT EXISTS `¤¦¤¦¤¦`(`¤¯¤¯¤¯` char(1)) DEFAULT CHARSET = ujis engine=INNODB; CREATE TABLE IF NOT EXISTS `íßíßíß`(`°£°£°£`char(1)) DEFAULT CHARSET = ujis engine=INNODB; @@ -178,11 +190,23 @@ CREATE TABLE ` CREATE TABLE `íÝíÝíÝ`(`°¡°¡°¡` char(1)) DEFAULT CHARSET = ujis engine=MyISAM; CREATE TABLE `íÞíÞíÞ`(`°¢°¢°¢` char(1)) DEFAULT CHARSET = ujis engine=MyISAM; CREATE TABLE IF NOT EXISTS `ޱޱޱ`(`޶޶޶` char(1)) DEFAULT CHARSET = ujis engine=MyISAM; +Warnings: +Note 1050 Table 'ޱޱޱ' already exists CREATE TABLE IF NOT EXISTS `޲޲޲`(`Ž·Ž·Ž·` char(1)) DEFAULT CHARSET = ujis engine=MyISAM; +Warnings: +Note 1050 Table '޲޲޲' already exists CREATE TABLE IF NOT EXISTS `¤¢¤¢¤¢`(`¤«¤«¤«` char(1)) DEFAULT CHARSET = ujis engine=MyISAM; +Warnings: +Note 1050 Table '¤¢¤¢¤¢' already exists CREATE TABLE IF NOT EXISTS `¤¤¤¤¤¤`(`¤­¤­¤­` char(1)) DEFAULT CHARSET = ujis engine=MyISAM; +Warnings: +Note 1050 Table '¤¤¤¤¤¤' already exists CREATE TABLE IF NOT EXISTS `íÝíÝíÝ`(`°¡°¡°¡` char(1)) DEFAULT CHARSET = ujis engine=MyISAM; +Warnings: +Note 1050 Table 'íÝíÝíÝ' already exists CREATE TABLE IF NOT EXISTS `íÞíÞíÞ`(`°¢°¢°¢` char(1)) DEFAULT CHARSET = ujis engine=MyISAM; +Warnings: +Note 1050 Table 'íÞíÞíÞ' already exists CREATE TABLE IF NOT EXISTS `޳޳޳`(`ޏޏޏ` char(1)) DEFAULT CHARSET = ujis engine=MyISAM; CREATE TABLE IF NOT EXISTS `¤¦¤¦¤¦`(`¤¯¤¯¤¯` char(1)) DEFAULT CHARSET = ujis engine=MyISAM; CREATE TABLE IF NOT EXISTS `íßíßíß`(`°£°£°£`char(1)) DEFAULT CHARSET = ujis engine=MyISAM; @@ -334,11 +358,23 @@ CREATE TABLE ` CREATE TABLE `íÝíÝíÝ`(`°¡°¡°¡` char(1)) DEFAULT CHARSET = ujis engine=HEAP; CREATE TABLE `íÞíÞíÞ`(`°¢°¢°¢` char(1)) DEFAULT CHARSET = ujis engine=HEAP; CREATE TABLE IF NOT EXISTS `ޱޱޱ`(`޶޶޶` char(1)) DEFAULT CHARSET = ujis engine=HEAP; +Warnings: +Note 1050 Table 'ޱޱޱ' already exists CREATE TABLE IF NOT EXISTS `޲޲޲`(`Ž·Ž·Ž·` char(1)) DEFAULT CHARSET = ujis engine=HEAP; +Warnings: +Note 1050 Table '޲޲޲' already exists CREATE TABLE IF NOT EXISTS `¤¢¤¢¤¢`(`¤«¤«¤«` char(1)) DEFAULT CHARSET = ujis engine=HEAP; +Warnings: +Note 1050 Table '¤¢¤¢¤¢' already exists CREATE TABLE IF NOT EXISTS `¤¤¤¤¤¤`(`¤­¤­¤­` char(1)) DEFAULT CHARSET = ujis engine=HEAP; +Warnings: +Note 1050 Table '¤¤¤¤¤¤' already exists CREATE TABLE IF NOT EXISTS `íÝíÝíÝ`(`°¡°¡°¡` char(1)) DEFAULT CHARSET = ujis engine=HEAP; +Warnings: +Note 1050 Table 'íÝíÝíÝ' already exists CREATE TABLE IF NOT EXISTS `íÞíÞíÞ`(`°¢°¢°¢` char(1)) DEFAULT CHARSET = ujis engine=HEAP; +Warnings: +Note 1050 Table 'íÞíÞíÞ' already exists CREATE TABLE IF NOT EXISTS `޳޳޳`(`ޏޏޏ` char(1)) DEFAULT CHARSET = ujis engine=HEAP; CREATE TABLE IF NOT EXISTS `¤¦¤¦¤¦`(`¤¯¤¯¤¯` char(1)) DEFAULT CHARSET = ujis engine=HEAP; CREATE TABLE IF NOT EXISTS `íßíßíß`(`°£°£°£`char(1)) DEFAULT CHARSET = ujis engine=HEAP; @@ -397,77 +433,77 @@ SHOW CREATE TABLE ` Table Create Table ޱޱޱ CREATE TABLE `ޱޱޱ` ( `޶޶޶` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `޲޲޲`; Table Create Table ޲޲޲ CREATE TABLE `޲޲޲` ( `Ž·Ž·Ž·` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `޳޳޳`; Table Create Table ޳޳޳ CREATE TABLE `޳޳޳` ( `ޏޏޏ` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `Ž´Ž´Ž´`; Table Create Table Ž´Ž´Ž´ CREATE TEMPORARY TABLE `Ž´Ž´Ž´` ( `޹޹޹` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `޵޵޵`; Table Create Table ޵޵޵ CREATE TEMPORARY TABLE `޵޵޵` ( `ŽºŽºŽº` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `¤¢¤¢¤¢`; Table Create Table ¤¢¤¢¤¢ CREATE TABLE `¤¢¤¢¤¢` ( `¤«¤«¤«` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `¤¤¤¤¤¤`; Table Create Table ¤¤¤¤¤¤ CREATE TABLE `¤¤¤¤¤¤` ( `¤­¤­¤­` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `¤¦¤¦¤¦`; Table Create Table ¤¦¤¦¤¦ CREATE TABLE `¤¦¤¦¤¦` ( `¤¯¤¯¤¯` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `¤¨¤¨¤¨`; Table Create Table ¤¨¤¨¤¨ CREATE TEMPORARY TABLE `¤¨¤¨¤¨` ( `¤±¤±¤±` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `¤ª¤ª¤ª`; Table Create Table ¤ª¤ª¤ª CREATE TEMPORARY TABLE `¤ª¤ª¤ª` ( `¤³¤³¤³` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `íÝíÝíÝ`; Table Create Table íÝíÝíÝ CREATE TABLE `íÝíÝíÝ` ( `°¡°¡°¡` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `íÞíÞíÞ`; Table Create Table íÞíÞíÞ CREATE TABLE `íÞíÞíÞ` ( `°¢°¢°¢` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `íßíßíß`; Table Create Table íßíßíß CREATE TABLE `íßíßíß` ( `°£°£°£` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `íàíàíà`; Table Create Table íàíàíà CREATE TEMPORARY TABLE `íàíàíà` ( `°¤°¤°¤` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `íáíáíá`; Table Create Table íáíáíá CREATE TEMPORARY TABLE `íáíáíá` ( `°¥°¥°¥` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis DROP TABLE `ޱޱޱ`; DROP TABLE `޲޲޲`; DROP TABLE `޳޳޳`; @@ -490,11 +526,23 @@ CREATE TABLE ` CREATE TABLE `íÝíÝíÝ`(`°¡°¡°¡` char(1)) DEFAULT CHARSET = ujis engine=BDB; CREATE TABLE `íÞíÞíÞ`(`°¢°¢°¢` char(1)) DEFAULT CHARSET = ujis engine=BDB; CREATE TABLE IF NOT EXISTS `ޱޱޱ`(`޶޶޶` char(1)) DEFAULT CHARSET = ujis engine=BDB; +Warnings: +Note 1050 Table 'ޱޱޱ' already exists CREATE TABLE IF NOT EXISTS `޲޲޲`(`Ž·Ž·Ž·` char(1)) DEFAULT CHARSET = ujis engine=BDB; +Warnings: +Note 1050 Table '޲޲޲' already exists CREATE TABLE IF NOT EXISTS `¤¢¤¢¤¢`(`¤«¤«¤«` char(1)) DEFAULT CHARSET = ujis engine=BDB; +Warnings: +Note 1050 Table '¤¢¤¢¤¢' already exists CREATE TABLE IF NOT EXISTS `¤¤¤¤¤¤`(`¤­¤­¤­` char(1)) DEFAULT CHARSET = ujis engine=BDB; +Warnings: +Note 1050 Table '¤¤¤¤¤¤' already exists CREATE TABLE IF NOT EXISTS `íÝíÝíÝ`(`°¡°¡°¡` char(1)) DEFAULT CHARSET = ujis engine=BDB; +Warnings: +Note 1050 Table 'íÝíÝíÝ' already exists CREATE TABLE IF NOT EXISTS `íÞíÞíÞ`(`°¢°¢°¢` char(1)) DEFAULT CHARSET = ujis engine=BDB; +Warnings: +Note 1050 Table 'íÞíÞíÞ' already exists CREATE TABLE IF NOT EXISTS `޳޳޳`(`ޏޏޏ` char(1)) DEFAULT CHARSET = ujis engine=BDB; CREATE TABLE IF NOT EXISTS `¤¦¤¦¤¦`(`¤¯¤¯¤¯` char(1)) DEFAULT CHARSET = ujis engine=BDB; CREATE TABLE IF NOT EXISTS `íßíßíß`(`°£°£°£`char(1)) DEFAULT CHARSET = ujis engine=BDB; diff --git a/mysql-test/suite/jp/r/jp_create_tbl_utf8.result b/mysql-test/suite/jp/r/jp_create_tbl_utf8.result index d4873406c46..6df30acbd7f 100644 --- a/mysql-test/suite/jp/r/jp_create_tbl_utf8.result +++ b/mysql-test/suite/jp/r/jp_create_tbl_utf8.result @@ -22,11 +22,23 @@ CREATE TABLE `ã„ã„ã„`(`ããã` char(1)) DEFAULT CHARSET = utf8 engine=INNO CREATE TABLE `é¾–é¾–é¾–`(`丂丂丂` char(1)) DEFAULT CHARSET = utf8 engine=INNODB; CREATE TABLE `é¾—é¾—é¾—`(`丄丄丄` char(1)) DEFAULT CHARSET = utf8 engine=INNODB; CREATE TABLE IF NOT EXISTS `アアア`(`ï½¶ï½¶ï½¶` char(1)) DEFAULT CHARSET = utf8 engine=INNODB; +Warnings: +Note 1050 Table 'アアア' already exists CREATE TABLE IF NOT EXISTS `イイイ`(`ï½·ï½·ï½·` char(1)) DEFAULT CHARSET = utf8 engine=INNODB; +Warnings: +Note 1050 Table 'イイイ' already exists CREATE TABLE IF NOT EXISTS `ã‚ã‚ã‚`(`ã‹ã‹ã‹` char(1)) DEFAULT CHARSET = utf8 engine=INNODB; +Warnings: +Note 1050 Table 'ã‚ã‚ã‚' already exists CREATE TABLE IF NOT EXISTS `ã„ã„ã„`(`ããã` char(1)) DEFAULT CHARSET = utf8 engine=INNODB; +Warnings: +Note 1050 Table 'ã„ã„ã„' already exists CREATE TABLE IF NOT EXISTS `é¾–é¾–é¾–`(`丂丂丂` char(1)) DEFAULT CHARSET = utf8 engine=INNODB; +Warnings: +Note 1050 Table 'é¾–é¾–é¾–' already exists CREATE TABLE IF NOT EXISTS `é¾—é¾—é¾—`(`丄丄丄` char(1)) DEFAULT CHARSET = utf8 engine=INNODB; +Warnings: +Note 1050 Table 'é¾—é¾—é¾—' already exists CREATE TABLE IF NOT EXISTS `ウウウ`(`ククク` char(1)) DEFAULT CHARSET = utf8 engine=INNODB; CREATE TABLE IF NOT EXISTS `ã†ã†ã†`(`ããã` char(1)) DEFAULT CHARSET = utf8 engine=INNODB; CREATE TABLE IF NOT EXISTS `龞龞龞`(`丅丅丅`char(1)) DEFAULT CHARSET = utf8 engine=INNODB; @@ -178,11 +190,23 @@ CREATE TABLE `ã„ã„ã„`(`ããã` char(1)) DEFAULT CHARSET = utf8 engine=MyIS CREATE TABLE `é¾–é¾–é¾–`(`丂丂丂` char(1)) DEFAULT CHARSET = utf8 engine=MyISAM; CREATE TABLE `é¾—é¾—é¾—`(`丄丄丄` char(1)) DEFAULT CHARSET = utf8 engine=MyISAM; CREATE TABLE IF NOT EXISTS `アアア`(`ï½¶ï½¶ï½¶` char(1)) DEFAULT CHARSET = utf8 engine=MyISAM; +Warnings: +Note 1050 Table 'アアア' already exists CREATE TABLE IF NOT EXISTS `イイイ`(`ï½·ï½·ï½·` char(1)) DEFAULT CHARSET = utf8 engine=MyISAM; +Warnings: +Note 1050 Table 'イイイ' already exists CREATE TABLE IF NOT EXISTS `ã‚ã‚ã‚`(`ã‹ã‹ã‹` char(1)) DEFAULT CHARSET = utf8 engine=MyISAM; +Warnings: +Note 1050 Table 'ã‚ã‚ã‚' already exists CREATE TABLE IF NOT EXISTS `ã„ã„ã„`(`ããã` char(1)) DEFAULT CHARSET = utf8 engine=MyISAM; +Warnings: +Note 1050 Table 'ã„ã„ã„' already exists CREATE TABLE IF NOT EXISTS `é¾–é¾–é¾–`(`丂丂丂` char(1)) DEFAULT CHARSET = utf8 engine=MyISAM; +Warnings: +Note 1050 Table 'é¾–é¾–é¾–' already exists CREATE TABLE IF NOT EXISTS `é¾—é¾—é¾—`(`丄丄丄` char(1)) DEFAULT CHARSET = utf8 engine=MyISAM; +Warnings: +Note 1050 Table 'é¾—é¾—é¾—' already exists CREATE TABLE IF NOT EXISTS `ウウウ`(`ククク` char(1)) DEFAULT CHARSET = utf8 engine=MyISAM; CREATE TABLE IF NOT EXISTS `ã†ã†ã†`(`ããã` char(1)) DEFAULT CHARSET = utf8 engine=MyISAM; CREATE TABLE IF NOT EXISTS `龞龞龞`(`丅丅丅`char(1)) DEFAULT CHARSET = utf8 engine=MyISAM; @@ -334,11 +358,23 @@ CREATE TABLE `ã„ã„ã„`(`ããã` char(1)) DEFAULT CHARSET = utf8 engine=HEAP CREATE TABLE `é¾–é¾–é¾–`(`丂丂丂` char(1)) DEFAULT CHARSET = utf8 engine=HEAP; CREATE TABLE `é¾—é¾—é¾—`(`丄丄丄` char(1)) DEFAULT CHARSET = utf8 engine=HEAP; CREATE TABLE IF NOT EXISTS `アアア`(`ï½¶ï½¶ï½¶` char(1)) DEFAULT CHARSET = utf8 engine=HEAP; +Warnings: +Note 1050 Table 'アアア' already exists CREATE TABLE IF NOT EXISTS `イイイ`(`ï½·ï½·ï½·` char(1)) DEFAULT CHARSET = utf8 engine=HEAP; +Warnings: +Note 1050 Table 'イイイ' already exists CREATE TABLE IF NOT EXISTS `ã‚ã‚ã‚`(`ã‹ã‹ã‹` char(1)) DEFAULT CHARSET = utf8 engine=HEAP; +Warnings: +Note 1050 Table 'ã‚ã‚ã‚' already exists CREATE TABLE IF NOT EXISTS `ã„ã„ã„`(`ããã` char(1)) DEFAULT CHARSET = utf8 engine=HEAP; +Warnings: +Note 1050 Table 'ã„ã„ã„' already exists CREATE TABLE IF NOT EXISTS `é¾–é¾–é¾–`(`丂丂丂` char(1)) DEFAULT CHARSET = utf8 engine=HEAP; +Warnings: +Note 1050 Table 'é¾–é¾–é¾–' already exists CREATE TABLE IF NOT EXISTS `é¾—é¾—é¾—`(`丄丄丄` char(1)) DEFAULT CHARSET = utf8 engine=HEAP; +Warnings: +Note 1050 Table 'é¾—é¾—é¾—' already exists CREATE TABLE IF NOT EXISTS `ウウウ`(`ククク` char(1)) DEFAULT CHARSET = utf8 engine=HEAP; CREATE TABLE IF NOT EXISTS `ã†ã†ã†`(`ããã` char(1)) DEFAULT CHARSET = utf8 engine=HEAP; CREATE TABLE IF NOT EXISTS `龞龞龞`(`丅丅丅`char(1)) DEFAULT CHARSET = utf8 engine=HEAP; @@ -397,77 +433,77 @@ SHOW CREATE TABLE `アアア`; Table Create Table アアア CREATE TABLE `アアア` ( `ï½¶ï½¶ï½¶` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `イイイ`; Table Create Table イイイ CREATE TABLE `イイイ` ( `ï½·ï½·ï½·` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `ウウウ`; Table Create Table ウウウ CREATE TABLE `ウウウ` ( `ククク` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `ï½´ï½´ï½´`; Table Create Table ï½´ï½´ï½´ CREATE TEMPORARY TABLE `ï½´ï½´ï½´` ( `ケケケ` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `オオオ`; Table Create Table オオオ CREATE TEMPORARY TABLE `オオオ` ( `コココ` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `ã‚ã‚ã‚`; Table Create Table ã‚ã‚ã‚ CREATE TABLE `ã‚ã‚ã‚` ( `ã‹ã‹ã‹` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `ã„ã„ã„`; Table Create Table ã„ã„ã„ CREATE TABLE `ã„ã„ã„` ( `ããã` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `ã†ã†ã†`; Table Create Table ã†ã†ã† CREATE TABLE `ã†ã†ã†` ( `ããã` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `ãˆãˆãˆ`; Table Create Table ãˆãˆãˆ CREATE TEMPORARY TABLE `ãˆãˆãˆ` ( `ã‘ã‘ã‘` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `ãŠãŠãŠ`; Table Create Table ãŠãŠãŠ CREATE TEMPORARY TABLE `ãŠãŠãŠ` ( `ã“ã“ã“` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `é¾–é¾–é¾–`; Table Create Table é¾–é¾–é¾– CREATE TABLE `é¾–é¾–é¾–` ( `丂丂丂` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `é¾—é¾—é¾—`; Table Create Table é¾—é¾—é¾— CREATE TABLE `é¾—é¾—é¾—` ( `丄丄丄` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `龞龞龞`; Table Create Table 龞龞龞 CREATE TABLE `龞龞龞` ( `丅丅丅` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `龡龡龡`; Table Create Table 龡龡龡 CREATE TEMPORARY TABLE `龡龡龡` ( `丌丌丌` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `龢龢龢`; Table Create Table 龢龢龢 CREATE TEMPORARY TABLE `龢龢龢` ( `丒丒丒` char(1) default NULL -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 DROP TABLE `アアア`; DROP TABLE `イイイ`; DROP TABLE `ウウウ`; @@ -490,11 +526,23 @@ CREATE TABLE `ã„ã„ã„`(`ããã` char(1)) DEFAULT CHARSET = utf8 engine=BDB; CREATE TABLE `é¾–é¾–é¾–`(`丂丂丂` char(1)) DEFAULT CHARSET = utf8 engine=BDB; CREATE TABLE `é¾—é¾—é¾—`(`丄丄丄` char(1)) DEFAULT CHARSET = utf8 engine=BDB; CREATE TABLE IF NOT EXISTS `アアア`(`ï½¶ï½¶ï½¶` char(1)) DEFAULT CHARSET = utf8 engine=BDB; +Warnings: +Note 1050 Table 'アアア' already exists CREATE TABLE IF NOT EXISTS `イイイ`(`ï½·ï½·ï½·` char(1)) DEFAULT CHARSET = utf8 engine=BDB; +Warnings: +Note 1050 Table 'イイイ' already exists CREATE TABLE IF NOT EXISTS `ã‚ã‚ã‚`(`ã‹ã‹ã‹` char(1)) DEFAULT CHARSET = utf8 engine=BDB; +Warnings: +Note 1050 Table 'ã‚ã‚ã‚' already exists CREATE TABLE IF NOT EXISTS `ã„ã„ã„`(`ããã` char(1)) DEFAULT CHARSET = utf8 engine=BDB; +Warnings: +Note 1050 Table 'ã„ã„ã„' already exists CREATE TABLE IF NOT EXISTS `é¾–é¾–é¾–`(`丂丂丂` char(1)) DEFAULT CHARSET = utf8 engine=BDB; +Warnings: +Note 1050 Table 'é¾–é¾–é¾–' already exists CREATE TABLE IF NOT EXISTS `é¾—é¾—é¾—`(`丄丄丄` char(1)) DEFAULT CHARSET = utf8 engine=BDB; +Warnings: +Note 1050 Table 'é¾—é¾—é¾—' already exists CREATE TABLE IF NOT EXISTS `ウウウ`(`ククク` char(1)) DEFAULT CHARSET = utf8 engine=BDB; CREATE TABLE IF NOT EXISTS `ã†ã†ã†`(`ããã` char(1)) DEFAULT CHARSET = utf8 engine=BDB; CREATE TABLE IF NOT EXISTS `龞龞龞`(`丅丅丅`char(1)) DEFAULT CHARSET = utf8 engine=BDB; diff --git a/mysql-test/suite/jp/r/jp_enum_sjis.result b/mysql-test/suite/jp/r/jp_enum_sjis.result index 1e46dbffbb1..43994123e3b 100644 --- a/mysql-test/suite/jp/r/jp_enum_sjis.result +++ b/mysql-test/suite/jp/r/jp_enum_sjis.result @@ -137,19 +137,19 @@ Table Create Table ‚s‚V CREATE TABLE `‚s‚V` ( `‚b‚P` enum('±','²','³') default NULL, KEY `‚b‚P` (`‚b‚P`) -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚s‚W`; Table Create Table ‚s‚W CREATE TABLE `‚s‚W` ( `‚b‚P` enum('‚ ','‚¢','‚¤') default NULL, KEY `‚b‚P` (`‚b‚P`) -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚s‚X`; Table Create Table ‚s‚X CREATE TABLE `‚s‚X` ( `‚b‚P` enum('ƒ\','\','•\') default NULL, KEY `‚b‚P` (`‚b‚P`) -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚s‚P‚O`; Table Create Table ‚s‚P‚O CREATE TABLE `‚s‚P‚O` ( @@ -219,134 +219,134 @@ ALTER TABLE ` SHOW CREATE TABLE `‚s‚P`; Table Create Table ‚s‚P CREATE TABLE `‚s‚P` ( - `‚b‚Q` char(1) NOT NULL default '', + `‚b‚Q` char(1) NOT NULL, `‚b‚P` enum('±','²','³') default NULL, KEY `‚b‚P` (`‚b‚P`) ) ENGINE=InnoDB DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚s‚Q`; Table Create Table ‚s‚Q CREATE TABLE `‚s‚Q` ( - `‚b‚Q` char(1) NOT NULL default '', + `‚b‚Q` char(1) NOT NULL, `‚b‚P` enum('‚ ','‚¢','‚¤') default NULL, KEY `‚b‚P` (`‚b‚P`) ) ENGINE=InnoDB DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚s‚R`; Table Create Table ‚s‚R CREATE TABLE `‚s‚R` ( - `‚b‚Q` char(1) NOT NULL default '', + `‚b‚Q` char(1) NOT NULL, `‚b‚P` enum('ƒ\','\','•\') default NULL, KEY `‚b‚P` (`‚b‚P`) ) ENGINE=InnoDB DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚s‚S`; Table Create Table ‚s‚S CREATE TABLE `‚s‚S` ( - `‚b‚Q` char(1) NOT NULL default '', + `‚b‚Q` char(1) NOT NULL, `‚b‚P` enum('±','²','³') default NULL, KEY `‚b‚P` (`‚b‚P`) ) ENGINE=MyISAM DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚s‚T`; Table Create Table ‚s‚T CREATE TABLE `‚s‚T` ( - `‚b‚Q` char(1) NOT NULL default '', + `‚b‚Q` char(1) NOT NULL, `‚b‚P` enum('‚ ','‚¢','‚¤') default NULL, KEY `‚b‚P` (`‚b‚P`) ) ENGINE=MyISAM DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚s‚U`; Table Create Table ‚s‚U CREATE TABLE `‚s‚U` ( - `‚b‚Q` char(1) NOT NULL default '', + `‚b‚Q` char(1) NOT NULL, `‚b‚P` enum('ƒ\','\','•\') default NULL, KEY `‚b‚P` (`‚b‚P`) ) ENGINE=MyISAM DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚s‚V`; Table Create Table ‚s‚V CREATE TABLE `‚s‚V` ( - `‚b‚Q` char(1) NOT NULL default '', + `‚b‚Q` char(1) NOT NULL, `‚b‚P` enum('±','²','³') default NULL, KEY `‚b‚P` (`‚b‚P`) -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚s‚W`; Table Create Table ‚s‚W CREATE TABLE `‚s‚W` ( - `‚b‚Q` char(1) NOT NULL default '', + `‚b‚Q` char(1) NOT NULL, `‚b‚P` enum('‚ ','‚¢','‚¤') default NULL, KEY `‚b‚P` (`‚b‚P`) -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚s‚X`; Table Create Table ‚s‚X CREATE TABLE `‚s‚X` ( - `‚b‚Q` char(1) NOT NULL default '', + `‚b‚Q` char(1) NOT NULL, `‚b‚P` enum('ƒ\','\','•\') default NULL, KEY `‚b‚P` (`‚b‚P`) -) ENGINE=HEAP DEFAULT CHARSET=sjis +) ENGINE=MEMORY DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚s‚P‚O`; Table Create Table ‚s‚P‚O CREATE TABLE `‚s‚P‚O` ( - `‚b‚Q` char(1) NOT NULL default '', + `‚b‚Q` char(1) NOT NULL, `‚b‚P` enum('±','²','³') default NULL, KEY `‚b‚P` (`‚b‚P`) ) ENGINE=BerkeleyDB DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚s‚P‚P`; Table Create Table ‚s‚P‚P CREATE TABLE `‚s‚P‚P` ( - `‚b‚Q` char(1) NOT NULL default '', + `‚b‚Q` char(1) NOT NULL, `‚b‚P` enum('‚ ','‚¢','‚¤') default NULL, KEY `‚b‚P` (`‚b‚P`) ) ENGINE=BerkeleyDB DEFAULT CHARSET=sjis SHOW CREATE TABLE `‚s‚P‚Q`; Table Create Table ‚s‚P‚Q CREATE TABLE `‚s‚P‚Q` ( - `‚b‚Q` char(1) NOT NULL default '', + `‚b‚Q` char(1) NOT NULL, `‚b‚P` enum('ƒ\','\','•\') default NULL, KEY `‚b‚P` (`‚b‚P`) ) ENGINE=BerkeleyDB DEFAULT CHARSET=sjis DESC `‚s‚P`; Field Type Null Key Default Extra -‚b‚Q char(1) +‚b‚Q char(1) NO NULL ‚b‚P enum('±','²','³') YES MUL NULL DESC `‚s‚Q`; Field Type Null Key Default Extra -‚b‚Q char(1) +‚b‚Q char(1) NO NULL ‚b‚P enum('‚ ','‚¢','‚¤') YES MUL NULL DESC `‚s‚R`; Field Type Null Key Default Extra -‚b‚Q char(1) +‚b‚Q char(1) NO NULL ‚b‚P enum('ƒ\','\','•\') YES MUL NULL DESC `‚s‚S`; Field Type Null Key Default Extra -‚b‚Q char(1) +‚b‚Q char(1) NO NULL ‚b‚P enum('±','²','³') YES MUL NULL DESC `‚s‚T`; Field Type Null Key Default Extra -‚b‚Q char(1) +‚b‚Q char(1) NO NULL ‚b‚P enum('‚ ','‚¢','‚¤') YES MUL NULL DESC `‚s‚U`; Field Type Null Key Default Extra -‚b‚Q char(1) +‚b‚Q char(1) NO NULL ‚b‚P enum('ƒ\','\','•\') YES MUL NULL DESC `‚s‚V`; Field Type Null Key Default Extra -‚b‚Q char(1) +‚b‚Q char(1) NO NULL ‚b‚P enum('±','²','³') YES MUL NULL DESC `‚s‚W`; Field Type Null Key Default Extra -‚b‚Q char(1) +‚b‚Q char(1) NO NULL ‚b‚P enum('‚ ','‚¢','‚¤') YES MUL NULL DESC `‚s‚X`; Field Type Null Key Default Extra -‚b‚Q char(1) +‚b‚Q char(1) NO NULL ‚b‚P enum('ƒ\','\','•\') YES MUL NULL DESC `‚s‚P‚O`; Field Type Null Key Default Extra -‚b‚Q char(1) +‚b‚Q char(1) NO NULL ‚b‚P enum('±','²','³') YES MUL NULL DESC `‚s‚P‚P`; Field Type Null Key Default Extra -‚b‚Q char(1) +‚b‚Q char(1) NO NULL ‚b‚P enum('‚ ','‚¢','‚¤') YES MUL NULL DESC `‚s‚P‚Q`; Field Type Null Key Default Extra -‚b‚Q char(1) +‚b‚Q char(1) NO NULL ‚b‚P enum('ƒ\','\','•\') YES MUL NULL DROP TABLE `‚s‚P`; DROP TABLE `‚s‚Q`; diff --git a/mysql-test/suite/jp/r/jp_enum_ucs2.result b/mysql-test/suite/jp/r/jp_enum_ucs2.result index a84cace35fe..c41e6c262eb 100644 --- a/mysql-test/suite/jp/r/jp_enum_ucs2.result +++ b/mysql-test/suite/jp/r/jp_enum_ucs2.result @@ -138,19 +138,19 @@ Table Create Table £Ô£· CREATE TABLE `£Ô£·` ( `£Ã£±` enum('ޱ','޲','޳') default NULL, KEY `£Ã£±` (`£Ã£±`) -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `£Ô£¸`; Table Create Table £Ô£¸ CREATE TABLE `£Ô£¸` ( `£Ã£±` enum('¤¢','¤¤','¤¦') default NULL, KEY `£Ã£±` (`£Ã£±`) -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `£Ô£¹`; Table Create Table £Ô£¹ CREATE TABLE `£Ô£¹` ( `£Ã£±` enum('íÜ','íÝ','íÞ') default NULL, KEY `£Ã£±` (`£Ã£±`) -) ENGINE=HEAP DEFAULT CHARSET=ucs2 +) ENGINE=MEMORY DEFAULT CHARSET=ucs2 SHOW CREATE TABLE `£Ô£±£°`; Table Create Table £Ô£±£° CREATE TABLE `£Ô£±£°` ( diff --git a/mysql-test/suite/jp/r/jp_enum_ujis.result b/mysql-test/suite/jp/r/jp_enum_ujis.result index dbc850b1368..9ba445eaba5 100644 --- a/mysql-test/suite/jp/r/jp_enum_ujis.result +++ b/mysql-test/suite/jp/r/jp_enum_ujis.result @@ -137,19 +137,19 @@ Table Create Table £Ô£· CREATE TABLE `£Ô£·` ( `£Ã£±` enum('ޱ','޲','޳') default NULL, KEY `£Ã£±` (`£Ã£±`) -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `£Ô£¸`; Table Create Table £Ô£¸ CREATE TABLE `£Ô£¸` ( `£Ã£±` enum('¤¢','¤¤','¤¦') default NULL, KEY `£Ã£±` (`£Ã£±`) -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `£Ô£¹`; Table Create Table £Ô£¹ CREATE TABLE `£Ô£¹` ( `£Ã£±` enum('íÜ','íÝ','íÞ') default NULL, KEY `£Ã£±` (`£Ã£±`) -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `£Ô£±£°`; Table Create Table £Ô£±£° CREATE TABLE `£Ô£±£°` ( @@ -219,134 +219,134 @@ ALTER TABLE ` SHOW CREATE TABLE `£Ô£±`; Table Create Table £Ô£± CREATE TABLE `£Ô£±` ( - `£Ã£²` char(1) NOT NULL default '', + `£Ã£²` char(1) NOT NULL, `£Ã£±` enum('ޱ','޲','޳') default NULL, KEY `£Ã£±` (`£Ã£±`) ) ENGINE=InnoDB DEFAULT CHARSET=ujis SHOW CREATE TABLE `£Ô£²`; Table Create Table £Ô£² CREATE TABLE `£Ô£²` ( - `£Ã£²` char(1) NOT NULL default '', + `£Ã£²` char(1) NOT NULL, `£Ã£±` enum('¤¢','¤¤','¤¦') default NULL, KEY `£Ã£±` (`£Ã£±`) ) ENGINE=InnoDB DEFAULT CHARSET=ujis SHOW CREATE TABLE `£Ô£³`; Table Create Table £Ô£³ CREATE TABLE `£Ô£³` ( - `£Ã£²` char(1) NOT NULL default '', + `£Ã£²` char(1) NOT NULL, `£Ã£±` enum('íÜ','íÝ','íÞ') default NULL, KEY `£Ã£±` (`£Ã£±`) ) ENGINE=InnoDB DEFAULT CHARSET=ujis SHOW CREATE TABLE `£Ô£´`; Table Create Table £Ô£´ CREATE TABLE `£Ô£´` ( - `£Ã£²` char(1) NOT NULL default '', + `£Ã£²` char(1) NOT NULL, `£Ã£±` enum('ޱ','޲','޳') default NULL, KEY `£Ã£±` (`£Ã£±`) ) ENGINE=MyISAM DEFAULT CHARSET=ujis SHOW CREATE TABLE `£Ô£µ`; Table Create Table £Ô£µ CREATE TABLE `£Ô£µ` ( - `£Ã£²` char(1) NOT NULL default '', + `£Ã£²` char(1) NOT NULL, `£Ã£±` enum('¤¢','¤¤','¤¦') default NULL, KEY `£Ã£±` (`£Ã£±`) ) ENGINE=MyISAM DEFAULT CHARSET=ujis SHOW CREATE TABLE `£Ô£¶`; Table Create Table £Ô£¶ CREATE TABLE `£Ô£¶` ( - `£Ã£²` char(1) NOT NULL default '', + `£Ã£²` char(1) NOT NULL, `£Ã£±` enum('íÜ','íÝ','íÞ') default NULL, KEY `£Ã£±` (`£Ã£±`) ) ENGINE=MyISAM DEFAULT CHARSET=ujis SHOW CREATE TABLE `£Ô£·`; Table Create Table £Ô£· CREATE TABLE `£Ô£·` ( - `£Ã£²` char(1) NOT NULL default '', + `£Ã£²` char(1) NOT NULL, `£Ã£±` enum('ޱ','޲','޳') default NULL, KEY `£Ã£±` (`£Ã£±`) -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `£Ô£¸`; Table Create Table £Ô£¸ CREATE TABLE `£Ô£¸` ( - `£Ã£²` char(1) NOT NULL default '', + `£Ã£²` char(1) NOT NULL, `£Ã£±` enum('¤¢','¤¤','¤¦') default NULL, KEY `£Ã£±` (`£Ã£±`) -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `£Ô£¹`; Table Create Table £Ô£¹ CREATE TABLE `£Ô£¹` ( - `£Ã£²` char(1) NOT NULL default '', + `£Ã£²` char(1) NOT NULL, `£Ã£±` enum('íÜ','íÝ','íÞ') default NULL, KEY `£Ã£±` (`£Ã£±`) -) ENGINE=HEAP DEFAULT CHARSET=ujis +) ENGINE=MEMORY DEFAULT CHARSET=ujis SHOW CREATE TABLE `£Ô£±£°`; Table Create Table £Ô£±£° CREATE TABLE `£Ô£±£°` ( - `£Ã£²` char(1) NOT NULL default '', + `£Ã£²` char(1) NOT NULL, `£Ã£±` enum('ޱ','޲','޳') default NULL, KEY `£Ã£±` (`£Ã£±`) ) ENGINE=BerkeleyDB DEFAULT CHARSET=ujis SHOW CREATE TABLE `£Ô£±£±`; Table Create Table £Ô£±£± CREATE TABLE `£Ô£±£±` ( - `£Ã£²` char(1) NOT NULL default '', + `£Ã£²` char(1) NOT NULL, `£Ã£±` enum('¤¢','¤¤','¤¦') default NULL, KEY `£Ã£±` (`£Ã£±`) ) ENGINE=BerkeleyDB DEFAULT CHARSET=ujis SHOW CREATE TABLE `£Ô£±£²`; Table Create Table £Ô£±£² CREATE TABLE `£Ô£±£²` ( - `£Ã£²` char(1) NOT NULL default '', + `£Ã£²` char(1) NOT NULL, `£Ã£±` enum('íÜ','íÝ','íÞ') default NULL, KEY `£Ã£±` (`£Ã£±`) ) ENGINE=BerkeleyDB DEFAULT CHARSET=ujis DESC `£Ô£±`; Field Type Null Key Default Extra -£Ã£² char(1) +£Ã£² char(1) NO NULL £Ã£± enum('ޱ','޲','޳') YES MUL NULL DESC `£Ô£²`; Field Type Null Key Default Extra -£Ã£² char(1) +£Ã£² char(1) NO NULL £Ã£± enum('¤¢','¤¤','¤¦') YES MUL NULL DESC `£Ô£³`; Field Type Null Key Default Extra -£Ã£² char(1) +£Ã£² char(1) NO NULL £Ã£± enum('íÜ','íÝ','íÞ') YES MUL NULL DESC `£Ô£´`; Field Type Null Key Default Extra -£Ã£² char(1) +£Ã£² char(1) NO NULL £Ã£± enum('ޱ','޲','޳') YES MUL NULL DESC `£Ô£µ`; Field Type Null Key Default Extra -£Ã£² char(1) +£Ã£² char(1) NO NULL £Ã£± enum('¤¢','¤¤','¤¦') YES MUL NULL DESC `£Ô£¶`; Field Type Null Key Default Extra -£Ã£² char(1) +£Ã£² char(1) NO NULL £Ã£± enum('íÜ','íÝ','íÞ') YES MUL NULL DESC `£Ô£·`; Field Type Null Key Default Extra -£Ã£² char(1) +£Ã£² char(1) NO NULL £Ã£± enum('ޱ','޲','޳') YES MUL NULL DESC `£Ô£¸`; Field Type Null Key Default Extra -£Ã£² char(1) +£Ã£² char(1) NO NULL £Ã£± enum('¤¢','¤¤','¤¦') YES MUL NULL DESC `£Ô£¹`; Field Type Null Key Default Extra -£Ã£² char(1) +£Ã£² char(1) NO NULL £Ã£± enum('íÜ','íÝ','íÞ') YES MUL NULL DESC `£Ô£±£°`; Field Type Null Key Default Extra -£Ã£² char(1) +£Ã£² char(1) NO NULL £Ã£± enum('ޱ','޲','޳') YES MUL NULL DESC `£Ô£±£±`; Field Type Null Key Default Extra -£Ã£² char(1) +£Ã£² char(1) NO NULL £Ã£± enum('¤¢','¤¤','¤¦') YES MUL NULL DESC `£Ô£±£²`; Field Type Null Key Default Extra -£Ã£² char(1) +£Ã£² char(1) NO NULL £Ã£± enum('íÜ','íÝ','íÞ') YES MUL NULL DROP TABLE `£Ô£±`; DROP TABLE `£Ô£²`; diff --git a/mysql-test/suite/jp/r/jp_enum_utf8.result b/mysql-test/suite/jp/r/jp_enum_utf8.result index f2515871ece..c4ff9193447 100644 --- a/mysql-test/suite/jp/r/jp_enum_utf8.result +++ b/mysql-test/suite/jp/r/jp_enum_utf8.result @@ -137,19 +137,19 @@ Table Create Table ï¼´ï¼— CREATE TABLE `ï¼´ï¼—` ( `C1` enum('ï½±','ï½²','ï½³') default NULL, KEY `C1` (`C1`) -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `T8`; Table Create Table T8 CREATE TABLE `T8` ( `C1` enum('ã‚','ã„','ã†') default NULL, KEY `C1` (`C1`) -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `ï¼´ï¼™`; Table Create Table ï¼´ï¼™ CREATE TABLE `ï¼´ï¼™` ( `C1` enum('é¾”','é¾–','é¾—') default NULL, KEY `C1` (`C1`) -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `T1ï¼`; Table Create Table ï¼´ï¼‘ï¼ CREATE TABLE `T1ï¼` ( @@ -219,134 +219,134 @@ ALTER TABLE `T12` ADD `C2` CHAR(1) NOT NULL FIRST; SHOW CREATE TABLE `T1`; Table Create Table T1 CREATE TABLE `T1` ( - `C2` char(1) NOT NULL default '', + `C2` char(1) NOT NULL, `C1` enum('ï½±','ï½²','ï½³') default NULL, KEY `C1` (`C1`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 SHOW CREATE TABLE `ï¼´ï¼’`; Table Create Table ï¼´ï¼’ CREATE TABLE `ï¼´ï¼’` ( - `C2` char(1) NOT NULL default '', + `C2` char(1) NOT NULL, `C1` enum('ã‚','ã„','ã†') default NULL, KEY `C1` (`C1`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 SHOW CREATE TABLE `T3`; Table Create Table T3 CREATE TABLE `T3` ( - `C2` char(1) NOT NULL default '', + `C2` char(1) NOT NULL, `C1` enum('é¾”','é¾–','é¾—') default NULL, KEY `C1` (`C1`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 SHOW CREATE TABLE `ï¼´ï¼”`; Table Create Table ï¼´ï¼” CREATE TABLE `ï¼´ï¼”` ( - `C2` char(1) NOT NULL default '', + `C2` char(1) NOT NULL, `C1` enum('ï½±','ï½²','ï½³') default NULL, KEY `C1` (`C1`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 SHOW CREATE TABLE `T5`; Table Create Table T5 CREATE TABLE `T5` ( - `C2` char(1) NOT NULL default '', + `C2` char(1) NOT NULL, `C1` enum('ã‚','ã„','ã†') default NULL, KEY `C1` (`C1`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 SHOW CREATE TABLE `ï¼´ï¼–`; Table Create Table ï¼´ï¼– CREATE TABLE `ï¼´ï¼–` ( - `C2` char(1) NOT NULL default '', + `C2` char(1) NOT NULL, `C1` enum('é¾”','é¾–','é¾—') default NULL, KEY `C1` (`C1`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 SHOW CREATE TABLE `ï¼´ï¼—`; Table Create Table ï¼´ï¼— CREATE TABLE `ï¼´ï¼—` ( - `C2` char(1) NOT NULL default '', + `C2` char(1) NOT NULL, `C1` enum('ï½±','ï½²','ï½³') default NULL, KEY `C1` (`C1`) -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `T8`; Table Create Table T8 CREATE TABLE `T8` ( - `C2` char(1) NOT NULL default '', + `C2` char(1) NOT NULL, `C1` enum('ã‚','ã„','ã†') default NULL, KEY `C1` (`C1`) -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `ï¼´ï¼™`; Table Create Table ï¼´ï¼™ CREATE TABLE `ï¼´ï¼™` ( - `C2` char(1) NOT NULL default '', + `C2` char(1) NOT NULL, `C1` enum('é¾”','é¾–','é¾—') default NULL, KEY `C1` (`C1`) -) ENGINE=HEAP DEFAULT CHARSET=utf8 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 SHOW CREATE TABLE `T1ï¼`; Table Create Table ï¼´ï¼‘ï¼ CREATE TABLE `T1ï¼` ( - `C2` char(1) NOT NULL default '', + `C2` char(1) NOT NULL, `C1` enum('ï½±','ï½²','ï½³') default NULL, KEY `C1` (`C1`) ) ENGINE=BerkeleyDB DEFAULT CHARSET=utf8 SHOW CREATE TABLE `T11`; Table Create Table T11 CREATE TABLE `T11` ( - `C2` char(1) NOT NULL default '', + `C2` char(1) NOT NULL, `C1` enum('ã‚','ã„','ã†') default NULL, KEY `C1` (`C1`) ) ENGINE=BerkeleyDB DEFAULT CHARSET=utf8 SHOW CREATE TABLE `T12`; Table Create Table T12 CREATE TABLE `T12` ( - `C2` char(1) NOT NULL default '', + `C2` char(1) NOT NULL, `C1` enum('é¾”','é¾–','é¾—') default NULL, KEY `C1` (`C1`) ) ENGINE=BerkeleyDB DEFAULT CHARSET=utf8 DESC `T1`; Field Type Null Key Default Extra -C2 char(1) +C2 char(1) NO NULL C1 enum('ï½±','ï½²','ï½³') YES MUL NULL DESC `ï¼´ï¼’`; Field Type Null Key Default Extra -C2 char(1) +C2 char(1) NO NULL C1 enum('ã‚','ã„','ã†') YES MUL NULL DESC `T3`; Field Type Null Key Default Extra -C2 char(1) +C2 char(1) NO NULL C1 enum('é¾”','é¾–','é¾—') YES MUL NULL DESC `ï¼´ï¼”`; Field Type Null Key Default Extra -C2 char(1) +C2 char(1) NO NULL C1 enum('ï½±','ï½²','ï½³') YES MUL NULL DESC `T5`; Field Type Null Key Default Extra -C2 char(1) +C2 char(1) NO NULL C1 enum('ã‚','ã„','ã†') YES MUL NULL DESC `ï¼´ï¼–`; Field Type Null Key Default Extra -C2 char(1) +C2 char(1) NO NULL C1 enum('é¾”','é¾–','é¾—') YES MUL NULL DESC `ï¼´ï¼—`; Field Type Null Key Default Extra -C2 char(1) +C2 char(1) NO NULL C1 enum('ï½±','ï½²','ï½³') YES MUL NULL DESC `T8`; Field Type Null Key Default Extra -C2 char(1) +C2 char(1) NO NULL C1 enum('ã‚','ã„','ã†') YES MUL NULL DESC `ï¼´ï¼™`; Field Type Null Key Default Extra -C2 char(1) +C2 char(1) NO NULL C1 enum('é¾”','é¾–','é¾—') YES MUL NULL DESC `T1ï¼`; Field Type Null Key Default Extra -C2 char(1) +C2 char(1) NO NULL C1 enum('ï½±','ï½²','ï½³') YES MUL NULL DESC `T11`; Field Type Null Key Default Extra -C2 char(1) +C2 char(1) NO NULL C1 enum('ã‚','ã„','ã†') YES MUL NULL DESC `T12`; Field Type Null Key Default Extra -C2 char(1) +C2 char(1) NO NULL C1 enum('é¾”','é¾–','é¾—') YES MUL NULL DROP TABLE `T1`; DROP TABLE `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/r/jp_join_sjis.result b/mysql-test/suite/jp/r/jp_join_sjis.result index a5ccc58ae4c..95df2d5488e 100644 --- a/mysql-test/suite/jp/r/jp_join_sjis.result +++ b/mysql-test/suite/jp/r/jp_join_sjis.result @@ -71,31 +71,31 @@ SELECT * FROM ` ¶ ± » ± SELECT * FROM `‚s‚Pa` JOIN `‚s‚Pb` USING (`‚b‚P`); -‚b‚P ‚b‚P -± ± +‚b‚P +± SELECT * FROM `‚s‚Pa` INNER JOIN `‚s‚Pb` USING (`‚b‚P`); -‚b‚P ‚b‚P -± ± +‚b‚P +± SELECT * FROM `‚s‚Pa` CROSS JOIN `‚s‚Pb`; ‚b‚P ‚b‚P ± ± ¶ ± » ± SELECT * FROM `‚s‚Pa` LEFT JOIN `‚s‚Pb` USING (`‚b‚P`); -‚b‚P ‚b‚P -± ± -¶ NULL -» NULL +‚b‚P +± +¶ +» SELECT * FROM `‚s‚Pa` LEFT JOIN `‚s‚Pb` ON (`‚s‚Pa`.`‚b‚P` = `‚s‚Pb`.`‚b‚P`); ‚b‚P ‚b‚P ± ± ¶ NULL » NULL SELECT * FROM `‚s‚Pb` RIGHT JOIN `‚s‚Pa` USING (`‚b‚P`); -‚b‚P ‚b‚P -± ± -NULL ¶ -NULL » +‚b‚P +± +¶ +» SELECT * FROM `‚s‚Pb` RIGHT JOIN `‚s‚Pa` ON (`‚s‚Pa`.`‚b‚P` = `‚s‚Pb`.`‚b‚P`); ‚b‚P ‚b‚P ± ± @@ -112,31 +112,31 @@ SELECT * FROM ` ‚© ‚  ‚³ ‚  SELECT * FROM `‚s‚Qa` JOIN `‚s‚Qb` USING (`‚b‚P`); -‚b‚P ‚b‚P -‚  ‚  +‚b‚P +‚  SELECT * FROM `‚s‚Qa` INNER JOIN `‚s‚Qb` USING (`‚b‚P`); -‚b‚P ‚b‚P -‚  ‚  +‚b‚P +‚  SELECT * FROM `‚s‚Qa` CROSS JOIN `‚s‚Qb`; ‚b‚P ‚b‚P ‚  ‚  ‚© ‚  ‚³ ‚  SELECT * FROM `‚s‚Qa` LEFT JOIN `‚s‚Qb` USING (`‚b‚P`); -‚b‚P ‚b‚P -‚  ‚  -‚© NULL -‚³ NULL +‚b‚P +‚  +‚© +‚³ SELECT * FROM `‚s‚Qa` LEFT JOIN `‚s‚Qb` ON (`‚s‚Qa`.`‚b‚P` = `‚s‚Qb`.`‚b‚P`); ‚b‚P ‚b‚P ‚  ‚  ‚© NULL ‚³ NULL SELECT * FROM `‚s‚Qb` RIGHT JOIN `‚s‚Qa` USING (`‚b‚P`); -‚b‚P ‚b‚P -‚  ‚  -NULL ‚© -NULL ‚³ +‚b‚P +‚  +‚© +‚³ SELECT * FROM `‚s‚Qb` RIGHT JOIN `‚s‚Qa` ON (`‚s‚Qa`.`‚b‚P` = `‚s‚Qb`.`‚b‚P`); ‚b‚P ‚b‚P ‚  ‚  @@ -153,31 +153,31 @@ SELECT * FROM ` \ ƒ\ •\ ƒ\ SELECT * FROM `‚s‚Ra` JOIN `‚s‚Rb` USING (`‚b‚P`); -‚b‚P ‚b‚P -ƒ\ ƒ\ +‚b‚P +ƒ\ SELECT * FROM `‚s‚Ra` INNER JOIN `‚s‚Rb` USING (`‚b‚P`); -‚b‚P ‚b‚P -ƒ\ ƒ\ +‚b‚P +ƒ\ SELECT * FROM `‚s‚Ra` CROSS JOIN `‚s‚Rb`; ‚b‚P ‚b‚P ƒ\ ƒ\ \ ƒ\ •\ ƒ\ SELECT * FROM `‚s‚Ra` LEFT JOIN `‚s‚Rb` USING (`‚b‚P`); -‚b‚P ‚b‚P -ƒ\ ƒ\ -\ NULL -•\ NULL +‚b‚P +ƒ\ +\ +•\ SELECT * FROM `‚s‚Ra` LEFT JOIN `‚s‚Rb` ON (`‚s‚Ra`.`‚b‚P` = `‚s‚Rb`.`‚b‚P`); ‚b‚P ‚b‚P ƒ\ ƒ\ \ NULL •\ NULL SELECT * FROM `‚s‚Rb` RIGHT JOIN `‚s‚Ra` USING (`‚b‚P`); -‚b‚P ‚b‚P -ƒ\ ƒ\ -NULL \ -NULL •\ +‚b‚P +ƒ\ +\ +•\ SELECT * FROM `‚s‚Rb` RIGHT JOIN `‚s‚Ra` ON (`‚s‚Ra`.`‚b‚P` = `‚s‚Rb`.`‚b‚P`); ‚b‚P ‚b‚P ƒ\ ƒ\ @@ -194,31 +194,31 @@ SELECT * FROM ` ¶ ± » ± SELECT * FROM `‚s‚Sa` JOIN `‚s‚Sb` USING (`‚b‚P`); -‚b‚P ‚b‚P -± ± +‚b‚P +± SELECT * FROM `‚s‚Sa` INNER JOIN `‚s‚Sb` USING (`‚b‚P`); -‚b‚P ‚b‚P -± ± +‚b‚P +± SELECT * FROM `‚s‚Sa` CROSS JOIN `‚s‚Sb`; ‚b‚P ‚b‚P ± ± ¶ ± » ± SELECT * FROM `‚s‚Sa` LEFT JOIN `‚s‚Sb` USING (`‚b‚P`); -‚b‚P ‚b‚P -± ± -¶ NULL -» NULL +‚b‚P +± +¶ +» SELECT * FROM `‚s‚Sa` LEFT JOIN `‚s‚Sb` ON (`‚s‚Sa`.`‚b‚P` = `‚s‚Sb`.`‚b‚P`); ‚b‚P ‚b‚P ± ± ¶ NULL » NULL SELECT * FROM `‚s‚Sb` RIGHT JOIN `‚s‚Sa` USING (`‚b‚P`); -‚b‚P ‚b‚P -± ± -NULL ¶ -NULL » +‚b‚P +± +¶ +» SELECT * FROM `‚s‚Sb` RIGHT JOIN `‚s‚Sa` ON (`‚s‚Sa`.`‚b‚P` = `‚s‚Sb`.`‚b‚P`); ‚b‚P ‚b‚P ± ± @@ -235,31 +235,31 @@ SELECT * FROM ` ‚© ‚  ‚³ ‚  SELECT * FROM `‚s‚Ta` JOIN `‚s‚Tb` USING (`‚b‚P`); -‚b‚P ‚b‚P -‚  ‚  +‚b‚P +‚  SELECT * FROM `‚s‚Ta` INNER JOIN `‚s‚Tb` USING (`‚b‚P`); -‚b‚P ‚b‚P -‚  ‚  +‚b‚P +‚  SELECT * FROM `‚s‚Ta` CROSS JOIN `‚s‚Tb`; ‚b‚P ‚b‚P ‚  ‚  ‚© ‚  ‚³ ‚  SELECT * FROM `‚s‚Ta` LEFT JOIN `‚s‚Tb` USING (`‚b‚P`); -‚b‚P ‚b‚P -‚  ‚  -‚© NULL -‚³ NULL +‚b‚P +‚  +‚© +‚³ SELECT * FROM `‚s‚Ta` LEFT JOIN `‚s‚Tb` ON (`‚s‚Ta`.`‚b‚P` = `‚s‚Tb`.`‚b‚P`); ‚b‚P ‚b‚P ‚  ‚  ‚© NULL ‚³ NULL SELECT * FROM `‚s‚Tb` RIGHT JOIN `‚s‚Ta` USING (`‚b‚P`); -‚b‚P ‚b‚P -‚  ‚  -NULL ‚© -NULL ‚³ +‚b‚P +‚  +‚© +‚³ SELECT * FROM `‚s‚Tb` RIGHT JOIN `‚s‚Ta` ON (`‚s‚Ta`.`‚b‚P` = `‚s‚Tb`.`‚b‚P`); ‚b‚P ‚b‚P ‚  ‚  @@ -276,31 +276,31 @@ SELECT * FROM ` \ ƒ\ •\ ƒ\ SELECT * FROM `‚s‚Ua` JOIN `‚s‚Ub` USING (`‚b‚P`); -‚b‚P ‚b‚P -ƒ\ ƒ\ +‚b‚P +ƒ\ SELECT * FROM `‚s‚Ua` INNER JOIN `‚s‚Ub` USING (`‚b‚P`); -‚b‚P ‚b‚P -ƒ\ ƒ\ +‚b‚P +ƒ\ SELECT * FROM `‚s‚Ua` CROSS JOIN `‚s‚Ub`; ‚b‚P ‚b‚P ƒ\ ƒ\ \ ƒ\ •\ ƒ\ SELECT * FROM `‚s‚Ua` LEFT JOIN `‚s‚Ub` USING (`‚b‚P`); -‚b‚P ‚b‚P -ƒ\ ƒ\ -\ NULL -•\ NULL +‚b‚P +ƒ\ +\ +•\ SELECT * FROM `‚s‚Ua` LEFT JOIN `‚s‚Ub` ON (`‚s‚Ua`.`‚b‚P` = `‚s‚Ub`.`‚b‚P`); ‚b‚P ‚b‚P ƒ\ ƒ\ \ NULL •\ NULL SELECT * FROM `‚s‚Ub` RIGHT JOIN `‚s‚Ua` USING (`‚b‚P`); -‚b‚P ‚b‚P -ƒ\ ƒ\ -NULL \ -NULL •\ +‚b‚P +ƒ\ +\ +•\ SELECT * FROM `‚s‚Ub` RIGHT JOIN `‚s‚Ua` ON (`‚s‚Ua`.`‚b‚P` = `‚s‚Ub`.`‚b‚P`); ‚b‚P ‚b‚P ƒ\ ƒ\ @@ -317,31 +317,31 @@ SELECT * FROM ` ¶ ± » ± SELECT * FROM `‚s‚Va` JOIN `‚s‚Vb` USING (`‚b‚P`); -‚b‚P ‚b‚P -± ± +‚b‚P +± SELECT * FROM `‚s‚Va` INNER JOIN `‚s‚Vb` USING (`‚b‚P`); -‚b‚P ‚b‚P -± ± +‚b‚P +± SELECT * FROM `‚s‚Va` CROSS JOIN `‚s‚Vb`; ‚b‚P ‚b‚P ± ± ¶ ± » ± SELECT * FROM `‚s‚Va` LEFT JOIN `‚s‚Vb` USING (`‚b‚P`); -‚b‚P ‚b‚P -± ± -¶ NULL -» NULL +‚b‚P +± +¶ +» SELECT * FROM `‚s‚Va` LEFT JOIN `‚s‚Vb` ON (`‚s‚Va`.`‚b‚P` = `‚s‚Vb`.`‚b‚P`); ‚b‚P ‚b‚P ± ± ¶ NULL » NULL SELECT * FROM `‚s‚Vb` RIGHT JOIN `‚s‚Va` USING (`‚b‚P`); -‚b‚P ‚b‚P -± ± -NULL ¶ -NULL » +‚b‚P +± +¶ +» SELECT * FROM `‚s‚Vb` RIGHT JOIN `‚s‚Va` ON (`‚s‚Va`.`‚b‚P` = `‚s‚Vb`.`‚b‚P`); ‚b‚P ‚b‚P ± ± @@ -358,31 +358,31 @@ SELECT * FROM ` ‚© ‚  ‚³ ‚  SELECT * FROM `‚s‚Wa` JOIN `‚s‚Wb` USING (`‚b‚P`); -‚b‚P ‚b‚P -‚  ‚  +‚b‚P +‚  SELECT * FROM `‚s‚Wa` INNER JOIN `‚s‚Wb` USING (`‚b‚P`); -‚b‚P ‚b‚P -‚  ‚  +‚b‚P +‚  SELECT * FROM `‚s‚Wa` CROSS JOIN `‚s‚Wb`; ‚b‚P ‚b‚P ‚  ‚  ‚© ‚  ‚³ ‚  SELECT * FROM `‚s‚Wa` LEFT JOIN `‚s‚Wb` USING (`‚b‚P`); -‚b‚P ‚b‚P -‚  ‚  -‚© NULL -‚³ NULL +‚b‚P +‚  +‚© +‚³ SELECT * FROM `‚s‚Wa` LEFT JOIN `‚s‚Wb` ON (`‚s‚Wa`.`‚b‚P` = `‚s‚Wb`.`‚b‚P`); ‚b‚P ‚b‚P ‚  ‚  ‚© NULL ‚³ NULL SELECT * FROM `‚s‚Wb` RIGHT JOIN `‚s‚Wa` USING (`‚b‚P`); -‚b‚P ‚b‚P -‚  ‚  -NULL ‚© -NULL ‚³ +‚b‚P +‚  +‚© +‚³ SELECT * FROM `‚s‚Wb` RIGHT JOIN `‚s‚Wa` ON (`‚s‚Wa`.`‚b‚P` = `‚s‚Wb`.`‚b‚P`); ‚b‚P ‚b‚P ‚  ‚  @@ -399,31 +399,31 @@ SELECT * FROM ` \ ƒ\ •\ ƒ\ SELECT * FROM `‚s‚Xa` JOIN `‚s‚Xb` USING (`‚b‚P`); -‚b‚P ‚b‚P -ƒ\ ƒ\ +‚b‚P +ƒ\ SELECT * FROM `‚s‚Xa` INNER JOIN `‚s‚Xb` USING (`‚b‚P`); -‚b‚P ‚b‚P -ƒ\ ƒ\ +‚b‚P +ƒ\ SELECT * FROM `‚s‚Xa` CROSS JOIN `‚s‚Xb`; ‚b‚P ‚b‚P ƒ\ ƒ\ \ ƒ\ •\ ƒ\ SELECT * FROM `‚s‚Xa` LEFT JOIN `‚s‚Xb` USING (`‚b‚P`); -‚b‚P ‚b‚P -ƒ\ ƒ\ -\ NULL -•\ NULL +‚b‚P +ƒ\ +\ +•\ SELECT * FROM `‚s‚Xa` LEFT JOIN `‚s‚Xb` ON (`‚s‚Xa`.`‚b‚P` = `‚s‚Xb`.`‚b‚P`); ‚b‚P ‚b‚P ƒ\ ƒ\ \ NULL •\ NULL SELECT * FROM `‚s‚Xb` RIGHT JOIN `‚s‚Xa` USING (`‚b‚P`); -‚b‚P ‚b‚P -ƒ\ ƒ\ -NULL \ -NULL •\ +‚b‚P +ƒ\ +\ +•\ SELECT * FROM `‚s‚Xb` RIGHT JOIN `‚s‚Xa` ON (`‚s‚Xa`.`‚b‚P` = `‚s‚Xb`.`‚b‚P`); ‚b‚P ‚b‚P ƒ\ ƒ\ @@ -440,31 +440,31 @@ SELECT * FROM ` ¶ ± » ± SELECT * FROM `‚s‚P‚Oa` JOIN `‚s‚P‚Ob` USING (`‚b‚P`); -‚b‚P ‚b‚P -± ± +‚b‚P +± SELECT * FROM `‚s‚P‚Oa` INNER JOIN `‚s‚P‚Ob` USING (`‚b‚P`); -‚b‚P ‚b‚P -± ± +‚b‚P +± SELECT * FROM `‚s‚P‚Oa` CROSS JOIN `‚s‚P‚Ob`; ‚b‚P ‚b‚P ± ± ¶ ± » ± SELECT * FROM `‚s‚P‚Oa` LEFT JOIN `‚s‚P‚Ob` USING (`‚b‚P`); -‚b‚P ‚b‚P -± ± -¶ NULL -» NULL +‚b‚P +± +¶ +» SELECT * FROM `‚s‚P‚Oa` LEFT JOIN `‚s‚P‚Ob` ON (`‚s‚P‚Oa`.`‚b‚P` = `‚s‚P‚Ob`.`‚b‚P`); ‚b‚P ‚b‚P ± ± ¶ NULL » NULL SELECT * FROM `‚s‚P‚Ob` RIGHT JOIN `‚s‚P‚Oa` USING (`‚b‚P`); -‚b‚P ‚b‚P -± ± -NULL ¶ -NULL » +‚b‚P +± +¶ +» SELECT * FROM `‚s‚P‚Ob` RIGHT JOIN `‚s‚P‚Oa` ON (`‚s‚P‚Oa`.`‚b‚P` = `‚s‚P‚Ob`.`‚b‚P`); ‚b‚P ‚b‚P ± ± @@ -481,31 +481,31 @@ SELECT * FROM ` ‚© ‚  ‚³ ‚  SELECT * FROM `‚s‚P‚Pa` JOIN `‚s‚P‚Pb` USING (`‚b‚P`); -‚b‚P ‚b‚P -‚  ‚  +‚b‚P +‚  SELECT * FROM `‚s‚P‚Pa` INNER JOIN `‚s‚P‚Pb` USING (`‚b‚P`); -‚b‚P ‚b‚P -‚  ‚  +‚b‚P +‚  SELECT * FROM `‚s‚P‚Pa` CROSS JOIN `‚s‚P‚Pb`; ‚b‚P ‚b‚P ‚  ‚  ‚© ‚  ‚³ ‚  SELECT * FROM `‚s‚P‚Pa` LEFT JOIN `‚s‚P‚Pb` USING (`‚b‚P`); -‚b‚P ‚b‚P -‚  ‚  -‚© NULL -‚³ NULL +‚b‚P +‚  +‚© +‚³ SELECT * FROM `‚s‚P‚Pa` LEFT JOIN `‚s‚P‚Pb` ON (`‚s‚P‚Pa`.`‚b‚P` = `‚s‚P‚Pb`.`‚b‚P`); ‚b‚P ‚b‚P ‚  ‚  ‚© NULL ‚³ NULL SELECT * FROM `‚s‚P‚Pb` RIGHT JOIN `‚s‚P‚Pa` USING (`‚b‚P`); -‚b‚P ‚b‚P -‚  ‚  -NULL ‚© -NULL ‚³ +‚b‚P +‚  +‚© +‚³ SELECT * FROM `‚s‚P‚Pb` RIGHT JOIN `‚s‚P‚Pa` ON (`‚s‚P‚Pa`.`‚b‚P` = `‚s‚P‚Pb`.`‚b‚P`); ‚b‚P ‚b‚P ‚  ‚  @@ -522,31 +522,31 @@ SELECT * FROM ` \ ƒ\ •\ ƒ\ SELECT * FROM `‚s‚P‚Qa` JOIN `‚s‚P‚Qb` USING (`‚b‚P`); -‚b‚P ‚b‚P -ƒ\ ƒ\ +‚b‚P +ƒ\ SELECT * FROM `‚s‚P‚Qa` INNER JOIN `‚s‚P‚Qb` USING (`‚b‚P`); -‚b‚P ‚b‚P -ƒ\ ƒ\ +‚b‚P +ƒ\ SELECT * FROM `‚s‚P‚Qa` CROSS JOIN `‚s‚P‚Qb`; ‚b‚P ‚b‚P ƒ\ ƒ\ \ ƒ\ •\ ƒ\ SELECT * FROM `‚s‚P‚Qa` LEFT JOIN `‚s‚P‚Qb` USING (`‚b‚P`); -‚b‚P ‚b‚P -ƒ\ ƒ\ -\ NULL -•\ NULL +‚b‚P +ƒ\ +\ +•\ SELECT * FROM `‚s‚P‚Qa` LEFT JOIN `‚s‚P‚Qb` ON (`‚s‚P‚Qa`.`‚b‚P` = `‚s‚P‚Qb`.`‚b‚P`); ‚b‚P ‚b‚P ƒ\ ƒ\ \ NULL •\ NULL SELECT * FROM `‚s‚P‚Qb` RIGHT JOIN `‚s‚P‚Qa` USING (`‚b‚P`); -‚b‚P ‚b‚P -ƒ\ ƒ\ -NULL \ -NULL •\ +‚b‚P +ƒ\ +\ +•\ SELECT * FROM `‚s‚P‚Qb` RIGHT JOIN `‚s‚P‚Qa` ON (`‚s‚P‚Qa`.`‚b‚P` = `‚s‚P‚Qb`.`‚b‚P`); ‚b‚P ‚b‚P ƒ\ ƒ\ diff --git a/mysql-test/suite/jp/r/jp_join_ucs2.result b/mysql-test/suite/jp/r/jp_join_ucs2.result index 76988f15cc4..ac19554eb5a 100644 --- a/mysql-test/suite/jp/r/jp_join_ucs2.result +++ b/mysql-test/suite/jp/r/jp_join_ucs2.result @@ -72,31 +72,31 @@ SELECT * FROM ` ޶ ޱ Ž» ޱ SELECT * FROM `£Ô£±a` JOIN `£Ô£±b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ +£Ã£± +ޱ SELECT * FROM `£Ô£±a` INNER JOIN `£Ô£±b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ +£Ã£± +ޱ SELECT * FROM `£Ô£±a` CROSS JOIN `£Ô£±b`; £Ã£± £Ã£± ޱ ޱ ޶ ޱ Ž» ޱ SELECT * FROM `£Ô£±a` LEFT JOIN `£Ô£±b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ -޶ NULL -Ž» NULL +£Ã£± +ޱ +޶ +Ž» SELECT * FROM `£Ô£±a` LEFT JOIN `£Ô£±b` ON (`£Ô£±a`.`£Ã£±` = `£Ô£±b`.`£Ã£±`); £Ã£± £Ã£± ޱ ޱ ޶ NULL Ž» NULL SELECT * FROM `£Ô£±b` RIGHT JOIN `£Ô£±a` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ -NULL ޶ -NULL Ž» +£Ã£± +ޱ +޶ +Ž» SELECT * FROM `£Ô£±b` RIGHT JOIN `£Ô£±a` ON (`£Ô£±a`.`£Ã£±` = `£Ô£±b`.`£Ã£±`); £Ã£± £Ã£± ޱ ޱ @@ -113,31 +113,31 @@ SELECT * FROM ` ¤« ¤¢ ¤µ ¤¢ SELECT * FROM `£Ô£²a` JOIN `£Ô£²b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ +£Ã£± +¤¢ SELECT * FROM `£Ô£²a` INNER JOIN `£Ô£²b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ +£Ã£± +¤¢ SELECT * FROM `£Ô£²a` CROSS JOIN `£Ô£²b`; £Ã£± £Ã£± ¤¢ ¤¢ ¤« ¤¢ ¤µ ¤¢ SELECT * FROM `£Ô£²a` LEFT JOIN `£Ô£²b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ -¤« NULL -¤µ NULL +£Ã£± +¤¢ +¤« +¤µ SELECT * FROM `£Ô£²a` LEFT JOIN `£Ô£²b` ON (`£Ô£²a`.`£Ã£±` = `£Ô£²b`.`£Ã£±`); £Ã£± £Ã£± ¤¢ ¤¢ ¤« NULL ¤µ NULL SELECT * FROM `£Ô£²b` RIGHT JOIN `£Ô£²a` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ -NULL ¤« -NULL ¤µ +£Ã£± +¤¢ +¤« +¤µ SELECT * FROM `£Ô£²b` RIGHT JOIN `£Ô£²a` ON (`£Ô£²a`.`£Ã£±` = `£Ô£²b`.`£Ã£±`); £Ã£± £Ã£± ¤¢ ¤¢ @@ -154,31 +154,31 @@ SELECT * FROM ` íÝ íÜ íÞ íÜ SELECT * FROM `£Ô£³a` JOIN `£Ô£³b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ +£Ã£± +íÜ SELECT * FROM `£Ô£³a` INNER JOIN `£Ô£³b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ +£Ã£± +íÜ SELECT * FROM `£Ô£³a` CROSS JOIN `£Ô£³b`; £Ã£± £Ã£± íÜ íÜ íÝ íÜ íÞ íÜ SELECT * FROM `£Ô£³a` LEFT JOIN `£Ô£³b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ -íÝ NULL -íÞ NULL +£Ã£± +íÜ +íÝ +íÞ SELECT * FROM `£Ô£³a` LEFT JOIN `£Ô£³b` ON (`£Ô£³a`.`£Ã£±` = `£Ô£³b`.`£Ã£±`); £Ã£± £Ã£± íÜ íÜ íÝ NULL íÞ NULL SELECT * FROM `£Ô£³b` RIGHT JOIN `£Ô£³a` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ -NULL íÝ -NULL íÞ +£Ã£± +íÜ +íÝ +íÞ SELECT * FROM `£Ô£³b` RIGHT JOIN `£Ô£³a` ON (`£Ô£³a`.`£Ã£±` = `£Ô£³b`.`£Ã£±`); £Ã£± £Ã£± íÜ íÜ @@ -195,31 +195,31 @@ SELECT * FROM ` ޶ ޱ Ž» ޱ SELECT * FROM `£Ô£´a` JOIN `£Ô£´b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ +£Ã£± +ޱ SELECT * FROM `£Ô£´a` INNER JOIN `£Ô£´b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ +£Ã£± +ޱ SELECT * FROM `£Ô£´a` CROSS JOIN `£Ô£´b`; £Ã£± £Ã£± ޱ ޱ ޶ ޱ Ž» ޱ SELECT * FROM `£Ô£´a` LEFT JOIN `£Ô£´b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ -޶ NULL -Ž» NULL +£Ã£± +ޱ +޶ +Ž» SELECT * FROM `£Ô£´a` LEFT JOIN `£Ô£´b` ON (`£Ô£´a`.`£Ã£±` = `£Ô£´b`.`£Ã£±`); £Ã£± £Ã£± ޱ ޱ ޶ NULL Ž» NULL SELECT * FROM `£Ô£´b` RIGHT JOIN `£Ô£´a` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ -NULL ޶ -NULL Ž» +£Ã£± +ޱ +޶ +Ž» SELECT * FROM `£Ô£´b` RIGHT JOIN `£Ô£´a` ON (`£Ô£´a`.`£Ã£±` = `£Ô£´b`.`£Ã£±`); £Ã£± £Ã£± ޱ ޱ @@ -236,31 +236,31 @@ SELECT * FROM ` ¤« ¤¢ ¤µ ¤¢ SELECT * FROM `£Ô£µa` JOIN `£Ô£µb` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ +£Ã£± +¤¢ SELECT * FROM `£Ô£µa` INNER JOIN `£Ô£µb` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ +£Ã£± +¤¢ SELECT * FROM `£Ô£µa` CROSS JOIN `£Ô£µb`; £Ã£± £Ã£± ¤¢ ¤¢ ¤« ¤¢ ¤µ ¤¢ SELECT * FROM `£Ô£µa` LEFT JOIN `£Ô£µb` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ -¤« NULL -¤µ NULL +£Ã£± +¤¢ +¤« +¤µ SELECT * FROM `£Ô£µa` LEFT JOIN `£Ô£µb` ON (`£Ô£µa`.`£Ã£±` = `£Ô£µb`.`£Ã£±`); £Ã£± £Ã£± ¤¢ ¤¢ ¤« NULL ¤µ NULL SELECT * FROM `£Ô£µb` RIGHT JOIN `£Ô£µa` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ -NULL ¤« -NULL ¤µ +£Ã£± +¤¢ +¤« +¤µ SELECT * FROM `£Ô£µb` RIGHT JOIN `£Ô£µa` ON (`£Ô£µa`.`£Ã£±` = `£Ô£µb`.`£Ã£±`); £Ã£± £Ã£± ¤¢ ¤¢ @@ -277,31 +277,31 @@ SELECT * FROM ` íÝ íÜ íÞ íÜ SELECT * FROM `£Ô£¶a` JOIN `£Ô£¶b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ +£Ã£± +íÜ SELECT * FROM `£Ô£¶a` INNER JOIN `£Ô£¶b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ +£Ã£± +íÜ SELECT * FROM `£Ô£¶a` CROSS JOIN `£Ô£¶b`; £Ã£± £Ã£± íÜ íÜ íÝ íÜ íÞ íÜ SELECT * FROM `£Ô£¶a` LEFT JOIN `£Ô£¶b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ -íÝ NULL -íÞ NULL +£Ã£± +íÜ +íÝ +íÞ SELECT * FROM `£Ô£¶a` LEFT JOIN `£Ô£¶b` ON (`£Ô£¶a`.`£Ã£±` = `£Ô£¶b`.`£Ã£±`); £Ã£± £Ã£± íÜ íÜ íÝ NULL íÞ NULL SELECT * FROM `£Ô£¶b` RIGHT JOIN `£Ô£¶a` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ -NULL íÝ -NULL íÞ +£Ã£± +íÜ +íÝ +íÞ SELECT * FROM `£Ô£¶b` RIGHT JOIN `£Ô£¶a` ON (`£Ô£¶a`.`£Ã£±` = `£Ô£¶b`.`£Ã£±`); £Ã£± £Ã£± íÜ íÜ @@ -318,31 +318,31 @@ SELECT * FROM ` ޶ ޱ Ž» ޱ SELECT * FROM `£Ô£·a` JOIN `£Ô£·b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ +£Ã£± +ޱ SELECT * FROM `£Ô£·a` INNER JOIN `£Ô£·b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ +£Ã£± +ޱ SELECT * FROM `£Ô£·a` CROSS JOIN `£Ô£·b`; £Ã£± £Ã£± ޱ ޱ ޶ ޱ Ž» ޱ SELECT * FROM `£Ô£·a` LEFT JOIN `£Ô£·b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ -޶ NULL -Ž» NULL +£Ã£± +ޱ +޶ +Ž» SELECT * FROM `£Ô£·a` LEFT JOIN `£Ô£·b` ON (`£Ô£·a`.`£Ã£±` = `£Ô£·b`.`£Ã£±`); £Ã£± £Ã£± ޱ ޱ ޶ NULL Ž» NULL SELECT * FROM `£Ô£·b` RIGHT JOIN `£Ô£·a` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ -NULL ޶ -NULL Ž» +£Ã£± +ޱ +޶ +Ž» SELECT * FROM `£Ô£·b` RIGHT JOIN `£Ô£·a` ON (`£Ô£·a`.`£Ã£±` = `£Ô£·b`.`£Ã£±`); £Ã£± £Ã£± ޱ ޱ @@ -359,31 +359,31 @@ SELECT * FROM ` ¤« ¤¢ ¤µ ¤¢ SELECT * FROM `£Ô£¸a` JOIN `£Ô£¸b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ +£Ã£± +¤¢ SELECT * FROM `£Ô£¸a` INNER JOIN `£Ô£¸b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ +£Ã£± +¤¢ SELECT * FROM `£Ô£¸a` CROSS JOIN `£Ô£¸b`; £Ã£± £Ã£± ¤¢ ¤¢ ¤« ¤¢ ¤µ ¤¢ SELECT * FROM `£Ô£¸a` LEFT JOIN `£Ô£¸b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ -¤« NULL -¤µ NULL +£Ã£± +¤¢ +¤« +¤µ SELECT * FROM `£Ô£¸a` LEFT JOIN `£Ô£¸b` ON (`£Ô£¸a`.`£Ã£±` = `£Ô£¸b`.`£Ã£±`); £Ã£± £Ã£± ¤¢ ¤¢ ¤« NULL ¤µ NULL SELECT * FROM `£Ô£¸b` RIGHT JOIN `£Ô£¸a` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ -NULL ¤« -NULL ¤µ +£Ã£± +¤¢ +¤« +¤µ SELECT * FROM `£Ô£¸b` RIGHT JOIN `£Ô£¸a` ON (`£Ô£¸a`.`£Ã£±` = `£Ô£¸b`.`£Ã£±`); £Ã£± £Ã£± ¤¢ ¤¢ @@ -400,31 +400,31 @@ SELECT * FROM ` íÝ íÜ íÞ íÜ SELECT * FROM `£Ô£¹a` JOIN `£Ô£¹b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ +£Ã£± +íÜ SELECT * FROM `£Ô£¹a` INNER JOIN `£Ô£¹b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ +£Ã£± +íÜ SELECT * FROM `£Ô£¹a` CROSS JOIN `£Ô£¹b`; £Ã£± £Ã£± íÜ íÜ íÝ íÜ íÞ íÜ SELECT * FROM `£Ô£¹a` LEFT JOIN `£Ô£¹b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ -íÝ NULL -íÞ NULL +£Ã£± +íÜ +íÝ +íÞ SELECT * FROM `£Ô£¹a` LEFT JOIN `£Ô£¹b` ON (`£Ô£¹a`.`£Ã£±` = `£Ô£¹b`.`£Ã£±`); £Ã£± £Ã£± íÜ íÜ íÝ NULL íÞ NULL SELECT * FROM `£Ô£¹b` RIGHT JOIN `£Ô£¹a` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ -NULL íÝ -NULL íÞ +£Ã£± +íÜ +íÝ +íÞ SELECT * FROM `£Ô£¹b` RIGHT JOIN `£Ô£¹a` ON (`£Ô£¹a`.`£Ã£±` = `£Ô£¹b`.`£Ã£±`); £Ã£± £Ã£± íÜ íÜ @@ -441,31 +441,31 @@ SELECT * FROM ` ޶ ޱ Ž» ޱ SELECT * FROM `£Ô£±£°a` JOIN `£Ô£±£°b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ +£Ã£± +ޱ SELECT * FROM `£Ô£±£°a` INNER JOIN `£Ô£±£°b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ +£Ã£± +ޱ SELECT * FROM `£Ô£±£°a` CROSS JOIN `£Ô£±£°b`; £Ã£± £Ã£± ޱ ޱ ޶ ޱ Ž» ޱ SELECT * FROM `£Ô£±£°a` LEFT JOIN `£Ô£±£°b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ -޶ NULL -Ž» NULL +£Ã£± +ޱ +޶ +Ž» SELECT * FROM `£Ô£±£°a` LEFT JOIN `£Ô£±£°b` ON (`£Ô£±£°a`.`£Ã£±` = `£Ô£±£°b`.`£Ã£±`); £Ã£± £Ã£± ޱ ޱ ޶ NULL Ž» NULL SELECT * FROM `£Ô£±£°b` RIGHT JOIN `£Ô£±£°a` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ -NULL ޶ -NULL Ž» +£Ã£± +ޱ +޶ +Ž» SELECT * FROM `£Ô£±£°b` RIGHT JOIN `£Ô£±£°a` ON (`£Ô£±£°a`.`£Ã£±` = `£Ô£±£°b`.`£Ã£±`); £Ã£± £Ã£± ޱ ޱ @@ -482,31 +482,31 @@ SELECT * FROM ` ¤« ¤¢ ¤µ ¤¢ SELECT * FROM `£Ô£±£±a` JOIN `£Ô£±£±b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ +£Ã£± +¤¢ SELECT * FROM `£Ô£±£±a` INNER JOIN `£Ô£±£±b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ +£Ã£± +¤¢ SELECT * FROM `£Ô£±£±a` CROSS JOIN `£Ô£±£±b`; £Ã£± £Ã£± ¤¢ ¤¢ ¤« ¤¢ ¤µ ¤¢ SELECT * FROM `£Ô£±£±a` LEFT JOIN `£Ô£±£±b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ -¤« NULL -¤µ NULL +£Ã£± +¤¢ +¤« +¤µ SELECT * FROM `£Ô£±£±a` LEFT JOIN `£Ô£±£±b` ON (`£Ô£±£±a`.`£Ã£±` = `£Ô£±£±b`.`£Ã£±`); £Ã£± £Ã£± ¤¢ ¤¢ ¤« NULL ¤µ NULL SELECT * FROM `£Ô£±£±b` RIGHT JOIN `£Ô£±£±a` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ -NULL ¤« -NULL ¤µ +£Ã£± +¤¢ +¤« +¤µ SELECT * FROM `£Ô£±£±b` RIGHT JOIN `£Ô£±£±a` ON (`£Ô£±£±a`.`£Ã£±` = `£Ô£±£±b`.`£Ã£±`); £Ã£± £Ã£± ¤¢ ¤¢ @@ -523,31 +523,31 @@ SELECT * FROM ` íÝ íÜ íÞ íÜ SELECT * FROM `£Ô£±£²a` JOIN `£Ô£±£²b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ +£Ã£± +íÜ SELECT * FROM `£Ô£±£²a` INNER JOIN `£Ô£±£²b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ +£Ã£± +íÜ SELECT * FROM `£Ô£±£²a` CROSS JOIN `£Ô£±£²b`; £Ã£± £Ã£± íÜ íÜ íÝ íÜ íÞ íÜ SELECT * FROM `£Ô£±£²a` LEFT JOIN `£Ô£±£²b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ -íÝ NULL -íÞ NULL +£Ã£± +íÜ +íÝ +íÞ SELECT * FROM `£Ô£±£²a` LEFT JOIN `£Ô£±£²b` ON (`£Ô£±£²a`.`£Ã£±` = `£Ô£±£²b`.`£Ã£±`); £Ã£± £Ã£± íÜ íÜ íÝ NULL íÞ NULL SELECT * FROM `£Ô£±£²b` RIGHT JOIN `£Ô£±£²a` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ -NULL íÝ -NULL íÞ +£Ã£± +íÜ +íÝ +íÞ SELECT * FROM `£Ô£±£²b` RIGHT JOIN `£Ô£±£²a` ON (`£Ô£±£²a`.`£Ã£±` = `£Ô£±£²b`.`£Ã£±`); £Ã£± £Ã£± íÜ íÜ diff --git a/mysql-test/suite/jp/r/jp_join_ujis.result b/mysql-test/suite/jp/r/jp_join_ujis.result index ac430cd9b5e..838d701cdcc 100644 --- a/mysql-test/suite/jp/r/jp_join_ujis.result +++ b/mysql-test/suite/jp/r/jp_join_ujis.result @@ -71,31 +71,31 @@ SELECT * FROM ` ޶ ޱ Ž» ޱ SELECT * FROM `£Ô£±a` JOIN `£Ô£±b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ +£Ã£± +ޱ SELECT * FROM `£Ô£±a` INNER JOIN `£Ô£±b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ +£Ã£± +ޱ SELECT * FROM `£Ô£±a` CROSS JOIN `£Ô£±b`; £Ã£± £Ã£± ޱ ޱ ޶ ޱ Ž» ޱ SELECT * FROM `£Ô£±a` LEFT JOIN `£Ô£±b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ -޶ NULL -Ž» NULL +£Ã£± +ޱ +޶ +Ž» SELECT * FROM `£Ô£±a` LEFT JOIN `£Ô£±b` ON (`£Ô£±a`.`£Ã£±` = `£Ô£±b`.`£Ã£±`); £Ã£± £Ã£± ޱ ޱ ޶ NULL Ž» NULL SELECT * FROM `£Ô£±b` RIGHT JOIN `£Ô£±a` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ -NULL ޶ -NULL Ž» +£Ã£± +ޱ +޶ +Ž» SELECT * FROM `£Ô£±b` RIGHT JOIN `£Ô£±a` ON (`£Ô£±a`.`£Ã£±` = `£Ô£±b`.`£Ã£±`); £Ã£± £Ã£± ޱ ޱ @@ -112,31 +112,31 @@ SELECT * FROM ` ¤« ¤¢ ¤µ ¤¢ SELECT * FROM `£Ô£²a` JOIN `£Ô£²b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ +£Ã£± +¤¢ SELECT * FROM `£Ô£²a` INNER JOIN `£Ô£²b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ +£Ã£± +¤¢ SELECT * FROM `£Ô£²a` CROSS JOIN `£Ô£²b`; £Ã£± £Ã£± ¤¢ ¤¢ ¤« ¤¢ ¤µ ¤¢ SELECT * FROM `£Ô£²a` LEFT JOIN `£Ô£²b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ -¤« NULL -¤µ NULL +£Ã£± +¤¢ +¤« +¤µ SELECT * FROM `£Ô£²a` LEFT JOIN `£Ô£²b` ON (`£Ô£²a`.`£Ã£±` = `£Ô£²b`.`£Ã£±`); £Ã£± £Ã£± ¤¢ ¤¢ ¤« NULL ¤µ NULL SELECT * FROM `£Ô£²b` RIGHT JOIN `£Ô£²a` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ -NULL ¤« -NULL ¤µ +£Ã£± +¤¢ +¤« +¤µ SELECT * FROM `£Ô£²b` RIGHT JOIN `£Ô£²a` ON (`£Ô£²a`.`£Ã£±` = `£Ô£²b`.`£Ã£±`); £Ã£± £Ã£± ¤¢ ¤¢ @@ -153,31 +153,31 @@ SELECT * FROM ` íÝ íÜ íÞ íÜ SELECT * FROM `£Ô£³a` JOIN `£Ô£³b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ +£Ã£± +íÜ SELECT * FROM `£Ô£³a` INNER JOIN `£Ô£³b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ +£Ã£± +íÜ SELECT * FROM `£Ô£³a` CROSS JOIN `£Ô£³b`; £Ã£± £Ã£± íÜ íÜ íÝ íÜ íÞ íÜ SELECT * FROM `£Ô£³a` LEFT JOIN `£Ô£³b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ -íÝ NULL -íÞ NULL +£Ã£± +íÜ +íÝ +íÞ SELECT * FROM `£Ô£³a` LEFT JOIN `£Ô£³b` ON (`£Ô£³a`.`£Ã£±` = `£Ô£³b`.`£Ã£±`); £Ã£± £Ã£± íÜ íÜ íÝ NULL íÞ NULL SELECT * FROM `£Ô£³b` RIGHT JOIN `£Ô£³a` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ -NULL íÝ -NULL íÞ +£Ã£± +íÜ +íÝ +íÞ SELECT * FROM `£Ô£³b` RIGHT JOIN `£Ô£³a` ON (`£Ô£³a`.`£Ã£±` = `£Ô£³b`.`£Ã£±`); £Ã£± £Ã£± íÜ íÜ @@ -194,31 +194,31 @@ SELECT * FROM ` ޶ ޱ Ž» ޱ SELECT * FROM `£Ô£´a` JOIN `£Ô£´b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ +£Ã£± +ޱ SELECT * FROM `£Ô£´a` INNER JOIN `£Ô£´b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ +£Ã£± +ޱ SELECT * FROM `£Ô£´a` CROSS JOIN `£Ô£´b`; £Ã£± £Ã£± ޱ ޱ ޶ ޱ Ž» ޱ SELECT * FROM `£Ô£´a` LEFT JOIN `£Ô£´b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ -޶ NULL -Ž» NULL +£Ã£± +ޱ +޶ +Ž» SELECT * FROM `£Ô£´a` LEFT JOIN `£Ô£´b` ON (`£Ô£´a`.`£Ã£±` = `£Ô£´b`.`£Ã£±`); £Ã£± £Ã£± ޱ ޱ ޶ NULL Ž» NULL SELECT * FROM `£Ô£´b` RIGHT JOIN `£Ô£´a` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ -NULL ޶ -NULL Ž» +£Ã£± +ޱ +޶ +Ž» SELECT * FROM `£Ô£´b` RIGHT JOIN `£Ô£´a` ON (`£Ô£´a`.`£Ã£±` = `£Ô£´b`.`£Ã£±`); £Ã£± £Ã£± ޱ ޱ @@ -235,31 +235,31 @@ SELECT * FROM ` ¤« ¤¢ ¤µ ¤¢ SELECT * FROM `£Ô£µa` JOIN `£Ô£µb` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ +£Ã£± +¤¢ SELECT * FROM `£Ô£µa` INNER JOIN `£Ô£µb` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ +£Ã£± +¤¢ SELECT * FROM `£Ô£µa` CROSS JOIN `£Ô£µb`; £Ã£± £Ã£± ¤¢ ¤¢ ¤« ¤¢ ¤µ ¤¢ SELECT * FROM `£Ô£µa` LEFT JOIN `£Ô£µb` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ -¤« NULL -¤µ NULL +£Ã£± +¤¢ +¤« +¤µ SELECT * FROM `£Ô£µa` LEFT JOIN `£Ô£µb` ON (`£Ô£µa`.`£Ã£±` = `£Ô£µb`.`£Ã£±`); £Ã£± £Ã£± ¤¢ ¤¢ ¤« NULL ¤µ NULL SELECT * FROM `£Ô£µb` RIGHT JOIN `£Ô£µa` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ -NULL ¤« -NULL ¤µ +£Ã£± +¤¢ +¤« +¤µ SELECT * FROM `£Ô£µb` RIGHT JOIN `£Ô£µa` ON (`£Ô£µa`.`£Ã£±` = `£Ô£µb`.`£Ã£±`); £Ã£± £Ã£± ¤¢ ¤¢ @@ -276,31 +276,31 @@ SELECT * FROM ` íÝ íÜ íÞ íÜ SELECT * FROM `£Ô£¶a` JOIN `£Ô£¶b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ +£Ã£± +íÜ SELECT * FROM `£Ô£¶a` INNER JOIN `£Ô£¶b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ +£Ã£± +íÜ SELECT * FROM `£Ô£¶a` CROSS JOIN `£Ô£¶b`; £Ã£± £Ã£± íÜ íÜ íÝ íÜ íÞ íÜ SELECT * FROM `£Ô£¶a` LEFT JOIN `£Ô£¶b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ -íÝ NULL -íÞ NULL +£Ã£± +íÜ +íÝ +íÞ SELECT * FROM `£Ô£¶a` LEFT JOIN `£Ô£¶b` ON (`£Ô£¶a`.`£Ã£±` = `£Ô£¶b`.`£Ã£±`); £Ã£± £Ã£± íÜ íÜ íÝ NULL íÞ NULL SELECT * FROM `£Ô£¶b` RIGHT JOIN `£Ô£¶a` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ -NULL íÝ -NULL íÞ +£Ã£± +íÜ +íÝ +íÞ SELECT * FROM `£Ô£¶b` RIGHT JOIN `£Ô£¶a` ON (`£Ô£¶a`.`£Ã£±` = `£Ô£¶b`.`£Ã£±`); £Ã£± £Ã£± íÜ íÜ @@ -317,31 +317,31 @@ SELECT * FROM ` ޶ ޱ Ž» ޱ SELECT * FROM `£Ô£·a` JOIN `£Ô£·b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ +£Ã£± +ޱ SELECT * FROM `£Ô£·a` INNER JOIN `£Ô£·b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ +£Ã£± +ޱ SELECT * FROM `£Ô£·a` CROSS JOIN `£Ô£·b`; £Ã£± £Ã£± ޱ ޱ ޶ ޱ Ž» ޱ SELECT * FROM `£Ô£·a` LEFT JOIN `£Ô£·b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ -޶ NULL -Ž» NULL +£Ã£± +ޱ +޶ +Ž» SELECT * FROM `£Ô£·a` LEFT JOIN `£Ô£·b` ON (`£Ô£·a`.`£Ã£±` = `£Ô£·b`.`£Ã£±`); £Ã£± £Ã£± ޱ ޱ ޶ NULL Ž» NULL SELECT * FROM `£Ô£·b` RIGHT JOIN `£Ô£·a` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ -NULL ޶ -NULL Ž» +£Ã£± +ޱ +޶ +Ž» SELECT * FROM `£Ô£·b` RIGHT JOIN `£Ô£·a` ON (`£Ô£·a`.`£Ã£±` = `£Ô£·b`.`£Ã£±`); £Ã£± £Ã£± ޱ ޱ @@ -358,31 +358,31 @@ SELECT * FROM ` ¤« ¤¢ ¤µ ¤¢ SELECT * FROM `£Ô£¸a` JOIN `£Ô£¸b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ +£Ã£± +¤¢ SELECT * FROM `£Ô£¸a` INNER JOIN `£Ô£¸b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ +£Ã£± +¤¢ SELECT * FROM `£Ô£¸a` CROSS JOIN `£Ô£¸b`; £Ã£± £Ã£± ¤¢ ¤¢ ¤« ¤¢ ¤µ ¤¢ SELECT * FROM `£Ô£¸a` LEFT JOIN `£Ô£¸b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ -¤« NULL -¤µ NULL +£Ã£± +¤¢ +¤« +¤µ SELECT * FROM `£Ô£¸a` LEFT JOIN `£Ô£¸b` ON (`£Ô£¸a`.`£Ã£±` = `£Ô£¸b`.`£Ã£±`); £Ã£± £Ã£± ¤¢ ¤¢ ¤« NULL ¤µ NULL SELECT * FROM `£Ô£¸b` RIGHT JOIN `£Ô£¸a` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ -NULL ¤« -NULL ¤µ +£Ã£± +¤¢ +¤« +¤µ SELECT * FROM `£Ô£¸b` RIGHT JOIN `£Ô£¸a` ON (`£Ô£¸a`.`£Ã£±` = `£Ô£¸b`.`£Ã£±`); £Ã£± £Ã£± ¤¢ ¤¢ @@ -399,31 +399,31 @@ SELECT * FROM ` íÝ íÜ íÞ íÜ SELECT * FROM `£Ô£¹a` JOIN `£Ô£¹b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ +£Ã£± +íÜ SELECT * FROM `£Ô£¹a` INNER JOIN `£Ô£¹b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ +£Ã£± +íÜ SELECT * FROM `£Ô£¹a` CROSS JOIN `£Ô£¹b`; £Ã£± £Ã£± íÜ íÜ íÝ íÜ íÞ íÜ SELECT * FROM `£Ô£¹a` LEFT JOIN `£Ô£¹b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ -íÝ NULL -íÞ NULL +£Ã£± +íÜ +íÝ +íÞ SELECT * FROM `£Ô£¹a` LEFT JOIN `£Ô£¹b` ON (`£Ô£¹a`.`£Ã£±` = `£Ô£¹b`.`£Ã£±`); £Ã£± £Ã£± íÜ íÜ íÝ NULL íÞ NULL SELECT * FROM `£Ô£¹b` RIGHT JOIN `£Ô£¹a` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ -NULL íÝ -NULL íÞ +£Ã£± +íÜ +íÝ +íÞ SELECT * FROM `£Ô£¹b` RIGHT JOIN `£Ô£¹a` ON (`£Ô£¹a`.`£Ã£±` = `£Ô£¹b`.`£Ã£±`); £Ã£± £Ã£± íÜ íÜ @@ -440,31 +440,31 @@ SELECT * FROM ` ޶ ޱ Ž» ޱ SELECT * FROM `£Ô£±£°a` JOIN `£Ô£±£°b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ +£Ã£± +ޱ SELECT * FROM `£Ô£±£°a` INNER JOIN `£Ô£±£°b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ +£Ã£± +ޱ SELECT * FROM `£Ô£±£°a` CROSS JOIN `£Ô£±£°b`; £Ã£± £Ã£± ޱ ޱ ޶ ޱ Ž» ޱ SELECT * FROM `£Ô£±£°a` LEFT JOIN `£Ô£±£°b` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ -޶ NULL -Ž» NULL +£Ã£± +ޱ +޶ +Ž» SELECT * FROM `£Ô£±£°a` LEFT JOIN `£Ô£±£°b` ON (`£Ô£±£°a`.`£Ã£±` = `£Ô£±£°b`.`£Ã£±`); £Ã£± £Ã£± ޱ ޱ ޶ NULL Ž» NULL SELECT * FROM `£Ô£±£°b` RIGHT JOIN `£Ô£±£°a` USING (`£Ã£±`); -£Ã£± £Ã£± -ޱ ޱ -NULL ޶ -NULL Ž» +£Ã£± +ޱ +޶ +Ž» SELECT * FROM `£Ô£±£°b` RIGHT JOIN `£Ô£±£°a` ON (`£Ô£±£°a`.`£Ã£±` = `£Ô£±£°b`.`£Ã£±`); £Ã£± £Ã£± ޱ ޱ @@ -481,31 +481,31 @@ SELECT * FROM ` ¤« ¤¢ ¤µ ¤¢ SELECT * FROM `£Ô£±£±a` JOIN `£Ô£±£±b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ +£Ã£± +¤¢ SELECT * FROM `£Ô£±£±a` INNER JOIN `£Ô£±£±b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ +£Ã£± +¤¢ SELECT * FROM `£Ô£±£±a` CROSS JOIN `£Ô£±£±b`; £Ã£± £Ã£± ¤¢ ¤¢ ¤« ¤¢ ¤µ ¤¢ SELECT * FROM `£Ô£±£±a` LEFT JOIN `£Ô£±£±b` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ -¤« NULL -¤µ NULL +£Ã£± +¤¢ +¤« +¤µ SELECT * FROM `£Ô£±£±a` LEFT JOIN `£Ô£±£±b` ON (`£Ô£±£±a`.`£Ã£±` = `£Ô£±£±b`.`£Ã£±`); £Ã£± £Ã£± ¤¢ ¤¢ ¤« NULL ¤µ NULL SELECT * FROM `£Ô£±£±b` RIGHT JOIN `£Ô£±£±a` USING (`£Ã£±`); -£Ã£± £Ã£± -¤¢ ¤¢ -NULL ¤« -NULL ¤µ +£Ã£± +¤¢ +¤« +¤µ SELECT * FROM `£Ô£±£±b` RIGHT JOIN `£Ô£±£±a` ON (`£Ô£±£±a`.`£Ã£±` = `£Ô£±£±b`.`£Ã£±`); £Ã£± £Ã£± ¤¢ ¤¢ @@ -522,31 +522,31 @@ SELECT * FROM ` íÝ íÜ íÞ íÜ SELECT * FROM `£Ô£±£²a` JOIN `£Ô£±£²b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ +£Ã£± +íÜ SELECT * FROM `£Ô£±£²a` INNER JOIN `£Ô£±£²b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ +£Ã£± +íÜ SELECT * FROM `£Ô£±£²a` CROSS JOIN `£Ô£±£²b`; £Ã£± £Ã£± íÜ íÜ íÝ íÜ íÞ íÜ SELECT * FROM `£Ô£±£²a` LEFT JOIN `£Ô£±£²b` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ -íÝ NULL -íÞ NULL +£Ã£± +íÜ +íÝ +íÞ SELECT * FROM `£Ô£±£²a` LEFT JOIN `£Ô£±£²b` ON (`£Ô£±£²a`.`£Ã£±` = `£Ô£±£²b`.`£Ã£±`); £Ã£± £Ã£± íÜ íÜ íÝ NULL íÞ NULL SELECT * FROM `£Ô£±£²b` RIGHT JOIN `£Ô£±£²a` USING (`£Ã£±`); -£Ã£± £Ã£± -íÜ íÜ -NULL íÝ -NULL íÞ +£Ã£± +íÜ +íÝ +íÞ SELECT * FROM `£Ô£±£²b` RIGHT JOIN `£Ô£±£²a` ON (`£Ô£±£²a`.`£Ã£±` = `£Ô£±£²b`.`£Ã£±`); £Ã£± £Ã£± íÜ íÜ diff --git a/mysql-test/suite/jp/r/jp_join_utf8.result b/mysql-test/suite/jp/r/jp_join_utf8.result index 716e97a2bb3..8c222653c3e 100644 --- a/mysql-test/suite/jp/r/jp_join_utf8.result +++ b/mysql-test/suite/jp/r/jp_join_utf8.result @@ -71,31 +71,31 @@ SELECT * FROM `T1a` INNER JOIN `T1b`; ï½¶ ï½± ï½» ï½± SELECT * FROM `T1a` JOIN `T1b` USING (`C1`); -C1 C1 -ï½± ï½± +C1 +ï½± SELECT * FROM `T1a` INNER JOIN `T1b` USING (`C1`); -C1 C1 -ï½± ï½± +C1 +ï½± SELECT * FROM `T1a` CROSS JOIN `T1b`; C1 C1 ï½± ï½± ï½¶ ï½± ï½» ï½± SELECT * FROM `T1a` LEFT JOIN `T1b` USING (`C1`); -C1 C1 -ï½± ï½± -ï½¶ NULL -ï½» NULL +C1 +ï½± +ï½¶ +ï½» SELECT * FROM `T1a` LEFT JOIN `T1b` ON (`T1a`.`C1` = `T1b`.`C1`); C1 C1 ï½± ï½± ï½¶ NULL ï½» NULL SELECT * FROM `T1b` RIGHT JOIN `T1a` USING (`C1`); -C1 C1 -ï½± ï½± -NULL ï½¶ -NULL ï½» +C1 +ï½± +ï½¶ +ï½» SELECT * FROM `T1b` RIGHT JOIN `T1a` ON (`T1a`.`C1` = `T1b`.`C1`); C1 C1 ï½± ï½± @@ -112,31 +112,31 @@ SELECT * FROM `ï¼´ï¼’a` INNER JOIN `ï¼´ï¼’b`; ã‹ ã‚ ã• ã‚ SELECT * FROM `ï¼´ï¼’a` JOIN `ï¼´ï¼’b` USING (`C1`); -C1 C1 -ã‚ ã‚ +C1 +ã‚ SELECT * FROM `ï¼´ï¼’a` INNER JOIN `ï¼´ï¼’b` USING (`C1`); -C1 C1 -ã‚ ã‚ +C1 +ã‚ SELECT * FROM `ï¼´ï¼’a` CROSS JOIN `ï¼´ï¼’b`; C1 C1 ã‚ ã‚ ã‹ ã‚ ã• ã‚ SELECT * FROM `ï¼´ï¼’a` LEFT JOIN `ï¼´ï¼’b` USING (`C1`); -C1 C1 -ã‚ ã‚ -ã‹ NULL -ã• NULL +C1 +ã‚ +ã‹ +ã• SELECT * FROM `ï¼´ï¼’a` LEFT JOIN `ï¼´ï¼’b` ON (`ï¼´ï¼’a`.`C1` = `ï¼´ï¼’b`.`C1`); C1 C1 ã‚ ã‚ ã‹ NULL ã• NULL SELECT * FROM `ï¼´ï¼’b` RIGHT JOIN `ï¼´ï¼’a` USING (`C1`); -C1 C1 -ã‚ ã‚ -NULL ã‹ -NULL ã• +C1 +ã‚ +ã‹ +ã• SELECT * FROM `ï¼´ï¼’b` RIGHT JOIN `ï¼´ï¼’a` ON (`ï¼´ï¼’a`.`C1` = `ï¼´ï¼’b`.`C1`); C1 C1 ã‚ ã‚ @@ -153,31 +153,31 @@ SELECT * FROM `T3a` INNER JOIN `T3b`; é¾– é¾” é¾— é¾” SELECT * FROM `T3a` JOIN `T3b` USING (`C1`); -C1 C1 -é¾” é¾” +C1 +é¾” SELECT * FROM `T3a` INNER JOIN `T3b` USING (`C1`); -C1 C1 -é¾” é¾” +C1 +é¾” SELECT * FROM `T3a` CROSS JOIN `T3b`; C1 C1 é¾” é¾” é¾– é¾” é¾— é¾” SELECT * FROM `T3a` LEFT JOIN `T3b` USING (`C1`); -C1 C1 -é¾” é¾” -é¾– NULL -é¾— NULL +C1 +é¾” +é¾– +é¾— SELECT * FROM `T3a` LEFT JOIN `T3b` ON (`T3a`.`C1` = `T3b`.`C1`); C1 C1 é¾” é¾” é¾– NULL é¾— NULL SELECT * FROM `T3b` RIGHT JOIN `T3a` USING (`C1`); -C1 C1 -é¾” é¾” -NULL é¾– -NULL é¾— +C1 +é¾” +é¾– +é¾— SELECT * FROM `T3b` RIGHT JOIN `T3a` ON (`T3a`.`C1` = `T3b`.`C1`); C1 C1 é¾” é¾” @@ -194,31 +194,31 @@ SELECT * FROM `ï¼´ï¼”a` INNER JOIN `ï¼´ï¼”b`; ï½¶ ï½± ï½» ï½± SELECT * FROM `ï¼´ï¼”a` JOIN `ï¼´ï¼”b` USING (`C1`); -C1 C1 -ï½± ï½± +C1 +ï½± SELECT * FROM `ï¼´ï¼”a` INNER JOIN `ï¼´ï¼”b` USING (`C1`); -C1 C1 -ï½± ï½± +C1 +ï½± SELECT * FROM `ï¼´ï¼”a` CROSS JOIN `ï¼´ï¼”b`; C1 C1 ï½± ï½± ï½¶ ï½± ï½» ï½± SELECT * FROM `ï¼´ï¼”a` LEFT JOIN `ï¼´ï¼”b` USING (`C1`); -C1 C1 -ï½± ï½± -ï½¶ NULL -ï½» NULL +C1 +ï½± +ï½¶ +ï½» SELECT * FROM `ï¼´ï¼”a` LEFT JOIN `ï¼´ï¼”b` ON (`ï¼´ï¼”a`.`C1` = `ï¼´ï¼”b`.`C1`); C1 C1 ï½± ï½± ï½¶ NULL ï½» NULL SELECT * FROM `ï¼´ï¼”b` RIGHT JOIN `ï¼´ï¼”a` USING (`C1`); -C1 C1 -ï½± ï½± -NULL ï½¶ -NULL ï½» +C1 +ï½± +ï½¶ +ï½» SELECT * FROM `ï¼´ï¼”b` RIGHT JOIN `ï¼´ï¼”a` ON (`ï¼´ï¼”a`.`C1` = `ï¼´ï¼”b`.`C1`); C1 C1 ï½± ï½± @@ -235,31 +235,31 @@ SELECT * FROM `T5a` INNER JOIN `T5b`; ã‹ ã‚ ã• ã‚ SELECT * FROM `T5a` JOIN `T5b` USING (`C1`); -C1 C1 -ã‚ ã‚ +C1 +ã‚ SELECT * FROM `T5a` INNER JOIN `T5b` USING (`C1`); -C1 C1 -ã‚ ã‚ +C1 +ã‚ SELECT * FROM `T5a` CROSS JOIN `T5b`; C1 C1 ã‚ ã‚ ã‹ ã‚ ã• ã‚ SELECT * FROM `T5a` LEFT JOIN `T5b` USING (`C1`); -C1 C1 -ã‚ ã‚ -ã‹ NULL -ã• NULL +C1 +ã‚ +ã‹ +ã• SELECT * FROM `T5a` LEFT JOIN `T5b` ON (`T5a`.`C1` = `T5b`.`C1`); C1 C1 ã‚ ã‚ ã‹ NULL ã• NULL SELECT * FROM `T5b` RIGHT JOIN `T5a` USING (`C1`); -C1 C1 -ã‚ ã‚ -NULL ã‹ -NULL ã• +C1 +ã‚ +ã‹ +ã• SELECT * FROM `T5b` RIGHT JOIN `T5a` ON (`T5a`.`C1` = `T5b`.`C1`); C1 C1 ã‚ ã‚ @@ -276,31 +276,31 @@ SELECT * FROM `ï¼´ï¼–a` INNER JOIN `ï¼´ï¼–b`; é¾– é¾” é¾— é¾” SELECT * FROM `ï¼´ï¼–a` JOIN `ï¼´ï¼–b` USING (`C1`); -C1 C1 -é¾” é¾” +C1 +é¾” SELECT * FROM `ï¼´ï¼–a` INNER JOIN `ï¼´ï¼–b` USING (`C1`); -C1 C1 -é¾” é¾” +C1 +é¾” SELECT * FROM `ï¼´ï¼–a` CROSS JOIN `ï¼´ï¼–b`; C1 C1 é¾” é¾” é¾– é¾” é¾— é¾” SELECT * FROM `ï¼´ï¼–a` LEFT JOIN `ï¼´ï¼–b` USING (`C1`); -C1 C1 -é¾” é¾” -é¾– NULL -é¾— NULL +C1 +é¾” +é¾– +é¾— SELECT * FROM `ï¼´ï¼–a` LEFT JOIN `ï¼´ï¼–b` ON (`ï¼´ï¼–a`.`C1` = `ï¼´ï¼–b`.`C1`); C1 C1 é¾” é¾” é¾– NULL é¾— NULL SELECT * FROM `ï¼´ï¼–b` RIGHT JOIN `ï¼´ï¼–a` USING (`C1`); -C1 C1 -é¾” é¾” -NULL é¾– -NULL é¾— +C1 +é¾” +é¾– +é¾— SELECT * FROM `ï¼´ï¼–b` RIGHT JOIN `ï¼´ï¼–a` ON (`ï¼´ï¼–a`.`C1` = `ï¼´ï¼–b`.`C1`); C1 C1 é¾” é¾” @@ -317,31 +317,31 @@ SELECT * FROM `ï¼´ï¼—a` INNER JOIN `ï¼´ï¼—b`; ï½¶ ï½± ï½» ï½± SELECT * FROM `ï¼´ï¼—a` JOIN `ï¼´ï¼—b` USING (`C1`); -C1 C1 -ï½± ï½± +C1 +ï½± SELECT * FROM `ï¼´ï¼—a` INNER JOIN `ï¼´ï¼—b` USING (`C1`); -C1 C1 -ï½± ï½± +C1 +ï½± SELECT * FROM `ï¼´ï¼—a` CROSS JOIN `ï¼´ï¼—b`; C1 C1 ï½± ï½± ï½¶ ï½± ï½» ï½± SELECT * FROM `ï¼´ï¼—a` LEFT JOIN `ï¼´ï¼—b` USING (`C1`); -C1 C1 -ï½± ï½± -ï½¶ NULL -ï½» NULL +C1 +ï½± +ï½¶ +ï½» SELECT * FROM `ï¼´ï¼—a` LEFT JOIN `ï¼´ï¼—b` ON (`ï¼´ï¼—a`.`C1` = `ï¼´ï¼—b`.`C1`); C1 C1 ï½± ï½± ï½¶ NULL ï½» NULL SELECT * FROM `ï¼´ï¼—b` RIGHT JOIN `ï¼´ï¼—a` USING (`C1`); -C1 C1 -ï½± ï½± -NULL ï½¶ -NULL ï½» +C1 +ï½± +ï½¶ +ï½» SELECT * FROM `ï¼´ï¼—b` RIGHT JOIN `ï¼´ï¼—a` ON (`ï¼´ï¼—a`.`C1` = `ï¼´ï¼—b`.`C1`); C1 C1 ï½± ï½± @@ -358,31 +358,31 @@ SELECT * FROM `T8a` INNER JOIN `T8b`; ã‹ ã‚ ã• ã‚ SELECT * FROM `T8a` JOIN `T8b` USING (`C1`); -C1 C1 -ã‚ ã‚ +C1 +ã‚ SELECT * FROM `T8a` INNER JOIN `T8b` USING (`C1`); -C1 C1 -ã‚ ã‚ +C1 +ã‚ SELECT * FROM `T8a` CROSS JOIN `T8b`; C1 C1 ã‚ ã‚ ã‹ ã‚ ã• ã‚ SELECT * FROM `T8a` LEFT JOIN `T8b` USING (`C1`); -C1 C1 -ã‚ ã‚ -ã‹ NULL -ã• NULL +C1 +ã‚ +ã‹ +ã• SELECT * FROM `T8a` LEFT JOIN `T8b` ON (`T8a`.`C1` = `T8b`.`C1`); C1 C1 ã‚ ã‚ ã‹ NULL ã• NULL SELECT * FROM `T8b` RIGHT JOIN `T8a` USING (`C1`); -C1 C1 -ã‚ ã‚ -NULL ã‹ -NULL ã• +C1 +ã‚ +ã‹ +ã• SELECT * FROM `T8b` RIGHT JOIN `T8a` ON (`T8a`.`C1` = `T8b`.`C1`); C1 C1 ã‚ ã‚ @@ -399,31 +399,31 @@ SELECT * FROM `ï¼´ï¼™a` INNER JOIN `ï¼´ï¼™b`; é¾– é¾” é¾— é¾” SELECT * FROM `ï¼´ï¼™a` JOIN `ï¼´ï¼™b` USING (`C1`); -C1 C1 -é¾” é¾” +C1 +é¾” SELECT * FROM `ï¼´ï¼™a` INNER JOIN `ï¼´ï¼™b` USING (`C1`); -C1 C1 -é¾” é¾” +C1 +é¾” SELECT * FROM `ï¼´ï¼™a` CROSS JOIN `ï¼´ï¼™b`; C1 C1 é¾” é¾” é¾– é¾” é¾— é¾” SELECT * FROM `ï¼´ï¼™a` LEFT JOIN `ï¼´ï¼™b` USING (`C1`); -C1 C1 -é¾” é¾” -é¾– NULL -é¾— NULL +C1 +é¾” +é¾– +é¾— SELECT * FROM `ï¼´ï¼™a` LEFT JOIN `ï¼´ï¼™b` ON (`ï¼´ï¼™a`.`C1` = `ï¼´ï¼™b`.`C1`); C1 C1 é¾” é¾” é¾– NULL é¾— NULL SELECT * FROM `ï¼´ï¼™b` RIGHT JOIN `ï¼´ï¼™a` USING (`C1`); -C1 C1 -é¾” é¾” -NULL é¾– -NULL é¾— +C1 +é¾” +é¾– +é¾— SELECT * FROM `ï¼´ï¼™b` RIGHT JOIN `ï¼´ï¼™a` ON (`ï¼´ï¼™a`.`C1` = `ï¼´ï¼™b`.`C1`); C1 C1 é¾” é¾” @@ -440,31 +440,31 @@ SELECT * FROM `T1ï¼a` INNER JOIN `T1ï¼b`; ï½¶ ï½± ï½» ï½± SELECT * FROM `T1ï¼a` JOIN `T1ï¼b` USING (`C1`); -C1 C1 -ï½± ï½± +C1 +ï½± SELECT * FROM `T1ï¼a` INNER JOIN `T1ï¼b` USING (`C1`); -C1 C1 -ï½± ï½± +C1 +ï½± SELECT * FROM `T1ï¼a` CROSS JOIN `T1ï¼b`; C1 C1 ï½± ï½± ï½¶ ï½± ï½» ï½± SELECT * FROM `T1ï¼a` LEFT JOIN `T1ï¼b` USING (`C1`); -C1 C1 -ï½± ï½± -ï½¶ NULL -ï½» NULL +C1 +ï½± +ï½¶ +ï½» SELECT * FROM `T1ï¼a` LEFT JOIN `T1ï¼b` ON (`T1ï¼a`.`C1` = `T1ï¼b`.`C1`); C1 C1 ï½± ï½± ï½¶ NULL ï½» NULL SELECT * FROM `T1ï¼b` RIGHT JOIN `T1ï¼a` USING (`C1`); -C1 C1 -ï½± ï½± -NULL ï½¶ -NULL ï½» +C1 +ï½± +ï½¶ +ï½» SELECT * FROM `T1ï¼b` RIGHT JOIN `T1ï¼a` ON (`T1ï¼a`.`C1` = `T1ï¼b`.`C1`); C1 C1 ï½± ï½± @@ -481,31 +481,31 @@ SELECT * FROM `T11a` INNER JOIN `T11b`; ã‹ ã‚ ã• ã‚ SELECT * FROM `T11a` JOIN `T11b` USING (`C1`); -C1 C1 -ã‚ ã‚ +C1 +ã‚ SELECT * FROM `T11a` INNER JOIN `T11b` USING (`C1`); -C1 C1 -ã‚ ã‚ +C1 +ã‚ SELECT * FROM `T11a` CROSS JOIN `T11b`; C1 C1 ã‚ ã‚ ã‹ ã‚ ã• ã‚ SELECT * FROM `T11a` LEFT JOIN `T11b` USING (`C1`); -C1 C1 -ã‚ ã‚ -ã‹ NULL -ã• NULL +C1 +ã‚ +ã‹ +ã• SELECT * FROM `T11a` LEFT JOIN `T11b` ON (`T11a`.`C1` = `T11b`.`C1`); C1 C1 ã‚ ã‚ ã‹ NULL ã• NULL SELECT * FROM `T11b` RIGHT JOIN `T11a` USING (`C1`); -C1 C1 -ã‚ ã‚ -NULL ã‹ -NULL ã• +C1 +ã‚ +ã‹ +ã• SELECT * FROM `T11b` RIGHT JOIN `T11a` ON (`T11a`.`C1` = `T11b`.`C1`); C1 C1 ã‚ ã‚ @@ -522,31 +522,31 @@ SELECT * FROM `T12a` INNER JOIN `T12b`; é¾– é¾” é¾— é¾” SELECT * FROM `T12a` JOIN `T12b` USING (`C1`); -C1 C1 -é¾” é¾” +C1 +é¾” SELECT * FROM `T12a` INNER JOIN `T12b` USING (`C1`); -C1 C1 -é¾” é¾” +C1 +é¾” SELECT * FROM `T12a` CROSS JOIN `T12b`; C1 C1 é¾” é¾” é¾– é¾” é¾— é¾” SELECT * FROM `T12a` LEFT JOIN `T12b` USING (`C1`); -C1 C1 -é¾” é¾” -é¾– NULL -é¾— NULL +C1 +é¾” +é¾– +é¾— SELECT * FROM `T12a` LEFT JOIN `T12b` ON (`T12a`.`C1` = `T12b`.`C1`); C1 C1 é¾” é¾” é¾– NULL é¾— NULL SELECT * FROM `T12b` RIGHT JOIN `T12a` USING (`C1`); -C1 C1 -é¾” é¾” -NULL é¾– -NULL é¾— +C1 +é¾” +é¾– +é¾— SELECT * FROM `T12b` RIGHT JOIN `T12a` ON (`T12a`.`C1` = `T12b`.`C1`); C1 C1 é¾” é¾” diff --git a/mysql-test/suite/jp/r/jp_select_sjis.result b/mysql-test/suite/jp/r/jp_select_sjis.result index d48d08d745f..652b538fb88 100644 --- a/mysql-test/suite/jp/r/jp_select_sjis.result +++ b/mysql-test/suite/jp/r/jp_select_sjis.result @@ -118,6 +118,7 @@ SELECT * FROM ` êê‘ê’ê“ê”ê•ê–ê—ê˜ê™êšê›êœêêžEEEEE SELECT * FROM `‚s‚R`; ‚b‚P + ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ SELECT * FROM `‚s‚S`; ‚b‚P @@ -201,6 +202,7 @@ SELECT * FROM ` êê‘ê’ê“ê”ê•ê–ê—ê˜ê™êšê›êœêêžEEEEE SELECT * FROM `‚s‚U`; ‚b‚P + ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ SELECT * FROM `‚s‚V`; ‚b‚P @@ -285,6 +287,7 @@ SELECT * FROM ` SELECT * FROM `‚s‚X`; ‚b‚P ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ + SELECT * FROM `‚s‚P‚O`; ‚b‚P !"#$%&'()*+,-./ @@ -368,6 +371,7 @@ SELECT * FROM ` SELECT * FROM `‚s‚P‚Q`; ‚b‚P ƒ\\•\—\\‰\Ž\\“\”\–\˜\‘\’\™\š\›\œ\\ž\ + drop table `‚s‚P`; drop table `‚s‚Q`; drop table `‚s‚R`; diff --git a/mysql-test/suite/jp/t/jp_alter_sjis.test b/mysql-test/suite/jp/t/jp_alter_sjis.test index b7b31862599..f250afcf5dd 100644 --- a/mysql-test/suite/jp/t/jp_alter_sjis.test +++ b/mysql-test/suite/jp/t/jp_alter_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis SET NAMES sjis; SET character_set_database = sjis; diff --git a/mysql-test/suite/jp/t/jp_alter_ucs2.test b/mysql-test/suite/jp/t/jp_alter_ucs2.test index 6c5b3132edf..27cf5b72839 100644 --- a/mysql-test/suite/jp/t/jp_alter_ucs2.test +++ b/mysql-test/suite/jp/t/jp_alter_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_alter_ujis.test b/mysql-test/suite/jp/t/jp_alter_ujis.test index d388d20c49b..b817f608446 100644 --- a/mysql-test/suite/jp/t/jp_alter_ujis.test +++ b/mysql-test/suite/jp/t/jp_alter_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_alter_utf8.test b/mysql-test/suite/jp/t/jp_alter_utf8.test index 6771343f38f..60a67485ba5 100644 --- a/mysql-test/suite/jp/t/jp_alter_utf8.test +++ b/mysql-test/suite/jp/t/jp_alter_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings DROP TABLE IF EXISTS `アアア`; DROP TABLE IF EXISTS `イイイ`; diff --git a/mysql-test/suite/jp/t/jp_charlength_sjis.test b/mysql-test/suite/jp/t/jp_charlength_sjis.test index 5f3543bb7a6..350605450da 100644 --- a/mysql-test/suite/jp/t/jp_charlength_sjis.test +++ b/mysql-test/suite/jp/t/jp_charlength_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_charlength_ucs2.test b/mysql-test/suite/jp/t/jp_charlength_ucs2.test index 2db9db7cfc6..714ced47ff8 100644 --- a/mysql-test/suite/jp/t/jp_charlength_ucs2.test +++ b/mysql-test/suite/jp/t/jp_charlength_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_charlength_ujis.test b/mysql-test/suite/jp/t/jp_charlength_ujis.test index 08973231f27..923bffef540 100644 --- a/mysql-test/suite/jp/t/jp_charlength_ujis.test +++ b/mysql-test/suite/jp/t/jp_charlength_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_charlength_utf8.test b/mysql-test/suite/jp/t/jp_charlength_utf8.test index a3f74db27ee..bc099caf74a 100644 --- a/mysql-test/suite/jp/t/jp_charlength_utf8.test +++ b/mysql-test/suite/jp/t/jp_charlength_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_charset_sjis.test b/mysql-test/suite/jp/t/jp_charset_sjis.test index 3a9f264bdfe..276be86cd9d 100644 --- a/mysql-test/suite/jp/t/jp_charset_sjis.test +++ b/mysql-test/suite/jp/t/jp_charset_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_charset_ucs2.test b/mysql-test/suite/jp/t/jp_charset_ucs2.test index 5183071033b..f7971095fa6 100644 --- a/mysql-test/suite/jp/t/jp_charset_ucs2.test +++ b/mysql-test/suite/jp/t/jp_charset_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_charset_ujis.test b/mysql-test/suite/jp/t/jp_charset_ujis.test index de9ef318530..a8a6544537a 100644 --- a/mysql-test/suite/jp/t/jp_charset_ujis.test +++ b/mysql-test/suite/jp/t/jp_charset_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_charset_utf8.test b/mysql-test/suite/jp/t/jp_charset_utf8.test index 2d73daba42a..7d8311c2f72 100644 --- a/mysql-test/suite/jp/t/jp_charset_utf8.test +++ b/mysql-test/suite/jp/t/jp_charset_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_convert_sjis.test b/mysql-test/suite/jp/t/jp_convert_sjis.test index 93fa33029bf..835328c92eb 100644 --- a/mysql-test/suite/jp/t/jp_convert_sjis.test +++ b/mysql-test/suite/jp/t/jp_convert_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis SET NAMES sjis; SET character_set_database = sjis; diff --git a/mysql-test/suite/jp/t/jp_convert_ucs2.test b/mysql-test/suite/jp/t/jp_convert_ucs2.test index 88b0d0c9cba..3ed4efe158d 100644 --- a/mysql-test/suite/jp/t/jp_convert_ucs2.test +++ b/mysql-test/suite/jp/t/jp_convert_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_convert_ujis.test b/mysql-test/suite/jp/t/jp_convert_ujis.test index d6303b66f34..4409b6cad90 100644 --- a/mysql-test/suite/jp/t/jp_convert_ujis.test +++ b/mysql-test/suite/jp/t/jp_convert_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_convert_utf8.test b/mysql-test/suite/jp/t/jp_convert_utf8.test index a687b0f06cb..e7c180e72fc 100644 --- a/mysql-test/suite/jp/t/jp_convert_utf8.test +++ b/mysql-test/suite/jp/t/jp_convert_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_create_tbl_sjis.test b/mysql-test/suite/jp/t/jp_create_tbl_sjis.test index 45c0b24388b..93f3ac3c4a3 100644 --- a/mysql-test/suite/jp/t/jp_create_tbl_sjis.test +++ b/mysql-test/suite/jp/t/jp_create_tbl_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis SET NAMES sjis; SET character_set_database = sjis; diff --git a/mysql-test/suite/jp/t/jp_create_tbl_ucs2.test b/mysql-test/suite/jp/t/jp_create_tbl_ucs2.test index 519697e3530..553ef8a4dad 100644 --- a/mysql-test/suite/jp/t/jp_create_tbl_ucs2.test +++ b/mysql-test/suite/jp/t/jp_create_tbl_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_create_tbl_ujis.test b/mysql-test/suite/jp/t/jp_create_tbl_ujis.test index ac70facdce9..1106ddc1417 100644 --- a/mysql-test/suite/jp/t/jp_create_tbl_ujis.test +++ b/mysql-test/suite/jp/t/jp_create_tbl_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_create_tbl_utf8.test b/mysql-test/suite/jp/t/jp_create_tbl_utf8.test index 5c816eb169a..9b0ece77e34 100644 --- a/mysql-test/suite/jp/t/jp_create_tbl_utf8.test +++ b/mysql-test/suite/jp/t/jp_create_tbl_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings DROP TABLE IF EXISTS `アアア`; DROP TABLE IF EXISTS `イイイ`; diff --git a/mysql-test/suite/jp/t/jp_enum_sjis.test b/mysql-test/suite/jp/t/jp_enum_sjis.test index 2ea1bf320e0..c433e0bcac4 100644 --- a/mysql-test/suite/jp/t/jp_enum_sjis.test +++ b/mysql-test/suite/jp/t/jp_enum_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_enum_ucs2.test b/mysql-test/suite/jp/t/jp_enum_ucs2.test index 2239ebab478..79f5952cf97 100644 --- a/mysql-test/suite/jp/t/jp_enum_ucs2.test +++ b/mysql-test/suite/jp/t/jp_enum_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc # half-with kana is not handled correctly in 4.1 diff --git a/mysql-test/suite/jp/t/jp_enum_ujis.test b/mysql-test/suite/jp/t/jp_enum_ujis.test index da41165aad0..f48d176ec6b 100644 --- a/mysql-test/suite/jp/t/jp_enum_ujis.test +++ b/mysql-test/suite/jp/t/jp_enum_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_enum_utf8.test b/mysql-test/suite/jp/t/jp_enum_utf8.test index 4ce3576b604..64fe2129164 100644 --- a/mysql-test/suite/jp/t/jp_enum_utf8.test +++ b/mysql-test/suite/jp/t/jp_enum_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_insert_sjis.test b/mysql-test/suite/jp/t/jp_insert_sjis.test index 0266ad1eaca..a940eeb5782 100644 --- a/mysql-test/suite/jp/t/jp_insert_sjis.test +++ b/mysql-test/suite/jp/t/jp_insert_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_insert_ucs2.test b/mysql-test/suite/jp/t/jp_insert_ucs2.test index 9b0a02e57d8..443f6f1107b 100644 --- a/mysql-test/suite/jp/t/jp_insert_ucs2.test +++ b/mysql-test/suite/jp/t/jp_insert_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_insert_ujis.test b/mysql-test/suite/jp/t/jp_insert_ujis.test index 7b6d2838386..ab82db59326 100644 --- a/mysql-test/suite/jp/t/jp_insert_ujis.test +++ b/mysql-test/suite/jp/t/jp_insert_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_insert_utf8.test b/mysql-test/suite/jp/t/jp_insert_utf8.test index ef6acb90063..e8c41bab4ea 100644 --- a/mysql-test/suite/jp/t/jp_insert_utf8.test +++ b/mysql-test/suite/jp/t/jp_insert_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_instr_sjis.test b/mysql-test/suite/jp/t/jp_instr_sjis.test index c19b5f2b14c..83480ea0267 100644 --- a/mysql-test/suite/jp/t/jp_instr_sjis.test +++ b/mysql-test/suite/jp/t/jp_instr_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_instr_ucs2.test b/mysql-test/suite/jp/t/jp_instr_ucs2.test index b8f83961e90..7b442d09a3d 100644 --- a/mysql-test/suite/jp/t/jp_instr_ucs2.test +++ b/mysql-test/suite/jp/t/jp_instr_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_instr_ujis.test b/mysql-test/suite/jp/t/jp_instr_ujis.test index 696e1147372..d0373ba73ce 100644 --- a/mysql-test/suite/jp/t/jp_instr_ujis.test +++ b/mysql-test/suite/jp/t/jp_instr_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_instr_utf8.test b/mysql-test/suite/jp/t/jp_instr_utf8.test index b25b72bc8d0..c7491101872 100644 --- a/mysql-test/suite/jp/t/jp_instr_utf8.test +++ b/mysql-test/suite/jp/t/jp_instr_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_join_sjis.test b/mysql-test/suite/jp/t/jp_join_sjis.test index 30b23913929..77d1dc15c5c 100644 --- a/mysql-test/suite/jp/t/jp_join_sjis.test +++ b/mysql-test/suite/jp/t/jp_join_sjis.test @@ -1,3 +1,4 @@ +-- source include/have_innodb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_join_ucs2.test b/mysql-test/suite/jp/t/jp_join_ucs2.test index 27e49203dd2..276af80f7af 100644 --- a/mysql-test/suite/jp/t/jp_join_ucs2.test +++ b/mysql-test/suite/jp/t/jp_join_ucs2.test @@ -1,3 +1,4 @@ +-- source include/have_innodb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_join_ujis.test b/mysql-test/suite/jp/t/jp_join_ujis.test index 079f260cc26..5716ee12e60 100644 --- a/mysql-test/suite/jp/t/jp_join_ujis.test +++ b/mysql-test/suite/jp/t/jp_join_ujis.test @@ -1,3 +1,4 @@ +-- source include/have_innodb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_join_utf8.test b/mysql-test/suite/jp/t/jp_join_utf8.test index 0b2f033f8bb..36f8e930bc3 100644 --- a/mysql-test/suite/jp/t/jp_join_utf8.test +++ b/mysql-test/suite/jp/t/jp_join_utf8.test @@ -1,3 +1,4 @@ +-- source include/have_innodb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_left_sjis.test b/mysql-test/suite/jp/t/jp_left_sjis.test index 5d69d9892e2..e93e92493a1 100644 --- a/mysql-test/suite/jp/t/jp_left_sjis.test +++ b/mysql-test/suite/jp/t/jp_left_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_left_ucs2.test b/mysql-test/suite/jp/t/jp_left_ucs2.test index 59d10b7d736..2c1be4a7e6a 100644 --- a/mysql-test/suite/jp/t/jp_left_ucs2.test +++ b/mysql-test/suite/jp/t/jp_left_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_left_ujis.test b/mysql-test/suite/jp/t/jp_left_ujis.test index 718639cd8a4..f639bf643df 100644 --- a/mysql-test/suite/jp/t/jp_left_ujis.test +++ b/mysql-test/suite/jp/t/jp_left_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_left_utf8.test b/mysql-test/suite/jp/t/jp_left_utf8.test index f9c99718e0f..63d9061a879 100644 --- a/mysql-test/suite/jp/t/jp_left_utf8.test +++ b/mysql-test/suite/jp/t/jp_left_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_length_sjis.test b/mysql-test/suite/jp/t/jp_length_sjis.test index 7023891b7f0..81121a4432e 100644 --- a/mysql-test/suite/jp/t/jp_length_sjis.test +++ b/mysql-test/suite/jp/t/jp_length_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_length_ucs2.test b/mysql-test/suite/jp/t/jp_length_ucs2.test index 9951c9b6cd1..1dcc975d868 100644 --- a/mysql-test/suite/jp/t/jp_length_ucs2.test +++ b/mysql-test/suite/jp/t/jp_length_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_length_ujis.test b/mysql-test/suite/jp/t/jp_length_ujis.test index ac3aef2c768..ad41c7a7113 100644 --- a/mysql-test/suite/jp/t/jp_length_ujis.test +++ b/mysql-test/suite/jp/t/jp_length_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_length_utf8.test b/mysql-test/suite/jp/t/jp_length_utf8.test index 5c5021f37be..7bfe1896034 100644 --- a/mysql-test/suite/jp/t/jp_length_utf8.test +++ b/mysql-test/suite/jp/t/jp_length_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_like_sjis.test b/mysql-test/suite/jp/t/jp_like_sjis.test index 5c41b9ff7ef..1cb7aadb876 100644 --- a/mysql-test/suite/jp/t/jp_like_sjis.test +++ b/mysql-test/suite/jp/t/jp_like_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_like_ucs2.test b/mysql-test/suite/jp/t/jp_like_ucs2.test index feae40de49e..1f9b7c09b9d 100644 --- a/mysql-test/suite/jp/t/jp_like_ucs2.test +++ b/mysql-test/suite/jp/t/jp_like_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_like_ujis.test b/mysql-test/suite/jp/t/jp_like_ujis.test index 29ef7c5d48b..56c4fa8a8b0 100644 --- a/mysql-test/suite/jp/t/jp_like_ujis.test +++ b/mysql-test/suite/jp/t/jp_like_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_like_utf8.test b/mysql-test/suite/jp/t/jp_like_utf8.test index 4247242029d..f6cc895d814 100644 --- a/mysql-test/suite/jp/t/jp_like_utf8.test +++ b/mysql-test/suite/jp/t/jp_like_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_locate_sjis.test b/mysql-test/suite/jp/t/jp_locate_sjis.test index 92c671199b6..a015109e2a3 100644 --- a/mysql-test/suite/jp/t/jp_locate_sjis.test +++ b/mysql-test/suite/jp/t/jp_locate_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_locate_ucs2.test b/mysql-test/suite/jp/t/jp_locate_ucs2.test index d00ad67235a..111caefb02e 100644 --- a/mysql-test/suite/jp/t/jp_locate_ucs2.test +++ b/mysql-test/suite/jp/t/jp_locate_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_locate_ujis.test b/mysql-test/suite/jp/t/jp_locate_ujis.test index 5375fad75db..872555a4532 100644 --- a/mysql-test/suite/jp/t/jp_locate_ujis.test +++ b/mysql-test/suite/jp/t/jp_locate_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_locate_utf8.test b/mysql-test/suite/jp/t/jp_locate_utf8.test index cbf6714e322..85d2e69fd60 100644 --- a/mysql-test/suite/jp/t/jp_locate_utf8.test +++ b/mysql-test/suite/jp/t/jp_locate_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_lpad_sjis.test b/mysql-test/suite/jp/t/jp_lpad_sjis.test index 7038112cbc8..4b18402473d 100644 --- a/mysql-test/suite/jp/t/jp_lpad_sjis.test +++ b/mysql-test/suite/jp/t/jp_lpad_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_lpad_ucs2.test b/mysql-test/suite/jp/t/jp_lpad_ucs2.test index e3bead0855a..95dd088abce 100644 --- a/mysql-test/suite/jp/t/jp_lpad_ucs2.test +++ b/mysql-test/suite/jp/t/jp_lpad_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_lpad_ujis.test b/mysql-test/suite/jp/t/jp_lpad_ujis.test index eea4877ec3a..c1149a67207 100644 --- a/mysql-test/suite/jp/t/jp_lpad_ujis.test +++ b/mysql-test/suite/jp/t/jp_lpad_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_lpad_utf8.test b/mysql-test/suite/jp/t/jp_lpad_utf8.test index 599bf5eba28..42aa2fd860b 100644 --- a/mysql-test/suite/jp/t/jp_lpad_utf8.test +++ b/mysql-test/suite/jp/t/jp_lpad_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_ltrim_sjis.test b/mysql-test/suite/jp/t/jp_ltrim_sjis.test index 864238df07c..7b5e20ec9a4 100644 --- a/mysql-test/suite/jp/t/jp_ltrim_sjis.test +++ b/mysql-test/suite/jp/t/jp_ltrim_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_ltrim_ucs2.test b/mysql-test/suite/jp/t/jp_ltrim_ucs2.test index 0ae647f5222..25a6eaabc60 100644 --- a/mysql-test/suite/jp/t/jp_ltrim_ucs2.test +++ b/mysql-test/suite/jp/t/jp_ltrim_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_ltrim_ujis.test b/mysql-test/suite/jp/t/jp_ltrim_ujis.test index 64363aa330b..fbba90a38b5 100644 --- a/mysql-test/suite/jp/t/jp_ltrim_ujis.test +++ b/mysql-test/suite/jp/t/jp_ltrim_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_ltrim_utf8.test b/mysql-test/suite/jp/t/jp_ltrim_utf8.test index 846ce11163b..b33d22e459d 100644 --- a/mysql-test/suite/jp/t/jp_ltrim_utf8.test +++ b/mysql-test/suite/jp/t/jp_ltrim_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_ps_sjis.test b/mysql-test/suite/jp/t/jp_ps_sjis.test index cc93dca2a79..2e09c51cf7a 100644 --- a/mysql-test/suite/jp/t/jp_ps_sjis.test +++ b/mysql-test/suite/jp/t/jp_ps_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/jp/t/jp_ps_ujis.test b/mysql-test/suite/jp/t/jp_ps_ujis.test index 7d61c12e496..ab64fcf5216 100644 --- a/mysql-test/suite/jp/t/jp_ps_ujis.test +++ b/mysql-test/suite/jp/t/jp_ps_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_replace_sjis.test b/mysql-test/suite/jp/t/jp_replace_sjis.test index 811d3350a34..91996ba83e9 100644 --- a/mysql-test/suite/jp/t/jp_replace_sjis.test +++ b/mysql-test/suite/jp/t/jp_replace_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_replace_ucs2.test b/mysql-test/suite/jp/t/jp_replace_ucs2.test index 7739a30cd9c..3043115ef62 100644 --- a/mysql-test/suite/jp/t/jp_replace_ucs2.test +++ b/mysql-test/suite/jp/t/jp_replace_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_replace_ujis.test b/mysql-test/suite/jp/t/jp_replace_ujis.test index 3d8724e63d5..1ba29426010 100644 --- a/mysql-test/suite/jp/t/jp_replace_ujis.test +++ b/mysql-test/suite/jp/t/jp_replace_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_replace_utf8.test b/mysql-test/suite/jp/t/jp_replace_utf8.test index 1d89a43648b..81b892a5df7 100644 --- a/mysql-test/suite/jp/t/jp_replace_utf8.test +++ b/mysql-test/suite/jp/t/jp_replace_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_reverse_sjis.test b/mysql-test/suite/jp/t/jp_reverse_sjis.test index c1e2b2a17ca..5d9014dc3a6 100644 --- a/mysql-test/suite/jp/t/jp_reverse_sjis.test +++ b/mysql-test/suite/jp/t/jp_reverse_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_reverse_ucs2.test b/mysql-test/suite/jp/t/jp_reverse_ucs2.test index d91ec7f70e8..95afeeda570 100644 --- a/mysql-test/suite/jp/t/jp_reverse_ucs2.test +++ b/mysql-test/suite/jp/t/jp_reverse_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_reverse_ujis.test b/mysql-test/suite/jp/t/jp_reverse_ujis.test index d37d363f59a..0d66201c367 100644 --- a/mysql-test/suite/jp/t/jp_reverse_ujis.test +++ b/mysql-test/suite/jp/t/jp_reverse_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_reverse_utf8.test b/mysql-test/suite/jp/t/jp_reverse_utf8.test index 4e53d4be049..ee323b64ada 100644 --- a/mysql-test/suite/jp/t/jp_reverse_utf8.test +++ b/mysql-test/suite/jp/t/jp_reverse_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_right_sjis.test b/mysql-test/suite/jp/t/jp_right_sjis.test index f481ec532ec..edf3795c510 100644 --- a/mysql-test/suite/jp/t/jp_right_sjis.test +++ b/mysql-test/suite/jp/t/jp_right_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_right_ucs2.test b/mysql-test/suite/jp/t/jp_right_ucs2.test index 23ca2fa4fae..d3132b3e11f 100644 --- a/mysql-test/suite/jp/t/jp_right_ucs2.test +++ b/mysql-test/suite/jp/t/jp_right_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_right_ujis.test b/mysql-test/suite/jp/t/jp_right_ujis.test index b5284489c7e..92cd7ed83dc 100644 --- a/mysql-test/suite/jp/t/jp_right_ujis.test +++ b/mysql-test/suite/jp/t/jp_right_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_right_utf8.test b/mysql-test/suite/jp/t/jp_right_utf8.test index 863755c1dcf..6d884e55771 100644 --- a/mysql-test/suite/jp/t/jp_right_utf8.test +++ b/mysql-test/suite/jp/t/jp_right_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_rpad_sjis.test b/mysql-test/suite/jp/t/jp_rpad_sjis.test index cc008631548..1bf752020bb 100644 --- a/mysql-test/suite/jp/t/jp_rpad_sjis.test +++ b/mysql-test/suite/jp/t/jp_rpad_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_rpad_ucs2.test b/mysql-test/suite/jp/t/jp_rpad_ucs2.test index ca5059497d3..f3876dafe2f 100644 --- a/mysql-test/suite/jp/t/jp_rpad_ucs2.test +++ b/mysql-test/suite/jp/t/jp_rpad_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_rpad_ujis.test b/mysql-test/suite/jp/t/jp_rpad_ujis.test index d7725b80af7..6ace7442b8d 100644 --- a/mysql-test/suite/jp/t/jp_rpad_ujis.test +++ b/mysql-test/suite/jp/t/jp_rpad_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_rpad_utf8.test b/mysql-test/suite/jp/t/jp_rpad_utf8.test index b5a335bc6ce..6c075e20cb9 100644 --- a/mysql-test/suite/jp/t/jp_rpad_utf8.test +++ b/mysql-test/suite/jp/t/jp_rpad_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_rtrim_sjis.test b/mysql-test/suite/jp/t/jp_rtrim_sjis.test index c80cf9410f9..1a9511698ce 100644 --- a/mysql-test/suite/jp/t/jp_rtrim_sjis.test +++ b/mysql-test/suite/jp/t/jp_rtrim_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_rtrim_ucs2.test b/mysql-test/suite/jp/t/jp_rtrim_ucs2.test index 0fac38d12d1..2132eaa5cbe 100644 --- a/mysql-test/suite/jp/t/jp_rtrim_ucs2.test +++ b/mysql-test/suite/jp/t/jp_rtrim_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_rtrim_ujis.test b/mysql-test/suite/jp/t/jp_rtrim_ujis.test index 46cda84dd55..07b42b96dfd 100644 --- a/mysql-test/suite/jp/t/jp_rtrim_ujis.test +++ b/mysql-test/suite/jp/t/jp_rtrim_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_rtrim_utf8.test b/mysql-test/suite/jp/t/jp_rtrim_utf8.test index 4880a42db3e..48f863d891c 100644 --- a/mysql-test/suite/jp/t/jp_rtrim_utf8.test +++ b/mysql-test/suite/jp/t/jp_rtrim_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_select_sjis.test b/mysql-test/suite/jp/t/jp_select_sjis.test index d84ed7a4b2c..fc80ce01471 100644 --- a/mysql-test/suite/jp/t/jp_select_sjis.test +++ b/mysql-test/suite/jp/t/jp_select_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_select_ucs2.test b/mysql-test/suite/jp/t/jp_select_ucs2.test index 2e4602e7ea4..6cebdb65db1 100644 --- a/mysql-test/suite/jp/t/jp_select_ucs2.test +++ b/mysql-test/suite/jp/t/jp_select_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_select_ujis.test b/mysql-test/suite/jp/t/jp_select_ujis.test index 4ad9e581a92..0e4d1ffc771 100644 --- a/mysql-test/suite/jp/t/jp_select_ujis.test +++ b/mysql-test/suite/jp/t/jp_select_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_select_utf8.test b/mysql-test/suite/jp/t/jp_select_utf8.test index e614b9ccfb0..88fd6677f7c 100644 --- a/mysql-test/suite/jp/t/jp_select_utf8.test +++ b/mysql-test/suite/jp/t/jp_select_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_subquery_sjis.test b/mysql-test/suite/jp/t/jp_subquery_sjis.test index 5292c7a2519..b6aa3e52f51 100644 --- a/mysql-test/suite/jp/t/jp_subquery_sjis.test +++ b/mysql-test/suite/jp/t/jp_subquery_sjis.test @@ -1,3 +1,4 @@ +-- source include/have_innodb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_subquery_ucs2.test b/mysql-test/suite/jp/t/jp_subquery_ucs2.test index 311433438f4..d2c1fd29358 100644 --- a/mysql-test/suite/jp/t/jp_subquery_ucs2.test +++ b/mysql-test/suite/jp/t/jp_subquery_ucs2.test @@ -1,3 +1,4 @@ +-- source include/have_innodb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_subquery_ujis.test b/mysql-test/suite/jp/t/jp_subquery_ujis.test index 67c9f00fd85..2fd0427481c 100644 --- a/mysql-test/suite/jp/t/jp_subquery_ujis.test +++ b/mysql-test/suite/jp/t/jp_subquery_ujis.test @@ -1,3 +1,4 @@ +-- source include/have_innodb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_subquery_utf8.test b/mysql-test/suite/jp/t/jp_subquery_utf8.test index 97c2df8ce30..460f1c1a903 100644 --- a/mysql-test/suite/jp/t/jp_subquery_utf8.test +++ b/mysql-test/suite/jp/t/jp_subquery_utf8.test @@ -1,3 +1,4 @@ +-- source include/have_innodb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_substring_sjis.test b/mysql-test/suite/jp/t/jp_substring_sjis.test index ac929114880..a6c9496a873 100644 --- a/mysql-test/suite/jp/t/jp_substring_sjis.test +++ b/mysql-test/suite/jp/t/jp_substring_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_substring_ucs2.test b/mysql-test/suite/jp/t/jp_substring_ucs2.test index f3cd5550072..71c0f903aa8 100644 --- a/mysql-test/suite/jp/t/jp_substring_ucs2.test +++ b/mysql-test/suite/jp/t/jp_substring_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_substring_ujis.test b/mysql-test/suite/jp/t/jp_substring_ujis.test index c201c7148da..c93ab761352 100644 --- a/mysql-test/suite/jp/t/jp_substring_ujis.test +++ b/mysql-test/suite/jp/t/jp_substring_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_substring_utf8.test b/mysql-test/suite/jp/t/jp_substring_utf8.test index 9f88115c899..3bd1bbbb491 100644 --- a/mysql-test/suite/jp/t/jp_substring_utf8.test +++ b/mysql-test/suite/jp/t/jp_substring_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_trim_sjis.test b/mysql-test/suite/jp/t/jp_trim_sjis.test index 0f6821605ed..04dc832d49f 100644 --- a/mysql-test/suite/jp/t/jp_trim_sjis.test +++ b/mysql-test/suite/jp/t/jp_trim_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_trim_ucs2.test b/mysql-test/suite/jp/t/jp_trim_ucs2.test index 1d8a12650e0..7c82c249dcc 100644 --- a/mysql-test/suite/jp/t/jp_trim_ucs2.test +++ b/mysql-test/suite/jp/t/jp_trim_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_trim_ujis.test b/mysql-test/suite/jp/t/jp_trim_ujis.test index de401217fcf..bcd9942f0ae 100644 --- a/mysql-test/suite/jp/t/jp_trim_ujis.test +++ b/mysql-test/suite/jp/t/jp_trim_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_trim_utf8.test b/mysql-test/suite/jp/t/jp_trim_utf8.test index 0777de15c36..f6f487254bc 100644 --- a/mysql-test/suite/jp/t/jp_trim_utf8.test +++ b/mysql-test/suite/jp/t/jp_trim_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_union_ujis.test b/mysql-test/suite/jp/t/jp_union_ujis.test index e36d18c85c0..c1252b9f5a2 100644 --- a/mysql-test/suite/jp/t/jp_union_ujis.test +++ b/mysql-test/suite/jp/t/jp_union_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_update_sjis.test b/mysql-test/suite/jp/t/jp_update_sjis.test index 0dc7372ae92..4b3733cff76 100644 --- a/mysql-test/suite/jp/t/jp_update_sjis.test +++ b/mysql-test/suite/jp/t/jp_update_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_update_ucs2.test b/mysql-test/suite/jp/t/jp_update_ucs2.test index 7a3c1233210..6ad7db9c5a0 100644 --- a/mysql-test/suite/jp/t/jp_update_ucs2.test +++ b/mysql-test/suite/jp/t/jp_update_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_update_ujis.test b/mysql-test/suite/jp/t/jp_update_ujis.test index 852e45b9eeb..14ca6580f04 100644 --- a/mysql-test/suite/jp/t/jp_update_ujis.test +++ b/mysql-test/suite/jp/t/jp_update_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_update_utf8.test b/mysql-test/suite/jp/t/jp_update_utf8.test index b4b3d18ecab..135f6e6981c 100644 --- a/mysql-test/suite/jp/t/jp_update_utf8.test +++ b/mysql-test/suite/jp/t/jp_update_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; diff --git a/mysql-test/suite/jp/t/jp_where_sjis.test b/mysql-test/suite/jp/t/jp_where_sjis.test index 452d137f643..890a4c28f3c 100644 --- a/mysql-test/suite/jp/t/jp_where_sjis.test +++ b/mysql-test/suite/jp/t/jp_where_sjis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --character_set sjis --disable_warnings drop table if exists `‚s‚P`; diff --git a/mysql-test/suite/jp/t/jp_where_ucs2.test b/mysql-test/suite/jp/t/jp_where_ucs2.test index 3b82eacd615..7d90faaaa89 100644 --- a/mysql-test/suite/jp/t/jp_where_ucs2.test +++ b/mysql-test/suite/jp/t/jp_where_ucs2.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ucs2.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_where_ujis.test b/mysql-test/suite/jp/t/jp_where_ujis.test index e96404fbb17..2f0924e8c8e 100644 --- a/mysql-test/suite/jp/t/jp_where_ujis.test +++ b/mysql-test/suite/jp/t/jp_where_ujis.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --source include/have_ujis.inc --disable_warnings diff --git a/mysql-test/suite/jp/t/jp_where_utf8.test b/mysql-test/suite/jp/t/jp_where_utf8.test index 7280bc33f21..231553e8819 100644 --- a/mysql-test/suite/jp/t/jp_where_utf8.test +++ b/mysql-test/suite/jp/t/jp_where_utf8.test @@ -1,3 +1,5 @@ +-- source include/have_innodb.inc +-- source include/have_bdb.inc --disable_warnings drop table if exists `T1`; drop table if exists `ï¼´ï¼’`; From 3228a2be669f5d92a607b8212c9c3260a02fd47f Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 9 Sep 2009 14:38:50 +0500 Subject: [PATCH 102/138] BUG#45638 - Create temporary table with engine innodb fails Create temporary InnoDB table fails on case insensitive filesystems, when lower_case_table_names is 2 (e.g. OS X) and temporary directory path contains upper case letters. The problem was that tmpdir prefix was converted to lower case when table was created, but was passed as is when table was opened. Fixed by leaving tmpdir prefix part intact. mysql-test/r/lowercase_mixed_tmpdir_innodb.result: A test case for BUG#45638. mysql-test/t/lowercase_mixed_tmpdir_innodb-master.opt: A test case for BUG#45638. mysql-test/t/lowercase_mixed_tmpdir_innodb-master.sh: A test case for BUG#45638. mysql-test/t/lowercase_mixed_tmpdir_innodb.test: A test case for BUG#45638. sql/handler.cc: Fixed get_canonical_filename() to not lowercase filesystem path prefix for temporary tables. --- .../r/lowercase_mixed_tmpdir_innodb.result | 6 ++++ .../lowercase_mixed_tmpdir_innodb-master.opt | 2 ++ .../t/lowercase_mixed_tmpdir_innodb-master.sh | 6 ++++ .../t/lowercase_mixed_tmpdir_innodb.test | 12 ++++++++ sql/handler.cc | 30 +++++++++++++++++++ 5 files changed, 56 insertions(+) create mode 100755 mysql-test/r/lowercase_mixed_tmpdir_innodb.result create mode 100644 mysql-test/t/lowercase_mixed_tmpdir_innodb-master.opt create mode 100644 mysql-test/t/lowercase_mixed_tmpdir_innodb-master.sh create mode 100644 mysql-test/t/lowercase_mixed_tmpdir_innodb.test diff --git a/mysql-test/r/lowercase_mixed_tmpdir_innodb.result b/mysql-test/r/lowercase_mixed_tmpdir_innodb.result new file mode 100755 index 00000000000..a478b49cfda --- /dev/null +++ b/mysql-test/r/lowercase_mixed_tmpdir_innodb.result @@ -0,0 +1,6 @@ +drop table if exists t1; +create table t1 (id int) engine=InnoDB; +insert into t1 values (1); +create temporary table t2 engine=InnoDB select * from t1; +drop temporary table t2; +drop table t1; diff --git a/mysql-test/t/lowercase_mixed_tmpdir_innodb-master.opt b/mysql-test/t/lowercase_mixed_tmpdir_innodb-master.opt new file mode 100644 index 00000000000..272f91d629c --- /dev/null +++ b/mysql-test/t/lowercase_mixed_tmpdir_innodb-master.opt @@ -0,0 +1,2 @@ +--lower-case-table-names=2 +--tmpdir=$MYSQLTEST_VARDIR/tmp/MixedCase diff --git a/mysql-test/t/lowercase_mixed_tmpdir_innodb-master.sh b/mysql-test/t/lowercase_mixed_tmpdir_innodb-master.sh new file mode 100644 index 00000000000..95c26e3aa02 --- /dev/null +++ b/mysql-test/t/lowercase_mixed_tmpdir_innodb-master.sh @@ -0,0 +1,6 @@ +# This test requires a non-lowercase tmpdir directory on a case-sensitive +# filesystem. + +d="$MYSQLTEST_VARDIR/tmp/MixedCase" +test -d "$d" || mkdir "$d" +rm -f "$d"/* diff --git a/mysql-test/t/lowercase_mixed_tmpdir_innodb.test b/mysql-test/t/lowercase_mixed_tmpdir_innodb.test new file mode 100644 index 00000000000..e3b9b7b2a32 --- /dev/null +++ b/mysql-test/t/lowercase_mixed_tmpdir_innodb.test @@ -0,0 +1,12 @@ +--source include/have_lowercase2.inc +--source include/have_innodb.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings + +create table t1 (id int) engine=InnoDB; +insert into t1 values (1); +create temporary table t2 engine=InnoDB select * from t1; +drop temporary table t2; +drop table t1; diff --git a/sql/handler.cc b/sql/handler.cc index e5c64452aaf..a4d88e84f4c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1885,12 +1885,42 @@ bool ha_flush_logs(handlerton *db_type) return FALSE; } + +/** + @brief make canonical filename + + @param[in] file table handler + @param[in] path original path + @param[out] tmp_path buffer for canonized path + + @details Lower case db name and table name path parts for + non file based tables when lower_case_table_names + is 2 (store as is, compare in lower case). + Filesystem path prefix (mysql_data_home or tmpdir) + is left intact. + + @note tmp_path may be left intact if no conversion was + performed. + + @retval canonized path + + @todo This may be done more efficiently when table path + gets built. Convert this function to something like + ASSERT_CANONICAL_FILENAME. +*/ const char *get_canonical_filename(handler *file, const char *path, char *tmp_path) { + uint i; if (lower_case_table_names != 2 || (file->ha_table_flags() & HA_FILE_BASED)) return path; + for (i= 0; i <= mysql_tmpdir_list.max; i++) + { + if (is_prefix(path, mysql_tmpdir_list.list[i])) + return path; + } + /* Ensure that table handler get path in lower case */ if (tmp_path != path) strmov(tmp_path, path); From 04ed3c9d94de3f426c97c7f193dbcfdd73886206 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 9 Sep 2009 14:42:12 +0500 Subject: [PATCH 103/138] BUG#29203 - archive tables have weird values in show table status Archive engine returns wrong values for average record length and max data length. With this fix they're calculated as following: - max data length is 2 ^ 63 where large files are supported and INT_MAX32 where this is not supported; - average record length is data length / records in data file. mysql-test/r/archive.result: A test case for BUG#29203. mysql-test/t/archive.test: A test case for BUG#29203. storage/archive/ha_archive.cc: Better estimation for average row length and maximal data file length. --- mysql-test/r/archive.result | 11 +++++++++++ mysql-test/t/archive.test | 11 +++++++++++ storage/archive/ha_archive.cc | 5 +++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index 8c26ea1ff82..3271e2f46d4 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -12695,3 +12695,14 @@ a b 1 NULL 2 NULL DROP TABLE t1; +CREATE TABLE t1(a INT, b BLOB) ENGINE=archive; +SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM +INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; +DATA_LENGTH AVG_ROW_LENGTH +8666 15 +INSERT INTO t1 VALUES(1, 'sampleblob1'),(2, 'sampleblob2'); +SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM +INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; +DATA_LENGTH AVG_ROW_LENGTH +8700 4350 +DROP TABLE t1; diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index 7139d95ab49..afb8e413b2c 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1599,3 +1599,14 @@ INSERT INTO t1 VALUES (NULL, NULL),(NULL, NULL); FLUSH TABLE t1; SELECT * FROM t1 ORDER BY a; DROP TABLE t1; + +# +# BUG#29203 - archive tables have weird values in show table status +# +CREATE TABLE t1(a INT, b BLOB) ENGINE=archive; +SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM + INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; +INSERT INTO t1 VALUES(1, 'sampleblob1'),(2, 'sampleblob2'); +SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM + INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; +DROP TABLE t1; diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 1146b2eb73a..49bf036c5a6 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1472,11 +1472,12 @@ int ha_archive::info(uint flag) VOID(my_stat(share->data_file_name, &file_stat, MYF(MY_WME))); - stats.mean_rec_length= table->s->reclength + buffer.alloced_length(); stats.data_file_length= file_stat.st_size; stats.create_time= (ulong) file_stat.st_ctime; stats.update_time= (ulong) file_stat.st_mtime; - stats.max_data_file_length= share->rows_recorded * stats.mean_rec_length; + stats.mean_rec_length= stats.records ? + stats.data_file_length / stats.records : table->s->reclength; + stats.max_data_file_length= MAX_FILE_SIZE; } stats.delete_length= 0; stats.index_file_length=0; From 70972926ab8970267fa8e3f06086282c4b9e747d Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Thu, 10 Sep 2009 11:40:57 +0400 Subject: [PATCH 104/138] A patch for Bug#45118 (mysqld.exe crashed in debug mode on Windows in dbug.c) -- part 2: a patch for the DBUG subsystem to detect misuse of DBUG_ENTER / DBUG_RETURN macros. 5.1 version. --- client/mysqltest.cc | 7 +- include/my_dbug.h | 51 ++++++++++++- sql/mysqld.cc | 4 +- sql/rpl_filter.cc | 2 + sql/set_var.cc | 1 + sql/sql_insert.cc | 85 ++++++++++++--------- sql/sql_parse.cc | 49 +++++++----- storage/ndb/src/kernel/blocks/suma/Suma.cpp | 18 ++--- 8 files changed, 144 insertions(+), 73 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index b9535ba6b05..af2749e3191 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -1165,6 +1165,7 @@ void free_used_memory() mysql_server_end(); /* Don't use DBUG after mysql_server_end() */ + DBUG_VIOLATION_HELPER_LEAVE; return; } @@ -2487,7 +2488,7 @@ void do_source(struct st_command *command) } dynstr_free(&ds_filename); - return; + DBUG_VOID_RETURN; } @@ -7507,6 +7508,8 @@ static void init_signal_handling(void) #endif sigaction(SIGILL, &sa, NULL); sigaction(SIGFPE, &sa, NULL); + + DBUG_VOID_RETURN; } #endif /* !__WIN__ */ @@ -8121,6 +8124,8 @@ void do_get_replace_column(struct st_command *command) } my_free(start, MYF(0)); command->last_argument= command->end; + + DBUG_VOID_RETURN; } diff --git a/include/my_dbug.h b/include/my_dbug.h index a77e439b5db..71dc34791dc 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -16,6 +16,29 @@ #ifndef _dbug_h #define _dbug_h +#if defined(__cplusplus) && !defined(DBUG_OFF) +class Dbug_violation_helper +{ +public: + inline Dbug_violation_helper() : + _entered(TRUE) + { } + + inline ~Dbug_violation_helper() + { + assert(!_entered); + } + + inline void leave() + { + _entered= FALSE; + } + +private: + bool _entered; +}; +#endif /* C++ */ + #ifdef __cplusplus extern "C" { #endif @@ -47,11 +70,31 @@ extern void _db_lock_file_(void); extern void _db_unlock_file_(void); extern FILE *_db_fp_(void); -#define DBUG_ENTER(a) const char *_db_func_, *_db_file_; uint _db_level_; \ - char **_db_framep_; \ - _db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_, \ - &_db_framep_) +#ifdef __cplusplus + +#define DBUG_ENTER(a) \ + const char *_db_func_, *_db_file_; \ + uint _db_level_; \ + char **_db_framep_; \ + Dbug_violation_helper dbug_violation_helper; \ + _db_enter_ (a, __FILE__, __LINE__, &_db_func_, &_db_file_, \ + &_db_level_, &_db_framep_) +#define DBUG_VIOLATION_HELPER_LEAVE dbug_violation_helper.leave() + +#else /* C */ + +#define DBUG_ENTER(a) \ + const char *_db_func_, *_db_file_; \ + uint _db_level_; \ + char **_db_framep_; \ + _db_enter_ (a, __FILE__, __LINE__, &_db_func_, &_db_file_, \ + &_db_level_, &_db_framep_) +#define DBUG_VIOLATION_HELPER_LEAVE do { } while(0) + +#endif /* C++ */ + #define DBUG_LEAVE \ + DBUG_VIOLATION_HELPER_LEAVE; \ _db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_) #define DBUG_RETURN(a1) do {DBUG_LEAVE; return(a1);} while(0) #define DBUG_VOID_RETURN do {DBUG_LEAVE; return;} while(0) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3e2f8eabd39..3f536f01094 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4789,10 +4789,10 @@ static bool read_init_file(char *file_name) DBUG_ENTER("read_init_file"); DBUG_PRINT("enter",("name: %s",file_name)); if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME)))) - return(1); + DBUG_RETURN(TRUE); bootstrap(file); (void) my_fclose(file,MYF(MY_WME)); - return 0; + DBUG_RETURN(FALSE); } diff --git a/sql/rpl_filter.cc b/sql/rpl_filter.cc index 3004a3905e5..68272c58bb1 100644 --- a/sql/rpl_filter.cc +++ b/sql/rpl_filter.cc @@ -350,6 +350,7 @@ Rpl_filter::add_do_db(const char* table_spec) DBUG_ENTER("Rpl_filter::add_do_db"); i_string *db = new i_string(table_spec); do_db.push_back(db); + DBUG_VOID_RETURN; } @@ -359,6 +360,7 @@ Rpl_filter::add_ignore_db(const char* table_spec) DBUG_ENTER("Rpl_filter::add_ignore_db"); i_string *db = new i_string(table_spec); ignore_db.push_back(db); + DBUG_VOID_RETURN; } extern "C" uchar *get_table_key(const uchar *, size_t *, my_bool); diff --git a/sql/set_var.cc b/sql/set_var.cc index 0b89333ce03..b64b54fdd29 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1238,6 +1238,7 @@ void fix_slave_exec_mode(enum_var_type type) } if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 0) bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT); + DBUG_VOID_RETURN; } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index b79b9b1ae9e..3ac40ae825a 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2274,44 +2274,9 @@ void kill_delayed_threads(void) } -/* - * Create a new delayed insert thread -*/ - -pthread_handler_t handle_delayed_insert(void *arg) +static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di) { - Delayed_insert *di=(Delayed_insert*) arg; - THD *thd= &di->thd; - - pthread_detach_this_thread(); - /* Add thread to THD list so that's it's visible in 'show processlist' */ - pthread_mutex_lock(&LOCK_thread_count); - thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; - thd->set_current_time(); - threads.append(thd); - thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED; - pthread_mutex_unlock(&LOCK_thread_count); - - /* - Wait until the client runs into pthread_cond_wait(), - where we free it after the table is opened and di linked in the list. - If we did not wait here, the client might detect the opened table - before it is linked to the list. It would release LOCK_delayed_create - and allow another thread to create another handler for the same table, - since it does not find one in the list. - */ - pthread_mutex_lock(&di->mutex); -#if !defined( __WIN__) /* Win32 calls this in pthread_create */ - if (my_thread_init()) - { - /* Can't use my_error since store_globals has not yet been called */ - thd->main_da.set_error_status(thd, ER_OUT_OF_RESOURCES, - ER(ER_OUT_OF_RESOURCES)); - goto end; - } -#endif - - DBUG_ENTER("handle_delayed_insert"); + DBUG_ENTER("handle_delayed_insert_impl"); thd->thread_stack= (char*) &thd; if (init_thr_lock() || thd->store_globals()) { @@ -2500,6 +2465,49 @@ err: */ ha_autocommit_or_rollback(thd, 1); + DBUG_VOID_RETURN; +} + + +/* + * Create a new delayed insert thread +*/ + +pthread_handler_t handle_delayed_insert(void *arg) +{ + Delayed_insert *di=(Delayed_insert*) arg; + THD *thd= &di->thd; + + pthread_detach_this_thread(); + /* Add thread to THD list so that's it's visible in 'show processlist' */ + pthread_mutex_lock(&LOCK_thread_count); + thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; + thd->set_current_time(); + threads.append(thd); + thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED; + pthread_mutex_unlock(&LOCK_thread_count); + + /* + Wait until the client runs into pthread_cond_wait(), + where we free it after the table is opened and di linked in the list. + If we did not wait here, the client might detect the opened table + before it is linked to the list. It would release LOCK_delayed_create + and allow another thread to create another handler for the same table, + since it does not find one in the list. + */ + pthread_mutex_lock(&di->mutex); +#if !defined( __WIN__) /* Win32 calls this in pthread_create */ + if (my_thread_init()) + { + /* Can't use my_error since store_globals has not yet been called */ + thd->main_da.set_error_status(thd, ER_OUT_OF_RESOURCES, + ER(ER_OUT_OF_RESOURCES)); + goto end; + } +#endif + + handle_delayed_insert_impl(thd, di); + #ifndef __WIN__ end: #endif @@ -2523,7 +2531,8 @@ end: my_thread_end(); pthread_exit(0); - DBUG_RETURN(0); + + return 0; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ca27d476213..a977740ebe2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -408,29 +408,12 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var, } -/** - Execute commands from bootstrap_file. - - Used when creating the initial grant tables. -*/ - -pthread_handler_t handle_bootstrap(void *arg) +static void handle_bootstrap_impl(THD *thd) { - THD *thd=(THD*) arg; FILE *file=bootstrap_file; char *buff; const char* found_semicolon= NULL; - /* The following must be called before DBUG_ENTER */ - thd->thread_stack= (char*) &thd; - if (my_thread_init() || thd->store_globals()) - { -#ifndef EMBEDDED_LIBRARY - close_connection(thd, ER_OUT_OF_RESOURCES, 1); -#endif - thd->fatal_error(); - goto end; - } DBUG_ENTER("handle_bootstrap"); #ifndef EMBEDDED_LIBRARY @@ -525,6 +508,33 @@ pthread_handler_t handle_bootstrap(void *arg) #endif } + DBUG_VOID_RETURN; +} + + +/** + Execute commands from bootstrap_file. + + Used when creating the initial grant tables. +*/ + +pthread_handler_t handle_bootstrap(void *arg) +{ + THD *thd=(THD*) arg; + + /* The following must be called before DBUG_ENTER */ + thd->thread_stack= (char*) &thd; + if (my_thread_init() || thd->store_globals()) + { +#ifndef EMBEDDED_LIBRARY + close_connection(thd, ER_OUT_OF_RESOURCES, 1); +#endif + thd->fatal_error(); + goto end; + } + + handle_bootstrap_impl(thd); + end: net_end(&thd->net); thd->cleanup(); @@ -539,7 +549,8 @@ end: my_thread_end(); pthread_exit(0); #endif - DBUG_RETURN(0); + + return 0; } diff --git a/storage/ndb/src/kernel/blocks/suma/Suma.cpp b/storage/ndb/src/kernel/blocks/suma/Suma.cpp index 5f0510cf43a..9179cf7fbbd 100644 --- a/storage/ndb/src/kernel/blocks/suma/Suma.cpp +++ b/storage/ndb/src/kernel/blocks/suma/Suma.cpp @@ -274,7 +274,7 @@ Suma::execSTTOR(Signal* signal) { jam(); send_start_me_req(signal); - return; + DBUG_VOID_RETURN; } } @@ -322,7 +322,7 @@ Suma::execSTTOR(Signal* signal) { if (ERROR_INSERTED(13030)) { ndbout_c("Dont start handover"); - return; + DBUG_VOID_RETURN; } }//if @@ -332,7 +332,7 @@ Suma::execSTTOR(Signal* signal) { * Allow API's to connect */ sendSTTORRY(signal); - return; + DBUG_VOID_RETURN; } if(startphase == 101) @@ -345,7 +345,7 @@ Suma::execSTTOR(Signal* signal) { */ c_startup.m_wait_handover= true; check_start_handover(signal); - return; + DBUG_VOID_RETURN; } } sendSTTORRY(signal); @@ -575,19 +575,19 @@ void Suma::execAPI_FAILREQ(Signal* signal) jam(); sendSignalWithDelay(reference(), GSN_API_FAILREQ, signal, 200, signal->getLength()); - return; + DBUG_VOID_RETURN; } if (c_failedApiNodes.get(failedApiNode)) { jam(); - return; + DBUG_VOID_RETURN; } if (!c_subscriber_nodes.get(failedApiNode)) { jam(); - return; + DBUG_VOID_RETURN; } c_failedApiNodes.set(failedApiNode); @@ -2453,7 +2453,7 @@ Suma::execSUB_START_REQ(Signal* signal){ jam(); c_subscriberPool.release(subbPtr); sendSubStartRef(signal, SubStartRef::PartiallyConnected); - return; + DBUG_VOID_RETURN; } DBUG_PRINT("info",("c_subscriberPool size: %d free: %d", @@ -4289,7 +4289,7 @@ Suma::Restart::runSUMA_START_ME_REQ(Signal* signal, Uint32 sumaRef) ref->errorCode = SumaStartMeRef::Busy; suma.sendSignal(sumaRef, GSN_SUMA_START_ME_REF, signal, SumaStartMeRef::SignalLength, JBB); - return; + DBUG_VOID_RETURN; } nodeId = refToNode(sumaRef); From 104d9ce76a68fd3da2f9217514a4c61454802c1d Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 10 Sep 2009 13:49:49 +0500 Subject: [PATCH 105/138] Bug#42364 SHOW ERRORS returns empty resultset after dropping non existent table partial backport of bug43138 fix mysql-test/r/warnings.result: test result mysql-test/t/warnings.test: test case sql/sql_class.cc: partial backport of bug43138 fix sql/sql_class.h: partial backport of bug43138 fix sql/sql_table.cc: partial backport of bug43138 fix --- mysql-test/r/warnings.result | 5 +++++ mysql-test/t/warnings.test | 7 +++++++ sql/sql_class.cc | 25 +++++++++++++++++++++++++ sql/sql_class.h | 25 +++++++++++++++++++++++++ sql/sql_table.cc | 8 ++++---- 5 files changed, 66 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result index 2e393aea9e4..8a87852d582 100644 --- a/mysql-test/r/warnings.result +++ b/mysql-test/r/warnings.result @@ -313,4 +313,9 @@ ERROR 22001: Data too long for column 'c_tinytext' at row 1 insert into t2 values(@q); ERROR 22001: Data too long for column 'c_tinyblob' at row 1 drop table t1, t2; +DROP TABLE t1; +ERROR 42S02: Unknown table 't1' +SHOW ERRORS; +Level Code Message +Error 1051 Unknown table 't1' End of 5.0 tests diff --git a/mysql-test/t/warnings.test b/mysql-test/t/warnings.test index 12421170eba..176f320e390 100644 --- a/mysql-test/t/warnings.test +++ b/mysql-test/t/warnings.test @@ -225,4 +225,11 @@ insert into t2 values(@q); drop table t1, t2; +# +# Bug#42364 SHOW ERRORS returns empty resultset after dropping non existent table +# +--error ER_BAD_TABLE_ERROR +DROP TABLE t1; +SHOW ERRORS; + --echo End of 5.0 tests diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 3f568566c89..daef5a26742 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -399,6 +399,31 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length, return buffer; } + +/** + Implementation of Drop_table_error_handler::handle_error(). + The reason in having this implementation is to silence technical low-level + warnings during DROP TABLE operation. Currently we don't want to expose + the following warnings during DROP TABLE: + - Some of table files are missed or invalid (the table is going to be + deleted anyway, so why bother that something was missed); + - A trigger associated with the table does not have DEFINER (One of the + MySQL specifics now is that triggers are loaded for the table being + dropped. So, we may have a warning that trigger does not have DEFINER + attribute during DROP TABLE operation). + + @return TRUE if the condition is handled. +*/ +bool Drop_table_error_handler::handle_error(uint sql_errno, + const char *message, + MYSQL_ERROR::enum_warning_level level, + THD *thd) +{ + return ((sql_errno == EE_DELETE && my_errno == ENOENT) || + sql_errno == ER_TRG_NO_DEFINER); +} + + /** Clear this diagnostics area. diff --git a/sql/sql_class.h b/sql/sql_class.h index f52d5fae76f..c38eb17f191 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1091,6 +1091,31 @@ public: }; +/** + This class is an internal error handler implementation for + DROP TABLE statements. The thing is that there may be warnings during + execution of these statements, which should not be exposed to the user. + This class is intended to silence such warnings. +*/ + +class Drop_table_error_handler : public Internal_error_handler +{ +public: + Drop_table_error_handler(Internal_error_handler *err_handler) + :m_err_handler(err_handler) + { } + +public: + bool handle_error(uint sql_errno, + const char *message, + MYSQL_ERROR::enum_warning_level level, + THD *thd); + +private: + Internal_error_handler *m_err_handler; +}; + + /** Stores status of the currently executed statement. Cleared at the beginning of the statement, and then diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 89a84ebc1fe..41e76211dd8 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1772,6 +1772,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, my_bool drop_temporary) { bool error= FALSE, need_start_waiters= FALSE; + Drop_table_error_handler err_handler(thd->get_internal_handler()); DBUG_ENTER("mysql_rm_table"); /* mark for close and remove all cached entries */ @@ -1792,7 +1793,10 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, LOCK_open during wait_if_global_read_lock(), other threads could not close their tables. This would make a pretty deadlock. */ + thd->push_internal_handler(&err_handler); error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0); + thd->pop_internal_handler(); + if (need_start_waiters) start_waiting_global_read_lock(thd); @@ -1894,9 +1898,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, DBUG_RETURN(1); } - /* Don't give warnings for not found errors, as we already generate notes */ - thd->no_warnings_for_error= 1; - for (table= tables; table; table= table->next_local) { char *db=table->db; @@ -2145,7 +2146,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, err_with_placeholders: unlock_table_names(thd, tables, (TABLE_LIST*) 0); pthread_mutex_unlock(&LOCK_open); - thd->no_warnings_for_error= 0; DBUG_RETURN(error); } From 63e56390a3f1a4f80642932a790ab74f28de8010 Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Thu, 10 Sep 2009 03:18:29 -0600 Subject: [PATCH 106/138] WL#2110 (SIGNAL) WL#2265 (RESIGNAL) Manual merge of SIGNAL and RESIGNAL to mysql-trunk-signal, plus required dependencies. --- include/my_sys.h | 31 +- libmysqld/CMakeLists.txt | 1 + libmysqld/Makefile.am | 2 +- libmysqld/emb_qcache.cc | 3 +- libmysqld/lib_sql.cc | 40 +- mysql-test/r/bigint.result | 4 +- mysql-test/r/cast.result | 2 +- mysql-test/r/ctype_utf8.result | 14 +- mysql-test/r/date_formats.result | 64 +- mysql-test/r/func_compress.result | 14 +- mysql-test/r/func_encrypt.result | 8 +- mysql-test/r/func_gconcat.result | 64 +- mysql-test/r/func_math.result | 10 +- mysql-test/r/func_str.result | 256 +- mysql-test/r/join_outer.result | 12 +- mysql-test/r/merge.result | 2 +- mysql-test/r/myisam-system.result | 2 +- mysql-test/r/partition.result | 1 - mysql-test/r/ps.result | 4 + mysql-test/r/query_cache.result | 8 +- mysql-test/r/signal.result | 2362 +++++++++++++++ mysql-test/r/signal_code.result | 35 + mysql-test/r/signal_demo1.result | 270 ++ mysql-test/r/signal_demo2.result | 197 ++ mysql-test/r/signal_demo3.result | 143 + mysql-test/r/signal_sqlmode.result | 86 + mysql-test/r/sp-dynamic.result | 8 - mysql-test/r/sp-vars.result | 70 - mysql-test/r/sp.result | 51 +- mysql-test/r/sp_notembedded.result | 2 + mysql-test/r/strict.result | 52 +- mysql-test/r/trigger.result | 14 +- mysql-test/r/type_newdecimal.result | 76 +- mysql-test/r/view.result | 20 +- mysql-test/suite/binlog/r/binlog_index.result | 2 +- .../suite/binlog/r/binlog_unsafe.result | 27 - mysql-test/suite/innodb/r/innodb-zip.result | 26 - mysql-test/suite/ndb/r/ndb_bitfield.result | 4 +- mysql-test/suite/ndb/r/ndb_dd_basic.result | 6 +- mysql-test/suite/ndb/r/ndb_dd_ddl.result | 2 +- mysql-test/suite/ndb/r/ndb_gis.result | 4 +- .../suite/ndb/r/ndb_partition_error.result | 2 +- mysql-test/suite/ndb/r/ndb_row_format.result | 2 +- mysql-test/suite/ndb/r/ndb_single_user.result | 10 +- mysql-test/suite/rpl/r/rpl_EE_err.result | 2 +- .../suite/rpl/r/rpl_row_sp007_innodb.result | 2 - mysql-test/t/func_gconcat.test | 32 + mysql-test/t/signal.test | 2685 +++++++++++++++++ mysql-test/t/signal_code.test | 57 + mysql-test/t/signal_demo1.test | 345 +++ mysql-test/t/signal_demo2.test | 207 ++ mysql-test/t/signal_demo3.test | 159 + mysql-test/t/signal_sqlmode.test | 123 + mysys/my_error.c | 18 +- mysys/my_messnc.c | 6 +- mysys/my_static.c | 6 +- sql/CMakeLists.txt | 1 + sql/Makefile.am | 4 +- sql/authors.h | 1 + sql/event_scheduler.cc | 13 +- sql/field.cc | 29 +- sql/ha_ndbcluster.cc | 18 +- sql/ha_ndbcluster_binlog.cc | 68 +- sql/handler.cc | 27 +- sql/item.cc | 5 +- sql/item_func.cc | 12 +- sql/item_strfunc.cc | 18 +- sql/item_sum.cc | 45 +- sql/item_sum.h | 5 +- sql/item_timefunc.cc | 2 +- sql/lex.h | 14 + sql/log.cc | 39 +- sql/log_event.cc | 35 +- sql/log_event_old.cc | 12 +- sql/my_decimal.cc | 6 +- sql/mysql_priv.h | 4 + sql/mysqld.cc | 82 +- sql/protocol.cc | 93 +- sql/protocol.h | 4 +- sql/repl_failsafe.cc | 2 +- sql/rpl_rli.cc | 4 +- sql/set_var.cc | 8 +- sql/share/errmsg.txt | 36 +- sql/slave.cc | 41 +- sql/sp.cc | 22 +- sql/sp_head.cc | 33 +- sql/sp_pcontext.cc | 3 +- sql/sp_pcontext.h | 2 +- sql/sp_rcontext.cc | 94 +- sql/sp_rcontext.h | 61 +- sql/sql_acl.cc | 26 +- sql/sql_base.cc | 30 +- sql/sql_cache.cc | 4 +- sql/sql_class.cc | 398 +-- sql/sql_class.h | 349 +-- sql/sql_connect.cc | 4 +- sql/sql_derived.cc | 6 +- sql/sql_error.cc | 650 +++- sql/sql_error.h | 520 +++- sql/sql_insert.cc | 30 +- sql/sql_lex.h | 98 +- sql/sql_load.cc | 41 +- sql/sql_parse.cc | 47 +- sql/sql_prepare.cc | 46 +- sql/sql_repl.cc | 4 +- sql/sql_select.cc | 10 +- sql/sql_servers.cc | 2 +- sql/sql_show.cc | 28 +- sql/sql_signal.cc | 510 ++++ sql/sql_signal.h | 152 + sql/sql_table.cc | 43 +- sql/sql_tablespace.cc | 4 +- sql/sql_update.cc | 7 +- sql/sql_yacc.yy | 281 +- sql/table.cc | 24 +- sql/thr_malloc.cc | 7 +- sql/time.cc | 2 +- sql/tztime.cc | 2 +- sql/unireg.cc | 21 +- storage/myisammrg/ha_myisammrg.cc | 2 +- 120 files changed, 10269 insertions(+), 1577 deletions(-) create mode 100644 mysql-test/r/signal.result create mode 100644 mysql-test/r/signal_code.result create mode 100644 mysql-test/r/signal_demo1.result create mode 100644 mysql-test/r/signal_demo2.result create mode 100644 mysql-test/r/signal_demo3.result create mode 100644 mysql-test/r/signal_sqlmode.result create mode 100644 mysql-test/t/signal.test create mode 100644 mysql-test/t/signal_code.test create mode 100644 mysql-test/t/signal_demo1.test create mode 100644 mysql-test/t/signal_demo2.test create mode 100644 mysql-test/t/signal_demo3.test create mode 100644 mysql-test/t/signal_sqlmode.test create mode 100644 sql/sql_signal.cc create mode 100644 sql/sql_signal.h diff --git a/include/my_sys.h b/include/my_sys.h index 222564e0b44..473633ce6ef 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -39,6 +39,17 @@ extern int NEAR my_errno; /* Last error in mysys */ #define MYSYS_PROGRAM_DONT_USE_CURSES() { error_handler_hook = my_message_no_curses; mysys_uses_curses=0;} #define MY_INIT(name); { my_progname= name; my_init(); } +/** + Max length of an error message generated by mysys utilities. + Some mysys functions produce error messages. These mostly go + to stderr. + This constant defines the size of the buffer used to format + the message. It should be kept in sync with MYSQL_ERRMSG_SIZE, + since sometimes mysys errors are stored in the server diagnostics + area, and we would like to avoid unexpected truncation. +*/ +#define MYSYS_ERRMSG_SIZE (512) + #define MY_FILE_ERROR ((size_t) -1) /* General bitmaps for my_func's */ @@ -89,8 +100,6 @@ extern int NEAR my_errno; /* Last error in mysys */ #define ME_COLOUR2 ((2 << ME_HIGHBYTE)) #define ME_COLOUR3 ((3 << ME_HIGHBYTE)) #define ME_FATALERROR 1024 /* Fatal statement error */ -#define ME_NO_WARNING_FOR_ERROR 2048 /* Don't push a warning for error */ -#define ME_NO_SP_HANDLER 4096 /* Don't call stored routine error handlers */ /* Bits in last argument to fn_format */ #define MY_REPLACE_DIR 1 /* replace dir in name with 'dir' */ @@ -209,8 +218,8 @@ extern int errno; /* declare errno */ extern char *home_dir; /* Home directory for user */ extern const char *my_progname; /* program-name (printed in errors) */ extern char NEAR curr_dir[]; /* Current directory for user */ -extern int (*error_handler_hook)(uint my_err, const char *str,myf MyFlags); -extern int (*fatal_error_handler_hook)(uint my_err, const char *str, +extern void (*error_handler_hook)(uint my_err, const char *str,myf MyFlags); +extern void (*fatal_error_handler_hook)(uint my_err, const char *str, myf MyFlags); extern uint my_file_limit; extern ulong my_thread_stack_size; @@ -645,15 +654,15 @@ extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags); extern int my_sync(File fd, myf my_flags); extern int my_sync_dir(const char *dir_name, myf my_flags); extern int my_sync_dir_by_file(const char *file_name, myf my_flags); -extern int my_error _VARARGS((int nr,myf MyFlags, ...)); -extern int my_printf_error _VARARGS((uint my_err, const char *format, - myf MyFlags, ...)) - ATTRIBUTE_FORMAT(printf, 2, 4); +extern void my_error _VARARGS((int nr,myf MyFlags, ...)); +extern void my_printf_error _VARARGS((uint my_err, const char *format, + myf MyFlags, ...)) + ATTRIBUTE_FORMAT(printf, 2, 4); extern int my_error_register(const char **errmsgs, int first, int last); extern const char **my_error_unregister(int first, int last); -extern int my_message(uint my_err, const char *str,myf MyFlags); -extern int my_message_no_curses(uint my_err, const char *str,myf MyFlags); -extern int my_message_curses(uint my_err, const char *str,myf MyFlags); +extern void my_message(uint my_err, const char *str,myf MyFlags); +extern void my_message_no_curses(uint my_err, const char *str,myf MyFlags); +extern void my_message_curses(uint my_err, const char *str,myf MyFlags); extern my_bool my_init(void); extern void my_end(int infoflag); extern int my_redel(const char *from, const char *to, int MyFlags); diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index 8500d73863a..b31082b438a 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -139,6 +139,7 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc ../sql/partition_info.cc ../sql/sql_connect.cc ../sql/scheduler.cc ../sql/event_parse_data.cc + ./sql/sql_signal.cc ${GEN_SOURCES} ${LIB_SOURCES}) diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index 171009c34f6..80a7c74a266 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -77,7 +77,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \ rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \ sql_tablespace.cc \ rpl_injector.cc my_user.c partition_info.cc \ - sql_servers.cc event_parse_data.cc + sql_servers.cc event_parse_data.cc sql_signal.cc libmysqld_int_a_SOURCES= $(libmysqld_sources) nodist_libmysqld_int_a_SOURCES= $(libmysqlsources) $(sqlsources) diff --git a/libmysqld/emb_qcache.cc b/libmysqld/emb_qcache.cc index b4eddf39c1f..5cbced8a8ff 100644 --- a/libmysqld/emb_qcache.cc +++ b/libmysqld/emb_qcache.cc @@ -483,7 +483,8 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src) *prev_row= NULL; data->embedded_info->prev_ptr= prev_row; return_ok: - net_send_eof(thd, thd->server_status, thd->total_warn_count); + net_send_eof(thd, thd->server_status, + thd->warning_info->statement_warn_count()); DBUG_RETURN(0); err: DBUG_RETURN(1); diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index d4a200c07b2..64822f8fad6 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -112,7 +112,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, /* Clear result variables */ thd->clear_error(); - thd->main_da.reset_diagnostics_area(); + thd->stmt_da->reset_diagnostics_area(); mysql->affected_rows= ~(my_ulonglong) 0; mysql->field_count= 0; net_clear_error(net); @@ -217,7 +217,7 @@ static my_bool emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) stmt->stmt_id= thd->client_stmt_id; stmt->param_count= thd->client_param_count; stmt->field_count= 0; - mysql->warning_count= thd->total_warn_count; + mysql->warning_count= thd->warning_info->statement_warn_count(); if (thd->first_data) { @@ -402,7 +402,7 @@ static void emb_free_embedded_thd(MYSQL *mysql) static const char * emb_read_statistics(MYSQL *mysql) { THD *thd= (THD*)mysql->thd; - return thd->is_error() ? thd->main_da.message() : ""; + return thd->is_error() ? thd->stmt_da->message() : ""; } @@ -703,9 +703,10 @@ int check_embedded_connection(MYSQL *mysql, const char *db) err: { NET *net= &mysql->net; - strmake(net->last_error, thd->main_da.message(), sizeof(net->last_error)-1); + strmake(net->last_error, thd->stmt_da->message(), + sizeof(net->last_error)-1); memcpy(net->sqlstate, - mysql_errno_to_sqlstate(thd->main_da.sql_errno()), + mysql_errno_to_sqlstate(thd->stmt_da->sql_errno()), sizeof(net->sqlstate)-1); } return result; @@ -729,8 +730,8 @@ void THD::clear_data_list() void THD::clear_error() { - if (main_da.is_error()) - main_da.reset_diagnostics_area(); + if (stmt_da->is_error()) + stmt_da->reset_diagnostics_area(); } static char *dup_str_aux(MEM_ROOT *root, const char *from, uint length, @@ -804,7 +805,7 @@ MYSQL_DATA *THD::alloc_new_dataset() static bool -write_eof_packet(THD *thd, uint server_status, uint total_warn_count) +write_eof_packet(THD *thd, uint server_status, uint statement_warn_count) { if (!thd->mysql) // bootstrap file handling return FALSE; @@ -821,7 +822,7 @@ write_eof_packet(THD *thd, uint server_status, uint total_warn_count) is cleared between substatements, and mysqltest gets confused */ thd->cur_data->embedded_info->warning_count= - (thd->spcont ? 0 : min(total_warn_count, 65535)); + (thd->spcont ? 0 : min(statement_warn_count, 65535)); return FALSE; } @@ -978,7 +979,8 @@ bool Protocol::send_fields(List *list, uint flags) } if (flags & SEND_EOF) - write_eof_packet(thd, thd->server_status, thd->total_warn_count); + write_eof_packet(thd, thd->server_status, + thd->warning_info->statement_warn_count()); DBUG_RETURN(prepare_for_send(list)); err: @@ -1040,25 +1042,24 @@ bool Protocol_binary::write() bool net_send_ok(THD *thd, - uint server_status, uint total_warn_count, - ha_rows affected_rows, ulonglong id, const char *message) + uint server_status, uint statement_warn_count, + ulonglong affected_rows, ulonglong id, const char *message) { DBUG_ENTER("emb_net_send_ok"); MYSQL_DATA *data; - bool error; MYSQL *mysql= thd->mysql; if (!mysql) // bootstrap file handling DBUG_RETURN(FALSE); if (!(data= thd->alloc_new_dataset())) - return TRUE; + DBUG_RETURN(TRUE); data->embedded_info->affected_rows= affected_rows; data->embedded_info->insert_id= id; if (message) strmake(data->embedded_info->info, message, sizeof(data->embedded_info->info)-1); - error= write_eof_packet(thd, server_status, total_warn_count); + bool error= write_eof_packet(thd, server_status, statement_warn_count); thd->cur_data= 0; DBUG_RETURN(error); } @@ -1075,15 +1076,16 @@ net_send_ok(THD *thd, */ bool -net_send_eof(THD *thd, uint server_status, uint total_warn_count) +net_send_eof(THD *thd, uint server_status, uint statement_warn_count) { - bool error= write_eof_packet(thd, server_status, total_warn_count); + bool error= write_eof_packet(thd, server_status, statement_warn_count); thd->cur_data= 0; return error; } -bool net_send_error_packet(THD *thd, uint sql_errno, const char *err) +bool net_send_error_packet(THD *thd, uint sql_errno, const char *err, + const char *sqlstate) { MYSQL_DATA *data= thd->cur_data; struct embedded_query_result *ei; @@ -1100,7 +1102,7 @@ bool net_send_error_packet(THD *thd, uint sql_errno, const char *err) ei= data->embedded_info; ei->last_errno= sql_errno; strmake(ei->info, err, sizeof(ei->info)-1); - strmov(ei->sqlstate, mysql_errno_to_sqlstate(sql_errno)); + strmov(ei->sqlstate, sqlstate); ei->server_status= thd->server_status; thd->cur_data= 0; return FALSE; diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result index 4a5b8fcf4aa..7c23f1267c2 100644 --- a/mysql-test/r/bigint.result +++ b/mysql-test/r/bigint.result @@ -362,12 +362,12 @@ select cast(19999999999999999999 as signed); cast(19999999999999999999 as signed) 9223372036854775807 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select cast(-19999999999999999999 as signed); cast(-19999999999999999999 as signed) -9223372036854775808 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select -9223372036854775808; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def -9223372036854775808 8 20 20 N 32897 0 63 diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result index dd61396e485..c53de220b60 100644 --- a/mysql-test/r/cast.result +++ b/mysql-test/r/cast.result @@ -380,7 +380,7 @@ select cast(s1 as decimal(7,2)) from t1; cast(s1 as decimal(7,2)) 99999.99 Warnings: -Error 1264 Out of range value for column 'cast(s1 as decimal(7,2))' at row 1 +Warning 1264 Out of range value for column 'cast(s1 as decimal(7,2))' at row 1 drop table t1; CREATE TABLE t1 (v varchar(10), tt tinytext, t text, mt mediumtext, lt longtext); diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 6f4ae965ca0..70f976ee9a7 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1631,27 +1631,27 @@ select char(0xff,0x8f using utf8); char(0xff,0x8f using utf8) NULL Warnings: -Error 1300 Invalid utf8 character string: 'FF8F' +Warning 1300 Invalid utf8 character string: 'FF8F' select char(195 using utf8); char(195 using utf8) NULL Warnings: -Error 1300 Invalid utf8 character string: 'C3' +Warning 1300 Invalid utf8 character string: 'C3' select char(196 using utf8); char(196 using utf8) NULL Warnings: -Error 1300 Invalid utf8 character string: 'C4' +Warning 1300 Invalid utf8 character string: 'C4' select char(2557 using utf8); char(2557 using utf8) NULL Warnings: -Error 1300 Invalid utf8 character string: 'FD' +Warning 1300 Invalid utf8 character string: 'FD' select convert(char(0xff,0x8f) using utf8); convert(char(0xff,0x8f) using utf8) NULL Warnings: -Error 1300 Invalid utf8 character string: 'FF8F' +Warning 1300 Invalid utf8 character string: 'FF8F' select hex(convert(char(2557 using latin1) using utf8)); hex(convert(char(2557 using latin1) using utf8)) 09C3BD @@ -1815,12 +1815,12 @@ select hex(char(0xFF using utf8)); hex(char(0xFF using utf8)) NULL Warnings: -Error 1300 Invalid utf8 character string: 'FF' +Warning 1300 Invalid utf8 character string: 'FF' select hex(convert(0xFF using utf8)); hex(convert(0xFF using utf8)) NULL Warnings: -Error 1300 Invalid utf8 character string: 'FF' +Warning 1300 Invalid utf8 character string: 'FF' select hex(_utf8 0x616263FF); ERROR HY000: Invalid utf8 character string: 'FF' select hex(_utf8 X'616263FF'); diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index 7e185daa668..b0b8316fe33 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -89,7 +89,7 @@ select STR_TO_DATE('2004.12.12 22.30.61','%Y.%m.%d %T'); STR_TO_DATE('2004.12.12 22.30.61','%Y.%m.%d %T') NULL Warnings: -Error 1411 Incorrect time value: '22.30.61' for function str_to_date +Warning 1411 Incorrect time value: '22.30.61' for function str_to_date create table t1 (date char(30), format char(30) not null); insert into t1 values ('2003-01-02 10:11:12', '%Y-%m-%d %H:%i:%S'), @@ -361,21 +361,21 @@ Tuesday 52 2001 %W %u %x NULL 7 53 1998 %w %u %Y NULL NULL %m.%d.%Y NULL Warnings: -Error 1411 Incorrect datetime value: '2003-01-02 10:11:12 PM' for function str_to_date -Error 1411 Incorrect datetime value: '2003-01-02 10:11:12.123456' for function str_to_date -Error 1411 Incorrect datetime value: '2003-01-02 10:11:12AM' for function str_to_date -Error 1411 Incorrect datetime value: '2003-01-02 10:11:12AN' for function str_to_date -Error 1411 Incorrect datetime value: '2003-01-02 10:11:12 PM' for function str_to_date -Error 1411 Incorrect datetime value: '10:20:10AM' for function str_to_date -Error 1411 Incorrect datetime value: '15 Septembei 2001' for function str_to_date -Error 1411 Incorrect datetime value: '15 Ju 2001' for function str_to_date -Error 1411 Incorrect datetime value: 'Sund 15 MA' for function str_to_date -Error 1411 Incorrect datetime value: 'Thursdai 12 1998' for function str_to_date -Error 1411 Incorrect datetime value: 'Sunday 01 2001' for function str_to_date -Error 1411 Incorrect datetime value: 'Tuesday 52 2001' for function str_to_date -Error 1411 Incorrect datetime value: 'Tuesday 52 2001' for function str_to_date -Error 1411 Incorrect datetime value: 'Tuesday 52 2001' for function str_to_date -Error 1411 Incorrect datetime value: '7 53 1998' for function str_to_date +Warning 1411 Incorrect datetime value: '2003-01-02 10:11:12 PM' for function str_to_date +Warning 1411 Incorrect datetime value: '2003-01-02 10:11:12.123456' for function str_to_date +Warning 1411 Incorrect datetime value: '2003-01-02 10:11:12AM' for function str_to_date +Warning 1411 Incorrect datetime value: '2003-01-02 10:11:12AN' for function str_to_date +Warning 1411 Incorrect datetime value: '2003-01-02 10:11:12 PM' for function str_to_date +Warning 1411 Incorrect datetime value: '10:20:10AM' for function str_to_date +Warning 1411 Incorrect datetime value: '15 Septembei 2001' for function str_to_date +Warning 1411 Incorrect datetime value: '15 Ju 2001' for function str_to_date +Warning 1411 Incorrect datetime value: 'Sund 15 MA' for function str_to_date +Warning 1411 Incorrect datetime value: 'Thursdai 12 1998' for function str_to_date +Warning 1411 Incorrect datetime value: 'Sunday 01 2001' for function str_to_date +Warning 1411 Incorrect datetime value: 'Tuesday 52 2001' for function str_to_date +Warning 1411 Incorrect datetime value: 'Tuesday 52 2001' for function str_to_date +Warning 1411 Incorrect datetime value: 'Tuesday 52 2001' for function str_to_date +Warning 1411 Incorrect datetime value: '7 53 1998' for function str_to_date select date,format,concat(str_to_date(date, format),'') as con from t1; date format con 2003-01-02 10:11:12 PM %Y-%m-%d %H:%i:%S %p NULL @@ -395,21 +395,21 @@ Tuesday 52 2001 %W %u %x NULL 7 53 1998 %w %u %Y NULL NULL %m.%d.%Y NULL Warnings: -Error 1411 Incorrect datetime value: '2003-01-02 10:11:12 PM' for function str_to_date -Error 1411 Incorrect datetime value: '2003-01-02 10:11:12.123456' for function str_to_date -Error 1411 Incorrect datetime value: '2003-01-02 10:11:12AM' for function str_to_date -Error 1411 Incorrect datetime value: '2003-01-02 10:11:12AN' for function str_to_date -Error 1411 Incorrect datetime value: '2003-01-02 10:11:12 PM' for function str_to_date -Error 1411 Incorrect datetime value: '10:20:10AM' for function str_to_date -Error 1411 Incorrect datetime value: '15 Septembei 2001' for function str_to_date -Error 1411 Incorrect datetime value: '15 Ju 2001' for function str_to_date -Error 1411 Incorrect datetime value: 'Sund 15 MA' for function str_to_date -Error 1411 Incorrect datetime value: 'Thursdai 12 1998' for function str_to_date -Error 1411 Incorrect datetime value: 'Sunday 01 2001' for function str_to_date -Error 1411 Incorrect datetime value: 'Tuesday 52 2001' for function str_to_date -Error 1411 Incorrect datetime value: 'Tuesday 52 2001' for function str_to_date -Error 1411 Incorrect datetime value: 'Tuesday 52 2001' for function str_to_date -Error 1411 Incorrect datetime value: '7 53 1998' for function str_to_date +Warning 1411 Incorrect datetime value: '2003-01-02 10:11:12 PM' for function str_to_date +Warning 1411 Incorrect datetime value: '2003-01-02 10:11:12.123456' for function str_to_date +Warning 1411 Incorrect datetime value: '2003-01-02 10:11:12AM' for function str_to_date +Warning 1411 Incorrect datetime value: '2003-01-02 10:11:12AN' for function str_to_date +Warning 1411 Incorrect datetime value: '2003-01-02 10:11:12 PM' for function str_to_date +Warning 1411 Incorrect datetime value: '10:20:10AM' for function str_to_date +Warning 1411 Incorrect datetime value: '15 Septembei 2001' for function str_to_date +Warning 1411 Incorrect datetime value: '15 Ju 2001' for function str_to_date +Warning 1411 Incorrect datetime value: 'Sund 15 MA' for function str_to_date +Warning 1411 Incorrect datetime value: 'Thursdai 12 1998' for function str_to_date +Warning 1411 Incorrect datetime value: 'Sunday 01 2001' for function str_to_date +Warning 1411 Incorrect datetime value: 'Tuesday 52 2001' for function str_to_date +Warning 1411 Incorrect datetime value: 'Tuesday 52 2001' for function str_to_date +Warning 1411 Incorrect datetime value: 'Tuesday 52 2001' for function str_to_date +Warning 1411 Incorrect datetime value: '7 53 1998' for function str_to_date truncate table t1; insert into t1 values ('10:20:10AM', '%h:%i:%s'), @@ -449,7 +449,7 @@ select str_to_date('15-01-2001 12:59:59', GET_FORMAT(DATE,'USA')); str_to_date('15-01-2001 12:59:59', GET_FORMAT(DATE,'USA')) NULL Warnings: -Error 1411 Incorrect datetime value: '15-01-2001 12:59:59' for function str_to_date +Warning 1411 Incorrect datetime value: '15-01-2001 12:59:59' for function str_to_date explain extended select makedate(1997,1), addtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002"),subtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002"),timediff("01.01.97 11:59:59.000001 PM","31.12.95 11:59:59.000002 PM"),cast(str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") as TIME), maketime(23,11,12),microsecond("1997-12-31 23:59:59.000001"); id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used diff --git a/mysql-test/r/func_compress.result b/mysql-test/r/func_compress.result index b4e61d0e4fc..650cc9c2c70 100644 --- a/mysql-test/r/func_compress.result +++ b/mysql-test/r/func_compress.result @@ -65,8 +65,8 @@ NULL 50000 NULL Warnings: -Error 1259 ZLIB: Input data corrupted -Error 1256 Uncompressed data size too large; the maximum size is 1048576 (probably, length of uncompressed data was corrupted) +Warning 1259 ZLIB: Input data corrupted +Warning 1256 Uncompressed data size too large; the maximum size is 1048576 (probably, length of uncompressed data was corrupted) drop table t1; set @@global.max_allowed_packet=1048576*100; select compress(repeat('aaaaaaaaaa', IF(XXX, 10, 10000000))) is null; @@ -96,12 +96,12 @@ explain select * from t1 where uncompress(a) is null; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 system NULL NULL NULL NULL 1 Warnings: -Error 1259 ZLIB: Input data corrupted +Warning 1259 ZLIB: Input data corrupted select * from t1 where uncompress(a) is null; a foo Warnings: -Error 1259 ZLIB: Input data corrupted +Warning 1259 ZLIB: Input data corrupted explain select *, uncompress(a) from t1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 system NULL NULL NULL NULL 1 @@ -109,13 +109,13 @@ select *, uncompress(a) from t1; a uncompress(a) foo NULL Warnings: -Error 1259 ZLIB: Input data corrupted +Warning 1259 ZLIB: Input data corrupted select *, uncompress(a), uncompress(a) is null from t1; a uncompress(a) uncompress(a) is null foo NULL 1 Warnings: -Error 1259 ZLIB: Input data corrupted -Error 1259 ZLIB: Input data corrupted +Warning 1259 ZLIB: Input data corrupted +Warning 1259 ZLIB: Input data corrupted drop table t1; CREATE TABLE t1 (c1 INT); INSERT INTO t1 VALUES (1), (1111), (11111); diff --git a/mysql-test/r/func_encrypt.result b/mysql-test/r/func_encrypt.result index 8fbf36b45b9..91ff4e218fb 100644 --- a/mysql-test/r/func_encrypt.result +++ b/mysql-test/r/func_encrypt.result @@ -124,7 +124,7 @@ select des_encrypt("hello",10); des_encrypt("hello",10) NULL Warnings: -Error 1108 Incorrect parameters to procedure 'des_encrypt' +Warning 1108 Incorrect parameters to procedure 'des_encrypt' select des_encrypt(NULL); des_encrypt(NULL) NULL @@ -138,12 +138,12 @@ select des_encrypt(10, NULL); des_encrypt(10, NULL) NULL Warnings: -Error 1108 Incorrect parameters to procedure 'des_encrypt' +Warning 1108 Incorrect parameters to procedure 'des_encrypt' select des_encrypt("hello", NULL); des_encrypt("hello", NULL) NULL Warnings: -Error 1108 Incorrect parameters to procedure 'des_encrypt' +Warning 1108 Incorrect parameters to procedure 'des_encrypt' select des_decrypt("hello",10); des_decrypt("hello",10) hello @@ -177,7 +177,7 @@ select hex(des_decrypt(des_encrypt("hello","hidden"))); hex(des_decrypt(des_encrypt("hello","hidden"))) NULL Warnings: -Error 1108 Incorrect parameters to procedure 'des_decrypt' +Warning 1108 Incorrect parameters to procedure 'des_decrypt' explain extended select des_decrypt(des_encrypt("hello",4),'password2'), des_decrypt(des_encrypt("hello","hidden")); id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 3b78851a1b9..ebec186591d 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -153,10 +153,10 @@ grp group_concat(c) 4 5 NULL Warnings: -Warning 1260 1 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 4 was cut by GROUP_CONCAT() show warnings; Level Code Message -Warning 1260 1 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 4 was cut by GROUP_CONCAT() set group_concat_max_len = 1024; select group_concat(sum(c)) from t1 group by grp; ERROR HY000: Invalid use of group function @@ -380,25 +380,29 @@ group_concat(b) bb,c BB,C Warnings: -Warning 1260 2 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() +Warning 1260 Row 4 was cut by GROUP_CONCAT() select group_concat(distinct b) from t1 group by a; group_concat(distinct b) bb,c BB,C Warnings: -Warning 1260 2 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() +Warning 1260 Row 4 was cut by GROUP_CONCAT() select group_concat(b order by b) from t1 group by a; group_concat(b order by b) a,bb A,BB Warnings: -Warning 1260 2 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 3 was cut by GROUP_CONCAT() +Warning 1260 Row 6 was cut by GROUP_CONCAT() select group_concat(distinct b order by b) from t1 group by a; group_concat(distinct b order by b) a,bb A,BB Warnings: -Warning 1260 2 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 3 was cut by GROUP_CONCAT() +Warning 1260 Row 6 was cut by GROUP_CONCAT() insert into t1 values (1, concat(repeat('1', 300), '2')), (1, concat(repeat('1', 300), '2')), (1, concat(repeat('0', 300), '1')), (2, concat(repeat('1', 300), '2')), (2, concat(repeat('1', 300), '2')), @@ -426,25 +430,29 @@ group_concat(b) bb,ccc,a,bb,ccc,1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112,1111111111111111111111111111111111111111111111111111111111111111111111111111111111 BB,CCC,A,BB,CCC,1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112,1111111111111111111111111111111111111111111111111111111111111111111111111111111111 Warnings: -Warning 1260 2 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 7 was cut by GROUP_CONCAT() +Warning 1260 Row 14 was cut by GROUP_CONCAT() select group_concat(distinct b) from t1 group by a; group_concat(distinct b) bb,ccc,a,1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 BB,CCC,A,1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 Warnings: -Warning 1260 2 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 5 was cut by GROUP_CONCAT() +Warning 1260 Row 10 was cut by GROUP_CONCAT() select group_concat(b order by b) from t1 group by a; group_concat(b order by b) 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 Warnings: -Warning 1260 2 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() +Warning 1260 Row 4 was cut by GROUP_CONCAT() select group_concat(distinct b order by b) from t1 group by a; group_concat(distinct b order by b) 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 Warnings: -Warning 1260 2 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() +Warning 1260 Row 4 was cut by GROUP_CONCAT() drop table t1; create table t1 (a varchar(255) character set cp1250 collate cp1250_general_ci, b varchar(255) character set koi8r); @@ -751,22 +759,22 @@ SELECT GROUP_CONCAT( a ) FROM t1; GROUP_CONCAT( a ) aaaaaaaaaa,bbbbbbbbb Warnings: -Warning 1260 1 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() SELECT GROUP_CONCAT( DISTINCT a ) FROM t1; GROUP_CONCAT( DISTINCT a ) aaaaaaaaaa,bbbbbbbbb Warnings: -Warning 1260 1 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() SELECT GROUP_CONCAT( a ORDER BY b ) FROM t1; GROUP_CONCAT( a ORDER BY b ) aaaaaaaaaa,bbbbbbbbb Warnings: -Warning 1260 1 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() SELECT GROUP_CONCAT( DISTINCT a ORDER BY b ) FROM t1; GROUP_CONCAT( DISTINCT a ORDER BY b ) aaaaaaaaaa,bbbbbbbbb Warnings: -Warning 1260 1 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() SET group_concat_max_len = DEFAULT; DROP TABLE t1; SET group_concat_max_len= 65535; @@ -979,3 +987,31 @@ GROUP BY t1.a 1 DROP TABLE t1, t2; End of 5.0 tests +DROP TABLE IF EXISTS t1, t2; +CREATE TABLE t1 (a VARCHAR(6), b INT); +CREATE TABLE t2 (a VARCHAR(6), b INT); +INSERT INTO t1 VALUES ('111111', 1); +INSERT INTO t1 VALUES ('222222', 2); +INSERT INTO t1 VALUES ('333333', 3); +INSERT INTO t1 VALUES ('444444', 4); +INSERT INTO t1 VALUES ('555555', 5); +SET group_concat_max_len = 5; +SET @old_sql_mode = @@sql_mode, @@sql_mode = 'traditional'; +SELECT GROUP_CONCAT(a), b FROM t1 GROUP BY b LIMIT 3; +GROUP_CONCAT(a) b +11111 1 +22222 2 +33333 3 +Warnings: +Warning 1260 Row 1 was cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() +Warning 1260 Row 3 was cut by GROUP_CONCAT() +INSERT INTO t2 SELECT GROUP_CONCAT(a), b FROM t1 GROUP BY b; +ERROR HY000: Row 1 was cut by GROUP_CONCAT() +UPDATE t1 SET a = '11111' WHERE b = 1; +UPDATE t1 SET a = '22222' WHERE b = 2; +INSERT INTO t2 SELECT GROUP_CONCAT(a), b FROM t1 GROUP BY b; +ERROR HY000: Row 3 was cut by GROUP_CONCAT() +SET group_concat_max_len = DEFAULT; +SET @@sql_mode = @old_sql_mode; +DROP TABLE t1, t2; diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index fd7ef72409e..d8b8a14afc6 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -225,27 +225,27 @@ select ln(-1); ln(-1) NULL Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 select log10(-1); log10(-1) NULL Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 select log2(-1); log2(-1) NULL Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 select log(2,-1); log(2,-1) NULL Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 select log(-2,1); log(-2,1) NULL Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 set sql_mode=''; select round(111,-10); round(111,-10) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index a0c3935fde0..47fd4f2cdad 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -1433,7 +1433,7 @@ select benchmark(-1, 1); benchmark(-1, 1) NULL Warnings: -Error 1411 Incorrect count value: '-1' for function benchmark +Warning 1411 Incorrect count value: '-1' for function benchmark set @password="password"; set @my_data="clear text to encode"; select md5(encode(@my_data, "password")); @@ -1533,7 +1533,7 @@ select locate('lo','hello',-18446744073709551615); locate('lo','hello',-18446744073709551615) 0 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select locate('lo','hello',18446744073709551615); locate('lo','hello',18446744073709551615) 0 @@ -1541,22 +1541,22 @@ select locate('lo','hello',-18446744073709551616); locate('lo','hello',-18446744073709551616) 0 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select locate('lo','hello',18446744073709551616); locate('lo','hello',18446744073709551616) 0 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select locate('lo','hello',-18446744073709551617); locate('lo','hello',-18446744073709551617) 0 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select locate('lo','hello',18446744073709551617); locate('lo','hello',18446744073709551617) 0 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select left('hello', 10); left('hello', 10) hello @@ -1588,8 +1588,8 @@ select left('hello', -18446744073709551615); left('hello', -18446744073709551615) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select left('hello', 18446744073709551615); left('hello', 18446744073709551615) hello @@ -1597,26 +1597,26 @@ select left('hello', -18446744073709551616); left('hello', -18446744073709551616) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select left('hello', 18446744073709551616); left('hello', 18446744073709551616) hello Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select left('hello', -18446744073709551617); left('hello', -18446744073709551617) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select left('hello', 18446744073709551617); left('hello', 18446744073709551617) hello Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select right('hello', 10); right('hello', 10) hello @@ -1648,8 +1648,8 @@ select right('hello', -18446744073709551615); right('hello', -18446744073709551615) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select right('hello', 18446744073709551615); right('hello', 18446744073709551615) hello @@ -1657,26 +1657,26 @@ select right('hello', -18446744073709551616); right('hello', -18446744073709551616) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select right('hello', 18446744073709551616); right('hello', 18446744073709551616) hello Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select right('hello', -18446744073709551617); right('hello', -18446744073709551617) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select right('hello', 18446744073709551617); right('hello', 18446744073709551617) hello Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select substring('hello', 2, -1); substring('hello', 2, -1) @@ -1708,8 +1708,8 @@ select substring('hello', -18446744073709551615, 1); substring('hello', -18446744073709551615, 1) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select substring('hello', 18446744073709551615, 1); substring('hello', 18446744073709551615, 1) @@ -1717,26 +1717,26 @@ select substring('hello', -18446744073709551616, 1); substring('hello', -18446744073709551616, 1) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select substring('hello', 18446744073709551616, 1); substring('hello', 18446744073709551616, 1) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select substring('hello', -18446744073709551617, 1); substring('hello', -18446744073709551617, 1) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select substring('hello', 18446744073709551617, 1); substring('hello', 18446744073709551617, 1) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select substring('hello', 1, -1); substring('hello', 1, -1) @@ -1762,8 +1762,8 @@ select substring('hello', 1, -18446744073709551615); substring('hello', 1, -18446744073709551615) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select substring('hello', 1, 18446744073709551615); substring('hello', 1, 18446744073709551615) hello @@ -1771,26 +1771,26 @@ select substring('hello', 1, -18446744073709551616); substring('hello', 1, -18446744073709551616) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select substring('hello', 1, 18446744073709551616); substring('hello', 1, 18446744073709551616) hello Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select substring('hello', 1, -18446744073709551617); substring('hello', 1, -18446744073709551617) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select substring('hello', 1, 18446744073709551617); substring('hello', 1, 18446744073709551617) hello Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select substring('hello', -1, -1); substring('hello', -1, -1) @@ -1816,10 +1816,10 @@ select substring('hello', -18446744073709551615, -18446744073709551615); substring('hello', -18446744073709551615, -18446744073709551615) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select substring('hello', 18446744073709551615, 18446744073709551615); substring('hello', 18446744073709551615, 18446744073709551615) @@ -1827,34 +1827,34 @@ select substring('hello', -18446744073709551616, -18446744073709551616); substring('hello', -18446744073709551616, -18446744073709551616) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select substring('hello', 18446744073709551616, 18446744073709551616); substring('hello', 18446744073709551616, 18446744073709551616) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select substring('hello', -18446744073709551617, -18446744073709551617); substring('hello', -18446744073709551617, -18446744073709551617) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select substring('hello', 18446744073709551617, 18446744073709551617); substring('hello', 18446744073709551617, 18446744073709551617) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select insert('hello', -1, 1, 'hi'); insert('hello', -1, 1, 'hi') hello @@ -1880,7 +1880,7 @@ select insert('hello', -18446744073709551615, 1, 'hi'); insert('hello', -18446744073709551615, 1, 'hi') hello Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select insert('hello', 18446744073709551615, 1, 'hi'); insert('hello', 18446744073709551615, 1, 'hi') hello @@ -1888,22 +1888,22 @@ select insert('hello', -18446744073709551616, 1, 'hi'); insert('hello', -18446744073709551616, 1, 'hi') hello Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select insert('hello', 18446744073709551616, 1, 'hi'); insert('hello', 18446744073709551616, 1, 'hi') hello Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select insert('hello', -18446744073709551617, 1, 'hi'); insert('hello', -18446744073709551617, 1, 'hi') hello Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select insert('hello', 18446744073709551617, 1, 'hi'); insert('hello', 18446744073709551617, 1, 'hi') hello Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select insert('hello', 1, -1, 'hi'); insert('hello', 1, -1, 'hi') hi @@ -1929,7 +1929,7 @@ select insert('hello', 1, -18446744073709551615, 'hi'); insert('hello', 1, -18446744073709551615, 'hi') hi Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select insert('hello', 1, 18446744073709551615, 'hi'); insert('hello', 1, 18446744073709551615, 'hi') hi @@ -1937,22 +1937,22 @@ select insert('hello', 1, -18446744073709551616, 'hi'); insert('hello', 1, -18446744073709551616, 'hi') hi Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select insert('hello', 1, 18446744073709551616, 'hi'); insert('hello', 1, 18446744073709551616, 'hi') hi Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select insert('hello', 1, -18446744073709551617, 'hi'); insert('hello', 1, -18446744073709551617, 'hi') hi Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select insert('hello', 1, 18446744073709551617, 'hi'); insert('hello', 1, 18446744073709551617, 'hi') hi Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select insert('hello', -1, -1, 'hi'); insert('hello', -1, -1, 'hi') hello @@ -1978,8 +1978,8 @@ select insert('hello', -18446744073709551615, -18446744073709551615, 'hi'); insert('hello', -18446744073709551615, -18446744073709551615, 'hi') hello Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select insert('hello', 18446744073709551615, 18446744073709551615, 'hi'); insert('hello', 18446744073709551615, 18446744073709551615, 'hi') hello @@ -1987,26 +1987,26 @@ select insert('hello', -18446744073709551616, -18446744073709551616, 'hi'); insert('hello', -18446744073709551616, -18446744073709551616, 'hi') hello Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select insert('hello', 18446744073709551616, 18446744073709551616, 'hi'); insert('hello', 18446744073709551616, 18446744073709551616, 'hi') hello Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select insert('hello', -18446744073709551617, -18446744073709551617, 'hi'); insert('hello', -18446744073709551617, -18446744073709551617, 'hi') hello Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select insert('hello', 18446744073709551617, 18446744073709551617, 'hi'); insert('hello', 18446744073709551617, 18446744073709551617, 'hi') hello Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select repeat('hello', -1); repeat('hello', -1) @@ -2038,8 +2038,8 @@ select repeat('hello', -18446744073709551615); repeat('hello', -18446744073709551615) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select repeat('hello', 18446744073709551615); repeat('hello', 18446744073709551615) NULL @@ -2049,27 +2049,27 @@ select repeat('hello', -18446744073709551616); repeat('hello', -18446744073709551616) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select repeat('hello', 18446744073709551616); repeat('hello', 18446744073709551616) NULL Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated select repeat('hello', -18446744073709551617); repeat('hello', -18446744073709551617) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select repeat('hello', 18446744073709551617); repeat('hello', 18446744073709551617) NULL Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated select space(-1); space(-1) @@ -2102,8 +2102,8 @@ select space(-18446744073709551615); space(-18446744073709551615) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select space(18446744073709551615); space(18446744073709551615) NULL @@ -2113,27 +2113,27 @@ select space(-18446744073709551616); space(-18446744073709551616) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select space(18446744073709551616); space(18446744073709551616) NULL Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated select space(-18446744073709551617); space(-18446744073709551617) Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select space(18446744073709551617); space(18446744073709551617) NULL Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated select rpad('hello', -1, '1'); rpad('hello', -1, '1') @@ -2166,8 +2166,8 @@ select rpad('hello', -18446744073709551615, '1'); rpad('hello', -18446744073709551615, '1') NULL Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select rpad('hello', 18446744073709551615, '1'); rpad('hello', 18446744073709551615, '1') NULL @@ -2177,27 +2177,27 @@ select rpad('hello', -18446744073709551616, '1'); rpad('hello', -18446744073709551616, '1') NULL Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select rpad('hello', 18446744073709551616, '1'); rpad('hello', 18446744073709551616, '1') NULL Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' Warning 1301 Result of rpad() was larger than max_allowed_packet (1048576) - truncated select rpad('hello', -18446744073709551617, '1'); rpad('hello', -18446744073709551617, '1') NULL Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select rpad('hello', 18446744073709551617, '1'); rpad('hello', 18446744073709551617, '1') NULL Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' Warning 1301 Result of rpad() was larger than max_allowed_packet (1048576) - truncated select lpad('hello', -1, '1'); lpad('hello', -1, '1') @@ -2230,8 +2230,8 @@ select lpad('hello', -18446744073709551615, '1'); lpad('hello', -18446744073709551615, '1') NULL Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select lpad('hello', 18446744073709551615, '1'); lpad('hello', 18446744073709551615, '1') NULL @@ -2241,27 +2241,27 @@ select lpad('hello', -18446744073709551616, '1'); lpad('hello', -18446744073709551616, '1') NULL Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select lpad('hello', 18446744073709551616, '1'); lpad('hello', 18446744073709551616, '1') NULL Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' Warning 1301 Result of lpad() was larger than max_allowed_packet (1048576) - truncated select lpad('hello', -18446744073709551617, '1'); lpad('hello', -18446744073709551617, '1') NULL Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select lpad('hello', 18446744073709551617, '1'); lpad('hello', 18446744073709551617, '1') NULL Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' Warning 1301 Result of lpad() was larger than max_allowed_packet (1048576) - truncated SET @orig_sql_mode = @@SQL_MODE; SET SQL_MODE=traditional; @@ -2269,12 +2269,12 @@ SELECT CHAR(0xff,0x8f USING utf8); CHAR(0xff,0x8f USING utf8) NULL Warnings: -Error 1300 Invalid utf8 character string: 'FF8F' +Warning 1300 Invalid utf8 character string: 'FF8F' SELECT CHAR(0xff,0x8f USING utf8) IS NULL; CHAR(0xff,0x8f USING utf8) IS NULL 1 Warnings: -Error 1300 Invalid utf8 character string: 'FF8F' +Warning 1300 Invalid utf8 character string: 'FF8F' SET SQL_MODE=@orig_sql_mode; select substring('abc', cast(2 as unsigned int)); substring('abc', cast(2 as unsigned int)) diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 1e4fc91b8bd..bc77072f67a 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -942,25 +942,29 @@ group_concat(t1.b,t2.c) aaaaa bbbbb Warnings: -Warning 1260 2 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 1 was cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by t1.a; group_concat(t1.b,t2.c) aaaaa bbbbb Warnings: -Warning 1260 2 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 1 was cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() select group_concat(t1.b,t2.c) from t1 left join t2 using(a) group by a; group_concat(t1.b,t2.c) aaaaa bbbbb Warnings: -Warning 1260 2 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 1 was cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by a; group_concat(t1.b,t2.c) aaaaa bbbbb Warnings: -Warning 1260 2 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 1 was cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() drop table t1, t2; set group_concat_max_len=default; create table t1 (gid smallint(5) unsigned not null, x int(11) not null, y int(11) not null, art int(11) not null, primary key (gid,x,y)); diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 893ea5acf88..a2248d3d878 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -914,7 +914,7 @@ SELECT * FROM tm1; ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist CHECK TABLE tm1; Table Op Msg_type Msg_text -test.tm1 check Error Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist +test.tm1 check Warning Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist test.tm1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist test.tm1 check error Corrupt ALTER TABLE t2 MODIFY a INT; diff --git a/mysql-test/r/myisam-system.result b/mysql-test/r/myisam-system.result index e0629d955ae..b3ba8066f5c 100644 --- a/mysql-test/r/myisam-system.result +++ b/mysql-test/r/myisam-system.result @@ -2,7 +2,7 @@ drop table if exists t1,t2; create table t1 (a int) engine=myisam; drop table if exists t1; Warnings: -Error 2 Can't find file: 't1' (errno: 2) +Warning 2 Can't find file: 't1' (errno: 2) create table t1 (a int) engine=myisam; drop table t1; Got one of the listed errors diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 2d54a66fe11..a76cb2ba225 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -1226,7 +1226,6 @@ COMMIT; END| CALL test.p1(12); Warnings: -Note 1051 Unknown table 't1' Warning 1196 Some non-transactional changed tables couldn't be rolled back CALL test.p1(13); Warnings: diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 1f8a077af40..06e6b8167fd 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -2748,17 +2748,21 @@ Warnings: Note 1051 Unknown table 't1' call proc_1(); Level Code Message +Note 1051 Unknown table 't1' drop table if exists t2; Warnings: Note 1051 Unknown table 't2' call proc_1(); Level Code Message +Note 1051 Unknown table 't2' drop table if exists t1, t2; Warnings: Note 1051 Unknown table 't1' Note 1051 Unknown table 't2' call proc_1(); Level Code Message +Note 1051 Unknown table 't1' +Note 1051 Unknown table 't2' drop procedure proc_1; create function func_1() returns int begin show warnings; return 1; end| ERROR 0A000: Not allowed to return a result set from a function diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 6cabc24d0eb..89057603c3d 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -889,7 +889,7 @@ select group_concat(a) FROM t1 group by b; group_concat(a) 1234567890 Warnings: -Warning 1260 1 line(s) were cut by GROUP_CONCAT() +Warning 1260 Row 1 was cut by GROUP_CONCAT() set group_concat_max_len=1024; select group_concat(a) FROM t1 group by b; group_concat(a) @@ -992,19 +992,19 @@ COUNT(*) 0 Warnings: Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 -Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 0 +Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050328 invalid'; COUNT(*) 0 Warnings: Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1 -Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 0 +Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1 SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050327 invalid'; COUNT(*) 0 Warnings: Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 -Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 0 +Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 0 diff --git a/mysql-test/r/signal.result b/mysql-test/r/signal.result new file mode 100644 index 00000000000..56140733c33 --- /dev/null +++ b/mysql-test/r/signal.result @@ -0,0 +1,2362 @@ +# +# PART 1: syntax +# +# +# Test every new reserved and non reserved keywords +# +drop table if exists signal_non_reserved; +create table signal_non_reserved ( +class_origin int, +subclass_origin int, +constraint_catalog int, +constraint_schema int, +constraint_name int, +catalog_name int, +schema_name int, +table_name int, +column_name int, +cursor_name int, +message_text int, +sqlcode int +); +drop table signal_non_reserved; +drop table if exists diag_non_reserved; +create table diag_non_reserved ( +diagnostics int, +current int, +stacked int, +exception int +); +drop table diag_non_reserved; +drop table if exists diag_cond_non_reserved; +create table diag_cond_non_reserved ( +condition_identifier int, +condition_number int, +condition_name int, +connection_name int, +message_length int, +message_octet_length int, +parameter_mode int, +parameter_name int, +parameter_ordinal_position int, +returned_sqlstate int, +routine_catalog int, +routine_name int, +routine_schema int, +server_name int, +specific_name int, +trigger_catalog int, +trigger_name int, +trigger_schema int +); +drop table diag_cond_non_reserved; +drop table if exists diag_stmt_non_reserved; +create table diag_stmt_non_reserved ( +number int, +more int, +command_function int, +command_function_code int, +dynamic_function int, +dynamic_function_code int, +row_count int, +transactions_committed int, +transactions_rolled_back int, +transaction_active int +); +drop table diag_stmt_non_reserved; +drop table if exists test_reserved; +create table test_reserved (signal int); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'signal int)' at line 1 +create table test_reserved (resignal int); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'resignal int)' at line 1 +create table test_reserved (condition int); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'condition int)' at line 1 +# +# Test the SIGNAL syntax +# +drop procedure if exists test_invalid; +drop procedure if exists test_signal_syntax; +drop function if exists test_signal_func; +create procedure test_invalid() +begin +SIGNAL; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL foo; +end $$ +ERROR 42000: Undefined CONDITION: foo +create procedure test_invalid() +begin +DECLARE foo CONDITION FOR 1234; +SIGNAL foo; +end $$ +ERROR HY000: SIGNAL/RESIGNAL can only use a CONDITION defined with SQLSTATE +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +SIGNAL SQLSTATE '23000'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +SIGNAL SQLSTATE VALUE '23000'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET CLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET SUBCLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET CONSTRAINT_CATALOG = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET CONSTRAINT_SCHEMA = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET CONSTRAINT_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET CATALOG_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET SCHEMA_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET TABLE_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET COLUMN_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET CURSOR_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MESSAGE_TEXT = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +create procedure test_invalid() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET CLASS_ORIGIN = 'foo', CLASS_ORIGIN = 'bar'; +end $$ +ERROR 42000: Duplicate condition information item 'CLASS_ORIGIN' +create procedure test_invalid() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MESSAGE_TEXT = 'foo', MESSAGE_TEXT = 'bar'; +end $$ +ERROR 42000: Duplicate condition information item 'MESSAGE_TEXT' +create procedure test_invalid() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = 'foo', MYSQL_ERRNO = 'bar'; +end $$ +ERROR 42000: Duplicate condition information item 'MYSQL_ERRNO' +create procedure test_signal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET +CLASS_ORIGIN = 'foo', +SUBCLASS_ORIGIN = 'foo', +CONSTRAINT_CATALOG = 'foo', +CONSTRAINT_SCHEMA = 'foo', +CONSTRAINT_NAME = 'foo', +CATALOG_NAME = 'foo', +SCHEMA_NAME = 'foo', +TABLE_NAME = 'foo', +COLUMN_NAME = 'foo', +CURSOR_NAME = 'foo', +MESSAGE_TEXT = 'foo', +MYSQL_ERRNO = 'foo'; +end $$ +drop procedure test_signal_syntax $$ +SIGNAL SQLSTATE '00000' $$ +ERROR 42000: Bad SQLSTATE: '00000' +SIGNAL SQLSTATE '00001' $$ +ERROR 42000: Bad SQLSTATE: '00001' +create procedure test_invalid() +begin +SIGNAL SQLSTATE '00000'; +end $$ +ERROR 42000: Bad SQLSTATE: '00000' +create procedure test_invalid() +begin +SIGNAL SQLSTATE '00001'; +end $$ +ERROR 42000: Bad SQLSTATE: '00001' +# +# Test conditions information that SIGNAL can not set +# +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET bla_bla = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'bla_bla = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET CONDITION_IDENTIFIER = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CONDITION_IDENTIFIER = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET CONDITION_NUMBER = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CONDITION_NUMBER = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET CONNECTION_NAME = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CONNECTION_NAME = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET MESSAGE_LENGTH = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'MESSAGE_LENGTH = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET MESSAGE_OCTET_LENGTH = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'MESSAGE_OCTET_LENGTH = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET PARAMETER_MODE = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'PARAMETER_MODE = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET PARAMETER_NAME = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'PARAMETER_NAME = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET PARAMETER_ORDINAL_POSITION = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'PARAMETER_ORDINAL_POSITION = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET RETURNED_SQLSTATE = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RETURNED_SQLSTATE = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET ROUTINE_CATALOG = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ROUTINE_CATALOG = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET ROUTINE_NAME = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ROUTINE_NAME = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET ROUTINE_SCHEMA = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ROUTINE_SCHEMA = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET SERVER_NAME = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SERVER_NAME = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET SPECIFIC_NAME = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SPECIFIC_NAME = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET TRIGGER_CATALOG = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TRIGGER_CATALOG = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET TRIGGER_NAME = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TRIGGER_NAME = 'foo'; +end' at line 3 +create procedure test_invalid() +begin +SIGNAL SQLSTATE '12345' SET TRIGGER_SCHEMA = 'foo'; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TRIGGER_SCHEMA = 'foo'; +end' at line 3 +# +# Test the RESIGNAL syntax +# +drop procedure if exists test_invalid; +drop procedure if exists test_resignal_syntax; +create procedure test_invalid() +begin +RESIGNAL foo; +end $$ +ERROR 42000: Undefined CONDITION: foo +create procedure test_resignal_syntax() +begin +RESIGNAL; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_invalid() +begin +DECLARE foo CONDITION FOR 1234; +RESIGNAL foo; +end $$ +ERROR HY000: SIGNAL/RESIGNAL can only use a CONDITION defined with SQLSTATE +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SQLSTATE '23000'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SQLSTATE VALUE '23000'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET CLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET CLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET SUBCLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET SUBCLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET CONSTRAINT_CATALOG = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET CONSTRAINT_CATALOG = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET CONSTRAINT_SCHEMA = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET CONSTRAINT_SCHEMA = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET CONSTRAINT_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET CONSTRAINT_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET CATALOG_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET CATALOG_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET SCHEMA_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET SCHEMA_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET TABLE_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET TABLE_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET COLUMN_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET COLUMN_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET CURSOR_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET CURSOR_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET MESSAGE_TEXT = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET MESSAGE_TEXT = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +RESIGNAL SET MYSQL_ERRNO = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET MYSQL_ERRNO = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_invalid() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET CLASS_ORIGIN = 'foo', CLASS_ORIGIN = 'bar'; +end $$ +ERROR 42000: Duplicate condition information item 'CLASS_ORIGIN' +create procedure test_invalid() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET MESSAGE_TEXT = 'foo', MESSAGE_TEXT = 'bar'; +end $$ +ERROR 42000: Duplicate condition information item 'MESSAGE_TEXT' +create procedure test_invalid() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET MYSQL_ERRNO = 'foo', MYSQL_ERRNO = 'bar'; +end $$ +ERROR 42000: Duplicate condition information item 'MYSQL_ERRNO' +create procedure test_resignal_syntax() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +RESIGNAL foo SET +CLASS_ORIGIN = 'foo', +SUBCLASS_ORIGIN = 'foo', +CONSTRAINT_CATALOG = 'foo', +CONSTRAINT_SCHEMA = 'foo', +CONSTRAINT_NAME = 'foo', +CATALOG_NAME = 'foo', +SCHEMA_NAME = 'foo', +TABLE_NAME = 'foo', +COLUMN_NAME = 'foo', +CURSOR_NAME = 'foo', +MESSAGE_TEXT = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ +create procedure test_invalid() +begin +RESIGNAL SQLSTATE '00000'; +end $$ +ERROR 42000: Bad SQLSTATE: '00000' +create procedure test_invalid() +begin +RESIGNAL SQLSTATE '00001'; +end $$ +ERROR 42000: Bad SQLSTATE: '00001' +# +# PART 2: non preparable statements +# +prepare stmt from 'SIGNAL SQLSTATE \'23000\''; +ERROR HY000: This command is not supported in the prepared statement protocol yet +prepare stmt from 'RESIGNAL SQLSTATE \'23000\''; +ERROR HY000: This command is not supported in the prepared statement protocol yet +# +# PART 3: runtime execution +# +drop procedure if exists test_signal; +drop procedure if exists test_resignal; +drop table if exists t_warn; +drop table if exists t_cursor; +create table t_warn(a integer(2)); +create table t_cursor(a integer); +# +# SIGNAL can also appear in a query +# +SIGNAL foo; +ERROR 42000: Undefined CONDITION: foo +SIGNAL SQLSTATE '01000'; +Warnings: +Warning 1640 Unhandled user-defined warning condition +SIGNAL SQLSTATE '02000'; +ERROR 02000: Unhandled user-defined not found condition +SIGNAL SQLSTATE '23000'; +ERROR 23000: Unhandled user-defined exception condition +SIGNAL SQLSTATE VALUE '23000'; +ERROR 23000: Unhandled user-defined exception condition +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 65536; +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of '65536' +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 99999; +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of '99999' +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 4294967295; +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of '4294967295' +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 0; +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of '0' +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = -1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1' at line 1 +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 65535; +ERROR HY000: Unhandled user-defined exception condition +# +# RESIGNAL can also appear in a query +# +RESIGNAL; +ERROR 0K000: RESIGNAL when handler not active +RESIGNAL foo; +ERROR 42000: Undefined CONDITION: foo +RESIGNAL SQLSTATE '12345'; +ERROR 0K000: RESIGNAL when handler not active +RESIGNAL SQLSTATE VALUE '12345'; +ERROR 0K000: RESIGNAL when handler not active +# +# Different kind of SIGNAL conditions +# +create procedure test_signal() +begin +# max range +DECLARE foo CONDITION FOR SQLSTATE 'AABBB'; +SIGNAL foo SET MYSQL_ERRNO = 65535; +end $$ +call test_signal() $$ +ERROR AABBB: Unhandled user-defined exception condition +drop procedure test_signal $$ +create procedure test_signal() +begin +# max range +DECLARE foo CONDITION FOR SQLSTATE 'AABBB'; +SIGNAL foo SET MYSQL_ERRNO = 65536; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of '65536' +drop procedure test_signal $$ +create procedure test_signal() +begin +# Error +DECLARE foo CONDITION FOR SQLSTATE '99999'; +SIGNAL foo SET MYSQL_ERRNO = 9999; +end $$ +call test_signal() $$ +ERROR 99999: Unhandled user-defined exception condition +drop procedure test_signal $$ +create procedure test_signal() +begin +# warning +DECLARE too_few_records CONDITION FOR SQLSTATE '01000'; +SIGNAL too_few_records SET MYSQL_ERRNO = 1261; +end $$ +call test_signal() $$ +Warnings: +Warning 1261 Unhandled user-defined warning condition +drop procedure test_signal $$ +create procedure test_signal() +begin +# Not found +DECLARE sp_fetch_no_data CONDITION FOR SQLSTATE '02000'; +SIGNAL sp_fetch_no_data SET MYSQL_ERRNO = 1329; +end $$ +call test_signal() $$ +ERROR 02000: Unhandled user-defined not found condition +drop procedure test_signal $$ +create procedure test_signal() +begin +# Error +DECLARE sp_cursor_already_open CONDITION FOR SQLSTATE '24000'; +SIGNAL sp_cursor_already_open SET MYSQL_ERRNO = 1325; +end $$ +call test_signal() $$ +ERROR 24000: Unhandled user-defined exception condition +drop procedure test_signal $$ +create procedure test_signal() +begin +# Severe error +DECLARE lock_deadlock CONDITION FOR SQLSTATE '40001'; +SIGNAL lock_deadlock SET MYSQL_ERRNO = 1213; +end $$ +call test_signal() $$ +ERROR 40001: Unhandled user-defined exception condition +drop procedure test_signal $$ +create procedure test_signal() +begin +# Unknown -> error +DECLARE foo CONDITION FOR SQLSTATE "99999"; +SIGNAL foo; +end $$ +call test_signal() $$ +ERROR 99999: Unhandled user-defined exception condition +drop procedure test_signal $$ +create procedure test_signal() +begin +# warning, no subclass +DECLARE warn CONDITION FOR SQLSTATE "01000"; +SIGNAL warn; +end $$ +call test_signal() $$ +Warnings: +Warning 1640 Unhandled user-defined warning condition +drop procedure test_signal $$ +create procedure test_signal() +begin +# warning, with subclass +DECLARE warn CONDITION FOR SQLSTATE "01123"; +SIGNAL warn; +end $$ +call test_signal() $$ +Warnings: +Warning 1640 Unhandled user-defined warning condition +drop procedure test_signal $$ +create procedure test_signal() +begin +# Not found, no subclass +DECLARE not_found CONDITION FOR SQLSTATE "02000"; +SIGNAL not_found; +end $$ +call test_signal() $$ +ERROR 02000: Unhandled user-defined not found condition +drop procedure test_signal $$ +create procedure test_signal() +begin +# Not found, with subclass +DECLARE not_found CONDITION FOR SQLSTATE "02XXX"; +SIGNAL not_found; +end $$ +call test_signal() $$ +ERROR 02XXX: Unhandled user-defined not found condition +drop procedure test_signal $$ +create procedure test_signal() +begin +# Error, no subclass +DECLARE error CONDITION FOR SQLSTATE "12000"; +SIGNAL error; +end $$ +call test_signal() $$ +ERROR 12000: Unhandled user-defined exception condition +drop procedure test_signal $$ +create procedure test_signal() +begin +# Error, with subclass +DECLARE error CONDITION FOR SQLSTATE "12ABC"; +SIGNAL error; +end $$ +call test_signal() $$ +ERROR 12ABC: Unhandled user-defined exception condition +drop procedure test_signal $$ +create procedure test_signal() +begin +# Severe error, no subclass +DECLARE error CONDITION FOR SQLSTATE "40000"; +SIGNAL error; +end $$ +call test_signal() $$ +ERROR 40000: Unhandled user-defined exception condition +drop procedure test_signal $$ +create procedure test_signal() +begin +# Severe error, with subclass +DECLARE error CONDITION FOR SQLSTATE "40001"; +SIGNAL error; +end $$ +call test_signal() $$ +ERROR 40001: Unhandled user-defined exception condition +drop procedure test_signal $$ +# +# Test the scope of condition +# +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '99999'; +begin +DECLARE foo CONDITION FOR 8888; +end; +SIGNAL foo SET MYSQL_ERRNO=9999; /* outer */ +end $$ +call test_signal() $$ +ERROR 99999: Unhandled user-defined exception condition +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR 9999; +begin +DECLARE foo CONDITION FOR SQLSTATE '88888'; +SIGNAL foo SET MYSQL_ERRNO=8888; /* inner */ +end; +end $$ +call test_signal() $$ +ERROR 88888: Unhandled user-defined exception condition +drop procedure test_signal $$ +# +# Test SET MYSQL_ERRNO +# +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '99999'; +SIGNAL foo SET MYSQL_ERRNO = 1111; +end $$ +call test_signal() $$ +ERROR 99999: Unhandled user-defined exception condition +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01000"; +SIGNAL warn SET MYSQL_ERRNO = 1111; +end $$ +call test_signal() $$ +Warnings: +Warning 1111 Unhandled user-defined warning condition +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02000"; +SIGNAL not_found SET MYSQL_ERRNO = 1111; +end $$ +call test_signal() $$ +ERROR 02000: Unhandled user-defined not found condition +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE "55000"; +SIGNAL error SET MYSQL_ERRNO = 1111; +end $$ +call test_signal() $$ +ERROR 55000: Unhandled user-defined exception condition +drop procedure test_signal $$ +# +# Test SET MESSAGE_TEXT +# +SIGNAL SQLSTATE '77777' SET MESSAGE_TEXT='' $$ +ERROR 77777: +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '77777'; +SIGNAL foo SET +MESSAGE_TEXT = "", +MYSQL_ERRNO=5678; +end $$ +call test_signal() $$ +ERROR 77777: +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '99999'; +SIGNAL foo SET +MESSAGE_TEXT = "Something bad happened", +MYSQL_ERRNO=9999; +end $$ +call test_signal() $$ +ERROR 99999: Something bad happened +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01000"; +SIGNAL warn SET MESSAGE_TEXT = "Something bad happened"; +end $$ +call test_signal() $$ +Warnings: +Warning 1640 Something bad happened +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02000"; +SIGNAL not_found SET MESSAGE_TEXT = "Something bad happened"; +end $$ +call test_signal() $$ +ERROR 02000: Something bad happened +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE "55000"; +SIGNAL error SET MESSAGE_TEXT = "Something bad happened"; +end $$ +call test_signal() $$ +ERROR 55000: Something bad happened +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE something CONDITION FOR SQLSTATE "01000"; +SIGNAL something SET MESSAGE_TEXT = _utf8 "This is a UTF8 text"; +end $$ +call test_signal() $$ +Warnings: +Warning 1640 This is a UTF8 text +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE something CONDITION FOR SQLSTATE "01000"; +SIGNAL something SET MESSAGE_TEXT = ""; +end $$ +call test_signal() $$ +Warnings: +Warning 1640 +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01111"; +SIGNAL warn SET MESSAGE_TEXT = "á a"; +end $$ +call test_signal() $$ +Warnings: +Warning 1640 á a +show warnings $$ +Level Code Message +Warning 1640 á a +drop procedure test_signal $$ +# +# Test SET complex expressions +# +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +MYSQL_ERRNO = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +CLASS_ORIGIN = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'CLASS_ORIGIN' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +SUBCLASS_ORIGIN = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'SUBCLASS_ORIGIN' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +CONSTRAINT_CATALOG = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'CONSTRAINT_CATALOG' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +CONSTRAINT_SCHEMA = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'CONSTRAINT_SCHEMA' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +CONSTRAINT_NAME = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'CONSTRAINT_NAME' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +CATALOG_NAME = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'CATALOG_NAME' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +SCHEMA_NAME = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'SCHEMA_NAME' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +TABLE_NAME = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'TABLE_NAME' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +COLUMN_NAME = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'COLUMN_NAME' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +CURSOR_NAME = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'CURSOR_NAME' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE '99999'; +SIGNAL error SET +MESSAGE_TEXT = NULL; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'MESSAGE_TEXT' can't be set to the value of 'NULL' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE something CONDITION FOR SQLSTATE '99999'; +DECLARE message_text VARCHAR(64) DEFAULT "Local string variable"; +DECLARE sqlcode INTEGER DEFAULT 1234; +SIGNAL something SET +MESSAGE_TEXT = message_text, +MYSQL_ERRNO = sqlcode; +end $$ +call test_signal() $$ +ERROR 99999: Local string variable +drop procedure test_signal $$ +create procedure test_signal(message_text VARCHAR(64), sqlcode INTEGER) +begin +DECLARE something CONDITION FOR SQLSTATE "12345"; +SIGNAL something SET +MESSAGE_TEXT = message_text, +MYSQL_ERRNO = sqlcode; +end $$ +call test_signal("Parameter string", NULL) $$ +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of 'NULL' +call test_signal(NULL, 1234) $$ +ERROR 42000: Variable 'MESSAGE_TEXT' can't be set to the value of 'NULL' +call test_signal("Parameter string", 5678) $$ +ERROR 12345: Parameter string +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE something CONDITION FOR SQLSTATE "AABBB"; +SIGNAL something SET +MESSAGE_TEXT = @message_text, +MYSQL_ERRNO = @sqlcode; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'MESSAGE_TEXT' can't be set to the value of 'NULL' +set @sqlcode= 12 $$ +call test_signal() $$ +ERROR 42000: Variable 'MESSAGE_TEXT' can't be set to the value of 'NULL' +set @message_text= "User variable" $$ +call test_signal() $$ +ERROR AABBB: User variable +drop procedure test_signal $$ +create procedure test_invalid() +begin +DECLARE something CONDITION FOR SQLSTATE "AABBB"; +SIGNAL something SET +MESSAGE_TEXT = @message_text := 'illegal', +MYSQL_ERRNO = @sqlcode := 1234; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' +MYSQL_ERRNO = @sqlcode := 1234; +end' at line 5 +create procedure test_signal() +begin +DECLARE aaa VARCHAR(64); +DECLARE bbb VARCHAR(64); +DECLARE ccc VARCHAR(64); +DECLARE ddd VARCHAR(64); +DECLARE eee VARCHAR(64); +DECLARE fff VARCHAR(64); +DECLARE ggg VARCHAR(64); +DECLARE hhh VARCHAR(64); +DECLARE iii VARCHAR(64); +DECLARE jjj VARCHAR(64); +DECLARE kkk VARCHAR(64); +DECLARE warn CONDITION FOR SQLSTATE "01234"; +set aaa= repeat("A", 64); +set bbb= repeat("B", 64); +set ccc= repeat("C", 64); +set ddd= repeat("D", 64); +set eee= repeat("E", 64); +set fff= repeat("F", 64); +set ggg= repeat("G", 64); +set hhh= repeat("H", 64); +set iii= repeat("I", 64); +set jjj= repeat("J", 64); +set kkk= repeat("K", 64); +SIGNAL warn SET +CLASS_ORIGIN = aaa, +SUBCLASS_ORIGIN = bbb, +CONSTRAINT_CATALOG = ccc, +CONSTRAINT_SCHEMA = ddd, +CONSTRAINT_NAME = eee, +CATALOG_NAME = fff, +SCHEMA_NAME = ggg, +TABLE_NAME = hhh, +COLUMN_NAME = iii, +CURSOR_NAME = jjj, +MESSAGE_TEXT = kkk, +MYSQL_ERRNO = 65535; +end $$ +call test_signal() $$ +Warnings: +Warning 65535 KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01234"; +SIGNAL warn SET +MYSQL_ERRNO = 999999999999999999999999999999999999999999999999999; +end $$ +call test_signal() $$ +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of '999999999999999999999999999999999999999999999999999' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE aaax VARCHAR(65); +DECLARE bbbx VARCHAR(65); +DECLARE cccx VARCHAR(65); +DECLARE dddx VARCHAR(65); +DECLARE eeex VARCHAR(65); +DECLARE fffx VARCHAR(65); +DECLARE gggx VARCHAR(65); +DECLARE hhhx VARCHAR(65); +DECLARE iiix VARCHAR(65); +DECLARE jjjx VARCHAR(65); +DECLARE kkkx VARCHAR(65); +DECLARE lllx VARCHAR(129); +DECLARE warn CONDITION FOR SQLSTATE "01234"; +set aaax= concat(repeat("A", 64), "X"); +set bbbx= concat(repeat("B", 64), "X"); +set cccx= concat(repeat("C", 64), "X"); +set dddx= concat(repeat("D", 64), "X"); +set eeex= concat(repeat("E", 64), "X"); +set fffx= concat(repeat("F", 64), "X"); +set gggx= concat(repeat("G", 64), "X"); +set hhhx= concat(repeat("H", 64), "X"); +set iiix= concat(repeat("I", 64), "X"); +set jjjx= concat(repeat("J", 64), "X"); +set kkkx= concat(repeat("K", 64), "X"); +set lllx= concat(repeat("1", 100), +repeat("2", 20), +repeat("8", 8), +"X"); +SIGNAL warn SET +CLASS_ORIGIN = aaax, +SUBCLASS_ORIGIN = bbbx, +CONSTRAINT_CATALOG = cccx, +CONSTRAINT_SCHEMA = dddx, +CONSTRAINT_NAME = eeex, +CATALOG_NAME = fffx, +SCHEMA_NAME = gggx, +TABLE_NAME = hhhx, +COLUMN_NAME = iiix, +CURSOR_NAME = jjjx, +MESSAGE_TEXT = lllx, +MYSQL_ERRNO = 10000; +end $$ +call test_signal() $$ +Warnings: +Warning 1645 Data truncated for condition item 'CLASS_ORIGIN' +Warning 1645 Data truncated for condition item 'SUBCLASS_ORIGIN' +Warning 1645 Data truncated for condition item 'CONSTRAINT_CATALOG' +Warning 1645 Data truncated for condition item 'CONSTRAINT_SCHEMA' +Warning 1645 Data truncated for condition item 'CONSTRAINT_NAME' +Warning 1645 Data truncated for condition item 'CATALOG_NAME' +Warning 1645 Data truncated for condition item 'SCHEMA_NAME' +Warning 1645 Data truncated for condition item 'TABLE_NAME' +Warning 1645 Data truncated for condition item 'COLUMN_NAME' +Warning 1645 Data truncated for condition item 'CURSOR_NAME' +Warning 1645 Data truncated for condition item 'MESSAGE_TEXT' +Warning 10000 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112222222222222222222288888888 +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01234"; +DECLARE CONTINUE HANDLER for SQLSTATE "01234" + begin +select "Caught by SQLSTATE"; +end; +SIGNAL warn SET +MESSAGE_TEXT = "Raising a warning", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by SQLSTATE +Caught by SQLSTATE +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01234"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "Caught by number"; +end; +SIGNAL warn SET +MESSAGE_TEXT = "Raising a warning", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by number +Caught by number +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01234"; +DECLARE CONTINUE HANDLER for SQLWARNING +begin +select "Caught by SQLWARNING"; +end; +SIGNAL warn SET +MESSAGE_TEXT = "Raising a warning", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by SQLWARNING +Caught by SQLWARNING +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; +DECLARE CONTINUE HANDLER for SQLSTATE "02ABC" + begin +select "Caught by SQLSTATE"; +end; +SIGNAL not_found SET +MESSAGE_TEXT = "Raising a not found", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by SQLSTATE +Caught by SQLSTATE +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "Caught by number"; +end; +SIGNAL not_found SET +MESSAGE_TEXT = "Raising a not found", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by number +Caught by number +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; +DECLARE CONTINUE HANDLER for NOT FOUND +begin +select "Caught by NOT FOUND"; +end; +SIGNAL not_found SET +MESSAGE_TEXT = "Raising a not found", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by NOT FOUND +Caught by NOT FOUND +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE "55555"; +DECLARE CONTINUE HANDLER for SQLSTATE "55555" + begin +select "Caught by SQLSTATE"; +end; +SIGNAL error SET +MESSAGE_TEXT = "Raising an error", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by SQLSTATE +Caught by SQLSTATE +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE "55555"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "Caught by number"; +end; +SIGNAL error SET +MESSAGE_TEXT = "Raising an error", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by number +Caught by number +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE error CONDITION FOR SQLSTATE "55555"; +DECLARE CONTINUE HANDLER for SQLEXCEPTION +begin +select "Caught by SQLEXCEPTION"; +end; +SIGNAL error SET +MESSAGE_TEXT = "Raising an error", +MYSQL_ERRNO = 1012; +end $$ +call test_signal() $$ +Caught by SQLEXCEPTION +Caught by SQLEXCEPTION +drop procedure test_signal $$ +# +# Test where SIGNAL can be used +# +create function test_signal_func() returns integer +begin +DECLARE warn CONDITION FOR SQLSTATE "01XXX"; +SIGNAL warn SET +MESSAGE_TEXT = "This function SIGNAL a warning", +MYSQL_ERRNO = 1012; +return 5; +end $$ +select test_signal_func() $$ +test_signal_func() +5 +Warnings: +Warning 1012 This function SIGNAL a warning +drop function test_signal_func $$ +create function test_signal_func() returns integer +begin +DECLARE not_found CONDITION FOR SQLSTATE "02XXX"; +SIGNAL not_found SET +MESSAGE_TEXT = "This function SIGNAL not found", +MYSQL_ERRNO = 1012; +return 5; +end $$ +select test_signal_func() $$ +ERROR 02XXX: This function SIGNAL not found +drop function test_signal_func $$ +create function test_signal_func() returns integer +begin +DECLARE error CONDITION FOR SQLSTATE "50000"; +SIGNAL error SET +MESSAGE_TEXT = "This function SIGNAL an error", +MYSQL_ERRNO = 1012; +return 5; +end $$ +select test_signal_func() $$ +ERROR 50000: This function SIGNAL an error +drop function test_signal_func $$ +drop table if exists t1 $$ +create table t1 (a integer) $$ +create trigger t1_ai after insert on t1 for each row +begin +DECLARE msg VARCHAR(128); +DECLARE warn CONDITION FOR SQLSTATE "01XXX"; +set msg= concat("This trigger SIGNAL a warning, a=", NEW.a); +SIGNAL warn SET +MESSAGE_TEXT = msg, +MYSQL_ERRNO = 1012; +end $$ +insert into t1 values (1), (2) $$ +Warnings: +Warning 1012 This trigger SIGNAL a warning, a=1 +Warning 1012 This trigger SIGNAL a warning, a=2 +drop trigger t1_ai $$ +create trigger t1_ai after insert on t1 for each row +begin +DECLARE msg VARCHAR(128); +DECLARE not_found CONDITION FOR SQLSTATE "02XXX"; +set msg= concat("This trigger SIGNAL a not found, a=", NEW.a); +SIGNAL not_found SET +MESSAGE_TEXT = msg, +MYSQL_ERRNO = 1012; +end $$ +insert into t1 values (3), (4) $$ +ERROR 02XXX: This trigger SIGNAL a not found, a=3 +drop trigger t1_ai $$ +create trigger t1_ai after insert on t1 for each row +begin +DECLARE msg VARCHAR(128); +DECLARE error CONDITION FOR SQLSTATE "03XXX"; +set msg= concat("This trigger SIGNAL an error, a=", NEW.a); +SIGNAL error SET +MESSAGE_TEXT = msg, +MYSQL_ERRNO = 1012; +end $$ +insert into t1 values (5), (6) $$ +ERROR 03XXX: This trigger SIGNAL an error, a=5 +drop table t1 $$ +create table t1 (errno integer, msg varchar(128)) $$ +create trigger t1_ai after insert on t1 for each row +begin +DECLARE warn CONDITION FOR SQLSTATE "01XXX"; +SIGNAL warn SET +MESSAGE_TEXT = NEW.msg, +MYSQL_ERRNO = NEW.errno; +end $$ +insert into t1 set errno=1012, msg='Warning message 1 in trigger' $$ +Warnings: +Warning 1012 Warning message 1 in trigger +insert into t1 set errno=1013, msg='Warning message 2 in trigger' $$ +Warnings: +Warning 1013 Warning message 2 in trigger +drop table t1 $$ +drop table if exists t1 $$ +drop procedure if exists p1 $$ +drop function if exists f1 $$ +create table t1 (s1 int) $$ +insert into t1 values (1) $$ +create procedure p1() +begin +declare a int; +declare c cursor for select f1() from t1; +declare continue handler for sqlstate '03000' + select "caught 03000"; +declare continue handler for 1326 +select "caught cursor is not open"; +select "Before open"; +open c; +select "Before fetch"; +fetch c into a; +select "Before close"; +close c; +end $$ +create function f1() returns int +begin +signal sqlstate '03000'; +return 5; +end $$ +drop table t1 $$ +drop procedure p1 $$ +drop function f1 $$ +# +# Test the RESIGNAL runtime +# +create procedure test_resignal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01234"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL; +select "after RESIGNAL"; +end; +SIGNAL warn SET +MESSAGE_TEXT = "Raising a warning", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Warning 1012 Raising a warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02222"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL; +select "after RESIGNAL"; +end; +SIGNAL not_found SET +MESSAGE_TEXT = "Raising a not found", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02222: Raising a not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE error CONDITION FOR SQLSTATE "55555"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL; +select "after RESIGNAL"; +end; +SIGNAL error SET +MESSAGE_TEXT = "Raising an error", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 55555: Raising an error +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlwarning +begin +select "before RESIGNAL"; +RESIGNAL; +select "after RESIGNAL"; +end; +insert into t_warn set a= 9999999999999999; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE x integer; +DECLARE c cursor for select * from t_cursor; +DECLARE CONTINUE HANDLER for not found +begin +select "before RESIGNAL"; +RESIGNAL; +select "after RESIGNAL"; +end; +open c; +fetch c into x; +close c; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02000: No data - zero rows fetched, selected, or processed +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlexception +begin +select "before RESIGNAL"; +RESIGNAL; +select "after RESIGNAL"; +end; +drop table no_such_table; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 42S02: Unknown table 'no_such_table' +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01234"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SET +MESSAGE_TEXT = "RESIGNAL of a warning", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL warn SET +MESSAGE_TEXT = "Raising a warning", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Warning 5555 RESIGNAL of a warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02111"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SET +MESSAGE_TEXT = "RESIGNAL of a not found", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL not_found SET +MESSAGE_TEXT = "Raising a not found", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02111: RESIGNAL of a not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE error CONDITION FOR SQLSTATE "33333"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SET +MESSAGE_TEXT = "RESIGNAL of an error", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL error SET +MESSAGE_TEXT = "Raising an error", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 33333: RESIGNAL of an error +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlwarning +begin +select "before RESIGNAL"; +RESIGNAL SET +MESSAGE_TEXT = "RESIGNAL of a warning", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +insert into t_warn set a= 9999999999999999; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Warning 5555 RESIGNAL of a warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE x integer; +DECLARE c cursor for select * from t_cursor; +DECLARE CONTINUE HANDLER for not found +begin +select "before RESIGNAL"; +RESIGNAL SET +MESSAGE_TEXT = "RESIGNAL of not found", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +open c; +fetch c into x; +close c; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02000: RESIGNAL of not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlexception +begin +select "before RESIGNAL"; +RESIGNAL SET +MESSAGE_TEXT = "RESIGNAL of an error", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +drop table no_such_table; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 42S02: RESIGNAL of an error +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01111"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "01222" SET +MESSAGE_TEXT = "RESIGNAL to warning", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL warn SET +MESSAGE_TEXT = "Raising a warning", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Warning 1012 Raising a warning +Warning 5555 RESIGNAL to warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01111"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "02222" SET +MESSAGE_TEXT = "RESIGNAL to not found", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL warn SET +MESSAGE_TEXT = "Raising a warning", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02222: RESIGNAL to not found +show warnings $$ +Level Code Message +Warning 1012 Raising a warning +Error 5555 RESIGNAL to not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE warn CONDITION FOR SQLSTATE "01111"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "33333" SET +MESSAGE_TEXT = "RESIGNAL to error", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL warn SET +MESSAGE_TEXT = "Raising a warning", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 33333: RESIGNAL to error +show warnings $$ +Level Code Message +Warning 1012 Raising a warning +Error 5555 RESIGNAL to error +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "01222" SET +MESSAGE_TEXT = "RESIGNAL to warning", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL not_found SET +MESSAGE_TEXT = "Raising a not found", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Error 1012 Raising a not found +Warning 5555 RESIGNAL to warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "02222" SET +MESSAGE_TEXT = "RESIGNAL to not found", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL not_found SET +MESSAGE_TEXT = "Raising a not found", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02222: RESIGNAL to not found +show warnings $$ +Level Code Message +Error 1012 Raising a not found +Error 5555 RESIGNAL to not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "33333" SET +MESSAGE_TEXT = "RESIGNAL to error", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL not_found SET +MESSAGE_TEXT = "Raising a not found", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 33333: RESIGNAL to error +show warnings $$ +Level Code Message +Error 1012 Raising a not found +Error 5555 RESIGNAL to error +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE error CONDITION FOR SQLSTATE "AAAAA"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "01222" SET +MESSAGE_TEXT = "RESIGNAL to warning", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL error SET +MESSAGE_TEXT = "Raising an error", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Error 1012 Raising an error +Warning 5555 RESIGNAL to warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE error CONDITION FOR SQLSTATE "AAAAA"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "02222" SET +MESSAGE_TEXT = "RESIGNAL to not found", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL error SET +MESSAGE_TEXT = "Raising an error", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02222: RESIGNAL to not found +show warnings $$ +Level Code Message +Error 1012 Raising an error +Error 5555 RESIGNAL to not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE error CONDITION FOR SQLSTATE "AAAAA"; +DECLARE CONTINUE HANDLER for 1012 +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "33333" SET +MESSAGE_TEXT = "RESIGNAL to error", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +SIGNAL error SET +MESSAGE_TEXT = "Raising an error", +MYSQL_ERRNO = 1012; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 33333: RESIGNAL to error +show warnings $$ +Level Code Message +Error 1012 Raising an error +Error 5555 RESIGNAL to error +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlwarning +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "01111" SET +MESSAGE_TEXT = "RESIGNAL to a warning", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +insert into t_warn set a= 9999999999999999; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +Warning 5555 RESIGNAL to a warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlwarning +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "02444" SET +MESSAGE_TEXT = "RESIGNAL to a not found", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +insert into t_warn set a= 9999999999999999; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02444: RESIGNAL to a not found +show warnings $$ +Level Code Message +Warning 1264 Out of range value for column 'a' at row 1 +Error 5555 RESIGNAL to a not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlwarning +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "44444" SET +MESSAGE_TEXT = "RESIGNAL to an error", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +insert into t_warn set a= 9999999999999999; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 44444: RESIGNAL to an error +show warnings $$ +Level Code Message +Warning 1264 Out of range value for column 'a' at row 1 +Error 5555 RESIGNAL to an error +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE x integer; +DECLARE c cursor for select * from t_cursor; +DECLARE CONTINUE HANDLER for not found +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "01111" SET +MESSAGE_TEXT = "RESIGNAL to a warning", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +open c; +fetch c into x; +close c; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Error 1329 No data - zero rows fetched, selected, or processed +Warning 5555 RESIGNAL to a warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE x integer; +DECLARE c cursor for select * from t_cursor; +DECLARE CONTINUE HANDLER for not found +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "02444" SET +MESSAGE_TEXT = "RESIGNAL to a not found", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +open c; +fetch c into x; +close c; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02444: RESIGNAL to a not found +show warnings $$ +Level Code Message +Error 1329 No data - zero rows fetched, selected, or processed +Error 5555 RESIGNAL to a not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE x integer; +DECLARE c cursor for select * from t_cursor; +DECLARE CONTINUE HANDLER for not found +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "44444" SET +MESSAGE_TEXT = "RESIGNAL to an error", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +open c; +fetch c into x; +close c; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 44444: RESIGNAL to an error +show warnings $$ +Level Code Message +Error 1329 No data - zero rows fetched, selected, or processed +Error 5555 RESIGNAL to an error +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlexception +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "01111" SET +MESSAGE_TEXT = "RESIGNAL to a warning", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +drop table no_such_table; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +after RESIGNAL +after RESIGNAL +Warnings: +Error 1051 Unknown table 'no_such_table' +Warning 5555 RESIGNAL to a warning +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlexception +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "02444" SET +MESSAGE_TEXT = "RESIGNAL to a not found", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +drop table no_such_table; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 02444: RESIGNAL to a not found +show warnings $$ +Level Code Message +Error 1051 Unknown table 'no_such_table' +Error 5555 RESIGNAL to a not found +drop procedure test_resignal $$ +create procedure test_resignal() +begin +DECLARE CONTINUE HANDLER for sqlexception +begin +select "before RESIGNAL"; +RESIGNAL SQLSTATE "44444" SET +MESSAGE_TEXT = "RESIGNAL to an error", +MYSQL_ERRNO = 5555 ; +select "after RESIGNAL"; +end; +drop table no_such_table; +end $$ +call test_resignal() $$ +before RESIGNAL +before RESIGNAL +ERROR 44444: RESIGNAL to an error +show warnings $$ +Level Code Message +Error 1051 Unknown table 'no_such_table' +Error 5555 RESIGNAL to an error +drop procedure test_resignal $$ +# +# More complex cases +# +drop procedure if exists peter_p1 $$ +drop procedure if exists peter_p2 $$ +CREATE PROCEDURE peter_p1 () +BEGIN +DECLARE x CONDITION FOR 1231; +DECLARE EXIT HANDLER FOR x +BEGIN +SELECT '2'; +RESIGNAL SET MYSQL_ERRNO = 9999; +END; +BEGIN +DECLARE EXIT HANDLER FOR x +BEGIN +SELECT '1'; +RESIGNAL SET SCHEMA_NAME = 'test'; +END; +SET @@sql_mode=NULL; +END; +END +$$ +CREATE PROCEDURE peter_p2 () +BEGIN +DECLARE x CONDITION for 9999; +DECLARE EXIT HANDLER FOR x +BEGIN +SELECT '3'; +RESIGNAL SET MESSAGE_TEXT = 'Hi, I am a useless error message'; +END; +CALL peter_p1(); +END +$$ +CALL peter_p2() $$ +1 +1 +2 +2 +3 +3 +ERROR 42000: Hi, I am a useless error message +show warnings $$ +Level Code Message +Error 9999 Hi, I am a useless error message +drop procedure peter_p1 $$ +drop procedure peter_p2 $$ +CREATE PROCEDURE peter_p1 () +BEGIN +DECLARE x CONDITION FOR SQLSTATE '42000'; +DECLARE EXIT HANDLER FOR x +BEGIN +SELECT '2'; +RESIGNAL x SET MYSQL_ERRNO = 9999; +END; +BEGIN +DECLARE EXIT HANDLER FOR x +BEGIN +SELECT '1'; +RESIGNAL x SET +SCHEMA_NAME = 'test', +MYSQL_ERRNO= 1231; +END; +/* Raises ER_WRONG_VALUE_FOR_VAR : 1231, SQLSTATE 42000 */ +SET @@sql_mode=NULL; +END; +END +$$ +CREATE PROCEDURE peter_p2 () +BEGIN +DECLARE x CONDITION for SQLSTATE '42000'; +DECLARE EXIT HANDLER FOR x +BEGIN +SELECT '3'; +RESIGNAL x SET +MESSAGE_TEXT = 'Hi, I am a useless error message', +MYSQL_ERRNO = 9999; +END; +CALL peter_p1(); +END +$$ +CALL peter_p2() $$ +1 +1 +2 +2 +3 +3 +ERROR 42000: Hi, I am a useless error message +show warnings $$ +Level Code Message +Error 1231 Variable 'sql_mode' can't be set to the value of 'NULL' +Error 1231 Variable 'sql_mode' can't be set to the value of 'NULL' +Error 9999 Variable 'sql_mode' can't be set to the value of 'NULL' +Error 9999 Hi, I am a useless error message +drop procedure peter_p1 $$ +drop procedure peter_p2 $$ +drop procedure if exists peter_p3 $$ +Warnings: +Note 1305 PROCEDURE peter_p3 does not exist +create procedure peter_p3() +begin +declare continue handler for sqlexception +resignal sqlstate '99002' set mysql_errno = 2; +signal sqlstate '99001' set mysql_errno = 1, message_text = "Original"; +end $$ +call peter_p3() $$ +ERROR 99002: Original +show warnings $$ +Level Code Message +Error 1 Original +Error 2 Original +drop procedure peter_p3 $$ +drop table t_warn; +drop table t_cursor; +# +# Miscelaneous test cases +# +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = 0x12; /* 18 */ +end $$ +call test_signal $$ +ERROR 12345: Unhandled user-defined exception condition +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = 0b00010010; /* 18 */ +end $$ +call test_signal $$ +ERROR 12345: Unhandled user-defined exception condition +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = '65'; /* 65 */ +end $$ +call test_signal $$ +ERROR 12345: Unhandled user-defined exception condition +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = 'A'; /* illegal */ +end $$ +call test_signal $$ +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of 'A' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = "65"; /* 65 */ +end $$ +call test_signal $$ +ERROR 12345: Unhandled user-defined exception condition +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = "A"; /* illegal */ +end $$ +call test_signal $$ +ERROR 42000: Variable 'MYSQL_ERRNO' can't be set to the value of 'A' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = `65`; /* illegal */ +end $$ +call test_signal $$ +ERROR 42S22: Unknown column '65' in 'field list' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = `A`; /* illegal */ +end $$ +call test_signal $$ +ERROR 42S22: Unknown column 'A' in 'field list' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = 3.141592; /* 3 */ +end $$ +call test_signal $$ +ERROR 12345: Unhandled user-defined exception condition +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = 1000, +MESSAGE_TEXT= 0x41; /* A */ +end $$ +call test_signal $$ +ERROR 12345: A +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = 1000, +MESSAGE_TEXT= 0b01000001; /* A */ +end $$ +call test_signal $$ +ERROR 12345: A +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = 1000, +MESSAGE_TEXT = "Hello"; +end $$ +call test_signal $$ +ERROR 12345: Hello +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = 1000, +MESSAGE_TEXT = 'Hello'; +end $$ +call test_signal $$ +ERROR 12345: Hello +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = 1000, +MESSAGE_TEXT = `Hello`; +end $$ +call test_signal $$ +ERROR 42S22: Unknown column 'Hello' in 'field list' +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo SET MYSQL_ERRNO = 1000, +MESSAGE_TEXT = 65.4321; +end $$ +call test_signal $$ +ERROR 12345: 65.4321 +drop procedure test_signal $$ +create procedure test_signal() +begin +DECLARE céèçà foo CONDITION FOR SQLSTATE '12345'; +SIGNAL céèçà SET MYSQL_ERRNO = 1000; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '©Ã¨Ã§Ã  foo CONDITION FOR SQLSTATE '12345'; +SIGNAL céèçà SET MYSQL_ERRNO = 1' at line 3 +create procedure test_signal() +begin +DECLARE "céèçà" CONDITION FOR SQLSTATE '12345'; +SIGNAL "céèçà" SET MYSQL_ERRNO = 1000; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"céèçà" CONDITION FOR SQLSTATE '12345'; +SIGNAL "céèçà" SET MYSQL_ERRNO =' at line 3 +create procedure test_signal() +begin +DECLARE 'céèçà' CONDITION FOR SQLSTATE '12345'; +SIGNAL 'céèçà' SET MYSQL_ERRNO = 1000; +end $$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''céèçà' CONDITION FOR SQLSTATE '12345'; +SIGNAL 'céèçà' SET MYSQL_ERRNO =' at line 3 +create procedure test_signal() +begin +DECLARE `céèçà` CONDITION FOR SQLSTATE '12345'; +SIGNAL `céèçà` SET MYSQL_ERRNO = 1000; +end $$ +call test_signal $$ +ERROR 12345: Unhandled user-defined exception condition +drop procedure test_signal $$ +create procedure test_signal() +begin +SIGNAL SQLSTATE '77777' SET MYSQL_ERRNO = 1000, MESSAGE_TEXT='ÃÂÃÅÄ'; +end $$ +drop procedure test_signal $$ diff --git a/mysql-test/r/signal_code.result b/mysql-test/r/signal_code.result new file mode 100644 index 00000000000..63db6656636 --- /dev/null +++ b/mysql-test/r/signal_code.result @@ -0,0 +1,35 @@ +use test; +drop procedure if exists signal_proc; +drop function if exists signal_func; +create procedure signal_proc() +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo; +SIGNAL foo SET MESSAGE_TEXT = "This is an error message"; +RESIGNAL foo; +RESIGNAL foo SET MESSAGE_TEXT = "This is an error message"; +end $$ +create function signal_func() returns int +begin +DECLARE foo CONDITION FOR SQLSTATE '12345'; +SIGNAL foo; +SIGNAL foo SET MESSAGE_TEXT = "This is an error message"; +RESIGNAL foo; +RESIGNAL foo SET MESSAGE_TEXT = "This is an error message"; +return 0; +end $$ +show procedure code signal_proc; +Pos Instruction +0 stmt 136 "SIGNAL foo" +1 stmt 136 "SIGNAL foo SET MESSAGE_TEXT = "This i..." +2 stmt 137 "RESIGNAL foo" +3 stmt 137 "RESIGNAL foo SET MESSAGE_TEXT = "This..." +drop procedure signal_proc; +show function code signal_func; +Pos Instruction +0 stmt 136 "SIGNAL foo" +1 stmt 136 "SIGNAL foo SET MESSAGE_TEXT = "This i..." +2 stmt 137 "RESIGNAL foo" +3 stmt 137 "RESIGNAL foo SET MESSAGE_TEXT = "This..." +4 freturn 3 0 +drop function signal_func; diff --git a/mysql-test/r/signal_demo1.result b/mysql-test/r/signal_demo1.result new file mode 100644 index 00000000000..752f23a48d6 --- /dev/null +++ b/mysql-test/r/signal_demo1.result @@ -0,0 +1,270 @@ +drop database if exists demo; +create database demo; +use demo; +create table ab_physical_person ( +person_id integer, +first_name VARCHAR(50), +middle_initial CHAR, +last_name VARCHAR(50), +primary key (person_id)); +create table ab_moral_person ( +company_id integer, +name VARCHAR(100), +primary key (company_id)); +create table in_inventory ( +item_id integer, +descr VARCHAR(50), +stock integer, +primary key (item_id)); +create table po_order ( +po_id integer auto_increment, +cust_type char, /* arc relationship, see cust_id */ +cust_id integer, /* FK to ab_physical_person *OR* ab_moral_person */ +primary key (po_id)); +create table po_order_line ( +po_id integer, /* FK to po_order.po_id */ +line_no integer, +item_id integer, /* FK to in_inventory.item_id */ +qty integer); +# +# Schema integrity enforcement +# +create procedure check_pk_person(in person_type char, in id integer) +begin +declare x integer; +declare msg varchar(128); +/* +Test integrity constraints for an 'arc' relationship. +Based on 'person_type', 'id' points to either a +physical person, or a moral person. +*/ +case person_type +when 'P' then +begin +select count(person_id) from ab_physical_person +where ab_physical_person.person_id = id +into x; +if (x != 1) +then +set msg= concat('No such physical person, PK:', id); +SIGNAL SQLSTATE '45000' SET +MESSAGE_TEXT = msg, +MYSQL_ERRNO = 10000; +end if; +end; +when 'M' then +begin +select count(company_id) from ab_moral_person +where ab_moral_person.company_id = id +into x; +if (x != 1) +then +set msg= concat('No such moral person, PK:', id); +SIGNAL SQLSTATE '45000' SET +MESSAGE_TEXT = msg, +MYSQL_ERRNO = 10000; +end if; +end; +else +begin +set msg= concat('No such person type:', person_type); +SIGNAL SQLSTATE '45000' SET +MESSAGE_TEXT = msg, +MYSQL_ERRNO = 20000; +end; +end case; +end +$$ +create procedure check_pk_inventory(in id integer) +begin +declare x integer; +declare msg varchar(128); +select count(item_id) from in_inventory +where in_inventory.item_id = id +into x; +if (x != 1) +then +set msg= concat('Failed integrity constraint, table in_inventory, PK:', +id); +SIGNAL SQLSTATE '45000' SET +MESSAGE_TEXT = msg, +MYSQL_ERRNO = 10000; +end if; +end +$$ +create procedure check_pk_order(in id integer) +begin +declare x integer; +declare msg varchar(128); +select count(po_id) from po_order +where po_order.po_id = id +into x; +if (x != 1) +then +set msg= concat('Failed integrity constraint, table po_order, PK:', id); +SIGNAL SQLSTATE '45000' SET +MESSAGE_TEXT = msg, +MYSQL_ERRNO = 10000; +end if; +end +$$ +create trigger po_order_bi before insert on po_order +for each row +begin +call check_pk_person(NEW.cust_type, NEW.cust_id); +end +$$ +create trigger po_order_bu before update on po_order +for each row +begin +call check_pk_person(NEW.cust_type, NEW.cust_id); +end +$$ +create trigger po_order_line_bi before insert on po_order_line +for each row +begin +call check_pk_order(NEW.po_id); +call check_pk_inventory(NEW.item_id); +end +$$ +create trigger po_order_line_bu before update on po_order_line +for each row +begin +call check_pk_order(NEW.po_id); +call check_pk_inventory(NEW.item_id); +end +$$ +# +# Application helpers +# +create procedure po_create_order( +in p_cust_type char, +in p_cust_id integer, +out id integer) +begin +insert into po_order set cust_type = p_cust_type, cust_id = p_cust_id; +set id = last_insert_id(); +end +$$ +create procedure po_add_order_line( +in po integer, +in line integer, +in item integer, +in q integer) +begin +insert into po_order_line set +po_id = po, line_no = line, item_id = item, qty = q; +end +$$ +# +# Create sample data +# +insert into ab_physical_person values +( 1, "John", "A", "Doe"), +( 2, "Marry", "B", "Smith") +; +insert into ab_moral_person values +( 3, "ACME real estate, INC"), +( 4, "Local school") +; +insert into in_inventory values +( 100, "Table, dinner", 5), +( 101, "Chair", 20), +( 200, "Table, coffee", 3), +( 300, "School table", 25), +( 301, "School chairs", 50) +; +select * from ab_physical_person order by person_id; +person_id first_name middle_initial last_name +1 John A Doe +2 Marry B Smith +select * from ab_moral_person order by company_id; +company_id name +3 ACME real estate, INC +4 Local school +select * from in_inventory order by item_id; +item_id descr stock +100 Table, dinner 5 +101 Chair 20 +200 Table, coffee 3 +300 School table 25 +301 School chairs 50 +# +# Entering an order +# +set @my_po = 0; +/* John Doe wants 1 table and 4 chairs */ +call po_create_order("P", 1, @my_po); +call po_add_order_line (@my_po, 1, 100, 1); +call po_add_order_line (@my_po, 2, 101, 4); +/* Marry Smith wants a coffee table */ +call po_create_order("P", 2, @my_po); +call po_add_order_line (@my_po, 1, 200, 1); +# +# Entering bad data in an order +# +call po_add_order_line (@my_po, 1, 999, 1); +ERROR 45000: Failed integrity constraint, table in_inventory, PK:999 +# +# Entering bad data in an unknown order +# +call po_add_order_line (99, 1, 100, 1); +ERROR 45000: Failed integrity constraint, table po_order, PK:99 +# +# Entering an order for an unknown company +# +call po_create_order("M", 7, @my_po); +ERROR 45000: No such moral person, PK:7 +# +# Entering an order for an unknown person type +# +call po_create_order("X", 1, @my_po); +ERROR 45000: No such person type:X +/* The local school wants 10 class tables and 20 chairs */ +call po_create_order("M", 4, @my_po); +call po_add_order_line (@my_po, 1, 300, 10); +call po_add_order_line (@my_po, 2, 301, 20); +select * from po_order; +po_id cust_type cust_id +1 P 1 +2 P 2 +3 M 4 +select * from po_order_line; +po_id line_no item_id qty +1 1 100 1 +1 2 101 4 +2 1 200 1 +3 1 300 10 +3 2 301 20 +select po_id as "PO#", +( case cust_type +when "P" then concat (pp.first_name, +" ", +pp.middle_initial, +" ", +pp.last_name) +when "M" then mp.name +end ) as "Sold to" + from po_order po +left join ab_physical_person pp on po.cust_id = pp.person_id +left join ab_moral_person mp on po.cust_id = company_id +; +PO# Sold to +1 John A Doe +2 Marry B Smith +3 Local school +select po_id as "PO#", +ol.line_no as "Line", +ol.item_id as "Item", +inv.descr as "Description", +ol.qty as "Quantity" + from po_order_line ol, in_inventory inv +where inv.item_id = ol.item_id +order by ol.item_id, ol.line_no; +PO# Line Item Description Quantity +1 1 100 Table, dinner 1 +1 2 101 Chair 4 +2 1 200 Table, coffee 1 +3 1 300 School table 10 +3 2 301 School chairs 20 +drop database demo; diff --git a/mysql-test/r/signal_demo2.result b/mysql-test/r/signal_demo2.result new file mode 100644 index 00000000000..223030b0624 --- /dev/null +++ b/mysql-test/r/signal_demo2.result @@ -0,0 +1,197 @@ +drop database if exists demo; +create database demo; +use demo; +create procedure proc_top_a(p1 integer) +begin +## DECLARE CONTINUE HANDLER for SQLEXCEPTION, NOT FOUND +begin +end; +select "Starting ..."; +call proc_middle_a(p1); +select "The end"; +end +$$ +create procedure proc_middle_a(p1 integer) +begin +DECLARE l integer; +# without RESIGNAL: +# Should be: DECLARE EXIT HANDLER for SQLEXCEPTION, NOT FOUND +DECLARE EXIT HANDLER for 1 /* not sure how to handle exceptions */ +begin +select "Oops ... now what ?"; +end; +select "In prod_middle()"; +create temporary table t1(a integer, b integer); +select GET_LOCK("user_mutex", 10) into l; +insert into t1 set a = p1, b = p1; +call proc_bottom_a(p1); +select RELEASE_LOCK("user_mutex") into l; +drop temporary table t1; +end +$$ +create procedure proc_bottom_a(p1 integer) +begin +select "In proc_bottom()"; +if (p1 = 1) then +begin +select "Doing something that works ..."; +select * from t1; +end; +end if; +if (p1 = 2) then +begin +select "Doing something that fail (simulate an error) ..."; +drop table no_such_table; +end; +end if; +if (p1 = 3) then +begin +select "Doing something that *SHOULD* works ..."; +select * from t1; +end; +end if; +end +$$ +call proc_top_a(1); +Starting ... +Starting ... +In prod_middle() +In prod_middle() +In proc_bottom() +In proc_bottom() +Doing something that works ... +Doing something that works ... +a b +1 1 +The end +The end +call proc_top_a(2); +Starting ... +Starting ... +In prod_middle() +In prod_middle() +In proc_bottom() +In proc_bottom() +Doing something that fail (simulate an error) ... +Doing something that fail (simulate an error) ... +ERROR 42S02: Unknown table 'no_such_table' +call proc_top_a(3); +Starting ... +Starting ... +In prod_middle() +In prod_middle() +ERROR 42S01: Table 't1' already exists +call proc_top_a(1); +Starting ... +Starting ... +In prod_middle() +In prod_middle() +ERROR 42S01: Table 't1' already exists +drop temporary table if exists t1; +create procedure proc_top_b(p1 integer) +begin +select "Starting ..."; +call proc_middle_b(p1); +select "The end"; +end +$$ +create procedure proc_middle_b(p1 integer) +begin +DECLARE l integer; +DECLARE EXIT HANDLER for SQLEXCEPTION, NOT FOUND +begin +begin +DECLARE CONTINUE HANDLER for SQLEXCEPTION, NOT FOUND +begin +/* Ignore errors from the cleanup code */ +end; +select "Doing cleanup !"; +select RELEASE_LOCK("user_mutex") into l; +drop temporary table t1; +end; +RESIGNAL; +end; +select "In prod_middle()"; +create temporary table t1(a integer, b integer); +select GET_LOCK("user_mutex", 10) into l; +insert into t1 set a = p1, b = p1; +call proc_bottom_b(p1); +select RELEASE_LOCK("user_mutex") into l; +drop temporary table t1; +end +$$ +create procedure proc_bottom_b(p1 integer) +begin +select "In proc_bottom()"; +if (p1 = 1) then +begin +select "Doing something that works ..."; +select * from t1; +end; +end if; +if (p1 = 2) then +begin +select "Doing something that fail (simulate an error) ..."; +drop table no_such_table; +end; +end if; +if (p1 = 3) then +begin +select "Doing something that *SHOULD* works ..."; +select * from t1; +end; +end if; +end +$$ +call proc_top_b(1); +Starting ... +Starting ... +In prod_middle() +In prod_middle() +In proc_bottom() +In proc_bottom() +Doing something that works ... +Doing something that works ... +a b +1 1 +The end +The end +call proc_top_b(2); +Starting ... +Starting ... +In prod_middle() +In prod_middle() +In proc_bottom() +In proc_bottom() +Doing something that fail (simulate an error) ... +Doing something that fail (simulate an error) ... +Doing cleanup ! +Doing cleanup ! +ERROR 42S02: Unknown table 'no_such_table' +call proc_top_b(3); +Starting ... +Starting ... +In prod_middle() +In prod_middle() +In proc_bottom() +In proc_bottom() +Doing something that *SHOULD* works ... +Doing something that *SHOULD* works ... +a b +3 3 +The end +The end +call proc_top_b(1); +Starting ... +Starting ... +In prod_middle() +In prod_middle() +In proc_bottom() +In proc_bottom() +Doing something that works ... +Doing something that works ... +a b +1 1 +The end +The end +drop database demo; diff --git a/mysql-test/r/signal_demo3.result b/mysql-test/r/signal_demo3.result new file mode 100644 index 00000000000..fea41ec2ef9 --- /dev/null +++ b/mysql-test/r/signal_demo3.result @@ -0,0 +1,143 @@ +SET @start_global_value = @@global.max_error_count; +SELECT @start_global_value; +@start_global_value +64 +SET @start_session_value = @@session.max_error_count; +SELECT @start_session_value; +@start_session_value +64 +drop database if exists demo; +create database demo; +use demo; +create procedure proc_1() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_1'; +call proc_2(); +end +$$ +create procedure proc_2() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_2'; +call proc_3(); +end +$$ +create procedure proc_3() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_3'; +call proc_4(); +end +$$ +create procedure proc_4() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_4'; +call proc_5(); +end +$$ +create procedure proc_5() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_5'; +call proc_6(); +end +$$ +create procedure proc_6() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_6'; +call proc_7(); +end +$$ +create procedure proc_7() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_7'; +call proc_8(); +end +$$ +create procedure proc_8() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_8'; +call proc_9(); +end +$$ +create procedure proc_9() +begin +declare exit handler for sqlexception +resignal sqlstate '45000' set message_text='Oops in proc_9'; +## Do something that fails, to see how errors are reported +drop table oops_it_is_not_here; +end +$$ +call proc_1(); +ERROR 45000: Oops in proc_1 +show warnings; +Level Code Message +Error 1051 Unknown table 'oops_it_is_not_here' +Error 1642 Oops in proc_9 +Error 1642 Oops in proc_8 +Error 1642 Oops in proc_7 +Error 1642 Oops in proc_6 +Error 1642 Oops in proc_5 +Error 1642 Oops in proc_4 +Error 1642 Oops in proc_3 +Error 1642 Oops in proc_2 +Error 1642 Oops in proc_1 +SET @@session.max_error_count = 5; +SELECT @@session.max_error_count; +@@session.max_error_count +5 +call proc_1(); +ERROR 45000: Oops in proc_1 +show warnings; +Level Code Message +Error 1642 Oops in proc_5 +Error 1642 Oops in proc_4 +Error 1642 Oops in proc_3 +Error 1642 Oops in proc_2 +Error 1642 Oops in proc_1 +SET @@session.max_error_count = 7; +SELECT @@session.max_error_count; +@@session.max_error_count +7 +call proc_1(); +ERROR 45000: Oops in proc_1 +show warnings; +Level Code Message +Error 1642 Oops in proc_7 +Error 1642 Oops in proc_6 +Error 1642 Oops in proc_5 +Error 1642 Oops in proc_4 +Error 1642 Oops in proc_3 +Error 1642 Oops in proc_2 +Error 1642 Oops in proc_1 +SET @@session.max_error_count = 9; +SELECT @@session.max_error_count; +@@session.max_error_count +9 +call proc_1(); +ERROR 45000: Oops in proc_1 +show warnings; +Level Code Message +Error 1642 Oops in proc_9 +Error 1642 Oops in proc_8 +Error 1642 Oops in proc_7 +Error 1642 Oops in proc_6 +Error 1642 Oops in proc_5 +Error 1642 Oops in proc_4 +Error 1642 Oops in proc_3 +Error 1642 Oops in proc_2 +Error 1642 Oops in proc_1 +drop database demo; +SET @@global.max_error_count = @start_global_value; +SELECT @@global.max_error_count; +@@global.max_error_count +64 +SET @@session.max_error_count = @start_session_value; +SELECT @@session.max_error_count; +@@session.max_error_count +64 diff --git a/mysql-test/r/signal_sqlmode.result b/mysql-test/r/signal_sqlmode.result new file mode 100644 index 00000000000..8fed85eb4a9 --- /dev/null +++ b/mysql-test/r/signal_sqlmode.result @@ -0,0 +1,86 @@ +SET @save_sql_mode=@@sql_mode; +SET sql_mode=''; +drop procedure if exists p; +drop procedure if exists p2; +drop procedure if exists p3; +create procedure p() +begin +declare utf8_var VARCHAR(128) CHARACTER SET UTF8; +set utf8_var = concat(repeat('A', 128), 'X'); +select length(utf8_var), utf8_var; +end +$$ +create procedure p2() +begin +declare msg VARCHAR(129) CHARACTER SET UTF8; +set msg = concat(repeat('A', 128), 'X'); +select length(msg), msg; +signal sqlstate '55555' set message_text = msg; +end +$$ +create procedure p3() +begin +declare name VARCHAR(65) CHARACTER SET UTF8; +set name = concat(repeat('A', 64), 'X'); +select length(name), name; +signal sqlstate '55555' set +message_text = 'Message', +table_name = name; +end +$$ +call p; +length(utf8_var) utf8_var +128 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +Warnings: +Warning 1265 Data truncated for column 'utf8_var' at row 1 +call p2; +length(msg) msg +129 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX +ERROR 55555: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +call p3; +length(name) name +65 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX +ERROR 55555: Message +drop procedure p; +drop procedure p2; +drop procedure p3; +SET sql_mode='STRICT_ALL_TABLES'; +create procedure p() +begin +declare utf8_var VARCHAR(128) CHARACTER SET UTF8; +set utf8_var = concat(repeat('A', 128), 'X'); +select length(utf8_var), utf8_var; +end +$$ +create procedure p2() +begin +declare msg VARCHAR(129) CHARACTER SET UTF8; +set msg = concat(repeat('A', 128), 'X'); +select length(msg), msg; +signal sqlstate '55555' set message_text = msg; +end +$$ +create procedure p3() +begin +declare name VARCHAR(65) CHARACTER SET UTF8; +set name = concat(repeat('A', 64), 'X'); +select length(name), name; +signal sqlstate '55555' set +message_text = 'Message', +table_name = name; +end +$$ +call p; +ERROR 22001: Data too long for column 'utf8_var' at row 1 +call p2; +length(msg) msg +129 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX +ERROR HY000: Data too long for condition item 'MESSAGE_TEXT' +call p3; +length(name) name +65 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX +ERROR HY000: Data too long for condition item 'TABLE_NAME' +drop procedure p; +drop procedure p2; +drop procedure p3; +SET @@sql_mode=@save_sql_mode; diff --git a/mysql-test/r/sp-dynamic.result b/mysql-test/r/sp-dynamic.result index 34b76a9424f..cdfeb8ab020 100644 --- a/mysql-test/r/sp-dynamic.result +++ b/mysql-test/r/sp-dynamic.result @@ -97,8 +97,6 @@ end| call p1()| a 1 -Warnings: -Note 1051 Unknown table 't1' call p1()| a 1 @@ -371,9 +369,6 @@ call p1(@a)| create table t1 (a int) @rsql create table t2 (a int) -Warnings: -Note 1051 Unknown table 't1' -Note 1051 Unknown table 't2' select @a| @a 0 @@ -382,9 +377,6 @@ call p1(@a)| create table t1 (a int) @rsql create table t2 (a int) -Warnings: -Note 1051 Unknown table 't1' -Note 1051 Unknown table 't2' select @a| @a 0 diff --git a/mysql-test/r/sp-vars.result b/mysql-test/r/sp-vars.result index f5420a62f63..f532a5284a9 100644 --- a/mysql-test/r/sp-vars.result +++ b/mysql-test/r/sp-vars.result @@ -110,24 +110,6 @@ v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19 v20 12.00 12.12 12.00 12.12 Warnings: -Warning 1264 Out of range value for column 'v1' at row 1 -Warning 1264 Out of range value for column 'v1u' at row 1 -Warning 1264 Out of range value for column 'v2' at row 1 -Warning 1264 Out of range value for column 'v2u' at row 1 -Warning 1264 Out of range value for column 'v3' at row 1 -Warning 1264 Out of range value for column 'v3u' at row 1 -Warning 1264 Out of range value for column 'v4' at row 1 -Warning 1264 Out of range value for column 'v4u' at row 1 -Warning 1264 Out of range value for column 'v5' at row 1 -Warning 1264 Out of range value for column 'v5u' at row 1 -Warning 1264 Out of range value for column 'v6' at row 1 -Warning 1264 Out of range value for column 'v6u' at row 1 -Warning 1366 Incorrect integer value: 'String 10 ' for column 'v10' at row 1 -Warning 1366 Incorrect integer value: 'String10' for column 'v11' at row 1 -Warning 1265 Data truncated for column 'v12' at row 1 -Warning 1265 Data truncated for column 'v13' at row 1 -Warning 1366 Incorrect integer value: 'Hello, world' for column 'v16' at row 1 -Note 1265 Data truncated for column 'v18' at row 1 Note 1265 Data truncated for column 'v20' at row 1 CALL sp_vars_check_assignment(); i1 i2 i3 i4 @@ -143,21 +125,6 @@ d1 d2 d3 d1 d2 d3 1234.00 1234.12 1234.12 Warnings: -Warning 1264 Out of range value for column 'i1' at row 1 -Warning 1264 Out of range value for column 'i2' at row 1 -Warning 1264 Out of range value for column 'i3' at row 1 -Warning 1264 Out of range value for column 'i4' at row 1 -Warning 1264 Out of range value for column 'i1' at row 1 -Warning 1264 Out of range value for column 'i2' at row 1 -Warning 1264 Out of range value for column 'i3' at row 1 -Warning 1264 Out of range value for column 'i4' at row 1 -Warning 1264 Out of range value for column 'u1' at row 1 -Warning 1264 Out of range value for column 'u2' at row 1 -Warning 1264 Out of range value for column 'u3' at row 1 -Warning 1264 Out of range value for column 'u4' at row 1 -Warning 1264 Out of range value for column 'u1' at row 1 -Warning 1264 Out of range value for column 'u2' at row 1 -Note 1265 Data truncated for column 'd3' at row 1 Note 1265 Data truncated for column 'd3' at row 1 SELECT sp_vars_check_ret1(); sp_vars_check_ret1() @@ -198,24 +165,6 @@ v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19 v20 12.00 12.12 12.00 12.12 Warnings: -Warning 1264 Out of range value for column 'v1' at row 1 -Warning 1264 Out of range value for column 'v1u' at row 1 -Warning 1264 Out of range value for column 'v2' at row 1 -Warning 1264 Out of range value for column 'v2u' at row 1 -Warning 1264 Out of range value for column 'v3' at row 1 -Warning 1264 Out of range value for column 'v3u' at row 1 -Warning 1264 Out of range value for column 'v4' at row 1 -Warning 1264 Out of range value for column 'v4u' at row 1 -Warning 1264 Out of range value for column 'v5' at row 1 -Warning 1264 Out of range value for column 'v5u' at row 1 -Warning 1264 Out of range value for column 'v6' at row 1 -Warning 1264 Out of range value for column 'v6u' at row 1 -Warning 1366 Incorrect integer value: 'String 10 ' for column 'v10' at row 1 -Warning 1366 Incorrect integer value: 'String10' for column 'v11' at row 1 -Warning 1265 Data truncated for column 'v12' at row 1 -Warning 1265 Data truncated for column 'v13' at row 1 -Warning 1366 Incorrect integer value: 'Hello, world' for column 'v16' at row 1 -Note 1265 Data truncated for column 'v18' at row 1 Note 1265 Data truncated for column 'v20' at row 1 CALL sp_vars_check_assignment(); i1 i2 i3 i4 @@ -231,21 +180,6 @@ d1 d2 d3 d1 d2 d3 1234.00 1234.12 1234.12 Warnings: -Warning 1264 Out of range value for column 'i1' at row 1 -Warning 1264 Out of range value for column 'i2' at row 1 -Warning 1264 Out of range value for column 'i3' at row 1 -Warning 1264 Out of range value for column 'i4' at row 1 -Warning 1264 Out of range value for column 'i1' at row 1 -Warning 1264 Out of range value for column 'i2' at row 1 -Warning 1264 Out of range value for column 'i3' at row 1 -Warning 1264 Out of range value for column 'i4' at row 1 -Warning 1264 Out of range value for column 'u1' at row 1 -Warning 1264 Out of range value for column 'u2' at row 1 -Warning 1264 Out of range value for column 'u3' at row 1 -Warning 1264 Out of range value for column 'u4' at row 1 -Warning 1264 Out of range value for column 'u1' at row 1 -Warning 1264 Out of range value for column 'u2' at row 1 -Note 1265 Data truncated for column 'd3' at row 1 Note 1265 Data truncated for column 'd3' at row 1 SELECT sp_vars_check_ret1(); sp_vars_check_ret1() @@ -451,10 +385,6 @@ FF HEX(v10) FF Warnings: -Warning 1264 Out of range value for column 'v8' at row 1 -Warning 1264 Out of range value for column 'v9' at row 1 -Warning 1264 Out of range value for column 'v10' at row 1 -Warning 1264 Out of range value for column 'v1' at row 1 Warning 1264 Out of range value for column 'v5' at row 1 DROP PROCEDURE p1; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 3ad556b8c30..6f4755fcf37 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -526,8 +526,6 @@ end| delete from t1| create table t3 ( s char(16), d int)| call into_test4()| -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed select * from t3| s d into4 NULL @@ -1120,8 +1118,6 @@ end| select f9()| f9() 6 -Warnings: -Note 1051 Unknown table 't3' select f9() from t1 limit 1| f9() 6 @@ -1162,8 +1158,6 @@ drop temporary table t3| select f12_1()| f12_1() 3 -Warnings: -Note 1051 Unknown table 't3' select f12_1() from t1 limit 1| f12_1() 3 @@ -2069,12 +2063,7 @@ end if; insert into t4 values (2, rc, t3); end| call bug1863(10)| -Warnings: -Note 1051 Unknown table 'temp_t1' -Warning 1329 No data - zero rows fetched, selected, or processed call bug1863(10)| -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed select * from t4| f1 rc t3 2 0 NULL @@ -2339,11 +2328,7 @@ begin end| call bug4579_1()| call bug4579_1()| -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed call bug4579_1()| -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed drop procedure bug4579_1| drop procedure bug4579_2| drop table t3| @@ -3736,9 +3721,6 @@ Table Create Table tm1 CREATE TEMPORARY TABLE `tm1` ( `spv1` decimal(3,3) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 -Warnings: -Warning 1264 Out of range value for column 'spv1' at row 1 -Warning 1366 Incorrect decimal value: 'test' for column 'spv1' at row 1 call bug12589_2()| Table Create Table tm1 CREATE TEMPORARY TABLE `tm1` ( @@ -6106,35 +6088,6 @@ bug5274_f2() x Warnings: Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 -Warning 1265 Data truncated for column 'bug5274_f1' at row 1 DROP FUNCTION bug5274_f1| DROP FUNCTION bug5274_f2| drop procedure if exists proc_21513| @@ -6229,20 +6182,17 @@ f1(2) 0 Warnings: Warning 1329 No data - zero rows fetched, selected, or processed -Warning 1329 No data - zero rows fetched, selected, or processed PREPARE s1 FROM 'SELECT f1(2)'; EXECUTE s1; f1(2) 0 Warnings: Warning 1329 No data - zero rows fetched, selected, or processed -Warning 1329 No data - zero rows fetched, selected, or processed EXECUTE s1; f1(2) 0 Warnings: Warning 1329 No data - zero rows fetched, selected, or processed -Warning 1329 No data - zero rows fetched, selected, or processed DROP PROCEDURE p1; DROP PROCEDURE p2; DROP FUNCTION f1; @@ -6254,6 +6204,7 @@ create procedure mysqltest_db1.sp_bug28551() begin end; call mysqltest_db1.sp_bug28551(); show warnings; Level Code Message +Note 1008 Can't drop database 'mysqltest_db1'; database doesn't exist drop database mysqltest_db1; drop database if exists mysqltest_db1; drop table if exists test.t1; diff --git a/mysql-test/r/sp_notembedded.result b/mysql-test/r/sp_notembedded.result index 831616f491b..228fe008447 100644 --- a/mysql-test/r/sp_notembedded.result +++ b/mysql-test/r/sp_notembedded.result @@ -21,9 +21,11 @@ end| call bug4902_2()| show warnings| Level Code Message +Note 1305 PROCEDURE bug4902_2 does not exist call bug4902_2()| show warnings| Level Code Message +Note 1305 PROCEDURE bug4902_2 does not exist drop procedure bug4902_2| drop table if exists t1| create table t1 ( diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index 241f4198bf7..a9e0d7f457d 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -315,8 +315,8 @@ MOD(col1,0) NULL NULL Warnings: -Error 1365 Division by 0 -Error 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 INSERT INTO t1 (col1) VALUES(-129); ERROR 22003: Out of range value for column 'col1' at row 1 INSERT INTO t1 (col1) VALUES(128); @@ -343,7 +343,7 @@ SELECT MOD(col1,0) FROM t1 WHERE col1 > 0 LIMIT 1; MOD(col1,0) NULL Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 UPDATE t1 SET col1 = col1 - 50 WHERE col1 < 0; ERROR 22003: Out of range value for column 'col1' at row 1 UPDATE t1 SET col2=col2 + 50 WHERE col2 > 0; @@ -353,16 +353,16 @@ ERROR 22012: Division by 0 set @@sql_mode='ERROR_FOR_DIVISION_BY_ZERO'; INSERT INTO t1 values (1/0,1/0); Warnings: -Error 1365 Division by 0 -Error 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 set @@sql_mode='ansi,traditional'; SELECT MOD(col1,0) FROM t1 WHERE col1 > 0 LIMIT 2; MOD(col1,0) NULL NULL Warnings: -Error 1365 Division by 0 -Error 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 INSERT INTO t1 (col1) VALUES (''); ERROR HY000: Incorrect integer value: '' for column 'col1' at row 1 INSERT INTO t1 (col1) VALUES ('a59b'); @@ -374,8 +374,8 @@ Warnings: Warning 1265 Data truncated for column 'col1' at row 1 INSERT IGNORE INTO t1 values (1/0,1/0); Warnings: -Error 1365 Division by 0 -Error 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 set @@sql_mode='ansi'; INSERT INTO t1 values (1/0,1/0); set @@sql_mode='ansi,traditional'; @@ -457,8 +457,8 @@ Warnings: Warning 1265 Data truncated for column 'col1' at row 1 INSERT IGNORE INTO t1 values (1/0,1/0); Warnings: -Error 1365 Division by 0 -Error 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 INSERT IGNORE INTO t1 VALUES(-32769,-1),(32768,65536); Warnings: Warning 1264 Out of range value for column 'col1' at row 1 @@ -541,8 +541,8 @@ Warnings: Warning 1265 Data truncated for column 'col1' at row 1 INSERT IGNORE INTO t1 values (1/0,1/0); Warnings: -Error 1365 Division by 0 -Error 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 INSERT IGNORE INTO t1 VALUES(-8388609,-1),(8388608,16777216); Warnings: Warning 1264 Out of range value for column 'col1' at row 1 @@ -625,8 +625,8 @@ Warnings: Warning 1265 Data truncated for column 'col1' at row 1 INSERT IGNORE INTO t1 values (1/0,1/0); Warnings: -Error 1365 Division by 0 -Error 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 INSERT IGNORE INTO t1 values (-2147483649, -1),(2147643648,4294967296); Warnings: Warning 1264 Out of range value for column 'col1' at row 1 @@ -707,8 +707,8 @@ Warnings: Warning 1265 Data truncated for column 'col1' at row 1 INSERT IGNORE INTO t1 values (1/0,1/0); Warnings: -Error 1365 Division by 0 -Error 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 INSERT IGNORE INTO t1 VALUES(-9223372036854775809,-1),(9223372036854775808,18446744073709551616); Warnings: Warning 1264 Out of range value for column 'col1' at row 1 @@ -794,7 +794,7 @@ Warnings: Note 1265 Data truncated for column 'col1' at row 1 INSERT IGNORE INTO t1 values (1/0); Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 INSERT IGNORE INTO t1 VALUES(1000),(-1000); Warnings: Warning 1264 Out of range value for column 'col1' at row 1 @@ -861,7 +861,7 @@ Warnings: Warning 1265 Data truncated for column 'col1' at row 1 INSERT IGNORE INTO t1 (col1) VALUES (1/0); Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 INSERT IGNORE INTO t1 VALUES (+3.4E+39,-3.4E+39); Warnings: Warning 1264 Out of range value for column 'col1' at row 1 @@ -910,7 +910,7 @@ Warnings: Warning 1265 Data truncated for column 'col1' at row 1 INSERT IGNORE INTO t1 (col1) values (1/0); Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 INSERT IGNORE INTO t1 VALUES (+1.9E+309,-1.9E+309); ERROR 22007: Illegal double '1.9E+309' value found during parsing INSERT IGNORE INTO t1 VALUES ('+2.0E+309','-2.0E+309'); @@ -1080,13 +1080,13 @@ Warnings: Warning 1292 Truncated incorrect datetime value: '31.10.2004 15.30 abc' insert into t1 values(STR_TO_DATE('32.10.2004 15.30','%d.%m.%Y %H.%i')); Warnings: -Error 1411 Incorrect datetime value: '32.10.2004 15.30' for function str_to_date +Warning 1411 Incorrect datetime value: '32.10.2004 15.30' for function str_to_date insert into t1 values(STR_TO_DATE('2004.12.12 22:22:33 AM','%Y.%m.%d %r')); Warnings: -Error 1411 Incorrect time value: '22:22:33 AM' for function str_to_date +Warning 1411 Incorrect time value: '22:22:33 AM' for function str_to_date insert into t1 values(STR_TO_DATE('2004.12.12 abc','%Y.%m.%d %T')); Warnings: -Error 1411 Incorrect time value: 'abc' for function str_to_date +Warning 1411 Incorrect time value: 'abc' for function str_to_date insert into t1 values(STR_TO_DATE('31.10.2004 15.30','%d.%m.%Y %H.%i')); insert into t1 values(STR_TO_DATE('2004.12.12 11:22:33 AM','%Y.%m.%d %r')); insert into t1 values(STR_TO_DATE('2004.12.12 10:22:59','%Y.%m.%d %T')); @@ -1104,9 +1104,9 @@ select count(*) from t1 where STR_TO_DATE('2004.12.12 10:22:61','%Y.%m.%d %T') I count(*) 7 Warnings: -Error 1411 Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date -Error 1411 Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date -Error 1411 Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date +Warning 1411 Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date +Warning 1411 Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date +Warning 1411 Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date drop table t1; create table t1 (col1 char(3), col2 integer); insert into t1 (col1) values (cast(1000 as char(3))); diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index 4476735735c..000b08113c1 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -1073,7 +1073,7 @@ NULL SET @x=2; UPDATE t1 SET i1 = @x; Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 SELECT @x; @x NULL @@ -1086,8 +1086,8 @@ NULL SET @x=4; UPDATE t1 SET i1 = @x; Warnings: -Error 1365 Division by 0 -Error 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 SELECT @x; @x NULL @@ -1190,16 +1190,16 @@ create trigger t4_bu before update on t4 for each row set @t4_bu_called:=1| insert into t1 values(10, 10)| set @a:=1/0| Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 select 1/0 from t1| 1/0 NULL Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 create trigger t1_bi before insert on t1 for each row set @a:=1/0| insert into t1 values(20, 20)| Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 drop trigger t1_bi| create trigger t1_bi before insert on t1 for each row begin @@ -1219,7 +1219,7 @@ end| set @check=0, @t4_bi_called=0, @t4_bu_called=0| insert into t1 values(30, 30)| Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 select @check, @t4_bi_called, @t4_bu_called| @check @t4_bi_called @t4_bu_called 2 1 1 diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index c3d1e400b23..1ad46821bb7 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -185,7 +185,7 @@ select 1e10/0e0; 1e10/0e0 NULL Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 create table wl1612 (col1 int, col2 decimal(38,10), col3 numeric(38,10)); insert into wl1612 values(1,12345678901234567890.1234567890,12345678901234567890.1234567890); select * from wl1612; @@ -205,27 +205,27 @@ NULL NULL NULL Warnings: -Error 1365 Division by 0 -Error 1365 Division by 0 -Error 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 select col2/0 from wl1612; col2/0 NULL NULL NULL Warnings: -Error 1365 Division by 0 -Error 1365 Division by 0 -Error 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 select col3/0 from wl1612; col3/0 NULL NULL NULL Warnings: -Error 1365 Division by 0 -Error 1365 Division by 0 -Error 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 insert into wl1612 values(5,5000.0005,5000.0005); insert into wl1612 values(6,5000.0005,5000.0005); select sum(col2),sum(col3) from wl1612; @@ -788,12 +788,12 @@ select 1 / 1E-500; 1 / 1E-500 NULL Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 select 1 / 0; 1 / 0 NULL Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 set sql_mode='ansi,traditional'; CREATE TABLE Sow6_2f (col1 NUMERIC(4,2)); INSERT INTO Sow6_2f VALUES (10.55); @@ -819,11 +819,11 @@ NULL NULL NULL Warnings: -Error 1365 Division by 0 -Error 1365 Division by 0 -Error 1365 Division by 0 -Error 1365 Division by 0 -Error 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 +Warning 1365 Division by 0 INSERT INTO Sow6_2f VALUES ('a59b'); ERROR HY000: Incorrect decimal value: 'a59b' for column 'col1' at row 1 drop table Sow6_2f; @@ -838,12 +838,12 @@ select 9999999999999999999999999999999999999999999999999999999999999999999999999 x 99999999999999999999999999999999999999999999999999999999999999999 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + 1 as x; x 100000000000000000000000000000000000000000000000000000000000000000 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' select 0.190287977636363637 + 0.040372670 * 0 - 0; 0.190287977636363637 + 0.040372670 * 0 - 0 0.190287977636363637 @@ -1380,15 +1380,15 @@ create table t1 (c1 decimal(64)); insert into t1 values( 89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000); Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' Warning 1264 Out of range value for column 'c1' at row 1 insert into t1 values( 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999); Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' Warning 1264 Out of range value for column 'c1' at row 1 insert into t1 values(1e100); Warnings: @@ -1432,7 +1432,7 @@ select cast(19999999999999999999 as unsigned); cast(19999999999999999999 as unsigned) 18446744073709551615 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' create table t1(a decimal(18)); insert into t1 values(123456789012345678); alter table t1 modify column a decimal(19); @@ -1444,12 +1444,12 @@ select cast(11.1234 as DECIMAL(3,2)); cast(11.1234 as DECIMAL(3,2)) 9.99 Warnings: -Error 1264 Out of range value for column 'cast(11.1234 as DECIMAL(3,2))' at row 1 +Warning 1264 Out of range value for column 'cast(11.1234 as DECIMAL(3,2))' at row 1 select * from (select cast(11.1234 as DECIMAL(3,2))) t; cast(11.1234 as DECIMAL(3,2)) 9.99 Warnings: -Error 1264 Out of range value for column 'cast(11.1234 as DECIMAL(3,2))' at row 1 +Warning 1264 Out of range value for column 'cast(11.1234 as DECIMAL(3,2))' at row 1 select cast(a as DECIMAL(3,2)) from (select 11.1233 as a UNION select 11.1234 @@ -1460,9 +1460,9 @@ cast(a as DECIMAL(3,2)) 9.99 9.99 Warnings: -Error 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1 -Error 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1 -Error 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1 +Warning 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1 +Warning 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1 +Warning 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1 select cast(a as DECIMAL(3,2)), count(*) from (select 11.1233 as a UNION select 11.1234 @@ -1471,10 +1471,10 @@ UNION select 12.1234 cast(a as DECIMAL(3,2)) count(*) 9.99 3 Warnings: -Error 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1 -Error 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1 -Error 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1 -Error 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1 +Warning 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1 +Warning 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1 +Warning 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1 +Warning 1264 Out of range value for column 'cast(a as DECIMAL(3,2))' at row 1 create table t1 (s varchar(100)); insert into t1 values (0.00000000010000000000000000364321973154977415791655470655996396089904010295867919921875); drop table t1; @@ -1560,7 +1560,7 @@ select cast(143.481 as decimal(2,1)); cast(143.481 as decimal(2,1)) 9.9 Warnings: -Error 1264 Out of range value for column 'cast(143.481 as decimal(2,1))' at row 1 +Warning 1264 Out of range value for column 'cast(143.481 as decimal(2,1))' at row 1 select cast(-3.4 as decimal(2,1)); cast(-3.4 as decimal(2,1)) -3.4 @@ -1568,12 +1568,12 @@ select cast(99.6 as decimal(2,0)); cast(99.6 as decimal(2,0)) 99 Warnings: -Error 1264 Out of range value for column 'cast(99.6 as decimal(2,0))' at row 1 +Warning 1264 Out of range value for column 'cast(99.6 as decimal(2,0))' at row 1 select cast(-13.4 as decimal(2,1)); cast(-13.4 as decimal(2,1)) -9.9 Warnings: -Error 1264 Out of range value for column 'cast(-13.4 as decimal(2,1))' at row 1 +Warning 1264 Out of range value for column 'cast(-13.4 as decimal(2,1))' at row 1 select cast(98.6 as decimal(2,0)); cast(98.6 as decimal(2,0)) 99 @@ -1674,7 +1674,7 @@ CREATE TABLE t1 SELECT /* 82 */ 1000000000000000000000000000000000000000000000000000000000000000000000000000000001 AS c1; Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' DESC t1; Field Type Null Key Default Extra c1 decimal(65,0) NO 0 @@ -1797,7 +1797,7 @@ CREATE TABLE t1 (a DECIMAL(30,30)); INSERT INTO t1 VALUES (0.1),(0.2),(0.3); CREATE TABLE t2 SELECT MIN(a + 0.0000000000000000000000000000001) AS c1 FROM t1; Warnings: -Note 1265 Data truncated for column 'c1' at row 3 +Note 1265 Data truncated for column 'c1' at row 4 DESC t2; Field Type Null Key Default Extra c1 decimal(32,30) YES NULL diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index b5e374aaf8c..e23e8930ddb 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1111,8 +1111,8 @@ insert into v1 values(3); ERROR HY000: CHECK OPTION failed 'test.v1' insert ignore into v1 values (2),(3),(0); Warnings: -Error 1369 CHECK OPTION failed 'test.v1' -Error 1369 CHECK OPTION failed 'test.v1' +Warning 1369 CHECK OPTION failed 'test.v1' +Warning 1369 CHECK OPTION failed 'test.v1' select * from t1; a 1 @@ -1125,8 +1125,8 @@ create table t2 (a int); insert into t2 values (2),(3),(0); insert ignore into v1 SELECT a from t2; Warnings: -Error 1369 CHECK OPTION failed 'test.v1' -Error 1369 CHECK OPTION failed 'test.v1' +Warning 1369 CHECK OPTION failed 'test.v1' +Warning 1369 CHECK OPTION failed 'test.v1' select * from t1 order by a desc; a 1 @@ -1148,7 +1148,7 @@ a update v1 set a=a+1; update ignore v1,t2 set v1.a=v1.a+1 where v1.a=t2.a; Warnings: -Error 1369 CHECK OPTION failed 'test.v1' +Warning 1369 CHECK OPTION failed 'test.v1' select * from t1; a 1 @@ -1182,7 +1182,7 @@ insert into v1 values (1) on duplicate key update a=2; ERROR HY000: CHECK OPTION failed 'test.v1' insert ignore into v1 values (1) on duplicate key update a=2; Warnings: -Error 1369 CHECK OPTION failed 'test.v1' +Warning 1369 CHECK OPTION failed 'test.v1' select * from t1; a 1 @@ -1283,7 +1283,7 @@ insert ignore into v1 values (6); ERROR HY000: CHECK OPTION failed 'test.v1' insert ignore into v1 values (6),(3); Warnings: -Error 1369 CHECK OPTION failed 'test.v1' +Warning 1369 CHECK OPTION failed 'test.v1' select * from t1; s1 3 @@ -1328,9 +1328,9 @@ delete from t1; load data infile '../../std_data/loaddata3.dat' ignore into table v1 fields terminated by '' enclosed by '' ignore 1 lines; Warnings: Warning 1366 Incorrect integer value: 'error ' for column 'a' at row 3 -Error 1369 CHECK OPTION failed 'test.v1' +Warning 1369 CHECK OPTION failed 'test.v1' Warning 1366 Incorrect integer value: 'wrong end ' for column 'a' at row 4 -Error 1369 CHECK OPTION failed 'test.v1' +Warning 1369 CHECK OPTION failed 'test.v1' select * from t1 order by a,b; a b 1 row 1 @@ -1354,7 +1354,7 @@ concat('|',a,'|') concat('|',b,'|') delete from t1; load data infile '../../std_data/loaddata2.dat' ignore into table v1 fields terminated by ',' enclosed by ''''; Warnings: -Error 1369 CHECK OPTION failed 'test.v1' +Warning 1369 CHECK OPTION failed 'test.v1' Warning 1261 Row 2 doesn't contain data for all columns select concat('|',a,'|'), concat('|',b,'|') from t1; concat('|',a,'|') concat('|',b,'|') diff --git a/mysql-test/suite/binlog/r/binlog_index.result b/mysql-test/suite/binlog/r/binlog_index.result index d49ceb00501..69d877c5adc 100644 --- a/mysql-test/suite/binlog/r/binlog_index.result +++ b/mysql-test/suite/binlog/r/binlog_index.result @@ -34,7 +34,7 @@ purge binary logs TO 'master-bin.000002'; ERROR HY000: Fatal error during log purge show warnings; Level Code Message -Error 1377 a problem with deleting master-bin.000001; consider examining correspondence of your binlog index file to the actual binlog files +Warning 1377 a problem with deleting master-bin.000001; consider examining correspondence of your binlog index file to the actual binlog files Error 1377 Fatal error during log purge reset master; End of tests diff --git a/mysql-test/suite/binlog/r/binlog_unsafe.result b/mysql-test/suite/binlog/r/binlog_unsafe.result index 4c2c32ad8f1..3047ff54cf0 100644 --- a/mysql-test/suite/binlog/r/binlog_unsafe.result +++ b/mysql-test/suite/binlog/r/binlog_unsafe.result @@ -43,12 +43,6 @@ END| CALL proc(); Warnings: Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. ---- Insert from stored function ---- CREATE FUNCTION func() RETURNS INT @@ -67,12 +61,6 @@ func() 0 Warnings: Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. ---- Insert from trigger ---- CREATE TRIGGER trig BEFORE INSERT ON trigger_table @@ -90,12 +78,6 @@ INSERT INTO trigger_table VALUES ('bye.'); Warnings: Note 1592 Statement may not be safe to log in statement format. Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. ---- Insert from prepared statement ---- PREPARE p1 FROM 'INSERT INTO t1 VALUES (@@global.sync_binlog)'; PREPARE p2 FROM 'INSERT INTO t1 VALUES (@@session.insert_id)'; @@ -155,12 +137,6 @@ func5() 0 Warnings: Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. ==== Variables that should *not* be unsafe ==== INSERT INTO t1 VALUES (@@session.pseudo_thread_id); INSERT INTO t1 VALUES (@@session.pseudo_thread_id); @@ -215,9 +191,6 @@ END| CALL p1(); Warnings: Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. -Note 1592 Statement may not be safe to log in statement format. DROP PROCEDURE p1; DROP TABLE t1; DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/innodb/r/innodb-zip.result b/mysql-test/suite/innodb/r/innodb-zip.result index b26c4112826..a59758c8673 100644 --- a/mysql-test/suite/innodb/r/innodb-zip.result +++ b/mysql-test/suite/innodb/r/innodb-zip.result @@ -198,13 +198,11 @@ create table t1 (id int primary key) engine = innodb key_block_size = 0; ERROR HY000: Can't create table 'test.t1' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 0. Valid values are [1, 2, 4, 8, 16] Error 1005 Can't create table 'test.t1' (errno: 1478) create table t2 (id int primary key) engine = innodb key_block_size = 9; ERROR HY000: Can't create table 'test.t2' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] Error 1005 Can't create table 'test.t2' (errno: 1478) create table t3 (id int primary key) engine = innodb key_block_size = 1; create table t4 (id int primary key) engine = innodb key_block_size = 2; @@ -235,28 +233,24 @@ key_block_size = 8 row_format = redundant; ERROR HY000: Can't create table 'test.t2' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. Error 1005 Can't create table 'test.t2' (errno: 1478) create table t3 (id int primary key) engine = innodb key_block_size = 8 row_format = compact; ERROR HY000: Can't create table 'test.t3' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. Error 1005 Can't create table 'test.t3' (errno: 1478) create table t4 (id int primary key) engine = innodb key_block_size = 8 row_format = dynamic; ERROR HY000: Can't create table 'test.t4' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. Error 1005 Can't create table 'test.t4' (errno: 1478) create table t5 (id int primary key) engine = innodb key_block_size = 8 row_format = default; ERROR HY000: Can't create table 'test.t5' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. Error 1005 Can't create table 'test.t5' (errno: 1478) SELECT table_schema, table_name, row_format FROM information_schema.tables WHERE engine='innodb'; @@ -268,24 +262,18 @@ key_block_size = 9 row_format = redundant; ERROR HY000: Can't create table 'test.t1' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] -Error 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. Error 1005 Can't create table 'test.t1' (errno: 1478) create table t2 (id int primary key) engine = innodb key_block_size = 9 row_format = compact; ERROR HY000: Can't create table 'test.t2' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] -Error 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. Error 1005 Can't create table 'test.t2' (errno: 1478) create table t2 (id int primary key) engine = innodb key_block_size = 9 row_format = dynamic; ERROR HY000: Can't create table 'test.t2' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] -Error 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. Error 1005 Can't create table 'test.t2' (errno: 1478) SELECT table_schema, table_name, row_format FROM information_schema.tables WHERE engine='innodb'; @@ -295,43 +283,36 @@ create table t1 (id int primary key) engine = innodb key_block_size = 1; ERROR HY000: Can't create table 'test.t1' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. Error 1005 Can't create table 'test.t1' (errno: 1478) create table t2 (id int primary key) engine = innodb key_block_size = 2; ERROR HY000: Can't create table 'test.t2' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. Error 1005 Can't create table 'test.t2' (errno: 1478) create table t3 (id int primary key) engine = innodb key_block_size = 4; ERROR HY000: Can't create table 'test.t3' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. Error 1005 Can't create table 'test.t3' (errno: 1478) create table t4 (id int primary key) engine = innodb key_block_size = 8; ERROR HY000: Can't create table 'test.t4' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. Error 1005 Can't create table 'test.t4' (errno: 1478) create table t5 (id int primary key) engine = innodb key_block_size = 16; ERROR HY000: Can't create table 'test.t5' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. Error 1005 Can't create table 'test.t5' (errno: 1478) create table t6 (id int primary key) engine = innodb row_format = compressed; ERROR HY000: Can't create table 'test.t6' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. Error 1005 Can't create table 'test.t6' (errno: 1478) create table t7 (id int primary key) engine = innodb row_format = dynamic; ERROR HY000: Can't create table 'test.t7' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. Error 1005 Can't create table 'test.t7' (errno: 1478) create table t8 (id int primary key) engine = innodb row_format = compact; create table t9 (id int primary key) engine = innodb row_format = redundant; @@ -347,43 +328,36 @@ create table t1 (id int primary key) engine = innodb key_block_size = 1; ERROR HY000: Can't create table 'test.t1' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. Error 1005 Can't create table 'test.t1' (errno: 1478) create table t2 (id int primary key) engine = innodb key_block_size = 2; ERROR HY000: Can't create table 'test.t2' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. Error 1005 Can't create table 'test.t2' (errno: 1478) create table t3 (id int primary key) engine = innodb key_block_size = 4; ERROR HY000: Can't create table 'test.t3' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. Error 1005 Can't create table 'test.t3' (errno: 1478) create table t4 (id int primary key) engine = innodb key_block_size = 8; ERROR HY000: Can't create table 'test.t4' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. Error 1005 Can't create table 'test.t4' (errno: 1478) create table t5 (id int primary key) engine = innodb key_block_size = 16; ERROR HY000: Can't create table 'test.t5' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. Error 1005 Can't create table 'test.t5' (errno: 1478) create table t6 (id int primary key) engine = innodb row_format = compressed; ERROR HY000: Can't create table 'test.t6' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. Error 1005 Can't create table 'test.t6' (errno: 1478) create table t7 (id int primary key) engine = innodb row_format = dynamic; ERROR HY000: Can't create table 'test.t7' (errno: 1478) show errors; Level Code Message -Error 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. Error 1005 Can't create table 'test.t7' (errno: 1478) create table t8 (id int primary key) engine = innodb row_format = compact; create table t9 (id int primary key) engine = innodb row_format = redundant; diff --git a/mysql-test/suite/ndb/r/ndb_bitfield.result b/mysql-test/suite/ndb/r/ndb_bitfield.result index 59c4d420b22..826f3a98348 100644 --- a/mysql-test/suite/ndb/r/ndb_bitfield.result +++ b/mysql-test/suite/ndb/r/ndb_bitfield.result @@ -204,7 +204,7 @@ b int ERROR HY000: Can't create table 'test.t1' (errno: 906) show warnings; Level Code Message -Error 1296 Got error 906 'Unsupported attribute type in index' from NDB +Warning 1296 Got error 906 'Unsupported attribute type in index' from NDB Error 1005 Can't create table 'test.t1' (errno: 906) create table t1 ( pk1 int not null primary key, @@ -214,7 +214,7 @@ key(b) ERROR HY000: Can't create table 'test.t1' (errno: 906) show warnings; Level Code Message -Error 1296 Got error 906 'Unsupported attribute type in index' from NDB +Warning 1296 Got error 906 'Unsupported attribute type in index' from NDB Error 1005 Can't create table 'test.t1' (errno: 906) create table t1 ( pk1 int primary key, diff --git a/mysql-test/suite/ndb/r/ndb_dd_basic.result b/mysql-test/suite/ndb/r/ndb_dd_basic.result index 41e3d10fe5b..b956d3b0047 100644 --- a/mysql-test/suite/ndb/r/ndb_dd_basic.result +++ b/mysql-test/suite/ndb/r/ndb_dd_basic.result @@ -8,20 +8,20 @@ INITIAL_SIZE 16M UNDO_BUFFER_SIZE = 1M ENGINE=MYISAM; Warnings: -Error 1478 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' +Warning 1478 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' ALTER LOGFILE GROUP lg1 ADD UNDOFILE 'undofile02.dat' INITIAL_SIZE = 4M ENGINE=XYZ; Warnings: Warning 1286 Unknown table engine 'XYZ' -Error 1478 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' +Warning 1478 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' CREATE TABLESPACE ts1 ADD DATAFILE 'datafile.dat' USE LOGFILE GROUP lg1 INITIAL_SIZE 12M; Warnings: -Error 1478 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' +Warning 1478 Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP' set storage_engine=ndb; CREATE LOGFILE GROUP lg1 ADD UNDOFILE 'undofile.dat' diff --git a/mysql-test/suite/ndb/r/ndb_dd_ddl.result b/mysql-test/suite/ndb/r/ndb_dd_ddl.result index d8d9e8631d5..2bf30f5c7fc 100644 --- a/mysql-test/suite/ndb/r/ndb_dd_ddl.result +++ b/mysql-test/suite/ndb/r/ndb_dd_ddl.result @@ -15,7 +15,7 @@ ENGINE NDB; ERROR HY000: Failed to create LOGFILE GROUP SHOW WARNINGS; Level Code Message -Error 1296 Got error 1514 'Currently there is a limit of one logfile group' from NDB +Warning 1296 Got error 1514 'Currently there is a limit of one logfile group' from NDB Error 1528 Failed to create LOGFILE GROUP CREATE LOGFILE GROUP lg1 ADD UNDOFILE 'undofile.dat' diff --git a/mysql-test/suite/ndb/r/ndb_gis.result b/mysql-test/suite/ndb/r/ndb_gis.result index 374d702c408..61d15b7cb98 100644 --- a/mysql-test/suite/ndb/r/ndb_gis.result +++ b/mysql-test/suite/ndb/r/ndb_gis.result @@ -463,7 +463,7 @@ drop table t1; End of 4.1 tests CREATE TABLE t1 (name VARCHAR(100), square GEOMETRY); Warnings: -Error 1478 Table storage engine 'ndbcluster' does not support the create option 'Binlog of table with BLOB attribute and no PK' +Warning 1478 Table storage engine 'ndbcluster' does not support the create option 'Binlog of table with BLOB attribute and no PK' INSERT INTO t1 VALUES("center", GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))')); INSERT INTO t1 VALUES("small", GeomFromText('POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0))')); INSERT INTO t1 VALUES("big", GeomFromText('POLYGON (( 0 0, 0 3, 3 3, 3 0, 0 0))')); @@ -1013,7 +1013,7 @@ drop table t1; End of 4.1 tests CREATE TABLE t1 (name VARCHAR(100), square GEOMETRY); Warnings: -Error 1478 Table storage engine 'ndbcluster' does not support the create option 'Binlog of table with BLOB attribute and no PK' +Warning 1478 Table storage engine 'ndbcluster' does not support the create option 'Binlog of table with BLOB attribute and no PK' INSERT INTO t1 VALUES("center", GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))')); INSERT INTO t1 VALUES("small", GeomFromText('POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0))')); INSERT INTO t1 VALUES("big", GeomFromText('POLYGON (( 0 0, 0 3, 3 3, 3 0, 0 0))')); diff --git a/mysql-test/suite/ndb/r/ndb_partition_error.result b/mysql-test/suite/ndb/r/ndb_partition_error.result index d86dc382185..df2db5c5f06 100644 --- a/mysql-test/suite/ndb/r/ndb_partition_error.result +++ b/mysql-test/suite/ndb/r/ndb_partition_error.result @@ -14,7 +14,7 @@ partition x3 values less than (20) nodegroup 14); ERROR HY000: Can't create table 'test.t1' (errno: 140) show warnings; Level Code Message -Error 1296 Got error 771 'Given NODEGROUP doesn't exist in this cluster' from NDB +Warning 1296 Got error 771 'Given NODEGROUP doesn't exist in this cluster' from NDB Error 1005 Can't create table 'test.t1' (errno: 140) CREATE TABLE t1 ( a int not null, diff --git a/mysql-test/suite/ndb/r/ndb_row_format.result b/mysql-test/suite/ndb/r/ndb_row_format.result index eea0692dd92..48a314c2fe9 100644 --- a/mysql-test/suite/ndb/r/ndb_row_format.result +++ b/mysql-test/suite/ndb/r/ndb_row_format.result @@ -8,7 +8,7 @@ ENGINE=NDB; ERROR HY000: Can't create table 'test.t1' (errno: 138) SHOW WARNINGS; Level Code Message -Error 1478 Table storage engine 'ndbcluster' does not support the create option 'Row format FIXED incompatible with variable sized attribute' +Warning 1478 Table storage engine 'ndbcluster' does not support the create option 'Row format FIXED incompatible with variable sized attribute' Error 1005 Can't create table 'test.t1' (errno: 138) CREATE TABLE t1 ( a INT KEY, diff --git a/mysql-test/suite/ndb/r/ndb_single_user.result b/mysql-test/suite/ndb/r/ndb_single_user.result index 8133e540d71..1d5f3041adb 100644 --- a/mysql-test/suite/ndb/r/ndb_single_user.result +++ b/mysql-test/suite/ndb/r/ndb_single_user.result @@ -9,7 +9,7 @@ ENGINE=NDB; ERROR HY000: Failed to create LOGFILE GROUP show warnings; Level Code Message -Error 1296 Got error 299 'Operation not allowed or aborted due to single user mode' from NDB +Warning 1296 Got error 299 'Operation not allowed or aborted due to single user mode' from NDB Error 1528 Failed to create LOGFILE GROUP create table t1 (a int key, b int unique, c int) engine ndb; CREATE LOGFILE GROUP lg1 @@ -25,14 +25,14 @@ ENGINE NDB; ERROR HY000: Failed to create TABLESPACE show warnings; Level Code Message -Error 1296 Got error 299 'Operation not allowed or aborted due to single user mode' from NDB +Warning 1296 Got error 299 'Operation not allowed or aborted due to single user mode' from NDB Error 1528 Failed to create TABLESPACE DROP LOGFILE GROUP lg1 ENGINE =NDB; ERROR HY000: Failed to drop LOGFILE GROUP show warnings; Level Code Message -Error 1296 Got error 299 'Operation not allowed or aborted due to single user mode' from NDB +Warning 1296 Got error 299 'Operation not allowed or aborted due to single user mode' from NDB Error 1529 Failed to drop LOGFILE GROUP CREATE TABLESPACE ts1 ADD DATAFILE 'datafile.dat' @@ -45,7 +45,7 @@ ENGINE NDB; ERROR HY000: Failed to alter: DROP DATAFILE show warnings; Level Code Message -Error 1296 Got error 299 'Operation not allowed or aborted due to single user mode' from NDB +Warning 1296 Got error 299 'Operation not allowed or aborted due to single user mode' from NDB Error 1533 Failed to alter: DROP DATAFILE ALTER TABLESPACE ts1 DROP DATAFILE 'datafile.dat' @@ -55,7 +55,7 @@ ENGINE NDB; ERROR HY000: Failed to drop TABLESPACE show warnings; Level Code Message -Error 1296 Got error 299 'Operation not allowed or aborted due to single user mode' from NDB +Warning 1296 Got error 299 'Operation not allowed or aborted due to single user mode' from NDB Error 1529 Failed to drop TABLESPACE DROP TABLESPACE ts1 ENGINE NDB; diff --git a/mysql-test/suite/rpl/r/rpl_EE_err.result b/mysql-test/suite/rpl/r/rpl_EE_err.result index 16fa931e303..8c1277445b2 100644 --- a/mysql-test/suite/rpl/r/rpl_EE_err.result +++ b/mysql-test/suite/rpl/r/rpl_EE_err.result @@ -8,4 +8,4 @@ create table t1 (a int) engine=myisam; flush tables; drop table if exists t1; Warnings: -Error 2 Can't find file: 't1' (errno: 2) +Warning 2 Can't find file: 't1' (errno: 2) diff --git a/mysql-test/suite/rpl/r/rpl_row_sp007_innodb.result b/mysql-test/suite/rpl/r/rpl_row_sp007_innodb.result index 9a2822835f8..5a6a9ace4c5 100644 --- a/mysql-test/suite/rpl/r/rpl_row_sp007_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_row_sp007_innodb.result @@ -22,8 +22,6 @@ END| < ---- Master selects-- > ------------------------- CALL test.p1(12); -Warnings: -Note 1051 Unknown table 't1' SELECT * FROM test.t1; num 12 diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index e92f3e96303..71d3d5a140b 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -694,3 +694,35 @@ SELECT 1 FROM t1 WHERE t1.a NOT IN DROP TABLE t1, t2; --echo End of 5.0 tests + +# +# Bug#36785: Wrong error message when group_concat() exceeds max length +# + +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +--enable_warnings + +CREATE TABLE t1 (a VARCHAR(6), b INT); +CREATE TABLE t2 (a VARCHAR(6), b INT); + +INSERT INTO t1 VALUES ('111111', 1); +INSERT INTO t1 VALUES ('222222', 2); +INSERT INTO t1 VALUES ('333333', 3); +INSERT INTO t1 VALUES ('444444', 4); +INSERT INTO t1 VALUES ('555555', 5); + +SET group_concat_max_len = 5; +SET @old_sql_mode = @@sql_mode, @@sql_mode = 'traditional'; + +SELECT GROUP_CONCAT(a), b FROM t1 GROUP BY b LIMIT 3; +--error ER_CUT_VALUE_GROUP_CONCAT +INSERT INTO t2 SELECT GROUP_CONCAT(a), b FROM t1 GROUP BY b; +UPDATE t1 SET a = '11111' WHERE b = 1; +UPDATE t1 SET a = '22222' WHERE b = 2; +--error ER_CUT_VALUE_GROUP_CONCAT +INSERT INTO t2 SELECT GROUP_CONCAT(a), b FROM t1 GROUP BY b; + +SET group_concat_max_len = DEFAULT; +SET @@sql_mode = @old_sql_mode; +DROP TABLE t1, t2; diff --git a/mysql-test/t/signal.test b/mysql-test/t/signal.test new file mode 100644 index 00000000000..bdb6625ba32 --- /dev/null +++ b/mysql-test/t/signal.test @@ -0,0 +1,2685 @@ +# Copyright (C) 2008 Sun Microsystems, Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# Tests for SIGNAL and RESIGNAL + +--echo # +--echo # PART 1: syntax +--echo # + +--echo # +--echo # Test every new reserved and non reserved keywords +--echo # + +--disable_warnings +drop table if exists signal_non_reserved; +--enable_warnings + +create table signal_non_reserved ( + class_origin int, + subclass_origin int, + constraint_catalog int, + constraint_schema int, + constraint_name int, + catalog_name int, + schema_name int, + table_name int, + column_name int, + cursor_name int, + message_text int, + sqlcode int +); + +drop table signal_non_reserved; + +--disable_warnings +drop table if exists diag_non_reserved; +--enable_warnings + +create table diag_non_reserved ( + diagnostics int, + current int, + stacked int, + exception int +); + +drop table diag_non_reserved; + +--disable_warnings +drop table if exists diag_cond_non_reserved; +--enable_warnings + +create table diag_cond_non_reserved ( + condition_identifier int, + condition_number int, + condition_name int, + connection_name int, + message_length int, + message_octet_length int, + parameter_mode int, + parameter_name int, + parameter_ordinal_position int, + returned_sqlstate int, + routine_catalog int, + routine_name int, + routine_schema int, + server_name int, + specific_name int, + trigger_catalog int, + trigger_name int, + trigger_schema int +); + +drop table diag_cond_non_reserved; + +--disable_warnings +drop table if exists diag_stmt_non_reserved; +--enable_warnings + +create table diag_stmt_non_reserved ( + number int, + more int, + command_function int, + command_function_code int, + dynamic_function int, + dynamic_function_code int, + row_count int, + transactions_committed int, + transactions_rolled_back int, + transaction_active int +); + +drop table diag_stmt_non_reserved; + +--disable_warnings +drop table if exists test_reserved; +--enable_warnings + +--error ER_PARSE_ERROR +create table test_reserved (signal int); + +--error ER_PARSE_ERROR +create table test_reserved (resignal int); + +--error ER_PARSE_ERROR +create table test_reserved (condition int); + +--echo # +--echo # Test the SIGNAL syntax +--echo # + +--disable_warnings +drop procedure if exists test_invalid; +drop procedure if exists test_signal_syntax; +drop function if exists test_signal_func; +--enable_warnings + +delimiter $$; + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL; +end $$ + +--error ER_SP_COND_MISMATCH +create procedure test_invalid() +begin + SIGNAL foo; +end $$ + +--error ER_SIGNAL_BAD_CONDITION_TYPE +create procedure test_invalid() +begin + DECLARE foo CONDITION FOR 1234; + SIGNAL foo; +end $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + SIGNAL SQLSTATE '23000'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + SIGNAL SQLSTATE VALUE '23000'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET CLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET SUBCLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET CONSTRAINT_CATALOG = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET CONSTRAINT_SCHEMA = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET CONSTRAINT_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET CATALOG_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET SCHEMA_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET TABLE_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET COLUMN_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET CURSOR_NAME = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MESSAGE_TEXT = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +--error ER_DUP_SIGNAL_SET +create procedure test_invalid() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET CLASS_ORIGIN = 'foo', CLASS_ORIGIN = 'bar'; +end $$ + +--error ER_DUP_SIGNAL_SET +create procedure test_invalid() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MESSAGE_TEXT = 'foo', MESSAGE_TEXT = 'bar'; +end $$ + +--error ER_DUP_SIGNAL_SET +create procedure test_invalid() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = 'foo', MYSQL_ERRNO = 'bar'; +end $$ + +create procedure test_signal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET + CLASS_ORIGIN = 'foo', + SUBCLASS_ORIGIN = 'foo', + CONSTRAINT_CATALOG = 'foo', + CONSTRAINT_SCHEMA = 'foo', + CONSTRAINT_NAME = 'foo', + CATALOG_NAME = 'foo', + SCHEMA_NAME = 'foo', + TABLE_NAME = 'foo', + COLUMN_NAME = 'foo', + CURSOR_NAME = 'foo', + MESSAGE_TEXT = 'foo', + MYSQL_ERRNO = 'foo'; +end $$ +drop procedure test_signal_syntax $$ + +--error ER_SP_BAD_SQLSTATE +SIGNAL SQLSTATE '00000' $$ + +--error ER_SP_BAD_SQLSTATE +SIGNAL SQLSTATE '00001' $$ + +--error ER_SP_BAD_SQLSTATE +create procedure test_invalid() +begin + SIGNAL SQLSTATE '00000'; +end $$ + +--error ER_SP_BAD_SQLSTATE +create procedure test_invalid() +begin + SIGNAL SQLSTATE '00001'; +end $$ + +--echo # +--echo # Test conditions information that SIGNAL can not set +--echo # + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET bla_bla = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET CONDITION_IDENTIFIER = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET CONDITION_NUMBER = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET CONNECTION_NAME = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET MESSAGE_LENGTH = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET MESSAGE_OCTET_LENGTH = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET PARAMETER_MODE = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET PARAMETER_NAME = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET PARAMETER_ORDINAL_POSITION = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET RETURNED_SQLSTATE = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET ROUTINE_CATALOG = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET ROUTINE_NAME = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET ROUTINE_SCHEMA = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET SERVER_NAME = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET SPECIFIC_NAME = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET TRIGGER_CATALOG = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET TRIGGER_NAME = 'foo'; +end $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + SIGNAL SQLSTATE '12345' SET TRIGGER_SCHEMA = 'foo'; +end $$ + +delimiter ;$$ + +--echo # +--echo # Test the RESIGNAL syntax +--echo # + +--disable_warnings +drop procedure if exists test_invalid; +drop procedure if exists test_resignal_syntax; +--enable_warnings + +delimiter $$; + +--error ER_SP_COND_MISMATCH +create procedure test_invalid() +begin + RESIGNAL foo; +end $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL; +end $$ +drop procedure test_resignal_syntax $$ + +--error ER_SIGNAL_BAD_CONDITION_TYPE +create procedure test_invalid() +begin + DECLARE foo CONDITION FOR 1234; + RESIGNAL foo; +end $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SQLSTATE '23000'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SQLSTATE VALUE '23000'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET CLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET CLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET SUBCLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET SUBCLASS_ORIGIN = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET CONSTRAINT_CATALOG = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET CONSTRAINT_CATALOG = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET CONSTRAINT_SCHEMA = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET CONSTRAINT_SCHEMA = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET CONSTRAINT_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET CONSTRAINT_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET CATALOG_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET CATALOG_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET SCHEMA_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET SCHEMA_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET TABLE_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET TABLE_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET COLUMN_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET COLUMN_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET CURSOR_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET CURSOR_NAME = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET MESSAGE_TEXT = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET MESSAGE_TEXT = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + RESIGNAL SET MYSQL_ERRNO = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET MYSQL_ERRNO = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +--error ER_DUP_SIGNAL_SET +create procedure test_invalid() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET CLASS_ORIGIN = 'foo', CLASS_ORIGIN = 'bar'; +end $$ + +--error ER_DUP_SIGNAL_SET +create procedure test_invalid() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET MESSAGE_TEXT = 'foo', MESSAGE_TEXT = 'bar'; +end $$ + +--error ER_DUP_SIGNAL_SET +create procedure test_invalid() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET MYSQL_ERRNO = 'foo', MYSQL_ERRNO = 'bar'; +end $$ + +create procedure test_resignal_syntax() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + RESIGNAL foo SET + CLASS_ORIGIN = 'foo', + SUBCLASS_ORIGIN = 'foo', + CONSTRAINT_CATALOG = 'foo', + CONSTRAINT_SCHEMA = 'foo', + CONSTRAINT_NAME = 'foo', + CATALOG_NAME = 'foo', + SCHEMA_NAME = 'foo', + TABLE_NAME = 'foo', + COLUMN_NAME = 'foo', + CURSOR_NAME = 'foo', + MESSAGE_TEXT = 'foo'; +end $$ +drop procedure test_resignal_syntax $$ + +--error ER_SP_BAD_SQLSTATE +create procedure test_invalid() +begin + RESIGNAL SQLSTATE '00000'; +end $$ + +--error ER_SP_BAD_SQLSTATE +create procedure test_invalid() +begin + RESIGNAL SQLSTATE '00001'; +end $$ + +delimiter ;$$ + +--echo # +--echo # PART 2: non preparable statements +--echo # + +--error ER_UNSUPPORTED_PS +prepare stmt from 'SIGNAL SQLSTATE \'23000\''; + +--error ER_UNSUPPORTED_PS +prepare stmt from 'RESIGNAL SQLSTATE \'23000\''; + +--echo # +--echo # PART 3: runtime execution +--echo # + +--disable_warnings +drop procedure if exists test_signal; +drop procedure if exists test_resignal; +drop table if exists t_warn; +drop table if exists t_cursor; +--enable_warnings + +# Helper tables +create table t_warn(a integer(2)); +create table t_cursor(a integer); + +--echo # +--echo # SIGNAL can also appear in a query +--echo # + +--error ER_SP_COND_MISMATCH +SIGNAL foo; + +SIGNAL SQLSTATE '01000'; + +--error ER_SIGNAL_NOT_FOUND +SIGNAL SQLSTATE '02000'; + +--error ER_SIGNAL_EXCEPTION +SIGNAL SQLSTATE '23000'; + +--error ER_SIGNAL_EXCEPTION +SIGNAL SQLSTATE VALUE '23000'; + +--error ER_WRONG_VALUE_FOR_VAR +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 65536; + +--error ER_WRONG_VALUE_FOR_VAR +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 99999; + +--error ER_WRONG_VALUE_FOR_VAR +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 4294967295; + +--error ER_WRONG_VALUE_FOR_VAR +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 0; + +--error ER_PARSE_ERROR +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = -1; + +--error 65535 +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 65535; + +--echo # +--echo # RESIGNAL can also appear in a query +--echo # + +--error ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER +RESIGNAL; + +--error ER_SP_COND_MISMATCH +RESIGNAL foo; + +--error ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER +RESIGNAL SQLSTATE '12345'; + +--error ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER +RESIGNAL SQLSTATE VALUE '12345'; + +--echo # +--echo # Different kind of SIGNAL conditions +--echo # + +delimiter $$; + +create procedure test_signal() +begin + # max range + DECLARE foo CONDITION FOR SQLSTATE 'AABBB'; + SIGNAL foo SET MYSQL_ERRNO = 65535; +end $$ + +--error 65535 +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # max range + DECLARE foo CONDITION FOR SQLSTATE 'AABBB'; + SIGNAL foo SET MYSQL_ERRNO = 65536; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Error + DECLARE foo CONDITION FOR SQLSTATE '99999'; + SIGNAL foo SET MYSQL_ERRNO = 9999; +end $$ + +--error 9999 +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # warning + DECLARE too_few_records CONDITION FOR SQLSTATE '01000'; + SIGNAL too_few_records SET MYSQL_ERRNO = 1261; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Not found + DECLARE sp_fetch_no_data CONDITION FOR SQLSTATE '02000'; + SIGNAL sp_fetch_no_data SET MYSQL_ERRNO = 1329; +end $$ + +--error ER_SP_FETCH_NO_DATA +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Error + DECLARE sp_cursor_already_open CONDITION FOR SQLSTATE '24000'; + SIGNAL sp_cursor_already_open SET MYSQL_ERRNO = 1325; +end $$ + +--error ER_SP_CURSOR_ALREADY_OPEN +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Severe error + DECLARE lock_deadlock CONDITION FOR SQLSTATE '40001'; + SIGNAL lock_deadlock SET MYSQL_ERRNO = 1213; +end $$ + +--error ER_LOCK_DEADLOCK +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Unknown -> error + DECLARE foo CONDITION FOR SQLSTATE "99999"; + SIGNAL foo; +end $$ + +--error ER_SIGNAL_EXCEPTION +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # warning, no subclass + DECLARE warn CONDITION FOR SQLSTATE "01000"; + SIGNAL warn; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # warning, with subclass + DECLARE warn CONDITION FOR SQLSTATE "01123"; + SIGNAL warn; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Not found, no subclass + DECLARE not_found CONDITION FOR SQLSTATE "02000"; + SIGNAL not_found; +end $$ + +--error ER_SIGNAL_NOT_FOUND +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Not found, with subclass + DECLARE not_found CONDITION FOR SQLSTATE "02XXX"; + SIGNAL not_found; +end $$ + +--error ER_SIGNAL_NOT_FOUND +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Error, no subclass + DECLARE error CONDITION FOR SQLSTATE "12000"; + SIGNAL error; +end $$ + +--error ER_SIGNAL_EXCEPTION +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Error, with subclass + DECLARE error CONDITION FOR SQLSTATE "12ABC"; + SIGNAL error; +end $$ + +--error ER_SIGNAL_EXCEPTION +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Severe error, no subclass + DECLARE error CONDITION FOR SQLSTATE "40000"; + SIGNAL error; +end $$ + +--error ER_SIGNAL_EXCEPTION +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + # Severe error, with subclass + DECLARE error CONDITION FOR SQLSTATE "40001"; + SIGNAL error; +end $$ + +--error ER_SIGNAL_EXCEPTION +call test_signal() $$ +drop procedure test_signal $$ + +--echo # +--echo # Test the scope of condition +--echo # + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '99999'; + begin + DECLARE foo CONDITION FOR 8888; + end; + SIGNAL foo SET MYSQL_ERRNO=9999; /* outer */ +end $$ + +--error 9999 +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR 9999; + begin + DECLARE foo CONDITION FOR SQLSTATE '88888'; + SIGNAL foo SET MYSQL_ERRNO=8888; /* inner */ + end; +end $$ + +--error 8888 +call test_signal() $$ +drop procedure test_signal $$ + +--echo # +--echo # Test SET MYSQL_ERRNO +--echo # + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '99999'; + SIGNAL foo SET MYSQL_ERRNO = 1111; +end $$ + +--error 1111 +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01000"; + SIGNAL warn SET MYSQL_ERRNO = 1111; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02000"; + SIGNAL not_found SET MYSQL_ERRNO = 1111; +end $$ + +--error 1111 +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE "55000"; + SIGNAL error SET MYSQL_ERRNO = 1111; +end $$ + +--error 1111 +call test_signal() $$ +drop procedure test_signal $$ + +--echo # +--echo # Test SET MESSAGE_TEXT +--echo # + +--error ER_SIGNAL_EXCEPTION +SIGNAL SQLSTATE '77777' SET MESSAGE_TEXT='' $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '77777'; + SIGNAL foo SET + MESSAGE_TEXT = "", + MYSQL_ERRNO=5678; +end $$ + +--error 5678 +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '99999'; + SIGNAL foo SET + MESSAGE_TEXT = "Something bad happened", + MYSQL_ERRNO=9999; +end $$ + +--error 9999 +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01000"; + SIGNAL warn SET MESSAGE_TEXT = "Something bad happened"; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02000"; + SIGNAL not_found SET MESSAGE_TEXT = "Something bad happened"; +end $$ + +--error ER_SIGNAL_NOT_FOUND +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE "55000"; + SIGNAL error SET MESSAGE_TEXT = "Something bad happened"; +end $$ + +--error ER_SIGNAL_EXCEPTION +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE something CONDITION FOR SQLSTATE "01000"; + SIGNAL something SET MESSAGE_TEXT = _utf8 "This is a UTF8 text"; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE something CONDITION FOR SQLSTATE "01000"; + SIGNAL something SET MESSAGE_TEXT = ""; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01111"; + SIGNAL warn SET MESSAGE_TEXT = "á a"; +end $$ + +call test_signal() $$ +show warnings $$ +drop procedure test_signal $$ + +--echo # +--echo # Test SET complex expressions +--echo # + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + MYSQL_ERRNO = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + CLASS_ORIGIN = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + SUBCLASS_ORIGIN = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + CONSTRAINT_CATALOG = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + CONSTRAINT_SCHEMA = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + CONSTRAINT_NAME = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + CATALOG_NAME = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + SCHEMA_NAME = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + TABLE_NAME = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + COLUMN_NAME = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + CURSOR_NAME = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE '99999'; + SIGNAL error SET + MESSAGE_TEXT = NULL; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE something CONDITION FOR SQLSTATE '99999'; + DECLARE message_text VARCHAR(64) DEFAULT "Local string variable"; + DECLARE sqlcode INTEGER DEFAULT 1234; + + SIGNAL something SET + MESSAGE_TEXT = message_text, + MYSQL_ERRNO = sqlcode; +end $$ + +--error 1234 +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal(message_text VARCHAR(64), sqlcode INTEGER) +begin + DECLARE something CONDITION FOR SQLSTATE "12345"; + + SIGNAL something SET + MESSAGE_TEXT = message_text, + MYSQL_ERRNO = sqlcode; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal("Parameter string", NULL) $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal(NULL, 1234) $$ + +--error 5678 +call test_signal("Parameter string", 5678) $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE something CONDITION FOR SQLSTATE "AABBB"; + + SIGNAL something SET + MESSAGE_TEXT = @message_text, + MYSQL_ERRNO = @sqlcode; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ + +set @sqlcode= 12 $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ + +set @message_text= "User variable" $$ + +--error 12 +call test_signal() $$ +drop procedure test_signal $$ + +--error ER_PARSE_ERROR +create procedure test_invalid() +begin + DECLARE something CONDITION FOR SQLSTATE "AABBB"; + + SIGNAL something SET + MESSAGE_TEXT = @message_text := 'illegal', + MYSQL_ERRNO = @sqlcode := 1234; +end $$ + +create procedure test_signal() +begin + DECLARE aaa VARCHAR(64); + DECLARE bbb VARCHAR(64); + DECLARE ccc VARCHAR(64); + DECLARE ddd VARCHAR(64); + DECLARE eee VARCHAR(64); + DECLARE fff VARCHAR(64); + DECLARE ggg VARCHAR(64); + DECLARE hhh VARCHAR(64); + DECLARE iii VARCHAR(64); + DECLARE jjj VARCHAR(64); + DECLARE kkk VARCHAR(64); + + DECLARE warn CONDITION FOR SQLSTATE "01234"; + + set aaa= repeat("A", 64); + set bbb= repeat("B", 64); + set ccc= repeat("C", 64); + set ddd= repeat("D", 64); + set eee= repeat("E", 64); + set fff= repeat("F", 64); + set ggg= repeat("G", 64); + set hhh= repeat("H", 64); + set iii= repeat("I", 64); + set jjj= repeat("J", 64); + set kkk= repeat("K", 64); + + SIGNAL warn SET + CLASS_ORIGIN = aaa, + SUBCLASS_ORIGIN = bbb, + CONSTRAINT_CATALOG = ccc, + CONSTRAINT_SCHEMA = ddd, + CONSTRAINT_NAME = eee, + CATALOG_NAME = fff, + SCHEMA_NAME = ggg, + TABLE_NAME = hhh, + COLUMN_NAME = iii, + CURSOR_NAME = jjj, + MESSAGE_TEXT = kkk, + MYSQL_ERRNO = 65535; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01234"; + + SIGNAL warn SET + MYSQL_ERRNO = 999999999999999999999999999999999999999999999999999; +end $$ + +--error ER_WRONG_VALUE_FOR_VAR +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE aaax VARCHAR(65); + DECLARE bbbx VARCHAR(65); + DECLARE cccx VARCHAR(65); + DECLARE dddx VARCHAR(65); + DECLARE eeex VARCHAR(65); + DECLARE fffx VARCHAR(65); + DECLARE gggx VARCHAR(65); + DECLARE hhhx VARCHAR(65); + DECLARE iiix VARCHAR(65); + DECLARE jjjx VARCHAR(65); + DECLARE kkkx VARCHAR(65); + DECLARE lllx VARCHAR(129); + + DECLARE warn CONDITION FOR SQLSTATE "01234"; + + set aaax= concat(repeat("A", 64), "X"); + set bbbx= concat(repeat("B", 64), "X"); + set cccx= concat(repeat("C", 64), "X"); + set dddx= concat(repeat("D", 64), "X"); + set eeex= concat(repeat("E", 64), "X"); + set fffx= concat(repeat("F", 64), "X"); + set gggx= concat(repeat("G", 64), "X"); + set hhhx= concat(repeat("H", 64), "X"); + set iiix= concat(repeat("I", 64), "X"); + set jjjx= concat(repeat("J", 64), "X"); + set kkkx= concat(repeat("K", 64), "X"); + set lllx= concat(repeat("1", 100), + repeat("2", 20), + repeat("8", 8), + "X"); + + SIGNAL warn SET + CLASS_ORIGIN = aaax, + SUBCLASS_ORIGIN = bbbx, + CONSTRAINT_CATALOG = cccx, + CONSTRAINT_SCHEMA = dddx, + CONSTRAINT_NAME = eeex, + CATALOG_NAME = fffx, + SCHEMA_NAME = gggx, + TABLE_NAME = hhhx, + COLUMN_NAME = iiix, + CURSOR_NAME = jjjx, + MESSAGE_TEXT = lllx, + MYSQL_ERRNO = 10000; +end $$ + +#NOTE: the warning text for ER_TRUNCATED_WRONG_VALUE contains +# value: '%-.128s', so the warning printed truncates the value too, +# which affects MESSAGE_TEXT (the X is missing) + +call test_signal() $$ +drop procedure test_signal $$ + +# Test that HANDLER can catch conditions raised by SIGNAL + +create procedure test_signal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01234"; + DECLARE CONTINUE HANDLER for SQLSTATE "01234" + begin + select "Caught by SQLSTATE"; + end; + + SIGNAL warn SET + MESSAGE_TEXT = "Raising a warning", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01234"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "Caught by number"; + end; + + SIGNAL warn SET + MESSAGE_TEXT = "Raising a warning", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01234"; + DECLARE CONTINUE HANDLER for SQLWARNING + begin + select "Caught by SQLWARNING"; + end; + + SIGNAL warn SET + MESSAGE_TEXT = "Raising a warning", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; + DECLARE CONTINUE HANDLER for SQLSTATE "02ABC" + begin + select "Caught by SQLSTATE"; + end; + + SIGNAL not_found SET + MESSAGE_TEXT = "Raising a not found", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "Caught by number"; + end; + + SIGNAL not_found SET + MESSAGE_TEXT = "Raising a not found", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; + DECLARE CONTINUE HANDLER for NOT FOUND + begin + select "Caught by NOT FOUND"; + end; + + SIGNAL not_found SET + MESSAGE_TEXT = "Raising a not found", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE "55555"; + DECLARE CONTINUE HANDLER for SQLSTATE "55555" + begin + select "Caught by SQLSTATE"; + end; + + SIGNAL error SET + MESSAGE_TEXT = "Raising an error", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE "55555"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "Caught by number"; + end; + + SIGNAL error SET + MESSAGE_TEXT = "Raising an error", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE error CONDITION FOR SQLSTATE "55555"; + DECLARE CONTINUE HANDLER for SQLEXCEPTION + begin + select "Caught by SQLEXCEPTION"; + end; + + SIGNAL error SET + MESSAGE_TEXT = "Raising an error", + MYSQL_ERRNO = 1012; +end $$ + +call test_signal() $$ +drop procedure test_signal $$ + +--echo # +--echo # Test where SIGNAL can be used +--echo # + +create function test_signal_func() returns integer +begin + DECLARE warn CONDITION FOR SQLSTATE "01XXX"; + + SIGNAL warn SET + MESSAGE_TEXT = "This function SIGNAL a warning", + MYSQL_ERRNO = 1012; + + return 5; +end $$ + +select test_signal_func() $$ +drop function test_signal_func $$ + +create function test_signal_func() returns integer +begin + DECLARE not_found CONDITION FOR SQLSTATE "02XXX"; + + SIGNAL not_found SET + MESSAGE_TEXT = "This function SIGNAL not found", + MYSQL_ERRNO = 1012; + + return 5; +end $$ + +--error 1012 +select test_signal_func() $$ +drop function test_signal_func $$ + +create function test_signal_func() returns integer +begin + DECLARE error CONDITION FOR SQLSTATE "50000"; + + SIGNAL error SET + MESSAGE_TEXT = "This function SIGNAL an error", + MYSQL_ERRNO = 1012; + + return 5; +end $$ + +--error 1012 +select test_signal_func() $$ +drop function test_signal_func $$ + +--disable_warnings +drop table if exists t1 $$ +--enable_warnings + +create table t1 (a integer) $$ + +create trigger t1_ai after insert on t1 for each row +begin + DECLARE msg VARCHAR(128); + DECLARE warn CONDITION FOR SQLSTATE "01XXX"; + + set msg= concat("This trigger SIGNAL a warning, a=", NEW.a); + SIGNAL warn SET + MESSAGE_TEXT = msg, + MYSQL_ERRNO = 1012; +end $$ + +insert into t1 values (1), (2) $$ + +drop trigger t1_ai $$ + +create trigger t1_ai after insert on t1 for each row +begin + DECLARE msg VARCHAR(128); + DECLARE not_found CONDITION FOR SQLSTATE "02XXX"; + + set msg= concat("This trigger SIGNAL a not found, a=", NEW.a); + SIGNAL not_found SET + MESSAGE_TEXT = msg, + MYSQL_ERRNO = 1012; +end $$ + +--error 1012 +insert into t1 values (3), (4) $$ + +drop trigger t1_ai $$ + +create trigger t1_ai after insert on t1 for each row +begin + DECLARE msg VARCHAR(128); + DECLARE error CONDITION FOR SQLSTATE "03XXX"; + + set msg= concat("This trigger SIGNAL an error, a=", NEW.a); + SIGNAL error SET + MESSAGE_TEXT = msg, + MYSQL_ERRNO = 1012; +end $$ + +--error 1012 +insert into t1 values (5), (6) $$ + +drop table t1 $$ + +create table t1 (errno integer, msg varchar(128)) $$ + +create trigger t1_ai after insert on t1 for each row +begin + DECLARE warn CONDITION FOR SQLSTATE "01XXX"; + + SIGNAL warn SET + MESSAGE_TEXT = NEW.msg, + MYSQL_ERRNO = NEW.errno; +end $$ + +insert into t1 set errno=1012, msg='Warning message 1 in trigger' $$ +insert into t1 set errno=1013, msg='Warning message 2 in trigger' $$ + +drop table t1 $$ + +--disable_warnings +drop table if exists t1 $$ +drop procedure if exists p1 $$ +drop function if exists f1 $$ +--enable_warnings + +create table t1 (s1 int) $$ +insert into t1 values (1) $$ + +create procedure p1() +begin + declare a int; + declare c cursor for select f1() from t1; + declare continue handler for sqlstate '03000' + select "caught 03000"; + declare continue handler for 1326 + select "caught cursor is not open"; + + select "Before open"; + open c; + select "Before fetch"; + fetch c into a; + select "Before close"; + close c; +end $$ + +create function f1() returns int +begin + signal sqlstate '03000'; + return 5; +end $$ + +## FIXME : MEMORY plugin warning, valgrind leak, bug#36518 +## call p1() $$ + +drop table t1 $$ +drop procedure p1 $$ +drop function f1 $$ + +--echo # +--echo # Test the RESIGNAL runtime +--echo # + +# 6 tests: +# {Signaled warning, Signaled Not Found, Signaled Error, +# warning, not found, error} --> RESIGNAL + +create procedure test_resignal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01234"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL; + select "after RESIGNAL"; + end; + + SIGNAL warn SET + MESSAGE_TEXT = "Raising a warning", + MYSQL_ERRNO = 1012; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02222"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL; + select "after RESIGNAL"; + end; + + SIGNAL not_found SET + MESSAGE_TEXT = "Raising a not found", + MYSQL_ERRNO = 1012; +end $$ + +--error 1012 +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE error CONDITION FOR SQLSTATE "55555"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL; + select "after RESIGNAL"; + end; + + SIGNAL error SET + MESSAGE_TEXT = "Raising an error", + MYSQL_ERRNO = 1012; +end $$ + +--error 1012 +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlwarning + begin + select "before RESIGNAL"; + RESIGNAL; + select "after RESIGNAL"; + end; + + insert into t_warn set a= 9999999999999999; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE x integer; + DECLARE c cursor for select * from t_cursor; + DECLARE CONTINUE HANDLER for not found + begin + select "before RESIGNAL"; + RESIGNAL; + select "after RESIGNAL"; + end; + + open c; + fetch c into x; + close c; +end $$ + +--error ER_SP_FETCH_NO_DATA +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlexception + begin + select "before RESIGNAL"; + RESIGNAL; + select "after RESIGNAL"; + end; + + drop table no_such_table; +end $$ + +--error ER_BAD_TABLE_ERROR +call test_resignal() $$ +drop procedure test_resignal $$ + +# 6 tests: +# {Signaled warning, Signaled Not Found, Signaled Error, +# warning, not found, error} --> RESIGNAL SET ... + +create procedure test_resignal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01234"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SET + MESSAGE_TEXT = "RESIGNAL of a warning", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL warn SET + MESSAGE_TEXT = "Raising a warning", + MYSQL_ERRNO = 1012; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02111"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SET + MESSAGE_TEXT = "RESIGNAL of a not found", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL not_found SET + MESSAGE_TEXT = "Raising a not found", + MYSQL_ERRNO = 1012; +end $$ + +--error 5555 +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE error CONDITION FOR SQLSTATE "33333"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SET + MESSAGE_TEXT = "RESIGNAL of an error", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL error SET + MESSAGE_TEXT = "Raising an error", + MYSQL_ERRNO = 1012; +end $$ + +--error 5555 +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlwarning + begin + select "before RESIGNAL"; + RESIGNAL SET + MESSAGE_TEXT = "RESIGNAL of a warning", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + insert into t_warn set a= 9999999999999999; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE x integer; + DECLARE c cursor for select * from t_cursor; + DECLARE CONTINUE HANDLER for not found + begin + select "before RESIGNAL"; + RESIGNAL SET + MESSAGE_TEXT = "RESIGNAL of not found", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + open c; + fetch c into x; + close c; +end $$ + +--error 5555 +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlexception + begin + select "before RESIGNAL"; + RESIGNAL SET + MESSAGE_TEXT = "RESIGNAL of an error", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + drop table no_such_table; +end $$ + +--error 5555 +call test_resignal() $$ +drop procedure test_resignal $$ + +######################################################### + +# 3 tests: +# {Signaled warning} +# --> RESIGNAL SQLSTATE {warning, not found, error} SET ... + +create procedure test_resignal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01111"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "01222" SET + MESSAGE_TEXT = "RESIGNAL to warning", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL warn SET + MESSAGE_TEXT = "Raising a warning", + MYSQL_ERRNO = 1012; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01111"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "02222" SET + MESSAGE_TEXT = "RESIGNAL to not found", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL warn SET + MESSAGE_TEXT = "Raising a warning", + MYSQL_ERRNO = 1012; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE warn CONDITION FOR SQLSTATE "01111"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "33333" SET + MESSAGE_TEXT = "RESIGNAL to error", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL warn SET + MESSAGE_TEXT = "Raising a warning", + MYSQL_ERRNO = 1012; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +# 3 tests: +# {Signaled not found} +# --> RESIGNAL SQLSTATE {warning, not found, error} SET ... + +create procedure test_resignal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "01222" SET + MESSAGE_TEXT = "RESIGNAL to warning", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL not_found SET + MESSAGE_TEXT = "Raising a not found", + MYSQL_ERRNO = 1012; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "02222" SET + MESSAGE_TEXT = "RESIGNAL to not found", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL not_found SET + MESSAGE_TEXT = "Raising a not found", + MYSQL_ERRNO = 1012; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE not_found CONDITION FOR SQLSTATE "02ABC"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "33333" SET + MESSAGE_TEXT = "RESIGNAL to error", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL not_found SET + MESSAGE_TEXT = "Raising a not found", + MYSQL_ERRNO = 1012; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +# 3 tests: +# {Signaled error} +# --> RESIGNAL SQLSTATE {warning, not found, error} SET ... + +create procedure test_resignal() +begin + DECLARE error CONDITION FOR SQLSTATE "AAAAA"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "01222" SET + MESSAGE_TEXT = "RESIGNAL to warning", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL error SET + MESSAGE_TEXT = "Raising an error", + MYSQL_ERRNO = 1012; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE error CONDITION FOR SQLSTATE "AAAAA"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "02222" SET + MESSAGE_TEXT = "RESIGNAL to not found", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL error SET + MESSAGE_TEXT = "Raising an error", + MYSQL_ERRNO = 1012; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE error CONDITION FOR SQLSTATE "AAAAA"; + DECLARE CONTINUE HANDLER for 1012 + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "33333" SET + MESSAGE_TEXT = "RESIGNAL to error", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + SIGNAL error SET + MESSAGE_TEXT = "Raising an error", + MYSQL_ERRNO = 1012; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +# 3 tests: +# {warning} +# --> RESIGNAL SQLSTATE {warning, not found, error} SET ... + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlwarning + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "01111" SET + MESSAGE_TEXT = "RESIGNAL to a warning", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + insert into t_warn set a= 9999999999999999; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlwarning + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "02444" SET + MESSAGE_TEXT = "RESIGNAL to a not found", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + insert into t_warn set a= 9999999999999999; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlwarning + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "44444" SET + MESSAGE_TEXT = "RESIGNAL to an error", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + insert into t_warn set a= 9999999999999999; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +# 3 tests: +# {not found} +# --> RESIGNAL SQLSTATE {warning, not found, error} SET ... + +create procedure test_resignal() +begin + DECLARE x integer; + DECLARE c cursor for select * from t_cursor; + DECLARE CONTINUE HANDLER for not found + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "01111" SET + MESSAGE_TEXT = "RESIGNAL to a warning", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + open c; + fetch c into x; + close c; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE x integer; + DECLARE c cursor for select * from t_cursor; + DECLARE CONTINUE HANDLER for not found + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "02444" SET + MESSAGE_TEXT = "RESIGNAL to a not found", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + open c; + fetch c into x; + close c; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE x integer; + DECLARE c cursor for select * from t_cursor; + DECLARE CONTINUE HANDLER for not found + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "44444" SET + MESSAGE_TEXT = "RESIGNAL to an error", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + open c; + fetch c into x; + close c; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +# 3 tests: +# {error} +# --> RESIGNAL SQLSTATE {warning, not found, error} SET ... + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlexception + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "01111" SET + MESSAGE_TEXT = "RESIGNAL to a warning", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + drop table no_such_table; +end $$ + +call test_resignal() $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlexception + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "02444" SET + MESSAGE_TEXT = "RESIGNAL to a not found", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + drop table no_such_table; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +create procedure test_resignal() +begin + DECLARE CONTINUE HANDLER for sqlexception + begin + select "before RESIGNAL"; + RESIGNAL SQLSTATE "44444" SET + MESSAGE_TEXT = "RESIGNAL to an error", + MYSQL_ERRNO = 5555 ; + select "after RESIGNAL"; + end; + + drop table no_such_table; +end $$ + +--error 5555 +call test_resignal() $$ +show warnings $$ +drop procedure test_resignal $$ + +--echo # +--echo # More complex cases +--echo # + +--disable_warnings +drop procedure if exists peter_p1 $$ +drop procedure if exists peter_p2 $$ +--enable_warnings + +CREATE PROCEDURE peter_p1 () +BEGIN + DECLARE x CONDITION FOR 1231; + DECLARE EXIT HANDLER FOR x + BEGIN + SELECT '2'; + RESIGNAL SET MYSQL_ERRNO = 9999; + END; + + BEGIN + DECLARE EXIT HANDLER FOR x + BEGIN + SELECT '1'; + RESIGNAL SET SCHEMA_NAME = 'test'; + END; + SET @@sql_mode=NULL; + END; +END +$$ + +CREATE PROCEDURE peter_p2 () +BEGIN + DECLARE x CONDITION for 9999; + DECLARE EXIT HANDLER FOR x + BEGIN + SELECT '3'; + RESIGNAL SET MESSAGE_TEXT = 'Hi, I am a useless error message'; + END; + CALL peter_p1(); +END +$$ + +# +# Here, RESIGNAL only modifies the condition caught, +# so there is only 1 condition at the end +# The final SQLSTATE is 42000 (it comes from the error 1231), +# since the condition attributes are preserved. +# +--error 9999 +CALL peter_p2() $$ +show warnings $$ + +drop procedure peter_p1 $$ +drop procedure peter_p2 $$ + +CREATE PROCEDURE peter_p1 () +BEGIN + DECLARE x CONDITION FOR SQLSTATE '42000'; + DECLARE EXIT HANDLER FOR x + BEGIN + SELECT '2'; + RESIGNAL x SET MYSQL_ERRNO = 9999; + END; + + BEGIN + DECLARE EXIT HANDLER FOR x + BEGIN + SELECT '1'; + RESIGNAL x SET + SCHEMA_NAME = 'test', + MYSQL_ERRNO= 1231; + END; + /* Raises ER_WRONG_VALUE_FOR_VAR : 1231, SQLSTATE 42000 */ + SET @@sql_mode=NULL; + END; +END +$$ + +CREATE PROCEDURE peter_p2 () +BEGIN + DECLARE x CONDITION for SQLSTATE '42000'; + DECLARE EXIT HANDLER FOR x + BEGIN + SELECT '3'; + RESIGNAL x SET + MESSAGE_TEXT = 'Hi, I am a useless error message', + MYSQL_ERRNO = 9999; + END; + CALL peter_p1(); +END +$$ + +# +# Here, "RESIGNAL " create a new condition in the diagnostics +# area, so that there are 4 conditions at the end. +# +--error 9999 +CALL peter_p2() $$ +show warnings $$ + +drop procedure peter_p1 $$ +drop procedure peter_p2 $$ + +# +# Test the value of MESSAGE_TEXT in RESIGNAL when no SET MESSAGE_TEXT clause +# is provided (the expected result is the text from the SIGNALed condition) +# + +drop procedure if exists peter_p3 $$ + +create procedure peter_p3() +begin + declare continue handler for sqlexception + resignal sqlstate '99002' set mysql_errno = 2; + + signal sqlstate '99001' set mysql_errno = 1, message_text = "Original"; +end $$ + +--error 2 +call peter_p3() $$ + +# Expecting 2 conditions, both with the text "Original" +show warnings $$ + +drop procedure peter_p3 $$ + +delimiter ;$$ + +drop table t_warn; +drop table t_cursor; + +--echo # +--echo # Miscelaneous test cases +--echo # + +delimiter $$; + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = 0x12; /* 18 */ +end $$ + +-- error 18 +call test_signal $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = 0b00010010; /* 18 */ +end $$ + +-- error 18 +call test_signal $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = '65'; /* 65 */ +end $$ + +-- error 65 +call test_signal $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = 'A'; /* illegal */ +end $$ + +-- error ER_WRONG_VALUE_FOR_VAR +call test_signal $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = "65"; /* 65 */ +end $$ + +-- error 65 +call test_signal $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = "A"; /* illegal */ +end $$ + +-- error ER_WRONG_VALUE_FOR_VAR +call test_signal $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = `65`; /* illegal */ +end $$ + +-- error ER_BAD_FIELD_ERROR +call test_signal $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = `A`; /* illegal */ +end $$ + +-- error ER_BAD_FIELD_ERROR +call test_signal $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = 3.141592; /* 3 */ +end $$ + +-- error 3 +call test_signal $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = 1000, + MESSAGE_TEXT= 0x41; /* A */ +end $$ + +-- error 1000 +call test_signal $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = 1000, + MESSAGE_TEXT= 0b01000001; /* A */ +end $$ + +-- error 1000 +call test_signal $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = 1000, + MESSAGE_TEXT = "Hello"; +end $$ + +-- error 1000 +call test_signal $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = 1000, + MESSAGE_TEXT = 'Hello'; +end $$ + +-- error 1000 +call test_signal $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = 1000, + MESSAGE_TEXT = `Hello`; +end $$ + +-- error ER_BAD_FIELD_ERROR +call test_signal $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + SIGNAL foo SET MYSQL_ERRNO = 1000, + MESSAGE_TEXT = 65.4321; +end $$ + +-- error 1000 +call test_signal $$ +drop procedure test_signal $$ + +-- error ER_PARSE_ERROR +create procedure test_signal() +begin + DECLARE céèçà foo CONDITION FOR SQLSTATE '12345'; + SIGNAL céèçà SET MYSQL_ERRNO = 1000; +end $$ + +-- error ER_PARSE_ERROR +create procedure test_signal() +begin + DECLARE "céèçà" CONDITION FOR SQLSTATE '12345'; + SIGNAL "céèçà" SET MYSQL_ERRNO = 1000; +end $$ + +-- error ER_PARSE_ERROR +create procedure test_signal() +begin + DECLARE 'céèçà' CONDITION FOR SQLSTATE '12345'; + SIGNAL 'céèçà' SET MYSQL_ERRNO = 1000; +end $$ + +create procedure test_signal() +begin + DECLARE `céèçà` CONDITION FOR SQLSTATE '12345'; + SIGNAL `céèçà` SET MYSQL_ERRNO = 1000; +end $$ + +-- error 1000 +call test_signal $$ +drop procedure test_signal $$ + +create procedure test_signal() +begin + SIGNAL SQLSTATE '77777' SET MYSQL_ERRNO = 1000, MESSAGE_TEXT='ÃÂÃÅÄ'; +end $$ + +# Commented until WL#751 is implemented in this version +# -- error 1000 +# call test_signal $$ +drop procedure test_signal $$ + +delimiter ; $$ + diff --git a/mysql-test/t/signal_code.test b/mysql-test/t/signal_code.test new file mode 100644 index 00000000000..d2f65647c81 --- /dev/null +++ b/mysql-test/t/signal_code.test @@ -0,0 +1,57 @@ +# Copyright (C) 2008 Sun Microsystems, Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# Tests for SIGNAL and RESIGNAL + +-- source include/have_debug.inc + +use test; + +--disable_warnings +drop procedure if exists signal_proc; +drop function if exists signal_func; +--enable_warnings + +delimiter $$; + +create procedure signal_proc() +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + + SIGNAL foo; + SIGNAL foo SET MESSAGE_TEXT = "This is an error message"; + RESIGNAL foo; + RESIGNAL foo SET MESSAGE_TEXT = "This is an error message"; +end $$ + +create function signal_func() returns int +begin + DECLARE foo CONDITION FOR SQLSTATE '12345'; + + SIGNAL foo; + SIGNAL foo SET MESSAGE_TEXT = "This is an error message"; + RESIGNAL foo; + RESIGNAL foo SET MESSAGE_TEXT = "This is an error message"; + return 0; +end $$ + +delimiter ;$$ + +show procedure code signal_proc; +drop procedure signal_proc; + +show function code signal_func; +drop function signal_func; + diff --git a/mysql-test/t/signal_demo1.test b/mysql-test/t/signal_demo1.test new file mode 100644 index 00000000000..5de847ba0ba --- /dev/null +++ b/mysql-test/t/signal_demo1.test @@ -0,0 +1,345 @@ +# Copyright (C) 2008 Sun Microsystems, Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# +# Demonstrate how SIGNAL can be used to enforce integrity constraints. +# + +# Naming: +# - PO: Purchase Order +# - AB: Address Book +# - IN: Inventory + +# Simplified schema: +# +# Relation 1: +# PO_ORDER (PK: po_id) 1:1 <---> 0:N (FK: po_id) PO_ORDER_LINE +# +# Relation 2: +# IN_INVENTORY (PK: item_id) 1:1 <---> 0:N (FK: item_id) PO_ORDER_LINE +# +# Relation 3: +# +--> 0:1 (PK: person_id) AB_PHYSICAL_PERSON +# PO_ORDER (FK: cust_id) 1:1 <--| +# +--> 0:1 (PK: company_id) AB_MORAL_PERSON +# This is an 'arc' relationship :) +# + + +--disable_warnings +drop database if exists demo; +--enable_warnings + +create database demo; + +use demo; + +create table ab_physical_person ( + person_id integer, + first_name VARCHAR(50), + middle_initial CHAR, + last_name VARCHAR(50), + primary key (person_id)); + +create table ab_moral_person ( + company_id integer, + name VARCHAR(100), + primary key (company_id)); + +create table in_inventory ( + item_id integer, + descr VARCHAR(50), + stock integer, + primary key (item_id)); + +create table po_order ( + po_id integer auto_increment, + cust_type char, /* arc relationship, see cust_id */ + cust_id integer, /* FK to ab_physical_person *OR* ab_moral_person */ + primary key (po_id)); + +create table po_order_line ( + po_id integer, /* FK to po_order.po_id */ + line_no integer, + item_id integer, /* FK to in_inventory.item_id */ + qty integer); + +delimiter $$; + +--echo # +--echo # Schema integrity enforcement +--echo # + +create procedure check_pk_person(in person_type char, in id integer) +begin + declare x integer; + declare msg varchar(128); + + /* + Test integrity constraints for an 'arc' relationship. + Based on 'person_type', 'id' points to either a + physical person, or a moral person. + */ + case person_type + when 'P' then + begin + select count(person_id) from ab_physical_person + where ab_physical_person.person_id = id + into x; + + if (x != 1) + then + set msg= concat('No such physical person, PK:', id); + SIGNAL SQLSTATE '45000' SET + MESSAGE_TEXT = msg, + MYSQL_ERRNO = 10000; + end if; + end; + + when 'M' then + begin + select count(company_id) from ab_moral_person + where ab_moral_person.company_id = id + into x; + + if (x != 1) + then + set msg= concat('No such moral person, PK:', id); + SIGNAL SQLSTATE '45000' SET + MESSAGE_TEXT = msg, + MYSQL_ERRNO = 10000; + end if; + end; + + else + begin + set msg= concat('No such person type:', person_type); + SIGNAL SQLSTATE '45000' SET + MESSAGE_TEXT = msg, + MYSQL_ERRNO = 20000; + end; + end case; +end +$$ + +create procedure check_pk_inventory(in id integer) +begin + declare x integer; + declare msg varchar(128); + + select count(item_id) from in_inventory + where in_inventory.item_id = id + into x; + + if (x != 1) + then + set msg= concat('Failed integrity constraint, table in_inventory, PK:', + id); + SIGNAL SQLSTATE '45000' SET + MESSAGE_TEXT = msg, + MYSQL_ERRNO = 10000; + end if; +end +$$ + +create procedure check_pk_order(in id integer) +begin + declare x integer; + declare msg varchar(128); + + select count(po_id) from po_order + where po_order.po_id = id + into x; + + if (x != 1) + then + set msg= concat('Failed integrity constraint, table po_order, PK:', id); + SIGNAL SQLSTATE '45000' SET + MESSAGE_TEXT = msg, + MYSQL_ERRNO = 10000; + end if; +end +$$ + +create trigger po_order_bi before insert on po_order +for each row +begin + call check_pk_person(NEW.cust_type, NEW.cust_id); +end +$$ + +create trigger po_order_bu before update on po_order +for each row +begin + call check_pk_person(NEW.cust_type, NEW.cust_id); +end +$$ + +create trigger po_order_line_bi before insert on po_order_line +for each row +begin + call check_pk_order(NEW.po_id); + call check_pk_inventory(NEW.item_id); +end +$$ + +create trigger po_order_line_bu before update on po_order_line +for each row +begin + call check_pk_order(NEW.po_id); + call check_pk_inventory(NEW.item_id); +end +$$ + +--echo # +--echo # Application helpers +--echo # + +create procedure po_create_order( + in p_cust_type char, + in p_cust_id integer, + out id integer) +begin + insert into po_order set cust_type = p_cust_type, cust_id = p_cust_id; + set id = last_insert_id(); +end +$$ + +create procedure po_add_order_line( + in po integer, + in line integer, + in item integer, + in q integer) +begin + insert into po_order_line set + po_id = po, line_no = line, item_id = item, qty = q; +end +$$ + +delimiter ;$$ + +--echo # +--echo # Create sample data +--echo # + +insert into ab_physical_person values + ( 1, "John", "A", "Doe"), + ( 2, "Marry", "B", "Smith") +; + +insert into ab_moral_person values + ( 3, "ACME real estate, INC"), + ( 4, "Local school") +; + +insert into in_inventory values + ( 100, "Table, dinner", 5), + ( 101, "Chair", 20), + ( 200, "Table, coffee", 3), + ( 300, "School table", 25), + ( 301, "School chairs", 50) +; + +select * from ab_physical_person order by person_id; +select * from ab_moral_person order by company_id; +select * from in_inventory order by item_id; + +--echo # +--echo # Entering an order +--echo # + +set @my_po = 0; + +/* John Doe wants 1 table and 4 chairs */ +call po_create_order("P", 1, @my_po); + +call po_add_order_line (@my_po, 1, 100, 1); +call po_add_order_line (@my_po, 2, 101, 4); + +/* Marry Smith wants a coffee table */ +call po_create_order("P", 2, @my_po); + +call po_add_order_line (@my_po, 1, 200, 1); + +--echo # +--echo # Entering bad data in an order +--echo # + +# There is no item 999 in in_inventory +--error 10000 +call po_add_order_line (@my_po, 1, 999, 1); + +--echo # +--echo # Entering bad data in an unknown order +--echo # + +# There is no order 99 in po_order +--error 10000 +call po_add_order_line (99, 1, 100, 1); + +--echo # +--echo # Entering an order for an unknown company +--echo # + +# There is no moral person of id 7 +--error 10000 +call po_create_order("M", 7, @my_po); + +--echo # +--echo # Entering an order for an unknown person type +--echo # + +# There is no person of type X +--error 20000 +call po_create_order("X", 1, @my_po); + +/* The local school wants 10 class tables and 20 chairs */ +call po_create_order("M", 4, @my_po); + +call po_add_order_line (@my_po, 1, 300, 10); +call po_add_order_line (@my_po, 2, 301, 20); + +# Raw data +select * from po_order; +select * from po_order_line; + +# Creative reporting ... + +select po_id as "PO#", + ( case cust_type + when "P" then concat (pp.first_name, + " ", + pp.middle_initial, + " ", + pp.last_name) + when "M" then mp.name + end ) as "Sold to" + from po_order po + left join ab_physical_person pp on po.cust_id = pp.person_id + left join ab_moral_person mp on po.cust_id = company_id +; + +select po_id as "PO#", + ol.line_no as "Line", + ol.item_id as "Item", + inv.descr as "Description", + ol.qty as "Quantity" + from po_order_line ol, in_inventory inv + where inv.item_id = ol.item_id + order by ol.item_id, ol.line_no; + +drop database demo; + + diff --git a/mysql-test/t/signal_demo2.test b/mysql-test/t/signal_demo2.test new file mode 100644 index 00000000000..fc909cb926c --- /dev/null +++ b/mysql-test/t/signal_demo2.test @@ -0,0 +1,207 @@ +# Copyright (C) 2008 Sun Microsystems, Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# +# Demonstrate how RESIGNAL can be used to 'catch' and 're-throw' an error +# + +--disable_warnings +drop database if exists demo; +--enable_warnings + +create database demo; + +use demo; + +delimiter $$; + +create procedure proc_top_a(p1 integer) +begin + ## DECLARE CONTINUE HANDLER for SQLEXCEPTION, NOT FOUND + begin + end; + + select "Starting ..."; + call proc_middle_a(p1); + select "The end"; +end +$$ + +create procedure proc_middle_a(p1 integer) +begin + DECLARE l integer; + # without RESIGNAL: + # Should be: DECLARE EXIT HANDLER for SQLEXCEPTION, NOT FOUND + DECLARE EXIT HANDLER for 1 /* not sure how to handle exceptions */ + begin + select "Oops ... now what ?"; + end; + + select "In prod_middle()"; + + create temporary table t1(a integer, b integer); + select GET_LOCK("user_mutex", 10) into l; + + insert into t1 set a = p1, b = p1; + + call proc_bottom_a(p1); + + select RELEASE_LOCK("user_mutex") into l; + drop temporary table t1; +end +$$ + +create procedure proc_bottom_a(p1 integer) +begin + select "In proc_bottom()"; + + if (p1 = 1) then + begin + select "Doing something that works ..."; + select * from t1; + end; + end if; + + if (p1 = 2) then + begin + select "Doing something that fail (simulate an error) ..."; + drop table no_such_table; + end; + end if; + + if (p1 = 3) then + begin + select "Doing something that *SHOULD* works ..."; + select * from t1; + end; + end if; + +end +$$ + +delimiter ;$$ + +# +# Code without RESIGNAL: +# errors are apparent to the caller, +# but there is no cleanup code, +# so that the environment (get_lock(), temporary table) is polluted ... +# +call proc_top_a(1); + +# Expected +--error ER_BAD_TABLE_ERROR +call proc_top_a(2); + +# Dirty state +--error ER_TABLE_EXISTS_ERROR +call proc_top_a(3); + +# Dirty state +--error ER_TABLE_EXISTS_ERROR +call proc_top_a(1); + +drop temporary table if exists t1; + +delimiter $$; + +create procedure proc_top_b(p1 integer) +begin + select "Starting ..."; + call proc_middle_b(p1); + select "The end"; +end +$$ + +create procedure proc_middle_b(p1 integer) +begin + DECLARE l integer; + DECLARE EXIT HANDLER for SQLEXCEPTION, NOT FOUND + begin + begin + DECLARE CONTINUE HANDLER for SQLEXCEPTION, NOT FOUND + begin + /* Ignore errors from the cleanup code */ + end; + + select "Doing cleanup !"; + select RELEASE_LOCK("user_mutex") into l; + drop temporary table t1; + end; + + RESIGNAL; + end; + + select "In prod_middle()"; + + create temporary table t1(a integer, b integer); + select GET_LOCK("user_mutex", 10) into l; + + insert into t1 set a = p1, b = p1; + + call proc_bottom_b(p1); + + select RELEASE_LOCK("user_mutex") into l; + drop temporary table t1; +end +$$ + +create procedure proc_bottom_b(p1 integer) +begin + select "In proc_bottom()"; + + if (p1 = 1) then + begin + select "Doing something that works ..."; + select * from t1; + end; + end if; + + if (p1 = 2) then + begin + select "Doing something that fail (simulate an error) ..."; + drop table no_such_table; + end; + end if; + + if (p1 = 3) then + begin + select "Doing something that *SHOULD* works ..."; + select * from t1; + end; + end if; + +end +$$ + +delimiter ;$$ + +# +# Code with RESIGNAL: +# errors are apparent to the caller, +# the but cleanup code did get a chance to act ... +# + +call proc_top_b(1); + +--error ER_BAD_TABLE_ERROR +call proc_top_b(2); + +call proc_top_b(3); + +call proc_top_b(1); + +drop database demo; + diff --git a/mysql-test/t/signal_demo3.test b/mysql-test/t/signal_demo3.test new file mode 100644 index 00000000000..347f1b75a79 --- /dev/null +++ b/mysql-test/t/signal_demo3.test @@ -0,0 +1,159 @@ +# Copyright (C) 2008 Sun Microsystems, Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# +# Demonstrate how RESIGNAL can be used to print a stack trace +# + +# Save defaults + +SET @start_global_value = @@global.max_error_count; +SELECT @start_global_value; +SET @start_session_value = @@session.max_error_count; +SELECT @start_session_value; + +--disable_warnings +drop database if exists demo; +--enable_warnings + +create database demo; + +use demo; + +delimiter $$; + +create procedure proc_1() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_1'; + + call proc_2(); +end +$$ + +create procedure proc_2() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_2'; + + call proc_3(); +end +$$ + +create procedure proc_3() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_3'; + + call proc_4(); +end +$$ + +create procedure proc_4() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_4'; + + call proc_5(); +end +$$ + +create procedure proc_5() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_5'; + + call proc_6(); +end +$$ + +create procedure proc_6() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_6'; + + call proc_7(); +end +$$ + +create procedure proc_7() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_7'; + + call proc_8(); +end +$$ + +create procedure proc_8() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_8'; + + call proc_9(); +end +$$ + +create procedure proc_9() +begin + declare exit handler for sqlexception + resignal sqlstate '45000' set message_text='Oops in proc_9'; + + ## Do something that fails, to see how errors are reported + drop table oops_it_is_not_here; +end +$$ + +delimiter ;$$ + +-- error ER_SIGNAL_EXCEPTION +call proc_1(); + +# This is the interesting part: +# the complete call stack from the origin of failure (proc_9) +# to the top level caller (proc_1) is available ... + +show warnings; + +SET @@session.max_error_count = 5; +SELECT @@session.max_error_count; + +-- error ER_SIGNAL_EXCEPTION +call proc_1(); +show warnings; + +SET @@session.max_error_count = 7; +SELECT @@session.max_error_count; + +-- error ER_SIGNAL_EXCEPTION +call proc_1(); +show warnings; + +SET @@session.max_error_count = 9; +SELECT @@session.max_error_count; + +-- error ER_SIGNAL_EXCEPTION +call proc_1(); +show warnings; + +drop database demo; + +# Restore defaults + +SET @@global.max_error_count = @start_global_value; +SELECT @@global.max_error_count; +SET @@session.max_error_count = @start_session_value; +SELECT @@session.max_error_count; + diff --git a/mysql-test/t/signal_sqlmode.test b/mysql-test/t/signal_sqlmode.test new file mode 100644 index 00000000000..860c145a361 --- /dev/null +++ b/mysql-test/t/signal_sqlmode.test @@ -0,0 +1,123 @@ +# Copyright (C) 2008 Sun Microsystems, Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# Tests for SIGNAL, RESIGNAL and GET DIAGNOSTICS + +SET @save_sql_mode=@@sql_mode; + +SET sql_mode=''; + +--disable_warnings +drop procedure if exists p; +drop procedure if exists p2; +drop procedure if exists p3; +--enable_warnings + +delimiter $$; + +create procedure p() +begin + declare utf8_var VARCHAR(128) CHARACTER SET UTF8; + set utf8_var = concat(repeat('A', 128), 'X'); + select length(utf8_var), utf8_var; +end +$$ + +create procedure p2() +begin + declare msg VARCHAR(129) CHARACTER SET UTF8; + set msg = concat(repeat('A', 128), 'X'); + select length(msg), msg; + + signal sqlstate '55555' set message_text = msg; +end +$$ + +create procedure p3() +begin + declare name VARCHAR(65) CHARACTER SET UTF8; + set name = concat(repeat('A', 64), 'X'); + select length(name), name; + + signal sqlstate '55555' set + message_text = 'Message', + table_name = name; +end +$$ +delimiter ;$$ + +call p; + +--error ER_SIGNAL_EXCEPTION +call p2; + +--error ER_SIGNAL_EXCEPTION +call p3; + +drop procedure p; +drop procedure p2; +drop procedure p3; + +SET sql_mode='STRICT_ALL_TABLES'; + +delimiter $$; + +create procedure p() +begin + declare utf8_var VARCHAR(128) CHARACTER SET UTF8; + set utf8_var = concat(repeat('A', 128), 'X'); + select length(utf8_var), utf8_var; +end +$$ + +create procedure p2() +begin + declare msg VARCHAR(129) CHARACTER SET UTF8; + set msg = concat(repeat('A', 128), 'X'); + select length(msg), msg; + + signal sqlstate '55555' set message_text = msg; +end +$$ + +create procedure p3() +begin + declare name VARCHAR(65) CHARACTER SET UTF8; + set name = concat(repeat('A', 64), 'X'); + select length(name), name; + + signal sqlstate '55555' set + message_text = 'Message', + table_name = name; +end +$$ + +delimiter ;$$ + +--error ER_DATA_TOO_LONG +call p; + +--error ER_COND_ITEM_TOO_LONG +call p2; + +--error ER_COND_ITEM_TOO_LONG +call p3; + +drop procedure p; +drop procedure p2; +drop procedure p3; + +SET @@sql_mode=@save_sql_mode; + diff --git a/mysys/my_error.c b/mysys/my_error.c index 2cf704d0089..e407e7706fc 100644 --- a/mysys/my_error.c +++ b/mysys/my_error.c @@ -22,7 +22,6 @@ /* Max length of a error message. Should be kept in sync with MYSQL_ERRMSG_SIZE. */ #define ERRMSGSIZE (512) - /* Define some external variables for error handling */ /* @@ -67,12 +66,9 @@ static struct my_err_head *my_errmsgs_list= &my_errmsgs_globerrs; MyFlags Flags ... variable list - RETURN - What (*error_handler_hook)() returns: - 0 OK */ -int my_error(int nr, myf MyFlags, ...) +void my_error(int nr, myf MyFlags, ...) { const char *format; struct my_err_head *meh_p; @@ -96,7 +92,8 @@ int my_error(int nr, myf MyFlags, ...) (void) my_vsnprintf (ebuff, sizeof(ebuff), format, args); va_end(args); } - DBUG_RETURN((*error_handler_hook)(nr, ebuff, MyFlags)); + (*error_handler_hook)(nr, ebuff, MyFlags); + DBUG_VOID_RETURN; } @@ -111,7 +108,7 @@ int my_error(int nr, myf MyFlags, ...) ... variable list */ -int my_printf_error(uint error, const char *format, myf MyFlags, ...) +void my_printf_error(uint error, const char *format, myf MyFlags, ...) { va_list args; char ebuff[ERRMSGSIZE]; @@ -122,7 +119,8 @@ int my_printf_error(uint error, const char *format, myf MyFlags, ...) va_start(args,MyFlags); (void) my_vsnprintf (ebuff, sizeof(ebuff), format, args); va_end(args); - DBUG_RETURN((*error_handler_hook)(error, ebuff, MyFlags)); + (*error_handler_hook)(error, ebuff, MyFlags); + DBUG_VOID_RETURN; } /* @@ -135,9 +133,9 @@ int my_printf_error(uint error, const char *format, myf MyFlags, ...) MyFlags Flags */ -int my_message(uint error, const char *str, register myf MyFlags) +void my_message(uint error, const char *str, register myf MyFlags) { - return (*error_handler_hook)(error, str, MyFlags); + (*error_handler_hook)(error, str, MyFlags); } diff --git a/mysys/my_messnc.c b/mysys/my_messnc.c index e2431959b7a..e2dee3f6710 100644 --- a/mysys/my_messnc.c +++ b/mysys/my_messnc.c @@ -15,8 +15,8 @@ #include "mysys_priv.h" -int my_message_no_curses(uint error __attribute__((unused)), - const char *str, myf MyFlags) +void my_message_no_curses(uint error __attribute__((unused)), + const char *str, myf MyFlags) { DBUG_ENTER("my_message_no_curses"); DBUG_PRINT("enter",("message: %s",str)); @@ -34,5 +34,5 @@ int my_message_no_curses(uint error __attribute__((unused)), (void)fputs(str,stderr); (void)fputc('\n',stderr); (void)fflush(stderr); - DBUG_RETURN(0); + DBUG_VOID_RETURN; } diff --git a/mysys/my_static.c b/mysys/my_static.c index d0c20da828a..1e7c30992f8 100644 --- a/mysys/my_static.c +++ b/mysys/my_static.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -87,9 +87,9 @@ ulong my_time_to_wait_for_lock=2; /* In seconds */ char * NEAR globerrs[GLOBERRS]; /* my_error_messages is here */ #endif void (*my_abort_hook)(int) = (void(*)(int)) exit; -int (*error_handler_hook)(uint error,const char *str,myf MyFlags)= +void (*error_handler_hook)(uint error,const char *str,myf MyFlags)= my_message_no_curses; -int (*fatal_error_handler_hook)(uint error,const char *str,myf MyFlags)= +void (*fatal_error_handler_hook)(uint error,const char *str,myf MyFlags)= my_message_no_curses; #ifdef __WIN__ diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 6f162f4d84d..592092ba7aa 100755 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -75,6 +75,7 @@ SET (SQL_SOURCE rpl_rli.cc rpl_mi.cc sql_servers.cc sql_connect.cc scheduler.cc sql_profile.cc event_parse_data.cc + sql_signal.cc ${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc ${PROJECT_SOURCE_DIR}/sql/sql_yacc.h ${PROJECT_SOURCE_DIR}/include/mysqld_error.h diff --git a/sql/Makefile.am b/sql/Makefile.am index 5263e62a439..600a6117ebf 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -110,7 +110,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ sql_plugin.h authors.h event_parse_data.h \ event_data_objects.h event_scheduler.h \ sql_partition.h partition_info.h partition_element.h \ - contributors.h sql_servers.h + contributors.h sql_servers.h sql_signal.h mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \ @@ -154,7 +154,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ event_queue.cc event_db_repository.cc events.cc \ sql_plugin.cc sql_binlog.cc \ sql_builtin.cc sql_tablespace.cc partition_info.cc \ - sql_servers.cc event_parse_data.cc + sql_servers.cc event_parse_data.cc sql_signal.cc nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c diff --git a/sql/authors.h b/sql/authors.h index dfe3b143e2f..bb5156742e5 100644 --- a/sql/authors.h +++ b/sql/authors.h @@ -36,6 +36,7 @@ struct show_table_authors_st { struct show_table_authors_st show_table_authors[]= { { "Brian (Krow) Aker", "Seattle, WA, USA", "Architecture, archive, federated, bunch of little stuff :)" }, + { "Marc Alff", "Denver, CO, USA", "Signal, Resignal" }, { "Venu Anuganti", "", "Client/server protocol (4.1)" }, { "David Axmark", "Uppsala, Sweden", "Small stuff long time ago, Monty ripped it out!" }, diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 8c0025f9ed4..daaa6be0520 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -74,7 +74,7 @@ Event_worker_thread::print_warnings(THD *thd, Event_job_data *et) { MYSQL_ERROR *err; DBUG_ENTER("evex_print_warnings"); - if (!thd->warn_list.elements) + if (thd->warning_info->is_empty()) DBUG_VOID_RETURN; char msg_buf[10 * STRING_BUFFER_USUAL_SIZE]; @@ -90,17 +90,18 @@ Event_worker_thread::print_warnings(THD *thd, Event_job_data *et) prefix.append(et->name.str, et->name.length, system_charset_info); prefix.append("] ", 2); - List_iterator_fast it(thd->warn_list); + List_iterator_fast it(thd->warning_info->warn_list()); while ((err= it++)) { String err_msg(msg_buf, sizeof(msg_buf), system_charset_info); /* set it to 0 or we start adding at the end. That's the trick ;) */ err_msg.length(0); err_msg.append(prefix); - err_msg.append(err->msg, strlen(err->msg), system_charset_info); - DBUG_ASSERT(err->level < 3); - (sql_print_message_handlers[err->level])("%*s", err_msg.length(), - err_msg.c_ptr()); + err_msg.append(err->get_message_text(), + err->get_message_octet_length(), system_charset_info); + DBUG_ASSERT(err->get_level() < 3); + (sql_print_message_handlers[err->get_level()])("%*s", err_msg.length(), + err_msg.c_ptr()); } DBUG_VOID_RETURN; } diff --git a/sql/field.cc b/sql/field.cc index 426effa57cd..5ca3b829d69 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1116,7 +1116,7 @@ int Field_num::check_int(CHARSET_INFO *cs, const char *str, int length, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), "integer", tmp.c_ptr(), field_name, - (ulong) table->in_use->row_count); + (ulong) table->in_use->warning_info->current_row_for_warning()); return 1; } /* Test if we have garbage at the end of the given string. */ @@ -2683,11 +2683,11 @@ int Field_new_decimal::store(const char *from, uint length, String from_as_str; from_as_str.copy(from, length, &my_charset_bin); - push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), "decimal", from_as_str.c_ptr(), field_name, - (ulong) table->in_use->row_count); + (ulong) table->in_use->warning_info->current_row_for_warning()); DBUG_RETURN(err); } @@ -2710,7 +2710,7 @@ int Field_new_decimal::store(const char *from, uint length, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), "decimal", from_as_str.c_ptr(), field_name, - (ulong) table->in_use->row_count); + (ulong) table->in_use->warning_info->current_row_for_warning()); my_decimal_set_zero(&decimal_value); break; @@ -5363,7 +5363,7 @@ bool Field_time::get_date(MYSQL_TIME *ltime, uint fuzzydate) push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, ER(ER_WARN_DATA_OUT_OF_RANGE), field_name, - thd->row_count); + thd->warning_info->current_row_for_warning()); return 1; } tmp=(long) sint3korr(ptr); @@ -6357,21 +6357,20 @@ check_string_copy_error(Field_str *field, { const char *pos; char tmp[32]; - + THD *thd= field->table->in_use; + if (!(pos= well_formed_error_pos) && !(pos= cannot_convert_error_pos)) return FALSE; convert_to_printable(tmp, sizeof(tmp), pos, (end - pos), cs, 6); - push_warning_printf(field->table->in_use, - field->table->in_use->abort_on_warning ? - MYSQL_ERROR::WARN_LEVEL_ERROR : + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, + ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), "string", tmp, field->field_name, - (ulong) field->table->in_use->row_count); + thd->warning_info->current_row_for_warning()); return TRUE; } @@ -6405,7 +6404,7 @@ Field_longstr::report_if_important_data(const char *ptr, const char *end, if (test_if_important_data(field_charset, ptr, end)) { if (table->in_use->abort_on_warning) - set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1); + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1); else set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); return 2; @@ -9035,7 +9034,7 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs) set_rec_bits((1 << bit_len) - 1, bit_ptr, bit_ofs, bit_len); memset(ptr, 0xff, bytes_in_rec); if (table->in_use->really_abort_on_warning()) - set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1); + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1); else set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); return 1; @@ -9446,7 +9445,7 @@ int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs) if (bits) *ptr&= ((1 << bits) - 1); /* set first uchar */ if (table->in_use->really_abort_on_warning()) - set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1); + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1); else set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); return 1; @@ -10321,7 +10320,7 @@ Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code, { thd->cuted_fields+= cuted_increment; push_warning_printf(thd, level, code, ER(code), field_name, - thd->row_count); + thd->warning_info->current_row_for_warning()); return 0; } return level >= MYSQL_ERROR::WARN_LEVEL_WARN; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 264e5649ea9..90194fa00e7 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -265,11 +265,11 @@ static int ndb_to_mysql_error(const NdbError *ndberr) - Used by replication to see if the error was temporary */ if (ndberr->status == NdbError::TemporaryError) - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_GET_TEMPORARY_ERRMSG, ER(ER_GET_TEMPORARY_ERRMSG), ndberr->code, ndberr->message, "NDB"); else - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_GET_ERRMSG, ER(ER_GET_ERRMSG), ndberr->code, ndberr->message, "NDB"); return error; @@ -536,7 +536,7 @@ static void set_ndb_err(THD *thd, const NdbError &err) { char buf[FN_REFLEN]; ndb_error_string(thd_ndb->m_error_code, buf, sizeof(buf)); - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_GET_ERRMSG, ER(ER_GET_ERRMSG), thd_ndb->m_error_code, buf, "NDB"); } @@ -5308,7 +5308,7 @@ int ha_ndbcluster::create(const char *name, { if (create_info->storage_media == HA_SM_MEMORY) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, ER(ER_ILLEGAL_HA_CREATE_OPTION), ndbcluster_hton_name, @@ -5363,7 +5363,7 @@ int ha_ndbcluster::create(const char *name, case ROW_TYPE_FIXED: if (field_type_forces_var_part(field->type())) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, ER(ER_ILLEGAL_HA_CREATE_OPTION), ndbcluster_hton_name, @@ -5703,7 +5703,7 @@ int ha_ndbcluster::create_index(const char *name, KEY *key_info, case ORDERED_INDEX: if (key_info->algorithm == HA_KEY_ALG_HASH) { - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, ER(ER_ILLEGAL_HA_CREATE_OPTION), ndbcluster_hton_name, @@ -9606,11 +9606,11 @@ char* ha_ndbcluster::get_tablespace_name(THD *thd, char* name, uint name_len) } err: if (ndberr.status == NdbError::TemporaryError) - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_GET_TEMPORARY_ERRMSG, ER(ER_GET_TEMPORARY_ERRMSG), ndberr.code, ndberr.message, "NDB"); else - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_GET_ERRMSG, ER(ER_GET_ERRMSG), ndberr.code, ndberr.message, "NDB"); return 0; @@ -9904,7 +9904,7 @@ uint ha_ndbcluster::set_up_partition_info(partition_info *part_info, { if (!current_thd->variables.new_mode) { - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, ER(ER_ILLEGAL_HA_CREATE_OPTION), ndbcluster_hton_name, diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index d9a9738ce72..b9b9e7acbf2 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -272,13 +272,13 @@ static void run_query(THD *thd, char *buf, char *end, Thd_ndb *thd_ndb= get_thd_ndb(thd); for (i= 0; no_print_error[i]; i++) if ((thd_ndb->m_error_code == no_print_error[i]) || - (thd->main_da.sql_errno() == (unsigned) no_print_error[i])) + (thd->stmt_da->sql_errno() == (unsigned) no_print_error[i])) break; if (!no_print_error[i]) sql_print_error("NDB: %s: error %s %d(ndb: %d) %d %d", buf, - thd->main_da.message(), - thd->main_da.sql_errno(), + thd->stmt_da->message(), + thd->stmt_da->sql_errno(), thd_ndb->m_error_code, (int) thd->is_error(), thd->is_slave_error); } @@ -293,7 +293,7 @@ static void run_query(THD *thd, char *buf, char *end, is called from ndbcluster_reset_logs(), which is called from mysql_flush(). */ - thd->main_da.reset_diagnostics_area(); + thd->stmt_da->reset_diagnostics_area(); thd->options= save_thd_options; thd->set_query(save_thd_query, save_thd_query_length); @@ -963,6 +963,21 @@ struct Cluster_schema uint32 any_value; }; +static void print_could_not_discover_error(THD *thd, + const Cluster_schema *schema) +{ + sql_print_error("NDB Binlog: Could not discover table '%s.%s' from " + "binlog schema event '%s' from node %d. " + "my_errno: %d", + schema->db, schema->name, schema->query, + schema->node_id, my_errno); + List_iterator_fast it(thd->warning_info->warn_list()); + MYSQL_ERROR *err; + while ((err= it++)) + sql_print_warning("NDB Binlog: (%d)%s", err->get_sql_errno(), + err->get_message_text()); +} + /* Transfer schema table data into corresponding struct */ @@ -1198,7 +1213,7 @@ ndbcluster_update_slock(THD *thd, } if (ndb_error) - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_GET_ERRMSG, ER(ER_GET_ERRMSG), ndb_error->code, ndb_error->message, @@ -1521,7 +1536,7 @@ err: } end: if (ndb_error) - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_GET_ERRMSG, ER(ER_GET_ERRMSG), ndb_error->code, ndb_error->message, @@ -1971,15 +1986,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb, } else if (ndb_create_table_from_engine(thd, schema->db, schema->name)) { - sql_print_error("NDB Binlog: Could not discover table '%s.%s' from " - "binlog schema event '%s' from node %d. " - "my_errno: %d", - schema->db, schema->name, schema->query, - schema->node_id, my_errno); - List_iterator_fast it(thd->warn_list); - MYSQL_ERROR *err; - while ((err= it++)) - sql_print_warning("NDB Binlog: (%d)%s", err->code, err->msg); + print_could_not_discover_error(thd, schema); } pthread_mutex_unlock(&LOCK_open); log_query= 1; @@ -2262,14 +2269,7 @@ ndb_binlog_thread_handle_schema_event_post_epoch(THD *thd, } else if (ndb_create_table_from_engine(thd, schema->db, schema->name)) { - sql_print_error("NDB Binlog: Could not discover table '%s.%s' from " - "binlog schema event '%s' from node %d. my_errno: %d", - schema->db, schema->name, schema->query, - schema->node_id, my_errno); - List_iterator_fast it(thd->warn_list); - MYSQL_ERROR *err; - while ((err= it++)) - sql_print_warning("NDB Binlog: (%d)%s", err->code, err->msg); + print_could_not_discover_error(thd, schema); } pthread_mutex_unlock(&LOCK_open); } @@ -2344,8 +2344,8 @@ static int open_ndb_binlog_index(THD *thd, TABLE_LIST *tables, sql_print_error("NDB Binlog: Opening ndb_binlog_index: killed"); else sql_print_error("NDB Binlog: Opening ndb_binlog_index: %d, '%s'", - thd->main_da.sql_errno(), - thd->main_da.message()); + thd->stmt_da->sql_errno(), + thd->stmt_da->message()); thd->proc_info= save_proc_info; return -1; } @@ -2741,7 +2741,7 @@ ndbcluster_create_event(Ndb *ndb, const NDBTAB *ndbtab, "with BLOB attribute and no PK is not supported", share->key); if (push_warning) - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, ER(ER_ILLEGAL_HA_CREATE_OPTION), ndbcluster_hton_name, @@ -2785,7 +2785,7 @@ ndbcluster_create_event(Ndb *ndb, const NDBTAB *ndbtab, failed, print a warning */ if (push_warning > 1) - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_GET_ERRMSG, ER(ER_GET_ERRMSG), dict->getNdbError().code, dict->getNdbError().message, "NDB"); @@ -2813,7 +2813,7 @@ ndbcluster_create_event(Ndb *ndb, const NDBTAB *ndbtab, dict->dropEvent(my_event.getName())) { if (push_warning > 1) - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_GET_ERRMSG, ER(ER_GET_ERRMSG), dict->getNdbError().code, dict->getNdbError().message, "NDB"); @@ -2832,7 +2832,7 @@ ndbcluster_create_event(Ndb *ndb, const NDBTAB *ndbtab, if (dict->createEvent(my_event)) { if (push_warning > 1) - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_GET_ERRMSG, ER(ER_GET_ERRMSG), dict->getNdbError().code, dict->getNdbError().message, "NDB"); @@ -2845,7 +2845,7 @@ ndbcluster_create_event(Ndb *ndb, const NDBTAB *ndbtab, DBUG_RETURN(-1); } #ifdef NDB_BINLOG_EXTRA_WARNINGS - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_GET_ERRMSG, ER(ER_GET_ERRMSG), 0, "NDB Binlog: Removed trailing event", "NDB"); @@ -2956,7 +2956,7 @@ ndbcluster_create_event_ops(NDB_SHARE *share, const NDBTAB *ndbtab, { sql_print_error("NDB Binlog: Creating NdbEventOperation failed for" " %s",event_name); - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_GET_ERRMSG, ER(ER_GET_ERRMSG), ndb->getNdbError().code, ndb->getNdbError().message, @@ -3005,7 +3005,7 @@ ndbcluster_create_event_ops(NDB_SHARE *share, const NDBTAB *ndbtab, sql_print_error("NDB Binlog: Creating NdbEventOperation" " blob field %u handles failed (code=%d) for %s", j, op->getNdbError().code, event_name); - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_GET_ERRMSG, ER(ER_GET_ERRMSG), op->getNdbError().code, op->getNdbError().message, @@ -3044,7 +3044,7 @@ ndbcluster_create_event_ops(NDB_SHARE *share, const NDBTAB *ndbtab, retries= 0; if (retries == 0) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_GET_ERRMSG, ER(ER_GET_ERRMSG), op->getNdbError().code, op->getNdbError().message, "NDB"); @@ -3112,7 +3112,7 @@ ndbcluster_handle_drop_table(Ndb *ndb, const char *event_name, if (dict->getNdbError().code != 4710) { /* drop event failed for some reason, issue a warning */ - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_GET_ERRMSG, ER(ER_GET_ERRMSG), dict->getNdbError().code, dict->getNdbError().message, "NDB"); diff --git a/sql/handler.cc b/sql/handler.cc index 0e83d2911f2..c29cb196b60 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1313,7 +1313,7 @@ int ha_rollback_trans(THD *thd, bool all) trans->ha_list= 0; trans->no_2pc=0; if (is_real_trans && thd->transaction_rollback_request) - thd->transaction.xid_state.rm_error= thd->main_da.sql_errno(); + thd->transaction.xid_state.rm_error= thd->stmt_da->sql_errno(); if (all) thd->variables.tx_isolation=thd->session_tx_isolation; } @@ -1914,23 +1914,28 @@ const char *get_canonical_filename(handler *file, const char *path, struct Ha_delete_table_error_handler: public Internal_error_handler { public: - virtual bool handle_error(uint sql_errno, - const char *message, - MYSQL_ERROR::enum_warning_level level, - THD *thd); + virtual bool handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl); char buff[MYSQL_ERRMSG_SIZE]; }; bool Ha_delete_table_error_handler:: -handle_error(uint sql_errno, - const char *message, - MYSQL_ERROR::enum_warning_level level, - THD *thd) +handle_condition(THD *, + uint, + const char*, + MYSQL_ERROR::enum_warning_level, + const char* msg, + MYSQL_ERROR ** cond_hdl) { + *cond_hdl= NULL; /* Grab the error message */ - strmake(buff, message, sizeof(buff)-1); + strmake(buff, msg, sizeof(buff)-1); return TRUE; } @@ -1989,7 +1994,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, XXX: should we convert *all* errors to warnings here? What if the error is fatal? */ - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, error, ha_delete_table_error_handler.buff); } delete file; diff --git a/sql/item.cc b/sql/item.cc index 9551c5feaff..6a92016e1ec 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4785,7 +4785,6 @@ String *Item::check_well_formed_result(String *str, bool send_error) { THD *thd= current_thd; char hexbuf[7]; - enum MYSQL_ERROR::enum_warning_level level; uint diff= str->length() - wlen; set_if_smaller(diff, 3); octet2hex(hexbuf, str->ptr() + wlen, diff); @@ -4798,16 +4797,14 @@ String *Item::check_well_formed_result(String *str, bool send_error) if ((thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))) { - level= MYSQL_ERROR::WARN_LEVEL_ERROR; null_value= 1; str= 0; } else { - level= MYSQL_ERROR::WARN_LEVEL_WARN; str->length(wlen); } - push_warning_printf(thd, level, ER_INVALID_CHARACTER_STRING, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_INVALID_CHARACTER_STRING, ER(ER_INVALID_CHARACTER_STRING), cs->csname, hexbuf); } return str; diff --git a/sql/item_func.cc b/sql/item_func.cc index 6abc78371db..5d91c8ab97c 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -599,7 +599,7 @@ void Item_func::signal_divide_by_null() { THD *thd= current_thd; if (thd->variables.sql_mode & MODE_ERROR_FOR_DIVISION_BY_ZERO) - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DIVISION_BY_ZERO, + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_DIVISION_BY_ZERO, ER(ER_DIVISION_BY_ZERO)); null_value= 1; } @@ -1054,7 +1054,7 @@ my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec) return dec; err: - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, ER(ER_WARN_DATA_OUT_OF_RANGE), name, 1); @@ -3670,7 +3670,7 @@ longlong Item_func_benchmark::val_int() { char buff[22]; llstr(((longlong) loop_count), buff); - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE), "count", buff, "benchmark"); } @@ -5814,12 +5814,12 @@ Item_func_sp::func_name() const } -int my_missing_function_error(const LEX_STRING &token, const char *func_name) +void my_missing_function_error(const LEX_STRING &token, const char *func_name) { if (token.length && is_lex_native_function (&token)) - return my_error(ER_FUNC_INEXISTENT_NAME_COLLISION, MYF(0), func_name); + my_error(ER_FUNC_INEXISTENT_NAME_COLLISION, MYF(0), func_name); else - return my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", func_name); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", func_name); } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index be94f19f597..25c9539c4a5 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -528,11 +528,11 @@ String *Item_func_des_encrypt::val_str(String *str) return &tmp_value; error: - push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN, code, ER(code), "des_encrypt"); #else - push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN, ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED), "des_encrypt","--with-openssl"); #endif /* HAVE_OPENSSL */ @@ -605,12 +605,12 @@ String *Item_func_des_decrypt::val_str(String *str) return &tmp_value; error: - push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN, code, ER(code), "des_decrypt"); wrong_key: #else - push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN, ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED), "des_decrypt","--with-openssl"); #endif /* HAVE_OPENSSL */ @@ -3232,7 +3232,7 @@ longlong Item_func_uncompressed_length::val_int() */ if (res->length() <= 4) { - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ZLIB_Z_DATA_ERROR, ER(ER_ZLIB_Z_DATA_ERROR)); null_value= 1; @@ -3309,7 +3309,7 @@ String *Item_func_compress::val_str(String *str) (const Bytef*)res->ptr(), res->length())) != Z_OK) { code= err==Z_MEM_ERROR ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_BUF_ERROR; - push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,code,ER(code)); + push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,code,ER(code)); null_value= 1; return 0; } @@ -3347,7 +3347,7 @@ String *Item_func_uncompress::val_str(String *str) /* If length is less than 4 bytes, data is corrupt */ if (res->length() <= 4) { - push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN, ER_ZLIB_Z_DATA_ERROR, ER(ER_ZLIB_Z_DATA_ERROR)); goto err; @@ -3357,7 +3357,7 @@ String *Item_func_uncompress::val_str(String *str) new_size= uint4korr(res->ptr()) & 0x3FFFFFFF; if (new_size > current_thd->variables.max_allowed_packet) { - push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN, ER_TOO_BIG_FOR_UNCOMPRESS, ER(ER_TOO_BIG_FOR_UNCOMPRESS), current_thd->variables.max_allowed_packet); @@ -3375,7 +3375,7 @@ String *Item_func_uncompress::val_str(String *str) code= ((err == Z_BUF_ERROR) ? ER_ZLIB_Z_BUF_ERROR : ((err == Z_MEM_ERROR) ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_DATA_ERROR)); - push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,code,ER(code)); + push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN,code,ER(code)); err: null_value= 1; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 08a48c6ce2f..ceb553f1c8a 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3102,6 +3102,8 @@ int dump_leaf_key(uchar* key, element_count count __attribute__((unused)), result->append(*res); } + item->row_count++; + /* stop if length of result more than max_length */ if (result->length() > item->max_length) { @@ -3120,8 +3122,11 @@ int dump_leaf_key(uchar* key, element_count count __attribute__((unused)), result->length(), &well_formed_error); result->length(old_length + add_length); - item->count_cut_values++; item->warning_for_row= TRUE; + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_CUT_VALUE_GROUP_CONCAT, ER(ER_CUT_VALUE_GROUP_CONCAT), + item->row_count); + return 1; } return 0; @@ -3141,12 +3146,12 @@ Item_func_group_concat:: Item_func_group_concat(Name_resolution_context *context_arg, bool distinct_arg, List *select_list, SQL_LIST *order_list, String *separator_arg) - :tmp_table_param(0), warning(0), - separator(separator_arg), tree(0), unique_filter(NULL), table(0), + :tmp_table_param(0), separator(separator_arg), tree(0), + unique_filter(NULL), table(0), order(0), context(context_arg), arg_count_order(order_list ? order_list->elements : 0), arg_count_field(select_list->elements), - count_cut_values(0), + row_count(0), distinct(distinct_arg), warning_for_row(FALSE), force_copy_fields(0), original(0) @@ -3200,7 +3205,6 @@ Item_func_group_concat::Item_func_group_concat(THD *thd, Item_func_group_concat *item) :Item_sum(thd, item), tmp_table_param(item->tmp_table_param), - warning(item->warning), separator(item->separator), tree(item->tree), unique_filter(item->unique_filter), @@ -3209,7 +3213,7 @@ Item_func_group_concat::Item_func_group_concat(THD *thd, context(item->context), arg_count_order(item->arg_count_order), arg_count_field(item->arg_count_field), - count_cut_values(item->count_cut_values), + row_count(item->row_count), distinct(item->distinct), warning_for_row(item->warning_for_row), always_null(item->always_null), @@ -3227,15 +3231,6 @@ void Item_func_group_concat::cleanup() DBUG_ENTER("Item_func_group_concat::cleanup"); Item_sum::cleanup(); - /* Adjust warning message to include total number of cut values */ - if (warning) - { - char warn_buff[MYSQL_ERRMSG_SIZE]; - sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values); - warning->set_msg(current_thd, warn_buff); - warning= 0; - } - /* Free table and tree if they belong to this item (if item have not pointer to original item from which was made copy => it own its objects ) @@ -3259,15 +3254,8 @@ void Item_func_group_concat::cleanup() delete unique_filter; unique_filter= NULL; } - if (warning) - { - char warn_buff[MYSQL_ERRMSG_SIZE]; - sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values); - warning->set_msg(thd, warn_buff); - warning= 0; - } } - DBUG_ASSERT(tree == 0 && warning == 0); + DBUG_ASSERT(tree == 0); } DBUG_VOID_RETURN; } @@ -3556,17 +3544,6 @@ String* Item_func_group_concat::val_str(String* str) /* Tree is used for sorting as in ORDER BY */ tree_walk(tree, (tree_walk_action)&dump_leaf_key, (void*)this, left_root_right); - if (count_cut_values && !warning) - { - /* - ER_CUT_VALUE_GROUP_CONCAT needs an argument, but this gets set in - Item_func_group_concat::cleanup(). - */ - DBUG_ASSERT(table); - warning= push_warning(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_CUT_VALUE_GROUP_CONCAT, - ER(ER_CUT_VALUE_GROUP_CONCAT)); - } return &result; } diff --git a/sql/item_sum.h b/sql/item_sum.h index d991327d847..8a20e2dd165 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -1181,12 +1181,9 @@ public: #endif /* HAVE_DLOPEN */ -class MYSQL_ERROR; - class Item_func_group_concat : public Item_sum { TMP_TABLE_PARAM *tmp_table_param; - MYSQL_ERROR *warning; String result; String *separator; TREE tree_base; @@ -1207,7 +1204,7 @@ class Item_func_group_concat : public Item_sum uint arg_count_order; /** The number of selected items, aka the expr list. */ uint arg_count_field; - uint count_cut_values; + uint row_count; bool distinct; bool warning_for_row; bool always_null; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index d79b0b02998..fe938426863 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -602,7 +602,7 @@ err: { char buff[128]; strmake(buff, val_begin, min(length, sizeof(buff)-1)); - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE), date_time_type, buff, "str_to_date"); } diff --git a/sql/lex.h b/sql/lex.h index 0a85824f6f7..268c77a4f98 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -96,6 +96,7 @@ static SYMBOL symbols[] = { { "CASCADE", SYM(CASCADE)}, { "CASCADED", SYM(CASCADED)}, { "CASE", SYM(CASE_SYM)}, + { "CATALOG_NAME", SYM(CATALOG_NAME_SYM)}, { "CHAIN", SYM(CHAIN_SYM)}, { "CHANGE", SYM(CHANGE)}, { "CHANGED", SYM(CHANGED)}, @@ -105,6 +106,7 @@ static SYMBOL symbols[] = { { "CHECK", SYM(CHECK_SYM)}, { "CHECKSUM", SYM(CHECKSUM_SYM)}, { "CIPHER", SYM(CIPHER_SYM)}, + { "CLASS_ORIGIN", SYM(CLASS_ORIGIN_SYM)}, { "CLIENT", SYM(CLIENT_SYM)}, { "CLOSE", SYM(CLOSE_SYM)}, { "COALESCE", SYM(COALESCE)}, @@ -112,6 +114,7 @@ static SYMBOL symbols[] = { { "COLLATE", SYM(COLLATE_SYM)}, { "COLLATION", SYM(COLLATION_SYM)}, { "COLUMN", SYM(COLUMN_SYM)}, + { "COLUMN_NAME", SYM(COLUMN_NAME_SYM)}, { "COLUMNS", SYM(COLUMNS)}, { "COMMENT", SYM(COMMENT_SYM)}, { "COMMIT", SYM(COMMIT_SYM)}, @@ -124,6 +127,9 @@ static SYMBOL symbols[] = { { "CONNECTION", SYM(CONNECTION_SYM)}, { "CONSISTENT", SYM(CONSISTENT_SYM)}, { "CONSTRAINT", SYM(CONSTRAINT)}, + { "CONSTRAINT_CATALOG", SYM(CONSTRAINT_CATALOG_SYM)}, + { "CONSTRAINT_NAME", SYM(CONSTRAINT_NAME_SYM)}, + { "CONSTRAINT_SCHEMA", SYM(CONSTRAINT_SCHEMA_SYM)}, { "CONTAINS", SYM(CONTAINS_SYM)}, { "CONTEXT", SYM(CONTEXT_SYM)}, { "CONTINUE", SYM(CONTINUE_SYM)}, @@ -138,6 +144,7 @@ static SYMBOL symbols[] = { { "CURRENT_TIMESTAMP", SYM(NOW_SYM)}, { "CURRENT_USER", SYM(CURRENT_USER)}, { "CURSOR", SYM(CURSOR_SYM)}, + { "CURSOR_NAME", SYM(CURSOR_NAME_SYM)}, { "DATA", SYM(DATA_SYM)}, { "DATABASE", SYM(DATABASE)}, { "DATABASES", SYM(DATABASES)}, @@ -334,6 +341,7 @@ static SYMBOL symbols[] = { { "MEDIUMTEXT", SYM(MEDIUMTEXT)}, { "MEMORY", SYM(MEMORY_SYM)}, { "MERGE", SYM(MERGE_SYM)}, + { "MESSAGE_TEXT", SYM(MESSAGE_TEXT_SYM)}, { "MICROSECOND", SYM(MICROSECOND_SYM)}, { "MIDDLEINT", SYM(MEDIUMINT)}, /* For powerbuilder */ { "MIGRATE", SYM(MIGRATE_SYM)}, @@ -350,6 +358,7 @@ static SYMBOL symbols[] = { { "MULTIPOINT", SYM(MULTIPOINT)}, { "MULTIPOLYGON", SYM(MULTIPOLYGON)}, { "MUTEX", SYM(MUTEX_SYM)}, + { "MYSQL_ERRNO", SYM(MYSQL_ERRNO_SYM)}, { "NAME", SYM(NAME_SYM)}, { "NAMES", SYM(NAMES_SYM)}, { "NATIONAL", SYM(NATIONAL_SYM)}, @@ -441,6 +450,7 @@ static SYMBOL symbols[] = { { "REPEAT", SYM(REPEAT_SYM)}, { "REQUIRE", SYM(REQUIRE_SYM)}, { "RESET", SYM(RESET_SYM)}, + { "RESIGNAL", SYM(RESIGNAL_SYM)}, { "RESTORE", SYM(RESTORE_SYM)}, { "RESTRICT", SYM(RESTRICT)}, { "RESUME", SYM(RESUME_SYM)}, @@ -459,6 +469,7 @@ static SYMBOL symbols[] = { { "SAVEPOINT", SYM(SAVEPOINT_SYM)}, { "SCHEDULE", SYM(SCHEDULE_SYM)}, { "SCHEMA", SYM(DATABASE)}, + { "SCHEMA_NAME", SYM(SCHEMA_NAME_SYM)}, { "SCHEMAS", SYM(DATABASES)}, { "SECOND", SYM(SECOND_SYM)}, { "SECOND_MICROSECOND", SYM(SECOND_MICROSECOND_SYM)}, @@ -474,6 +485,7 @@ static SYMBOL symbols[] = { { "SHARE", SYM(SHARE_SYM)}, { "SHOW", SYM(SHOW)}, { "SHUTDOWN", SYM(SHUTDOWN)}, + { "SIGNAL", SYM(SIGNAL_SYM)}, { "SIGNED", SYM(SIGNED_SYM)}, { "SIMPLE", SYM(SIMPLE_SYM)}, { "SLAVE", SYM(SLAVE)}, @@ -515,6 +527,7 @@ static SYMBOL symbols[] = { { "STORAGE", SYM(STORAGE_SYM)}, { "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN)}, { "STRING", SYM(STRING_SYM)}, + { "SUBCLASS_ORIGIN", SYM(SUBCLASS_ORIGIN_SYM)}, { "SUBJECT", SYM(SUBJECT_SYM)}, { "SUBPARTITION", SYM(SUBPARTITION_SYM)}, { "SUBPARTITIONS", SYM(SUBPARTITIONS_SYM)}, @@ -523,6 +536,7 @@ static SYMBOL symbols[] = { { "SWAPS", SYM(SWAPS_SYM)}, { "SWITCHES", SYM(SWITCHES_SYM)}, { "TABLE", SYM(TABLE_SYM)}, + { "TABLE_NAME", SYM(TABLE_NAME_SYM)}, { "TABLES", SYM(TABLES)}, { "TABLESPACE", SYM(TABLESPACE)}, { "TABLE_CHECKSUM", SYM(TABLE_CHECKSUM_SYM)}, diff --git a/sql/log.cc b/sql/log.cc index bb81d0c723e..fd2b686fb50 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -80,23 +80,28 @@ public: virtual ~Silence_log_table_errors() {} - virtual bool handle_error(uint sql_errno, const char *message, - MYSQL_ERROR::enum_warning_level level, - THD *thd); + virtual bool handle_condition(THD *thd, + uint sql_errno, + const char* sql_state, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl); const char *message() const { return m_message; } }; bool -Silence_log_table_errors::handle_error(uint /* sql_errno */, - const char *message_arg, - MYSQL_ERROR::enum_warning_level /* level */, - THD * /* thd */) +Silence_log_table_errors::handle_condition(THD *, + uint, + const char*, + MYSQL_ERROR::enum_warning_level, + const char* msg, + MYSQL_ERROR ** cond_hdl) { - strmake(m_message, message_arg, sizeof(m_message)-1); + *cond_hdl= NULL; + strmake(m_message, msg, sizeof(m_message)-1); return TRUE; } - sql_print_message_func sql_print_message_handlers[3] = { sql_print_information, @@ -1646,7 +1651,7 @@ bool MYSQL_BIN_LOG::check_write_error(THD *thd) if (!thd->is_error()) DBUG_RETURN(checked); - switch (thd->main_da.sql_errno()) + switch (thd->stmt_da->sql_errno()) { case ER_TRANS_CACHE_FULL: case ER_ERROR_ON_WRITE: @@ -2902,7 +2907,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) } else { - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_BINLOG_PURGE_FATAL_ERR, "a problem with deleting %s; " "consider examining correspondence " @@ -2933,7 +2938,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) } else { - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_BINLOG_PURGE_FATAL_ERR, "a problem with deleting %s; " "consider examining correspondence " @@ -3264,7 +3269,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log, */ if (thd) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_BINLOG_PURGE_FATAL_ERR, "a problem with getting info on being purged %s; " "consider examining correspondence " @@ -3310,7 +3315,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log, { if (thd) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_BINLOG_PURGE_FATAL_ERR, "a problem with deleting %s; " "consider examining correspondence " @@ -3409,7 +3414,7 @@ int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time) */ if (thd) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_BINLOG_PURGE_FATAL_ERR, "a problem with getting info on being purged %s; " "consider examining correspondence " @@ -4419,9 +4424,9 @@ int query_error_code(THD *thd, bool not_killed) if (not_killed) { - error= thd->is_error() ? thd->main_da.sql_errno() : 0; + error= thd->is_error() ? thd->stmt_da->sql_errno() : 0; - /* thd->main_da.sql_errno() might be ER_SERVER_SHUTDOWN or + /* thd->stmt_da->sql_errno() might be ER_SERVER_SHUTDOWN or ER_QUERY_INTERRUPTED, So here we need to make sure that error is not set to these errors when specified not_killed by the caller. diff --git a/sql/log_event.cc b/sql/log_event.cc index 375f9cf1859..a19c5929d7d 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -134,7 +134,7 @@ static void inline slave_rows_error_report(enum loglevel level, int ha_error, char buff[MAX_SLAVE_ERRMSG], *slider; const char *buff_end= buff + sizeof(buff); uint len; - List_iterator_fast it(thd->warn_list); + List_iterator_fast it(thd->warning_info->warn_list()); MYSQL_ERROR *err; buff[0]= 0; @@ -142,10 +142,11 @@ static void inline slave_rows_error_report(enum loglevel level, int ha_error, slider += len, err= it++) { len= my_snprintf(slider, buff_end - slider, - " %s, Error_code: %d;", err->msg, err->code); + " %s, Error_code: %d;", err->get_message_text(), + err->get_sql_errno()); } - rli->report(level, thd->is_error()? thd->main_da.sql_errno() : 0, + rli->report(level, thd->is_error()? thd->stmt_da->sql_errno() : 0, "Could not execute %s event on table %s.%s;" "%s handler error %s; " "the event's master log %s, end_log_pos %lu", @@ -353,13 +354,13 @@ inline int ignored_error_code(int err_code) */ int convert_handler_error(int error, THD* thd, TABLE *table) { - uint actual_error= (thd->is_error() ? thd->main_da.sql_errno() : + uint actual_error= (thd->is_error() ? thd->stmt_da->sql_errno() : 0); if (actual_error == 0) { table->file->print_error(error, MYF(0)); - actual_error= (thd->is_error() ? thd->main_da.sql_errno() : + actual_error= (thd->is_error() ? thd->stmt_da->sql_errno() : ER_UNKNOWN_ERROR); if (actual_error == ER_UNKNOWN_ERROR) if (global_system_variables.log_warnings) @@ -3162,7 +3163,7 @@ START SLAVE; . Query: '%s'", expected_error, thd->query); } /* If the query was not ignored, it is printed to the general log */ - if (!thd->is_error() || thd->main_da.sql_errno() != ER_SLAVE_IGNORED_TABLE) + if (!thd->is_error() || thd->stmt_da->sql_errno() != ER_SLAVE_IGNORED_TABLE) general_log_write(thd, COM_QUERY, thd->query, thd->query_length); compare_errors: @@ -3171,7 +3172,7 @@ compare_errors: If we expected a non-zero error code, and we don't get the same error code, and it should be ignored or is related to a concurrency issue. */ - actual_error= thd->is_error() ? thd->main_da.sql_errno() : 0; + actual_error= thd->is_error() ? thd->stmt_da->sql_errno() : 0; DBUG_PRINT("info",("expected_error: %d sql_errno: %d", expected_error, actual_error)); if ((expected_error && expected_error != actual_error && @@ -3186,7 +3187,7 @@ Error on master: '%s' (%d), Error on slave: '%s' (%d). \ Default database: '%s'. Query: '%s'", ER_SAFE(expected_error), expected_error, - actual_error ? thd->main_da.message() : "no error", + actual_error ? thd->stmt_da->message() : "no error", actual_error, print_slave_db_safe(db), query_arg); thd->is_slave_error= 1; @@ -3218,7 +3219,7 @@ Default database: '%s'. Query: '%s'", { rli->report(ERROR_LEVEL, actual_error, "Error '%s' on query. Default database: '%s'. Query: '%s'", - (actual_error ? thd->main_da.message() : + (actual_error ? thd->stmt_da->message() : "unexpected success or fatal error"), print_slave_db_safe(thd->db), query_arg); thd->is_slave_error= 1; @@ -4525,13 +4526,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli, VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query_id = next_query_id(); VOID(pthread_mutex_unlock(&LOCK_thread_count)); - /* - Initing thd->row_count is not necessary in theory as this variable has no - influence in the case of the slave SQL thread (it is used to generate a - "data truncated" warning but which is absorbed and never gets to the - error log); still we init it to avoid a Valgrind message. - */ - mysql_reset_errors(thd, 0); + thd->warning_info->opt_clear_warning_info(thd->query_id); TABLE_LIST tables; bzero((char*) &tables,sizeof(tables)); @@ -4692,8 +4687,8 @@ error: int sql_errno; if (thd->is_error()) { - err= thd->main_da.message(); - sql_errno= thd->main_da.sql_errno(); + err= thd->stmt_da->message(); + sql_errno= thd->stmt_da->sql_errno(); } else { @@ -7256,7 +7251,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) if (simple_open_n_lock_tables(thd, rli->tables_to_lock)) { - uint actual_error= thd->main_da.sql_errno(); + uint actual_error= thd->stmt_da->sql_errno(); if (thd->is_slave_error || thd->is_fatal_error) { /* @@ -7267,7 +7262,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) */ rli->report(ERROR_LEVEL, actual_error, "Error '%s' on opening tables", - (actual_error ? thd->main_da.message() : + (actual_error ? thd->stmt_da->message() : "unexpected success or fatal error")); thd->is_slave_error= 1; } diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 68cd2bf4673..49181bcf543 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -78,7 +78,7 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info if (simple_open_n_lock_tables(thd, rli->tables_to_lock)) { - uint actual_error= thd->main_da.sql_errno(); + uint actual_error= thd->stmt_da->sql_errno(); if (thd->is_slave_error || thd->is_fatal_error) { /* @@ -87,7 +87,7 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info */ rli->report(ERROR_LEVEL, actual_error, "Error '%s' on opening tables", - (actual_error ? thd->main_da.message() : + (actual_error ? thd->stmt_da->message() : "unexpected success or fatal error")); thd->is_slave_error= 1; } @@ -216,10 +216,10 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info break; default: - rli->report(ERROR_LEVEL, thd->main_da.sql_errno(), + rli->report(ERROR_LEVEL, thd->stmt_da->sql_errno(), "Error in %s event: row application failed. %s", ev->get_type_str(), - thd->is_error() ? thd->main_da.message() : ""); + thd->is_error() ? thd->stmt_da->message() : ""); thd->is_slave_error= 1; break; } @@ -245,12 +245,12 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info if (error) { /* error has occured during the transaction */ - rli->report(ERROR_LEVEL, thd->main_da.sql_errno(), + rli->report(ERROR_LEVEL, thd->stmt_da->sql_errno(), "Error in %s event: error during transaction execution " "on table %s.%s. %s", ev->get_type_str(), table->s->db.str, table->s->table_name.str, - thd->is_error() ? thd->main_da.message() : ""); + thd->is_error() ? thd->stmt_da->message() : ""); /* If one day we honour --skip-slave-errors in row-based replication, and diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc index 208ddefb890..16d07526a0f 100644 --- a/sql/my_decimal.cc +++ b/sql/my_decimal.cc @@ -41,17 +41,17 @@ int decimal_operation_results(int result) "", (long)-1); break; case E_DEC_OVERFLOW: - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_TRUNCATED_WRONG_VALUE, ER(ER_TRUNCATED_WRONG_VALUE), "DECIMAL", ""); break; case E_DEC_DIV_ZERO: - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_DIVISION_BY_ZERO, ER(ER_DIVISION_BY_ZERO)); break; case E_DEC_BAD_NUM: - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), "decimal", "", "", (long)-1); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index cd1a31f0fab..71f4619d6b8 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -128,6 +128,10 @@ extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *files_charset_info ; extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *national_charset_info; extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *table_alias_charset; +/** + Character set of the buildin error messages loaded from errmsg.sys. +*/ +extern CHARSET_INFO *error_message_charset_info; enum Derivation { diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5dad29a1ab7..6d0a5adc1ad 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -628,6 +628,7 @@ MY_BITMAP temp_pool; CHARSET_INFO *system_charset_info, *files_charset_info ; CHARSET_INFO *national_charset_info, *table_alias_charset; CHARSET_INFO *character_set_filesystem; +CHARSET_INFO *error_message_charset_info; MY_LOCALE *my_default_lc_time_names; @@ -1808,7 +1809,8 @@ void close_connection(THD *thd, uint errcode, bool lock) if ((vio= thd->net.vio) != 0) { if (errcode) - net_send_error(thd, errcode, ER(errcode)); /* purecov: inspected */ + net_send_error(thd, errcode, + ER(errcode), NULL); /* purecov: inspected */ vio_close(vio); /* vio is freed in delete thd */ } if (lock) @@ -2854,11 +2856,11 @@ static void check_data_home(const char *path) for the client. */ /* ARGSUSED */ -extern "C" int my_message_sql(uint error, const char *str, myf MyFlags); +extern "C" void my_message_sql(uint error, const char *str, myf MyFlags); -int my_message_sql(uint error, const char *str, myf MyFlags) +void my_message_sql(uint error, const char *str, myf MyFlags) { - THD *thd; + THD *thd= current_thd; DBUG_ENTER("my_message_sql"); DBUG_PRINT("error", ("error: %u message: '%s'", error, str)); @@ -2880,70 +2882,18 @@ int my_message_sql(uint error, const char *str, myf MyFlags) error= ER_UNKNOWN_ERROR; } - if ((thd= current_thd)) + if (thd) { - /* - TODO: There are two exceptions mechanism (THD and sp_rcontext), - this could be improved by having a common stack of handlers. - */ - if (thd->handle_error(error, str, - MYSQL_ERROR::WARN_LEVEL_ERROR)) - DBUG_RETURN(0); - - thd->is_slave_error= 1; // needed to catch query errors during replication - - /* - thd->lex->current_select == 0 if lex structure is not inited - (not query command (COM_QUERY)) - */ - if (thd->lex->current_select && - thd->lex->current_select->no_error && !thd->is_fatal_error) - { - DBUG_PRINT("error", - ("Error converted to warning: current_select: no_error %d " - "fatal_error: %d", - (thd->lex->current_select ? - thd->lex->current_select->no_error : 0), - (int) thd->is_fatal_error)); - } - else - { - if (! thd->main_da.is_error()) // Return only first message - { - thd->main_da.set_error_status(thd, error, str); - } - query_cache_abort(&thd->net); - } - /* - If a continue handler is found, the error message will be cleared - by the stored procedures code. - */ - if (thd->spcont && - ! (MyFlags & ME_NO_SP_HANDLER) && - thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd)) - { - /* - Do not push any warnings, a handled error must be completely - silenced. - */ - DBUG_RETURN(0); - } - - if (!thd->no_warnings_for_error && - !(MyFlags & ME_NO_WARNING_FOR_ERROR)) - { - /* - Suppress infinite recursion if there a memory allocation error - inside push_warning. - */ - thd->no_warnings_for_error= TRUE; - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str); - thd->no_warnings_for_error= FALSE; - } + if (MyFlags & ME_FATALERROR) + thd->is_fatal_error= 1; + (void) thd->raise_condition(error, + NULL, + MYSQL_ERROR::WARN_LEVEL_ERROR, + str); } if (!thd || MyFlags & ME_NOREFRESH) sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */ - DBUG_RETURN(0); + DBUG_VOID_RETURN; } @@ -3107,6 +3057,7 @@ SHOW_VAR com_status_vars[]= { {"replace", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE]), SHOW_LONG_STATUS}, {"replace_select", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS}, {"reset", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESET]), SHOW_LONG_STATUS}, + {"resignal", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESIGNAL]), SHOW_LONG_STATUS}, {"restore_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESTORE_TABLE]), SHOW_LONG_STATUS}, {"revoke", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE]), SHOW_LONG_STATUS}, {"revoke_all", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE_ALL]), SHOW_LONG_STATUS}, @@ -3115,6 +3066,7 @@ SHOW_VAR com_status_vars[]= { {"savepoint", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SAVEPOINT]), SHOW_LONG_STATUS}, {"select", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SELECT]), SHOW_LONG_STATUS}, {"set_option", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SET_OPTION]), SHOW_LONG_STATUS}, + {"signal", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SIGNAL]), SHOW_LONG_STATUS}, {"show_authors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_AUTHORS]), SHOW_LONG_STATUS}, {"show_binlog_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]), SHOW_LONG_STATUS}, {"show_binlogs", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOGS]), SHOW_LONG_STATUS}, @@ -4939,7 +4891,7 @@ void create_thread_to_handle_connection(THD *thd) /* Can't use my_error() since store_globals has not been called. */ my_snprintf(error_message_buff, sizeof(error_message_buff), ER(ER_CANT_CREATE_THREAD), error); - net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff); + net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff, NULL); (void) pthread_mutex_lock(&LOCK_thread_count); close_connection(thd,0,0); delete thd; diff --git a/sql/protocol.cc b/sql/protocol.cc index 4f69a0fdb52..54e17ff5c3b 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -28,13 +28,13 @@ #include static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024; +bool net_send_error_packet(THD *, uint, const char *, const char *); /* Declared non-static only because of the embedded library. */ -bool net_send_error_packet(THD *thd, uint sql_errno, const char *err); -bool net_send_ok(THD *, uint, uint, ha_rows, ulonglong, const char *); -bool net_send_eof(THD *thd, uint server_status, uint total_warn_count); +bool net_send_ok(THD *, uint, uint, ulonglong, ulonglong, const char *); +/* Declared non-static only because of the embedded library. */ +bool net_send_eof(THD *thd, uint server_status, uint statement_warn_count); #ifndef EMBEDDED_LIBRARY -static bool write_eof_packet(THD *thd, NET *net, - uint server_status, uint total_warn_count); +static bool write_eof_packet(THD *, NET *, uint, uint); #endif #ifndef EMBEDDED_LIBRARY @@ -80,29 +80,33 @@ bool Protocol_binary::net_store_data(const uchar *from, size_t length) @retval TRUE An error occurred and the message wasn't sent properly */ -bool net_send_error(THD *thd, uint sql_errno, const char *err) +bool net_send_error(THD *thd, uint sql_errno, const char *err, + const char* sqlstate) { DBUG_ENTER("net_send_error"); DBUG_ASSERT(!thd->spcont); DBUG_ASSERT(sql_errno); - DBUG_ASSERT(err && err[0]); + DBUG_ASSERT(err); DBUG_PRINT("enter",("sql_errno: %d err: %s", sql_errno, err)); bool error; + if (sqlstate == NULL) + sqlstate= mysql_errno_to_sqlstate(sql_errno); + /* It's one case when we can push an error even though there is an OK or EOF already. */ - thd->main_da.can_overwrite_status= TRUE; + thd->stmt_da->can_overwrite_status= TRUE; /* Abort multi-result sets */ thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS; - error= net_send_error_packet(thd, sql_errno, err); + error= net_send_error_packet(thd, sql_errno, err, sqlstate); - thd->main_da.can_overwrite_status= FALSE; + thd->stmt_da->can_overwrite_status= FALSE; DBUG_RETURN(error); } @@ -124,7 +128,7 @@ bool net_send_error(THD *thd, uint sql_errno, const char *err) @param thd Thread handler @param server_status The server status - @param total_warn_count Total number of warnings + @param statement_warn_count Total number of warnings @param affected_rows Number of rows changed by statement @param id Auto_increment id for first row (if used) @param message Message to send to the client (Used by mysql_status) @@ -138,8 +142,8 @@ bool net_send_error(THD *thd, uint sql_errno, const char *err) #ifndef EMBEDDED_LIBRARY bool net_send_ok(THD *thd, - uint server_status, uint total_warn_count, - ha_rows affected_rows, ulonglong id, const char *message) + uint server_status, uint statement_warn_count, + ulonglong affected_rows, ulonglong id, const char *message) { NET *net= &thd->net; uchar buff[MYSQL_ERRMSG_SIZE+10],*pos; @@ -162,12 +166,12 @@ net_send_ok(THD *thd, (ulong) affected_rows, (ulong) id, (uint) (server_status & 0xffff), - (uint) total_warn_count)); + (uint) statement_warn_count)); int2store(pos, server_status); pos+=2; /* We can only return up to 65535 warnings in two bytes */ - uint tmp= min(total_warn_count, 65535); + uint tmp= min(statement_warn_count, 65535); int2store(pos, tmp); pos+= 2; } @@ -176,7 +180,7 @@ net_send_ok(THD *thd, int2store(pos, server_status); pos+=2; } - thd->main_da.can_overwrite_status= TRUE; + thd->stmt_da->can_overwrite_status= TRUE; if (message && message[0]) pos= net_store_data(pos, (uchar*) message, strlen(message)); @@ -184,7 +188,7 @@ net_send_ok(THD *thd, if (!error) error= net_flush(net); - thd->main_da.can_overwrite_status= FALSE; + thd->stmt_da->can_overwrite_status= FALSE; DBUG_PRINT("info", ("OK sent, so no more error sending allowed")); DBUG_RETURN(error); @@ -208,7 +212,7 @@ static uchar eof_buff[1]= { (uchar) 254 }; /* Marker for end of fields */ @param thd Thread handler @param server_status The server status - @param total_warn_count Total number of warnings + @param statement_warn_count Total number of warnings @return @retval FALSE The message was successfully sent @@ -216,7 +220,7 @@ static uchar eof_buff[1]= { (uchar) 254 }; /* Marker for end of fields */ */ bool -net_send_eof(THD *thd, uint server_status, uint total_warn_count) +net_send_eof(THD *thd, uint server_status, uint statement_warn_count) { NET *net= &thd->net; bool error= FALSE; @@ -224,11 +228,11 @@ net_send_eof(THD *thd, uint server_status, uint total_warn_count) /* Set to TRUE if no active vio, to work well in case of --init-file */ if (net->vio != 0) { - thd->main_da.can_overwrite_status= TRUE; - error= write_eof_packet(thd, net, server_status, total_warn_count); + thd->stmt_da->can_overwrite_status= TRUE; + error= write_eof_packet(thd, net, server_status, statement_warn_count); if (!error) error= net_flush(net); - thd->main_da.can_overwrite_status= FALSE; + thd->stmt_da->can_overwrite_status= FALSE; DBUG_PRINT("info", ("EOF sent, so no more error sending allowed")); } DBUG_RETURN(error); @@ -242,7 +246,7 @@ net_send_eof(THD *thd, uint server_status, uint total_warn_count) @param thd The thread handler @param net The network handler @param server_status The server status - @param total_warn_count The number of warnings + @param statement_warn_count The number of warnings @return @@ -252,7 +256,7 @@ net_send_eof(THD *thd, uint server_status, uint total_warn_count) static bool write_eof_packet(THD *thd, NET *net, uint server_status, - uint total_warn_count) + uint statement_warn_count) { bool error; if (thd->client_capabilities & CLIENT_PROTOCOL_41) @@ -262,7 +266,7 @@ static bool write_eof_packet(THD *thd, NET *net, Don't send warn count during SP execution, as the warn_list is cleared between substatements, and mysqltest gets confused */ - uint tmp= min(total_warn_count, 65535); + uint tmp= min(statement_warn_count, 65535); buff[0]= 254; int2store(buff+1, tmp); /* @@ -309,7 +313,9 @@ bool send_old_password_request(THD *thd) @retval TRUE An error occurred and the messages wasn't sent properly */ -bool net_send_error_packet(THD *thd, uint sql_errno, const char *err) +bool net_send_error_packet(THD *thd, uint sql_errno, const char *err, + const char* sqlstate) + { NET *net= &thd->net; uint length; @@ -338,7 +344,7 @@ bool net_send_error_packet(THD *thd, uint sql_errno, const char *err) { /* The first # is to make the protocol backward compatible */ buff[2]= '#'; - pos= (uchar*) strmov((char*) buff+3, mysql_errno_to_sqlstate(sql_errno)); + pos= (uchar*) strmov((char*) buff+3, sqlstate); } length= (uint) (strmake((char*) pos, err, MYSQL_ERRMSG_SIZE-1) - (char*) buff); @@ -430,45 +436,45 @@ static uchar *net_store_length_fast(uchar *packet, uint length) void net_end_statement(THD *thd) { - DBUG_ASSERT(! thd->main_da.is_sent); + DBUG_ASSERT(! thd->stmt_da->is_sent); /* Can not be true, but do not take chances in production. */ - if (thd->main_da.is_sent) + if (thd->stmt_da->is_sent) return; bool error= FALSE; - switch (thd->main_da.status()) { + switch (thd->stmt_da->status()) { case Diagnostics_area::DA_ERROR: /* The query failed, send error to log and abort bootstrap. */ error= net_send_error(thd, - thd->main_da.sql_errno(), - thd->main_da.message()); + thd->stmt_da->sql_errno(), + thd->stmt_da->message(), + thd->stmt_da->get_sqlstate()); break; case Diagnostics_area::DA_EOF: error= net_send_eof(thd, - thd->main_da.server_status(), - thd->main_da.total_warn_count()); + thd->stmt_da->server_status(), + thd->stmt_da->statement_warn_count()); break; case Diagnostics_area::DA_OK: error= net_send_ok(thd, - thd->main_da.server_status(), - thd->main_da.total_warn_count(), - thd->main_da.affected_rows(), - thd->main_da.last_insert_id(), - thd->main_da.message()); + thd->stmt_da->server_status(), + thd->stmt_da->statement_warn_count(), + thd->stmt_da->affected_rows(), + thd->stmt_da->last_insert_id(), + thd->stmt_da->message()); break; case Diagnostics_area::DA_DISABLED: break; case Diagnostics_area::DA_EMPTY: default: DBUG_ASSERT(0); - error= net_send_ok(thd, thd->server_status, thd->total_warn_count, - 0, 0, NULL); + error= net_send_ok(thd, thd->server_status, 0, 0, 0, NULL); break; } if (!error) - thd->main_da.is_sent= TRUE; + thd->stmt_da->is_sent= TRUE; } @@ -711,7 +717,8 @@ bool Protocol::send_fields(List *list, uint flags) to show that there is no cursor. Send no warning information, as it will be sent at statement end. */ - write_eof_packet(thd, &thd->net, thd->server_status, thd->total_warn_count); + write_eof_packet(thd, &thd->net, thd->server_status, + thd->warning_info->statement_warn_count()); } DBUG_RETURN(prepare_for_send(list)); diff --git a/sql/protocol.h b/sql/protocol.h index 251ba6fbc33..1e584295028 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -17,6 +17,7 @@ #pragma interface /* gcc class implementation */ #endif +#include "sql_error.h" class i_string; class THD; @@ -173,7 +174,8 @@ public: }; void send_warning(THD *thd, uint sql_errno, const char *err=0); -bool net_send_error(THD *thd, uint sql_errno=0, const char *err=0); +bool net_send_error(THD *thd, uint sql_errno, const char *err, + const char* sqlstate); void net_end_statement(THD *thd); bool send_old_password_request(THD *thd); uchar *net_store_data(uchar *to,const uchar *from, size_t length); diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 582348608de..e470317abef 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -913,7 +913,7 @@ bool load_master_data(THD* thd) goto err; } /* Clear the result of mysql_create_db(). */ - thd->main_da.reset_diagnostics_area(); + thd->stmt_da->reset_diagnostics_area(); if (mysql_select_db(&mysql, db) || mysql_real_query(&mysql, STRING_WITH_LEN("SHOW TABLES")) || diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 18fbae9bb9d..61d3840569f 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -183,7 +183,7 @@ int init_relay_log_info(Relay_log_info* rli, { sql_print_error("Failed to create a new relay log info file (\ file '%s', errno %d)", fname, my_errno); - msg= current_thd->main_da.message(); + msg= current_thd->stmt_da->message(); goto err; } if (init_io_cache(&rli->info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L,0, @@ -191,7 +191,7 @@ file '%s', errno %d)", fname, my_errno); { sql_print_error("Failed to create a cache on relay log info file '%s'", fname); - msg= current_thd->main_da.message(); + msg= current_thd->stmt_da->message(); goto err; } diff --git a/sql/set_var.cc b/sql/set_var.cc index 0b89333ce03..185fc33deb9 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -3132,17 +3132,13 @@ static int check_pseudo_thread_id(THD *thd, set_var *var) static uchar *get_warning_count(THD *thd) { - thd->sys_var_tmp.long_value= - (thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_NOTE] + - thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR] + - thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_WARN]); + thd->sys_var_tmp.long_value= thd->warning_info->warn_count(); return (uchar*) &thd->sys_var_tmp.long_value; } static uchar *get_error_count(THD *thd) { - thd->sys_var_tmp.long_value= - thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR]; + thd->sys_var_tmp.long_value= thd->warning_info->error_count(); return (uchar*) &thd->sys_var_tmp.long_value; } diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 5531ee71620..4c5a4bf120f 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -4879,13 +4879,7 @@ ER_ZLIB_Z_DATA_ERROR por "ZLIB: Dados de entrada está corrupto" spa "ZLIB: Dato de entrada fué corrompido para zlib" ER_CUT_VALUE_GROUP_CONCAT - eng "%d line(s) were cut by GROUP_CONCAT()" - ger "%d Zeile(n) durch GROUP_CONCAT() abgeschnitten" - nla "%d regel(s) door GROUP_CONCAT() ingekort" - por "%d linha(s) foram cortada(s) por GROUP_CONCAT()" - spa "%d línea(s) fue(fueron) cortadas por group_concat()" - swe "%d rad(er) kapades av group_concat()" - ukr "%d line(s) was(were) cut by group_concat()" + eng "Row %u was cut by GROUP_CONCAT()" ER_WARN_TOO_FEW_RECORDS 01000 eng "Row %ld doesn't contain data for all columns" ger "Zeile %ld enthält nicht für alle Felder Daten" @@ -6206,3 +6200,31 @@ ER_TOO_MANY_CONCURRENT_TRXS WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED eng "Non-ASCII separator arguments are not fully supported" + +ER_DUP_SIGNAL_SET 42000 + eng "Duplicate condition information item '%s'" + +# Note that the SQLSTATE is not 01000, it is provided by SIGNAL/RESIGNAL +ER_SIGNAL_WARN 01000 + eng "Unhandled user-defined warning condition" + +# Note that the SQLSTATE is not 02000, it is provided by SIGNAL/RESIGNAL +ER_SIGNAL_NOT_FOUND 02000 + eng "Unhandled user-defined not found condition" + +# Note that the SQLSTATE is not HY000, it is provided by SIGNAL/RESIGNAL +ER_SIGNAL_EXCEPTION HY000 + eng "Unhandled user-defined exception condition" + +ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER 0K000 + eng "RESIGNAL when handler not active" + +ER_SIGNAL_BAD_CONDITION_TYPE + eng "SIGNAL/RESIGNAL can only use a CONDITION defined with SQLSTATE" + +WARN_COND_ITEM_TRUNCATED + eng "Data truncated for condition item '%s'" + +ER_COND_ITEM_TOO_LONG + eng "Data too long for condition item '%s'" + diff --git a/sql/slave.cc b/sql/slave.cc index fac9ee214c5..7ad282c0f24 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1274,7 +1274,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, else { /* Clear the OK result of mysql_rm_table(). */ - thd->main_da.reset_diagnostics_area(); + thd->stmt_da->reset_diagnostics_area(); } } @@ -1297,7 +1297,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, goto err; // mysql_parse took care of the error send thd_proc_info(thd, "Opening master dump table"); - thd->main_da.reset_diagnostics_area(); /* cleanup from CREATE_TABLE */ + thd->stmt_da->reset_diagnostics_area(); /* cleanup from CREATE_TABLE */ /* Note: If this function starts to fail for MERGE tables, change the next two lines to these: @@ -2011,7 +2011,7 @@ static int has_temporary_error(THD *thd) DBUG_ENTER("has_temporary_error"); DBUG_EXECUTE_IF("all_errors_are_temporary_errors", - if (thd->main_da.is_error()) + if (thd->stmt_da->is_error()) { thd->clear_error(); my_error(ER_LOCK_DEADLOCK, MYF(0)); @@ -2030,20 +2030,21 @@ static int has_temporary_error(THD *thd) currently, InnoDB deadlock detected by InnoDB or lock wait timeout (innodb_lock_wait_timeout exceeded */ - if (thd->main_da.sql_errno() == ER_LOCK_DEADLOCK || - thd->main_da.sql_errno() == ER_LOCK_WAIT_TIMEOUT) + if (thd->stmt_da->sql_errno() == ER_LOCK_DEADLOCK || + thd->stmt_da->sql_errno() == ER_LOCK_WAIT_TIMEOUT) DBUG_RETURN(1); #ifdef HAVE_NDB_BINLOG /* currently temporary error set in ndbcluster */ - List_iterator_fast it(thd->warn_list); + List_iterator_fast it(thd->warning_info->warn_list()); MYSQL_ERROR *err; while ((err= it++)) { - DBUG_PRINT("info", ("has warning %d %s", err->code, err->msg)); - switch (err->code) + DBUG_PRINT("info", ("has condition %d %s", err->get_sql_errno(), + err->get_message_text())); + switch (err->get_sql_errno()) { case ER_GET_TEMPORARY_ERRMSG: DBUG_RETURN(1); @@ -2977,9 +2978,9 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME, if (check_temp_dir(rli->slave_patternload_file)) { - rli->report(ERROR_LEVEL, thd->main_da.sql_errno(), + rli->report(ERROR_LEVEL, thd->stmt_da->sql_errno(), "Unable to use slave's temporary directory %s - %s", - slave_load_tmpdir, thd->main_da.message()); + slave_load_tmpdir, thd->stmt_da->message()); goto err; } @@ -2989,7 +2990,7 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME, execute_init_command(thd, &sys_init_slave, &LOCK_sys_init_slave); if (thd->is_slave_error) { - rli->report(ERROR_LEVEL, thd->main_da.sql_errno(), + rli->report(ERROR_LEVEL, thd->stmt_da->sql_errno(), "Slave SQL thread aborted. Can't execute init_slave query"); goto err; } @@ -3033,20 +3034,20 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME, if (thd->is_error()) { - char const *const errmsg= thd->main_da.message(); + char const *const errmsg= thd->stmt_da->message(); DBUG_PRINT("info", - ("thd->main_da.sql_errno()=%d; rli->last_error.number=%d", - thd->main_da.sql_errno(), last_errno)); + ("thd->stmt_da->sql_errno()=%d; rli->last_error.number=%d", + thd->stmt_da->sql_errno(), last_errno)); if (last_errno == 0) { /* This function is reporting an error which was not reported while executing exec_relay_log_event(). */ - rli->report(ERROR_LEVEL, thd->main_da.sql_errno(), errmsg); + rli->report(ERROR_LEVEL, thd->stmt_da->sql_errno(), errmsg); } - else if (last_errno != thd->main_da.sql_errno()) + else if (last_errno != thd->stmt_da->sql_errno()) { /* * An error was reported while executing exec_relay_log_event() @@ -3055,12 +3056,12 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME, * what caused the problem. */ sql_print_error("Slave (additional info): %s Error_code: %d", - errmsg, thd->main_da.sql_errno()); + errmsg, thd->stmt_da->sql_errno()); } } /* Print any warnings issued */ - List_iterator_fast it(thd->warn_list); + List_iterator_fast it(thd->warning_info->warn_list()); MYSQL_ERROR *err; /* Added controlled slave thread cancel for replication @@ -3069,9 +3070,9 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME, bool udf_error = false; while ((err= it++)) { - if (err->code == ER_CANT_OPEN_LIBRARY) + if (err->get_sql_errno() == ER_CANT_OPEN_LIBRARY) udf_error = true; - sql_print_warning("Slave: %s Error_code: %d",err->msg, err->code); + sql_print_warning("Slave: %s Error_code: %d", err->get_message_text(), err->get_sql_errno()); } if (udf_error) sql_print_error("Error loading user-defined library, slave SQL " diff --git a/sql/sp.cc b/sql/sp.cc index 4d840f53e2f..5898e553320 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -522,16 +522,24 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp) 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); + virtual bool handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl); }; bool -Silence_deprecated_warning::handle_error(uint sql_errno, const char *message, - MYSQL_ERROR::enum_warning_level level, - THD *thd) +Silence_deprecated_warning::handle_condition( + THD *, + uint sql_errno, + const char*, + MYSQL_ERROR::enum_warning_level level, + const char*, + MYSQL_ERROR ** cond_hdl) { + *cond_hdl= NULL; if (sql_errno == ER_WARN_DEPRECATED_SYNTAX && level == MYSQL_ERROR::WARN_LEVEL_WARN) return TRUE; @@ -1336,7 +1344,7 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any) &thd->sp_proc_cache, FALSE) != NULL || sp_find_routine(thd, TYPE_ENUM_FUNCTION, name, &thd->sp_func_cache, FALSE) != NULL; - mysql_reset_errors(thd, TRUE); + thd->warning_info->clear_warning_info(thd->query_id); if (sp_object_found) { if (any) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index aed19b76011..908f0997be6 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1083,6 +1083,7 @@ sp_head::execute(THD *thd) Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer; Object_creation_ctx *saved_creation_ctx; + Warning_info *saved_warning_info, warning_info(thd->warning_info->warn_id()); /* Use some extra margin for possible SP recursion and functions */ if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (uchar*)&old_packet)) @@ -1131,6 +1132,11 @@ sp_head::execute(THD *thd) thd->is_slave_error= 0; old_arena= thd->stmt_arena; + /* Push a new warning information area. */ + warning_info.append_warning_info(thd, thd->warning_info); + saved_warning_info= thd->warning_info; + thd->warning_info= &warning_info; + /* Switch query context. This has to be done early as this is sometimes allocated trough sql_alloc @@ -1278,29 +1284,33 @@ sp_head::execute(THD *thd) */ if (ctx) { - uint hf; + uint handler_index; - switch (ctx->found_handler(&hip, &hf)) { + switch (ctx->found_handler(& hip, & handler_index)) { case SP_HANDLER_NONE: break; case SP_HANDLER_CONTINUE: thd->restore_active_arena(&execute_arena, &backup_arena); thd->set_n_backup_active_arena(&execute_arena, &backup_arena); ctx->push_hstack(i->get_cont_dest()); - // Fall through + /* Fall through */ default: + if (ctx->end_partial_result_set) + thd->protocol->end_partial_result_set(thd); ip= hip; err_status= FALSE; ctx->clear_handler(); - ctx->enter_handler(hip); + ctx->enter_handler(hip, handler_index); thd->clear_error(); thd->is_fatal_error= 0; thd->killed= THD::NOT_KILLED; thd->mysys_var->abort= 0; continue; } + + ctx->end_partial_result_set= FALSE; } - } while (!err_status && !thd->killed); + } while (!err_status && !thd->killed && !thd->is_fatal_error); #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) thd->profiling.finish_current_query(); @@ -1334,6 +1344,10 @@ sp_head::execute(THD *thd) thd->stmt_arena= old_arena; state= EXECUTED; + /* Restore the caller's original warning information area. */ + saved_warning_info->merge_with_routine_info(thd, thd->warning_info); + thd->warning_info= saved_warning_info; + done: DBUG_PRINT("info", ("err_status: %d killed: %d is_slave_error: %d report_error: %d", err_status, thd->killed, thd->is_slave_error, @@ -2523,7 +2537,8 @@ void sp_head::optimize() else { if (src != dst) - { // Move the instruction and update prev. jumps + { + /* Move the instruction and update prev. jumps */ sp_instr *ibp; List_iterator_fast li(bp); @@ -2848,7 +2863,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) { res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this); - if (thd->main_da.is_eof()) + if (thd->stmt_da->is_eof()) net_end_statement(thd); query_cache_end_of_result(thd); @@ -2862,7 +2877,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) thd->query_name_consts= 0; if (!thd->is_error()) - thd->main_da.reset_diagnostics_area(); + thd->stmt_da->reset_diagnostics_area(); } DBUG_RETURN(res || thd->is_error()); } @@ -3238,7 +3253,7 @@ sp_instr_hpush_jump::execute(THD *thd, uint *nextp) sp_cond_type_t *p; while ((p= li++)) - thd->spcont->push_handler(p, m_ip+1, m_type, m_frame); + thd->spcont->push_handler(p, m_ip+1, m_type); *nextp= m_dest; DBUG_RETURN(0); diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 302faf3f681..31c307ebe74 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -51,7 +51,8 @@ sp_cond_check(LEX_STRING *sqlstate) (c < 'A' || 'Z' < c)) return FALSE; } - if (strcmp(sqlstate->str, "00000") == 0) + /* SQLSTATE class '00' : completion condition */ + if (strncmp(sqlstate->str, "00", 2) == 0) return FALSE; return TRUE; } diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 3145ba2fea4..75e55880e60 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -71,7 +71,7 @@ typedef struct sp_label typedef struct sp_cond_type { enum { number, state, warning, notfound, exception } type; - char sqlstate[6]; + char sqlstate[SQLSTATE_LENGTH+1]; uint mysqlerr; } sp_cond_type_t; diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 9b237b3e7cc..51b797fe088 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -32,7 +32,8 @@ sp_rcontext::sp_rcontext(sp_pcontext *root_parsing_ctx, Field *return_value_fld, sp_rcontext *prev_runtime_ctx) - :m_root_parsing_ctx(root_parsing_ctx), + :end_partial_result_set(FALSE), + m_root_parsing_ctx(root_parsing_ctx), m_var_table(0), m_var_items(0), m_return_value_fld(return_value_fld), @@ -68,21 +69,28 @@ sp_rcontext::~sp_rcontext() bool sp_rcontext::init(THD *thd) { + uint handler_count= m_root_parsing_ctx->max_handler_index(); + uint i; + in_sub_stmt= thd->in_sub_stmt; if (init_var_table(thd) || init_var_items()) return TRUE; + if (!(m_raised_conditions= new (thd->mem_root) MYSQL_ERROR[handler_count])) + return TRUE; + + for (i= 0; imem_root); + return !(m_handler= - (sp_handler_t*)thd->alloc(m_root_parsing_ctx->max_handler_index() * - sizeof(sp_handler_t))) || + (sp_handler_t*)thd->alloc(handler_count * sizeof(sp_handler_t))) || !(m_hstack= - (uint*)thd->alloc(m_root_parsing_ctx->max_handler_index() * - sizeof(uint))) || + (uint*)thd->alloc(handler_count * sizeof(uint))) || !(m_in_handler= - (uint*)thd->alloc(m_root_parsing_ctx->max_handler_index() * - sizeof(uint))) || + (sp_active_handler_t*)thd->alloc(handler_count * + sizeof(sp_active_handler_t))) || !(m_cstack= (sp_cursor**)thd->alloc(m_root_parsing_ctx->max_cursor_index() * sizeof(sp_cursor*))) || @@ -194,13 +202,19 @@ sp_rcontext::set_return_value(THD *thd, Item **return_value_item) */ bool -sp_rcontext::find_handler(THD *thd, uint sql_errno, - MYSQL_ERROR::enum_warning_level level) +sp_rcontext::find_handler(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl) { if (m_hfound >= 0) - return 1; // Already got one + { + *cond_hdl= NULL; + return TRUE; // Already got one + } - const char *sqlstate= mysql_errno_to_sqlstate(sql_errno); int i= m_hcount, found= -1; /* @@ -220,7 +234,7 @@ sp_rcontext::find_handler(THD *thd, uint sql_errno, /* Check active handlers, to avoid invoking one recursively */ while (j--) - if (m_in_handler[j] == m_handler[i].handler) + if (m_in_handler[j].ip == m_handler[i].handler) break; if (j >= 0) continue; // Already executing this handler @@ -264,10 +278,26 @@ sp_rcontext::find_handler(THD *thd, uint sql_errno, */ if (m_prev_runtime_ctx && IS_EXCEPTION_CONDITION(sqlstate) && level == MYSQL_ERROR::WARN_LEVEL_ERROR) - return m_prev_runtime_ctx->find_handler(thd, sql_errno, level); + return m_prev_runtime_ctx->find_handler(thd, + sql_errno, + sqlstate, + level, + msg, + cond_hdl); + *cond_hdl= NULL; return FALSE; } + m_hfound= found; + + MYSQL_ERROR *raised= NULL; + DBUG_ASSERT(m_hfound >= 0); + DBUG_ASSERT((uint) m_hfound < m_root_parsing_ctx->max_handler_index()); + raised= & m_raised_conditions[m_hfound]; + raised->clear(); + raised->set(sql_errno, sqlstate, level, msg); + + *cond_hdl= raised; return TRUE; } @@ -293,9 +323,12 @@ sp_rcontext::find_handler(THD *thd, uint sql_errno, FALSE if no handler was found. */ bool -sp_rcontext::handle_error(uint sql_errno, - MYSQL_ERROR::enum_warning_level level, - THD *thd) +sp_rcontext::handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl) { MYSQL_ERROR::enum_warning_level elevated_level= level; @@ -308,7 +341,7 @@ sp_rcontext::handle_error(uint sql_errno, elevated_level= MYSQL_ERROR::WARN_LEVEL_ERROR; } - return find_handler(thd, sql_errno, elevated_level); + return find_handler(thd, sql_errno, sqlstate, elevated_level, msg, cond_hdl); } void @@ -335,7 +368,7 @@ sp_rcontext::pop_cursors(uint count) } void -sp_rcontext::push_handler(struct sp_cond_type *cond, uint h, int type, uint f) +sp_rcontext::push_handler(struct sp_cond_type *cond, uint h, int type) { DBUG_ENTER("sp_rcontext::push_handler"); DBUG_ASSERT(m_hcount < m_root_parsing_ctx->max_handler_index()); @@ -343,7 +376,6 @@ sp_rcontext::push_handler(struct sp_cond_type *cond, uint h, int type, uint f) m_handler[m_hcount].cond= cond; m_handler[m_hcount].handler= h; m_handler[m_hcount].type= type; - m_handler[m_hcount].foffset= f; m_hcount+= 1; DBUG_PRINT("info", ("m_hcount: %d", m_hcount)); @@ -382,11 +414,13 @@ sp_rcontext::pop_hstack() } void -sp_rcontext::enter_handler(int hid) +sp_rcontext::enter_handler(uint hip, uint hindex) { DBUG_ENTER("sp_rcontext::enter_handler"); DBUG_ASSERT(m_ihsp < m_root_parsing_ctx->max_handler_index()); - m_in_handler[m_ihsp++]= hid; + m_in_handler[m_ihsp].ip= hip; + m_in_handler[m_ihsp].index= hindex; + m_ihsp++; DBUG_PRINT("info", ("m_ihsp: %d", m_ihsp)); DBUG_VOID_RETURN; } @@ -396,11 +430,29 @@ sp_rcontext::exit_handler() { DBUG_ENTER("sp_rcontext::exit_handler"); DBUG_ASSERT(m_ihsp); + uint hindex= m_in_handler[m_ihsp-1].index; + m_raised_conditions[hindex].clear(); m_ihsp-= 1; DBUG_PRINT("info", ("m_ihsp: %d", m_ihsp)); DBUG_VOID_RETURN; } +MYSQL_ERROR* +sp_rcontext::raised_condition() const +{ + if (m_ihsp > 0) + { + uint hindex= m_in_handler[m_ihsp - 1].index; + MYSQL_ERROR *raised= & m_raised_conditions[hindex]; + return raised; + } + + if (m_prev_runtime_ctx) + return m_prev_runtime_ctx->raised_condition(); + + return NULL; +} + int sp_rcontext::set_variable(THD *thd, uint var_idx, Item **value) diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index 368a017da21..2af96cf64dd 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -34,12 +34,21 @@ class sp_instr_cpush; typedef struct { + /** Condition caught by this HANDLER. */ struct sp_cond_type *cond; - uint handler; // Location of handler + /** Location (instruction pointer) of the handler code. */ + uint handler; + /** Handler type (EXIT, CONTINUE). */ int type; - uint foffset; // Frame offset for the handlers declare level } sp_handler_t; +typedef struct +{ + /** Instruction pointer of the active handler. */ + uint ip; + /** Handler index of the active handler. */ + uint index; +} sp_active_handler_t; /* This class is a runtime context of a Stored Routine. It is used in an @@ -75,6 +84,13 @@ class sp_rcontext : public Sql_alloc */ Query_arena *callers_arena; + /* + End a open result set before start executing a continue/exit + handler if one is found as otherwise the client will hang + due to a violation of the client/server protocol. + */ + bool end_partial_result_set; + #ifndef DBUG_OFF /* The routine for which this runtime context is created. Used for checking @@ -107,31 +123,41 @@ class sp_rcontext : public Sql_alloc return m_return_value_set; } - void push_handler(struct sp_cond_type *cond, uint h, int type, uint f); + void push_handler(struct sp_cond_type *cond, uint h, int type); void pop_handlers(uint count); // Returns 1 if a handler was found, 0 otherwise. bool - find_handler(THD *thd, uint sql_errno,MYSQL_ERROR::enum_warning_level level); + find_handler(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl); // If there is an error handler for this error, handle it and return TRUE. bool - handle_error(uint sql_errno, - MYSQL_ERROR::enum_warning_level level, - THD *thd); + handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl); // Returns handler type and sets *ip to location if one was found inline int - found_handler(uint *ip, uint *fp) + found_handler(uint *ip, uint *index) { if (m_hfound < 0) return SP_HANDLER_NONE; *ip= m_handler[m_hfound].handler; - *fp= m_handler[m_hfound].foffset; + *index= m_hfound; return m_handler[m_hfound].type; } + MYSQL_ERROR* raised_condition() const; + // Returns true if we found a handler in this context inline bool found_handler_here() @@ -150,7 +176,12 @@ class sp_rcontext : public Sql_alloc uint pop_hstack(); - void enter_handler(int hid); + /** + Enter a SQL exception handler. + @param hip the handler instruction pointer + @param index the handler index + */ + void enter_handler(uint hip, uint index); void exit_handler(); @@ -214,10 +245,18 @@ private: bool in_sub_stmt; sp_handler_t *m_handler; // Visible handlers + + /** + SQL conditions caught by each handler. + This is an array indexed by handler index. + */ + MYSQL_ERROR *m_raised_conditions; + uint m_hcount; // Stack pointer for m_handler uint *m_hstack; // Return stack for continue handlers uint m_hsp; // Stack pointer for m_hstack - uint *m_in_handler; // Active handler, for recursion check + /** Active handler stack. */ + sp_active_handler_t *m_in_handler; uint m_ihsp; // Stack pointer for m_in_handler int m_hfound; // Set by find_handler; -1 if not found diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index ab18a2d1d04..9ab13438926 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -702,7 +702,7 @@ my_bool acl_reload(THD *thd) if (simple_open_n_lock_tables(thd, tables)) { sql_print_error("Fatal error: Can't open and lock privilege tables: %s", - thd->main_da.message()); + thd->stmt_da->message()); goto end; } @@ -6036,9 +6036,12 @@ public: virtual ~Silence_routine_definer_errors() {} - virtual bool handle_error(uint sql_errno, const char *message, - MYSQL_ERROR::enum_warning_level level, - THD *thd); + virtual bool handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl); bool has_errors() { return is_grave; } @@ -6047,18 +6050,23 @@ private: }; bool -Silence_routine_definer_errors::handle_error(uint sql_errno, - const char *message, - MYSQL_ERROR::enum_warning_level level, - THD *thd) +Silence_routine_definer_errors::handle_condition( + THD *thd, + uint sql_errno, + const char*, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl) { + *cond_hdl= NULL; if (level == MYSQL_ERROR::WARN_LEVEL_ERROR) { switch (sql_errno) { case ER_NONEXISTING_PROC_GRANT: /* Convert the error into a warning. */ - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, sql_errno, message); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + sql_errno, msg); return TRUE; default: is_grave= TRUE; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index b81070000b3..92ae390894a 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -44,9 +44,12 @@ public: virtual ~Prelock_error_handler() {} - virtual bool handle_error(uint sql_errno, const char *message, - MYSQL_ERROR::enum_warning_level level, - THD *thd); + virtual bool handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl); bool safely_trapped_errors(); @@ -57,11 +60,14 @@ private: bool -Prelock_error_handler::handle_error(uint sql_errno, - const char * /* message */, - MYSQL_ERROR::enum_warning_level /* level */, - THD * /* thd */) +Prelock_error_handler::handle_condition(THD *, + uint sql_errno, + const char*, + MYSQL_ERROR::enum_warning_level, + const char*, + MYSQL_ERROR ** cond_hdl) { + *cond_hdl= NULL; if (sql_errno == ER_NO_SUCH_TABLE) { m_handled_errors++; @@ -473,7 +479,7 @@ static TABLE_SHARE @todo Rework alternative ways to deal with ER_NO_SUCH TABLE. */ - if (share || (thd->is_error() && thd->main_da.sql_errno() != ER_NO_SUCH_TABLE)) + if (share || (thd->is_error() && thd->stmt_da->sql_errno() != ER_NO_SUCH_TABLE)) DBUG_RETURN(share); @@ -520,7 +526,7 @@ static TABLE_SHARE DBUG_RETURN(0); } /* Table existed in engine. Let's open it */ - mysql_reset_errors(thd, 1); // Clear warnings + thd->warning_info->clear_warning_info(thd->query_id); thd->clear_error(); // Clear error message DBUG_RETURN(get_table_share(thd, table_list, key, key_length, db_flags, error)); @@ -1281,9 +1287,9 @@ void close_thread_tables(THD *thd) */ if (!(thd->state_flags & Open_tables_state::BACKUPS_AVAIL)) { - thd->main_da.can_overwrite_status= TRUE; + thd->stmt_da->can_overwrite_status= TRUE; ha_autocommit_or_rollback(thd, thd->is_error()); - thd->main_da.can_overwrite_status= FALSE; + thd->stmt_da->can_overwrite_status= FALSE; /* Reset transaction state, but only if we're not inside a @@ -3943,7 +3949,7 @@ retry: release_table_share(share, RELEASE_WAIT_FOR_DROP); if (!thd->killed) { - mysql_reset_errors(thd, 1); // Clear warnings + thd->warning_info->clear_warning_info(thd->query_id); thd->clear_error(); // Clear error message goto retry; } diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 3c4ee274e7b..9f427f39265 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -934,7 +934,7 @@ void query_cache_end_of_result(THD *thd) DBUG_VOID_RETURN; /* Ensure that only complete results are cached. */ - DBUG_ASSERT(thd->main_da.is_eof()); + DBUG_ASSERT(thd->stmt_da->is_eof()); if (thd->killed) { @@ -1626,7 +1626,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", thd->limit_found_rows = query->found_rows(); thd->status_var.last_query_cost= 0.0; - thd->main_da.disable_status(); + thd->stmt_da->disable_status(); BLOCK_UNLOCK_RD(query_block); MYSQL_QUERY_CACHE_HIT(thd->query, (ulong) thd->limit_found_rows); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 3f568566c89..0ef7aece3d8 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -199,19 +199,6 @@ bool foreign_key_prefix(Key *a, Key *b) ** Thread specific functions ****************************************************************************/ -/** Push an error to the error stack and return TRUE for now. */ - -bool -Reprepare_observer::report_error(THD *thd) -{ - my_error(ER_NEED_REPREPARE, MYF(ME_NO_WARNING_FOR_ERROR|ME_NO_SP_HANDLER)); - - m_invalidated= TRUE; - - return TRUE; -} - - Open_tables_state::Open_tables_state(ulong version_arg) :version(version_arg), state_flags(0U) { @@ -304,7 +291,7 @@ int thd_tx_isolation(const THD *thd) extern "C" void thd_inc_row_count(THD *thd) { - thd->row_count++; + thd->warning_info->inc_current_row_for_warning(); } @@ -399,139 +386,6 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length, return buffer; } -/** - Clear this diagnostics area. - - Normally called at the end of a statement. -*/ - -void -Diagnostics_area::reset_diagnostics_area() -{ -#ifdef DBUG_OFF - can_overwrite_status= FALSE; - /** Don't take chances in production */ - m_message[0]= '\0'; - m_sql_errno= 0; - m_server_status= 0; - m_affected_rows= 0; - m_last_insert_id= 0; - m_total_warn_count= 0; -#endif - is_sent= FALSE; - /** Tiny reset in debug mode to see garbage right away */ - m_status= DA_EMPTY; -} - - -/** - Set OK status -- ends commands that do not return a - result set, e.g. INSERT/UPDATE/DELETE. -*/ - -void -Diagnostics_area::set_ok_status(THD *thd, ha_rows affected_rows_arg, - ulonglong last_insert_id_arg, - const char *message_arg) -{ - DBUG_ASSERT(! is_set()); -#ifdef DBUG_OFF - /* - In production, refuse to overwrite an error or a custom response - with an OK packet. - */ - if (is_error() || is_disabled()) - return; -#endif - /** Only allowed to report success if has not yet reported an error */ - - m_server_status= thd->server_status; - m_total_warn_count= thd->total_warn_count; - 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) - 1); - else - m_message[0]= '\0'; - m_status= DA_OK; -} - - -/** - Set EOF status. -*/ - -void -Diagnostics_area::set_eof_status(THD *thd) -{ - /** Only allowed to report eof if has not yet reported an error */ - - DBUG_ASSERT(! is_set()); -#ifdef DBUG_OFF - /* - In production, refuse to overwrite an error or a custom response - with an EOF packet. - */ - if (is_error() || is_disabled()) - return; -#endif - - m_server_status= thd->server_status; - /* - If inside a stored procedure, do not return the total - number of warnings, since they are not available to the client - anyway. - */ - m_total_warn_count= thd->spcont ? 0 : thd->total_warn_count; - - m_status= DA_EOF; -} - -/** - Set ERROR status. -*/ - -void -Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg, - const char *message_arg) -{ - /* - Only allowed to report error if has not yet reported a success - The only exception is when we flush the message to the client, - an error can happen during the flush. - */ - DBUG_ASSERT(! is_set() || can_overwrite_status); -#ifdef DBUG_OFF - /* - In production, refuse to overwrite a custom response with an - ERROR packet. - */ - if (is_disabled()) - return; -#endif - - m_sql_errno= sql_errno_arg; - strmake(m_message, message_arg, sizeof(m_message) - 1); - - m_status= DA_ERROR; -} - - -/** - Mark the diagnostics area as 'DISABLED'. - - This is used in rare cases when the COM_ command at hand sends a response - in a custom format. One example is the query cache, another is - COM_STMT_PREPARE. -*/ - -void -Diagnostics_area::disable_status() -{ - DBUG_ASSERT(! is_set()); - m_status= DA_DISABLED; -} - THD::THD() :Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION, @@ -548,6 +402,8 @@ THD::THD() first_successful_insert_id_in_cur_stmt(0), stmt_depends_on_first_successful_insert_id_in_prev_stmt(FALSE), examined_row_count(0), + warning_info(&main_warning_info), + stmt_da(&main_da), global_read_lock(0), is_fatal_error(0), transaction_rollback_request(0), @@ -558,7 +414,8 @@ THD::THD() bootstrap(0), derived_tables_processing(FALSE), spcont(NULL), - m_parser_state(NULL) + m_parser_state(NULL), + main_warning_info(0) { ulong tmp; @@ -582,7 +439,8 @@ THD::THD() hash_clear(&handler_tables_hash); tmp_table=0; used_tables=0; - cuted_fields= sent_row_count= row_count= 0L; + cuted_fields= 0L; + sent_row_count= 0L; limit_found_rows= 0; row_count_func= -1; statement_id_counter= 0UL; @@ -602,7 +460,6 @@ THD::THD() file_id = 0; query_id= 0; query_name_consts= 0; - warn_id= 0; db_charset= global_system_variables.collation_database; bzero(ha_data, sizeof(ha_data)); mysys_var=0; @@ -638,8 +495,6 @@ THD::THD() *scramble= '\0'; init(); - /* Initialize sub structures */ - init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE); #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) profiling.set_thd(this); #endif @@ -687,19 +542,27 @@ void THD::push_internal_handler(Internal_error_handler *handler) } } - -bool THD::handle_error(uint sql_errno, const char *message, - MYSQL_ERROR::enum_warning_level level) +bool THD::handle_condition(uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl) { if (!m_internal_handler) + { + *cond_hdl= NULL; return FALSE; + } for (Internal_error_handler *error_handler= m_internal_handler; error_handler; error_handler= m_internal_handler->m_prev_internal_handler) { - if (error_handler->handle_error(sql_errno, message, level, this)) - return TRUE; + if (error_handler-> handle_condition(this, sql_errno, sqlstate, level, msg, + cond_hdl)) + { + return TRUE; + } } return FALSE; @@ -712,6 +575,207 @@ void THD::pop_internal_handler() m_internal_handler= m_internal_handler->m_prev_internal_handler; } + +void THD::raise_error(uint sql_errno) +{ + const char* msg= ER(sql_errno); + (void) raise_condition(sql_errno, + NULL, + MYSQL_ERROR::WARN_LEVEL_ERROR, + msg); +} + +void THD::raise_error_printf(uint sql_errno, ...) +{ + va_list args; + char ebuff[MYSQL_ERRMSG_SIZE]; + DBUG_ENTER("THD::raise_error_printf"); + DBUG_PRINT("my", ("nr: %d errno: %d", sql_errno, errno)); + const char* format= ER(sql_errno); + va_start(args, sql_errno); + my_vsnprintf(ebuff, sizeof(ebuff), format, args); + va_end(args); + (void) raise_condition(sql_errno, + NULL, + MYSQL_ERROR::WARN_LEVEL_ERROR, + ebuff); + DBUG_VOID_RETURN; +} + +void THD::raise_warning(uint sql_errno) +{ + const char* msg= ER(sql_errno); + (void) raise_condition(sql_errno, + NULL, + MYSQL_ERROR::WARN_LEVEL_WARN, + msg); +} + +void THD::raise_warning_printf(uint sql_errno, ...) +{ + va_list args; + char ebuff[MYSQL_ERRMSG_SIZE]; + DBUG_ENTER("THD::raise_warning_printf"); + DBUG_PRINT("enter", ("warning: %u", sql_errno)); + const char* format= ER(sql_errno); + va_start(args, sql_errno); + my_vsnprintf(ebuff, sizeof(ebuff), format, args); + va_end(args); + (void) raise_condition(sql_errno, + NULL, + MYSQL_ERROR::WARN_LEVEL_WARN, + ebuff); + DBUG_VOID_RETURN; +} + +void THD::raise_note(uint sql_errno) +{ + DBUG_ENTER("THD::raise_note"); + DBUG_PRINT("enter", ("code: %d", sql_errno)); + if (!(this->options & OPTION_SQL_NOTES)) + DBUG_VOID_RETURN; + const char* msg= ER(sql_errno); + (void) raise_condition(sql_errno, + NULL, + MYSQL_ERROR::WARN_LEVEL_NOTE, + msg); + DBUG_VOID_RETURN; +} + +void THD::raise_note_printf(uint sql_errno, ...) +{ + va_list args; + char ebuff[MYSQL_ERRMSG_SIZE]; + DBUG_ENTER("THD::raise_note_printf"); + DBUG_PRINT("enter",("code: %u", sql_errno)); + if (!(this->options & OPTION_SQL_NOTES)) + DBUG_VOID_RETURN; + const char* format= ER(sql_errno); + va_start(args, sql_errno); + my_vsnprintf(ebuff, sizeof(ebuff), format, args); + va_end(args); + (void) raise_condition(sql_errno, + NULL, + MYSQL_ERROR::WARN_LEVEL_NOTE, + ebuff); + DBUG_VOID_RETURN; +} + +MYSQL_ERROR* THD::raise_condition(uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg) +{ + MYSQL_ERROR *cond= NULL; + DBUG_ENTER("THD::raise_condition"); + + if (!(this->options & OPTION_SQL_NOTES) && + (level == MYSQL_ERROR::WARN_LEVEL_NOTE)) + DBUG_RETURN(NULL); + + warning_info->opt_clear_warning_info(query_id); + + /* + TODO: replace by DBUG_ASSERT(sql_errno != 0) once all bugs similar to + Bug#36768 are fixed: a SQL condition must have a real (!=0) error number + so that it can be caught by handlers. + */ + if (sql_errno == 0) + sql_errno= ER_UNKNOWN_ERROR; + if (msg == NULL) + msg= ER(sql_errno); + if (sqlstate == NULL) + sqlstate= mysql_errno_to_sqlstate(sql_errno); + + if ((level == MYSQL_ERROR::WARN_LEVEL_WARN) && + really_abort_on_warning()) + { + /* + FIXME: + push_warning and strict SQL_MODE case. + */ + level= MYSQL_ERROR::WARN_LEVEL_ERROR; + killed= THD::KILL_BAD_DATA; + } + + switch (level) + { + case MYSQL_ERROR::WARN_LEVEL_NOTE: + case MYSQL_ERROR::WARN_LEVEL_WARN: + got_warning= 1; + break; + case MYSQL_ERROR::WARN_LEVEL_ERROR: + break; + default: + DBUG_ASSERT(FALSE); + } + + if (handle_condition(sql_errno, sqlstate, level, msg, &cond)) + DBUG_RETURN(cond); + + if (level == MYSQL_ERROR::WARN_LEVEL_ERROR) + { + is_slave_error= 1; // needed to catch query errors during replication + + /* + thd->lex->current_select == 0 if lex structure is not inited + (not query command (COM_QUERY)) + */ + if (lex->current_select && + lex->current_select->no_error && !is_fatal_error) + { + DBUG_PRINT("error", + ("Error converted to warning: current_select: no_error %d " + "fatal_error: %d", + (lex->current_select ? + lex->current_select->no_error : 0), + (int) is_fatal_error)); + } + else + { + if (! stmt_da->is_error()) + stmt_da->set_error_status(this, sql_errno, msg, sqlstate); + } + } + + /* + If a continue handler is found, the error message will be cleared + by the stored procedures code. + */ + if (!is_fatal_error && spcont && + spcont->handle_condition(this, sql_errno, sqlstate, level, msg, &cond)) + { + /* + Do not push any warnings, a handled error must be completely + silenced. + */ + DBUG_RETURN(cond); + } + + /* Un-handled conditions */ + + cond= raise_condition_no_handler(sql_errno, sqlstate, level, msg); + DBUG_RETURN(cond); +} + +MYSQL_ERROR* +THD::raise_condition_no_handler(uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg) +{ + MYSQL_ERROR *cond= NULL; + DBUG_ENTER("THD::raise_condition_no_handler"); + + query_cache_abort(& net); + + /* FIXME: broken special case */ + if (no_warnings_for_error && (level == MYSQL_ERROR::WARN_LEVEL_ERROR)) + DBUG_RETURN(NULL); + + cond= warning_info->push_warning(this, sql_errno, sqlstate, level, msg); + DBUG_RETURN(cond); +} extern "C" void *thd_alloc(MYSQL_THD thd, unsigned int size) { @@ -800,9 +864,6 @@ void THD::init(void) TL_WRITE_LOW_PRIORITY : TL_WRITE); session_tx_isolation= (enum_tx_isolation) variables.tx_isolation; - warn_list.empty(); - bzero((char*) warn_count, sizeof(warn_count)); - total_warn_count= 0; update_charset(); reset_current_stmt_binlog_row_based(); bzero((char *) &status_var, sizeof(status_var)); @@ -940,7 +1001,6 @@ THD::~THD() DBUG_PRINT("info", ("freeing security context")); main_security_ctx.destroy(); safeFree(db); - free_root(&warn_root,MYF(0)); #ifdef USING_TRANSACTIONS free_root(&transaction.mem_root,MYF(0)); #endif @@ -1543,21 +1603,19 @@ bool select_send::send_fields(List &list, uint flags) void select_send::abort() { DBUG_ENTER("select_send::abort"); - if (is_result_set_started && thd->spcont && - thd->spcont->find_handler(thd, thd->main_da.sql_errno(), - MYSQL_ERROR::WARN_LEVEL_ERROR)) + + if (is_result_set_started && thd->spcont) { /* We're executing a stored procedure, have an open result - set, an SQL exception condition and a handler for it. - In this situation we must abort the current statement, - silence the error and start executing the continue/exit - handler. + set and an SQL exception condition. In this situation we + must abort the current statement, silence the error and + start executing the continue/exit handler if one is found. Before aborting the statement, let's end the open result set, as otherwise the client will hang due to the violation of the client/server protocol. */ - thd->protocol->end_partial_result_set(thd); + thd->spcont->end_partial_result_set= TRUE; } DBUG_VOID_RETURN; } diff --git a/sql/sql_class.h b/sql/sql_class.h index a8fe3227aeb..d7814fcb03f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -265,6 +265,41 @@ public: LEX_COLUMN (const String& x,const uint& y ): column (x),rights (y) {} }; +/* SIGNAL / RESIGNAL / GET DIAGNOSTICS */ + +/** + This enumeration list all the condition item names of a condition in the + SQL condition area. +*/ +typedef enum enum_diag_condition_item_name +{ + /* + Conditions that can be set by the user (SIGNAL/RESIGNAL), + and by the server implementation. + */ + + DIAG_CLASS_ORIGIN= 0, + FIRST_DIAG_SET_PROPERTY= DIAG_CLASS_ORIGIN, + DIAG_SUBCLASS_ORIGIN= 1, + DIAG_CONSTRAINT_CATALOG= 2, + DIAG_CONSTRAINT_SCHEMA= 3, + DIAG_CONSTRAINT_NAME= 4, + DIAG_CATALOG_NAME= 5, + DIAG_SCHEMA_NAME= 6, + DIAG_TABLE_NAME= 7, + DIAG_COLUMN_NAME= 8, + DIAG_CURSOR_NAME= 9, + DIAG_MESSAGE_TEXT= 10, + DIAG_MYSQL_ERRNO= 11, + LAST_DIAG_SET_PROPERTY= DIAG_MYSQL_ERRNO +} Diag_condition_item_name; + +/** + Name of each diagnostic condition item. + This array is indexed by Diag_condition_item_name. +*/ +extern const LEX_STRING Diag_condition_item_names[]; + #include "sql_lex.h" /* Must be here */ class Delayed_insert; @@ -1038,12 +1073,12 @@ protected: public: /** - Handle an error condition. + Handle a sql condition. This method can be implemented by a subclass to achieve any of the following: - - mask an error internally, prevent exposing it to the user, - - mask an error and throw another one instead. - When this method returns true, the error condition is considered + - mask a warning/error internally, prevent exposing it to the user, + - mask a warning/error and throw another one instead. + When this method returns true, the sql condition is considered 'handled', and will not be propagated to upper layers. It is the responsability of the code installing an internal handler to then check for trapped conditions, and implement logic to recover @@ -1057,15 +1092,17 @@ public: before removing it from the exception stack with THD::pop_internal_handler(). - @param sql_errno the error number - @param level the error level @param thd the calling thread - @return true if the error is handled + @param cond the condition raised. + @return true if the condition is handled */ - virtual bool handle_error(uint sql_errno, - const char *message, - MYSQL_ERROR::enum_warning_level level, - THD *thd) = 0; + virtual bool handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl) = 0; + private: Internal_error_handler *m_prev_internal_handler; friend class THD; @@ -1080,10 +1117,12 @@ private: class Dummy_error_handler : public Internal_error_handler { public: - bool handle_error(uint sql_errno, - const char *message, - MYSQL_ERROR::enum_warning_level level, - THD *thd) + bool handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl) { /* Ignore error */ return TRUE; @@ -1091,123 +1130,6 @@ public: }; -/** - Stores status of the currently executed statement. - Cleared at the beginning of the statement, and then - can hold either OK, ERROR, or EOF status. - Can not be assigned twice per statement. -*/ - -class Diagnostics_area -{ -public: - enum enum_diagnostics_status - { - /** The area is cleared at start of a statement. */ - DA_EMPTY= 0, - /** Set whenever one calls my_ok(). */ - DA_OK, - /** Set whenever one calls my_eof(). */ - DA_EOF, - /** Set whenever one calls my_error() or my_message(). */ - DA_ERROR, - /** Set in case of a custom response, such as one from COM_STMT_PREPARE. */ - DA_DISABLED - }; - /** True if status information is sent to the client. */ - bool is_sent; - /** Set to make set_error_status after set_{ok,eof}_status possible. */ - bool can_overwrite_status; - - void set_ok_status(THD *thd, ha_rows affected_rows_arg, - ulonglong last_insert_id_arg, - const char *message); - void set_eof_status(THD *thd); - void set_error_status(THD *thd, uint sql_errno_arg, const char *message_arg); - - void disable_status(); - - void reset_diagnostics_area(); - - bool is_set() const { return m_status != DA_EMPTY; } - bool is_error() const { return m_status == DA_ERROR; } - bool is_eof() const { return m_status == DA_EOF; } - bool is_ok() const { return m_status == DA_OK; } - bool is_disabled() const { return m_status == DA_DISABLED; } - enum_diagnostics_status status() const { return m_status; } - - const char *message() const - { DBUG_ASSERT(m_status == DA_ERROR || m_status == DA_OK); return m_message; } - - uint sql_errno() const - { DBUG_ASSERT(m_status == DA_ERROR); return m_sql_errno; } - - uint server_status() const - { - DBUG_ASSERT(m_status == DA_OK || m_status == DA_EOF); - return m_server_status; - } - - ha_rows affected_rows() const - { DBUG_ASSERT(m_status == DA_OK); return m_affected_rows; } - - ulonglong last_insert_id() const - { DBUG_ASSERT(m_status == DA_OK); return m_last_insert_id; } - - uint total_warn_count() const - { - DBUG_ASSERT(m_status == DA_OK || m_status == DA_EOF); - return m_total_warn_count; - } - - Diagnostics_area() { reset_diagnostics_area(); } - -private: - /** Message buffer. Can be used by OK or ERROR status. */ - char m_message[MYSQL_ERRMSG_SIZE]; - /** - SQL error number. One of ER_ codes from share/errmsg.txt. - Set by set_error_status. - */ - uint m_sql_errno; - - /** - Copied from thd->server_status when the diagnostics area is assigned. - We need this member as some places in the code use the following pattern: - thd->server_status|= ... - my_eof(thd); - thd->server_status&= ~... - Assigned by OK, EOF or ERROR. - */ - uint m_server_status; - /** - The number of rows affected by the last statement. This is - semantically close to thd->row_count_func, but has a different - life cycle. thd->row_count_func stores the value returned by - function ROW_COUNT() and is cleared only by statements that - update its value, such as INSERT, UPDATE, DELETE and few others. - This member is cleared at the beginning of the next statement. - - We could possibly merge the two, but life cycle of thd->row_count_func - can not be changed. - */ - ha_rows m_affected_rows; - /** - Similarly to the previous member, this is a replacement of - thd->first_successful_insert_id_in_prev_stmt, which is used - to implement LAST_INSERT_ID(). - */ - ulonglong m_last_insert_id; - /** The total number of warnings. */ - uint m_total_warn_count; - enum_diagnostics_status m_status; - /** - @todo: the following THD members belong here: - - warn_list, warn_count, - */ -}; - - /** Storage engine specific thread local data. */ @@ -1234,6 +1156,7 @@ struct Ha_data Ha_data() :ha_ptr(NULL) {} }; +extern "C" void my_message_sql(uint error, const char *str, myf MyFlags); /** @class THD @@ -1276,7 +1199,6 @@ public: struct st_mysql_stmt *current_stmt; #endif NET net; // client connection descriptor - MEM_ROOT warn_root; // For warnings and errors Protocol *protocol; // Current protocol Protocol_text protocol_text; // Normal protocol Protocol_binary protocol_binary; // Binary protocol @@ -1692,16 +1614,8 @@ public: table_map used_tables; USER_CONN *user_connect; CHARSET_INFO *db_charset; - /* - FIXME: this, and some other variables like 'count_cuted_fields' - maybe should be statement/cursor local, that is, moved to Statement - class. With current implementation warnings produced in each prepared - statement/cursor settle here. - */ - List warn_list; - uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END]; - uint total_warn_count; - Diagnostics_area main_da; + Warning_info *warning_info; + Diagnostics_area *stmt_da; #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) PROFILING profiling; #endif @@ -1714,7 +1628,7 @@ public: from table are necessary for this select, to check if it's necessary to update auto-updatable fields (like auto_increment and timestamp). */ - query_id_t query_id, warn_id; + query_id_t query_id; ulong col_access; #ifdef ERROR_INJECT_SUPPORT @@ -1723,11 +1637,6 @@ public: /* Statement id is thread-wide. This counter is used to generate ids */ ulong statement_id_counter; ulong rand_saved_seed1, rand_saved_seed2; - /* - Row counter, mainly for errors and warnings. Not increased in - create_sort_index(); may differ from examined_row_count. - */ - ulong row_count; pthread_t real_id; /* For debugging */ my_thread_id thread_id; uint tmp_table, global_read_lock; @@ -2031,8 +1940,8 @@ public: inline void clear_error() { DBUG_ENTER("clear_error"); - if (main_da.is_error()) - main_da.reset_diagnostics_area(); + if (stmt_da->is_error()) + stmt_da->reset_diagnostics_area(); is_slave_error= 0; DBUG_VOID_RETURN; } @@ -2064,7 +1973,7 @@ public: To raise this flag, use my_error(). */ - inline bool is_error() const { return main_da.is_error(); } + inline bool is_error() const { return stmt_da->is_error(); } inline CHARSET_INFO *charset() { return variables.character_set_client; } void update_charset(); @@ -2260,19 +2169,107 @@ public: void push_internal_handler(Internal_error_handler *handler); /** - Handle an error condition. - @param sql_errno the error number - @param level the error level - @return true if the error is handled + Handle a sql condition. + @param sql_errno the condition error number + @param sqlstate the condition sqlstate + @param level the condition level + @param msg the condition message text + @param[out] cond_hdl the sql condition raised, if any + @return true if the condition is handled */ - virtual bool handle_error(uint sql_errno, const char *message, - MYSQL_ERROR::enum_warning_level level); + virtual bool handle_condition(uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl); /** Remove the error handler last pushed. */ void pop_internal_handler(); + /** + Raise an exception condition. + @param code the MYSQL_ERRNO error code of the error + */ + void raise_error(uint code); + + /** + Raise an exception condition, with a formatted message. + @param code the MYSQL_ERRNO error code of the error + */ + void raise_error_printf(uint code, ...); + + /** + Raise a completion condition (warning). + @param code the MYSQL_ERRNO error code of the warning + */ + void raise_warning(uint code); + + /** + Raise a completion condition (warning), with a formatted message. + @param code the MYSQL_ERRNO error code of the warning + */ + void raise_warning_printf(uint code, ...); + + /** + Raise a completion condition (note), with a fixed message. + @param code the MYSQL_ERRNO error code of the note + */ + void raise_note(uint code); + + /** + Raise an completion condition (note), with a formatted message. + @param code the MYSQL_ERRNO error code of the note + */ + void raise_note_printf(uint code, ...); + +private: + /* + Only the implementation of the SIGNAL and RESIGNAL statements + is permitted to raise SQL conditions in a generic way, + or to raise them by bypassing handlers (RESIGNAL). + To raise a SQL condition, the code should use the public + raise_error() or raise_warning() methods provided by class THD. + */ + friend class Signal_common; + friend class Signal_statement; + friend class Resignal_statement; + friend void push_warning(THD*, MYSQL_ERROR::enum_warning_level, uint, const char*); + friend void my_message_sql(uint, const char *, myf); + + /** + Raise a generic SQL condition. + @param sql_errno the condition error number + @param sqlstate the condition SQLSTATE + @param level the condition level + @param msg the condition message text + @return The condition raised, or NULL + */ + MYSQL_ERROR* + raise_condition(uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg); + + /** + Raise a generic SQL condition, without activation any SQL condition + handlers. + This method is necessary to support the RESIGNAL statement, + which is allowed to bypass SQL exception handlers. + @param sql_errno the condition error number + @param sqlstate the condition SQLSTATE + @param level the condition level + @param msg the condition message text + @return The condition raised, or NULL + */ + MYSQL_ERROR* + raise_condition_no_handler(uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg); + +public: /** Overloaded to guard query/query_length fields */ virtual void set_statement(Statement *stmt); @@ -2300,25 +2297,27 @@ private: tree itself is reused between executions and thus is stored elsewhere. */ MEM_ROOT main_mem_root; + Warning_info main_warning_info; + Diagnostics_area main_da; }; -/** A short cut for thd->main_da.set_ok_status(). */ +/** A short cut for thd->stmt_da->set_ok_status(). */ inline void -my_ok(THD *thd, ha_rows affected_rows= 0, ulonglong id= 0, +my_ok(THD *thd, ulonglong affected_rows= 0, ulonglong id= 0, const char *message= NULL) { - thd->main_da.set_ok_status(thd, affected_rows, id, message); + thd->stmt_da->set_ok_status(thd, affected_rows, id, message); } -/** A short cut for thd->main_da.set_eof_status(). */ +/** A short cut for thd->stmt_da->set_eof_status(). */ inline void my_eof(THD *thd) { - thd->main_da.set_eof_status(thd); + thd->stmt_da->set_eof_status(thd); } #define tmp_disable_binlog(A) \ @@ -2986,11 +2985,11 @@ public: /* Bits in sql_command_flags */ -#define CF_CHANGES_DATA 1 -#define CF_HAS_ROW_COUNT 2 -#define CF_STATUS_COMMAND 4 -#define CF_SHOW_TABLE_COMMAND 8 -#define CF_WRITE_LOGS_COMMAND 16 +#define CF_CHANGES_DATA (1U << 0) +#define CF_HAS_ROW_COUNT (1U << 1) +#define CF_STATUS_COMMAND (1U << 2) +#define CF_SHOW_TABLE_COMMAND (1U << 3) +#define CF_WRITE_LOGS_COMMAND (1U << 4) /** Must be set for SQL statements that may contain Item expressions and/or use joins and tables. @@ -3004,7 +3003,17 @@ public: reprepare. Consequently, complex item expressions and joins are currently prohibited in these statements. */ -#define CF_REEXECUTION_FRAGILE 32 +#define CF_REEXECUTION_FRAGILE (1U << 5) + +/** + Diagnostic statement. + Diagnostic statements: + - SHOW WARNING + - SHOW ERROR + - GET DIAGNOSTICS (WL#2111) + do not modify the diagnostics area during execution. +*/ +#define CF_DIAGNOSTIC_STMT (1U << 8) /* Functions in sql_class.cc */ diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 3952567c329..404d734559f 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1001,7 +1001,7 @@ static void end_connection(THD *thd) thd->thread_id,(thd->db ? thd->db : "unconnected"), sctx->user ? sctx->user : "unauthenticated", sctx->host_or_ip, - (thd->main_da.is_error() ? thd->main_da.message() : + (thd->stmt_da->is_error() ? thd->stmt_da->message() : ER(ER_UNKNOWN_ERROR))); } } @@ -1046,7 +1046,7 @@ static void prepare_new_connection_state(THD* thd) thd->thread_id,(thd->db ? thd->db : "unconnected"), sctx->user ? sctx->user : "unauthenticated", sctx->host_or_ip, "init_connect command failed"); - sql_print_warning("%s", thd->main_da.message()); + sql_print_warning("%s", thd->stmt_da->message()); } thd->proc_info=0; thd->set_time(); diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 37adf5c403a..9b747759ece 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -178,9 +178,9 @@ exit: if (orig_table_list->view) { if (thd->is_error() && - (thd->main_da.sql_errno() == ER_BAD_FIELD_ERROR || - thd->main_da.sql_errno() == ER_FUNC_INEXISTENT_NAME_COLLISION || - thd->main_da.sql_errno() == ER_SP_DOES_NOT_EXIST)) + (thd->stmt_da->sql_errno() == ER_BAD_FIELD_ERROR || + thd->stmt_da->sql_errno() == ER_FUNC_INEXISTENT_NAME_COLLISION || + thd->stmt_da->sql_errno() == ER_SP_DOES_NOT_EXIST)) { thd->clear_error(); my_error(ER_VIEW_INVALID, MYF(0), orig_table_list->db, diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 9ea7facbe41..2837e45fb47 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -1,4 +1,5 @@ -/* Copyright (C) 1995-2002 MySQL AB +/* Copyright (C) 1995-2002 MySQL AB, + Copyright (C) 2008-2009 Sun Microsystems, Inc This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -42,133 +43,577 @@ This file contains the implementation of error and warnings related ***********************************************************************/ #include "mysql_priv.h" +#include "sql_error.h" #include "sp_rcontext.h" /* - Store a new message in an error object + Design notes about MYSQL_ERROR::m_message_text. - This is used to in group_concat() to register how many warnings we actually - got after the query has been executed. + The member MYSQL_ERROR::m_message_text contains the text associated with + an error, warning or note (which are all SQL 'conditions') + + Producer of MYSQL_ERROR::m_message_text: + ---------------------------------------- + + (#1) the server implementation itself, when invoking functions like + my_error() or push_warning() + + (#2) user code in stored programs, when using the SIGNAL statement. + + (#3) user code in stored programs, when using the RESIGNAL statement. + + When invoking my_error(), the error number and message is typically + provided like this: + - my_error(ER_WRONG_DB_NAME, MYF(0), ...); + - my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); + + In both cases, the message is retrieved from ER(ER_XXX), which in turn + is read from the resource file errmsg.sys at server startup. + The strings stored in the errmsg.sys file are expressed in the character set + that corresponds to the server --language start option + (see error_message_charset_info). + + When executing: + - a SIGNAL statement, + - a RESIGNAL statement, + the message text is provided by the user logic, and is expressed in UTF8. + + Storage of MYSQL_ERROR::m_message_text: + --------------------------------------- + + (#4) The class MYSQL_ERROR is used to hold the message text member. + This class represents a single SQL condition. + + (#5) The class Warning_info represents a SQL condition area, and contains + a collection of SQL conditions in the Warning_info::m_warn_list + + Consumer of MYSQL_ERROR::m_message_text: + ---------------------------------------- + + (#6) The statements SHOW WARNINGS and SHOW ERRORS display the content of + the warning list. + + (#7) The GET DIAGNOSTICS statement (planned, not implemented yet) will + also read the content of: + - the top level statement condition area (when executed in a query), + - a sub statement (when executed in a stored program) + and return the data stored in a MYSQL_ERROR. + + (#8) The RESIGNAL statement reads the MYSQL_ERROR caught by an exception + handler, to raise a new or modified condition (in #3). + + The big picture + --------------- + -------------- + | ^ + V | + my_error(#1) SIGNAL(#2) RESIGNAL(#3) | + |(#A) |(#B) |(#C) | + | | | | + ----------------------------|---------------------------- | + | | + V | + MYSQL_ERROR(#4) | + | | + | | + V | + Warning_info(#5) | + | | + ----------------------------------------------------- | + | | | | + | | | | + | | | | + V V V | + SHOW WARNINGS(#6) GET DIAGNOSTICS(#7) RESIGNAL(#8) | + | | | | | + | -------- | V | + | | | -------------- + V | | + Connectors | | + | | | + ------------------------- + | + V + Client application + + Current implementation status + ----------------------------- + + (#1) (my_error) produces data in the 'error_message_charset_info' CHARSET + + (#2) and (#3) (SIGNAL, RESIGNAL) produces data internally in UTF8 + + (#6) (SHOW WARNINGS) produces data in the 'error_message_charset_info' CHARSET + + (#7) (GET DIAGNOSTICS) is not implemented. + + (#8) (RESIGNAL) produces data internally in UTF8 (see #3) + + As a result, the design choice for (#4) and (#5) is to store data in + the 'error_message_charset_info' CHARSET, to minimize impact on the code base. + This is implemented by using 'String MYSQL_ERROR::m_message_text'. + + The UTF8 -> error_message_charset_info conversion is implemented in + Signal_common::eval_signal_informations() (for path #B and #C). + + Future work + ----------- + + - Change (#1) (my_error) to generate errors in UTF8. + See WL#751 (Recoding of error messages) + + - Change (#4 and #5) to store message text in UTF8 natively. + In practice, this means changing the type of the message text to + ' MYSQL_ERROR::m_message_text', and is a direct + consequence of WL#751. + + - Implement (#9) (GET DIAGNOSTICS). + See WL#2111 (Stored Procedures: Implement GET DIAGNOSTICS) */ -void MYSQL_ERROR::set_msg(THD *thd, const char *msg_arg) +MYSQL_ERROR::MYSQL_ERROR() + : Sql_alloc(), + m_class_origin((const char*) NULL, 0, & my_charset_utf8_bin), + m_subclass_origin((const char*) NULL, 0, & my_charset_utf8_bin), + m_constraint_catalog((const char*) NULL, 0, & my_charset_utf8_bin), + m_constraint_schema((const char*) NULL, 0, & my_charset_utf8_bin), + m_constraint_name((const char*) NULL, 0, & my_charset_utf8_bin), + m_catalog_name((const char*) NULL, 0, & my_charset_utf8_bin), + m_schema_name((const char*) NULL, 0, & my_charset_utf8_bin), + m_table_name((const char*) NULL, 0, & my_charset_utf8_bin), + m_column_name((const char*) NULL, 0, & my_charset_utf8_bin), + m_cursor_name((const char*) NULL, 0, & my_charset_utf8_bin), + m_message_text(), + m_sql_errno(0), + m_level(MYSQL_ERROR::WARN_LEVEL_ERROR), + m_mem_root(NULL) { - msg= strdup_root(&thd->warn_root, msg_arg); + memset(m_returned_sqlstate, 0, sizeof(m_returned_sqlstate)); } - -/* - Reset all warnings for the thread - - SYNOPSIS - mysql_reset_errors() - thd Thread handle - force Reset warnings even if it has been done before - - IMPLEMENTATION - Don't reset warnings if this has already been called for this query. - This may happen if one gets a warning during the parsing stage, - in which case push_warnings() has already called this function. -*/ - -void mysql_reset_errors(THD *thd, bool force) +void MYSQL_ERROR::init(MEM_ROOT *mem_root) { - DBUG_ENTER("mysql_reset_errors"); - if (thd->query_id != thd->warn_id || force) + DBUG_ASSERT(mem_root != NULL); + DBUG_ASSERT(m_mem_root == NULL); + m_mem_root= mem_root; +} + +void MYSQL_ERROR::clear() +{ + m_class_origin.length(0); + m_subclass_origin.length(0); + m_constraint_catalog.length(0); + m_constraint_schema.length(0); + m_constraint_name.length(0); + m_catalog_name.length(0); + m_schema_name.length(0); + m_table_name.length(0); + m_column_name.length(0); + m_cursor_name.length(0); + m_message_text.length(0); + m_sql_errno= 0; + m_level= MYSQL_ERROR::WARN_LEVEL_ERROR; +} + +MYSQL_ERROR::MYSQL_ERROR(MEM_ROOT *mem_root) + : Sql_alloc(), + m_class_origin((const char*) NULL, 0, & my_charset_utf8_bin), + m_subclass_origin((const char*) NULL, 0, & my_charset_utf8_bin), + m_constraint_catalog((const char*) NULL, 0, & my_charset_utf8_bin), + m_constraint_schema((const char*) NULL, 0, & my_charset_utf8_bin), + m_constraint_name((const char*) NULL, 0, & my_charset_utf8_bin), + m_catalog_name((const char*) NULL, 0, & my_charset_utf8_bin), + m_schema_name((const char*) NULL, 0, & my_charset_utf8_bin), + m_table_name((const char*) NULL, 0, & my_charset_utf8_bin), + m_column_name((const char*) NULL, 0, & my_charset_utf8_bin), + m_cursor_name((const char*) NULL, 0, & my_charset_utf8_bin), + m_message_text(), + m_sql_errno(0), + m_level(MYSQL_ERROR::WARN_LEVEL_ERROR), + m_mem_root(mem_root) +{ + DBUG_ASSERT(mem_root != NULL); + memset(m_returned_sqlstate, 0, sizeof(m_returned_sqlstate)); +} + +static void copy_string(MEM_ROOT *mem_root, String* dst, const String* src) +{ + size_t len= src->length(); + if (len) { - thd->warn_id= thd->query_id; - free_root(&thd->warn_root,MYF(0)); - bzero((char*) thd->warn_count, sizeof(thd->warn_count)); - if (force) - thd->total_warn_count= 0; - thd->warn_list.empty(); - thd->row_count= 1; // by default point to row 1 + char* copy= (char*) alloc_root(mem_root, len + 1); + if (copy) + { + memcpy(copy, src->ptr(), len); + copy[len]= '\0'; + dst->set(copy, len, src->charset()); + } } + else + dst->length(0); +} + +void +MYSQL_ERROR::copy_opt_attributes(const MYSQL_ERROR *cond) +{ + DBUG_ASSERT(this != cond); + copy_string(m_mem_root, & m_class_origin, & cond->m_class_origin); + copy_string(m_mem_root, & m_subclass_origin, & cond->m_subclass_origin); + copy_string(m_mem_root, & m_constraint_catalog, & cond->m_constraint_catalog); + copy_string(m_mem_root, & m_constraint_schema, & cond->m_constraint_schema); + copy_string(m_mem_root, & m_constraint_name, & cond->m_constraint_name); + copy_string(m_mem_root, & m_catalog_name, & cond->m_catalog_name); + copy_string(m_mem_root, & m_schema_name, & cond->m_schema_name); + copy_string(m_mem_root, & m_table_name, & cond->m_table_name); + copy_string(m_mem_root, & m_column_name, & cond->m_column_name); + copy_string(m_mem_root, & m_cursor_name, & cond->m_cursor_name); +} + +void +MYSQL_ERROR::set(uint sql_errno, const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, const char* msg) +{ + DBUG_ASSERT(sql_errno != 0); + DBUG_ASSERT(sqlstate != NULL); + DBUG_ASSERT(msg != NULL); + + m_sql_errno= sql_errno; + memcpy(m_returned_sqlstate, sqlstate, SQLSTATE_LENGTH); + m_returned_sqlstate[SQLSTATE_LENGTH]= '\0'; + + set_builtin_message_text(msg); + m_level= level; +} + +void +MYSQL_ERROR::set_builtin_message_text(const char* str) +{ + /* + See the comments + "Design notes about MYSQL_ERROR::m_message_text." + */ + const char* copy; + + copy= strdup_root(m_mem_root, str); + m_message_text.set(copy, strlen(copy), error_message_charset_info); + DBUG_ASSERT(! m_message_text.is_alloced()); +} + +const char* +MYSQL_ERROR::get_message_text() const +{ + return m_message_text.ptr(); +} + +int +MYSQL_ERROR::get_message_octet_length() const +{ + return m_message_text.length(); +} + +void +MYSQL_ERROR::set_sqlstate(const char* sqlstate) +{ + memcpy(m_returned_sqlstate, sqlstate, SQLSTATE_LENGTH); + m_returned_sqlstate[SQLSTATE_LENGTH]= '\0'; +} + +/** + Clear this diagnostics area. + + Normally called at the end of a statement. +*/ + +void +Diagnostics_area::reset_diagnostics_area() +{ + DBUG_ENTER("reset_diagnostics_area"); +#ifdef DBUG_OFF + can_overwrite_status= FALSE; + /** Don't take chances in production */ + m_message[0]= '\0'; + m_sql_errno= 0; + m_server_status= 0; + m_affected_rows= 0; + m_last_insert_id= 0; + m_statement_warn_count= 0; +#endif + is_sent= FALSE; + /** Tiny reset in debug mode to see garbage right away */ + m_status= DA_EMPTY; DBUG_VOID_RETURN; } -/* - Push the warning/error to error list if there is still room in the list +/** + Set OK status -- ends commands that do not return a + result set, e.g. INSERT/UPDATE/DELETE. +*/ + +void +Diagnostics_area::set_ok_status(THD *thd, ulonglong affected_rows_arg, + ulonglong last_insert_id_arg, + const char *message_arg) +{ + DBUG_ENTER("set_ok_status"); + DBUG_ASSERT(! is_set()); + /* + In production, refuse to overwrite an error or a custom response + with an OK packet. + */ + if (is_error() || is_disabled()) + return; + + m_server_status= thd->server_status; + m_statement_warn_count= thd->warning_info->statement_warn_count(); + 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) - 1); + else + m_message[0]= '\0'; + m_status= DA_OK; + DBUG_VOID_RETURN; +} + + +/** + Set EOF status. +*/ + +void +Diagnostics_area::set_eof_status(THD *thd) +{ + DBUG_ENTER("set_eof_status"); + /* Only allowed to report eof if has not yet reported an error */ + DBUG_ASSERT(! is_set()); + /* + In production, refuse to overwrite an error or a custom response + with an EOF packet. + */ + if (is_error() || is_disabled()) + return; + + m_server_status= thd->server_status; + /* + If inside a stored procedure, do not return the total + number of warnings, since they are not available to the client + anyway. + */ + m_statement_warn_count= (thd->spcont ? + 0 : thd->warning_info->statement_warn_count()); + + m_status= DA_EOF; + DBUG_VOID_RETURN; +} + +/** + Set ERROR status. +*/ + +void +Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg, + const char *message_arg, + const char *sqlstate) +{ + DBUG_ENTER("set_error_status"); + /* + Only allowed to report error if has not yet reported a success + The only exception is when we flush the message to the client, + an error can happen during the flush. + */ + DBUG_ASSERT(! is_set() || can_overwrite_status); +#ifdef DBUG_OFF + /* + In production, refuse to overwrite a custom response with an + ERROR packet. + */ + if (is_disabled()) + return; +#endif + + if (sqlstate == NULL) + sqlstate= mysql_errno_to_sqlstate(sql_errno_arg); + + m_sql_errno= sql_errno_arg; + memcpy(m_sqlstate, sqlstate, SQLSTATE_LENGTH); + m_sqlstate[SQLSTATE_LENGTH]= '\0'; + strmake(m_message, message_arg, sizeof(m_message)-1); + + m_status= DA_ERROR; + DBUG_VOID_RETURN; +} + + +/** + Mark the diagnostics area as 'DISABLED'. + + This is used in rare cases when the COM_ command at hand sends a response + in a custom format. One example is the query cache, another is + COM_STMT_PREPARE. +*/ + +void +Diagnostics_area::disable_status() +{ + DBUG_ASSERT(! is_set()); + m_status= DA_DISABLED; +} + +Warning_info::Warning_info(ulonglong warn_id_arg) + :m_statement_warn_count(0), + m_current_row_for_warning(1), + m_warn_id(warn_id_arg), + m_read_only(FALSE) +{ + /* Initialize sub structures */ + init_sql_alloc(&m_warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE); + m_warn_list.empty(); + bzero((char*) m_warn_count, sizeof(m_warn_count)); +} + + +Warning_info::~Warning_info() +{ + free_root(&m_warn_root,MYF(0)); +} + + +/** + Reset the warning information of this connection. +*/ + +void Warning_info::clear_warning_info(ulonglong warn_id_arg) +{ + m_warn_id= warn_id_arg; + free_root(&m_warn_root, MYF(0)); + bzero((char*) m_warn_count, sizeof(m_warn_count)); + m_warn_list.empty(); + m_statement_warn_count= 0; + m_current_row_for_warning= 1; /* Start counting from the first row */ +} + +void Warning_info::reserve_space(THD *thd, uint count) +{ + /* Make room for count conditions */ + while ((m_warn_list.elements > 0) && + ((m_warn_list.elements + count) > thd->variables.max_error_count)) + m_warn_list.pop(); +} + +/** + Append warnings only if the original contents of the routine + warning info was replaced. +*/ +void Warning_info::merge_with_routine_info(THD *thd, Warning_info *source) +{ + /* + If a routine body is empty or if a routine did not + generate any warnings (thus m_warn_id didn't change), + do not duplicate our own contents by appending the + contents of the called routine. We know that the called + routine did not change its warning info. + + On the other hand, if the routine body is not empty and + some statement in the routine generates a warning or + uses tables, m_warn_id is guaranteed to have changed. + In this case we know that the routine warning info + contains only new warnings, and thus we perform a copy. + */ + if (m_warn_id != source->m_warn_id) + { + /* + If the invocation of the routine was a standalone statement, + rather than a sub-statement, in other words, if it's a CALL + of a procedure, rather than invocation of a function or a + trigger, we need to clear the current contents of the caller's + warning info. + + This is per MySQL rules: if a statement generates a warning, + warnings from the previous statement are flushed. Normally + it's done in push_warning(). However, here we don't use + push_warning() to avoid invocation of condition handlers or + escalation of warnings to errors. + */ + opt_clear_warning_info(thd->query_id); + append_warning_info(thd, source); + } +} + +/** + Add a warning to the list of warnings. Increment the respective + counters. +*/ +MYSQL_ERROR *Warning_info::push_warning(THD *thd, + uint sql_errno, const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char *msg) +{ + MYSQL_ERROR *cond= NULL; + + if (! m_read_only) + { + if (m_warn_list.elements < thd->variables.max_error_count) + { + cond= new (& m_warn_root) MYSQL_ERROR(& m_warn_root); + if (cond) + { + cond->set(sql_errno, sqlstate, level, msg); + m_warn_list.push_back(cond, &m_warn_root); + } + } + m_warn_count[(uint) level]++; + } + + m_statement_warn_count++; + return cond; +} + +/* + Push the warning to error list if there is still room in the list SYNOPSIS push_warning() thd Thread handle - level Severity of warning (note, warning, error ...) + level Severity of warning (note, warning) code Error number msg Clear error message - - RETURN - pointer on MYSQL_ERROR object */ -MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, - uint code, const char *msg) +void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, + uint code, const char *msg) { - MYSQL_ERROR *err= 0; DBUG_ENTER("push_warning"); DBUG_PRINT("enter", ("code: %d, msg: %s", code, msg)); - DBUG_ASSERT(code != 0); - DBUG_ASSERT(msg != NULL); + /* + Calling push_warning/push_warning_printf with a + level of WARN_LEVEL_ERROR *is* a bug. + Either use my_error(), or WARN_LEVEL_WARN. + Please fix the calling code, and do *NOT* + add more work around code in the assert below. + */ + DBUG_ASSERT( (level != MYSQL_ERROR::WARN_LEVEL_ERROR) + || (code == ER_CANT_CREATE_TABLE) /* See Bug#47233 */ + || (code == ER_ILLEGAL_HA_CREATE_OPTION) /* See Bug#47233 */ + ); - if (level == MYSQL_ERROR::WARN_LEVEL_NOTE && - !(thd->options & OPTION_SQL_NOTES)) - DBUG_RETURN(0); + if (level == MYSQL_ERROR::WARN_LEVEL_ERROR) + level= MYSQL_ERROR::WARN_LEVEL_WARN; - if (thd->query_id != thd->warn_id && !thd->spcont) - mysql_reset_errors(thd, 0); - thd->got_warning= 1; + (void) thd->raise_condition(code, NULL, level, msg); - /* Abort if we are using strict mode and we are not using IGNORE */ - if ((int) level >= (int) MYSQL_ERROR::WARN_LEVEL_WARN && - thd->really_abort_on_warning()) - { - /* Avoid my_message() calling push_warning */ - bool no_warnings_for_error= thd->no_warnings_for_error; - sp_rcontext *spcont= thd->spcont; - - thd->no_warnings_for_error= 1; - thd->spcont= NULL; - - thd->killed= THD::KILL_BAD_DATA; - my_message(code, msg, MYF(0)); - - thd->spcont= spcont; - thd->no_warnings_for_error= no_warnings_for_error; - /* Store error in error list (as my_message() didn't do it) */ - level= MYSQL_ERROR::WARN_LEVEL_ERROR; - } - - if (thd->handle_error(code, msg, level)) - DBUG_RETURN(NULL); - - if (thd->spcont && - thd->spcont->handle_error(code, level, thd)) - { - DBUG_RETURN(NULL); - } - query_cache_abort(&thd->net); - - - if (thd->warn_list.elements < thd->variables.max_error_count) - { - /* We have to use warn_root, as mem_root is freed after each query */ - if ((err= new (&thd->warn_root) MYSQL_ERROR(thd, code, level, msg))) - thd->warn_list.push_back(err, &thd->warn_root); - } - thd->warn_count[(uint) level]++; - thd->total_warn_count++; - DBUG_RETURN(err); + DBUG_VOID_RETURN; } + /* - Push the warning/error to error list if there is still room in the list + Push the warning to error list if there is still room in the list SYNOPSIS push_warning_printf() thd Thread handle - level Severity of warning (note, warning, error ...) + level Severity of warning (note, warning) code Error number msg Clear error message */ @@ -217,10 +662,12 @@ const LEX_STRING warning_level_names[]= }; bool mysqld_show_warnings(THD *thd, ulong levels_to_show) -{ +{ List field_list; DBUG_ENTER("mysqld_show_warnings"); + DBUG_ASSERT(thd->warning_info->is_read_only()); + field_list.push_back(new Item_empty_string("Level", 7)); field_list.push_back(new Item_return_int("Code",4, MYSQL_TYPE_LONG)); field_list.push_back(new Item_empty_string("Message",MYSQL_ERRMSG_SIZE)); @@ -232,29 +679,36 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show) MYSQL_ERROR *err; SELECT_LEX *sel= &thd->lex->select_lex; SELECT_LEX_UNIT *unit= &thd->lex->unit; - ha_rows idx= 0; + ulonglong idx= 0; Protocol *protocol=thd->protocol; unit->set_limit(sel); - List_iterator_fast it(thd->warn_list); + List_iterator_fast it(thd->warning_info->warn_list()); while ((err= it++)) { /* Skip levels that the user is not interested in */ - if (!(levels_to_show & ((ulong) 1 << err->level))) + if (!(levels_to_show & ((ulong) 1 << err->get_level()))) continue; if (++idx <= unit->offset_limit_cnt) continue; if (idx > unit->select_limit_cnt) break; protocol->prepare_for_resend(); - protocol->store(warning_level_names[err->level].str, - warning_level_names[err->level].length, system_charset_info); - protocol->store((uint32) err->code); - protocol->store(err->msg, (uint) strlen(err->msg), system_charset_info); + protocol->store(warning_level_names[err->get_level()].str, + warning_level_names[err->get_level()].length, + system_charset_info); + protocol->store((uint32) err->get_sql_errno()); + protocol->store(err->get_message_text(), + err->get_message_octet_length(), + system_charset_info); if (protocol->write()) DBUG_RETURN(TRUE); } my_eof(thd); + + thd->warning_info->set_read_only(FALSE); + DBUG_RETURN(FALSE); } + diff --git a/sql/sql_error.h b/sql/sql_error.h index f98264dce50..f7b0ff56efa 100644 --- a/sql/sql_error.h +++ b/sql/sql_error.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2000-2003 MySQL AB +/* Copyright (C) 2000-2003 MySQL AB, + Copyright (C) 2008-2009 Sun Microsystems, Inc This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,31 +14,514 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -class MYSQL_ERROR: public Sql_alloc +#ifndef SQL_ERROR_H +#define SQL_ERROR_H + +#include "sql_list.h" /* Sql_alloc, MEM_ROOT */ +#include "m_string.h" /* LEX_STRING */ +#include "mysql_com.h" /* MYSQL_ERRMSG_SIZE */ + +class THD; + +/** + Stores status of the currently executed statement. + Cleared at the beginning of the statement, and then + can hold either OK, ERROR, or EOF status. + Can not be assigned twice per statement. +*/ + +class Diagnostics_area { public: - enum enum_warning_level - { WARN_LEVEL_NOTE, WARN_LEVEL_WARN, WARN_LEVEL_ERROR, WARN_LEVEL_END}; - - uint code; - enum_warning_level level; - char *msg; - - MYSQL_ERROR(THD *thd, uint code_arg, enum_warning_level level_arg, - const char *msg_arg) - :code(code_arg), level(level_arg) + enum enum_diagnostics_status { - if (msg_arg) - set_msg(thd, msg_arg); + /** The area is cleared at start of a statement. */ + DA_EMPTY= 0, + /** Set whenever one calls my_ok(). */ + DA_OK, + /** Set whenever one calls my_eof(). */ + DA_EOF, + /** Set whenever one calls my_error() or my_message(). */ + DA_ERROR, + /** Set in case of a custom response, such as one from COM_STMT_PREPARE. */ + DA_DISABLED + }; + /** True if status information is sent to the client. */ + bool is_sent; + /** Set to make set_error_status after set_{ok,eof}_status possible. */ + bool can_overwrite_status; + + void set_ok_status(THD *thd, ulonglong affected_rows_arg, + ulonglong last_insert_id_arg, + const char *message); + void set_eof_status(THD *thd); + void set_error_status(THD *thd, uint sql_errno_arg, const char *message_arg, + const char *sqlstate); + + void disable_status(); + + void reset_diagnostics_area(); + + bool is_set() const { return m_status != DA_EMPTY; } + bool is_error() const { return m_status == DA_ERROR; } + bool is_eof() const { return m_status == DA_EOF; } + bool is_ok() const { return m_status == DA_OK; } + bool is_disabled() const { return m_status == DA_DISABLED; } + enum_diagnostics_status status() const { return m_status; } + + const char *message() const + { DBUG_ASSERT(m_status == DA_ERROR || m_status == DA_OK); return m_message; } + + uint sql_errno() const + { DBUG_ASSERT(m_status == DA_ERROR); return m_sql_errno; } + + const char* get_sqlstate() const + { DBUG_ASSERT(m_status == DA_ERROR); return m_sqlstate; } + + uint server_status() const + { + DBUG_ASSERT(m_status == DA_OK || m_status == DA_EOF); + return m_server_status; } - void set_msg(THD *thd, const char *msg_arg); + + ulonglong affected_rows() const + { DBUG_ASSERT(m_status == DA_OK); return m_affected_rows; } + + ulonglong last_insert_id() const + { DBUG_ASSERT(m_status == DA_OK); return m_last_insert_id; } + + uint statement_warn_count() const + { + DBUG_ASSERT(m_status == DA_OK || m_status == DA_EOF); + return m_statement_warn_count; + } + + Diagnostics_area() { reset_diagnostics_area(); } + +private: + /** Message buffer. Can be used by OK or ERROR status. */ + char m_message[MYSQL_ERRMSG_SIZE]; + /** + SQL error number. One of ER_ codes from share/errmsg.txt. + Set by set_error_status. + */ + uint m_sql_errno; + + char m_sqlstate[SQLSTATE_LENGTH+1]; + + /** + Copied from thd->server_status when the diagnostics area is assigned. + We need this member as some places in the code use the following pattern: + thd->server_status|= ... + my_eof(thd); + thd->server_status&= ~... + Assigned by OK, EOF or ERROR. + */ + uint m_server_status; + /** + The number of rows affected by the last statement. This is + semantically close to thd->row_count_func, but has a different + life cycle. thd->row_count_func stores the value returned by + function ROW_COUNT() and is cleared only by statements that + update its value, such as INSERT, UPDATE, DELETE and few others. + This member is cleared at the beginning of the next statement. + + We could possibly merge the two, but life cycle of thd->row_count_func + can not be changed. + */ + ulonglong m_affected_rows; + /** + Similarly to the previous member, this is a replacement of + thd->first_successful_insert_id_in_prev_stmt, which is used + to implement LAST_INSERT_ID(). + */ + ulonglong m_last_insert_id; + /** + Number of warnings of this last statement. May differ from + the number of warnings returned by SHOW WARNINGS e.g. in case + the statement doesn't clear the warnings, and doesn't generate + them. + */ + uint m_statement_warn_count; + enum_diagnostics_status m_status; }; -MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, - uint code, const char *msg); +/////////////////////////////////////////////////////////////////////////// + +/** + Representation of a SQL condition. + A SQL condition can be a completion condition (note, warning), + or an exception condition (error, not found). + @note This class is named MYSQL_ERROR instead of SQL_condition for historical reasons, + to facilitate merging code with previous releases. +*/ +class MYSQL_ERROR : public Sql_alloc +{ +public: + /* + Enumeration value describing the severity of the error. + + Note that these enumeration values must correspond to the indices + of the sql_print_message_handlers array. + */ + enum enum_warning_level + { WARN_LEVEL_NOTE, WARN_LEVEL_WARN, WARN_LEVEL_ERROR, WARN_LEVEL_END}; + /** + Get the MESSAGE_TEXT of this condition. + @return the message text. + */ + const char* get_message_text() const; + + /** + Get the MESSAGE_OCTET_LENGTH of this condition. + @return the length in bytes of the message text. + */ + int get_message_octet_length() const; + + /** + Get the SQLSTATE of this condition. + @return the sql state. + */ + const char* get_sqlstate() const + { return m_returned_sqlstate; } + + /** + Get the SQL_ERRNO of this condition. + @return the sql error number condition item. + */ + uint get_sql_errno() const + { return m_sql_errno; } + + /** + Get the error level of this condition. + @return the error level condition item. + */ + MYSQL_ERROR::enum_warning_level get_level() const + { return m_level; } + +private: + /* + The interface of MYSQL_ERROR is mostly private, by design, + so that only the following code: + - various raise_error() or raise_warning() methods in class THD, + - the implementation of SIGNAL / RESIGNAL + - catch / re-throw of SQL conditions in stored procedures (sp_rcontext) + is allowed to create / modify a SQL condition. + Enforcing this policy prevents confusion, since the only public + interface available to the rest of the server implementation + is the interface offered by the THD methods (THD::raise_error()), + which should be used. + */ + friend class THD; + friend class Warning_info; + friend class Signal_common; + friend class Signal_statement; + friend class Resignal_statement; + friend class sp_rcontext; + + /** + Default constructor. + This constructor is usefull when allocating arrays. + Note that the init() method should be called to complete the MYSQL_ERROR. + */ + MYSQL_ERROR(); + + /** + Complete the MYSQL_ERROR initialisation. + @param mem_root The memory root to use for the condition items + of this condition + */ + void init(MEM_ROOT *mem_root); + + /** + Constructor. + @param mem_root The memory root to use for the condition items + of this condition + */ + MYSQL_ERROR(MEM_ROOT *mem_root); + + /** Destructor. */ + ~MYSQL_ERROR() + {} + + /** + Copy optional condition items attributes. + @param cond the condition to copy. + */ + void copy_opt_attributes(const MYSQL_ERROR *cond); + + /** + Set this condition area with a fixed message text. + @param thd the current thread. + @param code the error number for this condition. + @param str the message text for this condition. + @param level the error level for this condition. + @param MyFlags additional flags. + */ + void set(uint sql_errno, const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg); + + /** + Set the condition message test. + @param str Message text, expressed in the character set derived from + the server --language option + */ + void set_builtin_message_text(const char* str); + + /** Set the SQLSTATE of this condition. */ + void set_sqlstate(const char* sqlstate); + + /** + Clear this SQL condition. + */ + void clear(); + +private: + /** SQL CLASS_ORIGIN condition item. */ + String m_class_origin; + + /** SQL SUBCLASS_ORIGIN condition item. */ + String m_subclass_origin; + + /** SQL CONSTRAINT_CATALOG condition item. */ + String m_constraint_catalog; + + /** SQL CONSTRAINT_SCHEMA condition item. */ + String m_constraint_schema; + + /** SQL CONSTRAINT_NAME condition item. */ + String m_constraint_name; + + /** SQL CATALOG_NAME condition item. */ + String m_catalog_name; + + /** SQL SCHEMA_NAME condition item. */ + String m_schema_name; + + /** SQL TABLE_NAME condition item. */ + String m_table_name; + + /** SQL COLUMN_NAME condition item. */ + String m_column_name; + + /** SQL CURSOR_NAME condition item. */ + String m_cursor_name; + + /** Message text, expressed in the character set implied by --language. */ + String m_message_text; + + /** MySQL extension, MYSQL_ERRNO condition item. */ + uint m_sql_errno; + + /** + SQL RETURNED_SQLSTATE condition item. + This member is always NUL terminated. + */ + char m_returned_sqlstate[SQLSTATE_LENGTH+1]; + + /** Severity (error, warning, note) of this condition. */ + MYSQL_ERROR::enum_warning_level m_level; + + /** Memory root to use to hold condition item values. */ + MEM_ROOT *m_mem_root; +}; + +/////////////////////////////////////////////////////////////////////////// + +/** + Information about warnings of the current connection. +*/ + +class Warning_info +{ + /** A memory root to allocate warnings and errors */ + MEM_ROOT m_warn_root; + /** List of warnings of all severities (levels). */ + List m_warn_list; + /** A break down of the number of warnings per severity (level). */ + uint m_warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END]; + /** + The number of warnings of the current statement. Warning_info + life cycle differs from statement life cycle -- it may span + multiple statements. In that case we get + m_statement_warn_count 0, whereas m_warn_list is not empty. + */ + uint m_statement_warn_count; + /* + Row counter, to print in errors and warnings. Not increased in + create_sort_index(); may differ from examined_row_count. + */ + ulong m_current_row_for_warning; + /** Used to optionally clear warnings only once per statement. */ + ulonglong m_warn_id; + +private: + Warning_info(const Warning_info &rhs); /* Not implemented */ + Warning_info& operator=(const Warning_info &rhs); /* Not implemented */ +public: + + Warning_info(ulonglong warn_id_arg); + ~Warning_info(); + + /** + Reset the warning information. Clear all warnings, + the number of warnings, reset current row counter + to point to the first row. + */ + void clear_warning_info(ulonglong warn_id_arg); + /** + Only clear warning info if haven't yet done that already + for the current query. Allows to be issued at any time + during the query, without risk of clearing some warnings + that have been generated by the current statement. + + @todo: This is a sign of sloppy coding. Instead we need to + designate one place in a statement life cycle where we call + clear_warning_info(). + */ + void opt_clear_warning_info(ulonglong query_id) + { + if (query_id != m_warn_id) + clear_warning_info(query_id); + } + + void append_warning_info(THD *thd, Warning_info *source) + { + append_warnings(thd, & source->warn_list()); + } + + /** + Concatenate the list of warnings. + It's considered tolerable to lose a warning. + */ + void append_warnings(THD *thd, List *src) + { + MYSQL_ERROR *err; + MYSQL_ERROR *copy; + List_iterator_fast it(*src); + /* + Don't use ::push_warning() to avoid invocation of condition + handlers or escalation of warnings to errors. + */ + while ((err= it++)) + { + copy= Warning_info::push_warning(thd, err->get_sql_errno(), err->get_sqlstate(), + err->get_level(), err->get_message_text()); + if (copy) + copy->copy_opt_attributes(err); + } + } + + /** + Conditional merge of related warning information areas. + */ + void merge_with_routine_info(THD *thd, Warning_info *source); + + /** + Reset between two COM_ commands. Warnings are preserved + between commands, but statement_warn_count indicates + the number of warnings of this particular statement only. + */ + void reset_for_next_command() { m_statement_warn_count= 0; } + + /** + Used for @@warning_count system variable, which prints + the number of rows returned by SHOW WARNINGS. + */ + ulong warn_count() const + { + /* + This may be higher than warn_list.elements if we have + had more warnings than thd->variables.max_error_count. + */ + return (m_warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_NOTE] + + m_warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR] + + m_warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_WARN]); + } + + /** + This is for iteration purposes. We return a non-constant reference + since List doesn't have constant iterators. + */ + List &warn_list() { return m_warn_list; } + + /** + The number of errors, or number of rows returned by SHOW ERRORS, + also the value of session variable @@error_count. + */ + ulong error_count() const + { + return m_warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR]; + } + + /** Id of the warning information area. */ + ulonglong warn_id() const { return m_warn_id; } + + /** Do we have any errors and warnings that we can *show*? */ + bool is_empty() const { return m_warn_list.elements == 0; } + + /** Increment the current row counter to point at the next row. */ + void inc_current_row_for_warning() { m_current_row_for_warning++; } + /** Reset the current row counter. Start counting from the first row. */ + void reset_current_row_for_warning() { m_current_row_for_warning= 1; } + /** Return the current counter value. */ + ulong current_row_for_warning() const { return m_current_row_for_warning; } + + ulong statement_warn_count() const { return m_statement_warn_count; } + + /** + Reserve some space in the condition area. + This is a privileged operation, reserved for the RESIGNAL implementation, + as only the RESIGNAL statement is allowed to remove conditions from + the condition area. + For other statements, new conditions are not added to the condition + area once the condition area is full. + @param thd The current thread + @param count The number of slots to reserve + */ + void reserve_space(THD *thd, uint count); + + /** Add a new condition to the current list. */ + MYSQL_ERROR *push_warning(THD *thd, + uint sql_errno, const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg); + + /** + Set the read only status for this statement area. + This is a privileged operation, reserved for the implementation of + diagnostics related statements, to enforce that the statement area is + left untouched during execution. + The diagnostics statements are: + - SHOW WARNINGS + - SHOW ERRORS + - GET DIAGNOSTICS + @param read_only the read only property to set + */ + void set_read_only(bool read_only) + { m_read_only= read_only; } + + /** + Read only status. + @return the read only property + */ + bool is_read_only() const + { return m_read_only; } + +private: + /** Read only status. */ + bool m_read_only; + + friend class Resignal_statement; +}; + +void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, + uint code, const char *msg); void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code, const char *format, ...); -void mysql_reset_errors(THD *thd, bool force); bool mysqld_show_warnings(THD *thd, ulong levels_to_show); extern const LEX_STRING warning_level_names[]; + +#endif // SQL_ERROR_H diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index cda97ffe521..df5e3506f4b 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -810,7 +810,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, error=write_record(thd, table ,&info); if (error) break; - thd->row_count++; + thd->warning_info->inc_current_row_for_warning(); } free_underlaid_joins(thd, &thd->lex->select_lex); @@ -949,10 +949,12 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, if (ignore) sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, (lock_type == TL_WRITE_DELAYED) ? (ulong) 0 : - (ulong) (info.records - info.copied), (ulong) thd->cuted_fields); + (ulong) (info.records - info.copied), + (ulong) thd->warning_info->statement_warn_count()); else sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, - (ulong) (info.deleted + updated), (ulong) thd->cuted_fields); + (ulong) (info.deleted + updated), + (ulong) thd->warning_info->statement_warn_count()); thd->row_count_func= info.copied + info.deleted + updated; ::my_ok(thd, (ulong) thd->row_count_func, id, buff); } @@ -1955,7 +1957,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list) main thread. Use of my_message will enable stored procedures continue handlers. */ - my_message(di->thd.main_da.sql_errno(), di->thd.main_da.message(), + my_message(di->thd.stmt_da->sql_errno(), di->thd.stmt_da->message(), MYF(0)); } di->unlock(); @@ -2032,7 +2034,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) goto error; if (dead) { - my_message(thd.main_da.sql_errno(), thd.main_da.message(), MYF(0)); + my_message(thd.stmt_da->sql_errno(), thd.stmt_da->message(), MYF(0)); goto error; } } @@ -2305,8 +2307,8 @@ pthread_handler_t handle_delayed_insert(void *arg) if (my_thread_init()) { /* Can't use my_error since store_globals has not yet been called */ - thd->main_da.set_error_status(thd, ER_OUT_OF_RESOURCES, - ER(ER_OUT_OF_RESOURCES)); + thd->stmt_da->set_error_status(thd, ER_OUT_OF_RESOURCES, + ER(ER_OUT_OF_RESOURCES), NULL); goto end; } #endif @@ -2316,8 +2318,8 @@ pthread_handler_t handle_delayed_insert(void *arg) if (init_thr_lock() || thd->store_globals()) { /* Can't use my_error since store_globals has perhaps failed */ - thd->main_da.set_error_status(thd, ER_OUT_OF_RESOURCES, - ER(ER_OUT_OF_RESOURCES)); + thd->stmt_da->set_error_status(thd, ER_OUT_OF_RESOURCES, + ER(ER_OUT_OF_RESOURCES), NULL); thd->fatal_error(); goto err; } @@ -2744,7 +2746,7 @@ bool Delayed_insert::handle_inserts(void) { /* This should never happen */ table->file->print_error(error,MYF(0)); - sql_print_error("%s", thd.main_da.message()); + sql_print_error("%s", thd.stmt_da->message()); DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed in loop")); goto err; } @@ -2786,7 +2788,7 @@ bool Delayed_insert::handle_inserts(void) if ((error=table->file->extra(HA_EXTRA_NO_CACHE))) { // This shouldn't happen table->file->print_error(error,MYF(0)); - sql_print_error("%s", thd.main_da.message()); + sql_print_error("%s", thd.stmt_da->message()); DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed after loop")); goto err; } @@ -3254,10 +3256,12 @@ bool select_insert::send_eof() char buff[160]; if (info.ignore) sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, - (ulong) (info.records - info.copied), (ulong) thd->cuted_fields); + (ulong) (info.records - info.copied), + (ulong) thd->warning_info->statement_warn_count()); else sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, - (ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields); + (ulong) (info.deleted+info.updated), + (ulong) thd->warning_info->statement_warn_count()); thd->row_count_func= info.copied + info.deleted + ((thd->client_capabilities & CLIENT_FOUND_ROWS) ? info.touched : info.updated); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 76fd5354c51..47f66faf048 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -118,6 +118,7 @@ enum enum_sql_command { SQLCOM_SHOW_CREATE_TRIGGER, SQLCOM_ALTER_DB_UPGRADE, SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES, + SQLCOM_SIGNAL, SQLCOM_RESIGNAL, /* When a command is added here, be sure it's also added in mysqld.cc @@ -1518,6 +1519,62 @@ public: CHARSET_INFO *m_underscore_cs; }; +/** + Abstract representation of a statement. + This class is an interface between the parser and the runtime. + The parser builds the appropriate sub classes of Sql_statement + to represent a SQL statement in the parsed tree. + The execute() method in the sub classes contain the runtime implementation. + Note that this interface is used for SQL statement recently implemented, + the code for older statements tend to load the LEX structure with more + attributes instead. + The recommended way to implement new statements is to sub-class + Sql_statement, as this improves code modularity (see the 'big switch' in + dispatch_command()), and decrease the total size of the LEX structure + (therefore saving memory in stored programs). +*/ +class Sql_statement : public Sql_alloc +{ +public: + /** + Execute this SQL statement. + @param thd the current thread. + @return 0 on success. + */ + virtual bool execute(THD *thd) = 0; + +protected: + /** + Constructor. + @param lex the LEX structure that represents parts of this statement. + */ + Sql_statement(struct st_lex *lex) + : m_lex(lex) + {} + + /** Destructor. */ + virtual ~Sql_statement() + { + /* + Sql_statement objects are allocated in thd->mem_root. + In MySQL, the C++ destructor is never called, the underlying MEM_ROOT is + simply destroyed instead. + Do not rely on the destructor for any cleanup. + */ + DBUG_ASSERT(FALSE); + } + +protected: + /** + The legacy LEX structure for this statement. + The LEX structure contains the existing properties of the parsed tree. + TODO: with time, attributes from LEX should move to sub classes of + Sql_statement, so that the parser only builds Sql_statement objects + with the minimum set of attributes, instead of a LEX structure that + contains the collection of every possible attribute. + */ + struct st_lex *m_lex; +}; /* The state of the lex parsing. This is saved in the THD struct */ @@ -1619,6 +1676,9 @@ typedef struct st_lex : public Query_tables_list */ nesting_map allow_sum_func; enum_sql_command sql_command; + + Sql_statement *m_stmt; + /* Usually `expr` rule of yacc is quite reused but some commands better not support subqueries which comes standard with this rule, like @@ -1894,6 +1954,36 @@ typedef struct st_lex : public Query_tables_list } LEX; +/** + Set_signal_information is a container used in the parsed tree to represent + the collection of assignments to condition items in the SIGNAL and RESIGNAL + statements. +*/ +class Set_signal_information +{ +public: + /** Constructor. */ + Set_signal_information(); + + /** Copy constructor. */ + Set_signal_information(const Set_signal_information& set); + + /** Destructor. */ + ~Set_signal_information() + {} + + /** Clear all items. */ + void clear(); + + /** + For each contition item assignment, m_item[] contains the parsed tree + that represents the expression assigned, if any. + m_item[] is an array indexed by Diag_condition_item_name. + */ + Item *m_item[LAST_DIAG_SET_PROPERTY+1]; +}; + + /** The internal state of the syntax parser. This object is only available during parsing, @@ -1920,6 +2010,12 @@ public: */ uchar *yacc_yyvs; + /** + Fragments of parsed tree, + used during the parsing of SIGNAL and RESIGNAL. + */ + Set_signal_information m_set_signal_info; + /* TODO: move more attributes from the LEX structure here. */ @@ -1976,6 +2072,6 @@ extern bool is_lex_native_function(const LEX_STRING *name); @} (End of group Semantic_Analysis) */ -int my_missing_function_error(const LEX_STRING &token, const char *name); +void my_missing_function_error(const LEX_STRING &token, const char *name); #endif /* MYSQL_SERVER */ diff --git a/sql/sql_load.cc b/sql/sql_load.cc index b7f33d51335..079b6f2fe43 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -514,7 +514,8 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, goto err; } sprintf(name, ER(ER_LOAD_INFO), (ulong) info.records, (ulong) info.deleted, - (ulong) (info.records - info.copied), (ulong) thd->cuted_fields); + (ulong) (info.records - info.copied), + (ulong) thd->warning_info->statement_warn_count()); if (thd->transaction.stmt.modified_non_trans_table) thd->transaction.all.modified_non_trans_table= TRUE; @@ -645,9 +646,10 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, if (pos == read_info.row_end) { thd->cuted_fields++; /* Not enough fields */ - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_TOO_FEW_RECORDS, - ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count); + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_TOO_FEW_RECORDS, + ER(ER_WARN_TOO_FEW_RECORDS), + thd->warning_info->current_row_for_warning()); if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP) ((Field_timestamp*) field)->set_time(); } @@ -668,9 +670,10 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, if (pos != read_info.row_end) { thd->cuted_fields++; /* To long row */ - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_TOO_MANY_RECORDS, - ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count); + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_TOO_MANY_RECORDS, + ER(ER_WARN_TOO_MANY_RECORDS), + thd->warning_info->current_row_for_warning()); } if (thd->killed || @@ -703,11 +706,12 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, if (read_info.line_cuted) { thd->cuted_fields++; /* To long row */ - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_TOO_MANY_RECORDS, - ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count); + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_TOO_MANY_RECORDS, + ER(ER_WARN_TOO_MANY_RECORDS), + thd->warning_info->current_row_for_warning()); } - thd->row_count++; + thd->warning_info->inc_current_row_for_warning(); continue_loop:; } DBUG_RETURN(test(read_info.error)); @@ -773,7 +777,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, if (field->reset()) { my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name, - thd->row_count); + thd->warning_info->current_row_for_warning()); DBUG_RETURN(1); } field->set_null(); @@ -841,7 +845,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, if (field->reset()) { my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0),field->field_name, - thd->row_count); + thd->warning_info->current_row_for_warning()); DBUG_RETURN(1); } if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP) @@ -855,7 +859,8 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, thd->cuted_fields++; push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_TOO_FEW_RECORDS, - ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count); + ER(ER_WARN_TOO_FEW_RECORDS), + thd->warning_info->current_row_for_warning()); } else if (item->type() == Item::STRING_ITEM) { @@ -899,13 +904,13 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, if (read_info.line_cuted) { thd->cuted_fields++; /* To long row */ - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_TOO_MANY_RECORDS, ER(ER_WARN_TOO_MANY_RECORDS), - thd->row_count); + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_TOO_MANY_RECORDS, ER(ER_WARN_TOO_MANY_RECORDS), + thd->warning_info->current_row_for_warning()); if (thd->killed) DBUG_RETURN(1); } - thd->row_count++; + thd->warning_info->inc_current_row_for_warning(); continue_loop:; } DBUG_RETURN(test(read_info.error)); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a09fed98d65..59f947d925c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -305,8 +305,8 @@ void init_update_queries(void) sql_command_flags[SQLCOM_SHOW_AUTHORS]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_CONTRIBUTORS]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_PRIVILEGES]= CF_STATUS_COMMAND; - sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND; - sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND | CF_DIAGNOSTIC_STMT; + sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND | CF_DIAGNOSTIC_STMT; sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_ENGINE_MUTEX]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_ENGINE_LOGS]= CF_STATUS_COMMAND; @@ -790,7 +790,7 @@ bool do_command(THD *thd) Consider moving to init_connect() instead. */ thd->clear_error(); // Clear error message - thd->main_da.reset_diagnostics_area(); + thd->stmt_da->reset_diagnostics_area(); net_new_transaction(net); @@ -1053,7 +1053,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, tbl_name= strmake(db.str, packet + 1, db_len)+1; strmake(tbl_name, packet + db_len + 2, tbl_len); if (mysql_table_dump(thd, &db, tbl_name) == 0) - thd->main_da.disable_status(); + thd->stmt_da->disable_status(); break; } case COM_CHANGE_USER: @@ -1348,7 +1348,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, /* We don't calculate statistics for this command */ general_log_print(thd, command, NullS); net->error=0; // Don't give 'abort' message - thd->main_da.disable_status(); // Don't send anything back + thd->stmt_da->disable_status(); // Don't send anything back error=TRUE; // End server break; @@ -1516,7 +1516,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #ifndef EMBEDDED_LIBRARY VOID(my_net_write(net, (uchar*) buff, length)); VOID(net_flush(net)); - thd->main_da.disable_status(); + thd->stmt_da->disable_status(); #endif break; } @@ -1582,7 +1582,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, /* report error issued during command execution */ if (thd->killed_errno()) { - if (! thd->main_da.is_set()) + if (! thd->stmt_da->is_set()) thd->send_kill_message(); } if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA) @@ -1592,9 +1592,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } /* If commit fails, we should be able to reset the OK status. */ - thd->main_da.can_overwrite_status= TRUE; + thd->stmt_da->can_overwrite_status= TRUE; ha_autocommit_or_rollback(thd, thd->is_error()); - thd->main_da.can_overwrite_status= FALSE; + thd->stmt_da->can_overwrite_status= FALSE; thd->transaction.stmt.reset(); @@ -2035,8 +2035,14 @@ mysql_execute_command(THD *thd) variables, but for now this is probably good enough. Don't reset warnings when executing a stored routine. */ - if ((all_tables || !lex->is_single_level_stmt()) && !thd->spcont) - mysql_reset_errors(thd, 0); + if ((sql_command_flags[lex->sql_command] & CF_DIAGNOSTIC_STMT) != 0) + thd->warning_info->set_read_only(TRUE); + else + { + thd->warning_info->set_read_only(FALSE); + if (all_tables) + thd->warning_info->opt_clear_warning_info(thd->query_id); + } #ifdef HAVE_REPLICATION if (unlikely(thd->slave_thread)) @@ -4413,12 +4419,6 @@ create_sp_error: So just execute the statement. */ res= sp->execute_procedure(thd, &lex->value_list); - /* - If warnings have been cleared, we have to clear total_warn_count - too, otherwise the clients get confused. - */ - if (thd->warn_list.is_empty()) - thd->total_warn_count= 0; thd->variables.select_limit= select_limit; @@ -4449,7 +4449,7 @@ create_sp_error: else sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname, &thd->sp_func_cache, FALSE); - mysql_reset_errors(thd, 0); + thd->warning_info->opt_clear_warning_info(thd->query_id); if (! sp) { if (lex->spname->m_db.str) @@ -4524,7 +4524,7 @@ create_sp_error: TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION); sp_result= sp_routine_exists_in_table(thd, type, lex->spname); - mysql_reset_errors(thd, 0); + thd->warning_info->opt_clear_warning_info(thd->query_id); if (sp_result == SP_OK) { char *db= lex->spname->m_db.str; @@ -4975,6 +4975,11 @@ create_sp_error: my_ok(thd, 1); break; } + case SQLCOM_SIGNAL: + case SQLCOM_RESIGNAL: + DBUG_ASSERT(lex->m_stmt != NULL); + res= lex->m_stmt->execute(thd); + break; default: #ifndef EMBEDDED_LIBRARY DBUG_ASSERT(0); /* Impossible */ @@ -5724,8 +5729,8 @@ void mysql_reset_thd_for_next_command(THD *thd) thd->user_var_events_alloc= thd->mem_root; } thd->clear_error(); - thd->main_da.reset_diagnostics_area(); - thd->total_warn_count=0; // Warnings for this query + thd->stmt_da->reset_diagnostics_area(); + thd->warning_info->reset_for_next_command(); thd->rand_used= 0; thd->sent_row_count= thd->examined_row_count= 0; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 350b5fdd38c..75a0c538e04 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -250,7 +250,7 @@ static bool send_prep_stmt(Prepared_statement *stmt, uint columns) int2store(buff+5, columns); int2store(buff+7, stmt->param_count); buff[9]= 0; // Guard against a 4.1 client - tmp= min(stmt->thd->total_warn_count, 65535); + tmp= min(stmt->thd->warning_info->statement_warn_count(), 65535); int2store(buff+10, tmp); /* @@ -265,7 +265,7 @@ static bool send_prep_stmt(Prepared_statement *stmt, uint columns) Protocol::SEND_EOF); } /* Flag that a response has already been sent */ - thd->main_da.disable_status(); + thd->stmt_da->disable_status(); DBUG_RETURN(error); } #else @@ -277,7 +277,7 @@ static bool send_prep_stmt(Prepared_statement *stmt, thd->client_stmt_id= stmt->id; thd->client_param_count= stmt->param_count; thd->clear_error(); - thd->main_da.disable_status(); + thd->stmt_da->disable_status(); return 0; } @@ -1835,6 +1835,10 @@ static bool check_prepared_statement(Prepared_statement *stmt) lex->select_lex.context.resolve_in_table_list_only(select_lex-> get_table_list()); + /* Reset warning count for each query that uses tables */ + if (tables) + thd->warning_info->opt_clear_warning_info(thd->query_id); + switch (sql_command) { case SQLCOM_REPLACE: case SQLCOM_INSERT: @@ -2082,8 +2086,6 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length) DBUG_VOID_RETURN; } - /* Reset warnings from previous command */ - mysql_reset_errors(thd, 0); sp_cache_flush_obsolete(&thd->sp_proc_cache); sp_cache_flush_obsolete(&thd->sp_func_cache); @@ -2656,7 +2658,7 @@ void mysqld_stmt_close(THD *thd, char *packet) Prepared_statement *stmt; DBUG_ENTER("mysqld_stmt_close"); - thd->main_da.disable_status(); + thd->stmt_da->disable_status(); if (!(stmt= find_prepared_statement(thd, stmt_id))) DBUG_VOID_RETURN; @@ -2731,7 +2733,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) status_var_increment(thd->status_var.com_stmt_send_long_data); - thd->main_da.disable_status(); + thd->stmt_da->disable_status(); #ifndef EMBEDDED_LIBRARY /* Minimal size of long data packet is 6 bytes */ if (packet_length < MYSQL_LONG_DATA_HEADER) @@ -2822,6 +2824,30 @@ Select_fetch_protocol_binary::send_data(List &fields) return rc; } +/******************************************************************* +* Reprepare_observer +*******************************************************************/ +/** Push an error to the error stack and return TRUE for now. */ + +bool +Reprepare_observer::report_error(THD *thd) +{ + /* + This 'error' is purely internal to the server: + - No exception handler is invoked, + - No condition is added in the condition area (warn_list). + The diagnostics area is set to an error status to enforce + that this thread execution stops and returns to the caller, + backtracking all the way to Prepared_statement::execute_loop(). + */ + thd->stmt_da->set_error_status(thd, ER_NEED_REPREPARE, + ER(ER_NEED_REPREPARE), "HY000"); + m_invalidated= TRUE; + + return TRUE; +} + + /*************************************************************************** Prepared_statement ****************************************************************************/ @@ -3262,7 +3288,7 @@ reexecute: reprepare_observer.is_invalidated() && reprepare_attempt++ < MAX_REPREPARE_ATTEMPTS) { - DBUG_ASSERT(thd->main_da.sql_errno() == ER_NEED_REPREPARE); + DBUG_ASSERT(thd->stmt_da->sql_errno() == ER_NEED_REPREPARE); thd->clear_error(); error= reprepare(); @@ -3325,12 +3351,12 @@ Prepared_statement::reprepare() #endif /* Clear possible warnings during reprepare, it has to be completely - transparent to the user. We use mysql_reset_errors() since + transparent to the user. We use clear_warning_info() since there were no separate query id issued for re-prepare. Sic: we can't simply silence warnings during reprepare, because if it's failed, we need to return all the warnings to the user. */ - mysql_reset_errors(thd, TRUE); + thd->warning_info->clear_warning_info(thd->query_id); } return error; } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 0ec8d91214c..b6ae8860cf5 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -796,7 +796,7 @@ err: @param mi Pointer to Master_info object for the slave's IO thread. - @param net_report If true, saves the exit status into thd->main_da. + @param net_report If true, saves the exit status into thd->stmt_da. @retval 0 success @retval 1 error @@ -934,7 +934,7 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) @param mi Pointer to Master_info object for the slave's IO thread. - @param net_report If true, saves the exit status into thd->main_da. + @param net_report If true, saves the exit status into thd->stmt_da. @retval 0 success @retval 1 error diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0adb38e0838..0a55a01fcc8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10861,7 +10861,6 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) so we don't touch it here. */ join->examined_rows++; - join->thd->row_count++; DBUG_ASSERT(join->examined_rows <= 1); } else if (join->send_row_on_empty_set()) @@ -11115,7 +11114,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) /* Set first_unmatched for the last inner table of this group */ join_tab->last_inner->first_unmatched= join_tab; } - join->thd->row_count= 0; + join->thd->warning_info->reset_current_row_for_warning(); error= (*join_tab->read_first_record)(join_tab); rc= evaluate_join_record(join, join_tab, error); @@ -11225,7 +11224,6 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, (See above join->return_tab= tab). */ join->examined_rows++; - join->thd->row_count++; DBUG_PRINT("counts", ("join->examined_rows++: %lu", (ulong) join->examined_rows)); @@ -11234,6 +11232,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, enum enum_nested_loop_state rc; /* A match from join_tab is found for the current partial join. */ rc= (*join_tab->next_select)(join, join_tab+1, 0); + join->thd->warning_info->inc_current_row_for_warning(); if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS) return rc; if (join->return_tab < join_tab) @@ -11247,7 +11246,10 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, return NESTED_LOOP_NO_MORE_ROWS; } else + { + join->thd->warning_info->inc_current_row_for_warning(); join_tab->read_record.file->unlock_row(); + } } else { @@ -11256,7 +11258,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, with the beginning coinciding with the current partial join. */ join->examined_rows++; - join->thd->row_count++; + join->thd->warning_info->inc_current_row_for_warning(); join_tab->read_record.file->unlock_row(); } return NESTED_LOOP_OK; diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index f8a8dea18ff..33058887952 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -242,7 +242,7 @@ bool servers_reload(THD *thd) if (simple_open_n_lock_tables(thd, tables)) { sql_print_error("Can't open and lock privilege tables: %s", - thd->main_da.message()); + thd->stmt_da->message()); goto end; } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 5c2c351652b..b16f050dea6 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -598,7 +598,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) if (open_normal_and_derived_tables(thd, table_list, 0)) { if (!table_list->view || - (thd->is_error() && thd->main_da.sql_errno() != ER_VIEW_INVALID)) + (thd->is_error() && thd->stmt_da->sql_errno() != ER_VIEW_INVALID)) DBUG_RETURN(TRUE); /* @@ -606,7 +606,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) issue a warning with 'warning' level status in case of invalid view and last error is ER_VIEW_INVALID */ - mysql_reset_errors(thd, true); + thd->warning_info->clear_warning_info(thd->query_id); thd->clear_error(); push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN, @@ -2986,7 +2986,7 @@ static int fill_schema_table_names(THD *thd, TABLE *table, default: DBUG_ASSERT(0); } - if (thd->is_error() && thd->main_da.sql_errno() == ER_NO_SUCH_TABLE) + if (thd->is_error() && thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE) { thd->clear_error(); return 0; @@ -3350,10 +3350,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) can return an error without setting an error message in THD, which is a hack. This is why we have to check for res, then for thd->is_error() only then - for thd->main_da.sql_errno(). + for thd->stmt_da->sql_errno(). */ if (res && thd->is_error() && - thd->main_da.sql_errno() == ER_NO_SUCH_TABLE) + thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE) { /* Hide error for not existing table. @@ -3507,7 +3507,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, /* there was errors during opening tables */ - const char *error= thd->is_error() ? thd->main_da.message() : ""; + const char *error= thd->is_error() ? thd->stmt_da->message() : ""; if (tables->view) table->field[3]->store(STRING_WITH_LEN("VIEW"), cs); else if (tables->schema_table) @@ -3711,7 +3711,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, */ if (thd->is_error()) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - thd->main_da.sql_errno(), thd->main_da.message()); + thd->stmt_da->sql_errno(), thd->stmt_da->message()); thd->clear_error(); res= 0; } @@ -4223,7 +4223,7 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables, */ if (thd->is_error()) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - thd->main_da.sql_errno(), thd->main_da.message()); + thd->stmt_da->sql_errno(), thd->stmt_da->message()); thd->clear_error(); res= 0; } @@ -4436,7 +4436,7 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables, DBUG_RETURN(1); if (res && thd->is_error()) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - thd->main_da.sql_errno(), thd->main_da.message()); + thd->stmt_da->sql_errno(), thd->stmt_da->message()); } if (res) thd->clear_error(); @@ -4469,7 +4469,7 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, { if (thd->is_error()) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - thd->main_da.sql_errno(), thd->main_da.message()); + thd->stmt_da->sql_errno(), thd->stmt_da->message()); thd->clear_error(); DBUG_RETURN(0); } @@ -4574,7 +4574,7 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables, { if (thd->is_error()) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - thd->main_da.sql_errno(), thd->main_da.message()); + thd->stmt_da->sql_errno(), thd->stmt_da->message()); thd->clear_error(); DBUG_RETURN(0); } @@ -4653,7 +4653,7 @@ static int get_schema_key_column_usage_record(THD *thd, { if (thd->is_error()) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - thd->main_da.sql_errno(), thd->main_da.message()); + thd->stmt_da->sql_errno(), thd->stmt_da->message()); thd->clear_error(); DBUG_RETURN(0); } @@ -4848,7 +4848,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables, { if (thd->is_error()) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - thd->main_da.sql_errno(), thd->main_da.message()); + thd->stmt_da->sql_errno(), thd->stmt_da->message()); thd->clear_error(); DBUG_RETURN(0); } @@ -5386,7 +5386,7 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables, { if (thd->is_error()) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - thd->main_da.sql_errno(), thd->main_da.message()); + thd->stmt_da->sql_errno(), thd->stmt_da->message()); thd->clear_error(); DBUG_RETURN(0); } diff --git a/sql/sql_signal.cc b/sql/sql_signal.cc new file mode 100644 index 00000000000..c9ab37272b8 --- /dev/null +++ b/sql/sql_signal.cc @@ -0,0 +1,510 @@ +/* Copyright (C) 2008 Sun Microsystems, Inc + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include "mysql_priv.h" +#include "sp_head.h" +#include "sp_pcontext.h" +#include "sp_rcontext.h" +#include "sql_signal.h" + +/* + The parser accepts any error code (desired) + The runtime internally supports any error code (desired) + The client server protocol is limited to 16 bits error codes (restriction) + Enforcing the 65535 limit in the runtime until the protocol can change. +*/ +#define MAX_MYSQL_ERRNO UINT_MAX16 + +const LEX_STRING Diag_condition_item_names[]= +{ + { C_STRING_WITH_LEN("CLASS_ORIGIN") }, + { C_STRING_WITH_LEN("SUBCLASS_ORIGIN") }, + { C_STRING_WITH_LEN("CONSTRAINT_CATALOG") }, + { C_STRING_WITH_LEN("CONSTRAINT_SCHEMA") }, + { C_STRING_WITH_LEN("CONSTRAINT_NAME") }, + { C_STRING_WITH_LEN("CATALOG_NAME") }, + { C_STRING_WITH_LEN("SCHEMA_NAME") }, + { C_STRING_WITH_LEN("TABLE_NAME") }, + { C_STRING_WITH_LEN("COLUMN_NAME") }, + { C_STRING_WITH_LEN("CURSOR_NAME") }, + { C_STRING_WITH_LEN("MESSAGE_TEXT") }, + { C_STRING_WITH_LEN("MYSQL_ERRNO") }, + + { C_STRING_WITH_LEN("CONDITION_IDENTIFIER") }, + { C_STRING_WITH_LEN("CONDITION_NUMBER") }, + { C_STRING_WITH_LEN("CONNECTION_NAME") }, + { C_STRING_WITH_LEN("MESSAGE_LENGTH") }, + { C_STRING_WITH_LEN("MESSAGE_OCTET_LENGTH") }, + { C_STRING_WITH_LEN("PARAMETER_MODE") }, + { C_STRING_WITH_LEN("PARAMETER_NAME") }, + { C_STRING_WITH_LEN("PARAMETER_ORDINAL_POSITION") }, + { C_STRING_WITH_LEN("RETURNED_SQLSTATE") }, + { C_STRING_WITH_LEN("ROUTINE_CATALOG") }, + { C_STRING_WITH_LEN("ROUTINE_NAME") }, + { C_STRING_WITH_LEN("ROUTINE_SCHEMA") }, + { C_STRING_WITH_LEN("SERVER_NAME") }, + { C_STRING_WITH_LEN("SPECIFIC_NAME") }, + { C_STRING_WITH_LEN("TRIGGER_CATALOG") }, + { C_STRING_WITH_LEN("TRIGGER_NAME") }, + { C_STRING_WITH_LEN("TRIGGER_SCHEMA") } +}; + +const LEX_STRING Diag_statement_item_names[]= +{ + { C_STRING_WITH_LEN("NUMBER") }, + { C_STRING_WITH_LEN("MORE") }, + { C_STRING_WITH_LEN("COMMAND_FUNCTION") }, + { C_STRING_WITH_LEN("COMMAND_FUNCTION_CODE") }, + { C_STRING_WITH_LEN("DYNAMIC_FUNCTION") }, + { C_STRING_WITH_LEN("DYNAMIC_FUNCTION_CODE") }, + { C_STRING_WITH_LEN("ROW_COUNT") }, + { C_STRING_WITH_LEN("TRANSACTIONS_COMMITTED") }, + { C_STRING_WITH_LEN("TRANSACTIONS_ROLLED_BACK") }, + { C_STRING_WITH_LEN("TRANSACTION_ACTIVE") } +}; + +Set_signal_information::Set_signal_information() +{ + clear(); +} + +Set_signal_information::Set_signal_information( + const Set_signal_information& set) +{ + memcpy(m_item, set.m_item, sizeof(m_item)); +} + +void Set_signal_information::clear() +{ + memset(m_item, 0, sizeof(m_item)); +} + +void Signal_common::assign_defaults(MYSQL_ERROR *cond, + bool set_level_code, + MYSQL_ERROR::enum_warning_level level, + int sqlcode) +{ + if (set_level_code) + { + cond->m_level= level; + cond->m_sql_errno= sqlcode; + } + if (! cond->get_message_text()) + cond->set_builtin_message_text(ER(sqlcode)); +} + +void Signal_common::eval_defaults(THD *thd, MYSQL_ERROR *cond) +{ + DBUG_ASSERT(cond); + + const char* sqlstate; + bool set_defaults= (m_cond != 0); + + if (set_defaults) + { + /* + SIGNAL is restricted in sql_yacc.yy to only signal SQLSTATE conditions. + */ + DBUG_ASSERT(m_cond->type == sp_cond_type::state); + sqlstate= m_cond->sqlstate; + cond->set_sqlstate(sqlstate); + } + else + sqlstate= cond->get_sqlstate(); + + DBUG_ASSERT(sqlstate); + /* SQLSTATE class "00": illegal, rejected in the parser. */ + DBUG_ASSERT((sqlstate[0] != '0') || (sqlstate[1] != '0')); + + if ((sqlstate[0] == '0') && (sqlstate[1] == '1')) + { + /* SQLSTATE class "01": warning. */ + assign_defaults(cond, set_defaults, + MYSQL_ERROR::WARN_LEVEL_WARN, ER_SIGNAL_WARN); + } + else if ((sqlstate[0] == '0') && (sqlstate[1] == '2')) + { + /* SQLSTATE class "02": not found. */ + assign_defaults(cond, set_defaults, + MYSQL_ERROR::WARN_LEVEL_ERROR, ER_SIGNAL_NOT_FOUND); + } + else + { + /* other SQLSTATE classes : error. */ + assign_defaults(cond, set_defaults, + MYSQL_ERROR::WARN_LEVEL_ERROR, ER_SIGNAL_EXCEPTION); + } +} + +static bool assign_fixed_string(MEM_ROOT *mem_root, + CHARSET_INFO *dst_cs, + size_t max_char, + String *dst, + const String* src) +{ + bool truncated; + size_t numchars; + CHARSET_INFO *src_cs; + const char* src_str; + const char* src_end; + size_t src_len; + size_t to_copy; + char* dst_str; + size_t dst_len; + size_t dst_copied; + uint32 dummy_offset; + + src_str= src->ptr(); + if (src_str == NULL) + { + dst->set((const char*) NULL, 0, dst_cs); + return false; + } + + src_cs= src->charset(); + src_len= src->length(); + src_end= src_str + src_len; + numchars= src_cs->cset->numchars(src_cs, src_str, src_end); + + if (numchars <= max_char) + { + to_copy= src->length(); + truncated= false; + } + else + { + numchars= max_char; + to_copy= dst_cs->cset->charpos(dst_cs, src_str, src_end, numchars); + truncated= true; + } + + if (String::needs_conversion(to_copy, src_cs, dst_cs, & dummy_offset)) + { + dst_len= numchars * dst_cs->mbmaxlen; + dst_str= (char*) alloc_root(mem_root, dst_len + 1); + if (dst_str) + { + const char* well_formed_error_pos; + const char* cannot_convert_error_pos; + const char* from_end_pos; + + dst_copied= well_formed_copy_nchars(dst_cs, dst_str, dst_len, + src_cs, src_str, src_len, + numchars, + & well_formed_error_pos, + & cannot_convert_error_pos, + & from_end_pos); + DBUG_ASSERT(dst_copied <= dst_len); + dst_len= dst_copied; /* In case the copy truncated the data */ + dst_str[dst_copied]= '\0'; + } + } + else + { + dst_len= to_copy; + dst_str= (char*) alloc_root(mem_root, dst_len + 1); + if (dst_str) + { + memcpy(dst_str, src_str, to_copy); + dst_str[to_copy]= '\0'; + } + } + dst->set(dst_str, dst_len, dst_cs); + + return truncated; +} + +static int assign_condition_item(MEM_ROOT *mem_root, const char* name, THD *thd, + Item *set, String *ci) +{ + char str_buff[(64+1)*4]; /* Room for a null terminated UTF8 String 64 */ + String str_value(str_buff, sizeof(str_buff), & my_charset_utf8_bin); + String *str; + bool truncated; + + DBUG_ENTER("assign_condition_item"); + + if (set->is_null()) + { + thd->raise_error_printf(ER_WRONG_VALUE_FOR_VAR, name, "NULL"); + DBUG_RETURN(1); + } + + str= set->val_str(& str_value); + truncated= assign_fixed_string(mem_root, & my_charset_utf8_bin, 64, ci, str); + if (truncated) + { + if (thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | + MODE_STRICT_ALL_TABLES)) + { + thd->raise_error_printf(ER_COND_ITEM_TOO_LONG, name); + DBUG_RETURN(1); + } + + thd->raise_warning_printf(WARN_COND_ITEM_TRUNCATED, name); + } + + DBUG_RETURN(0); +} + + +int Signal_common::eval_signal_informations(THD *thd, MYSQL_ERROR *cond) +{ + struct cond_item_map + { + enum enum_diag_condition_item_name m_item; + String MYSQL_ERROR::*m_member; + }; + + static cond_item_map map[]= + { + { DIAG_CLASS_ORIGIN, & MYSQL_ERROR::m_class_origin }, + { DIAG_SUBCLASS_ORIGIN, & MYSQL_ERROR::m_subclass_origin }, + { DIAG_CONSTRAINT_CATALOG, & MYSQL_ERROR::m_constraint_catalog }, + { DIAG_CONSTRAINT_SCHEMA, & MYSQL_ERROR::m_constraint_schema }, + { DIAG_CONSTRAINT_NAME, & MYSQL_ERROR::m_constraint_name }, + { DIAG_CATALOG_NAME, & MYSQL_ERROR::m_catalog_name }, + { DIAG_SCHEMA_NAME, & MYSQL_ERROR::m_schema_name }, + { DIAG_TABLE_NAME, & MYSQL_ERROR::m_table_name }, + { DIAG_COLUMN_NAME, & MYSQL_ERROR::m_column_name }, + { DIAG_CURSOR_NAME, & MYSQL_ERROR::m_cursor_name } + }; + + Item *set; + String str_value; + String *str; + int i; + uint j; + int result= 1; + enum enum_diag_condition_item_name item_enum; + String *member; + const LEX_STRING *name; + + DBUG_ENTER("Signal_common::eval_signal_informations"); + + for (i= FIRST_DIAG_SET_PROPERTY; + i <= LAST_DIAG_SET_PROPERTY; + i++) + { + set= m_set_signal_information.m_item[i]; + if (set) + { + if (! set->fixed) + { + if (set->fix_fields(thd, & set)) + goto end; + m_set_signal_information.m_item[i]= set; + } + } + } + + /* + Generically assign all the UTF8 String 64 condition items + described in the map. + */ + for (j= 0; j < array_elements(map); j++) + { + item_enum= map[j].m_item; + set= m_set_signal_information.m_item[item_enum]; + if (set != NULL) + { + member= & (cond->* map[j].m_member); + name= & Diag_condition_item_names[item_enum]; + if (assign_condition_item(cond->m_mem_root, name->str, thd, set, member)) + goto end; + } + } + + /* + Assign the remaining attributes. + */ + + set= m_set_signal_information.m_item[DIAG_MESSAGE_TEXT]; + if (set != NULL) + { + if (set->is_null()) + { + thd->raise_error_printf(ER_WRONG_VALUE_FOR_VAR, + "MESSAGE_TEXT", "NULL"); + goto end; + } + /* + Enforce that SET MESSAGE_TEXT = evaluates the value + as VARCHAR(128) CHARACTER SET UTF8. + */ + bool truncated; + String utf8_text; + str= set->val_str(& str_value); + truncated= assign_fixed_string(thd->mem_root, & my_charset_utf8_bin, 128, + & utf8_text, str); + if (truncated) + { + if (thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | + MODE_STRICT_ALL_TABLES)) + { + thd->raise_error_printf(ER_COND_ITEM_TOO_LONG, + "MESSAGE_TEXT"); + goto end; + } + + thd->raise_warning_printf(WARN_COND_ITEM_TRUNCATED, + "MESSAGE_TEXT"); + } + + /* + See the comments + "Design notes about MYSQL_ERROR::m_message_text." + in file sql_error.cc + */ + String converted_text; + converted_text.set_charset(error_message_charset_info); + converted_text.append(utf8_text.ptr(), utf8_text.length(), + utf8_text.charset()); + cond->set_builtin_message_text(converted_text.c_ptr_safe()); + } + + set= m_set_signal_information.m_item[DIAG_MYSQL_ERRNO]; + if (set != NULL) + { + if (set->is_null()) + { + thd->raise_error_printf(ER_WRONG_VALUE_FOR_VAR, + "MYSQL_ERRNO", "NULL"); + goto end; + } + longlong code= set->val_int(); + if ((code <= 0) || (code > MAX_MYSQL_ERRNO)) + { + str= set->val_str(& str_value); + thd->raise_error_printf(ER_WRONG_VALUE_FOR_VAR, + "MYSQL_ERRNO", str->c_ptr_safe()); + goto end; + } + cond->m_sql_errno= (int) code; + } + + /* + The various item->val_xxx() methods don't return an error code, + but flag thd in case of failure. + */ + if (! thd->is_error()) + result= 0; + +end: + for (i= FIRST_DIAG_SET_PROPERTY; + i <= LAST_DIAG_SET_PROPERTY; + i++) + { + set= m_set_signal_information.m_item[i]; + if (set) + { + if (set->fixed) + set->cleanup(); + } + } + + DBUG_RETURN(result); +} + +bool Signal_common::raise_condition(THD *thd, MYSQL_ERROR *cond) +{ + bool result= TRUE; + + DBUG_ENTER("Signal_common::raise_condition"); + + DBUG_ASSERT(m_lex->query_tables == NULL); + + eval_defaults(thd, cond); + if (eval_signal_informations(thd, cond)) + DBUG_RETURN(result); + + /* SIGNAL should not signal WARN_LEVEL_NOTE */ + DBUG_ASSERT((cond->m_level == MYSQL_ERROR::WARN_LEVEL_WARN) || + (cond->m_level == MYSQL_ERROR::WARN_LEVEL_ERROR)); + + MYSQL_ERROR *raised= NULL; + raised= thd->raise_condition(cond->get_sql_errno(), + cond->get_sqlstate(), + cond->get_level(), + cond->get_message_text()); + if (raised) + raised->copy_opt_attributes(cond); + + if (cond->m_level == MYSQL_ERROR::WARN_LEVEL_WARN) + { + my_ok(thd); + result= FALSE; + } + + DBUG_RETURN(result); +} + +bool Signal_statement::execute(THD *thd) +{ + bool result= TRUE; + MYSQL_ERROR cond(thd->mem_root); + + DBUG_ENTER("Signal_statement::execute"); + + thd->stmt_da->reset_diagnostics_area(); + thd->row_count_func= 0; + thd->warning_info->clear_warning_info(thd->query_id); + + result= raise_condition(thd, &cond); + + DBUG_RETURN(result); +} + + +bool Resignal_statement::execute(THD *thd) +{ + MYSQL_ERROR *signaled; + int result= TRUE; + + DBUG_ENTER("Resignal_statement::execute"); + + thd->warning_info->m_warn_id= thd->query_id; + + if (! thd->spcont || ! (signaled= thd->spcont->raised_condition())) + { + thd->raise_error(ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER); + DBUG_RETURN(result); + } + + if (m_cond == NULL) + { + /* RESIGNAL without signal_value */ + result= raise_condition(thd, signaled); + DBUG_RETURN(result); + } + + /* RESIGNAL with signal_value */ + + /* Make room for 2 conditions */ + thd->warning_info->reserve_space(thd, 2); + + MYSQL_ERROR *raised= NULL; + raised= thd->raise_condition_no_handler(signaled->get_sql_errno(), + signaled->get_sqlstate(), + signaled->get_level(), + signaled->get_message_text()); + if (raised) + raised->copy_opt_attributes(signaled); + + result= raise_condition(thd, signaled); + + DBUG_RETURN(result); +} + diff --git a/sql/sql_signal.h b/sql/sql_signal.h new file mode 100644 index 00000000000..c9c1517f4ad --- /dev/null +++ b/sql/sql_signal.h @@ -0,0 +1,152 @@ +/* Copyright (C) 2008 Sun Microsystems, Inc + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef SQL_SIGNAL_H +#define SQL_SIGNAL_H + +/** + Signal_common represents the common properties of the SIGNAL and RESIGNAL + statements. +*/ +class Signal_common : public Sql_statement +{ +protected: + /** + Constructor. + @param lex the LEX structure for this statement. + @param cond the condition signaled if any, or NULL. + @param set collection of signal condition item assignments. + */ + Signal_common(LEX *lex, + const sp_cond_type_t *cond, + const Set_signal_information& set) + : Sql_statement(lex), + m_cond(cond), + m_set_signal_information(set) + {} + + virtual ~Signal_common() + {} + + /** + Assign the condition items 'MYSQL_ERRNO', 'level' and 'MESSAGE_TEXT' + default values of a condition. + @param cond the condition to update. + @param set_level_code true if 'level' and 'MYSQL_ERRNO' needs to be overwritten + @param level the level to assign + @param sqlcode the sql code to assign + */ + static void assign_defaults(MYSQL_ERROR *cond, + bool set_level_code, + MYSQL_ERROR::enum_warning_level level, + int sqlcode); + + /** + Evaluate the condition items 'SQLSTATE', 'MYSQL_ERRNO', 'level' and 'MESSAGE_TEXT' + default values for this statement. + @param thd the current thread. + @param cond the condition to update. + */ + void eval_defaults(THD *thd, MYSQL_ERROR *cond); + + /** + Evaluate each signal condition items for this statement. + @param thd the current thread. + @param cond the condition to update. + @return 0 on success. + */ + int eval_signal_informations(THD *thd, MYSQL_ERROR *cond); + + /** + Raise a SQL condition. + @param thd the current thread. + @param cond the condition to raise. + @return false on success. + */ + bool raise_condition(THD *thd, MYSQL_ERROR *cond); + + /** + The condition to signal or resignal. + This member is optional and can be NULL (RESIGNAL). + */ + const sp_cond_type_t *m_cond; + + /** + Collection of 'SET item = value' assignments in the + SIGNAL/RESIGNAL statement. + */ + Set_signal_information m_set_signal_information; +}; + +/** + Signal_statement represents a SIGNAL statement. +*/ +class Signal_statement : public Signal_common +{ +public: + /** + Constructor, used to represent a SIGNAL statement. + @param lex the LEX structure for this statement. + @param cond the SQL condition to signal (required). + @param set the collection of signal informations to signal. + */ + Signal_statement(LEX *lex, + const sp_cond_type_t *cond, + const Set_signal_information& set) + : Signal_common(lex, cond, set) + {} + + virtual ~Signal_statement() + {} + + /** + Execute a SIGNAL statement at runtime. + @param thd the current thread. + @return false on success. + */ + virtual bool execute(THD *thd); +}; + +/** + Resignal_statement represents a RESIGNAL statement. +*/ +class Resignal_statement : public Signal_common +{ +public: + /** + Constructor, used to represent a RESIGNAL statement. + @param lex the LEX structure for this statement. + @param cond the SQL condition to resignal (optional, may be NULL). + @param set the collection of signal informations to resignal. + */ + Resignal_statement(LEX *lex, + const sp_cond_type_t *cond, + const Set_signal_information& set) + : Signal_common(lex, cond, set) + {} + + virtual ~Resignal_statement() + {} + + /** + Execute a RESIGNAL statement at runtime. + @param thd the current thread. + @return 0 on success. + */ + virtual bool execute(THD *thd); +}; + +#endif + diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 81d00f46000..d0e4fb06b49 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4592,17 +4592,17 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, if (!table->table) { DBUG_PRINT("admin", ("open table failed")); - if (!thd->warn_list.elements) - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + if (thd->warning_info->is_empty()) + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE)); /* if it was a view will check md5 sum */ if (table->view && view_checksum(thd, table) == HA_ADMIN_WRONG_CHECKSUM) - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_VIEW_CHECKSUM, ER(ER_VIEW_CHECKSUM)); - if (thd->main_da.is_error() && - (thd->main_da.sql_errno() == ER_NO_SUCH_TABLE || - thd->main_da.sql_errno() == ER_FILE_NOT_FOUND)) + if (thd->stmt_da->is_error() && + (thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE || + thd->stmt_da->sql_errno() == ER_FILE_NOT_FOUND)) /* A missing table is just issued as a failed command */ result_code= HA_ADMIN_FAILED; else @@ -4644,7 +4644,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, table->table=0; // For query cache if (protocol->write()) goto err; - thd->main_da.reset_diagnostics_area(); + thd->stmt_da->reset_diagnostics_area(); continue; /* purecov: end */ } @@ -4704,8 +4704,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, we will store the error message in a result set row and then clear. */ - if (thd->main_da.is_ok()) - thd->main_da.reset_diagnostics_area(); + if (thd->stmt_da->is_ok()) + thd->stmt_da->reset_diagnostics_area(); goto send_result; } } @@ -4719,21 +4719,21 @@ send_result: lex->cleanup_after_one_table_open(); thd->clear_error(); // these errors shouldn't get client { - List_iterator_fast it(thd->warn_list); + List_iterator_fast it(thd->warning_info->warn_list()); MYSQL_ERROR *err; while ((err= it++)) { protocol->prepare_for_resend(); protocol->store(table_name, system_charset_info); protocol->store((char*) operator_name, system_charset_info); - protocol->store(warning_level_names[err->level].str, - warning_level_names[err->level].length, + protocol->store(warning_level_names[err->get_level()].str, + warning_level_names[err->get_level()].length, system_charset_info); - protocol->store(err->msg, system_charset_info); + protocol->store(err->get_message_text(), system_charset_info); if (protocol->write()) goto err; } - mysql_reset_errors(thd, true); + thd->warning_info->clear_warning_info(thd->query_id); } protocol->prepare_for_resend(); protocol->store(table_name, system_charset_info); @@ -4828,8 +4828,8 @@ send_result_message: we will store the error message in a result set row and then clear. */ - if (thd->main_da.is_ok()) - thd->main_da.reset_diagnostics_area(); + if (thd->stmt_da->is_ok()) + thd->stmt_da->reset_diagnostics_area(); ha_autocommit_or_rollback(thd, 0); close_thread_tables(thd); if (!result_code) // recreation went ok @@ -4847,7 +4847,7 @@ send_result_message: DBUG_ASSERT(thd->is_error()); if (thd->is_error()) { - const char *err_msg= thd->main_da.message(); + const char *err_msg= thd->stmt_da->message(); if (!thd->vio_ok()) { sql_print_error("%s", err_msg); @@ -7442,7 +7442,8 @@ err: the table to be altered isn't empty. Report error here. */ - if (alter_info->error_if_not_empty && thd->row_count) + if (alter_info->error_if_not_empty && + thd->warning_info->current_row_for_warning()) { const char *f_val= 0; enum enum_mysql_timestamp_type t_type= MYSQL_TIMESTAMP_DATE; @@ -7463,7 +7464,7 @@ err: } bool save_abort_on_warning= thd->abort_on_warning; thd->abort_on_warning= TRUE; - make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, f_val, strlength(f_val), t_type, alter_info->datetime_field->field_name); thd->abort_on_warning= save_abort_on_warning; @@ -7610,7 +7611,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE); if (ignore) to->file->extra(HA_EXTRA_IGNORE_DUP_KEY); - thd->row_count= 0; + thd->warning_info->reset_current_row_for_warning(); restore_record(to, s->default_values); // Create empty record while (!(error=info.read_record(&info))) { @@ -7620,7 +7621,6 @@ copy_data_between_tables(TABLE *from,TABLE *to, error= 1; break; } - thd->row_count++; /* Return error if source table isn't empty. */ if (error_if_not_empty) { @@ -7670,6 +7670,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, } else found_count++; + thd->warning_info->inc_current_row_for_warning(); } end_read_record(&info); free_io_cache(from); diff --git a/sql/sql_tablespace.cc b/sql/sql_tablespace.cc index 9fec0e3bc63..3549a44807e 100644 --- a/sql/sql_tablespace.cc +++ b/sql/sql_tablespace.cc @@ -31,7 +31,7 @@ int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info) { hton= ha_default_handlerton(thd); if (ts_info->storage_engine != 0) - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_USING_OTHER_HANDLER, ER(ER_WARN_USING_OTHER_HANDLER), ha_resolve_storage_engine_name(hton), @@ -60,7 +60,7 @@ int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info) } else { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, ER(ER_ILLEGAL_HA_CREATE_OPTION), ha_resolve_storage_engine_name(hton), diff --git a/sql/sql_update.cc b/sql/sql_update.cc index d4c1acabe11..f5c4b85e904 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -725,7 +725,7 @@ int mysql_update(THD *thd, } else table->file->unlock_row(); - thd->row_count++; + thd->warning_info->inc_current_row_for_warning(); if (thd->is_error()) { error= 1; @@ -831,8 +831,9 @@ int mysql_update(THD *thd, if (error < 0) { char buff[STRING_BUFFER_USUAL_SIZE]; - my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated, - (ulong) thd->cuted_fields); + my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found, + (ulong) updated, + (ulong) thd->warning_info->statement_warn_count()); thd->row_count_func= (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated; my_ok(thd, (ulong) thd->row_count_func, id, buff); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4ed9946a334..2d884cb739c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -43,6 +43,7 @@ #include "sp_pcontext.h" #include "sp_rcontext.h" #include "sp.h" +#include "sql_signal.h" #include "event_parse_data.h" #include #include @@ -507,6 +508,7 @@ Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal, sp_head *sphead; struct p_elem_val *p_elem_value; enum index_hint_type index_hint; + Diag_condition_item_name diag_condition_item_name; } %{ @@ -588,6 +590,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token CASCADED /* SQL-2003-R */ %token CASE_SYM /* SQL-2003-R */ %token CAST_SYM /* SQL-2003-R */ +%token CATALOG_NAME_SYM /* SQL-2003-N */ %token CHAIN_SYM /* SQL-2003-N */ %token CHANGE %token CHANGED @@ -596,6 +599,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token CHECKSUM_SYM %token CHECK_SYM /* SQL-2003-R */ %token CIPHER_SYM +%token CLASS_ORIGIN_SYM /* SQL-2003-N */ %token CLIENT_SYM %token CLOSE_SYM /* SQL-2003-R */ %token COALESCE /* SQL-2003-N */ @@ -604,6 +608,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token COLLATION_SYM /* SQL-2003-N */ %token COLUMNS %token COLUMN_SYM /* SQL-2003-R */ +%token COLUMN_NAME_SYM /* SQL-2003-N */ %token COMMENT_SYM %token COMMITTED_SYM /* SQL-2003-N */ %token COMMIT_SYM /* SQL-2003-R */ @@ -611,10 +616,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token COMPLETION_SYM %token COMPRESSED_SYM %token CONCURRENT -%token CONDITION_SYM /* SQL-2003-N */ +%token CONDITION_SYM /* SQL-2003-R, SQL-2008-R */ %token CONNECTION_SYM %token CONSISTENT_SYM %token CONSTRAINT /* SQL-2003-R */ +%token CONSTRAINT_CATALOG_SYM /* SQL-2003-N */ +%token CONSTRAINT_NAME_SYM /* SQL-2003-N */ +%token CONSTRAINT_SCHEMA_SYM /* SQL-2003-N */ %token CONTAINS_SYM /* SQL-2003-N */ %token CONTEXT_SYM %token CONTINUE_SYM /* SQL-2003-R */ @@ -628,6 +636,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token CURDATE /* MYSQL-FUNC */ %token CURRENT_USER /* SQL-2003-R */ %token CURSOR_SYM /* SQL-2003-R */ +%token CURSOR_NAME_SYM /* SQL-2003-N */ %token CURTIME /* MYSQL-FUNC */ %token DATABASE %token DATABASES @@ -829,6 +838,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token MEDIUM_SYM %token MEMORY_SYM %token MERGE_SYM /* SQL-2003-R */ +%token MESSAGE_TEXT_SYM /* SQL-2003-N */ %token MICROSECOND_SYM /* MYSQL-FUNC */ %token MIGRATE_SYM %token MINUTE_MICROSECOND_SYM @@ -845,6 +855,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token MULTIPOINT %token MULTIPOLYGON %token MUTEX_SYM +%token MYSQL_ERRNO_SYM %token NAMES_SYM /* SQL-2003-N */ %token NAME_SYM /* SQL-2003-N */ %token NATIONAL_SYM /* SQL-2003-R */ @@ -945,6 +956,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token REPLICATION %token REQUIRE_SYM %token RESET_SYM +%token RESIGNAL_SYM /* SQL-2003-R */ %token RESOURCES %token RESTORE_SYM %token RESTRICT @@ -962,6 +974,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token RTREE_SYM %token SAVEPOINT_SYM /* SQL-2003-R */ %token SCHEDULE_SYM +%token SCHEMA_NAME_SYM /* SQL-2003-N */ %token SECOND_MICROSECOND_SYM %token SECOND_SYM /* SQL-2003-R */ %token SECURITY_SYM /* SQL-2003-N */ @@ -980,6 +993,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token SHIFT_RIGHT /* OPERATOR */ %token SHOW %token SHUTDOWN +%token SIGNAL_SYM /* SQL-2003-R */ %token SIGNED_SYM %token SIMPLE_SYM /* SQL-2003-N */ %token SLAVE @@ -1013,6 +1027,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token STORAGE_SYM %token STRAIGHT_JOIN %token STRING_SYM +%token SUBCLASS_ORIGIN_SYM /* SQL-2003-N */ %token SUBDATE_SYM %token SUBJECT_SYM %token SUBPARTITIONS_SYM @@ -1029,6 +1044,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token TABLE_REF_PRIORITY %token TABLE_SYM /* SQL-2003-R */ %token TABLE_CHECKSUM_SYM +%token TABLE_NAME_SYM /* SQL-2003-N */ %token TEMPORARY /* SQL-2003-N */ %token TEMPTABLE_SYM %token TERMINATED @@ -1186,6 +1202,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); function_call_nonkeyword function_call_generic function_call_conflict + signal_allowed_expr %type NUM_literal @@ -1313,13 +1330,16 @@ END_OF_INPUT %type case_stmt_specification simple_case_stmt searched_case_stmt %type sp_decl_idents sp_opt_inout sp_handler_type sp_hcond_list -%type sp_cond sp_hcond +%type sp_cond sp_hcond sqlstate signal_value opt_signal_value %type sp_decls sp_decl %type sp_cursor_stmt %type sp_name %type index_hint_type %type index_hint_clause +%type signal_stmt resignal_stmt +%type signal_condition_information_item_name + %type '-' '+' '*' '/' '%' '(' ')' ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM @@ -1440,12 +1460,14 @@ statement: | repair | replace | reset + | resignal_stmt | restore | revoke | rollback | savepoint | select | set + | signal_stmt | show | slave | start @@ -2339,12 +2361,12 @@ sp_decl: LEX *lex= Lex; sp_pcontext *spc= lex->spcont; - if (spc->find_cond(&$2, TRUE)) - { - my_error(ER_SP_DUP_COND, MYF(0), $2.str); - MYSQL_YYABORT; - } - if(YYTHD->lex->spcont->push_cond(&$2, $5)) + if (spc->find_cond(&$2, TRUE)) + { + my_error(ER_SP_DUP_COND, MYF(0), $2.str); + MYSQL_YYABORT; + } + if(YYTHD->lex->spcont->push_cond(&$2, $5)) MYSQL_YYABORT; $$.vars= $$.hndlrs= $$.curs= 0; $$.conds= 1; @@ -2359,9 +2381,9 @@ sp_decl: sp_pcontext *ctx= lex->spcont; sp_instr_hpush_jump *i= new sp_instr_hpush_jump(sp->instructions(), ctx, $2, - ctx->current_var_count()); + ctx->current_var_count()); if (i == NULL || - sp->add_instr(i) || + sp->add_instr(i) || sp->push_backpatch(i, ctx->push_label((char *)"", 0))) MYSQL_YYABORT; } @@ -2378,15 +2400,15 @@ sp_decl: i= new sp_instr_hreturn(sp->instructions(), ctx, ctx->current_var_count()); if (i == NULL || - sp->add_instr(i)) + sp->add_instr(i)) MYSQL_YYABORT; } else { /* EXIT or UNDO handler, just jump to the end of the block */ i= new sp_instr_hreturn(sp->instructions(), ctx, 0); if (i == NULL || - sp->add_instr(i) || - sp->push_backpatch(i, lex->spcont->last_label())) /* Block end */ + sp->add_instr(i) || + sp->push_backpatch(i, lex->spcont->last_label())) /* Block end */ MYSQL_YYABORT; } lex->sphead->backpatch(hlab); @@ -2413,9 +2435,9 @@ sp_decl: } i= new sp_instr_cpush(sp->instructions(), ctx, $5, ctx->current_cursor_count()); - if (i == NULL || + if (i == NULL || sp->add_instr(i) || - ctx->push_cursor(&$2)) + ctx->push_cursor(&$2)) MYSQL_YYABORT; $$.vars= $$.conds= $$.hndlrs= 0; $$.curs= 1; @@ -2483,13 +2505,22 @@ sp_hcond_element: sp_cond: ulong_num { /* mysql errno */ + if ($1 == 0) + { + my_error(ER_WRONG_VALUE, MYF(0), "CONDITION", "0"); + MYSQL_YYABORT; + } $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); if ($$ == NULL) MYSQL_YYABORT; $$->type= sp_cond_type_t::number; $$->mysqlerr= $1; } - | SQLSTATE_SYM opt_value TEXT_STRING_literal + | sqlstate + ; + +sqlstate: + SQLSTATE_SYM opt_value TEXT_STRING_literal { /* SQLSTATE */ if (!sp_cond_check(&$3)) { @@ -2500,8 +2531,8 @@ sp_cond: if ($$ == NULL) MYSQL_YYABORT; $$->type= sp_cond_type_t::state; - memcpy($$->sqlstate, $3.str, 5); - $$->sqlstate[5]= '\0'; + memcpy($$->sqlstate, $3.str, SQLSTATE_LENGTH); + $$->sqlstate[SQLSTATE_LENGTH]= '\0'; } ; @@ -2547,6 +2578,160 @@ sp_hcond: } ; +signal_stmt: + SIGNAL_SYM signal_value opt_set_signal_information + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + Yacc_state *state= & thd->m_parser_state->m_yacc; + + lex->sql_command= SQLCOM_SIGNAL; + lex->m_stmt= new (thd->mem_root) Signal_statement(lex, $2, + state->m_set_signal_info); + if (lex->m_stmt == NULL) + MYSQL_YYABORT; + } + ; + +signal_value: + ident + { + LEX *lex= Lex; + sp_cond_type_t *cond; + if (lex->spcont == NULL) + { + /* SIGNAL foo cannot be used outside of stored programs */ + my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str); + MYSQL_YYABORT; + } + cond= lex->spcont->find_cond(&$1); + if (cond == NULL) + { + my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str); + MYSQL_YYABORT; + } + if (cond->type != sp_cond_type_t::state) + { + my_error(ER_SIGNAL_BAD_CONDITION_TYPE, MYF(0)); + MYSQL_YYABORT; + } + $$= cond; + } + | sqlstate + { $$= $1; } + ; + +opt_signal_value: + /* empty */ + { $$= NULL; } + | signal_value + { $$= $1; } + ; + +opt_set_signal_information: + /* empty */ + { + YYTHD->m_parser_state->m_yacc.m_set_signal_info.clear(); + } + | SET signal_information_item_list + ; + +signal_information_item_list: + signal_condition_information_item_name EQ signal_allowed_expr + { + Set_signal_information *info; + info= & YYTHD->m_parser_state->m_yacc.m_set_signal_info; + int index= (int) $1; + info->clear(); + info->m_item[index]= $3; + } + | signal_information_item_list ',' + signal_condition_information_item_name EQ signal_allowed_expr + { + Set_signal_information *info; + info= & YYTHD->m_parser_state->m_yacc.m_set_signal_info; + int index= (int) $3; + if (info->m_item[index] != NULL) + { + my_error(ER_DUP_SIGNAL_SET, MYF(0), + Diag_condition_item_names[index].str); + MYSQL_YYABORT; + } + info->m_item[index]= $5; + } + ; + +/* + Only a limited subset of are allowed in SIGNAL/RESIGNAL. +*/ +signal_allowed_expr: + literal + { $$= $1; } + | variable + { + if ($1->type() == Item::FUNC_ITEM) + { + Item_func *item= (Item_func*) $1; + if (item->functype() == Item_func::SUSERVAR_FUNC) + { + /* + Don't allow the following syntax: + SIGNAL/RESIGNAL ... + SET = @foo := expr + */ + my_parse_error(ER(ER_SYNTAX_ERROR)); + MYSQL_YYABORT; + } + } + $$= $1; + } + | simple_ident + { $$= $1; } + ; + +/* conditions that can be set in signal / resignal */ +signal_condition_information_item_name: + CLASS_ORIGIN_SYM + { $$= DIAG_CLASS_ORIGIN; } + | SUBCLASS_ORIGIN_SYM + { $$= DIAG_SUBCLASS_ORIGIN; } + | CONSTRAINT_CATALOG_SYM + { $$= DIAG_CONSTRAINT_CATALOG; } + | CONSTRAINT_SCHEMA_SYM + { $$= DIAG_CONSTRAINT_SCHEMA; } + | CONSTRAINT_NAME_SYM + { $$= DIAG_CONSTRAINT_NAME; } + | CATALOG_NAME_SYM + { $$= DIAG_CATALOG_NAME; } + | SCHEMA_NAME_SYM + { $$= DIAG_SCHEMA_NAME; } + | TABLE_NAME_SYM + { $$= DIAG_TABLE_NAME; } + | COLUMN_NAME_SYM + { $$= DIAG_COLUMN_NAME; } + | CURSOR_NAME_SYM + { $$= DIAG_CURSOR_NAME; } + | MESSAGE_TEXT_SYM + { $$= DIAG_MESSAGE_TEXT; } + | MYSQL_ERRNO_SYM + { $$= DIAG_MYSQL_ERRNO; } + ; + +resignal_stmt: + RESIGNAL_SYM opt_signal_value opt_set_signal_information + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + Yacc_state *state= & thd->m_parser_state->m_yacc; + + lex->sql_command= SQLCOM_RESIGNAL; + lex->m_stmt= new (thd->mem_root) Resignal_statement(lex, $2, + state->m_set_signal_info); + if (lex->m_stmt == NULL) + MYSQL_YYABORT; + } + ; + sp_decl_idents: ident { @@ -2683,7 +2868,7 @@ sp_proc_stmt_return: i= new sp_instr_freturn(sp->instructions(), lex->spcont, $3, sp->m_return_field_def.sql_type, lex); if (i == NULL || - sp->add_instr(i)) + sp->add_instr(i)) MYSQL_YYABORT; sp->m_flags|= sp_head::HAS_RETURN; } @@ -2923,7 +3108,7 @@ sp_if: sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, ctx, $2, lex); if (i == NULL || - sp->push_backpatch(i, ctx->push_label((char *)"", 0)) || + sp->push_backpatch(i, ctx->push_label((char *)"", 0)) || sp->add_cont_backpatch(i) || sp->add_instr(i)) MYSQL_YYABORT; @@ -3205,7 +3390,7 @@ sp_unlabeled_control: if (i == NULL || lex->sphead->add_instr(i)) MYSQL_YYABORT; - } + } | WHILE_SYM { Lex->sphead->reset_lex(YYTHD); } expr DO_SYM @@ -3216,7 +3401,7 @@ sp_unlabeled_control: sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, lex->spcont, $3, lex); if (i == NULL || - /* Jumping forward */ + /* Jumping forward */ sp->push_backpatch(i, lex->spcont->last_label()) || sp->new_cont_backpatch(i) || sp->add_instr(i)) @@ -5023,6 +5208,7 @@ field_length: opt_field_length: /* empty */ { Lex->length=(char*) 0; /* use default length */ } | field_length { } + ; opt_precision: /* empty */ {} @@ -6410,7 +6596,7 @@ select_paren: sel->olap != UNSPECIFIED_OLAP_TYPE && sel->master_unit()->fake_select_lex) { - my_error(ER_WRONG_USAGE, MYF(0), + my_error(ER_WRONG_USAGE, MYF(0), "CUBE/ROLLUP", "ORDER BY"); MYSQL_YYABORT; } @@ -8705,24 +8891,25 @@ interval: ; interval_time_stamp: - interval_time_st {} - | FRAC_SECOND_SYM { - $$=INTERVAL_MICROSECOND; - /* - FRAC_SECOND was mistakenly implemented with - a wrong resolution. According to the ODBC - standard it should be nanoseconds, not - microseconds. Changing it to nanoseconds - in MySQL would mean making TIMESTAMPDIFF - and TIMESTAMPADD to return DECIMAL, since - the return value would be too big for BIGINT - Hence we just deprecate the incorrect - implementation without changing its - resolution. - */ - WARN_DEPRECATED(yythd, "6.2", "FRAC_SECOND", "MICROSECOND"); - } - ; + interval_time_st {} + | FRAC_SECOND_SYM + { + $$=INTERVAL_MICROSECOND; + /* + FRAC_SECOND was mistakenly implemented with + a wrong resolution. According to the ODBC + standard it should be nanoseconds, not + microseconds. Changing it to nanoseconds + in MySQL would mean making TIMESTAMPDIFF + and TIMESTAMPADD to return DECIMAL, since + the return value would be too big for BIGINT + Hence we just deprecate the incorrect + implementation without changing its + resolution. + */ + WARN_DEPRECATED(yythd, "6.2", "FRAC_SECOND", "MICROSECOND"); + } + ; interval_time_st: DAY_SYM { $$=INTERVAL_DAY; } @@ -11423,13 +11610,16 @@ keyword_sp: | BOOLEAN_SYM {} | BTREE_SYM {} | CASCADED {} + | CATALOG_NAME_SYM {} | CHAIN_SYM {} | CHANGED {} | CIPHER_SYM {} | CLIENT_SYM {} + | CLASS_ORIGIN_SYM {} | COALESCE {} | CODE_SYM {} | COLLATION_SYM {} + | COLUMN_NAME_SYM {} | COLUMNS {} | COMMITTED_SYM {} | COMPACT_SYM {} @@ -11438,10 +11628,14 @@ keyword_sp: | CONCURRENT {} | CONNECTION_SYM {} | CONSISTENT_SYM {} + | CONSTRAINT_CATALOG_SYM {} + | CONSTRAINT_SCHEMA_SYM {} + | CONSTRAINT_NAME_SYM {} | CONTEXT_SYM {} | CONTRIBUTORS_SYM {} | CPU_SYM {} | CUBE_SYM {} + | CURSOR_NAME_SYM {} | DATA_SYM {} | DATAFILE_SYM {} | DATETIME {} @@ -11533,6 +11727,7 @@ keyword_sp: | MEDIUM_SYM {} | MEMORY_SYM {} | MERGE_SYM {} + | MESSAGE_TEXT_SYM {} | MICROSECOND_SYM {} | MIGRATE_SYM {} | MINUTE_SYM {} @@ -11544,6 +11739,7 @@ keyword_sp: | MULTIPOINT {} | MULTIPOLYGON {} | MUTEX_SYM {} + | MYSQL_ERRNO_SYM {} | NAME_SYM {} | NAMES_SYM {} | NATIONAL_SYM {} @@ -11603,6 +11799,7 @@ keyword_sp: | ROW_SYM {} | RTREE_SYM {} | SCHEDULE_SYM {} + | SCHEMA_NAME_SYM {} | SECOND_SYM {} | SERIAL_SYM {} | SERIALIZABLE_SYM {} @@ -11621,6 +11818,7 @@ keyword_sp: | STATUS_SYM {} | STORAGE_SYM {} | STRING_SYM {} + | SUBCLASS_ORIGIN_SYM {} | SUBDATE_SYM {} | SUBJECT_SYM {} | SUBPARTITION_SYM {} @@ -11629,6 +11827,7 @@ keyword_sp: | SUSPEND_SYM {} | SWAPS_SYM {} | SWITCHES_SYM {} + | TABLE_NAME_SYM {} | TABLES {} | TABLE_CHECKSUM_SYM {} | TABLESPACE {} diff --git a/sql/table.cc b/sql/table.cc index 4442243ec14..d71a3ecd9bb 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1262,7 +1262,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, "Please do \"ALTER TABLE '%s' FORCE\" to fix it!", share->fieldnames.type_names[i], share->table_name.str, share->table_name.str); - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_CRASHED_ON_USAGE, "Found incompatible DECIMAL field '%s' in %s; " "Please do \"ALTER TABLE '%s' FORCE\" to fix it!", @@ -1464,7 +1464,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, "Please do \"ALTER TABLE '%s' FORCE \" to fix it!", share->table_name.str, share->table_name.str); - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_CRASHED_ON_USAGE, "Found wrong key definition in %s; " "Please do \"ALTER TABLE '%s' FORCE\" to fix " @@ -3351,20 +3351,20 @@ void TABLE_LIST::hide_view_error(THD *thd) /* Hide "Unknown column" or "Unknown function" error */ DBUG_ASSERT(thd->is_error()); - if (thd->main_da.sql_errno() == ER_BAD_FIELD_ERROR || - thd->main_da.sql_errno() == ER_SP_DOES_NOT_EXIST || - thd->main_da.sql_errno() == ER_FUNC_INEXISTENT_NAME_COLLISION || - thd->main_da.sql_errno() == ER_PROCACCESS_DENIED_ERROR || - thd->main_da.sql_errno() == ER_COLUMNACCESS_DENIED_ERROR || - thd->main_da.sql_errno() == ER_TABLEACCESS_DENIED_ERROR || - thd->main_da.sql_errno() == ER_TABLE_NOT_LOCKED || - thd->main_da.sql_errno() == ER_NO_SUCH_TABLE) + if (thd->stmt_da->sql_errno() == ER_BAD_FIELD_ERROR || + thd->stmt_da->sql_errno() == ER_SP_DOES_NOT_EXIST || + thd->stmt_da->sql_errno() == ER_FUNC_INEXISTENT_NAME_COLLISION || + thd->stmt_da->sql_errno() == ER_PROCACCESS_DENIED_ERROR || + thd->stmt_da->sql_errno() == ER_COLUMNACCESS_DENIED_ERROR || + thd->stmt_da->sql_errno() == ER_TABLEACCESS_DENIED_ERROR || + thd->stmt_da->sql_errno() == ER_TABLE_NOT_LOCKED || + thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE) { TABLE_LIST *top= top_table(); thd->clear_error(); my_error(ER_VIEW_INVALID, MYF(0), top->view_db.str, top->view_name.str); } - else if (thd->main_da.sql_errno() == ER_NO_DEFAULT_FOR_FIELD) + else if (thd->stmt_da->sql_errno() == ER_NO_DEFAULT_FOR_FIELD) { TABLE_LIST *top= top_table(); thd->clear_error(); @@ -3442,7 +3442,7 @@ int TABLE_LIST::view_check_option(THD *thd, bool ignore_failure) TABLE_LIST *main_view= top_table(); if (ignore_failure) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED), main_view->view_db.str, main_view->view_name.str); return(VIEW_CHECK_SKIP); diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc index 0764fe8be33..ed17f7968c0 100644 --- a/sql/thr_malloc.cc +++ b/sql/thr_malloc.cc @@ -44,9 +44,10 @@ extern "C" { returned in the error packet. - SHOW ERROR/SHOW WARNINGS may be empty. */ - thd->main_da.set_error_status(thd, - ER_OUT_OF_RESOURCES, - ER(ER_OUT_OF_RESOURCES)); + thd->stmt_da->set_error_status(thd, + ER_OUT_OF_RESOURCES, + ER(ER_OUT_OF_RESOURCES), + NULL); } } } diff --git a/sql/time.cc b/sql/time.cc index 962b65e454c..810d6426a01 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -748,7 +748,7 @@ void make_truncated_value_warning(THD *thd, MYSQL_ERROR::enum_warning_level leve cs->cset->snprintf(cs, warn_buff, sizeof(warn_buff), ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), type_str, str.c_ptr(), field_name, - (ulong) thd->row_count); + (ulong) thd->warning_info->current_row_for_warning()); else { if (time_type > MYSQL_TIMESTAMP_ERROR) diff --git a/sql/tztime.cc b/sql/tztime.cc index c7a4ad049ec..6757798ad32 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1645,7 +1645,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) if (open_system_tables_for_read(thd, tz_tables, &open_tables_state_backup)) { sql_print_warning("Can't open and lock time zone table: %s " - "trying to live without them", thd->main_da.message()); + "trying to live without them", thd->stmt_da->message()); /* We will try emulate that everything is ok */ return_val= time_zone_tables_exist= 0; goto end_with_setting_default_tz; diff --git a/sql/unireg.cc b/sql/unireg.cc index 68a352e4a44..028f774e057 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -55,10 +55,12 @@ static bool make_empty_rec(THD *thd, int file, enum legacy_db_type table_type, struct Pack_header_error_handler: public Internal_error_handler { - virtual bool handle_error(uint sql_errno, - const char *message, - MYSQL_ERROR::enum_warning_level level, - THD *thd); + virtual bool handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl); bool is_handled; Pack_header_error_handler() :is_handled(FALSE) {} }; @@ -66,11 +68,14 @@ struct Pack_header_error_handler: public Internal_error_handler bool Pack_header_error_handler:: -handle_error(uint sql_errno, - const char * /* message */, - MYSQL_ERROR::enum_warning_level /* level */, - THD * /* thd */) +handle_condition(THD *, + uint sql_errno, + const char*, + MYSQL_ERROR::enum_warning_level, + const char*, + MYSQL_ERROR ** cond_hdl) { + *cond_hdl= NULL; is_handled= (sql_errno == ER_TOO_MANY_FIELDS); return is_handled; } diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 83a46ca9f9f..1e21f292727 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -153,7 +153,7 @@ extern "C" void myrg_print_wrong_table(const char *table_name) buf[db.length]= '.'; memcpy(buf + db.length + 1, name.str, name.length); buf[db.length + name.length + 1]= 0; - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ADMIN_WRONG_MRG_TABLE, ER(ER_ADMIN_WRONG_MRG_TABLE), buf); } From e436b8866be640b2160f0b756f85559437cff67d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 10 Sep 2009 18:05:53 +0800 Subject: [PATCH 107/138] BUG#45999 Row based replication fails when auto_increment field = 0 In RBR, There is an inconsistency between slaves and master. When INSERT statement which includes an auto_increment field is executed, Store engine of master will check the value of the auto_increment field. It will generate a sequence number and then replace the value, if its value is NULL or empty. if the field's value is 0, the store engine will do like encountering the NULL values unless NO_AUTO_VALUE_ON_ZERO is set into SQL_MODE. In contrast, if the field's value is 0, Store engine of slave always generates a new sequence number whether or not NO_AUTO_VALUE_ON_ZERO is set into SQL_MODE. SQL MODE of slave sql thread is always consistency with master's. Another variable is related to this bug. If generateing a sequence number is decided by the values of table->auto_increment_field_not_null and SQL_MODE(if includes MODE_NO_AUTO_VALUE_ON_ZERO) The table->auto_increment_is_not_null is FALSE, which causes this bug to appear. .. --- .../extra/rpl_tests/rpl_auto_increment.test | 78 ++++++++++++++++++- .../suite/rpl/r/rpl_auto_increment.result | 68 ++++++++++++++++ sql/log_event.cc | 11 +++ 3 files changed, 156 insertions(+), 1 deletion(-) diff --git a/mysql-test/extra/rpl_tests/rpl_auto_increment.test b/mysql-test/extra/rpl_tests/rpl_auto_increment.test index 24448a38408..abf3b4ec676 100644 --- a/mysql-test/extra/rpl_tests/rpl_auto_increment.test +++ b/mysql-test/extra/rpl_tests/rpl_auto_increment.test @@ -163,5 +163,81 @@ show create table t1; connection master; drop table t1; -# End cleanup +# +# BUG#45999 Row based replication fails when auto_increment field = 0. +# Store engine of Slaves auto-generates new sequence numbers for +# auto_increment fields if the values of them are 0. There is an inconsistency +# between slave and master. When MODE_NO_AUTO_VALUE_ON_ZERO are masters treat +# +source include/master-slave-reset.inc; + +connection master; +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +--enable_warnings + +eval CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=$engine_type; +eval CREATE TABLE t2 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=$engine_type2; +SET SQL_MODE=''; +# Value of the id will be 1; +INSERT INTO t1 VALUES(NULL); +INSERT INTO t2 VALUES(NULL); +SELECT * FROM t1; +SELECT * FROM t2; +# Value of the id will be 2; +INSERT INTO t1 VALUES(); +INSERT INTO t2 VALUES(); +SELECT * FROM t1; +SELECT * FROM t2; +# Value of the id will be 3. The master treats 0 as NULL or empty because +# NO_AUTO_VALUE_ON_ZERO is not assign to SQL_MODE. +INSERT INTO t1 VALUES(0); +INSERT INTO t2 VALUES(0); +SELECT * FROM t1; +SELECT * FROM t2; + +SET SQL_MODE=NO_AUTO_VALUE_ON_ZERO; +# Value of the id will be 0. The master does not treat 0 as NULL or empty +# because NO_AUTO_VALUE_ON_ZERO has assigned to SQL_MODE. +INSERT INTO t1 VALUES(0); +INSERT INTO t2 VALUES(0); +SELECT * FROM t1; +SELECT * FROM t2; + +INSERT INTO t1 VALUES(4); +INSERT INTO t2 VALUES(4); +FLUSH LOGS; +sync_slave_with_master; + +let $diff_table_1= master:test.t1; +let $diff_table_2= slave:test.t1; +source include/diff_tables.inc; + +let $diff_table_1= master:test.t2; +let $diff_table_2= slave:test.t2; +source include/diff_tables.inc; + +connection master; +DROP TABLE t1; +DROP TABLE t2; +sync_slave_with_master; + +connection master; +let $MYSQLD_DATADIR= `SELECT @@DATADIR`; +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 | $MYSQL test +sync_slave_with_master; + +let $diff_table_1= master:test.t1; +let $diff_table_2= slave:test.t1; +source include/diff_tables.inc; + +let $diff_table_1= master:test.t2; +let $diff_table_2= slave:test.t2; +source include/diff_tables.inc; + +# End cleanup +DROP TABLE t1; +DROP TABLE t2; +SET SQL_MODE=''; sync_slave_with_master; diff --git a/mysql-test/suite/rpl/r/rpl_auto_increment.result b/mysql-test/suite/rpl/r/rpl_auto_increment.result index 2a4c3a09361..fdd94264041 100644 --- a/mysql-test/suite/rpl/r/rpl_auto_increment.result +++ b/mysql-test/suite/rpl/r/rpl_auto_increment.result @@ -244,3 +244,71 @@ t1 CREATE TABLE `t1` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 drop table t1; +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; +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=innodb; +CREATE TABLE t2 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=myisam; +SET SQL_MODE=''; +INSERT INTO t1 VALUES(NULL); +INSERT INTO t2 VALUES(NULL); +SELECT * FROM t1; +id +1 +SELECT * FROM t2; +id +1 +INSERT INTO t1 VALUES(); +INSERT INTO t2 VALUES(); +SELECT * FROM t1; +id +1 +2 +SELECT * FROM t2; +id +1 +2 +INSERT INTO t1 VALUES(0); +INSERT INTO t2 VALUES(0); +SELECT * FROM t1; +id +1 +2 +3 +SELECT * FROM t2; +id +1 +2 +3 +SET SQL_MODE=NO_AUTO_VALUE_ON_ZERO; +INSERT INTO t1 VALUES(0); +INSERT INTO t2 VALUES(0); +SELECT * FROM t1; +id +0 +1 +2 +3 +SELECT * FROM t2; +id +0 +1 +2 +3 +INSERT INTO t1 VALUES(4); +INSERT INTO t2 VALUES(4); +FLUSH LOGS; +Comparing tables master:test.t1 and slave:test.t1 +Comparing tables master:test.t2 and slave:test.t2 +DROP TABLE t1; +DROP TABLE t2; +Comparing tables master:test.t1 and slave:test.t1 +Comparing tables master:test.t2 and slave:test.t2 +DROP TABLE t1; +DROP TABLE t2; +SET SQL_MODE=''; diff --git a/sql/log_event.cc b/sql/log_event.cc index 0cda724b698..08fe3aba8ed 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -8312,6 +8312,16 @@ Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability /* Honor next number column if present */ m_table->next_number_field= m_table->found_next_number_field; + /* + * Fixed Bug#45999, In RBR, Store engine of Slave auto-generates new + * sequence numbers for auto_increment fields if the values of them are 0. + * If generateing a sequence number is decided by the values of + * table->auto_increment_field_not_null and SQL_MODE(if includes + * MODE_NO_AUTO_VALUE_ON_ZERO) in update_auto_increment function. + * SQL_MODE of slave sql thread is always consistency with master's. + * In RBR, auto_increment fields never are NULL. + */ + m_table->auto_increment_field_not_null= TRUE; return error; } @@ -8321,6 +8331,7 @@ Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability * { int local_error= 0; m_table->next_number_field=0; + m_table->auto_increment_field_not_null= FALSE; if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1 || m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER) { From 10406ae65871de074e807e626f9ede686e9321d4 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 10 Sep 2009 15:24:07 +0500 Subject: [PATCH 108/138] Bug#46815 CONCAT_WS returning wrong data The problem is that argument buffer can be used as result buffer and it leads to argument value change. The fix is to use 'old buffer' as result buffer only if first argument is not constant item. mysql-test/r/func_str.result: test result mysql-test/t/func_str.test: test case sql/item_strfunc.cc: The problem is that argument buffer can be used as result buffer and it leads to argument value change. The fix is to use 'old buffer' as result buffer only if first argument is not constant item. --- mysql-test/r/func_str.result | 9 +++++++++ mysql-test/t/func_str.test | 13 +++++++++++++ sql/item_strfunc.cc | 7 ++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 75f8983e838..bf2a9ca8901 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -2196,4 +2196,13 @@ SELECT LOAD_FILE(a) FROM t1; LOAD_FILE(a) NULL DROP TABLE t1; +CREATE TABLE t1 (f2 VARCHAR(20)); +CREATE TABLE t2 (f2 VARCHAR(20)); +INSERT INTO t1 VALUES ('MIN'),('MAX'); +INSERT INTO t2 VALUES ('LOAD'); +SELECT CONCAT_WS('_', (SELECT t2.f2 FROM t2), t1.f2) AS concat_name FROM t1; +concat_name +LOAD_MIN +LOAD_MAX +DROP TABLE t1, t2; End of 5.0 tests diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 4b0f91e4408..e396fbcebd8 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -1177,5 +1177,18 @@ INSERT INTO t1 VALUES ('aaaaaaaa'); SELECT LOAD_FILE(a) FROM t1; DROP TABLE t1; +# +# Bug#46815 CONCAT_WS returning wrong data +# +CREATE TABLE t1 (f2 VARCHAR(20)); +CREATE TABLE t2 (f2 VARCHAR(20)); + +INSERT INTO t1 VALUES ('MIN'),('MAX'); +INSERT INTO t2 VALUES ('LOAD'); + +SELECT CONCAT_WS('_', (SELECT t2.f2 FROM t2), t1.f2) AS concat_name FROM t1; + +DROP TABLE t1, t2; + --echo End of 5.0 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index e3fe67f4324..6f697a1665a 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -600,6 +600,7 @@ String *Item_func_concat_ws::val_str(String *str) String tmp_sep_str(tmp_str_buff, sizeof(tmp_str_buff),default_charset_info), *sep_str, *res, *res2,*use_as_buff; uint i; + bool is_const= 0; null_value=0; if (!(sep_str= args[0]->val_str(&tmp_sep_str))) @@ -613,7 +614,11 @@ String *Item_func_concat_ws::val_str(String *str) // If not, return the empty string for (i=1; i < arg_count; i++) if ((res= args[i]->val_str(str))) + { + is_const= args[i]->const_item() || !args[i]->used_tables(); break; + } + if (i == arg_count) return &my_empty_string; @@ -631,7 +636,7 @@ String *Item_func_concat_ws::val_str(String *str) current_thd->variables.max_allowed_packet); goto null; } - if (res->alloced_length() >= + if (!is_const && res->alloced_length() >= res->length() + sep_str->length() + res2->length()) { // Use old buffer res->append(*sep_str); // res->length() > 0 always From 057192abbd261f453711a3296c48f091a702019a Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Thu, 10 Sep 2009 16:18:54 +0400 Subject: [PATCH 109/138] Add DBUG_VIOLATION_HELPER_LEAVE definition to non-debug build. --- include/my_dbug.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/my_dbug.h b/include/my_dbug.h index 71dc34791dc..474a46f29dd 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -128,6 +128,7 @@ extern FILE *_db_fp_(void); #define DBUG_ENTER(a1) #define DBUG_LEAVE +#define DBUG_VIOLATION_HELPER_LEAVE #define DBUG_RETURN(a1) do { return(a1); } while(0) #define DBUG_VOID_RETURN do { return; } while(0) #define DBUG_EXECUTE(keyword,a1) do { } while(0) From ea0d4516ed796179ef97a791bb04a646ac98610b Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Fri, 11 Sep 2009 01:15:41 -0600 Subject: [PATCH 110/138] Post merge fixes --- mysql-test/r/func_encrypt_nossl.result | 42 ++++----- .../suite/funcs_1/r/innodb_func_view.result | 92 +++++++++---------- .../funcs_1/r/innodb_storedproc_02.result | 3 - .../suite/funcs_1/r/memory_func_view.result | 92 +++++++++---------- .../funcs_1/r/memory_storedproc_02.result | 3 - .../suite/funcs_1/r/myisam_func_view.result | 92 +++++++++---------- .../funcs_1/r/myisam_storedproc_02.result | 3 - .../suite/funcs_1/r/ndb_func_view.result | 92 +++++++++---------- .../suite/funcs_1/r/ndb_storedproc_02.result | 3 - mysql-test/suite/funcs_1/r/storedproc.result | 73 +-------------- mysql-test/suite/ndb/r/ndb_multi_row.result | 6 +- 11 files changed, 210 insertions(+), 291 deletions(-) diff --git a/mysql-test/r/func_encrypt_nossl.result b/mysql-test/r/func_encrypt_nossl.result index d0df2335afa..fc003eec226 100644 --- a/mysql-test/r/func_encrypt_nossl.result +++ b/mysql-test/r/func_encrypt_nossl.result @@ -2,83 +2,83 @@ select des_encrypt("test", 'akeystr'); des_encrypt("test", 'akeystr') NULL Warnings: -Error 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working select des_encrypt("test", 1); des_encrypt("test", 1) NULL Warnings: -Error 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working select des_encrypt("test", 9); des_encrypt("test", 9) NULL Warnings: -Error 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working select des_encrypt("test", 100); des_encrypt("test", 100) NULL Warnings: -Error 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working select des_encrypt("test", NULL); des_encrypt("test", NULL) NULL Warnings: -Error 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working select des_encrypt(NULL, NULL); des_encrypt(NULL, NULL) NULL Warnings: -Error 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working select des_decrypt("test", 'anotherkeystr'); des_decrypt("test", 'anotherkeystr') NULL Warnings: -Error 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working select des_decrypt(1, 1); des_decrypt(1, 1) NULL Warnings: -Error 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working select des_decrypt(des_encrypt("test", 'thekey')); des_decrypt(des_encrypt("test", 'thekey')) NULL Warnings: -Error 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working select hex(des_encrypt("hello")),des_decrypt(des_encrypt("hello")); hex(des_encrypt("hello")) des_decrypt(des_encrypt("hello")) NULL NULL Warnings: -Error 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working -Error 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working select des_decrypt(des_encrypt("hello",4)); des_decrypt(des_encrypt("hello",4)) NULL Warnings: -Error 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working select des_decrypt(des_encrypt("hello",'test'),'test'); des_decrypt(des_encrypt("hello",'test'),'test') NULL Warnings: -Error 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working select hex(des_encrypt("hello")),hex(des_encrypt("hello",5)),hex(des_encrypt("hello",'default_password')); hex(des_encrypt("hello")) hex(des_encrypt("hello",5)) hex(des_encrypt("hello",'default_password')) NULL NULL NULL Warnings: -Error 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working -Error 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working -Error 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working select des_decrypt(des_encrypt("hello"),'default_password'); des_decrypt(des_encrypt("hello"),'default_password') NULL Warnings: -Error 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working select des_decrypt(des_encrypt("hello",4),'password4'); des_decrypt(des_encrypt("hello",4),'password4') NULL Warnings: -Error 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working SET @a=des_decrypt(des_encrypt("hello")); Warnings: -Error 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working flush des_key_file; select @a = des_decrypt(des_encrypt("hello")); @a = des_decrypt(des_encrypt("hello")) @@ -90,9 +90,9 @@ select hex(des_decrypt(des_encrypt("hello",4),'password2')); hex(des_decrypt(des_encrypt("hello",4),'password2')) NULL Warnings: -Error 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working select hex(des_decrypt(des_encrypt("hello","hidden"))); hex(des_decrypt(des_encrypt("hello","hidden"))) NULL Warnings: -Error 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MySQL built with '--with-openssl' to have it working diff --git a/mysql-test/suite/funcs_1/r/innodb_func_view.result b/mysql-test/suite/funcs_1/r/innodb_func_view.result index 4beb0c8aaf2..172f410b949 100644 --- a/mysql-test/suite/funcs_1/r/innodb_func_view.result +++ b/mysql-test/suite/funcs_1/r/innodb_func_view.result @@ -945,8 +945,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 9999999999999999999999999999999999.999999999999 0.000000000000000000000000000000 4 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select left('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö',`t1_values`.`my_decimal`) AS `LEFT('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö', my_decimal)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -960,8 +960,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 9999999999999999999999999999999999.999999999999 0.000000000000000000000000000000 4 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' DROP VIEW v1; @@ -2587,9 +2587,9 @@ NULL NULL 1 0 0.000000000000000000000000000000 4 0 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_decimal` as unsigned) AS `CAST(my_decimal AS UNSIGNED INTEGER)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2603,9 +2603,9 @@ NULL NULL 1 0 0.000000000000000000000000000000 4 0 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' DROP VIEW v1; @@ -2955,8 +2955,8 @@ NULL NULL 1 0 0.000000000000000000000000000000 4 -1 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_decimal` as signed) AS `CAST(my_decimal AS SIGNED INTEGER)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2970,8 +2970,8 @@ NULL NULL 1 0 0.000000000000000000000000000000 4 -1 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' DROP VIEW v1; @@ -3282,10 +3282,10 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 30 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as decimal(37,2)) AS `CAST(my_double AS DECIMAL(37,2))`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3300,10 +3300,10 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 30 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 DROP VIEW v1; @@ -3372,9 +3372,9 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 29 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as decimal(37,2)) AS `CAST(my_varbinary_1000 AS DECIMAL(37,2))`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3389,9 +3389,9 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 29 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 DROP VIEW v1; @@ -3408,11 +3408,11 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 28 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' Warning 1292 Truncated incorrect DECIMAL value: '-1' Warning 1292 Truncated incorrect DECIMAL value: '-3333.3333' @@ -3430,11 +3430,11 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 28 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' Warning 1292 Truncated incorrect DECIMAL value: '-1' Warning 1292 Truncated incorrect DECIMAL value: '-3333.3333' @@ -3454,9 +3454,9 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 27 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as decimal(37,2)) AS `CAST(my_varchar_1000 AS DECIMAL(37,2))`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3471,9 +3471,9 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 27 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 DROP VIEW v1; @@ -3490,11 +3490,11 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 26 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection @@ -3510,11 +3510,11 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 26 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' DROP VIEW v1; diff --git a/mysql-test/suite/funcs_1/r/innodb_storedproc_02.result b/mysql-test/suite/funcs_1/r/innodb_storedproc_02.result index 65fc5b5afc9..3e2d084aa0c 100644 --- a/mysql-test/suite/funcs_1/r/innodb_storedproc_02.result +++ b/mysql-test/suite/funcs_1/r/innodb_storedproc_02.result @@ -550,9 +550,6 @@ exit handler 2 exit handler 2 exit handler 1 exit handler 1 -Warnings: -Note 1051 Unknown table 'tqq' -Note 1051 Unknown table 'tqq' create table res_t1(w char unique, x char); insert into res_t1 values ('a', 'b'); CREATE PROCEDURE h1 () diff --git a/mysql-test/suite/funcs_1/r/memory_func_view.result b/mysql-test/suite/funcs_1/r/memory_func_view.result index 4e48d9412d1..a386272b8ab 100644 --- a/mysql-test/suite/funcs_1/r/memory_func_view.result +++ b/mysql-test/suite/funcs_1/r/memory_func_view.result @@ -946,8 +946,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 9999999999999999999999999999999999.999999999999 0.000000000000000000000000000000 4 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select left('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö',`t1_values`.`my_decimal`) AS `LEFT('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö', my_decimal)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -961,8 +961,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 9999999999999999999999999999999999.999999999999 0.000000000000000000000000000000 4 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' DROP VIEW v1; @@ -2588,9 +2588,9 @@ NULL NULL 1 0 0.000000000000000000000000000000 4 0 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_decimal` as unsigned) AS `CAST(my_decimal AS UNSIGNED INTEGER)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2604,9 +2604,9 @@ NULL NULL 1 0 0.000000000000000000000000000000 4 0 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' DROP VIEW v1; @@ -2956,8 +2956,8 @@ NULL NULL 1 0 0.000000000000000000000000000000 4 -1 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_decimal` as signed) AS `CAST(my_decimal AS SIGNED INTEGER)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2971,8 +2971,8 @@ NULL NULL 1 0 0.000000000000000000000000000000 4 -1 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' DROP VIEW v1; @@ -3283,10 +3283,10 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 30 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as decimal(37,2)) AS `CAST(my_double AS DECIMAL(37,2))`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3301,10 +3301,10 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 30 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 DROP VIEW v1; @@ -3373,9 +3373,9 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 29 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as decimal(37,2)) AS `CAST(my_varbinary_1000 AS DECIMAL(37,2))`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3390,9 +3390,9 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 29 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 DROP VIEW v1; @@ -3409,11 +3409,11 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 28 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' Warning 1292 Truncated incorrect DECIMAL value: '-1' Warning 1292 Truncated incorrect DECIMAL value: '-3333.3333' @@ -3431,11 +3431,11 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 28 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' Warning 1292 Truncated incorrect DECIMAL value: '-1' Warning 1292 Truncated incorrect DECIMAL value: '-3333.3333' @@ -3455,9 +3455,9 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 27 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as decimal(37,2)) AS `CAST(my_varchar_1000 AS DECIMAL(37,2))`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3472,9 +3472,9 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 27 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 DROP VIEW v1; @@ -3491,11 +3491,11 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 26 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection @@ -3511,11 +3511,11 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 26 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' DROP VIEW v1; diff --git a/mysql-test/suite/funcs_1/r/memory_storedproc_02.result b/mysql-test/suite/funcs_1/r/memory_storedproc_02.result index 6b474621685..16dde71400e 100644 --- a/mysql-test/suite/funcs_1/r/memory_storedproc_02.result +++ b/mysql-test/suite/funcs_1/r/memory_storedproc_02.result @@ -551,9 +551,6 @@ exit handler 2 exit handler 2 exit handler 1 exit handler 1 -Warnings: -Note 1051 Unknown table 'tqq' -Note 1051 Unknown table 'tqq' create table res_t1(w char unique, x char); insert into res_t1 values ('a', 'b'); CREATE PROCEDURE h1 () diff --git a/mysql-test/suite/funcs_1/r/myisam_func_view.result b/mysql-test/suite/funcs_1/r/myisam_func_view.result index 4e48d9412d1..a386272b8ab 100644 --- a/mysql-test/suite/funcs_1/r/myisam_func_view.result +++ b/mysql-test/suite/funcs_1/r/myisam_func_view.result @@ -946,8 +946,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 9999999999999999999999999999999999.999999999999 0.000000000000000000000000000000 4 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select left('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö',`t1_values`.`my_decimal`) AS `LEFT('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö', my_decimal)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -961,8 +961,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 9999999999999999999999999999999999.999999999999 0.000000000000000000000000000000 4 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' DROP VIEW v1; @@ -2588,9 +2588,9 @@ NULL NULL 1 0 0.000000000000000000000000000000 4 0 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_decimal` as unsigned) AS `CAST(my_decimal AS UNSIGNED INTEGER)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2604,9 +2604,9 @@ NULL NULL 1 0 0.000000000000000000000000000000 4 0 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' DROP VIEW v1; @@ -2956,8 +2956,8 @@ NULL NULL 1 0 0.000000000000000000000000000000 4 -1 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_decimal` as signed) AS `CAST(my_decimal AS SIGNED INTEGER)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2971,8 +2971,8 @@ NULL NULL 1 0 0.000000000000000000000000000000 4 -1 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' DROP VIEW v1; @@ -3283,10 +3283,10 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 30 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as decimal(37,2)) AS `CAST(my_double AS DECIMAL(37,2))`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3301,10 +3301,10 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 30 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 DROP VIEW v1; @@ -3373,9 +3373,9 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 29 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as decimal(37,2)) AS `CAST(my_varbinary_1000 AS DECIMAL(37,2))`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3390,9 +3390,9 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 29 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 DROP VIEW v1; @@ -3409,11 +3409,11 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 28 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' Warning 1292 Truncated incorrect DECIMAL value: '-1' Warning 1292 Truncated incorrect DECIMAL value: '-3333.3333' @@ -3431,11 +3431,11 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 28 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' Warning 1292 Truncated incorrect DECIMAL value: '-1' Warning 1292 Truncated incorrect DECIMAL value: '-3333.3333' @@ -3455,9 +3455,9 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 27 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as decimal(37,2)) AS `CAST(my_varchar_1000 AS DECIMAL(37,2))`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3472,9 +3472,9 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 27 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 DROP VIEW v1; @@ -3491,11 +3491,11 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 26 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection @@ -3511,11 +3511,11 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 26 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' DROP VIEW v1; diff --git a/mysql-test/suite/funcs_1/r/myisam_storedproc_02.result b/mysql-test/suite/funcs_1/r/myisam_storedproc_02.result index 6b474621685..16dde71400e 100644 --- a/mysql-test/suite/funcs_1/r/myisam_storedproc_02.result +++ b/mysql-test/suite/funcs_1/r/myisam_storedproc_02.result @@ -551,9 +551,6 @@ exit handler 2 exit handler 2 exit handler 1 exit handler 1 -Warnings: -Note 1051 Unknown table 'tqq' -Note 1051 Unknown table 'tqq' create table res_t1(w char unique, x char); insert into res_t1 values ('a', 'b'); CREATE PROCEDURE h1 () diff --git a/mysql-test/suite/funcs_1/r/ndb_func_view.result b/mysql-test/suite/funcs_1/r/ndb_func_view.result index 4beb0c8aaf2..172f410b949 100644 --- a/mysql-test/suite/funcs_1/r/ndb_func_view.result +++ b/mysql-test/suite/funcs_1/r/ndb_func_view.result @@ -945,8 +945,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 9999999999999999999999999999999999.999999999999 0.000000000000000000000000000000 4 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select left('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö',`t1_values`.`my_decimal`) AS `LEFT('AaBbCcDdEeFfGgHhIiJjÄäÜüÖö', my_decimal)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -960,8 +960,8 @@ AaBbCcDdEeFfGgHhIiJjÄäÜüÖö 9999999999999999999999999999999999.999999999999 0.000000000000000000000000000000 4 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' DROP VIEW v1; @@ -2587,9 +2587,9 @@ NULL NULL 1 0 0.000000000000000000000000000000 4 0 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_decimal` as unsigned) AS `CAST(my_decimal AS UNSIGNED INTEGER)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2603,9 +2603,9 @@ NULL NULL 1 0 0.000000000000000000000000000000 4 0 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' DROP VIEW v1; @@ -2955,8 +2955,8 @@ NULL NULL 1 0 0.000000000000000000000000000000 4 -1 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_decimal` as signed) AS `CAST(my_decimal AS SIGNED INTEGER)`,`t1_values`.`my_decimal` AS `my_decimal`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2970,8 +2970,8 @@ NULL NULL 1 0 0.000000000000000000000000000000 4 -1 -1.000000000000000000000000000000 5 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1292 Truncated incorrect DECIMAL value: '' DROP VIEW v1; @@ -3282,10 +3282,10 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 30 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as decimal(37,2)) AS `CAST(my_double AS DECIMAL(37,2))`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3300,10 +3300,10 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 30 Warnings: -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 -Error 1292 Truncated incorrect DECIMAL value: '' -Error 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 +Warning 1292 Truncated incorrect DECIMAL value: '' +Warning 1264 Out of range value for column 'CAST(my_double AS DECIMAL(37,2))' at row 1 DROP VIEW v1; @@ -3372,9 +3372,9 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 29 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as decimal(37,2)) AS `CAST(my_varbinary_1000 AS DECIMAL(37,2))`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3389,9 +3389,9 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 29 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 DROP VIEW v1; @@ -3408,11 +3408,11 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 28 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' Warning 1292 Truncated incorrect DECIMAL value: '-1' Warning 1292 Truncated incorrect DECIMAL value: '-3333.3333' @@ -3430,11 +3430,11 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 28 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' Warning 1292 Truncated incorrect DECIMAL value: '-1' Warning 1292 Truncated incorrect DECIMAL value: '-3333.3333' @@ -3454,9 +3454,9 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 27 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as decimal(37,2)) AS `CAST(my_varchar_1000 AS DECIMAL(37,2))`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3471,9 +3471,9 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 27 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 DROP VIEW v1; @@ -3490,11 +3490,11 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 26 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection @@ -3510,11 +3510,11 @@ NULL NULL 1 -1.00 -1 5 -3333.33 -3333.3333 26 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: '<--------30 characters------->' -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1366 Incorrect decimal value: '' for column '' at row -1 Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' DROP VIEW v1; diff --git a/mysql-test/suite/funcs_1/r/ndb_storedproc_02.result b/mysql-test/suite/funcs_1/r/ndb_storedproc_02.result index 65fc5b5afc9..3e2d084aa0c 100644 --- a/mysql-test/suite/funcs_1/r/ndb_storedproc_02.result +++ b/mysql-test/suite/funcs_1/r/ndb_storedproc_02.result @@ -550,9 +550,6 @@ exit handler 2 exit handler 2 exit handler 1 exit handler 1 -Warnings: -Note 1051 Unknown table 'tqq' -Note 1051 Unknown table 'tqq' create table res_t1(w char unique, x char); insert into res_t1 values ('a', 'b'); CREATE PROCEDURE h1 () diff --git a/mysql-test/suite/funcs_1/r/storedproc.result b/mysql-test/suite/funcs_1/r/storedproc.result index 3efb361dc82..ab917fce339 100644 --- a/mysql-test/suite/funcs_1/r/storedproc.result +++ b/mysql-test/suite/funcs_1/r/storedproc.result @@ -7128,8 +7128,6 @@ CALL sp1(); x y z 000 000 000 Warnings: -Warning 1264 Out of range value for column 'x' at row 1 -Warning 1264 Out of range value for column 'y' at row 1 Warning 1264 Out of range value for column 'z' at row 1 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1( ) @@ -7168,8 +7166,6 @@ CALL sp1(); x y z 00000 00000 00000 Warnings: -Warning 1264 Out of range value for column 'x' at row 1 -Warning 1264 Out of range value for column 'y' at row 1 Warning 1264 Out of range value for column 'z' at row 1 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1( ) @@ -7208,8 +7204,6 @@ CALL sp1(); x y z 00000000 00000000 00000000 Warnings: -Warning 1264 Out of range value for column 'x' at row 1 -Warning 1264 Out of range value for column 'y' at row 1 Warning 1264 Out of range value for column 'z' at row 1 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1( ) @@ -7248,8 +7242,6 @@ CALL sp1(); x y z 0000000000 0000000000 0000000000 Warnings: -Warning 1264 Out of range value for column 'x' at row 1 -Warning 1264 Out of range value for column 'y' at row 1 Warning 1264 Out of range value for column 'z' at row 1 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1( ) @@ -7288,8 +7280,6 @@ CALL sp1(); x y z 00000000000000000000 00000000000000000000 00000000000000000000 Warnings: -Warning 1264 Out of range value for column 'x' at row 1 -Warning 1264 Out of range value for column 'y' at row 1 Warning 1264 Out of range value for column 'z' at row 1 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1( ) @@ -7310,8 +7300,6 @@ CALL sp1(); x y z -9999999999 -9999999999 -9999999999 Warnings: -Warning 1264 Out of range value for column 'x' at row 1 -Warning 1264 Out of range value for column 'y' at row 1 Warning 1264 Out of range value for column 'z' at row 1 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1( ) @@ -7323,8 +7311,6 @@ CALL sp1(); x y z 0 0 0 Warnings: -Note 1265 Data truncated for column 'x' at row 1 -Note 1265 Data truncated for column 'y' at row 1 Note 1265 Data truncated for column 'z' at row 1 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1( ) @@ -7336,8 +7322,6 @@ CALL sp1(); x y z 0000000000 0000000000 0000000000 Warnings: -Warning 1264 Out of range value for column 'x' at row 1 -Warning 1264 Out of range value for column 'y' at row 1 Warning 1264 Out of range value for column 'z' at row 1 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1( ) @@ -7349,8 +7333,6 @@ CALL sp1(); x y z 0000000000 0000000000 0000000000 Warnings: -Note 1265 Data truncated for column 'x' at row 1 -Note 1265 Data truncated for column 'y' at row 1 Note 1265 Data truncated for column 'z' at row 1 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1( ) @@ -7362,8 +7344,6 @@ CALL sp1(); x y z 0 0 0 Warnings: -Note 1265 Data truncated for column 'x' at row 1 -Note 1265 Data truncated for column 'y' at row 1 Note 1265 Data truncated for column 'z' at row 1 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1( ) @@ -7375,8 +7355,6 @@ CALL sp1(); x y z 0 0 0 Warnings: -Note 1265 Data truncated for column 'x' at row 1 -Note 1265 Data truncated for column 'y' at row 1 Note 1265 Data truncated for column 'z' at row 1 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1( ) @@ -7388,8 +7366,6 @@ CALL sp1(); x y z 0000000000 0000000000 0000000000 Warnings: -Note 1265 Data truncated for column 'x' at row 1 -Note 1265 Data truncated for column 'y' at row 1 Note 1265 Data truncated for column 'z' at row 1 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1( ) @@ -7401,8 +7377,6 @@ CALL sp1(); x y z 0000000000 0000000000 0000000000 Warnings: -Note 1265 Data truncated for column 'x' at row 1 -Note 1265 Data truncated for column 'y' at row 1 Note 1265 Data truncated for column 'z' at row 1 DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1( ) @@ -13782,9 +13756,6 @@ END// CALL sp1(); x y @x NULL a 3 -Warnings: -Warning 1265 Data truncated for column 'y' at row 3 -Warning 1265 Data truncated for column 'y' at row 1 SELECT @v1, @v2; @v1 @v2 4 a @@ -15465,14 +15436,6 @@ count done 10 1 Warnings: Warning 1265 Data truncated for column 'name' at row 1 -Warning 1265 Data truncated for column 'name' at row 2 -Warning 1265 Data truncated for column 'name' at row 3 -Warning 1265 Data truncated for column 'name' at row 4 -Warning 1265 Data truncated for column 'name' at row 5 -Warning 1265 Data truncated for column 'name' at row 6 -Warning 1265 Data truncated for column 'name' at row 7 -Warning 1265 Data truncated for column 'name' at row 8 -Warning 1265 Data truncated for column 'name' at row 9 DROP PROCEDURE sp3; drop table res_t3_itisalongname_1381742_itsaverylongname_1381742; @@ -16387,7 +16350,6 @@ fn7(99999999999) 9999999999 Warnings: Warning 1264 Out of range value for column 'f1' at row 1 -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP FUNCTION IF EXISTS fn8; CREATE FUNCTION fn8( f1 decimal (0) unsigned zerofill) returns decimal (0) unsigned zerofill @@ -16432,7 +16394,6 @@ fn11(99999999999) 9999999999 Warnings: Warning 1264 Out of range value for column 'f1' at row 1 -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP FUNCTION IF EXISTS fn12; CREATE FUNCTION fn12( f1 decimal (0, 0) unsigned zerofill) returns decimal (0, 0) unsigned zerofill @@ -16533,7 +16494,6 @@ SELECT fn21_d_z(1.00e+00); fn21_d_z(1.00e+00) 0000000000000000000000000000000000000000000000000000000000000010 Warnings: -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP FUNCTION IF EXISTS fn22; CREATE FUNCTION fn22( f1 decimal unsigned) returns decimal unsigned @@ -16545,7 +16505,6 @@ SELECT fn22(1.00e+00); fn22(1.00e+00) 10 Warnings: -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP FUNCTION IF EXISTS fn23; CREATE FUNCTION fn23( f1 decimal unsigned zerofill) returns decimal unsigned zerofill @@ -16557,7 +16516,6 @@ SELECT fn23(1.00e+00); fn23(1.00e+00) 0000000010 Warnings: -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP FUNCTION IF EXISTS fn24; CREATE FUNCTION fn24( f1 decimal zerofill) returns decimal zerofill @@ -16903,7 +16861,6 @@ fn56(-8388601) Warnings: Warning 1264 Out of range value for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 -Warning 1264 Out of range value for column 'f1' at row 1 DROP FUNCTION IF EXISTS fn57; CREATE FUNCTION fn57( f1 numeric) returns numeric BEGIN @@ -16936,7 +16893,6 @@ SELECT fn59(9999999999); fn59(9999999999) 9999999999 Warnings: -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP FUNCTION IF EXISTS fn60; CREATE FUNCTION fn60( f1 numeric (0) unsigned zerofill) returns numeric (0) unsigned zerofill @@ -16982,7 +16938,6 @@ SELECT fn63(9999999999); fn63(9999999999) 9999999999 Warnings: -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP FUNCTION IF EXISTS fn64; CREATE FUNCTION fn64( f1 numeric (0, 0) unsigned zerofill) returns numeric (0, 0) unsigned zerofill @@ -17018,8 +16973,6 @@ fn66(-1e+36) -999999999999999999999999999999989.999999999999999999999999999999 Warnings: Warning 1264 Out of range value for column 'f1' at row 1 -Note 1265 Data truncated for column 'f1' at row 1 -Warning 1264 Out of range value for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP FUNCTION IF EXISTS fn67; CREATE FUNCTION fn67( f1 numeric (63, 30) unsigned) returns numeric (63, 30) unsigned @@ -17032,7 +16985,6 @@ fn67(1e+36) 999999999999999999999999999999999.999999999999999999999999999999 Warnings: Warning 1264 Out of range value for column 'f1' at row 1 -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP FUNCTION IF EXISTS fn68; CREATE FUNCTION fn68( f1 numeric (63, 30) unsigned zerofill) returns numeric (63, 30) unsigned zerofill @@ -17045,7 +16997,6 @@ fn68(1e+36) 999999999999999999999999999999999.999999999999999999999999999999 Warnings: Warning 1264 Out of range value for column 'f1' at row 1 -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP FUNCTION IF EXISTS fn69; CREATE FUNCTION fn69( f1 numeric (63, 30) zerofill) returns numeric (63, 30) zerofill @@ -17213,7 +17164,6 @@ fn84(-32601) Warnings: Warning 1264 Out of range value for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 -Warning 1264 Out of range value for column 'f1' at row 1 DROP FUNCTION IF EXISTS fn85; CREATE FUNCTION fn85( f1 tinyint) returns tinyint BEGIN @@ -17253,7 +17203,6 @@ fn88(-101) Warnings: Warning 1264 Out of range value for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 -Warning 1264 Out of range value for column 'f1' at row 1 DROP FUNCTION IF EXISTS fn89; CREATE FUNCTION fn89( f1 enum('1enum', '2enum')) returns enum('1enum', '2enum') BEGIN @@ -17511,7 +17460,6 @@ f1 9999999999 Warnings: Warning 1264 Out of range value for column 'f1' at row 1 -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP PROCEDURE IF EXISTS sp8; CREATE PROCEDURE sp8( f1 decimal (0) unsigned zerofill) @@ -17556,7 +17504,6 @@ f1 9999999999 Warnings: Warning 1264 Out of range value for column 'f1' at row 1 -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP PROCEDURE IF EXISTS sp12; CREATE PROCEDURE sp12( f1 decimal (0, 0) unsigned zerofill) @@ -17678,7 +17625,6 @@ CALL sp21(1.00e+00); f1 0000000000000000000000000000000000000000000000000000000000000010 Warnings: -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP PROCEDURE IF EXISTS sp22; CREATE PROCEDURE sp22( f1 decimal unsigned) @@ -17690,7 +17636,6 @@ CALL sp22(1.00e+00); f1 10 Warnings: -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP PROCEDURE IF EXISTS sp23; CREATE PROCEDURE sp23( f1 decimal unsigned zerofill) @@ -17702,7 +17647,6 @@ CALL sp23(1.00e+00); f1 0000000010 Warnings: -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP PROCEDURE IF EXISTS sp24; CREATE PROCEDURE sp24( f1 decimal zerofill) @@ -18048,7 +17992,6 @@ f1 Warnings: Warning 1264 Out of range value for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 -Warning 1264 Out of range value for column 'f1' at row 1 DROP PROCEDURE IF EXISTS sp57; CREATE PROCEDURE sp57( f1 numeric) BEGIN @@ -18081,7 +18024,6 @@ CALL sp59(9999999999); f1 9999999999 Warnings: -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP PROCEDURE IF EXISTS sp60; CREATE PROCEDURE sp60( f1 numeric (0) unsigned zerofill) @@ -18127,7 +18069,6 @@ CALL sp63(9999999999); f1 9999999999 Warnings: -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP PROCEDURE IF EXISTS sp64; CREATE PROCEDURE sp64( f1 numeric (0, 0) unsigned zerofill) @@ -18163,16 +18104,12 @@ f1 -999999999999999999999999999999989.999999999999999999999999999999 Warnings: Warning 1264 Out of range value for column 'f1' at row 1 -Note 1265 Data truncated for column 'f1' at row 1 -Warning 1264 Out of range value for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 CALL sp66_n( -1000000000000000000000000000000000000 ); f1 -999999999999999999999999999999989.999999999999999999999999999999 Warnings: Warning 1264 Out of range value for column 'f1' at row 1 -Note 1265 Data truncated for column 'f1' at row 1 -Warning 1264 Out of range value for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP PROCEDURE IF EXISTS sp67_nu; CREATE PROCEDURE sp67_nu( f1 numeric (63, 30) unsigned) @@ -18185,14 +18122,12 @@ f1 999999999999999999999999999999999.999999999999999999999999999999 Warnings: Warning 1264 Out of range value for column 'f1' at row 1 -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 CALL sp67_nu( 1000000000000000000000000000000000000 ); f1 999999999999999999999999999999999.999999999999999999999999999999 Warnings: Warning 1264 Out of range value for column 'f1' at row 1 -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP PROCEDURE IF EXISTS sp68_nuz; CREATE PROCEDURE sp68_nuz( f1 numeric (63, 30) unsigned zerofill) @@ -18205,14 +18140,12 @@ f1 999999999999999999999999999999999.999999999999999999999999999999 Warnings: Warning 1264 Out of range value for column 'f1' at row 1 -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 CALL sp68_nuz( 1000000000000000000000000000000000000 ); f1 999999999999999999999999999999999.999999999999999999999999999999 Warnings: Warning 1264 Out of range value for column 'f1' at row 1 -Note 1265 Data truncated for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 DROP PROCEDURE IF EXISTS sp69_n_z; CREATE PROCEDURE sp69_n_z( f1 numeric (63, 30) zerofill) @@ -18395,7 +18328,6 @@ f1 Warnings: Warning 1264 Out of range value for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 -Warning 1264 Out of range value for column 'f1' at row 1 DROP PROCEDURE IF EXISTS sp85; CREATE PROCEDURE sp85( f1 tinyint) BEGIN @@ -18435,7 +18367,6 @@ f1 Warnings: Warning 1264 Out of range value for column 'f1' at row 1 Warning 1264 Out of range value for column 'f1' at row 1 -Warning 1264 Out of range value for column 'f1' at row 1 DROP PROCEDURE IF EXISTS sp89; CREATE PROCEDURE sp89( f1 enum('1enum', '2enum')) BEGIN @@ -22263,9 +22194,9 @@ END latin1 latin1_swedish_ci latin1_swedish_ci set @@sql_mode=''; CALL sp4(); Level Code Message -Error 1365 Division by 0 +Warning 1365 Division by 0 Warnings: -Error 1365 Division by 0 +Warning 1365 Division by 0 DROP PROCEDURE sp4; set @@sql_mode=''; diff --git a/mysql-test/suite/ndb/r/ndb_multi_row.result b/mysql-test/suite/ndb/r/ndb_multi_row.result index 3d34b16a1a8..96986490d23 100644 --- a/mysql-test/suite/ndb/r/ndb_multi_row.result +++ b/mysql-test/suite/ndb/r/ndb_multi_row.result @@ -63,6 +63,6 @@ t4 drop table t1, t2, t3, t4; drop table if exists t1, t3, t4; Warnings: -Error 155 Table 'test.t1' doesn't exist -Error 155 Table 'test.t3' doesn't exist -Error 155 Table 'test.t4' doesn't exist +Warning 155 Table 'test.t1' doesn't exist +Warning 155 Table 'test.t3' doesn't exist +Warning 155 Table 'test.t4' doesn't exist From b6c16b329a861b4b7da9cda2ede9921af912fd38 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 11 Sep 2009 22:06:27 +0500 Subject: [PATCH 111/138] Fix for bug#47130: misplaced or redundant check for null pointer? Problem: LOGGER::general_log_write() relied on valid "thd" parameter passed but had inconsistent "if (thd)" check. Fix: as we always pass a valid "thd" parameter to the method, redundant check removed. sql/log.cc: Fix for bug#47130: misplaced or redundant check for null pointer? - code clean-up, as we rely on the "thd" parameter in the LOGGER::general_log_write(), redundant "if (thd)" check removed, added assert(thd) instead. --- sql/log.cc | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 1af2f3a4ddc..feaa5499912 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1024,14 +1024,10 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command, Log_event_handler **current_handler= general_log_handler_list; char user_host_buff[MAX_USER_HOST_SIZE + 1]; Security_context *sctx= thd->security_ctx; - ulong id; uint user_host_len= 0; time_t current_time; - if (thd) - id= thd->thread_id; /* Normal thread */ - else - id= 0; /* Log from connect handler */ + DBUG_ASSERT(thd); lock_shared(); if (!opt_log) @@ -1050,7 +1046,7 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command, while (*current_handler) error|= (*current_handler++)-> log_general(thd, current_time, user_host_buff, - user_host_len, id, + user_host_len, thd->thread_id, command_name[(uint) command].str, command_name[(uint) command].length, query, query_length, From 716099e07cd1a1726ad026281fdff3ef21b446f5 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 11 Sep 2009 22:26:35 +0200 Subject: [PATCH 112/138] This is the downport of Bug#24509 - 2048 file descriptor limit on windows needs increasing, also WL#3049 - improved Windows I/O The patch replaces the use of the POSIX I/O interfaces in mysys on Windows with the Win32 API calls (CreateFile, WriteFile, etc). The Windows HANDLE for the open file is stored in the my_file_info struct, along with a flag for append mode because the Windows API does not support opening files in append mode in all cases) The default max open files has been increased to 16384 and can be increased further by setting --max-open-files= during the server start. Another major change in this patch that almost all Windows specific file IO code has been moved to a new file my_winfile.c, greatly reducing the amount of code in #ifdef blocks within mysys, thus improving readability. Minor enhancements: - my_(f)stat() is changed to use __stati64 structure with 64 file size and timestamps. It will return correct file size now (C runtime implementation used to report outdated information) - my_lock on Windows is prepared to handle additional timeout parameter - after review : changed __WIN__ to _WIN32 in the new and changed code. client/mysqlbinlog.cc: fileno -> my_fileno client/readline.cc: fileno -> my_fileno include/config-win.h: Increase OS_FILE_LIMIT for Windows. Remove O_SHARE - Windows does not support it. Its definition conflicts with O_SHORT_LIVED, that has different semantics. include/my_dir.h: Use stat64 for stat() family of functions on Windows, because of 64 bit file size. include/my_global.h: Increased default value for open file limit to 16K include/my_sys.h: - my_file_info got new structure members - file handle and open flags - 2 new Windows-only mysys functions : my_get_osfhandle and my_osmaperr, modelled after Windows C runtime functions _get_osfhandle and _dosmaperr libmysql/CMakeLists.txt: new files my_winfile.c and my_winerr.c mysql-test/suite/large_tests/r/lock_tables_big.result: test for more then 2048 open file descriptors on Windows mysql-test/suite/large_tests/t/lock_tables_big.test: test for more then 2048 open file descriptors on Windows mysys/CMakeLists.txt: new files my_winfile.c and my_winerr.c mysys/Makefile.am: new files my_winfile.c and my_winerr.c mysys/default_modify.c: fileno -> my_fileno mysys/my_chsize.c: implementation of chsize on Windows now moved to my_winfile.c mysys/my_create.c: - my_sopen->my_win_open - close open file before removing (won't generally work on Windows otherwise) mysys/my_file.c: On Windows, files returned by my_open will not start with 0, but 2048 (making it simple to detect incompatible mix of CRT and mysys io functions) mysys/my_fopen.c: fileno->my_win_fileno , fclose->my_win_fclose, fdopen->my_win_fdopen Check for legal filename is done by my_win_[f]open functions mysys/my_fstream.c: fileno->my_fileno mysys/my_lib.c: Windows stat() functions are moved to my_winfile.c mysys/my_lock.c: Move Windows code under #ifdef to a separate function win_lock(). Add a parameter for lock wait timeout mysys/my_mmap.c: _get_osfhandle->my_get_osfhandle mysys/my_open.c: my_sopen->my_win_open (simpler interface) mysys/my_pread.c: moved most windows specific code to my_win_file.c Use my_win_pread mysys/my_quick.c: Use my_win_read/my_win_write mysys/my_read.c: Moved most of windows specific code to my_win_file.c Use my_win_read() mysys/my_seek.c: On Windows, use my_win_lseek() in my_seek()/my_tell() Removed dead code (synchronization of lseeks) Improved DBUG tracing (file position is ulonglong, not ulong) mysys/my_static.c: Removed array initialization. my_file_info_default is global variable thus it is initialized with all zeros anyway mysys/my_sync.c: _commit->my_win_fsync mysys/my_winerr.c: New file my_winerr.c Exports my_osmaperr modelled after undocumented C runtime function _dosmaperr(). The problem with _dosmaperr() used previously is that 1) it is nowhere documented and thus code relying on it is not guaranteed to work in subsequent releases on the C runtime 2) it is present only in static C runtime (mysqld does not link if compiled with /MD) mysys/my_winfile.c: New file my_winfile.c Implements ANSI/Posix file IO routines, when possible using native Windows IO, without C runtime (C runtime dropped because of the 2048 file descriptor limit). mysys/my_write.c: write->my_win_write mysys/mysys_priv.h: Declaration of Windows Posix functions (private to mysys, shall not be visible outside) storage/innobase/handler/ha_innodb.cc: mysys native Windows IO : correct innodb tmp file handling mysql_tmpfile does not return valid CRT file descriptor, thus it is not possible to dup() it. Instead, the native file handle has to be duplicated and then converted to CRT descriptor. storage/myisam/mi_locking.c: _commit->my_sync --- client/mysqlbinlog.cc | 2 +- client/mysqlslap.c | 2 +- client/readline.cc | 2 +- include/config-win.h | 3 +- include/my_dir.h | 4 + include/my_global.h | 41 +- include/my_sys.h | 24 +- libmysql/CMakeLists.txt | 2 +- .../large_tests/r/lock_tables_big.result | 1 + .../suite/large_tests/t/lock_tables_big.test | 32 + mysys/CMakeLists.txt | 2 +- mysys/Makefile.am | 2 +- mysys/default_modify.c | 6 +- mysys/my_chsize.c | 19 +- mysys/my_create.c | 15 +- mysys/my_dup.c | 6 +- mysys/my_file.c | 1 + mysys/my_fopen.c | 49 +- mysys/my_fstream.c | 17 +- mysys/my_lib.c | 26 +- mysys/my_lock.c | 140 +++- mysys/my_mmap.c | 6 +- mysys/my_open.c | 223 +----- mysys/my_pread.c | 103 +-- mysys/my_quick.c | 22 +- mysys/my_read.c | 21 +- mysys/my_seek.c | 38 +- mysys/my_static.c | 2 +- mysys/my_sync.c | 4 +- mysys/my_winerr.c | 123 ++++ mysys/my_winfile.c | 671 ++++++++++++++++++ mysys/my_write.c | 39 +- mysys/mysys_priv.h | 24 + storage/innobase/handler/ha_innodb.cc | 22 + storage/myisam/mi_locking.c | 8 +- 35 files changed, 1284 insertions(+), 418 deletions(-) create mode 100644 mysql-test/suite/large_tests/r/lock_tables_big.result create mode 100644 mysql-test/suite/large_tests/t/lock_tables_big.test create mode 100644 mysys/my_winerr.c create mode 100644 mysys/my_winfile.c diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 82af7ca65f6..a01918caad4 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -1909,7 +1909,7 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, return ERROR_STOP; } #endif - if (init_io_cache(file, fileno(stdin), 0, READ_CACHE, (my_off_t) 0, + if (init_io_cache(file, my_fileno(stdin), 0, READ_CACHE, (my_off_t) 0, 0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE))) { error("Failed to init IO cache."); diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 70abfbb7136..6a016b72383 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -1199,7 +1199,7 @@ get_options(int *argc,char ***argv) if (opt_csv_str[0] == '-') { - csv_file= fileno(stdout); + csv_file= my_fileno(stdout); } else { diff --git a/client/readline.cc b/client/readline.cc index b32cb71b0de..73ce7c3b8c7 100644 --- a/client/readline.cc +++ b/client/readline.cc @@ -33,7 +33,7 @@ LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file) if (!(line_buff=(LINE_BUFFER*) my_malloc(sizeof(*line_buff),MYF(MY_WME | MY_ZEROFILL)))) return 0; - if (init_line_buffer(line_buff,fileno(file),IO_SIZE,max_size)) + if (init_line_buffer(line_buff,my_fileno(file),IO_SIZE,max_size)) { my_free(line_buff,MYF(0)); return 0; diff --git a/include/config-win.h b/include/config-win.h index af4915440b1..bcad4e04346 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -65,7 +65,6 @@ #endif /* File and lock constants */ -#define O_SHARE 0x1000 /* Open file in sharing mode */ #ifdef __BORLANDC__ #define F_RDLCK LK_NBLCK /* read lock */ #define F_WRLCK LK_NBRLCK /* write lock */ @@ -336,7 +335,7 @@ inline ulonglong double2ulonglong(double d) #define FN_DEVCHAR ':' #define FN_NETWORK_DRIVES /* Uses \\ to indicate network drives */ #define FN_NO_CASE_SENCE /* Files are not case-sensitive */ -#define OS_FILE_LIMIT 2048 +#define OS_FILE_LIMIT UINT_MAX /* No limit*/ #define DO_NOT_REMOVE_THREAD_WRAPPERS #define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V)) diff --git a/include/my_dir.h b/include/my_dir.h index 06509a3af19..90d708ac811 100644 --- a/include/my_dir.h +++ b/include/my_dir.h @@ -69,7 +69,11 @@ typedef struct my_stat #else +#if(_MSC_VER) +#define MY_STAT struct _stati64 /* 64 bit file size */ +#else #define MY_STAT struct stat /* Orginal struct have what we need */ +#endif #endif /* USE_MY_STAT_STRUCT */ diff --git a/include/my_global.h b/include/my_global.h index 4ad851e9e5d..f7e65d80dbb 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -736,7 +736,41 @@ typedef SOCKET_SIZE_TYPE size_socket; #define FN_LIBCHAR '/' #define FN_ROOTDIR "/" #endif -#define MY_NFILE 64 /* This is only used to save filenames */ + +/* + MY_FILE_MIN is Windows speciality and is used to quickly detect + the mismatch of CRT and mysys file IO usage on Windows at runtime. + CRT file descriptors can be in the range 0-2047, whereas descriptors returned + by my_open() will start with 2048. If a file descriptor with value less then + MY_FILE_MIN is passed to mysys IO function, chances are it stemms from + open()/fileno() and not my_open()/my_fileno. + + For Posix, mysys functions are light wrappers around libc, and MY_FILE_MIN + is logically 0. +*/ + +#ifdef _WIN32 +#define MY_FILE_MIN 2048 +#else +#define MY_FILE_MIN 0 +#endif + +/* + MY_NFILE is the default size of my_file_info array. + + It is larger on Windows, because it all file handles are stored in my_file_info + Default size is 16384 and this should be enough for most cases.If it is not + enough, --max-open-files with larger value can be used. + + For Posix , my_file_info array is only used to store filenames for + error reporting and its size is not a limitation for number of open files. +*/ +#ifdef _WIN32 +#define MY_NFILE (16384 + MY_FILE_MIN) +#else +#define MY_NFILE 64 +#endif + #ifndef OS_FILE_LIMIT #define OS_FILE_LIMIT 65535 #endif @@ -773,9 +807,8 @@ typedef SOCKET_SIZE_TYPE size_socket; /* Some things that this system doesn't have */ #define NO_HASH /* Not needed anymore */ -#ifdef __WIN__ -#define NO_DIR_LIBRARY /* Not standar dir-library */ -#define USE_MY_STAT_STRUCT /* For my_lib */ +#ifdef _WIN32 +#define NO_DIR_LIBRARY /* Not standard dir-library */ #endif /* Some defines of functions for portability */ diff --git a/include/my_sys.h b/include/my_sys.h index 222564e0b44..849c35606b1 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -310,9 +310,13 @@ enum file_type struct st_my_file_info { - char * name; - enum file_type type; -#if defined(THREAD) && !defined(HAVE_PREAD) + char *name; +#ifdef _WIN32 + HANDLE fhandle; /* win32 file handle */ + int oflag; /* open flags, e.g O_APPEND */ +#endif + enum file_type type; +#if defined(THREAD) && !defined(HAVE_PREAD) && !defined(_WIN32) pthread_mutex_t mutex; #endif }; @@ -617,12 +621,12 @@ extern void *my_memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen); -#ifdef __WIN__ -extern int my_access(const char *path, int amode); -extern File my_sopen(const char *path, int oflag, int shflag, int pmode); +#ifdef _WIN32 +extern int my_access(const char *path, int amode); #else #define my_access access #endif + extern int check_if_legal_filename(const char *path); extern int check_if_legal_tablename(const char *path); @@ -633,6 +637,13 @@ extern int nt_share_delete(const char *name,myf MyFlags); #define my_delete_allow_opened(fname,flags) my_delete((fname),(flags)) #endif +#ifdef _WIN32 +/* Windows-only functions (CRT equivalents)*/ +extern File my_sopen(const char *path, int oflag, int shflag, int pmode); +extern HANDLE my_get_osfhandle(File fd); +extern void my_osmaperr(unsigned long last_error); +#endif + #ifndef TERMINATE extern void TERMINATE(FILE *file, uint flag); #endif @@ -641,6 +652,7 @@ extern void wait_for_free_space(const char *filename, int errors); extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags); extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags); extern int my_fclose(FILE *fd,myf MyFlags); +extern File my_fileno(FILE *fd); extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags); extern int my_sync(File fd, myf my_flags); extern int my_sync_dir(const char *dir_name, myf my_flags); diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index 55138e4aa06..b252d94b50e 100755 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -98,7 +98,7 @@ SET(CLIENT_SOURCES ../mysys/array.c ../strings/bchange.c ../strings/bmove.c ../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c ../strings/strxnmov.c ../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c ../mysys/mf_qsort.c - ../mysys/my_getsystime.c ../mysys/my_sync.c ${LIB_SOURCES}) + ../mysys/my_getsystime.c ../mysys/my_sync.c ../mysys/my_winerr.c ../mysys/my_winfile.c ${LIB_SOURCES}) # Need to set USE_TLS for building the DLL, since __declspec(thread) # approach to thread local storage does not work properly in DLLs. diff --git a/mysql-test/suite/large_tests/r/lock_tables_big.result b/mysql-test/suite/large_tests/r/lock_tables_big.result new file mode 100644 index 00000000000..de639143055 --- /dev/null +++ b/mysql-test/suite/large_tests/r/lock_tables_big.result @@ -0,0 +1 @@ +all done diff --git a/mysql-test/suite/large_tests/t/lock_tables_big.test b/mysql-test/suite/large_tests/t/lock_tables_big.test new file mode 100644 index 00000000000..41dcff3577c --- /dev/null +++ b/mysql-test/suite/large_tests/t/lock_tables_big.test @@ -0,0 +1,32 @@ +# +# Bug#24509 cannot use more than 2048 file descriptors on windows +# +--disable_query_log +create database many_tables; +use many_tables; +let $max_tables=3000; +let $i=$max_tables; + +--disable_warnings +create table t (i int); +let $table_list=t READ; + +while ($i) +{ + eval create table t$i (i int); + let $table_list= $table_list ,t$i READ; + dec $i; +} + +#lock all tables we just created (resembles mysqldump startup is doing with --all-databases operation) +#There will be 3 descriptors for each table (table.FRM, table.MYI and table.MYD files) means 9000 files +#descriptors altogether. For Microsoft C runtime, this is way too many. + +eval LOCK TABLES $table_list; +unlock tables; + +drop database many_tables; +--disable_query_log +--echo all done + + diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt index 545278485d1..f2d540d2295 100755 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -39,7 +39,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_ my_mkdir.c my_mmap.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_sleep.c my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c - my_windac.c my_winthread.c my_write.c ptr_cmp.c queues.c stacktrace.c + my_winerr.c my_winfile.c my_windac.c my_winthread.c my_write.c ptr_cmp.c queues.c stacktrace.c rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c) diff --git a/mysys/Makefile.am b/mysys/Makefile.am index 4b07cf89676..fdc93ba1a4a 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -56,7 +56,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ thr_mutex.c thr_rwlock.c \ CMakeLists.txt mf_soundex.c \ - my_conio.c my_wincond.c my_winthread.c + my_conio.c my_wincond.c my_winthread.c my_winerr.c my_winfile.c libmysys_a_LIBADD = @THREAD_LOBJECTS@ # test_dir_DEPENDENCIES= $(LIBRARIES) # testhash_DEPENDENCIES= $(LIBRARIES) diff --git a/mysys/default_modify.c b/mysys/default_modify.c index 88df0122da2..b214a1df445 100644 --- a/mysys/default_modify.c +++ b/mysys/default_modify.c @@ -21,7 +21,7 @@ #define BUFF_SIZE 1024 #define RESERVE 1024 /* Extend buffer with this extent */ -#ifdef __WIN__ +#ifdef _WIN32 #define NEWLINE "\r\n" #define NEWLINE_LEN 2 #else @@ -78,7 +78,7 @@ int modify_defaults_file(const char *file_location, const char *option, DBUG_RETURN(2); /* my_fstat doesn't use the flag parameter */ - if (my_fstat(fileno(cnf_file), &file_stat, MYF(0))) + if (my_fstat(my_fileno(cnf_file), &file_stat, MYF(0))) goto malloc_err; if (option && option_value) @@ -213,7 +213,7 @@ int modify_defaults_file(const char *file_location, const char *option, if (opt_applied) { /* Don't write the file if there are no changes to be made */ - if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0, + if (my_chsize(my_fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0, MYF(MY_WME)) || my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) || my_fwrite(cnf_file, (uchar*) file_buffer, (size_t) (dst_ptr - file_buffer), diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c index b1dbb22c687..b9013811b34 100644 --- a/mysys/my_chsize.c +++ b/mysys/my_chsize.c @@ -52,20 +52,13 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags) if (oldsize > newlength) { -#if defined(HAVE_SETFILEPOINTER) - /* This is for the moment only true on windows */ - long is_success; - HANDLE win_file= (HANDLE) _get_osfhandle(fd); - long length_low, length_high; - length_low= (long) (ulong) newlength; - length_high= (long) ((ulonglong) newlength >> 32); - is_success= SetFilePointer(win_file, length_low, &length_high, FILE_BEGIN); - if (is_success == -1 && (my_errno= GetLastError()) != NO_ERROR) +#ifdef _WIN32 + if (my_win_chsize(fd, newlength)) + { + my_errno= errno; goto err; - if (SetEndOfFile(win_file)) - DBUG_RETURN(0); - my_errno= GetLastError(); - goto err; + } + DBUG_RETURN(0); #elif defined(HAVE_FTRUNCATE) if (ftruncate(fd, (off_t) newlength)) { diff --git a/mysys/my_create.c b/mysys/my_create.c index 5c9a1e027d2..d0436276d03 100644 --- a/mysys/my_create.c +++ b/mysys/my_create.c @@ -18,7 +18,7 @@ #include "mysys_err.h" #include #include -#if defined(__WIN__) +#if defined(_WIN32) #include #endif @@ -41,16 +41,12 @@ File my_create(const char *FileName, int CreateFlags, int access_flags, FileName, CreateFlags, access_flags, MyFlags)); #if !defined(NO_OPEN_3) - fd = open((char *) FileName, access_flags | O_CREAT, + fd= open((char *) FileName, access_flags | O_CREAT, CreateFlags ? CreateFlags : my_umask); -#elif defined(VMS) - fd = open((char *) FileName, access_flags | O_CREAT, 0, - "ctx=stm","ctx=bin"); -#elif defined(__WIN__) - fd= my_sopen((char *) FileName, access_flags | O_CREAT | O_BINARY, - SH_DENYNO, MY_S_IREAD | MY_S_IWRITE); +#elif defined(_WIN32) + fd= my_win_open(FileName, access_flags | O_CREAT); #else - fd = open(FileName, access_flags); + fd= open(FileName, access_flags); #endif if ((MyFlags & MY_SYNC_DIR) && (fd >=0) && @@ -71,6 +67,7 @@ File my_create(const char *FileName, int CreateFlags, int access_flags, if (unlikely(fd >= 0 && rc < 0)) { int tmp= my_errno; + my_close(fd, MyFlags); my_delete(FileName, MyFlags); my_errno= tmp; } diff --git a/mysys/my_dup.c b/mysys/my_dup.c index 55f5e0c0099..5fdd6e9f364 100644 --- a/mysys/my_dup.c +++ b/mysys/my_dup.c @@ -29,7 +29,11 @@ File my_dup(File file, myf MyFlags) const char *filename; DBUG_ENTER("my_dup"); DBUG_PRINT("my",("file: %d MyFlags: %d", file, MyFlags)); - fd = dup(file); +#ifdef _WIN32 + fd= my_win_dup(file); +#else + fd= dup(file); +#endif filename= (((uint) file < my_file_limit) ? my_file_info[(int) file].name : "Unknown"); DBUG_RETURN(my_register_filename(fd, filename, FILE_BY_DUP, diff --git a/mysys/my_file.c b/mysys/my_file.c index 44bacf55307..ec0c9c425ea 100644 --- a/mysys/my_file.c +++ b/mysys/my_file.c @@ -97,6 +97,7 @@ uint my_set_max_open_files(uint files) DBUG_ENTER("my_set_max_open_files"); DBUG_PRINT("enter",("files: %u my_file_limit: %u", files, my_file_limit)); + files+= MY_FILE_MIN; files= set_max_open_files(min(files, OS_FILE_LIMIT)); if (files <= MY_NFILE) DBUG_RETURN(files); diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c index 44156da6ae3..879acac0111 100644 --- a/mysys/my_fopen.c +++ b/mysys/my_fopen.c @@ -41,24 +41,14 @@ FILE *my_fopen(const char *filename, int flags, myf MyFlags) DBUG_ENTER("my_fopen"); DBUG_PRINT("my",("Name: '%s' flags: %d MyFlags: %d", filename, flags, MyFlags)); - /* - if we are not creating, then we need to use my_access to make sure - the file exists since Windows doesn't handle files like "com1.sym" - very well - */ -#ifdef __WIN__ - if (check_if_legal_filename(filename)) - { - errno= EACCES; - fd= 0; - } - else + + make_ftype(type,flags); + +#ifdef _WIN32 + fd= my_win_fopen(filename, type); +#else + fd= fopen(filename, type); #endif - { - make_ftype(type,flags); - fd = fopen(filename, type); - } - if (fd != 0) { /* @@ -66,18 +56,20 @@ FILE *my_fopen(const char *filename, int flags, myf MyFlags) on some OS (SUNOS). Actually the filename save isn't that important so we can ignore if this doesn't work. */ - if ((uint) fileno(fd) >= my_file_limit) + + int filedesc= my_fileno(fd); + if ((uint)filedesc >= my_file_limit) { thread_safe_increment(my_stream_opened,&THR_LOCK_open); DBUG_RETURN(fd); /* safeguard */ } pthread_mutex_lock(&THR_LOCK_open); - if ((my_file_info[fileno(fd)].name = (char*) + if ((my_file_info[filedesc].name= (char*) my_strdup(filename,MyFlags))) { my_stream_opened++; my_file_total_opened++; - my_file_info[fileno(fd)].type = STREAM_BY_FOPEN; + my_file_info[filedesc].type= STREAM_BY_FOPEN; pthread_mutex_unlock(&THR_LOCK_open); DBUG_PRINT("exit",("stream: 0x%lx", (long) fd)); DBUG_RETURN(fd); @@ -99,6 +91,7 @@ FILE *my_fopen(const char *filename, int flags, myf MyFlags) /* Close a stream */ +/* Close a stream */ int my_fclose(FILE *fd, myf MyFlags) { int err,file; @@ -106,8 +99,13 @@ int my_fclose(FILE *fd, myf MyFlags) DBUG_PRINT("my",("stream: 0x%lx MyFlags: %d", (long) fd, MyFlags)); pthread_mutex_lock(&THR_LOCK_open); - file=fileno(fd); - if ((err = fclose(fd)) < 0) + file= my_fileno(fd); +#ifndef _WIN32 + err= fclose(fd); +#else + err= my_win_fclose(fd); +#endif + if(err < 0) { my_errno=errno; if (MyFlags & (MY_FAE | MY_WME)) @@ -138,7 +136,12 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags) Filedes, Flags, MyFlags)); make_ftype(type,Flags); - if ((fd = fdopen(Filedes, type)) == 0) +#ifdef _WIN32 + fd= my_win_fdopen(Filedes, type); +#else + fd= fdopen(Filedes, type); +#endif + if (!fd) { my_errno=errno; if (MyFlags & (MY_FAE | MY_WME)) diff --git a/mysys/my_fstream.c b/mysys/my_fstream.c index f3b5418b906..2059e1a9f18 100644 --- a/mysys/my_fstream.c +++ b/mysys/my_fstream.c @@ -56,11 +56,11 @@ size_t my_fread(FILE *stream, uchar *Buffer, size_t Count, myf MyFlags) { if (ferror(stream)) my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG), - my_filename(fileno(stream)),errno); + my_filename(my_fileno(stream)),errno); else if (MyFlags & (MY_NABP | MY_FNABP)) my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG), - my_filename(fileno(stream)),errno); + my_filename(my_fileno(stream)),errno); } my_errno=errno ? errno : -1; if (ferror(stream) || MyFlags & (MY_NABP | MY_FNABP)) @@ -142,7 +142,7 @@ size_t my_fwrite(FILE *stream, const uchar *Buffer, size_t Count, myf MyFlags) if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) { my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG), - my_filename(fileno(stream)),errno); + my_filename(my_fileno(stream)),errno); } writtenbytes= (size_t) -1; /* Return that we got error */ break; @@ -182,3 +182,14 @@ my_off_t my_ftell(FILE *stream, myf MyFlags __attribute__((unused))) DBUG_PRINT("exit",("ftell: %lu",(ulong) pos)); DBUG_RETURN((my_off_t) pos); } /* my_ftell */ + + +/* Get a File corresponding to the stream*/ +int my_fileno(FILE *f) +{ +#ifdef _WIN32 + return my_win_fileno(f); +#else + return fileno(f); +#endif +} diff --git a/mysys/my_lib.c b/mysys/my_lib.c index c18d14fb549..033f8789b49 100644 --- a/mysys/my_lib.c +++ b/mysys/my_lib.c @@ -35,8 +35,7 @@ # if defined(HAVE_NDIR_H) # include # endif -# if defined(__WIN__) -# include +# if defined(_WIN32) # ifdef __BORLANDC__ # include # endif @@ -92,7 +91,7 @@ static int comp_names(struct fileinfo *a, struct fileinfo *b) } /* comp_names */ -#if !defined(__WIN__) +#if !defined(_WIN32) MY_DIR *my_dir(const char *path, myf MyFlags) { @@ -507,19 +506,24 @@ error: DBUG_RETURN((MY_DIR *) NULL); } /* my_dir */ -#endif /* __WIN__ */ +#endif /* _WIN32 */ /**************************************************************************** ** File status ** Note that MY_STAT is assumed to be same as struct stat ****************************************************************************/ -int my_fstat(int Filedes, MY_STAT *stat_area, + +int my_fstat(File Filedes, MY_STAT *stat_area, myf MyFlags __attribute__((unused))) { DBUG_ENTER("my_fstat"); DBUG_PRINT("my",("fd: %d MyFlags: %d", Filedes, MyFlags)); +#ifdef _WIN32 + DBUG_RETURN(my_win_fstat(Filedes, stat_area)); +#else DBUG_RETURN(fstat(Filedes, (struct stat *) stat_area)); +#endif } @@ -531,11 +535,15 @@ MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags) (long) stat_area, my_flags)); if ((m_used= (stat_area == NULL))) - if (!(stat_area = (MY_STAT *) my_malloc(sizeof(MY_STAT), my_flags))) + if (!(stat_area= (MY_STAT *) my_malloc(sizeof(MY_STAT), my_flags))) goto error; - if (! stat((char *) path, (struct stat *) stat_area) ) - DBUG_RETURN(stat_area); - +#ifndef _WIN32 + if (! stat((char *) path, (struct stat *) stat_area) ) + DBUG_RETURN(stat_area); +#else + if (! my_win_stat(path, stat_area) ) + DBUG_RETURN(stat_area); +#endif DBUG_PRINT("error",("Got errno: %d from stat", errno)); my_errno= errno; if (m_used) /* Free if new area */ diff --git a/mysys/my_lock.c b/mysys/my_lock.c index c0522ee849d..62f39bd3b71 100644 --- a/mysys/my_lock.c +++ b/mysys/my_lock.c @@ -22,13 +22,113 @@ #undef NO_ALARM_LOOP #endif #include -#ifdef __WIN__ -#include -#endif #ifdef __NETWARE__ #include #endif +#ifdef _WIN32 +#define WIN_LOCK_INFINITE -1 +#define WIN_LOCK_SLEEP_MILLIS 100 + +static int win_lock(File fd, int locktype, my_off_t start, my_off_t length, + int timeout_sec) +{ + LARGE_INTEGER liOffset,liLength; + DWORD dwFlags; + OVERLAPPED ov= {0}; + HANDLE hFile= (HANDLE)my_get_osfhandle(fd); + DWORD lastError= 0; + int i; + int timeout_millis= timeout_sec * 1000; + + DBUG_ENTER("win_lock"); + + liOffset.QuadPart= start; + liLength.QuadPart= length; + + ov.Offset= liOffset.LowPart; + ov.OffsetHigh= liOffset.HighPart; + + if (locktype == F_UNLCK) + { + if (UnlockFileEx(hFile, 0, liLength.LowPart, liLength.HighPart, &ov)) + DBUG_RETURN(0); + /* + For compatibility with fcntl implementation, ignore error, + if region was not locked + */ + if (GetLastError() == ERROR_NOT_LOCKED) + { + SetLastError(0); + DBUG_RETURN(0); + } + goto error; + } + else if (locktype == F_RDLCK) + /* read lock is mapped to a shared lock. */ + dwFlags= 0; + else + /* write lock is mapped to an exclusive lock. */ + dwFlags= LOCKFILE_EXCLUSIVE_LOCK; + + /* + Drop old lock first to avoid double locking. + During analyze of Bug#38133 (Myisamlog test fails on Windows) + I met the situation that the program myisamlog locked the file + exclusively, then additionally shared, then did one unlock, and + then blocked on an attempt to lock it exclusively again. + Unlocking before every lock fixed the problem. + Note that this introduces a race condition. When the application + wants to convert an exclusive lock into a shared one, it will now + first unlock the file and then lock it shared. A waiting exclusive + lock could step in here. For reasons described in Bug#38133 and + Bug#41124 (Server hangs on Windows with --external-locking after + INSERT...SELECT) and in the review thread at + http://lists.mysql.com/commits/60721 it seems to be the better + option than not to unlock here. + If one day someone notices a way how to do file lock type changes + on Windows without unlocking before taking the new lock, please + change this code accordingly to fix the race condition. + */ + if (!UnlockFileEx(hFile, 0, liLength.LowPart, liLength.HighPart, &ov) && + (GetLastError() != ERROR_NOT_LOCKED)) + goto error; + + if (timeout_sec == WIN_LOCK_INFINITE) + { + if (LockFileEx(hFile, dwFlags, 0, liLength.LowPart, liLength.HighPart, &ov)) + DBUG_RETURN(0); + goto error; + } + + dwFlags|= LOCKFILE_FAIL_IMMEDIATELY; + timeout_millis= timeout_sec * 1000; + /* Try lock in a loop, until the lock is acquired or timeout happens */ + for(i= 0; ;i+= WIN_LOCK_SLEEP_MILLIS) + { + if (LockFileEx(hFile, dwFlags, 0, liLength.LowPart, liLength.HighPart, &ov)) + DBUG_RETURN(0); + + if (GetLastError() != ERROR_LOCK_VIOLATION) + goto error; + + if (i >= timeout_millis) + break; + Sleep(WIN_LOCK_SLEEP_MILLIS); + } + + /* timeout */ + errno= EAGAIN; + DBUG_RETURN(-1); + +error: + my_osmaperr(GetLastError()); + DBUG_RETURN(-1); +} +#endif + + + /* Lock a part of a file @@ -48,8 +148,9 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length, #ifdef __NETWARE__ int nxErrno; #endif + DBUG_ENTER("my_lock"); - DBUG_PRINT("my",("Fd: %d Op: %d start: %ld Length: %ld MyFlags: %d", + DBUG_PRINT("my",("fd: %d Op: %d start: %ld Length: %ld MyFlags: %d", fd,locktype,(long) start,(long) length,MyFlags)); #ifdef VMS DBUG_RETURN(0); @@ -97,29 +198,16 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length, DBUG_RETURN(0); } } -#elif defined(HAVE_LOCKING) - /* Windows */ +#elif defined(_WIN32) { - my_bool error= FALSE; - pthread_mutex_lock(&my_file_info[fd].mutex); - if (MyFlags & MY_SEEK_NOT_DONE) - { - if( my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE)) - == MY_FILEPOS_ERROR ) - { - /* - If my_seek fails my_errno will already contain an error code; - just unlock and return error code. - */ - DBUG_PRINT("error",("my_errno: %d (%d)",my_errno,errno)); - pthread_mutex_unlock(&my_file_info[fd].mutex); - DBUG_RETURN(-1); - } - } - error= locking(fd,locktype,(ulong) length) && errno != EINVAL; - pthread_mutex_unlock(&my_file_info[fd].mutex); - if (!error) - DBUG_RETURN(0); + int timeout_sec; + if (MyFlags & MY_DONT_WAIT) + timeout_sec= 0; + else + timeout_sec= WIN_LOCK_INFINITE; + + if(win_lock(fd, locktype, start, length, timeout_sec) == 0) + DBUG_RETURN(0); } #else #if defined(HAVE_FCNTL) diff --git a/mysys/my_mmap.c b/mysys/my_mmap.c index 023a06fd896..303d8efaf30 100644 --- a/mysys/my_mmap.c +++ b/mysys/my_mmap.c @@ -27,17 +27,17 @@ int my_msync(int fd, void *addr, size_t len, int flags) return my_sync(fd, MYF(0)); } -#elif defined(__WIN__) +#elif defined(_WIN32) static SECURITY_ATTRIBUTES mmap_security_attributes= {sizeof(SECURITY_ATTRIBUTES), 0, TRUE}; void *my_mmap(void *addr, size_t len, int prot, - int flags, int fd, my_off_t offset) + int flags, File fd, my_off_t offset) { HANDLE hFileMap; LPVOID ptr; - HANDLE hFile= (HANDLE)_get_osfhandle(fd); + HANDLE hFile= (HANDLE)my_get_osfhandle(fd); if (hFile == INVALID_HANDLE_VALUE) return MAP_FAILED; diff --git a/mysys/my_open.c b/mysys/my_open.c index fe7f65c450b..79a4da242f9 100644 --- a/mysys/my_open.c +++ b/mysys/my_open.c @@ -17,9 +17,7 @@ #include "mysys_err.h" #include #include -#if defined(__WIN__) -#include -#endif + /* Open a file @@ -43,29 +41,8 @@ File my_open(const char *FileName, int Flags, myf MyFlags) DBUG_ENTER("my_open"); DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %d", FileName, Flags, MyFlags)); -#if defined(__WIN__) - /* - Check that we don't try to open or create a file name that may - cause problems for us in the future (like PRN) - */ - if (check_if_legal_filename(FileName)) - { - errno= EACCES; - DBUG_RETURN(my_register_filename(-1, FileName, FILE_BY_OPEN, - EE_FILENOTFOUND, MyFlags)); - } -#ifndef __WIN__ - if (Flags & O_SHARE) - fd = sopen((char *) FileName, (Flags & ~O_SHARE) | O_BINARY, SH_DENYNO, - MY_S_IREAD | MY_S_IWRITE); - else - fd = open((char *) FileName, Flags | O_BINARY, - MY_S_IREAD | MY_S_IWRITE); -#else - fd= my_sopen((char *) FileName, (Flags & ~O_SHARE) | O_BINARY, SH_DENYNO, - MY_S_IREAD | MY_S_IWRITE); -#endif - +#if defined(_WIN32) + fd= my_win_open(FileName, Flags); #elif !defined(NO_OPEN_3) fd = open(FileName, Flags, my_umask); /* Normal unix */ #else @@ -94,11 +71,14 @@ int my_close(File fd, myf MyFlags) DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags)); pthread_mutex_lock(&THR_LOCK_open); +#ifndef _WIN32 do { err= close(fd); } while (err == -1 && errno == EINTR); - +#else + err= my_win_close(fd); +#endif if (err) { DBUG_PRINT("error",("Got error %d on close",err)); @@ -109,7 +89,7 @@ int my_close(File fd, myf MyFlags) if ((uint) fd < my_file_limit && my_file_info[fd].type != UNOPEN) { my_free(my_file_info[fd].name, MYF(0)); -#if defined(THREAD) && !defined(HAVE_PREAD) +#if defined(THREAD) && !defined(HAVE_PREAD) && !defined(_WIN32) pthread_mutex_destroy(&my_file_info[fd].mutex); #endif my_file_info[fd].type = UNOPEN; @@ -141,11 +121,11 @@ File my_register_filename(File fd, const char *FileName, enum file_type type_of_file, uint error_message_number, myf MyFlags) { DBUG_ENTER("my_register_filename"); - if ((int) fd >= 0) + if ((int) fd >= MY_FILE_MIN) { if ((uint) fd >= my_file_limit) { -#if defined(THREAD) && !defined(HAVE_PREAD) +#if defined(THREAD) && !defined(HAVE_PREAD) my_errno= EMFILE; #else thread_safe_increment(my_file_opened,&THR_LOCK_open); @@ -160,7 +140,7 @@ File my_register_filename(File fd, const char *FileName, enum file_type my_file_opened++; my_file_total_opened++; my_file_info[fd].type = type_of_file; -#if defined(THREAD) && !defined(HAVE_PREAD) +#if defined(THREAD) && !defined(HAVE_PREAD) && !defined(_WIN32) pthread_mutex_init(&my_file_info[fd].mutex,MY_MUTEX_INIT_FAST); #endif pthread_mutex_unlock(&THR_LOCK_open); @@ -187,188 +167,7 @@ File my_register_filename(File fd, const char *FileName, enum file_type DBUG_RETURN(-1); } -#ifdef __WIN__ -extern void __cdecl _dosmaperr(unsigned long); - -/* - Open a file with sharing. Similar to _sopen() from libc, but allows managing - share delete on win32 - - SYNOPSIS - my_sopen() - path fully qualified file name - oflag operation flags - shflag share flag - pmode permission flags - - RETURN VALUE - File descriptor of opened file if success - -1 and sets errno if fails. -*/ - -File my_sopen(const char *path, int oflag, int shflag, int pmode) -{ - int fh; /* handle of opened file */ - int mask; - HANDLE osfh; /* OS handle of opened file */ - DWORD fileaccess; /* OS file access (requested) */ - DWORD fileshare; /* OS file sharing mode */ - DWORD filecreate; /* OS method of opening/creating */ - DWORD fileattrib; /* OS file attribute flags */ - SECURITY_ATTRIBUTES SecurityAttributes; - - SecurityAttributes.nLength= sizeof(SecurityAttributes); - SecurityAttributes.lpSecurityDescriptor= NULL; - SecurityAttributes.bInheritHandle= !(oflag & _O_NOINHERIT); - - /* - * decode the access flags - */ - switch (oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)) { - case _O_RDONLY: /* read access */ - fileaccess= GENERIC_READ; - break; - case _O_WRONLY: /* write access */ - fileaccess= GENERIC_WRITE; - break; - case _O_RDWR: /* read and write access */ - fileaccess= GENERIC_READ | GENERIC_WRITE; - break; - default: /* error, bad oflag */ - errno= EINVAL; - _doserrno= 0L; /* not an OS error */ - return -1; - } - - /* - * decode sharing flags - */ - switch (shflag) { - case _SH_DENYRW: /* exclusive access except delete */ - fileshare= FILE_SHARE_DELETE; - break; - case _SH_DENYWR: /* share read and delete access */ - fileshare= FILE_SHARE_READ | FILE_SHARE_DELETE; - break; - case _SH_DENYRD: /* share write and delete access */ - fileshare= FILE_SHARE_WRITE | FILE_SHARE_DELETE; - break; - case _SH_DENYNO: /* share read, write and delete access */ - fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; - break; - case _SH_DENYRWD: /* exclusive access */ - fileshare= 0L; - break; - case _SH_DENYWRD: /* share read access */ - fileshare= FILE_SHARE_READ; - break; - case _SH_DENYRDD: /* share write access */ - fileshare= FILE_SHARE_WRITE; - break; - case _SH_DENYDEL: /* share read and write access */ - fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE; - break; - default: /* error, bad shflag */ - errno= EINVAL; - _doserrno= 0L; /* not an OS error */ - return -1; - } - - /* - * decode open/create method flags - */ - switch (oflag & (_O_CREAT | _O_EXCL | _O_TRUNC)) { - case 0: - case _O_EXCL: /* ignore EXCL w/o CREAT */ - filecreate= OPEN_EXISTING; - break; - - case _O_CREAT: - filecreate= OPEN_ALWAYS; - break; - - case _O_CREAT | _O_EXCL: - case _O_CREAT | _O_TRUNC | _O_EXCL: - filecreate= CREATE_NEW; - break; - - case _O_TRUNC: - case _O_TRUNC | _O_EXCL: /* ignore EXCL w/o CREAT */ - filecreate= TRUNCATE_EXISTING; - break; - - case _O_CREAT | _O_TRUNC: - filecreate= CREATE_ALWAYS; - break; - - default: - /* this can't happen ... all cases are covered */ - errno= EINVAL; - _doserrno= 0L; - return -1; - } - - /* - * decode file attribute flags if _O_CREAT was specified - */ - fileattrib= FILE_ATTRIBUTE_NORMAL; /* default */ - if (oflag & _O_CREAT) - { - _umask((mask= _umask(0))); - - if (!((pmode & ~mask) & _S_IWRITE)) - fileattrib= FILE_ATTRIBUTE_READONLY; - } - - /* - * Set temporary file (delete-on-close) attribute if requested. - */ - if (oflag & _O_TEMPORARY) - { - fileattrib|= FILE_FLAG_DELETE_ON_CLOSE; - fileaccess|= DELETE; - } - - /* - * Set temporary file (delay-flush-to-disk) attribute if requested. - */ - if (oflag & _O_SHORT_LIVED) - fileattrib|= FILE_ATTRIBUTE_TEMPORARY; - - /* - * Set sequential or random access attribute if requested. - */ - if (oflag & _O_SEQUENTIAL) - fileattrib|= FILE_FLAG_SEQUENTIAL_SCAN; - else if (oflag & _O_RANDOM) - fileattrib|= FILE_FLAG_RANDOM_ACCESS; - - /* - * try to open/create the file - */ - if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes, - filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE) - { - /* - * OS call to open/create file failed! map the error, release - * the lock, and return -1. note that it's not necessary to - * call _free_osfhnd (it hasn't been used yet). - */ - _dosmaperr(GetLastError()); /* map error */ - return -1; /* return error to caller */ - } - - if ((fh= _open_osfhandle((intptr_t)osfh, - oflag & (_O_APPEND | _O_RDONLY | _O_TEXT))) == -1) - { - _dosmaperr(GetLastError()); /* map error */ - CloseHandle(osfh); - } - - return fh; /* return handle */ -} -#endif /* __WIN__ */ #ifdef EXTRA_DEBUG diff --git a/mysys/my_pread.c b/mysys/my_pread.c index 3f62f150c91..eaabcb1b728 100644 --- a/mysys/my_pread.c +++ b/mysys/my_pread.c @@ -15,11 +15,15 @@ #include "mysys_priv.h" #include "mysys_err.h" +#include "my_base.h" +#include #include -#ifdef HAVE_PREAD +#if defined (HAVE_PREAD) && !defined(_WIN32) #include #endif + + /* Read a chunk of bytes from a file from a given position @@ -46,27 +50,39 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset, { size_t readbytes; int error= 0; +#if !defined (HAVE_PREAD) && !defined (_WIN32) + int save_errno; +#endif DBUG_ENTER("my_pread"); - DBUG_PRINT("my",("Fd: %d Seek: %lu Buffer: 0x%lx Count: %u MyFlags: %d", - Filedes, (ulong) offset, (long) Buffer, (uint) Count, - MyFlags)); + DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %d", + Filedes, (ulonglong)offset, Buffer, (ulong)Count, MyFlags)); for (;;) { -#ifndef __WIN__ - errno=0; /* Linux doesn't reset this */ -#endif -#ifndef HAVE_PREAD + errno= 0; /* Linux, Windows don't reset this on EOF/success */ +#if !defined (HAVE_PREAD) && !defined (_WIN32) pthread_mutex_lock(&my_file_info[Filedes].mutex); readbytes= (uint) -1; error= (lseek(Filedes, offset, MY_SEEK_SET) == (my_off_t) -1 || - (readbytes= read(Filedes, Buffer, (uint) Count)) != Count); + (readbytes= read(Filedes, Buffer, Count)) != Count); + save_errno= errno; pthread_mutex_unlock(&my_file_info[Filedes].mutex); + if (error) + errno= save_errno; #else - if ((error= ((readbytes= pread(Filedes, Buffer, Count, offset)) != Count))) - my_errno= errno ? errno : -1; +#if defined(_WIN32) + readbytes= my_win_pread(Filedes, Buffer, Count, offset); +#else + readbytes= pread(Filedes, Buffer, Count, offset); #endif - if (error || readbytes != Count) + error= (readbytes != Count); +#endif + if(error) { + my_errno= errno ? errno : -1; + if (errno == 0 || (readbytes != (size_t) -1 && + (MyFlags & (MY_NABP | MY_FNABP)))) + my_errno= HA_ERR_FILE_TOO_SHORT; + DBUG_PRINT("warning",("Read only %d bytes off %u from %d, errno: %d", (int) readbytes, (uint) Count,Filedes,my_errno)); #ifdef THREAD @@ -79,19 +95,19 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset, #endif if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) { - if (readbytes == (size_t) -1) - my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG), - my_filename(Filedes),my_errno); - else if (MyFlags & (MY_NABP | MY_FNABP)) - my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG), - my_filename(Filedes),my_errno); + if (readbytes == (size_t) -1) + my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG), + my_filename(Filedes),my_errno); + else if (MyFlags & (MY_NABP | MY_FNABP)) + my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG), + my_filename(Filedes),my_errno); } if (readbytes == (size_t) -1 || (MyFlags & (MY_FNABP | MY_NABP))) - DBUG_RETURN(MY_FILE_ERROR); /* Return with error */ + DBUG_RETURN(MY_FILE_ERROR); /* Return with error */ } if (MyFlags & (MY_NABP | MY_FNABP)) - DBUG_RETURN(0); /* Read went ok; Return 0 */ - DBUG_RETURN(readbytes); /* purecov: inspected */ + DBUG_RETURN(0); /* Read went ok; Return 0 */ + DBUG_RETURN(readbytes); /* purecov: inspected */ } } /* my_pread */ @@ -117,42 +133,45 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset, # Number of bytes read */ -size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count, +size_t my_pwrite(File Filedes, const uchar *Buffer, size_t Count, my_off_t offset, myf MyFlags) { - size_t writenbytes, written; + size_t writtenbytes, written; uint errors; + DBUG_ENTER("my_pwrite"); - DBUG_PRINT("my",("Fd: %d Seek: %lu Buffer: 0x%lx Count: %u MyFlags: %d", - Filedes, (ulong) offset, (long) Buffer, (uint) Count, - MyFlags)); + DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %d", + Filedes, offset, Buffer, (ulong)Count, MyFlags)); errors= 0; written= 0; for (;;) { -#ifndef HAVE_PREAD +#if !defined (HAVE_PREAD) && !defined (_WIN32) int error; - writenbytes= (size_t) -1; + writtenbytes= (size_t) -1; pthread_mutex_lock(&my_file_info[Filedes].mutex); error= (lseek(Filedes, offset, MY_SEEK_SET) != (my_off_t) -1 && - (writenbytes = write(Filedes, Buffer, (uint) Count)) == Count); + (writtenbytes= write(Filedes, Buffer, Count)) == Count); pthread_mutex_unlock(&my_file_info[Filedes].mutex); if (error) break; +#elif defined (_WIN32) + writtenbytes= my_win_pwrite(Filedes, Buffer, Count, offset); #else - if ((writenbytes= pwrite(Filedes, Buffer, Count,offset)) == Count) + writtenbytes= pwrite(Filedes, Buffer, Count, offset); +#endif + if(writtenbytes == Count) break; my_errno= errno; -#endif - if (writenbytes != (size_t) -1) - { /* Safegueard */ - written+=writenbytes; - Buffer+=writenbytes; - Count-=writenbytes; - offset+=writenbytes; + if (writtenbytes != (size_t) -1) + { + written+= writtenbytes; + Buffer+= writtenbytes; + Count-= writtenbytes; + offset+= writtenbytes; } - DBUG_PRINT("error",("Write only %u bytes", (uint) writenbytes)); + DBUG_PRINT("error",("Write only %u bytes", (uint) writtenbytes)); #ifndef NO_BACKGROUND #ifdef THREAD if (my_thread_var->abort) @@ -165,15 +184,15 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count, errors++; continue; } - if ((writenbytes && writenbytes != (size_t) -1) || my_errno == EINTR) + if ((writtenbytes && writtenbytes != (size_t) -1) || my_errno == EINTR) continue; /* Retry */ #endif if (MyFlags & (MY_NABP | MY_FNABP)) { if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) { - my_error(EE_WRITE, MYF(ME_BELL | ME_WAITTANG), - my_filename(Filedes),my_errno); + my_error(EE_WRITE, MYF(ME_BELL | ME_WAITTANG), + my_filename(Filedes),my_errno); } DBUG_RETURN(MY_FILE_ERROR); /* Error on read */ } @@ -183,5 +202,5 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count, DBUG_EXECUTE_IF("check", my_seek(Filedes, -1, SEEK_SET, MYF(0));); if (MyFlags & (MY_NABP | MY_FNABP)) DBUG_RETURN(0); /* Want only errors */ - DBUG_RETURN(writenbytes+written); /* purecov: inspected */ + DBUG_RETURN(writtenbytes+written); /* purecov: inspected */ } /* my_pwrite */ diff --git a/mysys/my_quick.c b/mysys/my_quick.c index 0ba20a5bdee..b93e7e17224 100644 --- a/mysys/my_quick.c +++ b/mysys/my_quick.c @@ -19,11 +19,19 @@ #include "my_nosys.h" +#ifdef _WIN32 +extern size_t my_win_read(File Filedes,uchar *Buffer,size_t Count); +#endif + size_t my_quick_read(File Filedes,uchar *Buffer,size_t Count,myf MyFlags) { size_t readbytes; - - if ((readbytes = read(Filedes, Buffer, (uint) Count)) != Count) +#ifdef _WIN32 + readbytes= my_win_read(Filedes, Buffer, Count); +#else + readbytes= read(Filedes, Buffer, Count); +#endif + if(readbytes != Count) { #ifndef DBUG_OFF if ((readbytes == 0 || readbytes == (size_t) -1) && errno == EINTR) @@ -40,8 +48,13 @@ size_t my_quick_read(File Filedes,uchar *Buffer,size_t Count,myf MyFlags) } -size_t my_quick_write(File Filedes,const uchar *Buffer,size_t Count) + +size_t my_quick_write(File Filedes, const uchar *Buffer, size_t Count) { +#ifdef _WIN32 + return my_win_write(Filedes, Buffer, Count); +#else + #ifndef DBUG_OFF size_t writtenbytes; #endif @@ -50,7 +63,7 @@ size_t my_quick_write(File Filedes,const uchar *Buffer,size_t Count) #ifndef DBUG_OFF writtenbytes = #endif - (size_t) write(Filedes,Buffer, (uint) Count)) != Count) + (size_t) write(Filedes,Buffer,Count)) != Count) { #ifndef DBUG_OFF if ((writtenbytes == 0 || writtenbytes == (size_t) -1) && errno == EINTR) @@ -64,4 +77,5 @@ size_t my_quick_write(File Filedes,const uchar *Buffer,size_t Count) return (size_t) -1; } return 0; +#endif } diff --git a/mysys/my_read.c b/mysys/my_read.c index 0c302d5b227..75f9dd64f1d 100644 --- a/mysys/my_read.c +++ b/mysys/my_read.c @@ -15,9 +15,9 @@ #include "mysys_priv.h" #include "mysys_err.h" +#include #include - /* Read a chunk of bytes from a file with retry's if needed @@ -37,16 +37,25 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags) { size_t readbytes, save_count; DBUG_ENTER("my_read"); - DBUG_PRINT("my",("Fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d", - Filedes, (long) Buffer, (ulong) Count, MyFlags)); + DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %d", + Filedes, Buffer, (ulong) Count, MyFlags)); save_count= Count; for (;;) { - errno= 0; /* Linux doesn't reset this */ - if ((readbytes= read(Filedes, Buffer, (uint) Count)) != Count) + errno= 0; /* Linux, Windows don't reset this on EOF/success */ +#ifdef _WIN32 + readbytes= my_win_read(Filedes, Buffer, Count); +#else + readbytes= read(Filedes, Buffer, Count); +#endif + + if (readbytes != Count) { - my_errno= errno ? errno : -1; + my_errno= errno; + if (errno == 0 || (readbytes != (size_t) -1 && + (MyFlags & (MY_NABP | MY_FNABP)))) + my_errno= HA_ERR_FILE_TOO_SHORT; DBUG_PRINT("warning",("Read only %d bytes off %lu from %d, errno: %d", (int) readbytes, (ulong) Count, Filedes, my_errno)); diff --git a/mysys/my_seek.c b/mysys/my_seek.c index 2c661baeff7..8502c259353 100644 --- a/mysys/my_seek.c +++ b/mysys/my_seek.c @@ -45,36 +45,30 @@ my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags __attribute__((unused))) { - reg1 os_off_t newpos= -1; + os_off_t newpos= -1; DBUG_ENTER("my_seek"); - DBUG_PRINT("my",("Fd: %d Hpos: %lu Pos: %lu Whence: %d MyFlags: %d", - fd, (ulong) (((ulonglong) pos) >> 32), (ulong) pos, - whence, MyFlags)); + DBUG_PRINT("my",("fd: %d Pos: %llu Whence: %d MyFlags: %d", + fd, (ulonglong) pos, whence, MyFlags)); DBUG_ASSERT(pos != MY_FILEPOS_ERROR); /* safety check */ /* Make sure we are using a valid file descriptor! */ DBUG_ASSERT(fd != -1); -#if defined(THREAD) && !defined(HAVE_PREAD) - if (MyFlags & MY_THREADSAFE) - { - pthread_mutex_lock(&my_file_info[fd].mutex); - newpos= lseek(fd, pos, whence); - pthread_mutex_unlock(&my_file_info[fd].mutex); - } - else +#if defined (_WIN32) + newpos= my_win_lseek(fd, pos, whence); +#else + newpos= lseek(fd, pos, whence); #endif - newpos= lseek(fd, pos, whence); if (newpos == (os_off_t) -1) { - my_errno=errno; - DBUG_PRINT("error",("lseek: %lu errno: %d", (ulong) newpos,errno)); + my_errno= errno; + DBUG_PRINT("error",("lseek: %llu errno: %d", (ulonglong) newpos,errno)); DBUG_RETURN(MY_FILEPOS_ERROR); } if ((my_off_t) newpos != pos) { - DBUG_PRINT("exit",("pos: %lu", (ulong) newpos)); + DBUG_PRINT("exit",("pos: %llu", (ulonglong) newpos)); } DBUG_RETURN((my_off_t) newpos); } /* my_seek */ @@ -87,15 +81,15 @@ my_off_t my_tell(File fd, myf MyFlags __attribute__((unused))) { os_off_t pos; DBUG_ENTER("my_tell"); - DBUG_PRINT("my",("Fd: %d MyFlags: %d",fd, MyFlags)); + DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags)); DBUG_ASSERT(fd >= 0); -#ifdef HAVE_TELL - pos=tell(fd); +#if defined (HAVE_TELL) && !defined (_WIN32) + pos= tell(fd); #else - pos=lseek(fd, 0L, MY_SEEK_CUR); + pos= my_seek(fd, 0L, MY_SEEK_CUR,0); #endif if (pos == (os_off_t) -1) - my_errno=errno; - DBUG_PRINT("exit",("pos: %lu", (ulong) pos)); + my_errno= errno; + DBUG_PRINT("exit",("pos: %llu", (ulonglong) pos)); DBUG_RETURN((my_off_t) pos); } /* my_tell */ diff --git a/mysys/my_static.c b/mysys/my_static.c index d0c20da828a..1ddf3524052 100644 --- a/mysys/my_static.c +++ b/mysys/my_static.c @@ -35,7 +35,7 @@ int NEAR my_umask=0664, NEAR my_umask_dir=0777; #ifndef THREAD int NEAR my_errno=0; #endif -struct st_my_file_info my_file_info_default[MY_NFILE]= {{0,UNOPEN}}; +struct st_my_file_info my_file_info_default[MY_NFILE]; uint my_file_limit= MY_NFILE; struct st_my_file_info *my_file_info= my_file_info_default; diff --git a/mysys/my_sync.c b/mysys/my_sync.c index ba6964b00d6..7b2112fa032 100644 --- a/mysys/my_sync.c +++ b/mysys/my_sync.c @@ -62,8 +62,8 @@ int my_sync(File fd, myf my_flags) res= fdatasync(fd); #elif defined(HAVE_FSYNC) res= fsync(fd); -#elif defined(__WIN__) - res= _commit(fd); +#elif defined(_WIN32) + res= my_win_fsync(fd); #else #error Cannot find a way to sync a file, durability in danger res= 0; /* No sync (strange OS) */ diff --git a/mysys/my_winerr.c b/mysys/my_winerr.c new file mode 100644 index 00000000000..534078b6737 --- /dev/null +++ b/mysys/my_winerr.c @@ -0,0 +1,123 @@ +/* Copyright (C) 2008 MySQL AB + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + Convert Windows API error (GetLastError() to Posix equivalent (errno) + The exported function my_osmaperr() is modelled after and borrows + heavily from undocumented _dosmaperr()(found of the static Microsoft C runtime). +*/ + +#include +#include + + +struct errentry +{ + unsigned long oscode; /* OS return value */ + int sysv_errno; /* System V error code */ +}; + +static struct errentry errtable[]= { + { ERROR_INVALID_FUNCTION, EINVAL }, /* 1 */ + { ERROR_FILE_NOT_FOUND, ENOENT }, /* 2 */ + { ERROR_PATH_NOT_FOUND, ENOENT }, /* 3 */ + { ERROR_TOO_MANY_OPEN_FILES, EMFILE }, /* 4 */ + { ERROR_ACCESS_DENIED, EACCES }, /* 5 */ + { ERROR_INVALID_HANDLE, EBADF }, /* 6 */ + { ERROR_ARENA_TRASHED, ENOMEM }, /* 7 */ + { ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, /* 8 */ + { ERROR_INVALID_BLOCK, ENOMEM }, /* 9 */ + { ERROR_BAD_ENVIRONMENT, E2BIG }, /* 10 */ + { ERROR_BAD_FORMAT, ENOEXEC }, /* 11 */ + { ERROR_INVALID_ACCESS, EINVAL }, /* 12 */ + { ERROR_INVALID_DATA, EINVAL }, /* 13 */ + { ERROR_INVALID_DRIVE, ENOENT }, /* 15 */ + { ERROR_CURRENT_DIRECTORY, EACCES }, /* 16 */ + { ERROR_NOT_SAME_DEVICE, EXDEV }, /* 17 */ + { ERROR_NO_MORE_FILES, ENOENT }, /* 18 */ + { ERROR_LOCK_VIOLATION, EACCES }, /* 33 */ + { ERROR_BAD_NETPATH, ENOENT }, /* 53 */ + { ERROR_NETWORK_ACCESS_DENIED, EACCES }, /* 65 */ + { ERROR_BAD_NET_NAME, ENOENT }, /* 67 */ + { ERROR_FILE_EXISTS, EEXIST }, /* 80 */ + { ERROR_CANNOT_MAKE, EACCES }, /* 82 */ + { ERROR_FAIL_I24, EACCES }, /* 83 */ + { ERROR_INVALID_PARAMETER, EINVAL }, /* 87 */ + { ERROR_NO_PROC_SLOTS, EAGAIN }, /* 89 */ + { ERROR_DRIVE_LOCKED, EACCES }, /* 108 */ + { ERROR_BROKEN_PIPE, EPIPE }, /* 109 */ + { ERROR_DISK_FULL, ENOSPC }, /* 112 */ + { ERROR_INVALID_TARGET_HANDLE, EBADF }, /* 114 */ + { ERROR_INVALID_HANDLE, EINVAL }, /* 124 */ + { ERROR_WAIT_NO_CHILDREN, ECHILD }, /* 128 */ + { ERROR_CHILD_NOT_COMPLETE, ECHILD }, /* 129 */ + { ERROR_DIRECT_ACCESS_HANDLE, EBADF }, /* 130 */ + { ERROR_NEGATIVE_SEEK, EINVAL }, /* 131 */ + { ERROR_SEEK_ON_DEVICE, EACCES }, /* 132 */ + { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, /* 145 */ + { ERROR_NOT_LOCKED, EACCES }, /* 158 */ + { ERROR_BAD_PATHNAME, ENOENT }, /* 161 */ + { ERROR_MAX_THRDS_REACHED, EAGAIN }, /* 164 */ + { ERROR_LOCK_FAILED, EACCES }, /* 167 */ + { ERROR_ALREADY_EXISTS, EEXIST }, /* 183 */ + { ERROR_FILENAME_EXCED_RANGE, ENOENT }, /* 206 */ + { ERROR_NESTING_NOT_ALLOWED, EAGAIN }, /* 215 */ + { ERROR_NOT_ENOUGH_QUOTA, ENOMEM } /* 1816 */ +}; + +/* size of the table */ +#define ERRTABLESIZE (sizeof(errtable)/sizeof(errtable[0])) + +/* The following two constants must be the minimum and maximum +values in the (contiguous) range of Exec Failure errors. */ +#define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG +#define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN + +/* These are the low and high value in the range of errors that are +access violations */ +#define MIN_EACCES_RANGE ERROR_WRITE_PROTECT +#define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED + + +static int get_errno_from_oserr(unsigned long oserrno) +{ + int i; + + /* check the table for the OS error code */ + for (i= 0; i < ERRTABLESIZE; ++i) + { + if (oserrno == errtable[i].oscode) + { + return errtable[i].sysv_errno; + } + } + + /* The error code wasn't in the table. We check for a range of */ + /* EACCES errors or exec failure errors (ENOEXEC). Otherwise */ + /* EINVAL is returned. */ + + if (oserrno >= MIN_EACCES_RANGE && oserrno <= MAX_EACCES_RANGE) + return EACCES; + else if (oserrno >= MIN_EXEC_ERROR && oserrno <= MAX_EXEC_ERROR) + return ENOEXEC; + else + return EINVAL; +} + +/* Set errno corresponsing to GetLastError() value */ +void my_osmaperr ( unsigned long oserrno) +{ + errno= get_errno_from_oserr(oserrno); +} diff --git a/mysys/my_winfile.c b/mysys/my_winfile.c new file mode 100644 index 00000000000..de1d747c967 --- /dev/null +++ b/mysys/my_winfile.c @@ -0,0 +1,671 @@ +/* Copyright (C) 2008 MySQL AB + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + The purpose of this file is to provide implementation of file IO routines on + Windows that can be thought as drop-in replacement for corresponding C runtime + functionality. + + Compared to Windows CRT, this one + - does not have the same file descriptor + limitation (default is 16384 and can be increased further, whereas CRT poses + a hard limit of 2048 file descriptors) + - the file operations are not serialized + - positional IO pread/pwrite is ported here. + - no text mode for files, all IO is "binary" + + Naming convention: + All routines are prefixed with my_win_, e.g Posix open() is implemented with + my_win_open() + + Implemented are + - POSIX routines(e.g open, read, lseek ...) + - Some ANSI C stream routines (fopen, fdopen, fileno, fclose) + - Windows CRT equvalients (my_get_osfhandle, open_osfhandle) + + Worth to note: + - File descriptors used here are located in a range that is not compatible + with CRT on purpose. Attempt to use a file descriptor from Windows CRT library + range in my_win_* function will be punished with DBUG_ASSERT() + + - File streams (FILE *) are actually from the C runtime. The routines provided + here are useful only in scernarios that use low-level IO with my_win_fileno() +*/ + +#ifdef _WIN32 + +#include "mysys_priv.h" +#include +#include + +/* Associates a file descriptor with an existing operating-system file handle.*/ +File my_open_osfhandle(HANDLE handle, int oflag) +{ + int offset= -1; + uint i; + DBUG_ENTER("my_open_osfhandle"); + + pthread_mutex_lock(&THR_LOCK_open); + for(i= MY_FILE_MIN; i < my_file_limit;i++) + { + if(my_file_info[i].fhandle == 0) + { + struct st_my_file_info *finfo= &(my_file_info[i]); + finfo->type= FILE_BY_OPEN; + finfo->fhandle= handle; + finfo->oflag= oflag; + offset= i; + break; + } + } + pthread_mutex_unlock(&THR_LOCK_open); + if(offset == -1) + errno= EMFILE; /* to many file handles open */ + DBUG_RETURN(offset); +} + + +static void invalidate_fd(File fd) +{ + DBUG_ENTER("invalidate_fd"); + DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit); + my_file_info[fd].fhandle= 0; + DBUG_VOID_RETURN; +} + + +/* Get Windows handle for a file descriptor */ +HANDLE my_get_osfhandle(File fd) +{ + DBUG_ENTER("my_get_osfhandle"); + DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit); + DBUG_RETURN(my_file_info[fd].fhandle); +} + + +static int my_get_open_flags(File fd) +{ + DBUG_ENTER("my_get_osfhandle"); + DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit); + DBUG_RETURN(my_file_info[fd].oflag); +} + + +/* + Open a file with sharing. Similar to _sopen() from libc, but allows managing + share delete on win32 + + SYNOPSIS + my_win_sopen() + path file name + oflag operation flags + shflag share flag + pmode permission flags + + RETURN VALUE + File descriptor of opened file if success + -1 and sets errno if fails. +*/ + +File my_win_sopen(const char *path, int oflag, int shflag, int pmode) +{ + int fh; /* handle of opened file */ + int mask; + HANDLE osfh; /* OS handle of opened file */ + DWORD fileaccess; /* OS file access (requested) */ + DWORD fileshare; /* OS file sharing mode */ + DWORD filecreate; /* OS method of opening/creating */ + DWORD fileattrib; /* OS file attribute flags */ + SECURITY_ATTRIBUTES SecurityAttributes; + + DBUG_ENTER("my_win_sopen"); + + if (check_if_legal_filename(path)) + { + errno= EACCES; + DBUG_RETURN(-1); + } + SecurityAttributes.nLength= sizeof(SecurityAttributes); + SecurityAttributes.lpSecurityDescriptor= NULL; + SecurityAttributes.bInheritHandle= !(oflag & _O_NOINHERIT); + + /* decode the access flags */ + switch (oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)) { + case _O_RDONLY: /* read access */ + fileaccess= GENERIC_READ; + break; + case _O_WRONLY: /* write access */ + fileaccess= GENERIC_WRITE; + break; + case _O_RDWR: /* read and write access */ + fileaccess= GENERIC_READ | GENERIC_WRITE; + break; + default: /* error, bad oflag */ + errno= EINVAL; + DBUG_RETURN(-1); + } + + /* decode sharing flags */ + switch (shflag) { + case _SH_DENYRW: /* exclusive access except delete */ + fileshare= FILE_SHARE_DELETE; + break; + case _SH_DENYWR: /* share read and delete access */ + fileshare= FILE_SHARE_READ | FILE_SHARE_DELETE; + break; + case _SH_DENYRD: /* share write and delete access */ + fileshare= FILE_SHARE_WRITE | FILE_SHARE_DELETE; + break; + case _SH_DENYNO: /* share read, write and delete access */ + fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; + break; + case _SH_DENYRWD: /* exclusive access */ + fileshare= 0L; + break; + case _SH_DENYWRD: /* share read access */ + fileshare= FILE_SHARE_READ; + break; + case _SH_DENYRDD: /* share write access */ + fileshare= FILE_SHARE_WRITE; + break; + case _SH_DENYDEL: /* share read and write access */ + fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE; + break; + default: /* error, bad shflag */ + errno= EINVAL; + DBUG_RETURN(-1); + } + + /* decode open/create method flags */ + switch (oflag & (_O_CREAT | _O_EXCL | _O_TRUNC)) { + case 0: + case _O_EXCL: /* ignore EXCL w/o CREAT */ + filecreate= OPEN_EXISTING; + break; + + case _O_CREAT: + filecreate= OPEN_ALWAYS; + break; + + case _O_CREAT | _O_EXCL: + case _O_CREAT | _O_TRUNC | _O_EXCL: + filecreate= CREATE_NEW; + break; + + case _O_TRUNC: + case _O_TRUNC | _O_EXCL: /* ignore EXCL w/o CREAT */ + filecreate= TRUNCATE_EXISTING; + break; + + case _O_CREAT | _O_TRUNC: + filecreate= CREATE_ALWAYS; + break; + + default: + /* this can't happen ... all cases are covered */ + errno= EINVAL; + DBUG_RETURN(-1); + } + + /* decode file attribute flags if _O_CREAT was specified */ + fileattrib= FILE_ATTRIBUTE_NORMAL; /* default */ + if (oflag & _O_CREAT) + { + _umask((mask= _umask(0))); + + if (!((pmode & ~mask) & _S_IWRITE)) + fileattrib= FILE_ATTRIBUTE_READONLY; + } + + /* Set temporary file (delete-on-close) attribute if requested. */ + if (oflag & _O_TEMPORARY) + { + fileattrib|= FILE_FLAG_DELETE_ON_CLOSE; + fileaccess|= DELETE; + } + + /* Set temporary file (delay-flush-to-disk) attribute if requested.*/ + if (oflag & _O_SHORT_LIVED) + fileattrib|= FILE_ATTRIBUTE_TEMPORARY; + + /* Set sequential or random access attribute if requested. */ + if (oflag & _O_SEQUENTIAL) + fileattrib|= FILE_FLAG_SEQUENTIAL_SCAN; + else if (oflag & _O_RANDOM) + fileattrib|= FILE_FLAG_RANDOM_ACCESS; + + /* try to open/create the file */ + if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes, + filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE) + { + /* + OS call to open/create file failed! map the error, release + the lock, and return -1. note that it's not necessary to + call _free_osfhnd (it hasn't been used yet). + */ + my_osmaperr(GetLastError()); /* map error */ + DBUG_RETURN(-1); /* return error to caller */ + } + + if ((fh= my_open_osfhandle(osfh, + oflag & (_O_APPEND | _O_RDONLY | _O_TEXT))) == -1) + { + CloseHandle(osfh); + } + + DBUG_RETURN(fh); /* return handle */ +} + + +File my_win_open(const char *path, int flags) +{ + DBUG_ENTER("my_win_open"); + DBUG_RETURN(my_win_sopen((char *) path, flags | _O_BINARY, _SH_DENYNO, + _S_IREAD | S_IWRITE)); +} + + +int my_win_close(File fd) +{ + DBUG_ENTER("my_win_close"); + if(CloseHandle(my_get_osfhandle(fd))) + { + invalidate_fd(fd); + DBUG_RETURN(0); + } + my_osmaperr(GetLastError()); + DBUG_RETURN(-1); +} + + +size_t my_win_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset) +{ + DWORD nBytesRead; + HANDLE hFile; + OVERLAPPED ov= {0}; + LARGE_INTEGER li; + + DBUG_ENTER("my_win_pread"); + + if(!Count) + DBUG_RETURN(0); +#ifdef _WIN64 + if(Count > UINT_MAX) + Count= UINT_MAX; +#endif + + hFile= (HANDLE)my_get_osfhandle(Filedes); + li.QuadPart= offset; + ov.Offset= li.LowPart; + ov.OffsetHigh= li.HighPart; + + if(!ReadFile(hFile, Buffer, (DWORD)Count, &nBytesRead, &ov)) + { + DWORD lastError= GetLastError(); + /* + ERROR_BROKEN_PIPE is returned when no more data coming + through e.g. a command pipe in windows : see MSDN on ReadFile. + */ + if(lastError == ERROR_HANDLE_EOF || lastError == ERROR_BROKEN_PIPE) + DBUG_RETURN(0); /*return 0 at EOF*/ + my_osmaperr(lastError); + DBUG_RETURN(-1); + } + DBUG_RETURN(nBytesRead); +} + + +size_t my_win_read(File Filedes, uchar *Buffer, size_t Count) +{ + DWORD nBytesRead; + HANDLE hFile; + + DBUG_ENTER("my_win_read"); + if(!Count) + DBUG_RETURN(0); +#ifdef _WIN64 + if(Count > UINT_MAX) + Count= UINT_MAX; +#endif + + hFile= (HANDLE)my_get_osfhandle(Filedes); + + if(!ReadFile(hFile, Buffer, (DWORD)Count, &nBytesRead, NULL)) + { + DWORD lastError= GetLastError(); + /* + ERROR_BROKEN_PIPE is returned when no more data coming + through e.g. a command pipe in windows : see MSDN on ReadFile. + */ + if(lastError == ERROR_HANDLE_EOF || lastError == ERROR_BROKEN_PIPE) + DBUG_RETURN(0); /*return 0 at EOF*/ + my_osmaperr(lastError); + DBUG_RETURN(-1); + } + DBUG_RETURN(nBytesRead); +} + + +size_t my_win_pwrite(File Filedes, const uchar *Buffer, size_t Count, + my_off_t offset) +{ + DWORD nBytesWritten; + HANDLE hFile; + OVERLAPPED ov= {0}; + LARGE_INTEGER li; + + DBUG_ENTER("my_win_pwrite"); + DBUG_PRINT("my",("Filedes: %d, Buffer: %p, Count: %zd, offset: %llu", + Filedes, Buffer, Count, (ulonglong)offset)); + + if(!Count) + DBUG_RETURN(0); + +#ifdef _WIN64 + if(Count > UINT_MAX) + Count= UINT_MAX; +#endif + + hFile= (HANDLE)my_get_osfhandle(Filedes); + li.QuadPart= offset; + ov.Offset= li.LowPart; + ov.OffsetHigh= li.HighPart; + + if(!WriteFile(hFile, Buffer, (DWORD)Count, &nBytesWritten, &ov)) + { + my_osmaperr(GetLastError()); + DBUG_RETURN(-1); + } + else + DBUG_RETURN(nBytesWritten); +} + + +my_off_t my_win_lseek(File fd, my_off_t pos, int whence) +{ + LARGE_INTEGER offset; + LARGE_INTEGER newpos; + + DBUG_ENTER("my_win_lseek"); + + /* Check compatibility of Windows and Posix seek constants */ + compile_time_assert(FILE_BEGIN == SEEK_SET && FILE_CURRENT == SEEK_CUR + && FILE_END == SEEK_END); + + offset.QuadPart= pos; + if(!SetFilePointerEx(my_get_osfhandle(fd), offset, &newpos, whence)) + { + my_osmaperr(GetLastError()); + newpos.QuadPart= -1; + } + DBUG_RETURN(newpos.QuadPart); +} + + +#ifndef FILE_WRITE_TO_END_OF_FILE +#define FILE_WRITE_TO_END_OF_FILE 0xffffffff +#endif +size_t my_win_write(File fd, const uchar *Buffer, size_t Count) +{ + DWORD nWritten; + OVERLAPPED ov; + OVERLAPPED *pov= NULL; + HANDLE hFile; + + DBUG_ENTER("my_win_write"); + DBUG_PRINT("my",("Filedes: %d, Buffer: %p, Count %zd", fd, Buffer, Count)); + if(my_get_open_flags(fd) & _O_APPEND) + { + /* + Atomic append to the end of file is is done by special initialization of + the OVERLAPPED structure. See MSDN WriteFile documentation for more info. + */ + memset(&ov, 0, sizeof(ov)); + ov.Offset= FILE_WRITE_TO_END_OF_FILE; + ov.OffsetHigh= -1; + pov= &ov; + } + + hFile= my_get_osfhandle(fd); + if(!WriteFile(hFile, Buffer, (DWORD)Count, &nWritten, pov)) + { + nWritten= (size_t)-1; + my_osmaperr(GetLastError()); + } + DBUG_RETURN((size_t)nWritten); +} + + +int my_win_chsize(File fd, my_off_t newlength) +{ + HANDLE hFile; + LARGE_INTEGER length; + DBUG_ENTER("my_win_chsize"); + + hFile= (HANDLE) my_get_osfhandle(fd); + length.QuadPart= newlength; + if (!SetFilePointerEx(hFile, length , NULL , FILE_BEGIN)) + goto err; + if (!SetEndOfFile(hFile)) + goto err; + DBUG_RETURN(0); +err: + my_osmaperr(GetLastError()); + my_errno= errno; + DBUG_RETURN(-1); +} + + +/* Get the file descriptor for stdin,stdout or stderr */ +static File my_get_stdfile_descriptor(FILE *stream) +{ + HANDLE hFile; + DWORD nStdHandle; + DBUG_ENTER("my_get_stdfile_descriptor"); + + if(stream == stdin) + nStdHandle= STD_INPUT_HANDLE; + else if(stream == stdout) + nStdHandle= STD_OUTPUT_HANDLE; + else if(stream == stderr) + nStdHandle= STD_ERROR_HANDLE; + else + DBUG_RETURN(-1); + + hFile= GetStdHandle(nStdHandle); + if(hFile != INVALID_HANDLE_VALUE) + DBUG_RETURN(my_open_osfhandle(hFile, 0)); + DBUG_RETURN(-1); +} + + +File my_win_fileno(FILE *file) +{ + HANDLE hFile= (HANDLE)_get_osfhandle(fileno(file)); + int retval= -1; + uint i; + + DBUG_ENTER("my_win_fileno"); + + for(i= MY_FILE_MIN; i < my_file_limit; i++) + { + if(my_file_info[i].fhandle == hFile) + { + retval= i; + break; + } + } + if(retval == -1) + /* try std stream */ + DBUG_RETURN(my_get_stdfile_descriptor(file)); + DBUG_RETURN(retval); +} + + +FILE *my_win_fopen(const char *filename, const char *type) +{ + FILE *file; + int flags= 0; + DBUG_ENTER("my_win_open"); + + /* + If we are not creating, then we need to use my_access to make sure + the file exists since Windows doesn't handle files like "com1.sym" + very well + */ + if (check_if_legal_filename(filename)) + { + errno= EACCES; + DBUG_RETURN(NULL); + } + + file= fopen(filename, type); + if(!file) + DBUG_RETURN(NULL); + + if(strchr(type,'a') != NULL) + flags= O_APPEND; + + /* + Register file handle in my_table_info. + Necessary for my_fileno() + */ + if(my_open_osfhandle((HANDLE)_get_osfhandle(fileno(file)), flags) < 0) + { + fclose(file); + DBUG_RETURN(NULL); + } + DBUG_RETURN(file); +} + + +FILE * my_win_fdopen(File fd, const char *type) +{ + FILE *file; + int crt_fd; + int flags= 0; + + DBUG_ENTER("my_win_fdopen"); + + if(strchr(type,'a') != NULL) + flags= O_APPEND; + /* Convert OS file handle to CRT file descriptor and then call fdopen*/ + crt_fd= _open_osfhandle((intptr_t)my_get_osfhandle(fd), flags); + if(crt_fd < 0) + file= NULL; + else + file= fdopen(crt_fd, type); + DBUG_RETURN(file); +} + + +int my_win_fclose(FILE *file) +{ + File fd; + + DBUG_ENTER("my_win_close"); + fd= my_fileno(file); + if(fd < 0) + DBUG_RETURN(-1); + if(fclose(file) < 0) + DBUG_RETURN(-1); + invalidate_fd(fd); + DBUG_RETURN(0); +} + + + +/* + Quick and dirty my_fstat() implementation for Windows. + Use CRT fstat on temporarily allocated file descriptor. + Patch file size, because size that fstat returns is not + reliable (may be outdated) +*/ +int my_win_fstat(File fd, struct _stati64 *buf) +{ + int crt_fd; + int retval; + HANDLE hFile, hDup; + + DBUG_ENTER("my_win_fstat"); + + hFile= my_get_osfhandle(fd); + if(!DuplicateHandle( GetCurrentProcess(), hFile, GetCurrentProcess(), + &hDup ,0,FALSE,DUPLICATE_SAME_ACCESS)) + { + my_osmaperr(GetLastError()); + DBUG_RETURN(-1); + } + if ((crt_fd= _open_osfhandle((intptr_t)hDup,0)) < 0) + DBUG_RETURN(-1); + + retval= _fstati64(crt_fd, buf); + if(retval == 0) + { + /* File size returned by stat is not accurate (may be outdated), fix it*/ + GetFileSizeEx(hDup, (PLARGE_INTEGER) (&(buf->st_size))); + } + _close(crt_fd); + DBUG_RETURN(retval); +} + + + +int my_win_stat( const char *path, struct _stati64 *buf) +{ + DBUG_ENTER("my_win_stat"); + if(_stati64( path, buf) == 0) + { + /* File size returned by stat is not accurate (may be outdated), fix it*/ + WIN32_FILE_ATTRIBUTE_DATA data; + if (GetFileAttributesEx(path, GetFileExInfoStandard, &data)) + { + LARGE_INTEGER li; + li.LowPart= data.nFileSizeLow; + li.HighPart= data.nFileSizeHigh; + buf->st_size= li.QuadPart; + } + DBUG_RETURN(0); + } + DBUG_RETURN(-1); +} + + + +int my_win_fsync(File fd) +{ + DBUG_ENTER("my_win_fsync"); + if(FlushFileBuffers(my_get_osfhandle(fd))) + DBUG_RETURN(0); + my_osmaperr(GetLastError()); + DBUG_RETURN(-1); +} + + + +int my_win_dup(File fd) +{ + HANDLE hDup; + DBUG_ENTER("my_win_dup"); + if (DuplicateHandle(GetCurrentProcess(), my_get_osfhandle(fd), + GetCurrentProcess(), &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS)) + { + DBUG_RETURN(my_open_osfhandle(hDup, my_get_open_flags(fd))); + } + my_osmaperr(GetLastError()); + DBUG_RETURN(-1); +} + +#endif /*_WIN32*/ diff --git a/mysys/my_write.c b/mysys/my_write.c index d7eb390bdd2..3eac1364f46 100644 --- a/mysys/my_write.c +++ b/mysys/my_write.c @@ -20,14 +20,14 @@ /* Write a chunk of bytes to a file */ -size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags) +size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags) { - size_t writenbytes, written; + size_t writtenbytes, written; uint errors; DBUG_ENTER("my_write"); - DBUG_PRINT("my",("Fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d", - Filedes, (long) Buffer, (ulong) Count, MyFlags)); - errors=0; written=0; + DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %d", + Filedes, Buffer, (ulong) Count, MyFlags)); + errors= 0; written= 0; /* The behavior of write(fd, buf, 0) is not portable */ if (unlikely(!Count)) @@ -35,17 +35,22 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags) for (;;) { - if ((writenbytes= write(Filedes, Buffer, Count)) == Count) +#ifdef _WIN32 + writtenbytes= my_win_write(Filedes, Buffer, Count); +#else + writtenbytes= write(Filedes, Buffer, Count); +#endif + if (writtenbytes == Count) break; - if (writenbytes != (size_t) -1) + if (writtenbytes != (size_t) -1) { /* Safeguard */ - written+=writenbytes; - Buffer+=writenbytes; - Count-=writenbytes; + written+= writtenbytes; + Buffer+= writtenbytes; + Count-= writtenbytes; } - my_errno=errno; + my_errno= errno; DBUG_PRINT("error",("Write only %ld bytes, error: %d", - (long) writenbytes, my_errno)); + (long) writtenbytes, my_errno)); #ifndef NO_BACKGROUND #ifdef THREAD if (my_thread_var->abort) @@ -59,19 +64,19 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags) continue; } - if ((writenbytes == 0 || writenbytes == (size_t) -1)) + if ((writtenbytes == 0 || writtenbytes == (size_t) -1)) { if (my_errno == EINTR) { DBUG_PRINT("debug", ("my_write() was interrupted and returned %ld", - (long) writenbytes)); + (long) writtenbytes)); continue; /* Interrupted */ } - if (!writenbytes && !errors++) /* Retry once */ + if (!writtenbytes && !errors++) /* Retry once */ { /* We may come here if the file quota is exeeded */ - errno=EFBIG; /* Assume this is the error */ + errno= EFBIG; /* Assume this is the error */ continue; } } @@ -92,5 +97,5 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags) } if (MyFlags & (MY_NABP | MY_FNABP)) DBUG_RETURN(0); /* Want only errors */ - DBUG_RETURN(writenbytes+written); + DBUG_RETURN(writtenbytes+written); } /* my_write */ diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h index 6e0959ae08c..4c4d6ea3598 100644 --- a/mysys/mysys_priv.h +++ b/mysys/mysys_priv.h @@ -42,3 +42,27 @@ extern pthread_mutex_t THR_LOCK_charset, THR_LOCK_time; #endif void my_error_unregister_all(void); + +#ifdef _WIN32 +/* my_winfile.c exports, should not be used outside mysys */ +extern File my_win_open(const char *path, int oflag); +extern int my_win_close(File fd); +extern size_t my_win_read(File fd, uchar *buffer, size_t count); +extern size_t my_win_write(File fd, const uchar *buffer, size_t count); +extern size_t my_win_pread(File fd, uchar *buffer, size_t count, + my_off_t offset); +extern size_t my_win_pwrite(File fd, const uchar *buffer, size_t count, + my_off_t offset); +extern my_off_t my_win_lseek(File fd, my_off_t pos, int whence); +extern int my_win_chsize(File fd, my_off_t newlength); +extern FILE* my_win_fopen(const char *filename, const char *type); +extern File my_win_fclose(FILE *file); +extern File my_win_fileno(FILE *file); +extern FILE* my_win_fdopen(File Filedes, const char *type); +extern int my_win_stat(const char *path, struct _stat64 *buf); +extern int my_win_fstat(File fd, struct _stat64 *buf); +extern int my_win_fsync(File fd); +extern File my_win_dup(File fd); +extern File my_win_sopen(const char *path, int oflag, int shflag, int perm); +extern File my_open_osfhandle(HANDLE handle, int oflag); +#endif diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 166c4f00158..0ad509ab43b 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1135,7 +1135,29 @@ innobase_mysql_tmpfile(void) will be passed to fdopen(), it will be closed by invoking fclose(), which in turn will invoke close() instead of my_close(). */ + +#ifdef _WIN32 + /* Note that on Windows, the integer returned by mysql_tmpfile + has no relation to C runtime file descriptor. Here, we need + to call my_get_osfhandle to get the HANDLE and then convert it + to C runtime filedescriptor. */ + { + HANDLE hFile = my_get_osfhandle(fd); + HANDLE hDup; + BOOL bOK = + DuplicateHandle(GetCurrentProcess(), hFile, GetCurrentProcess(), + &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS); + if(bOK) { + fd2 = _open_osfhandle((intptr_t)hDup,0); + } + else { + my_osmaperr(GetLastError()); + fd2 = -1; + } + } +#else fd2 = dup(fd); +#endif if (fd2 < 0) { DBUG_PRINT("error",("Got error %d on dup",fd2)); my_errno=errno; diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c index 6a4c21160f4..8a5866ae763 100644 --- a/storage/myisam/mi_locking.c +++ b/storage/myisam/mi_locking.c @@ -236,7 +236,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) break; /* Impossible */ } } -#ifdef __WIN__ +#ifdef _WIN32 else { /* @@ -455,11 +455,11 @@ int _mi_writeinfo(register MI_INFO *info, uint operation) share->state.update_count= info->last_loop= ++info->this_loop; if ((error=mi_state_info_write(share->kfile, &share->state, 1))) olderror=my_errno; -#ifdef __WIN__ +#ifdef _WIN32 if (myisam_flush) { - _commit(share->kfile); - _commit(info->dfile); + my_sync(share->kfile,0); + my_sync(info->dfile,0); } #endif } From fc8db5e9ea231da4e8f5af3b38a12688d1590d53 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 11 Sep 2009 22:42:39 +0200 Subject: [PATCH 113/138] Downport WL#1624 -determine MAC addresses on Windows. Contribution by Chris Runyan --- mysys/my_gethwaddr.c | 92 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c index c7f138c7337..7fae1a51446 100644 --- a/mysys/my_gethwaddr.c +++ b/mysys/my_gethwaddr.c @@ -101,7 +101,97 @@ err: return res; } -#else /* FreeBSD elif linux */ +#elif defined(__WIN__) +#include + +/* + The following typedef is for dynamically loading + iphlpapi.dll / GetAdaptersAddresses. Dynamic loading is + used because GetAdaptersAddresses is not available on Windows 2000 + which MySQL still supports. Static linking would cause an unresolved export. +*/ +typedef DWORD (WINAPI *pfnGetAdaptersAddresses)(IN ULONG Family, + IN DWORD Flags,IN PVOID Reserved, + OUT PIP_ADAPTER_ADDRESSES pAdapterAddresses, + IN OUT PULONG pOutBufLen); + +/* + my_gethwaddr - Windows version + + @brief Retrieve MAC address from network hardware + + @param[out] to MAC address exactly six bytes + + @return Operation status + @retval 0 OK + @retval <>0 FAILED +*/ +my_bool my_gethwaddr(uchar *to) +{ + PIP_ADAPTER_ADDRESSES pAdapterAddresses; + PIP_ADAPTER_ADDRESSES pCurrAddresses; + IP_ADAPTER_ADDRESSES adapterAddresses; + ULONG address_len; + my_bool return_val= 1; + static pfnGetAdaptersAddresses fnGetAdaptersAddresses= + (pfnGetAdaptersAddresses)-1; + + if(fnGetAdaptersAddresses == (pfnGetAdaptersAddresses)-1) + { + /* Get the function from the DLL */ + fnGetAdaptersAddresses= (pfnGetAdaptersAddresses) + GetProcAddress(LoadLibrary("iphlpapi.dll"), + "GetAdaptersAddresses"); + } + if (!fnGetAdaptersAddresses) + return 1; /* failed to get function */ + address_len= sizeof (IP_ADAPTER_ADDRESSES); + + /* Get the required size for the address data. */ + if (fnGetAdaptersAddresses(AF_UNSPEC, 0, 0, &adapterAddresses, &address_len) + == ERROR_BUFFER_OVERFLOW) + { + pAdapterAddresses= my_malloc(address_len, 0); + if (!pAdapterAddresses) + return 1; /* error, alloc failed */ + } + else + pAdapterAddresses= &adapterAddresses; /* one is enough don't alloc */ + + /* Get the hardware info. */ + if (fnGetAdaptersAddresses(AF_UNSPEC, 0, 0, pAdapterAddresses, &address_len) + == NO_ERROR) + { + pCurrAddresses= pAdapterAddresses; + + while (pCurrAddresses) + { + /* Look for ethernet cards. */ + if (pCurrAddresses->IfType == IF_TYPE_ETHERNET_CSMACD) + { + /* check for a good address */ + if (pCurrAddresses->PhysicalAddressLength < 6) + continue; /* bad address */ + + /* save 6 bytes of the address in the 'to' parameter */ + memcpy(to, pCurrAddresses->PhysicalAddress, 6); + + /* Network card found, we're done. */ + return_val= 0; + break; + } + pCurrAddresses= pCurrAddresses->Next; + } + } + + /* Clean up memory allocation. */ + if (pAdapterAddresses != &adapterAddresses) + my_free(pAdapterAddresses, 0); + + return return_val; +} + +#else /* __FreeBSD__ || __linux__ || __WIN__ */ /* just fail */ my_bool my_gethwaddr(uchar *to __attribute__((unused))) { From 12cea944fc705b9b88d8750a61a2c8b3b53386f9 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sun, 13 Sep 2009 19:38:06 +0200 Subject: [PATCH 114/138] fix compile error. definition of VOID in trunk still conflicts with windows headers. that was fixed in 6.0 --- mysys/my_gethwaddr.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c index 7fae1a51446..38fa0313c5d 100644 --- a/mysys/my_gethwaddr.c +++ b/mysys/my_gethwaddr.c @@ -102,6 +102,14 @@ err: } #elif defined(__WIN__) + +/* Workaround for BUG#32082 (Definition of VOID in my_global.h conflicts with +windows headers) */ +#ifdef VOID +#undef VOID +#define VOID void +#endif + #include /* From 3c916057ad772fe613c294fb654f9a70b65b1b5a Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Sun, 13 Sep 2009 21:52:14 +0100 Subject: [PATCH 115/138] BUG#47014: rpl_drop_temp fails on PB-2 with results mismatch The test case creates two temporary tables, then closes the connection, waits for it to disconnect, then syncs the slave with the master, checks for remaining opened temporary tables on slave (which should be 0) and finally drops the used database (mysqltest). Unfortunately, sometimes, the test fails with one open table on the slave. This seems to be caused by the fact that waiting for the connection to be closed is not sufficient. The test needs to wait for the DROP event to be logged and only then synchronize the slave with the master and proceed with the check. This is caused by the asynchronous nature of the disconnect wrt binlogging of the DROP temporary table statement. We fix this by deploying a call to wait_for_binlog_event.inc on the test case, which makes execution to wait for the DROP temp tables event before synchronizing master and slave. --- mysql-test/suite/rpl/t/rpl_drop_temp.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/suite/rpl/t/rpl_drop_temp.test b/mysql-test/suite/rpl/t/rpl_drop_temp.test index df162d3b244..7827e16e45f 100644 --- a/mysql-test/suite/rpl/t/rpl_drop_temp.test +++ b/mysql-test/suite/rpl/t/rpl_drop_temp.test @@ -23,6 +23,8 @@ disconnect con_temp; --source include/wait_until_disconnected.inc connection master; +-- let $wait_binlog_event= DROP +-- source include/wait_for_binlog_event.inc sync_slave_with_master; connection slave; From 63a81c09946be5f008eb3423e24db93dc72a3fe8 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Sun, 13 Sep 2009 22:43:47 +0100 Subject: [PATCH 116/138] BUG#47016: rpl_do_grant fails on PB-2 with a failing connect The test case rpl_do_grant fails sporadically on PB2 with "Access denied for user 'create_rout_db'@'localhost' ...". Inspecting the test case, one may find that if issues a GRANT on the master connection and immediately after it creates two new connections (one to the master and one to the slave) using the credentials set with the GRANT. Unfortunately, there is no synchronization between master and slave after the grant and before the connections are established. This can result in slave not having executed the GRANT by the time the connection is attempted. This patch fixes this by deploying a sync_slave_with_master between the grant and the connections attempt. --- mysql-test/suite/rpl/t/rpl_do_grant.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/suite/rpl/t/rpl_do_grant.test b/mysql-test/suite/rpl/t/rpl_do_grant.test index 806de780086..fc793c03649 100644 --- a/mysql-test/suite/rpl/t/rpl_do_grant.test +++ b/mysql-test/suite/rpl/t/rpl_do_grant.test @@ -129,6 +129,9 @@ CREATE DATABASE bug42217_db; GRANT CREATE ROUTINE ON bug42217_db.* TO 'create_rout_db'@'localhost' IDENTIFIED BY 'create_rout_db' WITH GRANT OPTION; +-- sync_slave_with_master +-- connection master + connect (create_rout_db_master, localhost, create_rout_db, create_rout_db, bug42217_db,$MASTER_MYPORT,); connect (create_rout_db_slave, localhost, create_rout_db, create_rout_db, bug42217_db, $SLAVE_MYPORT,); From 68fd9874b3669576ca10739b7cd9dad78e2ec7d1 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 16 Sep 2009 14:02:07 +0400 Subject: [PATCH 117/138] Fix default.conf --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 39ebdda8d7a..07179ac7dea 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.4" +tree_name = "mysql-5.4.3-trunk" From b93add2065b1aa40d483b502060ce9805caed286 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 16 Sep 2009 14:08:43 +0400 Subject: [PATCH 118/138] Fix default.conf --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 07179ac7dea..4f36ee61644 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.4.3-trunk" +tree_name = "mysql-5.4.3-trunk-bugfixing" From 7cf8f7a4bb465eca331fb08568127eadb709a4a2 Mon Sep 17 00:00:00 2001 From: Satya B Date: Thu, 17 Sep 2009 11:59:43 +0530 Subject: [PATCH 119/138] Applying InnoDB snapshot 5.1-ss5282, Fixes BUG#44030 1. Fixes BUG#44030 - Error: (1500) Couldn't read the MAX(ID) autoinc value from the index (PRIMARY) 2. Disables the innodb-autoinc test for innodb plugin temporarily. The testcase for this bug has different result file for InnoDB plugin. Should add the testcase to Innodb suite with a different result file. Detailed revision comments: r5243 | sunny | 2009-06-04 03:17:14 +0300 (Thu, 04 Jun 2009) | 14 lines branches/5.1: When the InnoDB and MySQL data dictionaries go out of sync, before the bug fix we would assert on missing autoinc columns. With this fix we allow MySQL to open the table but set the next autoinc value for the column to the MAX value. This effectively disables the next value generation. INSERTs will fail with a generic AUTOINC failure. However, the user should be able to read/dump the table, set the column values explicitly, use ALTER TABLE to set the next autoinc value and/or sync the two data dictionaries to resume normal operations. Fix Bug#44030 Error: (1500) Couldn't read the MAX(ID) autoinc value from the index (PRIMARY) rb://118 r5252 | sunny | 2009-06-04 10:16:24 +0300 (Thu, 04 Jun 2009) | 2 lines branches/5.1: The version of the result file checked in was broken in r5243. r5259 | vasil | 2009-06-05 10:29:16 +0300 (Fri, 05 Jun 2009) | 7 lines branches/5.1: Remove the word "Error" from the printout because the mysqltest suite interprets it as an error and thus the innodb-autoinc test fails. Approved by: Sunny (via IM) r5466 | vasil | 2009-07-02 10:46:45 +0300 (Thu, 02 Jul 2009) | 6 lines branches/5.1: Adjust the failing innodb-autoinc test to conform to the latest behavior of the MySQL code. The idea and the comment in innodb-autoinc.test come from Sunny. --- mysql-test/lib/mtr_cases.pm | 1 + mysql-test/r/innodb-autoinc.result | 22 ++++++++++++++++++++++ mysql-test/t/innodb-autoinc.test | 24 ++++++++++++++++++++++++ storage/innobase/handler/ha_innodb.cc | 27 +++++++++++++++++++++------ 4 files changed, 68 insertions(+), 6 deletions(-) diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index 873339166b3..efd9980eb7a 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -495,6 +495,7 @@ sub collect_one_suite($) # Exceptions next if ($test->{'name'} eq 'main.innodb'); # Failed with wrong errno (fk) next if ($test->{'name'} eq 'main.index_merge_innodb'); # Explain diff + next if ($test->{'name'} eq 'main.innodb-autoinc'); # Need dfrnt result file # innodb_file_per_table is rw with innodb_plugin next if ($test->{'name'} eq 'sys_vars.innodb_file_per_table_basic'); # innodb_lock_wait_timeout is rw with innodb_plugin diff --git a/mysql-test/r/innodb-autoinc.result b/mysql-test/r/innodb-autoinc.result index ade4db35ce6..76575ae4160 100644 --- a/mysql-test/r/innodb-autoinc.result +++ b/mysql-test/r/innodb-autoinc.result @@ -867,3 +867,25 @@ INSERT INTO t2 SELECT NULL FROM t1; Got one of the listed errors DROP TABLE t1; DROP TABLE t2; +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (null); +INSERT INTO t1 VALUES (null); +ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT; +SELECT * FROM t1; +d1 +1 +3 +SELECT * FROM t1; +d1 +1 +3 +INSERT INTO t1 VALUES(null); +ALTER TABLE t1 AUTO_INCREMENT = 3; +INSERT INTO t1 VALUES(null); +SELECT * FROM t1; +d1 +1 +3 +4 +5 +DROP TABLE t1; diff --git a/mysql-test/t/innodb-autoinc.test b/mysql-test/t/innodb-autoinc.test index d76b29a7dc8..b51014ef4b3 100644 --- a/mysql-test/t/innodb-autoinc.test +++ b/mysql-test/t/innodb-autoinc.test @@ -478,3 +478,27 @@ INSERT INTO t2 SELECT c1 FROM t1; INSERT INTO t2 SELECT NULL FROM t1; DROP TABLE t1; DROP TABLE t2; +# +# 44030: Error: (1500) Couldn't read the MAX(ID) autoinc value from +# the index (PRIMARY) +# This test requires a restart of the server +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (null); +INSERT INTO t1 VALUES (null); +ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT; +SELECT * FROM t1; +# Restart the server +-- source include/restart_mysqld.inc +# The MySQL and InnoDB data dictionaries should now be out of sync. +# The select should print message to the error log +SELECT * FROM t1; +# MySQL have made a change (http://lists.mysql.com/commits/75268) that no +# longer results in the two data dictionaries being out of sync. If they +# revert their changes then this check for ER_AUTOINC_READ_FAILED will need +# to be enabled. +# -- error ER_AUTOINC_READ_FAILED,1467 +INSERT INTO t1 VALUES(null); +ALTER TABLE t1 AUTO_INCREMENT = 3; +INSERT INTO t1 VALUES(null); +SELECT * FROM t1; +DROP TABLE t1; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index b35f83cce58..207406f8673 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2515,12 +2515,28 @@ ha_innobase::innobase_initialize_autoinc() dict_table_autoinc_initialize(innodb_table, auto_inc); - } else { + } else if (error == DB_RECORD_NOT_FOUND) { ut_print_timestamp(stderr); - fprintf(stderr, " InnoDB: Error: (%lu) Couldn't read " - "the MAX(%s) autoinc value from the " - "index (%s).\n", error, col_name, index->name); - } + fprintf(stderr, " InnoDB: MySQL and InnoDB data " + "dictionaries are out of sync.\n" + "InnoDB: Unable to find the AUTOINC column %s in the " + "InnoDB table %s.\n" + "InnoDB: We set the next AUTOINC column value to the " + "maximum possible value,\n" + "InnoDB: in effect disabling the AUTOINC next value " + "generation.\n" + "InnoDB: You can either set the next AUTOINC value " + "explicitly using ALTER TABLE\n" + "InnoDB: or fix the data dictionary by recreating " + "the table.\n", + col_name, index->table->name); + + auto_inc = 0xFFFFFFFFFFFFFFFFULL; + + dict_table_autoinc_initialize(innodb_table, auto_inc); + + error = DB_SUCCESS; + } /* else other errors are still fatal */ return(ulong(error)); } @@ -2731,7 +2747,6 @@ retry: if (dict_table_autoinc_read(prebuilt->table) == 0) { error = innobase_initialize_autoinc(); - /* Should always succeed! */ ut_a(error == DB_SUCCESS); } From 4336ca40729a86c9c6f5d48a52589ab05f22158d Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Thu, 17 Sep 2009 03:23:05 -0600 Subject: [PATCH 120/138] fixed tree name --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index ddb2588bbc1..197a0ef0dc0 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.4.3-next-mr" +tree_name = "mysql-5.4.3-trunk-signal" From 2535ede7138cb4d1e8986d18b4154c377ba37f3f Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 17 Sep 2009 16:33:23 +0500 Subject: [PATCH 121/138] Bug#42364 SHOW ERRORS returns empty resultset after dropping non existent table additional backport of of bug43138 fix mysql-test/t/myisam-system.test: additional backport of of bug43138 fix sql/sql_db.cc: additional backport of of bug43138 fix --- mysql-test/r/trigger_notembedded.result | 2 -- mysql-test/t/myisam-system.test | 6 +++--- sql/sql_db.cc | 4 ++++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/trigger_notembedded.result b/mysql-test/r/trigger_notembedded.result index 335e6910a3a..d66308a9bd7 100644 --- a/mysql-test/r/trigger_notembedded.result +++ b/mysql-test/r/trigger_notembedded.result @@ -180,8 +180,6 @@ NULL mysqltest_db1 trg5 DELETE NULL mysqltest_db1 t1 0 NULL SET @a = 5 ROW BEFOR DROP USER mysqltest_dfn@localhost; DROP USER mysqltest_inv@localhost; DROP DATABASE mysqltest_db1; -Warnings: -Warning 1454 No definer attribute for trigger 'mysqltest_db1'.'trg1'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger. DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%'; DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%'; DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%'; diff --git a/mysql-test/t/myisam-system.test b/mysql-test/t/myisam-system.test index dc5bb58b6a2..d908e639a4e 100644 --- a/mysql-test/t/myisam-system.test +++ b/mysql-test/t/myisam-system.test @@ -12,11 +12,11 @@ let $MYSQLD_DATADIR= `select @@datadir`; drop table if exists t1; create table t1 (a int) engine=myisam; --remove_file $MYSQLD_DATADIR/test/t1.MYI ---error 1051,6 +--error ER_BAD_TABLE_ERROR,6 drop table t1; create table t1 (a int) engine=myisam; --remove_file $MYSQLD_DATADIR/test/t1.MYD ---error 1105,6,29 +--error ER_BAD_TABLE_ERROR,6,29 drop table t1; ---error 1051 +--error ER_BAD_TABLE_ERROR drop table t1; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 3fca5bd7df6..bcc8fcf54fc 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -907,6 +907,9 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) remove_db_from_cache(db); pthread_mutex_unlock(&LOCK_open); + Drop_table_error_handler err_handler(thd->get_internal_handler()); + thd->push_internal_handler(&err_handler); + error= -1; /* We temporarily disable the binary log while dropping the objects @@ -939,6 +942,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) error = 0; reenable_binlog(thd); } + thd->pop_internal_handler(); } if (!silent && deleted>=0) { From e60ff2b6a30f207f18760ca9a0de444110e800f5 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Fri, 18 Sep 2009 17:24:49 +0400 Subject: [PATCH 122/138] Revert InnoDB default values as of the InnoDB plugin 1.0.4. --- storage/innobase/handler/ha_innodb.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 166c4f00158..f9c893ac845 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -9831,12 +9831,12 @@ static MYSQL_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_ static MYSQL_SYSVAR_ULONG(autoextend_increment, srv_auto_extend_increment, PLUGIN_VAR_RQCMDARG, "Data file autoextend increment in megabytes", - NULL, NULL, 64L, 1L, 1000L, 0); + NULL, NULL, 8L, 1L, 1000L, 0); static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.", - NULL, NULL, 1024*1024*1024L, 5*1024*1024L, LONGLONG_MAX, 1024*1024L); + NULL, NULL, 128*1024*1024L, 5*1024*1024L, LONGLONG_MAX, 1024*1024L); static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency, PLUGIN_VAR_RQCMDARG, @@ -9856,12 +9856,12 @@ static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads, static MYSQL_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "Number of background read I/O threads in InnoDB.", - NULL, NULL, 8, 1, 64, 0); + NULL, NULL, 4, 1, 64, 0); static MYSQL_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "Number of background write I/O threads in InnoDB.", - NULL, NULL, 8, 1, 64, 0); + NULL, NULL, 4, 1, 64, 0); static MYSQL_SYSVAR_LONG(force_recovery, innobase_force_recovery, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, @@ -9871,17 +9871,17 @@ static MYSQL_SYSVAR_LONG(force_recovery, innobase_force_recovery, static MYSQL_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "The size of the buffer which InnoDB uses to write log to the log files on disk.", - NULL, NULL, 16*1024*1024L, 256*1024L, LONG_MAX, 1024); + NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024); static MYSQL_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "Size of each log file in a log group.", - NULL, NULL, 128*1024*1024L, 1*1024*1024L, LONGLONG_MAX, 1024*1024L); + NULL, NULL, 5*1024*1024L, 1*1024*1024L, LONGLONG_MAX, 1024*1024L); static MYSQL_SYSVAR_LONG(log_files_in_group, innobase_log_files_in_group, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.", - NULL, NULL, 3, 2, 100, 0); + NULL, NULL, 2, 2, 100, 0); static MYSQL_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, From 9d8c02385926ba0878ef9d52bdaaf4825a3580bf Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Sat, 19 Sep 2009 13:37:22 +0400 Subject: [PATCH 123/138] Mark some tests experimental. --- mysql-test/collections/default.experimental | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 8bec38a373b..8ad0d8a41cd 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -1,6 +1,17 @@ funcs_1.charset_collation_1 # depends on compile-time decisions + binlog.binlog_tmp_table # Bug#45578: Test binlog_tmp_table fails ramdonly on PB2: Unknown table 't2' + +innodb.innodb_information_schema # Bug#47449 2009-09-19 alik main.information_schema and innodb.innodb_information_schema fail sporadically + main.ctype_gbk_binlog # Bug#46010: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists +main.lock_multi_bug38499 # Bug#47448 2009-09-19 alik main.lock_multi_bug38499 times out sporadically +main.information_schema # Bug#47449 2009-09-19 alik main.information_schema and innodb.innodb_information_schema fail sporadically + rpl.rpl_row_create_table # Bug#45576: rpl_row_create_table fails on PB2 rpl_ndb.rpl_ndb_log # Bug#38998 rpl.rpl_innodb_bug28430 # Bug#46029 +rpl.rpl_get_master_version_and_clock # Bug#46931 2009-08-26 alik rpl.rpl_get_master_version_and_clock fails on hpux11.31 + +ndb.* # Consider all NDB tests experimental. +rpl_ndb.* # Consider all NDB tests experimental. From 18f7dd0fad8479007d9618bfd570be72cae90277 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Sun, 20 Sep 2009 01:09:02 +0400 Subject: [PATCH 124/138] Update default.experimental. --- mysql-test/collections/default.experimental | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 8ad0d8a41cd..42e68759580 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -13,5 +13,5 @@ rpl_ndb.rpl_ndb_log # Bug#38998 rpl.rpl_innodb_bug28430 # Bug#46029 rpl.rpl_get_master_version_and_clock # Bug#46931 2009-08-26 alik rpl.rpl_get_master_version_and_clock fails on hpux11.31 -ndb.* # Consider all NDB tests experimental. -rpl_ndb.* # Consider all NDB tests experimental. +ndb.n* # Consider all NDB tests experimental. +rpl_ndb.r* # Consider all NDB tests experimental. From 4a75d269cedf201a6a5f46a936c4db7c960f3be3 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 21 Sep 2009 11:28:49 +0200 Subject: [PATCH 125/138] tiny suppression fix: avoid / --- mysql-test/include/mtr_warnings.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql index 02e8d68263f..47b1d9b10bb 100644 --- a/mysql-test/include/mtr_warnings.sql +++ b/mysql-test/include/mtr_warnings.sql @@ -162,7 +162,7 @@ INSERT INTO global_suppressions VALUES ("Slave: Unknown column 'c7' in 't15' Error_code: 1054"), ("Slave: Can't DROP 'c7'.* 1091"), ("Slave: Key column 'c6'.* 1072"), - ("Slave I/O: The slave I/O thread stops because a fatal error is encountered when it try to get the value of SERVER_ID variable from master."), + ("Slave I.O: The slave I.O thread stops because a fatal error is encountered when it try to get the value of SERVER_ID variable from master."), (".SELECT UNIX_TIMESTAMP... failed on master, do not trust column Seconds_Behind_Master of SHOW SLAVE STATUS"), /* Test case for Bug#31590 in order_by.test produces the following error */ From dcf935a198af05c701f0d5f9cd0d574acae321ed Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Tue, 22 Sep 2009 18:21:44 +0400 Subject: [PATCH 126/138] Update version. --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 2723286a405..b4aa9bb4e72 100644 --- a/configure.in +++ b/configure.in @@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM # # When changing major version number please also check switch statement # in client/mysqlbinlog.cc:check_master_version(). -AM_INIT_AUTOMAKE(mysql, 5.4.3-beta) +AM_INIT_AUTOMAKE(mysql, 5.4.4-beta) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 From 60781e320f600cebb713a08152b920d44aa22e0f Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 23 Sep 2009 13:50:31 +0400 Subject: [PATCH 127/138] Update version in configure.in. --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index b4aa9bb4e72..60a583fa25b 100644 --- a/configure.in +++ b/configure.in @@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM # # When changing major version number please also check switch statement # in client/mysqlbinlog.cc:check_master_version(). -AM_INIT_AUTOMAKE(mysql, 5.4.4-beta) +AM_INIT_AUTOMAKE(mysql, 5.4.5-beta) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 From 5a361c26cf02e8db4d578c2d57c8de9cb6adc722 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 23 Sep 2009 14:04:08 +0400 Subject: [PATCH 128/138] Update default.conf. --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 4f36ee61644..6f293210bae 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.4.3-trunk-bugfixing" +tree_name = "mysql-5.4.5-trunk-bugfixing" From 7cd113e57c58c2c276f305e8053c71077aaf72d8 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 23 Sep 2009 14:08:38 +0400 Subject: [PATCH 129/138] Update default.conf. --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 6f293210bae..30c0d1f9e32 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.4.5-trunk-bugfixing" +tree_name = "mysql-5.4.5-trunk" From 7947948c5225b5e48dfeb18a17f0c170620bfc89 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 23 Sep 2009 14:12:43 +0400 Subject: [PATCH 130/138] Update default.conf. --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index efd9210319e..771201a109b 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.4.5-next-mr-bugfixing" +tree_name = "mysql-5.4.5-next-mr" From b0220ff9ff6fbc9fc65a9b04f25e337951edd259 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 23 Sep 2009 18:02:39 +0400 Subject: [PATCH 131/138] Ignore a new symbolic link. --- .bzrignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.bzrignore b/.bzrignore index 6c6a43dacab..0dd59e5cee8 100644 --- a/.bzrignore +++ b/.bzrignore @@ -3064,3 +3064,4 @@ sql/share/spanish sql/share/swedish sql/share/ukrainian libmysqld/examples/mysqltest.cc +libmysqld/sql_signal.cc From 41a8a638576183f4e426adaa70d064593ecce273 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 23 Sep 2009 22:50:13 +0400 Subject: [PATCH 132/138] Update disabled.def files. --- mysql-test/suite/funcs_1/t/disabled.def | 2 +- mysql-test/suite/innodb/t/disabled.def | 2 +- mysql-test/suite/parts/t/disabled.def | 2 +- mysql-test/suite/rpl/t/disabled.def | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/funcs_1/t/disabled.def b/mysql-test/suite/funcs_1/t/disabled.def index 3f260ca49ba..23f15b78103 100644 --- a/mysql-test/suite/funcs_1/t/disabled.def +++ b/mysql-test/suite/funcs_1/t/disabled.def @@ -10,4 +10,4 @@ # ############################################################################## -ndb_trig_1011ext: Bug#32656 NDB: Duplicate key error aborts transaction in handler. Doesn't talk back to SQL +ndb_trig_1011ext: Bug#47564 diff --git a/mysql-test/suite/innodb/t/disabled.def b/mysql-test/suite/innodb/t/disabled.def index baf8c89f539..195fd1c0758 100644 --- a/mysql-test/suite/innodb/t/disabled.def +++ b/mysql-test/suite/innodb/t/disabled.def @@ -1 +1 @@ -innodb-index: InnoDB: Error: table `test`.`t1#1` already exists in InnoDB internal +innodb-index : Bug#47563 2009-06-11 svoj InnoDB: Error: table `test`.`t1#1` already exists in InnoDB internal diff --git a/mysql-test/suite/parts/t/disabled.def b/mysql-test/suite/parts/t/disabled.def index 518a3c90422..8a1dafe59a2 100644 --- a/mysql-test/suite/parts/t/disabled.def +++ b/mysql-test/suite/parts/t/disabled.def @@ -1,3 +1,3 @@ -partition_basic_ndb : Bug#19899 Crashing the server +partition_basic_ndb : Bug#44919 parts-suite in mtr tries to use features not supported by ndb # http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-limitations-syntax.html partition_syntax_ndb : Bug#36735 Not supported diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index 38fc9e21322..85747264b6f 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -10,4 +10,4 @@ # ############################################################################## -rpl_cross_version : Bug#42311 2009-03-27 joro rpl_cross_version fails on macosx +rpl_cross_version : Bug#43913 2009-03-27 joro rpl_cross_version can't pass on conflicts complainig clash with --slave-load-tm From 45921153db55119eb7a9ad4f991fe067085a3269 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Thu, 24 Sep 2009 16:29:29 +0400 Subject: [PATCH 133/138] Mark some tests experimental. Update default.conf. --- .bzr-mysql/default.conf | 2 +- mysql-test/collections/default.experimental | 58 +++++++++++++++++++-- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 30c0d1f9e32..55e3841ef90 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.4.5-trunk" +tree_name = "mysql-5.4.5-trunk-alik" diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 85c14c6f67a..edc6df26ce0 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -2,18 +2,68 @@ # in alphabetical order. This also helps with merge conflict resolution. binlog.binlog_tmp_table* # Bug#45578:2009-07-10 alik Test binlog_tmp_table fails ramdonly on PB2: Unknown table 't2' + funcs_1.charset_collation_1 # depends on compile-time decisions + innodb.innodb_information_schema # Bug#47449 2009-09-19 alik main.information_schema and innodb.innodb_information_schema fail sporadically + main.ctype_gbk_binlog @solaris # Bug#46010: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists main.information_schema # Bug#47449 2009-09-19 alik main.information_schema and innodb.innodb_information_schema fail sporadically +main.innodb-autoinc # Bug#44030 2009-09-24 alik Marking innodb-autoinc experimental while waiting for the patch to be merged main.lock_multi_bug38499 # Bug#47448 2009-09-19 alik main.lock_multi_bug38499 times out sporadically -main.plugin* @solaris # Bug#47146 Linking problem with example plugin when dtrace enabled -main.plugin_load @solaris # Bug#47146 +main.plugin # Bug#47146 Linking problem with example plugin when dtrace enabled +main.plugin_load # Bug#47146 + rpl.rpl_get_master_version_and_clock* # Bug#46931 2009-08-26 alik rpl.rpl_get_master_version_and_clock fails on hpux11.31 rpl.rpl_innodb_bug28430* @solaris # Bug#46029 rpl.rpl_plugin_load* @solaris # Bug#47146 rpl.rpl_row_create_table* # Bug#45576: rpl_row_create_table fails on PB2 + rpl_ndb.rpl_ndb_log # Bug#38998 -ndb.n* # Consider all NDB tests experimental. -rpl_ndb.r* # Consider all NDB tests experimental. +# Declare all NDB-tests in other test suites experimental. + +stress.ddl_ndb + +sys_vars.ndb_log_update_as_write_basic +sys_vars.have_ndbcluster_basic +sys_vars.ndb_log_updated_only_basic + +funcs_1.ndb_storedproc_10 +funcs_1.ndb_bitdata +funcs_1.ndb_trig_03 +funcs_1.ndb_trig_0102 +funcs_1.is_tables_ndb +funcs_1.is_columns_ndb +funcs_1.ndb_trig_0407 +funcs_1.ndb_trig_1011ext +funcs_1.ndb_storedproc_06 +funcs_1.ndb_views +funcs_1.is_cml_ndb +funcs_1.ndb_storedproc_02 +funcs_1.ndb_storedproc_03 +funcs_1.ndb_trig_03e +funcs_1.is_engines_ndb +funcs_1.ndb_trig_08 +funcs_1.ndb_storedproc_07 +funcs_1.ndb_storedproc_08 +funcs_1.ndb_func_view +funcs_1.ndb_trig_09 +funcs_1.ndb_cursors + +funcs_2.ndb_charset + +parts.partition_engine_ndb +parts.ndb_dd_backuprestore +parts.partition_value_ndb +parts.partition_mgm_lc2_ndb +parts.partition_alter1_2_ndb +parts.partition_alter1_1_ndb +parts.part_supported_sql_func_ndb +parts.partition_int_ndb +parts.partition_mgm_lc1_ndb +parts.partition_auto_increment_ndb +parts.partition_syntax_ndb +parts.partition_alter1_1_2_ndb +parts.partition_basic_ndb +parts.partition_mgm_lc0_ndb From b893cc510c69f2098ac751e5350e171c21c2bfa8 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Thu, 24 Sep 2009 16:30:13 +0400 Subject: [PATCH 134/138] Disable ndb and rpl_ndb test suites from regular tests. --- mysql-test/collections/mysql-trunk.push | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 mysql-test/collections/mysql-trunk.push diff --git a/mysql-test/collections/mysql-trunk.push b/mysql-test/collections/mysql-trunk.push new file mode 100644 index 00000000000..99ff6f21673 --- /dev/null +++ b/mysql-test/collections/mysql-trunk.push @@ -0,0 +1,5 @@ +perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --mysqld=--binlog-format=mixed --suite=main,binlog,innodb,federated,rpl +perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --ps-protocol --mysqld=--binlog-format=row --suite=main,binlog,innodb,federated,rpl +perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=embedded --embedded --suite=main,binlog,innodb,federated,rpl +perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_row --mysqld=--binlog-format=row --suite=rpl,binlog +perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --suite=funcs_1 From 350fad0e46be5bc103451bce9978f46712cb93fe Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Fri, 25 Sep 2009 13:21:49 +0400 Subject: [PATCH 135/138] Mark rpl.rpl_trigger experimental. --- mysql-test/collections/default.experimental | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index edc6df26ce0..872b8f29101 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -18,6 +18,7 @@ rpl.rpl_get_master_version_and_clock* # Bug#46931 2009-08-26 alik rpl.rpl_get rpl.rpl_innodb_bug28430* @solaris # Bug#46029 rpl.rpl_plugin_load* @solaris # Bug#47146 rpl.rpl_row_create_table* # Bug#45576: rpl_row_create_table fails on PB2 +rpl.rpl_trigger* # Bug#46656 2009-09-25 alik InnoDB plugin: memory leaks (Valgrind) rpl_ndb.rpl_ndb_log # Bug#38998 From 3f0caab6e596a453d9667e489bf5bf381f81456a Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Fri, 25 Sep 2009 13:40:25 +0400 Subject: [PATCH 136/138] Mark rpl.rpl_innodb_bug30888 experimental. --- mysql-test/collections/default.experimental | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 872b8f29101..fc057256147 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -16,6 +16,7 @@ main.plugin_load # Bug#47146 rpl.rpl_get_master_version_and_clock* # Bug#46931 2009-08-26 alik rpl.rpl_get_master_version_and_clock fails on hpux11.31 rpl.rpl_innodb_bug28430* @solaris # Bug#46029 +rpl.rpl_innodb_bug30888* @solaris # Bug#47646 2009-09-25 alik rpl.rpl_innodb_bug30888 fails sporadically on Solaris rpl.rpl_plugin_load* @solaris # Bug#47146 rpl.rpl_row_create_table* # Bug#45576: rpl_row_create_table fails on PB2 rpl.rpl_trigger* # Bug#46656 2009-09-25 alik InnoDB plugin: memory leaks (Valgrind) From 3baea8b9e8f26120260e2745c051a5cfee81e88b Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Fri, 25 Sep 2009 13:42:54 +0400 Subject: [PATCH 137/138] Update default.conf --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 55e3841ef90..30c0d1f9e32 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.4.5-trunk-alik" +tree_name = "mysql-5.4.5-trunk" From a8edd0aabb5059935b99076fbcc92403079535df Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Mon, 28 Sep 2009 00:54:22 +0400 Subject: [PATCH 138/138] Update default.conf. --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 172fa24692b..771201a109b 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.4.5-next-windows-enhancements" +tree_name = "mysql-5.4.5-next-mr"