diff options
author | unknown <knielsen@knielsen-hq.org> | 2012-02-22 12:14:34 +0100 |
---|---|---|
committer | unknown <knielsen@knielsen-hq.org> | 2012-02-22 12:14:34 +0100 |
commit | aabf212b01f3896aa38ad596554401a4c34a61a3 (patch) | |
tree | 4b00876e2caec3792a3a61b1e084e10d0d0e270f | |
parent | 1e7105786ff8d8b7f2cc34cd725c2304b39c5433 (diff) | |
parent | de9ba100773cec486c4d5f94b730e88ca8d3daf2 (diff) | |
download | mariadb-git-aabf212b01f3896aa38ad596554401a4c34a61a3.tar.gz |
Merge latest MariaDB 5.5 into MWL#192: Non-blocking client library.
281 files changed, 7981 insertions, 3760 deletions
diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 43d479a1043..20aadc5d7fc 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,6 @@ [MYSQL] -post_commit_to = "commits@lists.mysql.com" -post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.5" +tree_location = lp:maria/5.3 +post_commit_to = commits@mariadb.org +post_commit_url = lp:maria/5.3 +tree_name = maria/5.3 +project_name = "Mariadb 5.3, with Aria 2.0" @@ -45,6 +45,9 @@ https://bugs.launchpad.net/maria Bugs in the MySQL code can also be submitted at http://bugs.mysql.com +The code for MariaDB, including all revision history, can be found at: +https://code.launchpad.net/maria + *************************************************************************** %%The following software may be included in this product: @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=21 +MYSQL_VERSION_PATCH=20 MYSQL_VERSION_EXTRA= diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index d29cc902aa3..fb8b123b9d6 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -31,12 +31,13 @@ MYSQL_ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc TARGET_LINK_LIBRARIES(mysql mysqlclient) IF(UNIX) TARGET_LINK_LIBRARIES(mysql ${MY_READLINE_LIBRARY}) - SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rdynamic") + SET_TARGET_PROPERTIES(mysql PROPERTIES ENABLE_EXPORTS TRUE) ENDIF(UNIX) MYSQL_ADD_EXECUTABLE(mysqltest mysqltest.cc COMPONENT Test) SET_SOURCE_FILES_PROPERTIES(mysqltest.cc PROPERTIES COMPILE_FLAGS "-DTHREADS") TARGET_LINK_LIBRARIES(mysqltest mysqlclient regex) +SET_TARGET_PROPERTIES(mysqltest PROPERTIES ENABLE_EXPORTS TRUE) MYSQL_ADD_EXECUTABLE(mysqlcheck mysqlcheck.c) diff --git a/cmake/dtrace.cmake b/cmake/dtrace.cmake index 882ea0de6aa..0e7c71c7f09 100644 --- a/cmake/dtrace.cmake +++ b/cmake/dtrace.cmake @@ -34,9 +34,15 @@ MACRO(CHECK_DTRACE) FIND_PROGRAM(DTRACE dtrace) MARK_AS_ADVANCED(DTRACE) + IF(CMAKE_C_COMPILER MATCHES "ccache" AND CMAKE_SYSTEM_NAME MATCHES "Linux") + # dtrace fails on fedora if CC='ccache gcc' is used + SET(BUGGY_LINUX_DTRACE 1) + ENDIF() + # On FreeBSD, dtrace does not handle userland tracing yet IF(DTRACE AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD" - AND NOT BUGGY_GCC_NO_DTRACE_MODULES) + AND NOT BUGGY_GCC_NO_DTRACE_MODULES + AND NOT BUGGY_LINUX_DTRACE) SET(ENABLE_DTRACE ON CACHE BOOL "Enable dtrace") ENDIF() SET(HAVE_DTRACE ${ENABLE_DTRACE}) diff --git a/cmake/libutils.cmake b/cmake/libutils.cmake index bb90f7d2a6c..7c13df05ca4 100644 --- a/cmake/libutils.cmake +++ b/cmake/libutils.cmake @@ -305,16 +305,27 @@ FUNCTION(GET_DEPENDEND_OS_LIBS target result) ENDFUNCTION() MACRO(RESTRICT_SYMBOL_EXPORTS target) + SET(VISIBILITY_HIDDEN_FLAG) + IF(CMAKE_COMPILER_IS_GNUCXX AND UNIX) CHECK_C_COMPILER_FLAG("-fvisibility=hidden" HAVE_VISIBILITY_HIDDEN) IF(HAVE_VISIBILITY_HIDDEN) - GET_TARGET_PROPERTY(COMPILE_FLAGS ${target} COMPILE_FLAGS) - IF(NOT COMPILE_FLAGS) - # Avoid COMPILE_FLAGS-NOTFOUND - SET(COMPILE_FLAGS) - ENDIF() - SET_TARGET_PROPERTIES(${target} PROPERTIES - COMPILE_FLAGS "${COMPILE_FLAGS} -fvisibility=hidden") + SET(VISIBILITY_HIDDEN_FLAG "-fvisibility=hidden") + ENDIF() + ENDIF() + + IF(CMAKE_C_COMPILER_ID MATCHES "SunPro") + SET(VISIBILITY_HIDDEN_FLAG "-xldscope=hidden") + ENDIF() + + IF(VISIBILITY_HIDDEN_FLAG) + GET_TARGET_PROPERTY(COMPILE_FLAGS ${target} COMPILE_FLAGS) + IF(NOT COMPILE_FLAGS) + # Avoid COMPILE_FLAGS-NOTFOUND + SET(COMPILE_FLAGS) ENDIF() + SET_TARGET_PROPERTIES(${target} PROPERTIES + COMPILE_FLAGS "${COMPILE_FLAGS} ${VISIBILITY_HIDDEN_FLAG}") ENDIF() + ENDMACRO() diff --git a/cmake/os/SunOS.cmake b/cmake/os/SunOS.cmake index 3d2b4b8949a..d5a4b5c96b0 100644 --- a/cmake/os/SunOS.cmake +++ b/cmake/os/SunOS.cmake @@ -93,3 +93,8 @@ IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_SIZEOF_VOID_P EQUAL 4 ENDIF() ENDIF() ENDIF() + +IF(CMAKE_CXX_COMPILER_ID MATCHES "SunPro") + # Unnamed structs and unions + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -features=extensions") +ENDIF() diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake index a74802c2314..ac6ce6bc237 100644 --- a/cmake/plugin.cmake +++ b/cmake/plugin.cmake @@ -136,6 +136,7 @@ MACRO(MYSQL_ADD_PLUGIN) SET_TARGET_PROPERTIES(${target} PROPERTIES COMPILE_DEFINITONS "MYSQL_SERVER") DTRACE_INSTRUMENT(${target}) ADD_DEPENDENCIES(${target} GenError ${ARG_DEPENDENCIES}) + RESTRICT_SYMBOL_EXPORTS(${target}) IF(WITH_EMBEDDED_SERVER) # Embedded library should contain PIC code and be linkable # to shared libraries (on systems that need PIC) diff --git a/cmake/readline.cmake b/cmake/readline.cmake index 24a411e3f1d..49ab92f8bdb 100644 --- a/cmake/readline.cmake +++ b/cmake/readline.cmake @@ -116,7 +116,6 @@ MACRO (MYSQL_USE_BUNDLED_READLINE) SET(HAVE_HIST_ENTRY) SET(READLINE_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/cmd-line-utils) SET(READLINE_LIBRARY readline) - FIND_CURSES() ADD_SUBDIRECTORY(${CMAKE_SOURCE_DIR}/cmd-line-utils/readline) ENDMACRO() @@ -126,10 +125,10 @@ MACRO (MYSQL_FIND_SYSTEM_READLINE) FIND_LIBRARY(READLINE_LIBRARY NAMES readline) MARK_AS_ADVANCED(READLINE_INCLUDE_DIR READLINE_LIBRARY) - SET(CMAKE_REQUIRES_LIBRARIES ${READLINE_LIBRARY}) + SET(CMAKE_REQUIRES_LIBRARIES ${READLINE_LIBRARY} ${CURSES_LIBRARY}) IF(READLINE_LIBRARY AND READLINE_INCLUDE_DIR) - SET(CMAKE_REQUIRED_LIBRARIES ${READLINE_LIBRARY}) + SET(CMAKE_REQUIRED_LIBRARIES ${READLINE_LIBRARY} ${CURSES_LIBRARY}) CHECK_CXX_SOURCE_COMPILES(" #include <stdio.h> #include <readline/readline.h> @@ -175,6 +174,7 @@ MACRO (MYSQL_FIND_SYSTEM_READLINE) ENDIF(READLINE_V5) ENDIF(NEW_READLINE_INTERFACE) ENDIF() + SET(CMAKE_REQUIRES_LIBRARIES ) ENDMACRO() MACRO (MYSQL_FIND_SYSTEM_LIBEDIT) @@ -197,6 +197,7 @@ MACRO (MYSQL_FIND_SYSTEM_LIBEDIT) LIBEDIT_INTERFACE) SET(USE_LIBEDIT_INTERFACE ${LIBEDIT_INTERFACE}) ENDIF() + SET(CMAKE_REQUIRES_LIBRARIES) ENDMACRO() @@ -204,6 +205,7 @@ MACRO (MYSQL_CHECK_READLINE) IF (NOT WIN32) MYSQL_CHECK_MULTIBYTE() SET(WITH_READLINE OFF CACHE BOOL "Use bundled readline") + FIND_CURSES() IF(WITH_READLINE) MYSQL_USE_BUNDLED_READLINE() @@ -217,7 +219,7 @@ MACRO (MYSQL_CHECK_READLINE) ENDIF() ENDIF() SET(MY_READLINE_INCLUDE_DIR ${READLINE_INCLUDE_DIR}) - SET(MY_READLINE_LIBRARY ${READLINE_LIBRARY}) + SET(MY_READLINE_LIBRARY ${READLINE_LIBRARY} ${CURSES_LIBRARY}) ENDIF(NOT WIN32) ENDMACRO() diff --git a/cmd-line-utils/libedit/chartype.h b/cmd-line-utils/libedit/chartype.h index 678d13683be..40012afb47d 100644 --- a/cmd-line-utils/libedit/chartype.h +++ b/cmd-line-utils/libedit/chartype.h @@ -45,11 +45,11 @@ * seems to actually advertise this properly, despite Unicode 3.1 having * been around since 2001... */ -/* XXXMYSQL : Added FreeBSD to bypass this check. - TODO : Verify if FreeBSD stores ISO 10646 in wchar_t. */ +/* XXXMYSQL : Added FreeBSD & AIX to bypass this check. + TODO : Verify if FreeBSD & AIX stores ISO 10646 in wchar_t. */ #if !defined(__NetBSD__) && !defined(__sun) \ && !(defined(__APPLE__) && defined(__MACH__)) \ - && !defined(__FreeBSD__) + && !defined(__FreeBSD__) && !defined(_AIX) #ifndef __STDC_ISO_10646__ /* In many places it is assumed that the first 127 code points are ASCII * compatible, so ensure wchar_t indeed does ISO 10646 and not some other diff --git a/cmd-line-utils/libedit/eln.c b/cmd-line-utils/libedit/eln.c index 4b9f16c38f3..f996367115a 100644 --- a/cmd-line-utils/libedit/eln.c +++ b/cmd-line-utils/libedit/eln.c @@ -200,7 +200,7 @@ el_set(EditLine *el, int op, ...) ret = -1; goto out; } - // XXX: The two strdup's leak + /* XXX: The two strdups leak. */ ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]), func); ct_free_argv(wargv); diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c index eaf26d4c497..a2a92edc1b4 100644 --- a/cmd-line-utils/libedit/readline.c +++ b/cmd-line-utils/libedit/readline.c @@ -1978,7 +1978,7 @@ rl_callback_read_char() } else wbuf = NULL; (*(void (*)(const char *))rl_linefunc)(wbuf); - //el_set(e, EL_UNBUFFERED, 1); + /*el_set(e, EL_UNBUFFERED, 1);*/ } } diff --git a/dbug/dbug.c b/dbug/dbug.c index eb7a0e9c4b6..799c6bc8113 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -1884,6 +1884,8 @@ static void DBUGOpenFile(CODE_STATE *cs, name=cs->stack->name; if (strcmp(name, "-") == 0) { + if (!is_shared(cs->stack, out_file)) + DBUGCloseFile(cs, cs->stack->out_file); cs->stack->out_file= stdout; cs->stack->flags |= FLUSH_ON_WRITE; cs->stack->name[0]=0; @@ -1906,6 +1908,8 @@ static void DBUGOpenFile(CODE_STATE *cs, } else { + if (!is_shared(cs->stack, out_file)) + DBUGCloseFile(cs, cs->stack->out_file); cs->stack->out_file= fp; } } diff --git a/debian/dist/Debian/mariadb-server-5.5.postinst b/debian/dist/Debian/mariadb-server-5.5.postinst index 60365711ebf..e3f2df13b4b 100644 --- a/debian/dist/Debian/mariadb-server-5.5.postinst +++ b/debian/dist/Debian/mariadb-server-5.5.postinst @@ -21,7 +21,7 @@ invoke() { fi } -MYSQL_BOOTSTRAP="/usr/sbin/mysqld --bootstrap --user=mysql --skip-grant-tables --innodb=OFF --pbxt=OFF --default-storage-engine=myisam" +MYSQL_BOOTSTRAP="/usr/sbin/mysqld --bootstrap --user=mysql --skip-grant-tables --loose-innodb=OFF --loose-pbxt=OFF --default-storage-engine=myisam" test_mysql_access() { mysql --no-defaults -u root -h localhost </dev/null >/dev/null 2>&1 diff --git a/debian/dist/Debian/rules b/debian/dist/Debian/rules index 24e9b22132a..457502882c4 100755 --- a/debian/dist/Debian/rules +++ b/debian/dist/Debian/rules @@ -66,7 +66,7 @@ endif ( test -d $(builddir) || mkdir $(builddir) ) && cd $(builddir) && \ sh -c 'PATH=$${MYSQL_BUILD_PATH:-"/bin:/usr/bin:/usr/local/bin"} \ CC=$${MYSQL_BUILD_CC:-gcc} \ - CFLAGS=$${MYSQL_BUILD_CFLAGS:-"-O2 -fno-omit-frame-pointer -g -pipe -Wall -Wno-uninitialized"} \ + CFLAGS=$${MYSQL_BUILD_CFLAGS:-"-O2 -fno-omit-frame-pointer -g -pipe -Wall -Wno-uninitialized $$(case `lsb_release -sc` in (lenny) echo -DWORKAROUND_GCC_4_3_2_BUG ;; esac)"} \ CXX=$${MYSQL_BUILD_CXX:-g++} \ CXXFLAGS=$${MYSQL_BUILD_CXXFLAGS:-"-O2 -fno-omit-frame-pointer -g -pipe -Wall -Wno-uninitialized"} \ cmake .. \ diff --git a/debian/dist/Ubuntu/mariadb-server-5.5.postinst b/debian/dist/Ubuntu/mariadb-server-5.5.postinst index 68e24a2d833..a0c351194bb 100644 --- a/debian/dist/Ubuntu/mariadb-server-5.5.postinst +++ b/debian/dist/Ubuntu/mariadb-server-5.5.postinst @@ -21,7 +21,7 @@ invoke() { fi } -MYSQL_BOOTSTRAP="/usr/sbin/mysqld --bootstrap --user=mysql --skip-grant-tables --innodb=OFF --pbxt=OFF --default-storage-engine=myisam" +MYSQL_BOOTSTRAP="/usr/sbin/mysqld --bootstrap --user=mysql --skip-grant-tables --loose-innodb=OFF --loose-pbxt=OFF --default-storage-engine=myisam" test_mysql_access() { mysql --no-defaults -u root -h localhost </dev/null >/dev/null 2>&1 diff --git a/debian/mariadb-server-5.5.preinst b/debian/mariadb-server-5.5.preinst index 9a7e337d168..1c48fde2837 100644 --- a/debian/mariadb-server-5.5.preinst +++ b/debian/mariadb-server-5.5.preinst @@ -49,7 +49,7 @@ stop_server() { this_version=5.5 # Abort if an NDB cluster is in use. -if egrep -qi -r '^[^#]*ndb.connectstring|^[:space:]*\[[:space:]*ndb_mgmd' /etc/mysql/; then +if egrep -qi -r '^[^#]*ndb.connectstring|^[[:space:]]*\[[[:space:]]*ndb_mgmd' /etc/mysql/; then db_fset mysql-server/no_upgrade_when_using_ndb seen false || true db_input high mysql-server/no_upgrade_when_using_ndb || true db_go diff --git a/include/wqueue.h b/include/wqueue.h index b3fe3dc8602..e568ab8e91e 100644 --- a/include/wqueue.h +++ b/include/wqueue.h @@ -1,6 +1,22 @@ +/* + Copyright (c) 2007, 2008, Sun Microsystems, Inc, + Copyright (c) 2011, 2012, Monty Program Ab -#ifndef _wqueue_h -#define _wqueue_h + 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 WQUEUE_INCLUDED +#define WQUEUE_INCLUDED #include <my_global.h> #include <my_pthread.h> diff --git a/libmysql/get_password.c b/libmysql/get_password.c index c3428dd2838..a10d112ccd0 100644 --- a/libmysql/get_password.c +++ b/libmysql/get_password.c @@ -71,9 +71,9 @@ void get_tty_password_buff(const char *opt_message, char *to, size_t length) _cputs(opt_message ? opt_message : "Enter password: "); for (;;) { - char tmp; + int tmp; tmp=_getch(); - if (tmp == '\b' || (int) tmp == 127) + if (tmp == '\b' || tmp == 127) { if (pos != to) { @@ -82,15 +82,13 @@ void get_tty_password_buff(const char *opt_message, char *to, size_t length) continue; } } - if (tmp == '\n' || tmp == '\r' || tmp == 3) + if (tmp == -1 || tmp == '\n' || tmp == '\r' || tmp == 3) break; if (iscntrl(tmp) || pos == end) continue; _cputs("*"); - *(pos++) = tmp; + *(pos++) = (char)tmp; } - while (pos != to && isspace(pos[-1]) == ' ') - pos--; /* Allow dummy space at end */ *pos=0; _cputs("\n"); } @@ -137,8 +135,6 @@ static void get_password(char *to,uint length,int fd, my_bool echo) } *(pos++) = tmp; } - while (pos != to && isspace(pos[-1]) == ' ') - pos--; /* Allow dummy space at end */ *pos=0; return; } diff --git a/mysql-test/include/icp_tests.inc b/mysql-test/include/icp_tests.inc index e77cb220375..f412843ded0 100644 --- a/mysql-test/include/icp_tests.inc +++ b/mysql-test/include/icp_tests.inc @@ -852,3 +852,25 @@ SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; +--echo # check "Handler_pushed" status varuiables +CREATE TABLE t1 ( + c1 CHAR(1), + c2 CHAR(1), + KEY (c1) +); + +INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5'); + +flush status; +show status like "Handler_pushed%"; + +SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ; + +show status like "Handler_pushed%"; + +SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ; + +show status like "Handler_pushed%"; + +DROP TABLE t1; + diff --git a/mysql-test/include/wait_until_disconnected.inc b/mysql-test/include/wait_until_disconnected.inc index c274fbbe089..71361682442 100644 --- a/mysql-test/include/wait_until_disconnected.inc +++ b/mysql-test/include/wait_until_disconnected.inc @@ -12,7 +12,7 @@ while (!$mysql_errno) # Strangely enough, the server might return "Too many connections" # while being shutdown, thus 1040 is an "allowed" error. # See BUG#36228. - --error 0,1040,1053,2002,2003,2006,2013 + --error 0,1040,1053,2002,2003,2005,2006,2013 show status; dec $counter; diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index 3c91429f90c..3c9afadfe2f 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -913,6 +913,13 @@ sub collect_one_test_case { $tinfo->{'long_test'}= 1; } + if ( ! $tinfo->{'big_test'} and $::opt_big_test > 1 ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Small test"; + return $tinfo + } + if ( $tinfo->{'need_debug'} && ! $::debug_compiled_binaries ) { $tinfo->{'skip'}= 1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 46c5a3dffbc..28779c045b4 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -585,6 +585,7 @@ sub main { } mtr_report_test($tinfo); push @$completed, $tinfo; + ++$num_tests } mtr_print_line(); @@ -600,7 +601,8 @@ sub main { if ( @$completed != $num_tests) { - mtr_error("Not all tests completed"); + mtr_error("Not all tests completed (only ". scalar(@$completed) . + " of $num_tests)"); } remove_vardir_subs() if $opt_clean_vardir; @@ -1148,7 +1150,7 @@ sub command_line_setup { 'skip-test=s' => \&collect_option, 'do-test=s' => \&collect_option, 'start-from=s' => \&collect_option, - 'big-test' => \$opt_big_test, + 'big-test+' => \$opt_big_test, 'combination=s' => \@opt_combinations, 'skip-combinations' => \&collect_option, 'experimental=s' => \@opt_experimentals, @@ -1943,8 +1945,11 @@ sub collect_mysqld_features { # Put variables into hash if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ ) { - # print "$1=\"$2\"\n"; - $mysqld_variables{$1}= $2; + my $name= $1; + my $value=$2; + $name =~ s/_/-/g; + # print "$name=\"$value\"\n"; + $mysqld_variables{$name}= $value; } else { @@ -1998,8 +2003,11 @@ sub collect_mysqld_features_from_running_server () # Put variables into hash if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ ) { - # print "$1=\"$2\"\n"; - $mysqld_variables{$1}= $2; + my $name= $1; + my $value=$2; + $name =~ s/_/-/g; + # print "$name=\"$value\"\n"; + $mysqld_variables{$name}= $value; } } @@ -4777,9 +4785,9 @@ sub extract_warning_lines ($$) { qr/Failed on request_dump/, qr/Slave: Can't drop database.* database doesn't exist/, qr/Slave: Operation DROP USER failed for 'create_rout_db'/, - qr|Checking table: '\./mtr/test_suppressions'|, + qr|Checking table: '\..mtr.test_suppressions'|, qr|Table \./test/bug53592 has a primary key in InnoDB data dictionary, but not in MySQL|, - qr|mysqld: Table '\./mtr/test_suppressions' is marked as crashed and should be repaired|, + qr|mysqld: Table '\..mtr.test_suppressions' is marked as crashed and should be repaired|, qr|Can't open shared library.*ha_archive|, qr|InnoDB: Error: table 'test/bug39438'|, qr| entry '.*' ignored in --skip-name-resolve mode|, @@ -6362,7 +6370,8 @@ Options to control what test suites or cases to run list of suite names. The default is: "$DEFAULT_SUITES" skip-rpl Skip the replication test cases. - big-test Also run tests marked as "big" + big-test Also run tests marked as "big". Repeat this option + twice to run only "big" tests. staging-run Run a limited number of tests (no slow tests). Used for running staging trees with valgrind. enable-disabled Run also tests marked as disabled diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index b63131fcca6..fbc8e3d28e2 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1562,6 +1562,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 7 drop table t1,t2; CREATE TABLE t1(c1 VARCHAR(33), KEY USING BTREE (c1)); diff --git a/mysql-test/r/derived_opt.result b/mysql-test/r/derived_opt.result index 721d4277775..c5376bee756 100644 --- a/mysql-test/r/derived_opt.result +++ b/mysql-test/r/derived_opt.result @@ -273,4 +273,13 @@ ON alias3.f4 != 0 ) ON alias3.f4 != 0; f4 f4 f2 f4 drop table t1,t2,t3,t4; +# +# LP BUG#910123 MariaDB 5.3.3 causes 1093 error on Drupal +# Fix: force materialization in case of conflict +# +SET optimizer_switch='derived_merge=on'; +CREATE TABLE t1 ( i INT ); +INSERT INTO t1 VALUES ( (SELECT 1 FROM ( SELECT * FROM t1 ) as a) ); +drop table t1; +set optimizer_switch=@save_optimizer_switch; set optimizer_switch=@exit_optimizer_switch; diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result index 587a1dd9e31..4756daaf687 100644 --- a/mysql-test/r/derived_view.result +++ b/mysql-test/r/derived_view.result @@ -80,6 +80,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; select * from (select * from t1 where f1 in (2,3)) tt where f11=2; @@ -93,6 +94,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 12 for merged views create view v1 as select * from t1; @@ -165,6 +167,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; select * from v4 where f2 in (1,3); @@ -178,6 +181,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 12 for materialized derived tables explain for simple derived @@ -229,6 +233,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; select * from t1 join (select * from t2 group by f2) tt on f1=f2; @@ -244,6 +249,7 @@ Handler_read_last 0 Handler_read_next 3 Handler_read_prev 0 Handler_read_rnd 11 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 36 for materialized views drop view v1,v2,v3; @@ -318,6 +324,7 @@ Handler_read_last 0 Handler_read_next 22 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 60 explain showing late materialization flush status; @@ -334,6 +341,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; select * from t1 join v2 on f1=f2; @@ -349,6 +357,7 @@ Handler_read_last 0 Handler_read_next 3 Handler_read_prev 0 Handler_read_rnd 11 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 36 explain extended select * from v1 join v4 on f1=f2; id select_type table type possible_keys key key_len ref rows filtered Extra @@ -443,6 +452,7 @@ Handler_read_last 0 Handler_read_next 2 Handler_read_prev 0 Handler_read_rnd 8 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 39 flush status; merged in merged derived join merged in merged derived @@ -1089,7 +1099,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t system NULL NULL NULL NULL 1 100.00 1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00 1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00 -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: Note 1003 select 6 AS `a`,5 AS `b` from `test`.`t3` where (not(<expr_cache><6,5>(<in_optimizer>((6,5),<exists>(select 7,5 having (trigcond(((<cache>(6) = 7) or isnull(7))) and trigcond(((<cache>(5) = 5) or isnull(5))) and trigcond(<is_not_null_test>(7)) and trigcond(<is_not_null_test>(5)))))))) SELECT t.a,t.b FROM t3 RIGHT JOIN ((SELECT * FROM t1) AS t, t2) ON t2.b != 0 @@ -1103,7 +1113,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00 1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00 1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00 -3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: Note 1003 select 6 AS `a`,5 AS `b` from `test`.`t3` where (not(<expr_cache><6,5>(<in_optimizer>((6,5),<exists>(select 7,5 having (trigcond(((<cache>(6) = 7) or isnull(7))) and trigcond(((<cache>(5) = 5) or isnull(5))) and trigcond(<is_not_null_test>(7)) and trigcond(<is_not_null_test>(5)))))))) SELECT t.a,t.b FROM t3 RIGHT JOIN (v1 AS t, t2) ON t2.b != 0 @@ -1117,7 +1127,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00 1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00 1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00 -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: Note 1003 select 6 AS `a`,5 AS `b` from `test`.`t3` where (not(<expr_cache><6,5>(<in_optimizer>((6,5),<exists>(select 7,5 having (trigcond(((<cache>(6) = 7) or isnull(7))) and trigcond(((<cache>(5) = 5) or isnull(5))) and trigcond(<is_not_null_test>(7)) and trigcond(<is_not_null_test>(5)))))))) DROP VIEW v1; @@ -1800,6 +1810,7 @@ INSERT INTO t2 VALUES (7), (4); CREATE TABLE t1 (b int NOT NULL); INSERT INTO t1 VALUES (5), (7); CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1; +SET @save_optimizer_switch=@@optimizer_switch; SET SESSION optimizer_switch='derived_merge=off'; PREPARE st1 FROM 'SELECT * FROM (SELECT * FROM t2 LEFT JOIN v1 ON t2.a = v1.b) AS t'; @@ -1812,9 +1823,9 @@ a b 7 7 4 NULL DEALLOCATE PREPARE st1; +set SESSION optimizer_switch= @save_optimizer_switch; DROP VIEW v1; DROP TABLE t1,t2; -SET SESSION optimizer_switch='derived_merge=on'; # # LP bug #879939: assertion in ha_maria::enable_indexes # with derived_with_keys=on @@ -1832,6 +1843,7 @@ INSERT INTO t1 VALUES ('USA','Mesquite'), ('USA','Metairie'), ('USA','Miami'); CREATE TABLE t3 (a varchar(35)); INSERT INTO t3 VALUES ('Miami'); +SET @save_optimizer_switch=@@optimizer_switch; SET optimizer_switch = 'derived_with_keys=on'; SET @@tmp_table_size=1024*4; explain SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b; @@ -1855,6 +1867,7 @@ USA Miami Miami USA Miami Miami USA Miami Miami SET @@tmp_table_size=default; +set SESSION optimizer_switch= @save_optimizer_switch; drop table t1,t2,t3; # # BUG#882994: Crash in QUICK_RANGE_SELECT::reset with derived_with_keys @@ -1889,5 +1902,42 @@ ORDER BY CONCAT(alias2.col_varchar_nokey); col_varchar_key pk col_varchar_key col_varchar_nokey set max_heap_table_size= @tmp_882994; drop table t1,t2,t3; +# +# LP bug #917990: Bad estimate of #rows for derived table with LIMIT +# +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES +(8), (3), (4), (7), (9), (5), (1), (2); +SELECT * FROM (SELECT * FROM t1 LIMIT 3) t; +a +8 +3 +4 +EXPLAIN +SELECT * FROM (SELECT * FROM t1 LIMIT 3) t; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 +2 DERIVED t1 ALL NULL NULL NULL NULL 8 +DROP TABLE t1; +# +# LP BUG#921878 incorrect check of items during columns union types +# aggregation for merged derived tables +# +SET @save_optimizer_switch=@@optimizer_switch; +SET SESSION optimizer_switch='derived_merge=on'; +CREATE TABLE t1 ( a ENUM( 'x', 'y' ) ); +insert into t1 values ('x'); +CREATE TABLE t2 LIKE t1; +insert into t1 values ('y'); +CREATE TABLE t3 LIKE t1; +INSERT INTO t3 +SELECT * FROM ( SELECT * FROM t1 ) AS A +UNION SELECT * FROM t2; +select * from t3; +a +x +y +drop table t1,t2,t3; +set SESSION optimizer_switch= @save_optimizer_switch; set optimizer_switch=@exit_optimizer_switch; set join_cache_level=@exit_join_cache_level; diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index c39a226303b..aa93424f2ae 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1825,6 +1825,70 @@ drop table t1; # End of 5.1 tests # +# Bug #904345: MIN/MAX optimization with constant FALSE condition +# +CREATE TABLE t1 (a int NOT NULL, KEY(a)); +INSERT INTO t1 VALUES (10), (8), (11), (7), (15), (12), (9); +CREATE TABLE t2 (a int, b int); +INSERT INTO t2 VALUES +(8,2), (6,9), (8,4), (5,3), (9,1); +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 range a a 4 NULL 4 100.00 Using where; Using index +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` where (<expr_cache><<cache>(1),<cache>(2)>(<in_optimizer>(<cache>((1,2)),<exists>(select 3,4 having (((1 = 3) or isnull(3)) and ((2 = 4) or isnull(4)) and <is_not_null_test>(3) and <is_not_null_test>(4))))) and (`test`.`t1`.`a` < 10)) +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; +MAX(a) +NULL +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1 100.00 +1 PRIMARY t1 range a a 4 NULL 4 100.00 Using where; Using index; Using join buffer (flat, BNL join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where +Warnings: +Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = 2) and (`test`.`t2`.`a` = 1) and (`test`.`t1`.`a` < 10)) +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10; +MAX(a) +NULL +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE RAND()*0<>0 AND a<10; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 range a a 4 NULL 4 100.00 Using where; Using index +Warnings: +Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` where (((rand() * 0) <> 0) and (`test`.`t1`.`a` < 10)) +SELECT MAX(a) FROM t1 WHERE RAND()*0<>0 AND a<10; +MAX(a) +NULL +DROP TABLE t1,t2; +# +# Bug #879860: MIN/MAX for subquery returning empty set +# +CREATE TABLE t1 (a int PRIMARY KEY); +INSERT INTO t1 VALUES (1); +CREATE TABLE t2 (a int NOT NULL); +INSERT INTO t2 VALUES (10); +CREATE TABLE t3 ( a int, b int); +INSERT INTO t3 VALUES (19,1), (20,5); +EXPLAIN EXTENDED +SELECT (SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) FROM t3; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 +2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00 +2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1 100.00 +Warnings: +Note 1276 Field or reference 'test.t3.b' of SELECT #2 was resolved in SELECT #1 +Note 1003 select <expr_cache><`test`.`t3`.`b`>((select min(1) from dual where (10 = `test`.`t3`.`b`))) AS `(SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b)` from `test`.`t3` +SELECT (SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) FROM t3; +(SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) +NULL +NULL +DROP TABLE t1,t2,t3; +# +End of 5.2 tests +# # BUG#46680 - Assertion failed in file item_subselect.cc, # line 305 crashing on HAVING subquery # diff --git a/mysql-test/r/handler_read_last.result b/mysql-test/r/handler_read_last.result index a21e9ed9564..574c3c25ab1 100644 --- a/mysql-test/r/handler_read_last.result +++ b/mysql-test/r/handler_read_last.result @@ -13,6 +13,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 FLUSH STATUS; SELECT a FROM t1 ORDER BY a DESC LIMIT 1; @@ -26,6 +27,7 @@ Handler_read_last 1 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 FLUSH STATUS; SELECT a FROM t1 ORDER BY a LIMIT 3; @@ -41,6 +43,7 @@ Handler_read_last 0 Handler_read_next 2 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 FLUSH STATUS; SELECT a FROM t1 ORDER BY a DESC LIMIT 3; @@ -56,5 +59,6 @@ Handler_read_last 1 Handler_read_next 0 Handler_read_prev 2 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 DROP TABLE t1; diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result index 0f9da2ea3b6..50b0147b6ad 100644 --- a/mysql-test/r/index_merge_innodb.result +++ b/mysql-test/r/index_merge_innodb.result @@ -549,7 +549,7 @@ primary key (pk1, pk2) ); explain select * from t1 where pk1 = 1 and pk2 < 80 and key1=0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,key1 PRIMARY 8 NULL 9 Using index condition; Using where +1 SIMPLE t1 range PRIMARY,key1 PRIMARY 8 NULL 9 Using where select * from t1 where pk1 = 1 and pk2 < 80 and key1=0; pk1 pk2 key1 key2 pktail1ok pktail2ok pktail3bad pktail4bad pktail5bad pk2copy badkey filler1 filler2 1 10 0 0 0 0 0 0 0 10 0 filler-data-10 filler2 diff --git a/mysql-test/r/information_schema-big.result b/mysql-test/r/information_schema-big.result index d0973af1741..3d4fa27859d 100644 --- a/mysql-test/r/information_schema-big.result +++ b/mysql-test/r/information_schema-big.result @@ -54,7 +54,6 @@ TRIGGERS TRIGGER_SCHEMA USER_PRIVILEGES GRANTEE USER_STATISTICS USER VIEWS TABLE_SCHEMA -PBXT_STATISTICS ID XTRADB_ADMIN_COMMAND result_message SELECT t.table_name, c1.column_name FROM information_schema.tables t @@ -107,5 +106,4 @@ TRIGGERS TRIGGER_SCHEMA USER_PRIVILEGES GRANTEE USER_STATISTICS USER VIEWS TABLE_SCHEMA -PBXT_STATISTICS ID XTRADB_ADMIN_COMMAND result_message diff --git a/mysql-test/r/innodb_icp.result b/mysql-test/r/innodb_icp.result index 08238289330..a5029d7508a 100644 --- a/mysql-test/r/innodb_icp.result +++ b/mysql-test/r/innodb_icp.result @@ -167,7 +167,7 @@ WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00' ORDER BY ts DESC LIMIT 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using index condition +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where DROP TABLE t1; # @@ -431,7 +431,7 @@ SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using index condition +2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using where 2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using where; Using index; Using join buffer (flat, BNL join) SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10); @@ -452,7 +452,7 @@ PRIMARY KEY (pk) INSERT INTO t1 VALUES (1,9),(2,7),(3,6),(4,3),(5,1); EXPLAIN SELECT pk, c1 FROM t1 WHERE pk <> 3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using index condition +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where SET SESSION optimizer_switch='index_condition_pushdown=off'; SELECT pk, c1 FROM t1 WHERE pk <> 3; pk c1 @@ -507,8 +507,8 @@ SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1 WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR (t1.pk > 1 AND t2.pk BETWEEN 6 AND 6); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Using where -1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Using join buffer (flat, BNL join) +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where +1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where; Using join buffer (flat, BNL join) SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1 WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR (t1.pk > 1 AND t2.pk BETWEEN 6 AND 6); @@ -680,7 +680,7 @@ EXPLAIN SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Using filesort +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort 1 SIMPLE t2 ref a a 515 test.t1.a 1 Using where SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; @@ -793,7 +793,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t ALL PRIMARY,c NULL NULL NULL 64 Using where 1 PRIMARY t2 ref g g 5 test.t.c 9 Using where 2 DEPENDENT SUBQUERY t1 index PRIMARY d 3 NULL 64 Using where; Using index -2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using index condition; Using where +2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where SELECT COUNT(*) FROM t1 AS t, t2 WHERE c = g AND (EXISTS (SELECT * FROM t1, t2 WHERE a = f AND h <= t.e AND a > t.b) @@ -808,5 +808,61 @@ COUNT(*) 1478 SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; +# check "Handler_pushed" status varuiables +CREATE TABLE t1 ( +c1 CHAR(1), +c2 CHAR(1), +KEY (c1) +); +INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5'); +flush status; +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 +SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +DROP TABLE t1; +# +# BUG#920132: Assert trx->n_active_thrs == 1 failed at que0que.c line 1050 +# +CREATE TABLE t1 ( a INT ) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (7),(7); +CREATE TABLE t2 ( b VARCHAR(1) ); +INSERT INTO t2 VALUES ('j'),('v'); +CREATE TABLE t3 ( +c INT, d VARCHAR(1), e VARCHAR(1), +KEY (d,c) +) ENGINE=InnoDB; +INSERT INTO t3 +VALUES (6,'w','w'), +(1,'v','v'),(7,'s','s'),(4,'l','l'), +(7,'y','y'),(0,'c','c'),(2,'i','i'), +(9,'h','h'),(4,'q','q'),(0,'a','a'), +(9,'v','v'),(1,'u','u'),(3,'s','s'), +(8,'z','z'),(1,'h','h'),(8,'p','p'), +(6,'e','e'),(3,'i','i'),(6,'y','y'); +SELECT * +FROM t1 INNER JOIN t2 INNER JOIN t3 +ON d = b +WHERE +NOT EXISTS ( SELECT * FROM t3 ) +OR a = c +ORDER BY e; +a b c d e +DROP TABLE t1,t2,t3; set optimizer_switch=@innodb_icp_tmp; set storage_engine= @save_storage_engine; diff --git a/mysql-test/r/innodb_mrr_cpk.result b/mysql-test/r/innodb_mrr_cpk.result index 81536f2a43b..90f59b96e61 100644 --- a/mysql-test/r/innodb_mrr_cpk.result +++ b/mysql-test/r/innodb_mrr_cpk.result @@ -82,7 +82,7 @@ insert into t2 values ('a-1010=A', 1010), ('a-1030=A', 1030), ('a-1020=A', 1020) explain select * from t1, t2 where t1.a=t2.a and t1.b=t2.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where -1 SIMPLE t1 eq_ref PRIMARY PRIMARY 30 test.t2.a,test.t2.b 1 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered scan +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 30 test.t2.a,test.t2.b 1 Using where; Using join buffer (flat, BKA join); Key-ordered scan select * from t1, t2 where t1.a=t2.a and t1.b=t2.b; a b filler a b a-1010=A 1010 filler a-1010=A 1010 @@ -91,7 +91,7 @@ a-1030=A 1030 filler a-1030=A 1030 explain select * from t1, t2 where t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where -1 SIMPLE t1 ref PRIMARY PRIMARY 26 test.t2.a 1 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered scan +1 SIMPLE t1 ref PRIMARY PRIMARY 26 test.t2.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered scan select * from t1, t2 where t1.a=t2.a; a b filler a b a-1010=A 1010 filler a-1010=A 1010 @@ -133,7 +133,7 @@ set join_cache_level=6; explain select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where -1 SIMPLE t1 ref PRIMARY PRIMARY 4 test.t2.a 1 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered scan +1 SIMPLE t1 ref PRIMARY PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered scan select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100; a b c filler a b set optimizer_switch='index_condition_pushdown=off'; diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index 538d6ddd0fd..04754375103 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -698,6 +698,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 1 DROP TABLE t1; CREATE TABLE t1 ( diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index d8230826048..d826fbe2aa7 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -861,6 +861,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 5 drop table t1, t2, t3; create table t1 (a int); @@ -1271,6 +1272,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 1 DROP TABLE t1, t2; End of 5.1 tests diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index 07ceb573f85..db9a3b7090e 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -3506,6 +3506,7 @@ insert into t2 values (2,1, 'qwerty'),(2,2, 'qwerty'),(2,3, 'qwerty'), insert into t2 values (3,1, 'qwerty'),(3,4, 'qwerty'); insert into t2 values (4,1, 'qwerty'),(4,2, 'qwerty'),(4,3, 'qwerty'), (4,4, 'qwerty'); +flush status; set join_cache_level=5; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; @@ -3519,6 +3520,10 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 20 +Handler_pushed_index_cond_filtered 16 set join_cache_level=6; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; @@ -3532,6 +3537,10 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 40 +Handler_pushed_index_cond_filtered 32 set join_cache_level=7; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; @@ -3545,6 +3554,10 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 60 +Handler_pushed_index_cond_filtered 48 set join_cache_level=8; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; @@ -3558,6 +3571,10 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 80 +Handler_pushed_index_cond_filtered 64 drop table t1,t2; set join_cache_level=default; # @@ -5392,4 +5409,184 @@ x 5 5 4 SET join_cache_level = DEFAULT; SET optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3,t4; +# +# Bug#53305 Duplicate weedout + join buffer (join cache --level=7,8) +# +create table t1 (uid int, fid int, index(uid)); +insert into t1 values +(1,1), (1,2), (1,3), (1,4), +(2,5), (2,6), (2,7), (2,8), +(3,1), (3,2), (3,9); +create table t2 (uid int primary key, name varchar(128), index(name)); +insert into t2 values +(1, "A"), (2, "B"), (3, "C"), (4, "D"), (5, "E"), +(6, "F"), (7, "G"), (8, "H"), (9, "I"); +create table t3 (uid int, fid int, index(uid)); +insert into t3 values +(1,1), (1,2), (1,3),(1,4), +(2,5), (2,6), (2,7), (2,8), +(3,1), (3,2), (3,9); +set @tmp_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch='semijoin=on'; +set optimizer_switch='materialization=off'; +set optimizer_switch='loosescan=off,firstmatch=off'; +set optimizer_switch='mrr_sort_keys=off'; +set join_cache_level=7; +create table t4 (uid int primary key, name varchar(128), index(name)); +insert into t4 values +(1, "A"), (2, "B"), (3, "C"), (4, "D"), (5, "E"), +(6, "F"), (7, "G"), (8, "H"), (9, "I"); +explain select name from t2, t1 +where t1.uid in (select t4.uid from t4, t3 where t3.uid=1 and t4.uid=t3.fid) +and t2.uid=t1.fid; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ref uid uid 5 const 4 Using where; Start temporary +1 PRIMARY t4 eq_ref PRIMARY PRIMARY 4 test.t3.fid 1 Using index +1 PRIMARY t1 ALL uid NULL NULL NULL 11 Using where; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.fid 1 Using join buffer (flat, BKAH join); Rowid-ordered scan +select name from t2, t1 +where t1.uid in (select t4.uid from t4, t3 where t3.uid=1 and t4.uid=t3.fid) +and t2.uid=t1.fid; +name +A +A +B +B +C +D +E +F +G +H +I +set join_cache_level = default; +set optimizer_switch=@tmp_optimizer_switch; +drop table t1,t2,t3,t4; +# +# Bug#50358 - semijoin execution of subquery with outerjoin +# emplying join buffer +# +CREATE TABLE t1 (i int); +CREATE TABLE t2 (i int); +CREATE TABLE t3 (i int); +INSERT INTO t1 VALUES (1), (2); +INSERT INTO t2 VALUES (6); +INSERT INTO t3 VALUES (1), (2); +set @tmp_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch='semijoin=on'; +set optimizer_switch='materialization=on'; +set join_cache_level=0; +EXPLAIN +SELECT * FROM t1 WHERE t1.i IN +(SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2 +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 1 Using where +SELECT * FROM t1 WHERE t1.i IN +(SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i); +i +1 +2 +set join_cache_level=2; +EXPLAIN +SELECT * FROM t1 WHERE t1.i IN +(SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2 +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join) +SELECT * FROM t1 WHERE t1.i IN +(SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i); +i +1 +2 +set join_cache_level = default; +set optimizer_switch=@tmp_optimizer_switch; +DROP TABLE t1,t2,t3; +# +# Bug #12546542: missing row with semijoin=off + join cache +# (LP bug #922971) +# +CREATE TABLE t1 (a varchar(1024)); +INSERT INTO t1 VALUES ('v'), ('we'); +CREATE TABLE t2 ( +a varchar(1024) CHARACTER SET utf8 DEFAULT NULL, b int, c int +); +INSERT INTO t2 VALUES ('we',4,NULL), ('v',1305673728,6); +CREATE TABLE t3 (b int, c int); +INSERT INTO t3 VALUES (4,4); +set @tmp_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=off'; +set optimizer_switch='materialization=off'; +set join_cache_level=0; +EXPLAIN +SELECT * FROM t1 +WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b +WHERE t2.c < 10 OR t3.c > 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 1 Using where +SELECT * FROM t1 +WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b +WHERE t2.c < 10 OR t3.c > 1); +a +v +we +set join_cache_level=2; +EXPLAIN +SELECT * FROM t1 +WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b +WHERE t2.c < 10 OR t3.c > 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join) +SELECT * FROM t1 +WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b +WHERE t2.c < 10 OR t3.c > 1); +a +v +we +set join_cache_level = default; +set optimizer_switch=@tmp_optimizer_switch; +DROP TABLE t1,t2,t3; +# +# Bug #925985: LEFT JOIN with optimize_join_buffer_size=off + +# join_buffer_size > join_buffer_space_limit +# +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (5), (3); +CREATE TABLE t2 (a int, b int); +INSERT INTO t2 VALUES +(3,30), (1,10), (7,70), (2,20), +(3,31), (1,11), (7,71), (2,21), +(3,32), (1,12), (7,72), (2,22); +CREATE TABLE t3 (b int, c int); +INSERT INTO t3 VALUES (32, 302), (42,400), (30,300); +set @tmp_optimizer_switch=@@optimizer_switch; +set optimizer_switch='optimize_join_buffer_size=off'; +set join_buffer_space_limit=4096; +set join_buffer_size=4096*2; +set join_cache_level=2; +set optimizer_switch='outer_join_with_cache=on'; +EXPLAIN +SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 +1 SIMPLE t2 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (incremental, BNL join) +SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a; +a a b b c +3 3 30 30 300 +3 3 31 NULL NULL +3 3 32 32 302 +set join_buffer_space_limit=default; +set join_buffer_size=default; +set join_cache_level=default; +set optimizer_switch=@tmp_optimizer_switch; +DROP TABLE t1,t2,t3; set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 16913864f5d..842ac2e81cd 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -1245,6 +1245,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 6 DROP TABLE t1,t2; CREATE TABLE t1 (c int PRIMARY KEY, e int NOT NULL); @@ -1747,6 +1748,7 @@ Handler_read_last 0 Handler_read_next 5 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 1048581 flush status; select sum(t3.b) from t2 left join t3 on t3.a=t2.a and t2.a <> 10; @@ -1760,6 +1762,7 @@ Handler_read_last 0 Handler_read_next 5 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 1048581 drop table t1,t2,t3; # diff --git a/mysql-test/r/join_outer_innodb.result b/mysql-test/r/join_outer_innodb.result index 749cb2ab212..5a99cb83b90 100644 --- a/mysql-test/r/join_outer_innodb.result +++ b/mysql-test/r/join_outer_innodb.result @@ -52,3 +52,11 @@ pk DROP TABLE t1,t2; # End BUG#58456 +CREATE TABLE t1(a int, b int, KEY (a), PRIMARY KEY (b)) ENGINE=InnoDB; +CREATE TABLE t2 (b int, PRIMARY KEY (b)); +INSERT INTO t2 VALUES (4),(9); +SELECT STRAIGHT_JOIN t1.a FROM t1 RIGHT JOIN t2 ON t1.b = t2.b +WHERE (t1.b NOT BETWEEN 1 AND 7 OR t1.a IS NULL AND t1.b = t2.b) AND t2.b = 4 +GROUP BY 1; +a +DROP TABLE t1,t2; diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result index 7605af40a6f..046c758a751 100644 --- a/mysql-test/r/join_outer_jcl6.result +++ b/mysql-test/r/join_outer_jcl6.result @@ -1256,6 +1256,7 @@ Handler_read_last 0 Handler_read_next 9 Handler_read_prev 0 Handler_read_rnd 3 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 6 DROP TABLE t1,t2; CREATE TABLE t1 (c int PRIMARY KEY, e int NOT NULL); @@ -1758,6 +1759,7 @@ Handler_read_last 0 Handler_read_next 5 Handler_read_prev 0 Handler_read_rnd 5 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 1048581 flush status; select sum(t3.b) from t2 left join t3 on t3.a=t2.a and t2.a <> 10; @@ -1771,6 +1773,7 @@ Handler_read_last 0 Handler_read_next 5 Handler_read_prev 0 Handler_read_rnd 5 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 1048581 drop table t1,t2,t3; # diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result index a1feb3ad40d..fad980c810c 100644 --- a/mysql-test/r/key_cache.result +++ b/mysql-test/r/key_cache.result @@ -385,6 +385,22 @@ Variable_name Value key_cache_block_size 1536 SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size; DROP TABLE t1; +# +# Bug#12361113: crash when load index into cache +# +# Note that this creates an empty disabled key cache! +SET GLOBAL key_cache_none.key_cache_block_size = 1024; +CREATE TABLE t1 (a INT, b INTEGER NOT NULL, KEY (b) ) ENGINE = MYISAM; +INSERT INTO t1 VALUES (1, 1); +CACHE INDEX t1 in key_cache_none; +ERROR HY000: Unknown key cache 'key_cache_none' +# The bug crashed the server at LOAD INDEX below. Now it will succeed +# since the default cache is used due to CACHE INDEX failed for +# key_cache_none. +LOAD INDEX INTO CACHE t1; +Table Op Msg_type Msg_text +test.t1 preload_keys status OK +DROP TABLE t1; set global key_buffer_size=@save_key_buffer_size; set global key_cache_block_size=@save_key_cache_block_size; select @@key_buffer_size; diff --git a/mysql-test/r/maria_icp.result b/mysql-test/r/maria_icp.result index 5739bbaa90c..1b777d63578 100644 --- a/mysql-test/r/maria_icp.result +++ b/mysql-test/r/maria_icp.result @@ -814,5 +814,32 @@ COUNT(*) 1478 SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; +# check "Handler_pushed" status varuiables +CREATE TABLE t1 ( +c1 CHAR(1), +c2 CHAR(1), +KEY (c1) +); +INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5'); +flush status; +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 +SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +DROP TABLE t1; set storage_engine= @save_storage_engine; set optimizer_switch=@maria_icp_tmp; diff --git a/mysql-test/r/myisam_icp.result b/mysql-test/r/myisam_icp.result index e4343a21606..a9b0dba3fb9 100644 --- a/mysql-test/r/myisam_icp.result +++ b/mysql-test/r/myisam_icp.result @@ -812,6 +812,33 @@ COUNT(*) 1478 SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; +# check "Handler_pushed" status varuiables +CREATE TABLE t1 ( +c1 CHAR(1), +c2 CHAR(1), +KEY (c1) +); +INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5'); +flush status; +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 +SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +DROP TABLE t1; drop table if exists t0, t1, t1i, t1m; # # BUG#826935 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed @@ -887,4 +914,19 @@ Warning 1292 Truncated incorrect DOUBLE value: 'c' Warning 1292 Truncated incorrect DOUBLE value: 'c' SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2,t3,t4; +# +# BUG#933412: Server crashes in _mi_put_key_in_record on KILL QUERY with ICP, STRAIGHT_JOIN +# +CREATE TABLE t1 ( +b INT, +c VARCHAR(1) NOT NULL, +d DATETIME, +KEY (c, b) +) ENGINE=MyISAM; +# INSERT some data +CREATE TABLE t2 ( a INT ) ENGINE=MyISAM; +INSERT INTO t2 VALUES +(7),(3),(7),(3); +# Now run a number of ICP queries while trying to kill them +DROP TABLE t1,t2; set optimizer_switch=@myisam_icp_tmp; diff --git a/mysql-test/r/myisam_mrr.result b/mysql-test/r/myisam_mrr.result index 9dd3602bab7..01d3e6aeb5d 100644 --- a/mysql-test/r/myisam_mrr.result +++ b/mysql-test/r/myisam_mrr.result @@ -557,4 +557,66 @@ COUNT(alias2.f2) set @@join_cache_level= @tmp_730133_jcl; set @@optimizer_switch= @tmp_730133_os; drop table t1; +# +# Test of MRR handler counters +# +flush status; +show status like 'Handler_mrr%'; +Variable_name Value +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (a int, b int, filler char(200), key(a)); +insert into t1 +select A.a+10*B.a+100*C.a+1000*D.a, 123,'filler' from t0 A, t0 B, t0 C, t0 D; +explain select sum(b) from t1 where a < 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 5 NULL 8 Using index condition; Rowid-ordered scan +# This should show one MRR scan and no re-fills: +flush status; +select sum(b) from t1 where a < 10; +sum(b) +1230 +show status like 'handler_mrr%'; +Variable_name Value +set @mrr_buffer_size_save= @@mrr_buffer_size; +set mrr_buffer_size=128; +explain select sum(b) from t1 where a < 1600; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 5 NULL 1380 Using index condition; Rowid-ordered scan +# This should show one MRR scan and one extra rowid sort: +flush status; +select sum(b) from t1 where a < 1600; +sum(b) +196800 +show status like 'handler_mrr%'; +Variable_name Value +set @@mrr_buffer_size= @mrr_buffer_size_save; +#Now, let's check BKA: +set @join_cache_level_save= @@join_cache_level; +set @join_buffer_size_save= @@join_buffer_size; +set join_cache_level=6; +explain select sum(t1.b) from t0,t1 where t0.a=t1.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using where +1 SIMPLE t1 ref a a 5 test.t0.a 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +flush status; +select sum(t1.b) from t0,t1 where t0.a=t1.a; +sum(t1.b) +1230 +show status like 'handler_mrr%'; +Variable_name Value +set join_buffer_size=10; +explain select sum(t1.b) from t0,t1 where t0.a=t1.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using where +1 SIMPLE t1 ref a a 5 test.t0.a 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +flush status; +select sum(t1.b) from t0,t1 where t0.a=t1.a; +sum(t1.b) +1230 +show status like 'handler_mrr%'; +Variable_name Value +set join_cache_level= @join_cache_level_save; +set join_buffer_size= @join_buffer_size_save; +drop table t0, t1; set optimizer_switch= @myisam_mrr_tmp; diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index ca9d3a20404..ab707ceef80 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -191,6 +191,7 @@ CREATE TABLE `я` (a INT) engine=myisam; SET NAMES DEFAULT; call mtr.add_suppression("@003f.frm' \\(errno: 22\\)"); mysqlcheck --default-character-set="latin1" --databases test +call mtr.add_suppression("Can't find file: '..test.@003f.frm'"); test.? Error : Table doesn't exist status : Operation failed diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 022523d4749..3db422657e3 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -4770,79 +4770,11 @@ INSERT INTO b12809202_db.t2 VALUES (1), (2), (3); -- Retrieving table structure for table t1... -- Sending SELECT query... -- Retrieving rows... --- --- Host: localhost Database: b12809202_db --- ------------------------------------------------------ - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- --- Table structure for table `t1` --- - -DROP TABLE IF EXISTS `t1`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `t1` ( - `c1` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `t1` --- - -LOCK TABLES `t1` WRITE; -/*!40000 ALTER TABLE `t1` DISABLE KEYS */; -INSERT INTO `t1` VALUES (1),(2),(3); -- Retrieving table structure for table t2... -- Sending SELECT query... -- Retrieving rows... -/*!40000 ALTER TABLE `t1` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `t2` --- - -DROP TABLE IF EXISTS `t2`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `t2` ( - `c1` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `t2` --- - -LOCK TABLES `t2` WRITE; -/*!40000 ALTER TABLE `t2` DISABLE KEYS */; -INSERT INTO `t2` VALUES (1),(2),(3); -/*!40000 ALTER TABLE `t2` ENABLE KEYS */; -UNLOCK TABLES; -- Disconnecting from localhost... -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed #### Dump ends here #### DROP TABLE b12809202_db.t1; DROP TABLE b12809202_db.t2; diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result index 4e28f73caad..35c6ebe1442 100644 --- a/mysql-test/r/null_key.result +++ b/mysql-test/r/null_key.result @@ -428,6 +428,7 @@ Handler_read_last 0 Handler_read_next 2 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 5 DROP TABLE t1,t2,t3,t4; CREATE TABLE t1 ( diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 270e74ddf52..d320b5b669f 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -1759,3 +1759,57 @@ i1 i2 4 4 5 5 DROP TABLE t1, t2, t3; +# +# Fix of LP BUG#793589 Wrong result with double ORDER BY +# +CREATE TABLE t1 ( b int) ; +INSERT INTO t1 VALUES (8),(9); +CREATE TABLE t2 ( a int, b int, PRIMARY KEY (a)) ; +INSERT INTO t2 VALUES (6,7),(7,7),(8,1),(9,7),(10,1),(11,5),(12,2),(13,0),(14,1),(15,8),(16,1),(17,1),(18,9),(19,1),(20,5); +SELECT t2.b AS field1 FROM t1, t2 WHERE t1.b = t2.a GROUP BY field1 ORDER BY t1.b, field1; +field1 +1 +7 +SELECT t2.b, t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b, t2.b; +b b +1 8 +7 9 +SELECT t2.b,t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +b b +1 8 +7 9 +SELECT t2.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +b +1 +7 +# field1 removed from ORDER BY +explain extended +SELECT t2.b AS field1 FROM t1, t2 WHERE t1.b = t2.a GROUP BY field1 ORDER BY t1.b, field1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 +Warnings: +Note 1003 select `test`.`t2`.`b` AS `field1` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`) group by `test`.`t2`.`b` order by `test`.`t1`.`b` +explain extended +SELECT t2.b, t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b, t2.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 +Warnings: +Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t1`.`b` AS `b` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`) group by `test`.`t2`.`b` order by `test`.`t1`.`b` +explain extended +SELECT t2.b,t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 +Warnings: +Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t1`.`b` AS `b` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`) group by `test`.`t2`.`b` order by `test`.`t1`.`b` +explain extended +SELECT t2.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 +Warnings: +Note 1003 select `test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`) group by `test`.`t2`.`b` order by `test`.`t1`.`b` +drop table t1,t2; +End of 5.2 tests diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 2e90bf8e27b..7c38fa18faa 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -521,6 +521,7 @@ Handler_read_last 0 Handler_read_next 4 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 EXPLAIN PARTITIONS SELECT c1 FROM t2 WHERE (c1 > 10 AND c1 < 13) OR (c1 > 17 AND c1 < 20); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -540,6 +541,7 @@ Handler_read_last 0 Handler_read_next 4 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 DROP TABLE t1,t2; CREATE TABLE `t1` ( @@ -571,6 +573,7 @@ Handler_read_last 0 Handler_read_next 2 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 EXPLAIN PARTITIONS SELECT c1 FROM t2 WHERE (c1 > 2 AND c1 < 5); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -588,6 +591,7 @@ Handler_read_last 0 Handler_read_next 2 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 EXPLAIN PARTITIONS SELECT c1 FROM t1 WHERE (c1 > 12 AND c1 < 15); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -605,6 +609,7 @@ Handler_read_last 0 Handler_read_next 2 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 EXPLAIN PARTITIONS SELECT c1 FROM t2 WHERE (c1 > 12 AND c1 < 15); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -622,6 +627,7 @@ Handler_read_last 0 Handler_read_next 2 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 DROP TABLE t1,t2; create table t1 (a int) partition by list ((a/3)*10 div 1) diff --git a/mysql-test/r/partition_key_cache.result b/mysql-test/r/partition_key_cache.result index 653d2f29d54..f1b174ca249 100644 --- a/mysql-test/r/partition_key_cache.result +++ b/mysql-test/r/partition_key_cache.result @@ -397,6 +397,33 @@ test.t1 assign_to_keycache error Subpartition sp0 returned error test.t1 assign_to_keycache Error Key 'inx_b' doesn't exist in table 't1' test.t1 assign_to_keycache status Operation failed DROP TABLE t1,t2; +# +# Bug#12361113: crash when load index into cache +# +# Note that this creates an empty disabled key cache! +SET GLOBAL key_cache_none.key_cache_block_size = 1024; +CREATE TABLE t1 (a INT, b INTEGER NOT NULL, KEY (b) ) +ENGINE = MYISAM +PARTITION BY HASH(a) PARTITIONS 2; +INSERT INTO t1 VALUES (1, 1); +CACHE INDEX t1 IN key_cache_none; +ERROR HY000: Unknown key cache 'key_cache_none' +CACHE INDEX t1 PARTITION (p0) IN key_cache_none; +ERROR HY000: Unknown key cache 'key_cache_none' +CACHE INDEX t1 PARTITION (p1) IN key_cache_none; +ERROR HY000: Unknown key cache 'key_cache_none' +CACHE INDEX t1 PARTITION (p0) KEY (`b`) IN key_cache_none; +ERROR HY000: Unknown key cache 'key_cache_none' +CACHE INDEX t1 PARTITION (p1) KEY (`b`) IN key_cache_none; +ERROR HY000: Unknown key cache 'key_cache_none' +# The bug crashed the server at LOAD INDEX below. Now it will succeed +# since the default cache is used due to CACHE INDEX failed for +# key_cache_none. +LOAD INDEX INTO CACHE t1; +Table Op Msg_type Msg_text +test.t1 preload_keys status OK +DROP TABLE t1; +# Clean up SET GLOBAL hot_cache.key_buffer_size = 0; SET GLOBAL warm_cache.key_buffer_size = 0; SET @@global.cold_cache.key_buffer_size = 0; diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result index eb0849e2cad..32c0cd34942 100644 --- a/mysql-test/r/partition_pruning.result +++ b/mysql-test/r/partition_pruning.result @@ -2968,7 +2968,10 @@ flush status; delete from t2 where b > 5; show status like 'Handler_read_rnd_next'; Variable_name Value -Handler_read_rnd_next 1215 +Handler_read_rnd_next 815 +show status like 'Handler_read_rnd_deleted'; +Variable_name Value +Handler_read_rnd_deleted 400 show status like 'Handler_read_key'; Variable_name Value Handler_read_key 0 @@ -2982,7 +2985,10 @@ flush status; delete from t2 where b < 5 or b > 3; show status like 'Handler_read_rnd_next'; Variable_name Value -Handler_read_rnd_next 1215 +Handler_read_rnd_next 515 +show status like 'Handler_read_rnd_deleted'; +Variable_name Value +Handler_read_rnd_deleted 700 show status like 'Handler_read_key'; Variable_name Value Handler_read_key 0 diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 7d793f16c1a..b4a09091aa6 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -3790,6 +3790,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; execute st; @@ -3803,6 +3804,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; select * from t1 use index() where a=3; @@ -3816,6 +3818,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 8 flush status; execute st; @@ -3829,6 +3832,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 deallocate prepare st; drop table t1; diff --git a/mysql-test/r/ps_11bugs.result b/mysql-test/r/ps_11bugs.result index f9f0525646d..56894302505 100644 --- a/mysql-test/r/ps_11bugs.result +++ b/mysql-test/r/ps_11bugs.result @@ -121,8 +121,8 @@ insert into t1 values (1); explain select * from t1 where 3 in (select (1+1) union select 1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used -3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL select * from t1 where 3 in (select (1+1) union select 1); a diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index a6b48403029..70ab2207e89 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -1769,6 +1769,21 @@ SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk; pk i4 pk i4 DROP TABLE t1; End of 5.1 tests +# +# LP Bug #533117: Wrong use_count in SEL_ARG trees +# (Bug #58731) +# +create table t1 (a int, b int, c int, key idx (a,b,c)); +insert into t1 values (0,0,0), (2,2,0), (1,1,1), (2,2,1); +explain +select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range idx idx 5 NULL 3 Using where; Using index +select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; +a b c +2 2 0 +2 2 1 +drop table t1; create table t1 (f1 datetime, key (f1)); insert into t1 values ('2000-03-09 15:56:59'),('2000-05-05 23:24:28'),('2000-06-13 13:12:06'); select min(f1) from t1 where f1 >= '2006-05-25 07:00:20' and f1 between '2003-11-23 10:00:09' and '2010-01-01 01:01:01' and f1 > '2001-01-01 01:01:01'; diff --git a/mysql-test/r/range_mrr_icp.result b/mysql-test/r/range_mrr_icp.result index 5966785c7c3..f52bdbdc587 100644 --- a/mysql-test/r/range_mrr_icp.result +++ b/mysql-test/r/range_mrr_icp.result @@ -1771,6 +1771,21 @@ SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk; pk i4 pk i4 DROP TABLE t1; End of 5.1 tests +# +# LP Bug #533117: Wrong use_count in SEL_ARG trees +# (Bug #58731) +# +create table t1 (a int, b int, c int, key idx (a,b,c)); +insert into t1 values (0,0,0), (2,2,0), (1,1,1), (2,2,1); +explain +select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range idx idx 5 NULL 3 Using where; Using index +select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; +a b c +2 2 0 +2 2 1 +drop table t1; create table t1 (f1 datetime, key (f1)); insert into t1 values ('2000-03-09 15:56:59'),('2000-05-05 23:24:28'),('2000-06-13 13:12:06'); select min(f1) from t1 where f1 >= '2006-05-25 07:00:20' and f1 between '2003-11-23 10:00:09' and '2010-01-01 01:01:01' and f1 > '2001-01-01 01:01:01'; diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result index 57862ded4f2..c42f80f0e85 100644 --- a/mysql-test/r/range_vs_index_merge_innodb.result +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -328,15 +328,15 @@ ID Name Country Population EXPLAIN SELECT * FROM City WHERE (ID < 10) OR (ID BETWEEN 100 AND 110); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 20 Using index condition; Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 20 Using where EXPLAIN SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 100 AND 200); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 200 Using index condition; Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 200 Using where EXPLAIN SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1500); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 1198 Using index condition; Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 1198 Using where EXPLAIN SELECT * FROM City WHERE Country > 'A' AND Country < 'ARG'; id select_type table type possible_keys key key_len ref rows Extra @@ -355,7 +355,7 @@ WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 20 Using index condition; Using where +1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 20 Using where EXPLAIN SELECT * FROM City WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) @@ -369,7 +369,7 @@ WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 200) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 200 Using index condition; Using where +1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 200 Using where SELECT * FROM City USE INDEX () WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND @@ -601,11 +601,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3400 AND 3800; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 400 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 400 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where EXPLAIN SELECT * FROM City WHERE Name LIKE 'P%'; id select_type table type possible_keys key key_len ref rows Extra @@ -765,27 +765,27 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 4025 AND 4035; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 4028 AND 4032; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 5 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 5 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3500 AND 3800; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 300 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 300 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 4000 AND 4300; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 80 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 80 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 250 and 260 ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where EXPLAIN SELECT * FROM City WHERE (Population > 101000 AND Population < 102000); id select_type table type possible_keys key key_len ref rows Extra @@ -1422,7 +1422,7 @@ SELECT * FROM t1 WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND (t1.c=0 OR t1.a=500); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,idx PRIMARY 4 NULL 1 Using index condition; Using where +1 SIMPLE t1 range PRIMARY,idx PRIMARY 4 NULL 1 Using where SELECT * FROM t1 WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND (t1.c=0 OR t1.a=500); diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 7f035ca749a..d2e3594dfc6 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2783,10 +2783,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away explain select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 range key1 key1 5 NULL 3 Using where; Using index select max(key1) from t1 where key1 <= 0.6158; max(key1) 0.6158000230789185 @@ -2805,10 +2805,10 @@ max(key1) min(key2) 0.6158000230789185 1.3761999607086182 select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; max(key1) -0.6158000230789185 +0.38449999690055847 select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; min(key1) -0.37619999051094055 +0.38449999690055847 DROP TABLE t1,t2; CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL); INSERT INTO t1 VALUES (10); @@ -4346,6 +4346,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 6 DROP TABLE t1, t2; CREATE TABLE t1 (f1 bigint(20) NOT NULL default '0', diff --git a/mysql-test/r/select_jcl6.result b/mysql-test/r/select_jcl6.result index 54eed1ebaae..f5aa02fe94c 100644 --- a/mysql-test/r/select_jcl6.result +++ b/mysql-test/r/select_jcl6.result @@ -2794,10 +2794,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away explain select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 range key1 key1 5 NULL 3 Using where; Using index select max(key1) from t1 where key1 <= 0.6158; max(key1) 0.6158000230789185 @@ -2816,10 +2816,10 @@ max(key1) min(key2) 0.6158000230789185 1.3761999607086182 select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; max(key1) -0.6158000230789185 +0.38449999690055847 select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; min(key1) -0.37619999051094055 +0.38449999690055847 DROP TABLE t1,t2; CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL); INSERT INTO t1 VALUES (10); @@ -4357,7 +4357,8 @@ Handler_read_last 0 Handler_read_next 10 Handler_read_prev 0 Handler_read_rnd 10 -Handler_read_rnd_next 7 +Handler_read_rnd_deleted 1 +Handler_read_rnd_next 6 DROP TABLE t1, t2; CREATE TABLE t1 (f1 bigint(20) NOT NULL default '0', f2 int(11) NOT NULL default '0', diff --git a/mysql-test/r/select_pkeycache.result b/mysql-test/r/select_pkeycache.result index 7f035ca749a..d2e3594dfc6 100644 --- a/mysql-test/r/select_pkeycache.result +++ b/mysql-test/r/select_pkeycache.result @@ -2783,10 +2783,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away explain select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 range key1 key1 5 NULL 3 Using where; Using index select max(key1) from t1 where key1 <= 0.6158; max(key1) 0.6158000230789185 @@ -2805,10 +2805,10 @@ max(key1) min(key2) 0.6158000230789185 1.3761999607086182 select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; max(key1) -0.6158000230789185 +0.38449999690055847 select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; min(key1) -0.37619999051094055 +0.38449999690055847 DROP TABLE t1,t2; CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL); INSERT INTO t1 VALUES (10); @@ -4346,6 +4346,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 6 DROP TABLE t1, t2; CREATE TABLE t1 (f1 bigint(20) NOT NULL default '0', diff --git a/mysql-test/r/single_delete_update.result b/mysql-test/r/single_delete_update.result index 72419c6ec9d..d4534a2c2d8 100644 --- a/mysql-test/r/single_delete_update.result +++ b/mysql-test/r/single_delete_update.result @@ -29,6 +29,7 @@ Handler_read_last 0 Handler_read_next 4 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 FLUSH STATUS; DELETE FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5; @@ -46,6 +47,7 @@ Handler_read_last 0 Handler_read_next 4 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i; a i @@ -80,6 +82,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 FLUSH STATUS; DELETE FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5; @@ -97,6 +100,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 5 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i; a i @@ -128,6 +132,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 FLUSH STATUS; DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; @@ -145,6 +150,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 1 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 ## should be 5 (previous LIMIT) SELECT 1 - COUNT(*) FROM t2 WHERE b = 10; @@ -180,6 +186,7 @@ Handler_read_last 0 Handler_read_next 4 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 FLUSH STATUS; DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; @@ -197,6 +204,7 @@ Handler_read_last 0 Handler_read_next 4 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 ## should be 5 (previous LIMIT) SELECT 257 - COUNT(*) FROM t2 WHERE b = 10; @@ -226,6 +234,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 FLUSH STATUS; DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; @@ -243,6 +252,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 1 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 SELECT * FROM t2 WHERE b = 10 ORDER BY a, c; a b c d @@ -270,6 +280,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 1 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 FLUSH STATUS; DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5; @@ -287,6 +298,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 1 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 SELECT * FROM t2 WHERE b = 10 ORDER BY a, c; a b c d @@ -317,6 +329,7 @@ Handler_read_last 0 Handler_read_next 7 Handler_read_prev 0 Handler_read_rnd 4 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 EXPLAIN EXTENDED SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1; id select_type table type possible_keys key key_len ref rows filtered Extra @@ -339,6 +352,7 @@ Handler_read_last 0 Handler_read_next 7 Handler_read_prev 0 Handler_read_rnd 8 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1; i key1 key2 @@ -375,6 +389,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 4 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 FLUSH STATUS; DELETE FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i DESC LIMIT 5; @@ -392,6 +407,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 4 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i; a i @@ -426,6 +442,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 FLUSH STATUS; DELETE FROM t2 ORDER BY a, b DESC LIMIT 5; @@ -443,6 +460,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 5 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 SELECT * FROM t2 ORDER BY a, b DESC; a b c @@ -486,6 +504,7 @@ Handler_read_last 0 Handler_read_next 4 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 FLUSH STATUS; SELECT * FROM t2 ORDER BY a DESC, b DESC LIMIT 5; @@ -509,6 +528,7 @@ Handler_read_last 1 Handler_read_next 0 Handler_read_prev 4 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 FLUSH STATUS; DELETE FROM t2 ORDER BY a DESC, b DESC LIMIT 5; @@ -526,6 +546,7 @@ Handler_read_last 1 Handler_read_next 0 Handler_read_prev 4 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 SELECT * FROM t2 WHERE c = 10 ORDER BY a DESC, b DESC; a b c @@ -561,6 +582,7 @@ Handler_read_last 0 Handler_read_next 4 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 FLUSH STATUS; UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5; @@ -578,6 +600,7 @@ Handler_read_last 0 Handler_read_next 4 Handler_read_prev 0 Handler_read_rnd 5 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i; a i @@ -617,6 +640,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 FLUSH STATUS; UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5; @@ -634,6 +658,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 5 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i; a i @@ -670,6 +695,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 FLUSH STATUS; UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5; @@ -687,6 +713,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 1 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 ## should be 5 (previous LIMIT) SELECT COUNT(*) FROM t2 WHERE b = 10 AND d = 10 ORDER BY a, c; @@ -722,6 +749,7 @@ Handler_read_last 0 Handler_read_next 4 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 FLUSH STATUS; UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5; @@ -739,6 +767,7 @@ Handler_read_last 0 Handler_read_next 4 Handler_read_prev 0 Handler_read_rnd 5 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 ## should be 5 (previous LIMIT) SELECT COUNT(*) FROM t2 WHERE b = 10 AND d = 10 ORDER BY a, c; @@ -768,6 +797,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 FLUSH STATUS; UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5; @@ -785,6 +815,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 1 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 SELECT * FROM t2 WHERE b = 10 ORDER BY a, c; a b c d @@ -813,6 +844,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 1 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 FLUSH STATUS; UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5; @@ -830,6 +862,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 1 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 SELECT * FROM t2 WHERE b = 10 ORDER BY a, c; a b c d @@ -861,6 +894,7 @@ Handler_read_last 0 Handler_read_next 7 Handler_read_prev 0 Handler_read_rnd 4 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 EXPLAIN EXTENDED SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1; id select_type table type possible_keys key key_len ref rows filtered Extra @@ -883,6 +917,7 @@ Handler_read_last 0 Handler_read_next 7 Handler_read_prev 0 Handler_read_rnd 8 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1; i key1 key2 @@ -923,6 +958,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 4 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 FLUSH STATUS; UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i DESC LIMIT 5; @@ -940,6 +976,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 4 Handler_read_rnd 5 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i; a i @@ -979,6 +1016,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 FLUSH STATUS; UPDATE t2 SET c = 10 ORDER BY a, b DESC LIMIT 5; @@ -996,6 +1034,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 5 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 SELECT * FROM t2 WHERE c = 10 ORDER BY a, b DESC; a b c @@ -1033,6 +1072,7 @@ Handler_read_last 0 Handler_read_next 4 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 FLUSH STATUS; SELECT * FROM t2 ORDER BY a DESC, b DESC LIMIT 5; @@ -1056,6 +1096,7 @@ Handler_read_last 1 Handler_read_next 0 Handler_read_prev 4 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 FLUSH STATUS; UPDATE t2 SET c = 10 ORDER BY a DESC, b DESC LIMIT 5; @@ -1073,6 +1114,7 @@ Handler_read_last 1 Handler_read_next 0 Handler_read_prev 4 Handler_read_rnd 5 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 SELECT * FROM t2 WHERE c = 10 ORDER BY a DESC, b DESC; a b c diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result index 91a120313ae..644137a43bd 100644 --- a/mysql-test/r/status.result +++ b/mysql-test/r/status.result @@ -276,12 +276,15 @@ Handler_commit 0 Handler_delete 0 Handler_discover 0 Handler_prepare 0 +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 Handler_read_first 0 Handler_read_key 4 Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 7 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 23 Handler_rollback 0 Handler_savepoint 0 @@ -297,7 +300,37 @@ Created_tmp_files 0 Created_tmp_tables 2 Handler_tmp_update 2 Handler_tmp_write 7 -Rows_tmp_read 35 +Rows_tmp_read 38 +drop table t1; +CREATE TABLE t1 (i int(11) DEFAULT NULL, KEY i (i) ) ENGINE=MyISAM; +insert into t1 values (1),(2),(3),(4),(5); +flush status; +select * from t1 where i=5 union select * from t1 where i=5; +i +5 +show status like "handler%"; +Variable_name Value +Handler_commit 0 +Handler_delete 0 +Handler_discover 0 +Handler_prepare 0 +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 +Handler_read_first 0 +Handler_read_key 2 +Handler_read_last 0 +Handler_read_next 2 +Handler_read_prev 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 1 +Handler_read_rnd_next 2 +Handler_rollback 0 +Handler_savepoint 0 +Handler_savepoint_rollback 0 +Handler_tmp_update 0 +Handler_tmp_write 2 +Handler_update 0 +Handler_write 0 drop table t1; set @@global.concurrent_insert= @old_concurrent_insert; SET GLOBAL log_output = @old_log_output; diff --git a/mysql-test/r/status_user.result b/mysql-test/r/status_user.result index cd8e5af3004..e6db4ac2403 100644 --- a/mysql-test/r/status_user.result +++ b/mysql-test/r/status_user.result @@ -101,12 +101,15 @@ Handler_commit 19 Handler_delete 1 Handler_discover 0 Handler_prepare 18 +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 Handler_read_first 0 Handler_read_key 3 Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 5 Handler_rollback 2 Handler_savepoint 0 diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 7d3877e678d..e7883c5801e 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4620,6 +4620,13 @@ CREATE TABLE t1(a1 int); INSERT INTO t1 VALUES (1),(2); SELECT @@session.sql_mode INTO @old_sql_mode; SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +EXPLAIN EXTENDED +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 +2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 +Warnings: +Note 1003 select 1 AS `1` from `test`.`t1` where <nop>(<in_optimizer>(1,((select max(`test`.`t1`.`a1`) from `test`.`t1`) > 1))) SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); 1 1 @@ -5322,7 +5329,6 @@ EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1, WHERE t1.a = d1.a; ERROR 42S22: Unknown column 'd1.a' in 'where clause' DROP TABLE t1; -End of 5.1 tests. Set up test tables. CREATE TABLE t1 ( t1_id INT UNSIGNED, @@ -5847,10 +5853,161 @@ NULL NULL 5 DROP TABLE t1, t2, t3; +# +# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER +# +CREATE TABLE t1(a1 int); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2(a1 int); +INSERT INTO t2 VALUES (3); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); +1 +1 +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); +1 +1 +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); +1 +1 +1 +SET SESSION sql_mode=@old_sql_mode; +DROP TABLE t1, t2; +create table t2(i int); +insert into t2 values(0); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +CREATE VIEW v1 AS +SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2 +; +CREATE TABLE t1 ( +pk int NOT NULL, +col_varchar_key varchar(1) DEFAULT NULL, +PRIMARY KEY (pk), +KEY col_varchar_key (col_varchar_key) +); +SELECT t1.pk +FROM t1 +WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 ) +; +pk +SET SESSION sql_mode=@old_sql_mode; +drop table t2, t1; +drop view v1; +# +# BUG#50257: Missing info in REF column of the EXPLAIN +# lines for subselects +# +CREATE TABLE t1 (a INT, b INT, INDEX (a)); +INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20); +EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref a a 5 const 1 +EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +2 SUBQUERY t1 ref a a 5 const 1 Using index +DROP TABLE t1; +# +# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS) +# (duplicate of LP bug #888456) +# +CREATE TABLE t1 (f1 varchar(1)); +INSERT INTO t1 VALUES ('v'),('s'); +CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key)); +INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'), +('d'),('y'),('t'),('d'),('s'); +EXPLAIN +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 +WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 +WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY table1 ALL NULL NULL NULL NULL 2 +1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join) +2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 +WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 +WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +f1 f1_key +v j +s j +v v +s v +v c +s c +v m +s m +v d +s d +v d +s d +v y +s y +v t +s t +v d +s d +v s +s s +DROP TABLE t1,t2; +# +# LP bug 919427: EXPLAIN for a query over a single-row table +# with IN subquery in WHERE condition +# +CREATE TABLE ot ( +col_int_nokey int(11), +col_varchar_nokey varchar(1) +) ; +INSERT INTO ot VALUES (1,'x'); +CREATE TABLE it1( +col_int_key int(11), +col_varchar_key varchar(1), +KEY idx_cvk_cik (col_varchar_key,col_int_key) +); +INSERT INTO it1 VALUES (NULL,'x'), (NULL,'f'); +CREATE TABLE it2 ( +col_int_key int(11), +col_varchar_key varchar(1), +col_varchar_key2 varchar(1), +KEY idx_cvk_cvk2_cik (col_varchar_key, col_varchar_key2, col_int_key), +KEY idx_cvk_cik (col_varchar_key, col_int_key) +); +INSERT INTO it2 VALUES (NULL,'x','x'), (NULL,'f','f'); +EXPLAIN +SELECT col_int_nokey FROM ot +WHERE col_varchar_nokey IN +(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot system NULL NULL NULL NULL 1 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1 +2 MATERIALIZED it1 ref idx_cvk_cik idx_cvk_cik 9 const,const 1 Using where; Using index +SELECT col_int_nokey FROM ot +WHERE col_varchar_nokey IN +(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +col_int_nokey +1 +EXPLAIN +SELECT col_int_nokey FROM ot +WHERE (col_varchar_nokey, 'x') IN +(SELECT col_varchar_key, col_varchar_key2 FROM it2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot system NULL NULL NULL NULL 1 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1 +2 MATERIALIZED it2 ref idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 const,const 1 Using where; Using index +SELECT col_int_nokey FROM ot +WHERE (col_varchar_nokey, 'x') IN +(SELECT col_varchar_key, col_varchar_key2 FROM it2); +col_int_nokey +1 +DROP TABLE ot,it1,it2; End of 5.2 tests # # BUG#779885: Crash in eliminate_item_equal with materialization=on in -# maria-5.3 # CREATE TABLE t1 ( f1 int ); INSERT INTO t1 VALUES (19), (20); @@ -5897,32 +6054,6 @@ b c 9 NULL SET optimizer_switch=@save_optimizer_switch; drop table t1, t2, t3; -End of 5.3 tests -# -# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER -# -CREATE TABLE t1(a1 int); -INSERT INTO t1 VALUES (1),(2); -CREATE TABLE t2(a1 int); -INSERT INTO t2 VALUES (3); -SELECT @@session.sql_mode INTO @old_sql_mode; -SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); -1 -1 -1 -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); -1 -1 -1 -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); -1 -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); -1 -1 -1 -SET SESSION sql_mode=@old_sql_mode; -DROP TABLE t1, t2; # # BUG#50257: Missing info in REF column of the EXPLAIN # lines for subselects @@ -5945,6 +6076,54 @@ id select_type table type possible_keys key key_len ref rows Extra DROP TABLE t1; # +# Bug#11764086: Null left operand to NOT IN in WHERE clause +# behaves differently than real NULL +# +CREATE TABLE parent (id int); +INSERT INTO parent VALUES (1), (2); +CREATE TABLE child (parent_id int, other int); +INSERT INTO child VALUES (1,NULL); +# Offending query (c.parent_id is NULL for null-complemented rows only) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Some syntactic variations with IS FALSE and IS NOT TRUE +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS NOT TRUE; +id parent_id +1 1 +2 NULL +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS FALSE; +id parent_id +1 1 +2 NULL +DROP TABLE parent, child; +# End of test for bug#11764086. +# # Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET || # BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX # @@ -6283,5 +6462,14 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; 1 NULL drop table t1,t2,t3; +# +# LP BUG#905353 Wrong non-empty result with a constant table, +# aggregate function in subquery, MyISAM or Aria +# +CREATE TABLE t1 ( a INT ) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1); +SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 ); +a +drop table t1; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result index 833d6f203c2..d5d75b68628 100644 --- a/mysql-test/r/subselect3.result +++ b/mysql-test/r/subselect3.result @@ -125,6 +125,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 50 select 'No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.' Z; Z diff --git a/mysql-test/r/subselect3_jcl6.result b/mysql-test/r/subselect3_jcl6.result index 5d7fee48d87..d794d35cf1a 100644 --- a/mysql-test/r/subselect3_jcl6.result +++ b/mysql-test/r/subselect3_jcl6.result @@ -135,6 +135,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 50 select 'No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.' Z; Z @@ -1153,7 +1154,7 @@ insert into t4 select a from t3; explain select * from t3 where a in (select t1.kp1 from t1,t4 where kp1<20 and t4.pk=t1.c); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using index condition; Using where; Rowid-ordered scan; LooseScan +1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using index condition; Using where; LooseScan 1 PRIMARY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index; FirstMatch(t1) 1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join) drop table t1, t3, t4; diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index 1fd638fd42c..14c4254028d 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -711,7 +711,7 @@ EXPLAIN SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2); 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 NULL NULL NULL NULL NULL NULL NULL No matching min/max row +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2); f1 f2 SET @@optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off'; @@ -802,7 +802,7 @@ EXPLAIN SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2); 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 NULL NULL NULL NULL NULL NULL NULL No matching min/max row +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2); f1 f2 INSERT INTO t1 VALUES (1, 2); @@ -897,7 +897,7 @@ EXPLAIN SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); f1 f2 SET @@optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off'; @@ -988,7 +988,7 @@ EXPLAIN SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); f1 f2 set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/subselect_cache.result b/mysql-test/r/subselect_cache.result index d8ac44005f9..e38e8b42e9a 100644 --- a/mysql-test/r/subselect_cache.result +++ b/mysql-test/r/subselect_cache.result @@ -37,6 +37,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 31 set optimizer_switch='subquery_cache=off'; flush status; @@ -64,6 +65,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 61 set optimizer_switch='subquery_cache=on'; #single value subquery test (where) @@ -90,6 +92,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 31 set optimizer_switch='subquery_cache=off'; flush status; @@ -115,6 +118,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 61 set optimizer_switch='subquery_cache=on'; #single value subquery test (having) @@ -141,6 +145,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 31 set optimizer_switch='subquery_cache=off'; flush status; @@ -166,6 +171,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 61 set optimizer_switch='subquery_cache=on'; #single value subquery test (OUTER JOIN ON) @@ -264,6 +270,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 442 set optimizer_switch='subquery_cache=off'; flush status; @@ -361,6 +368,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 472 set optimizer_switch='subquery_cache=on'; #single value subquery test (GROUP BY) @@ -383,6 +391,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 4 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 36 set optimizer_switch='subquery_cache=off'; flush status; @@ -404,6 +413,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 4 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 86 set optimizer_switch='subquery_cache=on'; #single value subquery test (distinct GROUP BY) @@ -426,6 +436,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 4 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 41 set optimizer_switch='subquery_cache=off'; flush status; @@ -447,6 +458,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 4 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 91 set optimizer_switch='subquery_cache=on'; #single value subquery test (ORDER BY) @@ -475,6 +487,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 10 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 42 set optimizer_switch='subquery_cache=off'; flush status; @@ -502,6 +515,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 10 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 72 set optimizer_switch='subquery_cache=on'; #single value subquery test (distinct ORDER BY) @@ -524,7 +538,8 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 4 -Handler_read_rnd_next 37 +Handler_read_rnd_deleted 1 +Handler_read_rnd_next 36 set optimizer_switch='subquery_cache=off'; flush status; select distinct a from t1 ORDER BY (select d from t2 where b=c); @@ -545,7 +560,8 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 4 -Handler_read_rnd_next 67 +Handler_read_rnd_deleted 1 +Handler_read_rnd_next 66 set optimizer_switch='subquery_cache=on'; #single value subquery test (LEFT JOIN ON) flush status; @@ -643,6 +659,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 141 set optimizer_switch='subquery_cache=off'; flush status; @@ -740,6 +757,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 671 set optimizer_switch='subquery_cache=on'; #single value subquery test (PS) @@ -1364,6 +1382,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 145 set optimizer_switch='subquery_cache=on'; flush status; @@ -1393,6 +1412,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 84 #several subqueries (several levels) set optimizer_switch='subquery_cache=off'; @@ -1425,6 +1445,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 127 set optimizer_switch='subquery_cache=on'; flush status; @@ -1454,6 +1475,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 69 #clean up drop table t1,t2; @@ -1644,6 +1666,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 8 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 57 set optimizer_switch='subquery_cache=on'; flush status; @@ -1669,6 +1692,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 8 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 37 argument of aggregate function as parameter of subquery (illegal use) set optimizer_switch='subquery_cache=off'; @@ -1695,6 +1719,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 8 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 57 set optimizer_switch='subquery_cache=on'; flush status; @@ -1720,6 +1745,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 8 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 41 drop table t1,t2; #test of flattening subquery optimisations and cache @@ -1761,6 +1787,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 16 alter table t2 drop primary key; set optimizer_switch='default,semijoin=off,materialization=off,subquery_cache=off'; @@ -1798,6 +1825,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 151 set optimizer_switch='default,semijoin=off,materialization=off,subquery_cache=on'; explain select * from t1 where a in (select pk from t2); @@ -1834,6 +1862,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 43 set optimizer_switch='default,semijoin=off,materialization=on,subquery_cache=on'; explain select * from t1 where a in (select pk from t2); @@ -1870,6 +1899,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 27 drop table t0,t1,t2; set optimizer_switch='default'; diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index 5c750e8b078..b6e31a6ec34 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -1793,7 +1793,7 @@ SELECT * FROM t1 WHERE a IN ( SELECT MIN(a) FROM t1 ); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00 -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away Warnings: Note 1003 select 8 AS `a` from dual where <expr_cache><8>(<in_optimizer>(8,<exists>(select min(`test`.`t1`.`a`) from `test`.`t1` having (<cache>(8) = <ref_null_helper>(min(`test`.`t1`.`a`)))))) DROP TABLE t1; @@ -1811,6 +1811,56 @@ a b c 4 4 2 4 4 4 DROP TABLE t1,t2; +# +# BUG#922254: Assertion `0' failed at item_cmpfunc.cc:5899: Item* Item_equal::get_first(JOIN_TAB*, Item*) +# +CREATE TABLE t1 ( a VARCHAR(3) ); +CREATE TABLE t2 ( b VARCHAR(3), c VARCHAR(8), KEY(c) ); +INSERT INTO t2 VALUES ('USA','Abilene'),('USA','Akron'); +EXPLAIN +SELECT * FROM +( SELECT * FROM t1 ) AS alias1, +t2 AS alias2 +WHERE b = a AND a IN ( +SELECT alias3.c +FROM t2 AS alias3, t2 AS alias4 +WHERE alias4.c = alias3.b +); +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 +3 MATERIALIZED alias3 ALL NULL NULL NULL NULL 2 +3 MATERIALIZED alias4 index c c 11 NULL 2 Using where; Using index; Using join buffer (flat, BNL join) +DROP TABLE t1,t2; +# +# BUG#928048: Query containing IN subquery with OR in the where clause returns a wrong result +# +create table t1 (a int, b int); +insert into t1 values (7,5), (3,3), (5,4), (9,3); +create table t2 (a int, b int, index i_a(a)); +insert into t2 values +(4,2), (7,9), (7,4), (3,1), (5,3), (3,1), (9,4), (8,1); +explain select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +2 MATERIALIZED t2 ALL i_a NULL NULL NULL 8 Using where +select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); +a b +7 5 +3 3 +drop table t1,t2; +# +# BUG#933407: Valgrind warnings in mark_as_null_row with materialization+semijoin, STRAIGHT_JOIN, impossible WHERE +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0),(8); +SELECT STRAIGHT_JOIN MIN(a) FROM t1 +WHERE a IN ( +SELECT a FROM t1 +WHERE 'condition'='impossible' + ); +MIN(a) +NULL +DROP TABLE t1; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result index 8ac856857eb..b515ea39f9e 100644 --- a/mysql-test/r/subselect_no_mat.result +++ b/mysql-test/r/subselect_no_mat.result @@ -4622,6 +4622,13 @@ CREATE TABLE t1(a1 int); INSERT INTO t1 VALUES (1),(2); SELECT @@session.sql_mode INTO @old_sql_mode; SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +EXPLAIN EXTENDED +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 +2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 +Warnings: +Note 1003 select 1 AS `1` from `test`.`t1` where <nop>(<in_optimizer>(1,((select max(`test`.`t1`.`a1`) from `test`.`t1`) > 1))) SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); 1 1 @@ -5324,7 +5331,6 @@ EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1, WHERE t1.a = d1.a; ERROR 42S22: Unknown column 'd1.a' in 'where clause' DROP TABLE t1; -End of 5.1 tests. Set up test tables. CREATE TABLE t1 ( t1_id INT UNSIGNED, @@ -5848,10 +5854,159 @@ NULL NULL 5 DROP TABLE t1, t2, t3; +# +# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER +# +CREATE TABLE t1(a1 int); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2(a1 int); +INSERT INTO t2 VALUES (3); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); +1 +1 +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); +1 +1 +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); +1 +1 +1 +SET SESSION sql_mode=@old_sql_mode; +DROP TABLE t1, t2; +create table t2(i int); +insert into t2 values(0); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +CREATE VIEW v1 AS +SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2 +; +CREATE TABLE t1 ( +pk int NOT NULL, +col_varchar_key varchar(1) DEFAULT NULL, +PRIMARY KEY (pk), +KEY col_varchar_key (col_varchar_key) +); +SELECT t1.pk +FROM t1 +WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 ) +; +pk +SET SESSION sql_mode=@old_sql_mode; +drop table t2, t1; +drop view v1; +# +# BUG#50257: Missing info in REF column of the EXPLAIN +# lines for subselects +# +CREATE TABLE t1 (a INT, b INT, INDEX (a)); +INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20); +EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref a a 5 const 1 +EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +2 SUBQUERY t1 ref a a 5 const 1 Using index +DROP TABLE t1; +# +# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS) +# (duplicate of LP bug #888456) +# +CREATE TABLE t1 (f1 varchar(1)); +INSERT INTO t1 VALUES ('v'),('s'); +CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key)); +INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'), +('d'),('y'),('t'),('d'),('s'); +EXPLAIN +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 +WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 +WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY table1 ALL NULL NULL NULL NULL 2 +1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join) +2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 +WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 +WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +f1 f1_key +v j +s j +v v +s v +v c +s c +v m +s m +v d +s d +v d +s d +v y +s y +v t +s t +v d +s d +v s +s s +DROP TABLE t1,t2; +# +# LP bug 919427: EXPLAIN for a query over a single-row table +# with IN subquery in WHERE condition +# +CREATE TABLE ot ( +col_int_nokey int(11), +col_varchar_nokey varchar(1) +) ; +INSERT INTO ot VALUES (1,'x'); +CREATE TABLE it1( +col_int_key int(11), +col_varchar_key varchar(1), +KEY idx_cvk_cik (col_varchar_key,col_int_key) +); +INSERT INTO it1 VALUES (NULL,'x'), (NULL,'f'); +CREATE TABLE it2 ( +col_int_key int(11), +col_varchar_key varchar(1), +col_varchar_key2 varchar(1), +KEY idx_cvk_cvk2_cik (col_varchar_key, col_varchar_key2, col_int_key), +KEY idx_cvk_cik (col_varchar_key, col_int_key) +); +INSERT INTO it2 VALUES (NULL,'x','x'), (NULL,'f','f'); +EXPLAIN +SELECT col_int_nokey FROM ot +WHERE col_varchar_nokey IN +(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot system NULL NULL NULL NULL 1 +1 PRIMARY it1 ref idx_cvk_cik idx_cvk_cik 9 const,const 1 Using where; Using index; FirstMatch(ot) +SELECT col_int_nokey FROM ot +WHERE col_varchar_nokey IN +(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +col_int_nokey +1 +EXPLAIN +SELECT col_int_nokey FROM ot +WHERE (col_varchar_nokey, 'x') IN +(SELECT col_varchar_key, col_varchar_key2 FROM it2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot system NULL NULL NULL NULL 1 +1 PRIMARY it2 ref idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 const,const 1 Using where; Using index; FirstMatch(ot) +SELECT col_int_nokey FROM ot +WHERE (col_varchar_nokey, 'x') IN +(SELECT col_varchar_key, col_varchar_key2 FROM it2); +col_int_nokey +1 +DROP TABLE ot,it1,it2; End of 5.2 tests # # BUG#779885: Crash in eliminate_item_equal with materialization=on in -# maria-5.3 # CREATE TABLE t1 ( f1 int ); INSERT INTO t1 VALUES (19), (20); @@ -5898,32 +6053,6 @@ b c 9 NULL SET optimizer_switch=@save_optimizer_switch; drop table t1, t2, t3; -End of 5.3 tests -# -# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER -# -CREATE TABLE t1(a1 int); -INSERT INTO t1 VALUES (1),(2); -CREATE TABLE t2(a1 int); -INSERT INTO t2 VALUES (3); -SELECT @@session.sql_mode INTO @old_sql_mode; -SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); -1 -1 -1 -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); -1 -1 -1 -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); -1 -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); -1 -1 -1 -SET SESSION sql_mode=@old_sql_mode; -DROP TABLE t1, t2; # # BUG#50257: Missing info in REF column of the EXPLAIN # lines for subselects @@ -5946,6 +6075,54 @@ id select_type table type possible_keys key key_len ref rows Extra DROP TABLE t1; # +# Bug#11764086: Null left operand to NOT IN in WHERE clause +# behaves differently than real NULL +# +CREATE TABLE parent (id int); +INSERT INTO parent VALUES (1), (2); +CREATE TABLE child (parent_id int, other int); +INSERT INTO child VALUES (1,NULL); +# Offending query (c.parent_id is NULL for null-complemented rows only) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Some syntactic variations with IS FALSE and IS NOT TRUE +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS NOT TRUE; +id parent_id +1 1 +2 NULL +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS FALSE; +id parent_id +1 1 +2 NULL +DROP TABLE parent, child; +# End of test for bug#11764086. +# # Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET || # BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX # @@ -6284,6 +6461,15 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; 1 NULL drop table t1,t2,t3; +# +# LP BUG#905353 Wrong non-empty result with a constant table, +# aggregate function in subquery, MyISAM or Aria +# +CREATE TABLE t1 ( a INT ) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1); +SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 ); +a +drop table t1; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set optimizer_switch=default; diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result index 518f9366b80..c50ee1bac69 100644 --- a/mysql-test/r/subselect_no_opts.result +++ b/mysql-test/r/subselect_no_opts.result @@ -4618,6 +4618,13 @@ CREATE TABLE t1(a1 int); INSERT INTO t1 VALUES (1),(2); SELECT @@session.sql_mode INTO @old_sql_mode; SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +EXPLAIN EXTENDED +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 +2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 +Warnings: +Note 1003 select 1 AS `1` from `test`.`t1` where <nop>(<in_optimizer>(1,((select max(`test`.`t1`.`a1`) from `test`.`t1`) > 1))) SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); 1 1 @@ -5320,7 +5327,6 @@ EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1, WHERE t1.a = d1.a; ERROR 42S22: Unknown column 'd1.a' in 'where clause' DROP TABLE t1; -End of 5.1 tests. Set up test tables. CREATE TABLE t1 ( t1_id INT UNSIGNED, @@ -5844,10 +5850,159 @@ NULL NULL 5 DROP TABLE t1, t2, t3; +# +# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER +# +CREATE TABLE t1(a1 int); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2(a1 int); +INSERT INTO t2 VALUES (3); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); +1 +1 +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); +1 +1 +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); +1 +1 +1 +SET SESSION sql_mode=@old_sql_mode; +DROP TABLE t1, t2; +create table t2(i int); +insert into t2 values(0); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +CREATE VIEW v1 AS +SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2 +; +CREATE TABLE t1 ( +pk int NOT NULL, +col_varchar_key varchar(1) DEFAULT NULL, +PRIMARY KEY (pk), +KEY col_varchar_key (col_varchar_key) +); +SELECT t1.pk +FROM t1 +WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 ) +; +pk +SET SESSION sql_mode=@old_sql_mode; +drop table t2, t1; +drop view v1; +# +# BUG#50257: Missing info in REF column of the EXPLAIN +# lines for subselects +# +CREATE TABLE t1 (a INT, b INT, INDEX (a)); +INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20); +EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref a a 5 const 1 +EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +2 SUBQUERY t1 ref a a 5 const 1 Using index +DROP TABLE t1; +# +# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS) +# (duplicate of LP bug #888456) +# +CREATE TABLE t1 (f1 varchar(1)); +INSERT INTO t1 VALUES ('v'),('s'); +CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key)); +INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'), +('d'),('y'),('t'),('d'),('s'); +EXPLAIN +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 +WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 +WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY table1 ALL NULL NULL NULL NULL 2 +1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join) +2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 +WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 +WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +f1 f1_key +v j +s j +v v +s v +v c +s c +v m +s m +v d +s d +v d +s d +v y +s y +v t +s t +v d +s d +v s +s s +DROP TABLE t1,t2; +# +# LP bug 919427: EXPLAIN for a query over a single-row table +# with IN subquery in WHERE condition +# +CREATE TABLE ot ( +col_int_nokey int(11), +col_varchar_nokey varchar(1) +) ; +INSERT INTO ot VALUES (1,'x'); +CREATE TABLE it1( +col_int_key int(11), +col_varchar_key varchar(1), +KEY idx_cvk_cik (col_varchar_key,col_int_key) +); +INSERT INTO it1 VALUES (NULL,'x'), (NULL,'f'); +CREATE TABLE it2 ( +col_int_key int(11), +col_varchar_key varchar(1), +col_varchar_key2 varchar(1), +KEY idx_cvk_cvk2_cik (col_varchar_key, col_varchar_key2, col_int_key), +KEY idx_cvk_cik (col_varchar_key, col_int_key) +); +INSERT INTO it2 VALUES (NULL,'x','x'), (NULL,'f','f'); +EXPLAIN +SELECT col_int_nokey FROM ot +WHERE col_varchar_nokey IN +(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot system NULL NULL NULL NULL 1 +2 DEPENDENT SUBQUERY it1 index_subquery idx_cvk_cik idx_cvk_cik 9 func,const 2 Using index; Using where +SELECT col_int_nokey FROM ot +WHERE col_varchar_nokey IN +(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +col_int_nokey +1 +EXPLAIN +SELECT col_int_nokey FROM ot +WHERE (col_varchar_nokey, 'x') IN +(SELECT col_varchar_key, col_varchar_key2 FROM it2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot system NULL NULL NULL NULL 1 +2 DEPENDENT SUBQUERY it2 index_subquery idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 func,const 1 Using index; Using where +SELECT col_int_nokey FROM ot +WHERE (col_varchar_nokey, 'x') IN +(SELECT col_varchar_key, col_varchar_key2 FROM it2); +col_int_nokey +1 +DROP TABLE ot,it1,it2; End of 5.2 tests # # BUG#779885: Crash in eliminate_item_equal with materialization=on in -# maria-5.3 # CREATE TABLE t1 ( f1 int ); INSERT INTO t1 VALUES (19), (20); @@ -5894,32 +6049,6 @@ b c 9 NULL SET optimizer_switch=@save_optimizer_switch; drop table t1, t2, t3; -End of 5.3 tests -# -# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER -# -CREATE TABLE t1(a1 int); -INSERT INTO t1 VALUES (1),(2); -CREATE TABLE t2(a1 int); -INSERT INTO t2 VALUES (3); -SELECT @@session.sql_mode INTO @old_sql_mode; -SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); -1 -1 -1 -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); -1 -1 -1 -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); -1 -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); -1 -1 -1 -SET SESSION sql_mode=@old_sql_mode; -DROP TABLE t1, t2; # # BUG#50257: Missing info in REF column of the EXPLAIN # lines for subselects @@ -5942,6 +6071,54 @@ id select_type table type possible_keys key key_len ref rows Extra DROP TABLE t1; # +# Bug#11764086: Null left operand to NOT IN in WHERE clause +# behaves differently than real NULL +# +CREATE TABLE parent (id int); +INSERT INTO parent VALUES (1), (2); +CREATE TABLE child (parent_id int, other int); +INSERT INTO child VALUES (1,NULL); +# Offending query (c.parent_id is NULL for null-complemented rows only) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Some syntactic variations with IS FALSE and IS NOT TRUE +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS NOT TRUE; +id parent_id +1 1 +2 NULL +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS FALSE; +id parent_id +1 1 +2 NULL +DROP TABLE parent, child; +# End of test for bug#11764086. +# # Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET || # BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX # @@ -6280,6 +6457,15 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; 1 NULL drop table t1,t2,t3; +# +# LP BUG#905353 Wrong non-empty result with a constant table, +# aggregate function in subquery, MyISAM or Aria +# +CREATE TABLE t1 ( a INT ) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1); +SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 ); +a +drop table t1; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set @optimizer_switch_for_subselect_test=null; diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result index 320e51da39e..3e2305ebe73 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -4626,6 +4626,13 @@ CREATE TABLE t1(a1 int); INSERT INTO t1 VALUES (1),(2); SELECT @@session.sql_mode INTO @old_sql_mode; SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +EXPLAIN EXTENDED +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 +2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 +Warnings: +Note 1003 select 1 AS `1` from `test`.`t1` where <nop>(<in_optimizer>(1,((select max(`test`.`t1`.`a1`) from `test`.`t1`) > 1))) SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); 1 1 @@ -5328,7 +5335,6 @@ EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1, WHERE t1.a = d1.a; ERROR 42S22: Unknown column 'd1.a' in 'where clause' DROP TABLE t1; -End of 5.1 tests. Set up test tables. CREATE TABLE t1 ( t1_id INT UNSIGNED, @@ -5853,10 +5859,161 @@ NULL NULL 5 DROP TABLE t1, t2, t3; +# +# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER +# +CREATE TABLE t1(a1 int); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2(a1 int); +INSERT INTO t2 VALUES (3); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); +1 +1 +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); +1 +1 +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); +1 +1 +1 +SET SESSION sql_mode=@old_sql_mode; +DROP TABLE t1, t2; +create table t2(i int); +insert into t2 values(0); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +CREATE VIEW v1 AS +SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2 +; +CREATE TABLE t1 ( +pk int NOT NULL, +col_varchar_key varchar(1) DEFAULT NULL, +PRIMARY KEY (pk), +KEY col_varchar_key (col_varchar_key) +); +SELECT t1.pk +FROM t1 +WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 ) +; +pk +SET SESSION sql_mode=@old_sql_mode; +drop table t2, t1; +drop view v1; +# +# BUG#50257: Missing info in REF column of the EXPLAIN +# lines for subselects +# +CREATE TABLE t1 (a INT, b INT, INDEX (a)); +INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20); +EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref a a 5 const 1 +EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +2 SUBQUERY t1 ref a a 5 const 1 Using index +DROP TABLE t1; +# +# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS) +# (duplicate of LP bug #888456) +# +CREATE TABLE t1 (f1 varchar(1)); +INSERT INTO t1 VALUES ('v'),('s'); +CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key)); +INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'), +('d'),('y'),('t'),('d'),('s'); +EXPLAIN +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 +WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 +WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY table1 ALL NULL NULL NULL NULL 2 +1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join) +2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 +WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 +WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +f1 f1_key +v j +s j +v v +s v +v c +s c +v m +s m +v d +s d +v d +s d +v y +s y +v t +s t +v d +s d +v s +s s +DROP TABLE t1,t2; +# +# LP bug 919427: EXPLAIN for a query over a single-row table +# with IN subquery in WHERE condition +# +CREATE TABLE ot ( +col_int_nokey int(11), +col_varchar_nokey varchar(1) +) ; +INSERT INTO ot VALUES (1,'x'); +CREATE TABLE it1( +col_int_key int(11), +col_varchar_key varchar(1), +KEY idx_cvk_cik (col_varchar_key,col_int_key) +); +INSERT INTO it1 VALUES (NULL,'x'), (NULL,'f'); +CREATE TABLE it2 ( +col_int_key int(11), +col_varchar_key varchar(1), +col_varchar_key2 varchar(1), +KEY idx_cvk_cvk2_cik (col_varchar_key, col_varchar_key2, col_int_key), +KEY idx_cvk_cik (col_varchar_key, col_int_key) +); +INSERT INTO it2 VALUES (NULL,'x','x'), (NULL,'f','f'); +EXPLAIN +SELECT col_int_nokey FROM ot +WHERE col_varchar_nokey IN +(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot system NULL NULL NULL NULL 1 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1 +2 MATERIALIZED it1 ref idx_cvk_cik idx_cvk_cik 9 const,const 1 Using where; Using index +SELECT col_int_nokey FROM ot +WHERE col_varchar_nokey IN +(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +col_int_nokey +1 +EXPLAIN +SELECT col_int_nokey FROM ot +WHERE (col_varchar_nokey, 'x') IN +(SELECT col_varchar_key, col_varchar_key2 FROM it2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot system NULL NULL NULL NULL 1 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1 +2 MATERIALIZED it2 ref idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 const,const 1 Using where; Using index +SELECT col_int_nokey FROM ot +WHERE (col_varchar_nokey, 'x') IN +(SELECT col_varchar_key, col_varchar_key2 FROM it2); +col_int_nokey +1 +DROP TABLE ot,it1,it2; End of 5.2 tests # # BUG#779885: Crash in eliminate_item_equal with materialization=on in -# maria-5.3 # CREATE TABLE t1 ( f1 int ); INSERT INTO t1 VALUES (19), (20); @@ -5903,32 +6060,6 @@ b c 9 NULL SET optimizer_switch=@save_optimizer_switch; drop table t1, t2, t3; -End of 5.3 tests -# -# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER -# -CREATE TABLE t1(a1 int); -INSERT INTO t1 VALUES (1),(2); -CREATE TABLE t2(a1 int); -INSERT INTO t2 VALUES (3); -SELECT @@session.sql_mode INTO @old_sql_mode; -SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); -1 -1 -1 -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); -1 -1 -1 -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); -1 -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); -1 -1 -1 -SET SESSION sql_mode=@old_sql_mode; -DROP TABLE t1, t2; # # BUG#50257: Missing info in REF column of the EXPLAIN # lines for subselects @@ -5951,6 +6082,54 @@ id select_type table type possible_keys key key_len ref rows Extra DROP TABLE t1; # +# Bug#11764086: Null left operand to NOT IN in WHERE clause +# behaves differently than real NULL +# +CREATE TABLE parent (id int); +INSERT INTO parent VALUES (1), (2); +CREATE TABLE child (parent_id int, other int); +INSERT INTO child VALUES (1,NULL); +# Offending query (c.parent_id is NULL for null-complemented rows only) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Some syntactic variations with IS FALSE and IS NOT TRUE +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS NOT TRUE; +id parent_id +1 1 +2 NULL +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS FALSE; +id parent_id +1 1 +2 NULL +DROP TABLE parent, child; +# End of test for bug#11764086. +# # Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET || # BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX # @@ -6289,6 +6468,15 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; 1 NULL drop table t1,t2,t3; +# +# LP BUG#905353 Wrong non-empty result with a constant table, +# aggregate function in subquery, MyISAM or Aria +# +CREATE TABLE t1 ( a INT ) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1); +SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 ); +a +drop table t1; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set optimizer_switch=default; diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result index 0c41f612ae9..47368b1eca7 100644 --- a/mysql-test/r/subselect_no_semijoin.result +++ b/mysql-test/r/subselect_no_semijoin.result @@ -4618,6 +4618,13 @@ CREATE TABLE t1(a1 int); INSERT INTO t1 VALUES (1),(2); SELECT @@session.sql_mode INTO @old_sql_mode; SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +EXPLAIN EXTENDED +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 +2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 +Warnings: +Note 1003 select 1 AS `1` from `test`.`t1` where <nop>(<in_optimizer>(1,((select max(`test`.`t1`.`a1`) from `test`.`t1`) > 1))) SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); 1 1 @@ -5320,7 +5327,6 @@ EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1, WHERE t1.a = d1.a; ERROR 42S22: Unknown column 'd1.a' in 'where clause' DROP TABLE t1; -End of 5.1 tests. Set up test tables. CREATE TABLE t1 ( t1_id INT UNSIGNED, @@ -5844,10 +5850,159 @@ NULL NULL 5 DROP TABLE t1, t2, t3; +# +# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER +# +CREATE TABLE t1(a1 int); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2(a1 int); +INSERT INTO t2 VALUES (3); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); +1 +1 +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); +1 +1 +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); +1 +1 +1 +SET SESSION sql_mode=@old_sql_mode; +DROP TABLE t1, t2; +create table t2(i int); +insert into t2 values(0); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +CREATE VIEW v1 AS +SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2 +; +CREATE TABLE t1 ( +pk int NOT NULL, +col_varchar_key varchar(1) DEFAULT NULL, +PRIMARY KEY (pk), +KEY col_varchar_key (col_varchar_key) +); +SELECT t1.pk +FROM t1 +WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 ) +; +pk +SET SESSION sql_mode=@old_sql_mode; +drop table t2, t1; +drop view v1; +# +# BUG#50257: Missing info in REF column of the EXPLAIN +# lines for subselects +# +CREATE TABLE t1 (a INT, b INT, INDEX (a)); +INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20); +EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref a a 5 const 1 +EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +2 SUBQUERY t1 ref a a 5 const 1 Using index +DROP TABLE t1; +# +# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS) +# (duplicate of LP bug #888456) +# +CREATE TABLE t1 (f1 varchar(1)); +INSERT INTO t1 VALUES ('v'),('s'); +CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key)); +INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'), +('d'),('y'),('t'),('d'),('s'); +EXPLAIN +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 +WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 +WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY table1 ALL NULL NULL NULL NULL 2 +1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join) +2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 +WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 +WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +f1 f1_key +v j +s j +v v +s v +v c +s c +v m +s m +v d +s d +v d +s d +v y +s y +v t +s t +v d +s d +v s +s s +DROP TABLE t1,t2; +# +# LP bug 919427: EXPLAIN for a query over a single-row table +# with IN subquery in WHERE condition +# +CREATE TABLE ot ( +col_int_nokey int(11), +col_varchar_nokey varchar(1) +) ; +INSERT INTO ot VALUES (1,'x'); +CREATE TABLE it1( +col_int_key int(11), +col_varchar_key varchar(1), +KEY idx_cvk_cik (col_varchar_key,col_int_key) +); +INSERT INTO it1 VALUES (NULL,'x'), (NULL,'f'); +CREATE TABLE it2 ( +col_int_key int(11), +col_varchar_key varchar(1), +col_varchar_key2 varchar(1), +KEY idx_cvk_cvk2_cik (col_varchar_key, col_varchar_key2, col_int_key), +KEY idx_cvk_cik (col_varchar_key, col_int_key) +); +INSERT INTO it2 VALUES (NULL,'x','x'), (NULL,'f','f'); +EXPLAIN +SELECT col_int_nokey FROM ot +WHERE col_varchar_nokey IN +(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot system NULL NULL NULL NULL 1 +2 DEPENDENT SUBQUERY it1 index_subquery idx_cvk_cik idx_cvk_cik 9 func,const 2 Using index; Using where +SELECT col_int_nokey FROM ot +WHERE col_varchar_nokey IN +(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +col_int_nokey +1 +EXPLAIN +SELECT col_int_nokey FROM ot +WHERE (col_varchar_nokey, 'x') IN +(SELECT col_varchar_key, col_varchar_key2 FROM it2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot system NULL NULL NULL NULL 1 +2 DEPENDENT SUBQUERY it2 index_subquery idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 func,const 1 Using index; Using where +SELECT col_int_nokey FROM ot +WHERE (col_varchar_nokey, 'x') IN +(SELECT col_varchar_key, col_varchar_key2 FROM it2); +col_int_nokey +1 +DROP TABLE ot,it1,it2; End of 5.2 tests # # BUG#779885: Crash in eliminate_item_equal with materialization=on in -# maria-5.3 # CREATE TABLE t1 ( f1 int ); INSERT INTO t1 VALUES (19), (20); @@ -5894,32 +6049,6 @@ b c 9 NULL SET optimizer_switch=@save_optimizer_switch; drop table t1, t2, t3; -End of 5.3 tests -# -# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER -# -CREATE TABLE t1(a1 int); -INSERT INTO t1 VALUES (1),(2); -CREATE TABLE t2(a1 int); -INSERT INTO t2 VALUES (3); -SELECT @@session.sql_mode INTO @old_sql_mode; -SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); -1 -1 -1 -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); -1 -1 -1 -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); -1 -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); -1 -1 -1 -SET SESSION sql_mode=@old_sql_mode; -DROP TABLE t1, t2; # # BUG#50257: Missing info in REF column of the EXPLAIN # lines for subselects @@ -5942,6 +6071,54 @@ id select_type table type possible_keys key key_len ref rows Extra DROP TABLE t1; # +# Bug#11764086: Null left operand to NOT IN in WHERE clause +# behaves differently than real NULL +# +CREATE TABLE parent (id int); +INSERT INTO parent VALUES (1), (2); +CREATE TABLE child (parent_id int, other int); +INSERT INTO child VALUES (1,NULL); +# Offending query (c.parent_id is NULL for null-complemented rows only) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Some syntactic variations with IS FALSE and IS NOT TRUE +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS NOT TRUE; +id parent_id +1 1 +2 NULL +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS FALSE; +id parent_id +1 1 +2 NULL +DROP TABLE parent, child; +# End of test for bug#11764086. +# # Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET || # BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX # @@ -6280,6 +6457,15 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; 1 NULL drop table t1,t2,t3; +# +# LP BUG#905353 Wrong non-empty result with a constant table, +# aggregate function in subquery, MyISAM or Aria +# +CREATE TABLE t1 ( a INT ) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1); +SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 ); +a +drop table t1; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set @optimizer_switch_for_subselect_test=null; diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result index 8fcedc5807f..3bc1d1f4293 100644 --- a/mysql-test/r/subselect_sj.result +++ b/mysql-test/r/subselect_sj.result @@ -1231,6 +1231,364 @@ IN (SELECT t3.pk, t3.pk FROM t2 LEFT JOIN t3 ON t3.varchar_key) AND pk = 9; datetime_key DROP TABLE t1, t2, t3; +# +# BUG#53060: LooseScan semijoin strategy does not return all rows +# +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=on,materialization=off'; +set optimizer_switch='firstmatch=off,loosescan=on'; +CREATE TABLE t1 (i INTEGER); +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +CREATE TABLE t2 (i INTEGER, j INTEGER, KEY k(i, j)); +INSERT INTO t2 VALUES (1, 0), (1, 1), (2, 0), (2, 1); +EXPLAIN +SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 index k k 10 NULL 4 Using where; Using index; LooseScan +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join) +SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0); +i +1 +2 +DROP TABLE t1, t2; +set optimizer_switch=@save_optimizer_switch; +# +# BUG#49453: re-execution of prepared statement with view +# and semijoin crashes +# +CREATE TABLE t1 (city VARCHAR(50), country_id INT); +CREATE TABLE t2 (country_id INT, country VARCHAR(50)); +INSERT INTO t1 VALUES +('Batna',2),('Bchar',2),('Skikda',2),('Tafuna',3),('Algeria',2) ; +INSERT INTO t2 VALUES (2,'Algeria'),(2,'AlgeriaDup'),(3,'XAmerican Samoa'); +CREATE VIEW v1 AS +SELECT country_id as vf_country_id +FROM t2 +WHERE LEFT(country,1) = "A"; +PREPARE stmt FROM " +SELECT city, country_id +FROM t1 +WHERE country_id IN (SELECT vf_country_id FROM v1); +"; + +EXECUTE stmt; +city country_id +Batna 2 +Bchar 2 +Skikda 2 +Algeria 2 +EXECUTE stmt; +city country_id +Batna 2 +Bchar 2 +Skikda 2 +Algeria 2 +DROP TABLE t1,t2; +DROP VIEW v1; +# +# Bug#54437 Extra rows with LEFT JOIN + semijoin +# +create table t1 (a int); +create table t2 (a int); +create table t3 (a int); +insert into t1 values(1),(1); +insert into t2 values(1),(1),(1),(1); +insert into t3 values(2),(2); +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='materialization=off'; +set optimizer_switch='semijoin=off'; +explain +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using where +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +a +1 +1 +set optimizer_switch='semijoin=on'; +explain +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; Start temporary +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +a +1 +1 +set optimizer_switch=@save_optimizer_switch; +drop table t1,t2,t3; +# +# Bug#55955: crash in MEMORY engine with IN(LEFT JOIN (JOIN)) +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); +CREATE TABLE t3 (a INT); +INSERT INTO t1 VALUES(1),(1); +INSERT INTO t2 VALUES(1),(1); +INSERT INTO t3 VALUES(2),(2); +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=off,materialization=off'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2inner ALL NULL NULL NULL NULL 2 +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +a +1 +1 +set optimizer_switch='semijoin=off,materialization=on'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 +2 MATERIALIZED t2inner ALL NULL NULL NULL NULL 2 +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 Using where +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +a +1 +1 +set optimizer_switch='semijoin=on,materialization=off'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary +1 PRIMARY t2inner ALL NULL NULL NULL NULL 2 +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +a +1 +1 +set optimizer_switch=@save_optimizer_switch; +DROP TABLE t1,t2,t3; +# +# BUG#52329 - Wrong result: subquery materialization, IN, +# non-null field followed by nullable +# +CREATE TABLE t1 (a1 CHAR(8) NOT NULL, a2 char(8) NOT NULL); +CREATE TABLE t2a (b1 char(8), b2 char(8)); +CREATE TABLE t2b (b1 CHAR(8), b2 char(8) NOT NULL); +CREATE TABLE t2c (b1 CHAR(8) NOT NULL, b2 char(8)); +INSERT INTO t1 VALUES ('1 - 12', '2 - 22'); +INSERT INTO t2a VALUES ('1 - 11', '2 - 21'), +('1 - 11', '2 - 21'), +('1 - 12', '2 - 22'), +('1 - 12', '2 - 22'), +('1 - 13', '2 - 23'); +INSERT INTO t2b SELECT * FROM t2a; +INSERT INTO t2c SELECT * FROM t2a; +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=off,materialization=on'; +SELECT * FROM t1 +WHERE (a1, a2) IN ( +SELECT b1, b2 FROM t2c WHERE b1 > '0' GROUP BY b1, b2); +a1 a2 +1 - 12 2 - 22 +SELECT * FROM t1 +WHERE (a1, a2) IN ( +SELECT b1, b2 FROM t2a WHERE b1 > '0'); +a1 a2 +1 - 12 2 - 22 +SELECT * FROM t1 +WHERE (a1, a2) IN ( +SELECT b1, b2 FROM t2b WHERE b1 > '0'); +a1 a2 +1 - 12 2 - 22 +SELECT * FROM t1 +WHERE (a1, a2) IN ( +SELECT b1, b2 FROM t2c WHERE b1 > '0'); +a1 a2 +1 - 12 2 - 22 +set optimizer_switch=@save_optimizer_switch; +DROP TABLE t1,t2a,t2b,t2c; +# +# Bug#57623: subquery within before insert trigger causes crash (sj=on) +# +CREATE TABLE ot1(a INT); +CREATE TABLE ot2(a INT); +CREATE TABLE ot3(a INT); +CREATE TABLE it1(a INT); +INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7); +INSERT INTO ot2 VALUES(0),(2),(4),(6); +INSERT INTO ot3 VALUES(0),(3),(6); +INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7); +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=on'; +set optimizer_switch='materialization=off'; +explain SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot1 ALL NULL NULL NULL NULL 8 +1 PRIMARY ot3 ALL NULL NULL NULL NULL 3 Using where +1 PRIMARY ot2 ALL NULL NULL NULL NULL 4 Using where +2 DEPENDENT SUBQUERY it1 ALL NULL NULL NULL NULL 8 Using where +SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); +a a a +0 0 0 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +6 6 6 +7 NULL NULL +prepare s from 'SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1)'; +execute s; +a a a +0 0 0 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +6 6 6 +7 NULL NULL +execute s; +a a a +0 0 0 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +6 6 6 +7 NULL NULL +deallocate prepare s; +set optimizer_switch='materialization=on'; +explain SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot1 ALL NULL NULL NULL NULL 8 +1 PRIMARY ot3 ALL NULL NULL NULL NULL 3 Using where +1 PRIMARY ot2 ALL NULL NULL NULL NULL 4 Using where +2 MATERIALIZED it1 ALL NULL NULL NULL NULL 8 +SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); +a a a +0 0 0 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +6 6 6 +7 NULL NULL +prepare s from 'SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1)'; +execute s; +a a a +0 0 0 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +6 6 6 +7 NULL NULL +execute s; +a a a +0 0 0 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +6 6 6 +7 NULL NULL +deallocate prepare s; +set optimizer_switch=@save_optimizer_switch; +DROP TABLE ot1, ot2, ot3, it1; +# +# Bug#59919/11766739: Crash in tmp_table_param::init() with semijoin=on +# +CREATE TABLE t1 (f1 INTEGER) ENGINE=MyISAM; +CREATE TABLE t2 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM; +CREATE TABLE t3 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1,1), (2,1); +INSERT INTO t3 VALUES +(1,1), (2,1), (5,4), (7,3), (8,2), (8,1), (7,3), +(9,5), (4,3), (7,2), (7,7), (3,1), (5,8), (9,7); +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=off,materialization=on'; +EXPLAIN +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 +FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 14 Using where +2 MATERIALIZED t1 system NULL NULL NULL NULL 1 +2 MATERIALIZED b1 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED b2 ALL NULL NULL NULL NULL 2 +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 +FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +f1 f2 +1 1 +2 1 +8 1 +3 1 +set optimizer_switch='semijoin=on,materialization=on'; +EXPLAIN +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 +FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1 +1 PRIMARY t3 ALL NULL NULL NULL NULL 14 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED b1 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED b2 ALL NULL NULL NULL NULL 2 +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 +FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +f1 f2 +1 1 +2 1 +8 1 +3 1 +set optimizer_switch=@save_optimizer_switch; +DROP TABLE t1, t2, t3 ; +# # # BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 # @@ -2179,4 +2537,105 @@ WHERE c = b AND b = a a COUNT(*) NULL 0 DROP TABLE t1, t2, t3; +# +# BUG#920255: Wrong result (extra rows) with loosescan and IN subquery +# +CREATE TABLE t1 ( a INT PRIMARY KEY, b INT, KEY(b) ); +INSERT INTO t1 VALUES +(1,2),(2,1),(3,3),(4,2),(5,5), +(6,3),(7,1),(8,4),(9,3),(10,2); +CREATE TABLE t2 ( c INT, d INT, UNIQUE KEY(c) ); +INSERT INTO t2 VALUES +(1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1); +SELECT a, b, d FROM t1, t2 +WHERE ( b, d ) IN +( SELECT b, d FROM t1, t2 WHERE b = c ); +a b d +2 1 2 +7 1 2 +2 1 2 +7 1 2 +1 2 1 +4 2 1 +10 2 1 +1 2 1 +4 2 1 +10 2 1 +3 3 3 +6 3 3 +9 3 3 +3 3 3 +6 3 3 +9 3 3 +8 4 2 +8 4 2 +5 5 5 +DROP TABLE t1, t2; +# +# BUG#920713: Wrong result (missing rows) with firstmatch+BNL, IN subquery, ... +# +CREATE TABLE t1 ( a VARCHAR(1) ) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('e'),('w'),('a'),('h'),('x'),('k'),('g'); +CREATE TABLE t2 ( b INT, c VARCHAR(1) ); +INSERT INTO t2 VALUES (0,'j'),(8,'v'); +SELECT * FROM t1 alias1, t2 alias2 +WHERE alias2.c IN ( +SELECT alias4.c FROM t1 alias3, t2 alias4 +); +a b c +e 0 j +e 8 v +w 0 j +w 8 v +a 0 j +a 8 v +h 0 j +h 8 v +x 0 j +x 8 v +k 0 j +k 8 v +g 0 j +g 8 v +DROP TABLE t1, t2; +# +# BUG#923246: Loosescan reports different result than other semijoin methods +# +set @tmp_923246= @@optimizer_switch; +set optimizer_switch='mrr=on,materialization=off'; +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (kp1 int, kp2 int, c int, filler char(100), key(kp1, kp2)); +insert into t1 select A.a+10*(B.a+10*C.a), 0, 0, 'filler' from t0 A, t0 B, t0 C; +insert into t1 select * from t1 where kp1 < 20; +create table t3 (a int); +insert into t3 select A.a + 10*B.a from t0 A, t0 B; +select * from t3 where a in (select kp1 from t1 where kp1<20); +a +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +explain select * from t3 where a in (select kp1 from t1 where kp1<20); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using where; Using index; LooseScan +1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join) +drop table t0,t1,t3; +set optimizer_switch= @tmp_923246; set optimizer_switch=@subselect_sj_tmp; diff --git a/mysql-test/r/subselect_sj2.result b/mysql-test/r/subselect_sj2.result index 85a3b6971bd..2d8c189942e 100644 --- a/mysql-test/r/subselect_sj2.result +++ b/mysql-test/r/subselect_sj2.result @@ -886,5 +886,19 @@ a b b a c c NULL NULL DROP VIEW v1; DROP TABLE t1,t2,t3,t4; +# +# BUG#912538: Wrong result (missing rows) with semijoin=on, firstmatch=on, ... +# +CREATE TABLE t1 ( a INT NOT NULL, UNIQUE KEY(a) ); +INSERT INTO t1 VALUES (1),(2),(3),(4); +CREATE TABLE t2 ( b INT, c INT ) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,1); +SELECT * FROM t1, t2 WHERE c IN (SELECT c FROM t1, t2 WHERE a = b); +a b c +1 1 1 +2 1 1 +3 1 1 +4 1 1 +DROP TABLE t1,t2; # This must be the last in the file: set optimizer_switch=@subselect_sj2_tmp; diff --git a/mysql-test/r/subselect_sj2_jcl6.result b/mysql-test/r/subselect_sj2_jcl6.result index b179a735f20..f2895662196 100644 --- a/mysql-test/r/subselect_sj2_jcl6.result +++ b/mysql-test/r/subselect_sj2_jcl6.result @@ -900,6 +900,20 @@ a b b a c c NULL NULL DROP VIEW v1; DROP TABLE t1,t2,t3,t4; +# +# BUG#912538: Wrong result (missing rows) with semijoin=on, firstmatch=on, ... +# +CREATE TABLE t1 ( a INT NOT NULL, UNIQUE KEY(a) ); +INSERT INTO t1 VALUES (1),(2),(3),(4); +CREATE TABLE t2 ( b INT, c INT ) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,1); +SELECT * FROM t1, t2 WHERE c IN (SELECT c FROM t1, t2 WHERE a = b); +a b c +1 1 1 +2 1 1 +3 1 1 +4 1 1 +DROP TABLE t1,t2; # This must be the last in the file: set optimizer_switch=@subselect_sj2_tmp; # @@ -921,9 +935,9 @@ SELECT t3.* FROM t1 JOIN t3 ON t3.b = t1.b WHERE c IN (SELECT t4.b FROM t4 JOIN t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where -1 PRIMARY t2 ALL NULL NULL NULL NULL 1 +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 FirstMatch(t3) 1 PRIMARY t1 ref b b 4 test.t3.b 1 Using index -1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t2) +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1) SELECT t3.* FROM t1 JOIN t3 ON t3.b = t1.b WHERE c IN (SELECT t4.b FROM t4 JOIN t2); b c @@ -949,12 +963,13 @@ EXPLAIN SELECT * FROM t1, t2 WHERE b IN (SELECT a FROM t3, t4 WHERE b = pk); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 -1 PRIMARY t4 ALL NULL NULL NULL NULL 1 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 1 Using where; FirstMatch(t2) 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 -1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.b 1 Using where; FirstMatch(t4) +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.b 1 Using where; FirstMatch(t1) SELECT * FROM t1, t2 WHERE b IN (SELECT a FROM t3, t4 WHERE b = pk); pk a b 1 6 8 +2 8 8 set optimizer_switch=@tmp_optimizer_switch; set join_cache_level=default; DROP TABLE t1,t2,t3,t4; diff --git a/mysql-test/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result index 0284bab0972..3e68c9ebeb5 100644 --- a/mysql-test/r/subselect_sj2_mat.result +++ b/mysql-test/r/subselect_sj2_mat.result @@ -888,6 +888,20 @@ a b b a c c NULL NULL DROP VIEW v1; DROP TABLE t1,t2,t3,t4; +# +# BUG#912538: Wrong result (missing rows) with semijoin=on, firstmatch=on, ... +# +CREATE TABLE t1 ( a INT NOT NULL, UNIQUE KEY(a) ); +INSERT INTO t1 VALUES (1),(2),(3),(4); +CREATE TABLE t2 ( b INT, c INT ) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,1); +SELECT * FROM t1, t2 WHERE c IN (SELECT c FROM t1, t2 WHERE a = b); +a b c +1 1 1 +2 1 1 +3 1 1 +4 1 1 +DROP TABLE t1,t2; # This must be the last in the file: set optimizer_switch=@subselect_sj2_tmp; set optimizer_switch=default; diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index 88acba0ebea..96fe8819705 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -1244,6 +1244,364 @@ IN (SELECT t3.pk, t3.pk FROM t2 LEFT JOIN t3 ON t3.varchar_key) AND pk = 9; datetime_key DROP TABLE t1, t2, t3; +# +# BUG#53060: LooseScan semijoin strategy does not return all rows +# +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=on,materialization=off'; +set optimizer_switch='firstmatch=off,loosescan=on'; +CREATE TABLE t1 (i INTEGER); +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +CREATE TABLE t2 (i INTEGER, j INTEGER, KEY k(i, j)); +INSERT INTO t2 VALUES (1, 0), (1, 1), (2, 0), (2, 1); +EXPLAIN +SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 index k k 10 NULL 4 Using where; Using index; LooseScan +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join) +SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0); +i +1 +2 +DROP TABLE t1, t2; +set optimizer_switch=@save_optimizer_switch; +# +# BUG#49453: re-execution of prepared statement with view +# and semijoin crashes +# +CREATE TABLE t1 (city VARCHAR(50), country_id INT); +CREATE TABLE t2 (country_id INT, country VARCHAR(50)); +INSERT INTO t1 VALUES +('Batna',2),('Bchar',2),('Skikda',2),('Tafuna',3),('Algeria',2) ; +INSERT INTO t2 VALUES (2,'Algeria'),(2,'AlgeriaDup'),(3,'XAmerican Samoa'); +CREATE VIEW v1 AS +SELECT country_id as vf_country_id +FROM t2 +WHERE LEFT(country,1) = "A"; +PREPARE stmt FROM " +SELECT city, country_id +FROM t1 +WHERE country_id IN (SELECT vf_country_id FROM v1); +"; + +EXECUTE stmt; +city country_id +Batna 2 +Bchar 2 +Skikda 2 +Algeria 2 +EXECUTE stmt; +city country_id +Batna 2 +Bchar 2 +Skikda 2 +Algeria 2 +DROP TABLE t1,t2; +DROP VIEW v1; +# +# Bug#54437 Extra rows with LEFT JOIN + semijoin +# +create table t1 (a int); +create table t2 (a int); +create table t3 (a int); +insert into t1 values(1),(1); +insert into t2 values(1),(1),(1),(1); +insert into t3 values(2),(2); +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='materialization=off'; +set optimizer_switch='semijoin=off'; +explain +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using where +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +a +1 +1 +set optimizer_switch='semijoin=on'; +explain +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; Start temporary; Using join buffer (flat, BNL join) +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (incremental, BNL join) +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +a +1 +1 +set optimizer_switch=@save_optimizer_switch; +drop table t1,t2,t3; +# +# Bug#55955: crash in MEMORY engine with IN(LEFT JOIN (JOIN)) +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); +CREATE TABLE t3 (a INT); +INSERT INTO t1 VALUES(1),(1); +INSERT INTO t2 VALUES(1),(1); +INSERT INTO t3 VALUES(2),(2); +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=off,materialization=off'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2inner ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join) +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +a +1 +1 +set optimizer_switch='semijoin=off,materialization=on'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 +2 MATERIALIZED t2inner ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join) +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +a +1 +1 +set optimizer_switch='semijoin=on,materialization=off'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2inner ALL NULL NULL NULL NULL 2 Using join buffer (incremental, BNL join) +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (incremental, BNL join) +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +a +1 +1 +set optimizer_switch=@save_optimizer_switch; +DROP TABLE t1,t2,t3; +# +# BUG#52329 - Wrong result: subquery materialization, IN, +# non-null field followed by nullable +# +CREATE TABLE t1 (a1 CHAR(8) NOT NULL, a2 char(8) NOT NULL); +CREATE TABLE t2a (b1 char(8), b2 char(8)); +CREATE TABLE t2b (b1 CHAR(8), b2 char(8) NOT NULL); +CREATE TABLE t2c (b1 CHAR(8) NOT NULL, b2 char(8)); +INSERT INTO t1 VALUES ('1 - 12', '2 - 22'); +INSERT INTO t2a VALUES ('1 - 11', '2 - 21'), +('1 - 11', '2 - 21'), +('1 - 12', '2 - 22'), +('1 - 12', '2 - 22'), +('1 - 13', '2 - 23'); +INSERT INTO t2b SELECT * FROM t2a; +INSERT INTO t2c SELECT * FROM t2a; +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=off,materialization=on'; +SELECT * FROM t1 +WHERE (a1, a2) IN ( +SELECT b1, b2 FROM t2c WHERE b1 > '0' GROUP BY b1, b2); +a1 a2 +1 - 12 2 - 22 +SELECT * FROM t1 +WHERE (a1, a2) IN ( +SELECT b1, b2 FROM t2a WHERE b1 > '0'); +a1 a2 +1 - 12 2 - 22 +SELECT * FROM t1 +WHERE (a1, a2) IN ( +SELECT b1, b2 FROM t2b WHERE b1 > '0'); +a1 a2 +1 - 12 2 - 22 +SELECT * FROM t1 +WHERE (a1, a2) IN ( +SELECT b1, b2 FROM t2c WHERE b1 > '0'); +a1 a2 +1 - 12 2 - 22 +set optimizer_switch=@save_optimizer_switch; +DROP TABLE t1,t2a,t2b,t2c; +# +# Bug#57623: subquery within before insert trigger causes crash (sj=on) +# +CREATE TABLE ot1(a INT); +CREATE TABLE ot2(a INT); +CREATE TABLE ot3(a INT); +CREATE TABLE it1(a INT); +INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7); +INSERT INTO ot2 VALUES(0),(2),(4),(6); +INSERT INTO ot3 VALUES(0),(3),(6); +INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7); +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=on'; +set optimizer_switch='materialization=off'; +explain SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot1 ALL NULL NULL NULL NULL 8 +1 PRIMARY ot3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) +1 PRIMARY ot2 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (incremental, BNL join) +2 DEPENDENT SUBQUERY it1 ALL NULL NULL NULL NULL 8 Using where +SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); +a a a +0 0 0 +6 6 6 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +7 NULL NULL +prepare s from 'SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1)'; +execute s; +a a a +0 0 0 +6 6 6 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +7 NULL NULL +execute s; +a a a +0 0 0 +6 6 6 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +7 NULL NULL +deallocate prepare s; +set optimizer_switch='materialization=on'; +explain SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot1 ALL NULL NULL NULL NULL 8 +1 PRIMARY ot3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) +1 PRIMARY ot2 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (incremental, BNL join) +2 MATERIALIZED it1 ALL NULL NULL NULL NULL 8 +SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); +a a a +0 0 0 +6 6 6 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +7 NULL NULL +prepare s from 'SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1)'; +execute s; +a a a +0 0 0 +6 6 6 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +7 NULL NULL +execute s; +a a a +0 0 0 +6 6 6 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +7 NULL NULL +deallocate prepare s; +set optimizer_switch=@save_optimizer_switch; +DROP TABLE ot1, ot2, ot3, it1; +# +# Bug#59919/11766739: Crash in tmp_table_param::init() with semijoin=on +# +CREATE TABLE t1 (f1 INTEGER) ENGINE=MyISAM; +CREATE TABLE t2 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM; +CREATE TABLE t3 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1,1), (2,1); +INSERT INTO t3 VALUES +(1,1), (2,1), (5,4), (7,3), (8,2), (8,1), (7,3), +(9,5), (4,3), (7,2), (7,7), (3,1), (5,8), (9,7); +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=off,materialization=on'; +EXPLAIN +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 +FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 14 Using where +2 MATERIALIZED t1 system NULL NULL NULL NULL 1 +2 MATERIALIZED b1 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED b2 ALL NULL NULL NULL NULL 2 +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 +FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +f1 f2 +1 1 +2 1 +8 1 +3 1 +set optimizer_switch='semijoin=on,materialization=on'; +EXPLAIN +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 +FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1 +1 PRIMARY t3 ALL NULL NULL NULL NULL 14 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED b1 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED b2 ALL NULL NULL NULL NULL 2 +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 +FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +f1 f2 +1 1 +2 1 +8 1 +3 1 +set optimizer_switch=@save_optimizer_switch; +DROP TABLE t1, t2, t3 ; +# # # BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 # @@ -2193,6 +2551,107 @@ WHERE c = b AND b = a a COUNT(*) NULL 0 DROP TABLE t1, t2, t3; +# +# BUG#920255: Wrong result (extra rows) with loosescan and IN subquery +# +CREATE TABLE t1 ( a INT PRIMARY KEY, b INT, KEY(b) ); +INSERT INTO t1 VALUES +(1,2),(2,1),(3,3),(4,2),(5,5), +(6,3),(7,1),(8,4),(9,3),(10,2); +CREATE TABLE t2 ( c INT, d INT, UNIQUE KEY(c) ); +INSERT INTO t2 VALUES +(1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1); +SELECT a, b, d FROM t1, t2 +WHERE ( b, d ) IN +( SELECT b, d FROM t1, t2 WHERE b = c ); +a b d +1 2 1 +1 2 1 +2 1 2 +2 1 2 +3 3 3 +3 3 3 +4 2 1 +4 2 1 +5 5 5 +6 3 3 +6 3 3 +7 1 2 +7 1 2 +8 4 2 +8 4 2 +9 3 3 +9 3 3 +10 2 1 +10 2 1 +DROP TABLE t1, t2; +# +# BUG#920713: Wrong result (missing rows) with firstmatch+BNL, IN subquery, ... +# +CREATE TABLE t1 ( a VARCHAR(1) ) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('e'),('w'),('a'),('h'),('x'),('k'),('g'); +CREATE TABLE t2 ( b INT, c VARCHAR(1) ); +INSERT INTO t2 VALUES (0,'j'),(8,'v'); +SELECT * FROM t1 alias1, t2 alias2 +WHERE alias2.c IN ( +SELECT alias4.c FROM t1 alias3, t2 alias4 +); +a b c +e 0 j +e 8 v +w 0 j +w 8 v +a 0 j +a 8 v +h 0 j +h 8 v +x 0 j +x 8 v +k 0 j +k 8 v +g 0 j +g 8 v +DROP TABLE t1, t2; +# +# BUG#923246: Loosescan reports different result than other semijoin methods +# +set @tmp_923246= @@optimizer_switch; +set optimizer_switch='mrr=on,materialization=off'; +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (kp1 int, kp2 int, c int, filler char(100), key(kp1, kp2)); +insert into t1 select A.a+10*(B.a+10*C.a), 0, 0, 'filler' from t0 A, t0 B, t0 C; +insert into t1 select * from t1 where kp1 < 20; +create table t3 (a int); +insert into t3 select A.a + 10*B.a from t0 A, t0 B; +select * from t3 where a in (select kp1 from t1 where kp1<20); +a +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +explain select * from t3 where a in (select kp1 from t1 where kp1<20); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using where; Using index; LooseScan +1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join) +drop table t0,t1,t3; +set optimizer_switch= @tmp_923246; set optimizer_switch=@subselect_sj_tmp; # # BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off @@ -2274,6 +2733,158 @@ w 5 19:11:10 set optimizer_switch=@save_optimizer_switch; set join_cache_level=default; DROP TABLE t1,t2,t3; +# +# BUG#912513: Wrong result (missing rows) with join_cache_hashed+materialization+semijoin=on +# +set @os_912513= @@optimizer_switch; +set @jcl_912513= @@join_cache_level; +SET optimizer_switch = 'semijoin=on,materialization=on,join_cache_hashed=on'; +SET join_cache_level = 3; +CREATE TABLE t1 ( a INT, b INT, KEY(a) ); +INSERT INTO t1 VALUES +(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7); +CREATE TABLE t2 ( c INT ); +INSERT INTO t2 VALUES (1),(2),(3),(4),(5),(6),(7); +SELECT alias1.* FROM +t1 AS alias1 INNER JOIN t1 AS alias2 +ON alias2.a = alias1.b +WHERE alias1.b IN ( +SELECT a FROM t1, t2 +); +a b +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +DROP table t1, t2; +set @@optimizer_switch= @os_912513; +set @@join_cache_level= @jcl_912513; +# End +# +# BUG#934342: outer join + semijoin materialization +# + join_cache_level > 2 +# +CREATE TABLE t1 (a varchar(1), b varchar(1), INDEX idx_a(a) ); +INSERT INTO t1 VALUES ('v','v'), ('w','w'), ('t','t'); +CREATE TABLE t2 (c varchar(1), INDEX idx_c(c) ); +INSERT INTO t2 VALUES ('v'), ('v'), ('s'), ('j'); +CREATE TABLE t3 (c varchar(1), d varchar(1), INDEX idx_c(c) ); +INSERT INTO t3 VALUES ('v','v'), ('v','v'), ('s','s'), ('j','j'); +INSERT INTO t3 VALUES ('m','m'), ('d','d'), ('k','k'), ('m','m'); +set @tmp_otimizer_switch= @@optimizer_switch; +set @tmp_join_cache_level=@@join_cache_level; +set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on'; +set join_cache_level=0; +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY t2 ref idx_c idx_c 4 test.t1.b 2 Using where; Using index +2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +a b c +v v v +v v v +w w NULL +t t NULL +EXPLAIN +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY t3 ref idx_c idx_c 4 test.t1.b 2 Using where +2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +a b c d +v v v v +v v v v +w w NULL NULL +t t NULL NULL +set join_cache_level=6; +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY t2 ref idx_c idx_c 4 test.t1.b 2 Using where; Using index +2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +a b c +v v v +v v v +w w NULL +t t NULL +EXPLAIN +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY t3 ref idx_c idx_c 4 test.t1.b 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +a b c d +v v v v +v v v v +w w NULL NULL +t t NULL NULL +set optimizer_switch=@tmp_optimizer_switch; +set join_cache_level=@tmp_join_cache_level; +DROP TABLE t1,t2,t3; +# End +# +# BUG#934348: GROUP BY with HAVING + semijoin materialization +# + join_cache_level > 2 +# +CREATE TABLE t1 (a varchar(1), INDEX idx_a(a)); +INSERT INTO t1 VALUES ('c'), ('v'), ('c'); +CREATE TABLE t2 (b varchar(1)); +INSERT INTO t2 VALUES ('v'), ('c'); +set @tmp_otimizer_switch= @@optimizer_switch; +set @tmp_join_cache_level=@@join_cache_level; +set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on'; +set join_cache_level=0; +EXPLAIN +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) +GROUP BY a HAVING a != 'z'; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2 Using temporary; Using filesort +1 PRIMARY t ref idx_a idx_a 4 test.t2.b 2 Using index +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED t1 ref idx_a idx_a 4 test.t2.b 2 Using index +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) +GROUP BY a HAVING a != 'z'; +a +c +v +set join_cache_level=6; +EXPLAIN +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) +GROUP BY a HAVING a != 'z'; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2 Using temporary; Using filesort +1 PRIMARY t ref idx_a idx_a 4 test.t2.b 2 Using index +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED t1 ref idx_a idx_a 4 test.t2.b 2 Using index +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) +GROUP BY a HAVING a != 'z'; +a +c +v +set optimizer_switch=@tmp_optimizer_switch; +set join_cache_level=@tmp_join_cache_level; +DROP TABLE t1,t2; # End set join_cache_level=default; show variables like 'join_cache_level'; diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index ee8a365327c..e3c5926ffee 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -1849,6 +1849,55 @@ a b c 4 4 2 4 4 4 DROP TABLE t1,t2; +# +# BUG#922254: Assertion `0' failed at item_cmpfunc.cc:5899: Item* Item_equal::get_first(JOIN_TAB*, Item*) +# +CREATE TABLE t1 ( a VARCHAR(3) ); +CREATE TABLE t2 ( b VARCHAR(3), c VARCHAR(8), KEY(c) ); +INSERT INTO t2 VALUES ('USA','Abilene'),('USA','Akron'); +EXPLAIN +SELECT * FROM +( SELECT * FROM t1 ) AS alias1, +t2 AS alias2 +WHERE b = a AND a IN ( +SELECT alias3.c +FROM t2 AS alias3, t2 AS alias4 +WHERE alias4.c = alias3.b +); +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 +DROP TABLE t1,t2; +# +# BUG#928048: Query containing IN subquery with OR in the where clause returns a wrong result +# +create table t1 (a int, b int); +insert into t1 values (7,5), (3,3), (5,4), (9,3); +create table t2 (a int, b int, index i_a(a)); +insert into t2 values +(4,2), (7,9), (7,4), (3,1), (5,3), (3,1), (9,4), (8,1); +explain select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1 +2 MATERIALIZED t2 ALL i_a NULL NULL NULL 8 Using where +select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); +a b +7 5 +3 3 +drop table t1,t2; +# +# BUG#933407: Valgrind warnings in mark_as_null_row with materialization+semijoin, STRAIGHT_JOIN, impossible WHERE +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0),(8); +SELECT STRAIGHT_JOIN MIN(a) FROM t1 +WHERE a IN ( +SELECT a FROM t1 +WHERE 'condition'='impossible' + ); +MIN(a) +NULL +DROP TABLE t1; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/r/sum_distinct.result b/mysql-test/r/sum_distinct.result index c615817f52d..2746f5a09f4 100644 --- a/mysql-test/r/sum_distinct.result +++ b/mysql-test/r/sum_distinct.result @@ -95,3 +95,15 @@ SELECT SUM(DISTINCT id % 11) FROM t1; SUM(DISTINCT id % 11) 55 DROP TABLE t1; +# +# Bug #777654: empty subselect in FROM clause returning +# SUM(DISTINCT) over non-nullable field +# +CREATE TABLE t1 (a int NOT NULL) ; +SELECT SUM(DISTINCT a) FROM t1; +SUM(DISTINCT a) +NULL +SELECT * FROM (SELECT SUM(DISTINCT a) FROM t1) AS t; +SUM(DISTINCT a) +NULL +DROP TABLE t1; diff --git a/mysql-test/r/table_elim.result b/mysql-test/r/table_elim.result index 9b2656c17e4..69cd9792299 100644 --- a/mysql-test/r/table_elim.result +++ b/mysql-test/r/table_elim.result @@ -588,4 +588,23 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using index drop view v1; DROP TABLE t1,t2,t3; +# +# BUG#919878: Assertion `!eliminated_tables... +# +CREATE TABLE t1 ( a INT ); +INSERT INTO t1 VALUES (1); +CREATE TABLE t2 +( b INT, UNIQUE INDEX(b) ); +INSERT INTO t2 VALUES (1),(2); +EXPLAIN EXTENDED +SELECT * FROM t2 +WHERE b IN ( +SELECT SUM(a) FROM t1 LEFT JOIN t2 ON b=a +); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 index NULL b 5 NULL 2 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00 +Warnings: +Note 1003 select `test`.`t2`.`b` AS `b` from `test`.`t2` where <expr_cache><`test`.`t2`.`b`>(<in_optimizer>(`test`.`t2`.`b`,<exists>(select sum(1) from dual where 1 having (<cache>(`test`.`t2`.`b`) = <ref_null_helper>(sum(1)))))) +DROP TABLE t1,t2; SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result index 54170ae3dad..427374fd995 100644 --- a/mysql-test/r/update.result +++ b/mysql-test/r/update.result @@ -277,6 +277,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; update t1 set a=9999 order by a limit 1; @@ -289,6 +290,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 2 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 9 flush status; delete from t1 order by a limit 1; @@ -300,6 +302,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; delete from t1 order by a desc limit 1; @@ -311,6 +314,7 @@ Handler_read_last 1 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 alter table t1 disable keys; flush status; @@ -323,7 +327,8 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 1 -Handler_read_rnd_next 9 +Handler_read_rnd_deleted 2 +Handler_read_rnd_next 7 select * from t1; a b 0 0 @@ -377,6 +382,7 @@ Handler_read_last 0 Handler_read_next 1 Handler_read_prev 0 Handler_read_rnd 1 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 drop table t1, t2; create table t1(f1 int, `*f2` int); @@ -415,6 +421,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 SELECT user_id FROM t1 WHERE request_id=999999999999999999999999999999; user_id @@ -426,6 +433,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 UPDATE t1 SET user_id=null WHERE request_id=9999999999999; show status like '%Handler_read%'; @@ -436,6 +444,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 UPDATE t1 SET user_id=null WHERE request_id=999999999999999999999999999999; show status like '%Handler_read%'; @@ -446,6 +455,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 DROP TABLE t1; CREATE TABLE t1 ( diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index f2d3820ff58..9b6ae60b3b5 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -304,7 +304,7 @@ a+1 4 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort drop view v1; drop table t1; @@ -4045,6 +4045,63 @@ drop table t1,t2; # -- End of 5.1 tests. # ----------------------------------------------------------------- # +# Bug #794005: crash in st_table::mark_virtual_columns_for_write +# +CREATE TABLE t1 (a int); +insert into t1 values (1); +CREATE TABLE t2 (a int); +insert into t2 values (1); +CREATE VIEW v2 AS SELECT * FROM t2; +CREATE VIEW v1 AS SELECT * FROM v2; +CREATE VIEW v3 AS SELECT t2.a,v1.a as b FROM t2,v1 where t2.a=v1.a; +CREATE OR REPLACE ALGORITHM = TEMPTABLE VIEW v2 AS SELECT * FROM t1; +UPDATE v1 SET a = 10; +ERROR HY000: The target table v1 of the UPDATE is not updatable +REPLACE v1 SET a = 10; +ERROR HY000: The target table v1 of the INSERT is not insertable-into +INSERT into v1 values (20); +ERROR HY000: The target table v1 of the INSERT is not insertable-into +DELETE from v1; +ERROR HY000: The target table v1 of the DELETE is not updatable +UPDATE v3 SET b= 10; +ERROR HY000: The target table v2 of the UPDATE is not updatable +REPLACE v3 SET b= 10; +ERROR HY000: The target table v3 of the INSERT is not insertable-into +INSERT into v3(b) values (20); +ERROR HY000: The target table v3 of the INSERT is not insertable-into +DELETE from v3 where b=20; +ERROR HY000: Can not delete from join view 'test.v3' +DELETE from v3 where a=20; +ERROR HY000: Can not delete from join view 'test.v3' +DELETE v1 from v1,t1 where v1.a=t1.a; +ERROR HY000: The target table v1 of the DELETE is not updatable +UPDATE v3 SET a = 10; +REPLACE v3 SET a = 11; +INSERT INTO v3(a) values (20); +select * from t1; +a +1 +select * from t2; +a +10 +11 +20 +CREATE OR REPLACE ALGORITHM = MERGE VIEW v2 AS SELECT * FROM t2; +DELETE from v1 where a=11; +DELETE v1 from v1,t1 where v1.a=t1.a; +select * from t1; +a +1 +select * from t2; +a +10 +20 +DROP VIEW v1,v2,v3; +DROP TABLE t1,t2; +# ----------------------------------------------------------------- +# -- End of 5.2 tests. +# ----------------------------------------------------------------- +# # Bug #59696 Optimizer does not use equalities for conditions over view # CREATE TABLE t1 (a int NOT NULL); @@ -4075,6 +4132,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 CREATE VIEW v AS SELECT * FROM t2; EXPLAIN EXTENDED @@ -4097,6 +4155,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 DROP VIEW v; DROP TABLE t1, t2; @@ -4569,4 +4628,7 @@ NULL NULL 1 0 NULL NULL 1 0 DROP VIEW v2; DROP TABLE t1, t2, t3; +# ----------------------------------------------------------------- +# -- End of 5.3 tests. +# ----------------------------------------------------------------- SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 5223c566475..a1782ea5f6e 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -2933,26 +2933,6 @@ a DROP TABLE t1,t2; End of 5.3 tests # -# Test for bug #39932 "create table fails if column for FK is in different -# case than in corr index". -# -drop tables if exists t1, t2; -create table t1 (pk int primary key) engine=InnoDB; -# Even although the below statement uses uppercased field names in -# foreign key definition it still should be able to find explicitly -# created supporting index. So it should succeed and should not -# create any additional supporting indexes. -create table t2 (fk int, key x (fk), -constraint x foreign key (FK) references t1 (PK)) engine=InnoDB; -show create table t2; -Table Create Table -t2 CREATE TABLE `t2` ( - `fk` int(11) DEFAULT NULL, - KEY `x` (`fk`), - CONSTRAINT `x` FOREIGN KEY (`fk`) REFERENCES `t1` (`pk`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 -drop table t2, t1; -# # Test for bug #11762012 - "54553: INNODB ASSERTS IN HA_INNOBASE:: # UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK". # diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test index 54628b0fb1b..c2309c0fcd6 100644 --- a/mysql-test/suite/innodb/t/innodb.test +++ b/mysql-test/suite/innodb/t/innodb.test @@ -19,6 +19,7 @@ # # ####################################################################### +-- source include/have_innodb.inc let $MYSQLD_DATADIR= `select @@datadir`; let collation=utf8_unicode_ci; --source include/have_collation.inc diff --git a/mysql-test/suite/innodb/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test index 498bd3f443f..378df7fdcd8 100644 --- a/mysql-test/suite/innodb/t/innodb_mysql.test +++ b/mysql-test/suite/innodb/t/innodb_mysql.test @@ -1101,24 +1101,6 @@ DROP TABLE t1,t2; --echo End of 5.3 tests --echo # ---echo # Test for bug #39932 "create table fails if column for FK is in different ---echo # case than in corr index". ---echo # ---disable_warnings -drop tables if exists t1, t2; ---enable_warnings -create table t1 (pk int primary key) engine=InnoDB; ---echo # Even although the below statement uses uppercased field names in ---echo # foreign key definition it still should be able to find explicitly ---echo # created supporting index. So it should succeed and should not ---echo # create any additional supporting indexes. -create table t2 (fk int, key x (fk), - constraint x foreign key (FK) references t1 (PK)) engine=InnoDB; -show create table t2; -drop table t2, t1; - - ---echo # --echo # Test for bug #11762012 - "54553: INNODB ASSERTS IN HA_INNOBASE:: --echo # UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK". --echo # diff --git a/mysql-test/suite/maria/r/maria-gis-recovery.result b/mysql-test/suite/maria/r/maria-gis-recovery.result new file mode 100644 index 00000000000..d1088dd1ba0 --- /dev/null +++ b/mysql-test/suite/maria/r/maria-gis-recovery.result @@ -0,0 +1,66 @@ +set global aria_log_file_size=4294967295; +Warnings: +Warning 1292 Truncated incorrect aria_log_file_size value: '4294967295' +drop database if exists mysqltest; +create database mysqltest; +use mysqltest; +* shut down mysqld, removed logs, restarted it +CREATE TABLE t1 ( +i int, +shape GEOMETRY NOT NULL, +SPATIAL (shape) +) ENGINE=ARIA; +insert into t1 values(1,POINT(1, 1)); +* copied t1 for feeding_recovery +insert into t1 values(2,POINT(2, 2)), (3,POINT(3, 3)), (4,POINT(4, 4)); +flush table t1; +* copied t1 for comparison +SET SESSION debug_dbug="+d,maria_flush_whole_log,maria_crash"; +* crashing mysqld intentionally +set global aria_checkpoint_interval=1; +ERROR HY000: Lost connection to MySQL server during query +* copied t1 back for feeding_recovery +* recovery happens +check table t1 extended; +Table Op Msg_type Msg_text +mysqltest.t1 check status OK +* testing that checksum after recovery is as expected +Checksum-check +ok +use mysqltest; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL, + `shape` geometry NOT NULL, + SPATIAL KEY `shape` (`shape`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +* TEST of UPDATE vs state.auto_increment +* copied t1 for feeding_recovery +update t1 set shape=POINT(5, 5) where i=2; +flush table t1; +* copied t1 for comparison +SET SESSION debug_dbug="+d,maria_flush_whole_log,maria_crash"; +* crashing mysqld intentionally +set global aria_checkpoint_interval=1; +ERROR HY000: Lost connection to MySQL server during query +* copied t1 back for feeding_recovery +* recovery happens +check table t1 extended; +Table Op Msg_type Msg_text +mysqltest.t1 check status OK +* testing that checksum after recovery is as expected +Checksum-check +ok +use mysqltest; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL, + `shape` geometry NOT NULL, + SPATIAL KEY `shape` (`shape`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +drop table t1; +drop database mysqltest_for_feeding_recovery; +drop database mysqltest_for_comparison; +drop database mysqltest; diff --git a/mysql-test/suite/maria/t/maria-gis-recovery.opt b/mysql-test/suite/maria/t/maria-gis-recovery.opt new file mode 100644 index 00000000000..58d0d012c54 --- /dev/null +++ b/mysql-test/suite/maria/t/maria-gis-recovery.opt @@ -0,0 +1 @@ +--skip-stack-trace --skip-core-file --loose-aria-log-dir-path=$MYSQLTEST_VARDIR/tmp diff --git a/mysql-test/suite/maria/t/maria-gis-recovery.test b/mysql-test/suite/maria/t/maria-gis-recovery.test new file mode 100644 index 00000000000..c40cc3788de --- /dev/null +++ b/mysql-test/suite/maria/t/maria-gis-recovery.test @@ -0,0 +1,64 @@ +--source include/not_embedded.inc +# Don't test this under valgrind, memory leaks will occur as we crash +--source include/not_valgrind.inc +# Binary must be compiled with debug for crash to occur +--source include/have_debug.inc +--source include/have_maria.inc +--source include/have_geometry.inc + +set global aria_log_file_size=4294967295; +let $MARIA_LOG=../../tmp; + +--disable_warnings +drop database if exists mysqltest; +--enable_warnings +create database mysqltest; +let $mms_tname=t; + +# Include scripts can perform SQL. For it to not influence the main test +# they use a separate connection. This way if they use a DDL it would +# not autocommit in the main test. +connect (admin, localhost, root,,mysqltest,,); +--enable_reconnect + +connection default; +use mysqltest; +--enable_reconnect + +-- source include/maria_empty_logs.inc +let $mms_tables=1; +CREATE TABLE t1 ( + i int, + shape GEOMETRY NOT NULL, + SPATIAL (shape) +) ENGINE=ARIA; +insert into t1 values(1,POINT(1, 1)); +-- source include/maria_make_snapshot_for_feeding_recovery.inc +insert into t1 values(2,POINT(2, 2)), (3,POINT(3, 3)), (4,POINT(4, 4)); +-- source include/maria_make_snapshot_for_comparison.inc +let $mvr_restore_old_snapshot=1; +let $mms_compare_physically=0; +let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; +-- source include/maria_verify_recovery.inc +show create table t1; + +# Test that UPDATE's effect on auto-increment is recovered +--echo * TEST of UPDATE vs state.auto_increment +-- source include/maria_make_snapshot_for_feeding_recovery.inc +update t1 set shape=POINT(5, 5) where i=2; +-- source include/maria_make_snapshot_for_comparison.inc +let $mvr_restore_old_snapshot=1; +let $mms_compare_physically=0; +let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; +-- source include/maria_verify_recovery.inc +show create table t1; +drop table t1; + +# clean up everything +let $mms_purpose=feeding_recovery; +eval drop database mysqltest_for_$mms_purpose; +let $mms_purpose=comparison; +eval drop database mysqltest_for_$mms_purpose; +drop database mysqltest; diff --git a/mysql-test/suite/pbxt/r/heap.result.THIS b/mysql-test/suite/pbxt/r/heap.result.THIS deleted file mode 100644 index 0404e8b98f9..00000000000 --- a/mysql-test/suite/pbxt/r/heap.result.THIS +++ /dev/null @@ -1,733 +0,0 @@ -drop table if exists t1,t2,t3; -create table t1 (a int not null,b int not null, primary key (a)) engine=heap comment="testing heaps" avg_row_length=100 min_rows=1 max_rows=100; -insert into t1 values(1,1),(2,2),(3,3),(4,4); -delete from t1 where a=1 or a=0; -show keys from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t1 0 PRIMARY 1 a NULL 3 NULL NULL HASH -select * from t1; -a b -2 2 -3 3 -4 4 -select * from t1 where a=4; -a b -4 4 -update t1 set b=5 where a=4; -update t1 set b=b+1 where a>=3; -replace t1 values (3,3); -select * from t1; -a b -2 2 -3 3 -4 6 -alter table t1 add c int not null, add key (c,a); -drop table t1; -create table t1 (a int not null,b int not null, primary key (a)) engine=memory comment="testing heaps"; -insert into t1 values(1,1),(2,2),(3,3),(4,4); -delete from t1 where a > 0; -select * from t1; -a b -drop table t1; -create table t1 (a int not null,b int not null, primary key (a)) engine=heap comment="testing heaps"; -insert into t1 values(1,1),(2,2),(3,3),(4,4); -alter table t1 modify a int not null auto_increment, engine=myisam, comment="new myisam table"; -select * from t1; -a b -1 1 -2 2 -3 3 -4 4 -drop table t1; -create table t1 (a int not null) engine=heap; -insert into t1 values (869751),(736494),(226312),(802616),(728912); -select * from t1 where a > 736494; -a -869751 -802616 -alter table t1 add unique uniq_id(a); -select * from t1 where a > 736494; -a -869751 -802616 -select * from t1 where a = 736494; -a -736494 -select * from t1 where a=869751 or a=736494; -a -736494 -869751 -select * from t1 where a in (869751,736494,226312,802616); -a -226312 -736494 -802616 -869751 -alter table t1 engine=myisam; -explain select * from t1 where a in (869751,736494,226312,802616); -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range uniq_id uniq_id 4 NULL 4 Using where; Using index -drop table t1; -create table t1 (x int not null, y int not null, key x (x), unique y (y)) -engine=heap; -insert into t1 values (1,1),(2,2),(1,3),(2,4),(2,5),(2,6); -select * from t1 where x=1; -x y -1 3 -1 1 -select * from t1,t1 as t2 where t1.x=t2.y; -x y x y -1 1 1 1 -2 2 2 2 -1 3 1 1 -2 4 2 2 -2 5 2 2 -2 6 2 2 -explain select * from t1,t1 as t2 where t1.x=t2.y; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL x NULL NULL NULL 6 -1 SIMPLE t2 eq_ref y y 4 test.t1.x 1 -drop table t1; -create table t1 (a int) engine=heap; -insert into t1 values(1); -select max(a) from t1; -max(a) -1 -drop table t1; -CREATE TABLE t1 ( a int not null default 0, b int not null default 0, key(a), key(b) ) ENGINE=HEAP; -insert into t1 values(1,1),(1,2),(2,3),(1,3),(1,4),(1,5),(1,6); -select * from t1 where a=1; -a b -1 6 -1 5 -1 4 -1 3 -1 2 -1 1 -insert into t1 values(1,1),(1,2),(2,3),(1,3),(1,4),(1,5),(1,6); -select * from t1 where a=1; -a b -1 6 -1 5 -1 4 -1 3 -1 2 -1 1 -1 6 -1 5 -1 4 -1 3 -1 2 -1 1 -drop table t1; -create table t1 (id int unsigned not null, primary key (id)) engine=HEAP; -insert into t1 values(1); -select max(id) from t1; -max(id) -1 -insert into t1 values(2); -select max(id) from t1; -max(id) -2 -replace into t1 values(1); -drop table t1; -create table t1 (n int) engine=heap; -drop table t1; -create table t1 (n int) engine=heap; -drop table if exists t1; -CREATE table t1(f1 int not null,f2 char(20) not -null,index(f2)) engine=heap; -INSERT into t1 set f1=12,f2="bill"; -INSERT into t1 set f1=13,f2="bill"; -INSERT into t1 set f1=14,f2="bill"; -INSERT into t1 set f1=15,f2="bill"; -INSERT into t1 set f1=16,f2="ted"; -INSERT into t1 set f1=12,f2="ted"; -INSERT into t1 set f1=12,f2="ted"; -INSERT into t1 set f1=12,f2="ted"; -INSERT into t1 set f1=12,f2="ted"; -delete from t1 where f2="bill"; -select * from t1; -f1 f2 -16 ted -12 ted -12 ted -12 ted -12 ted -drop table t1; -create table t1 (btn char(10) not null, key(btn)) engine=heap; -insert into t1 values ("hello"),("hello"),("hello"),("hello"),("hello"),("a"),("b"),("c"),("d"),("e"),("f"),("g"),("h"),("i"); -explain select * from t1 where btn like "q%"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL btn NULL NULL NULL 14 Using where -select * from t1 where btn like "q%"; -btn -alter table t1 add column new_col char(1) not null, add key (btn,new_col), drop key btn; -update t1 set new_col=left(btn,1); -explain select * from t1 where btn="a"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL btn NULL NULL NULL 14 Using where -explain select * from t1 where btn="a" and new_col="a"; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref btn btn 11 const,const 2 Using where -drop table t1; -CREATE TABLE t1 ( -a int default NULL, -b int default NULL, -KEY a (a), -UNIQUE b (b) -) engine=heap; -INSERT INTO t1 VALUES (NULL,99),(99,NULL),(1,1),(2,2),(1,3); -SELECT * FROM t1 WHERE a=NULL; -a b -explain SELECT * FROM t1 WHERE a IS NULL; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref a a 5 const 2 Using where -SELECT * FROM t1 WHERE a<=>NULL; -a b -NULL 99 -SELECT * FROM t1 WHERE b=NULL; -a b -explain SELECT * FROM t1 WHERE b IS NULL; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref b b 5 const 1 Using where -SELECT * FROM t1 WHERE b<=>NULL; -a b -99 NULL -INSERT INTO t1 VALUES (1,3); -ERROR 23000: Duplicate entry '3' for key 'b' -DROP TABLE t1; -CREATE TABLE t1 ( -a int default NULL, -key a (a) -) ENGINE=HEAP; -INSERT INTO t1 VALUES (10), (10), (10); -EXPLAIN SELECT * FROM t1 WHERE a=10; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref a a 5 const 3 -SELECT * FROM t1 WHERE a=10; -a -10 -10 -10 -DROP TABLE t1; -CREATE TABLE t1 (a int not null, primary key(a)) engine=heap; -INSERT into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11); -DELETE from t1 where a < 100; -SELECT * from t1; -a -DROP TABLE t1; -CREATE TABLE `job_titles` ( -`job_title_id` int(6) unsigned NOT NULL default '0', -`job_title` char(18) NOT NULL default '', -PRIMARY KEY (`job_title_id`), -UNIQUE KEY `job_title_id` (`job_title_id`,`job_title`) -) ENGINE=HEAP; -SELECT MAX(job_title_id) FROM job_titles; -MAX(job_title_id) -NULL -DROP TABLE job_titles; -CREATE TABLE t1 (a INT NOT NULL, B INT, KEY(B)) ENGINE=HEAP; -INSERT INTO t1 VALUES(1,1), (1,NULL); -SELECT * FROM t1 WHERE B is not null; -a B -1 1 -DROP TABLE t1; -CREATE TABLE t1 (pseudo char(35) PRIMARY KEY, date int(10) unsigned NOT NULL) ENGINE=HEAP; -INSERT INTO t1 VALUES ('massecot',1101106491),('altec',1101106492),('stitch+',1101106304),('Seb Corgan',1101106305),('beerfilou',1101106263),('flaker',1101106529),('joce8',5),('M4vrick',1101106418),('gabay008',1101106525),('Vamp irX',1101106291),('ZoomZip',1101106546),('rip666',1101106502),('CBP ',1101106397),('guezpard',1101106496); -DELETE FROM t1 WHERE date<1101106546; -SELECT * FROM t1; -pseudo date -ZoomZip 1101106546 -DROP TABLE t1; -create table t1(a char(2)) engine=memory; -insert into t1 values (NULL), (NULL); -delete from t1 where a is null; -insert into t1 values ('2'), ('3'); -select * from t1; -a -3 -2 -drop table t1; -set storage_engine=HEAP; -create table t1 (v varchar(10), c char(10), t varchar(50)); -insert into t1 values('+ ', '+ ', '+ '); -set @a=repeat(' ',20); -insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a)); -Warnings: -Note 1265 Data truncated for column 'v' at row 1 -select concat('*',v,'*',c,'*',t,'*') from t1; -concat('*',v,'*',c,'*',t,'*') -*+ *+*+ * -*+ *+*+ * -show create table t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `v` varchar(10) DEFAULT NULL, - `c` char(10) DEFAULT NULL, - `t` varchar(50) DEFAULT NULL -) ENGINE=MEMORY DEFAULT CHARSET=latin1 -create table t2 like t1; -show create table t2; -Table Create Table -t2 CREATE TABLE `t2` ( - `v` varchar(10) DEFAULT NULL, - `c` char(10) DEFAULT NULL, - `t` varchar(50) DEFAULT NULL -) ENGINE=MEMORY DEFAULT CHARSET=latin1 -create table t3 select * from t1; -show create table t3; -Table Create Table -t3 CREATE TABLE `t3` ( - `v` varchar(10) DEFAULT NULL, - `c` char(10) DEFAULT NULL, - `t` varchar(50) DEFAULT NULL -) ENGINE=MEMORY DEFAULT CHARSET=latin1 -alter table t1 modify c varchar(10); -show create table t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `v` varchar(10) DEFAULT NULL, - `c` varchar(10) DEFAULT NULL, - `t` varchar(50) DEFAULT NULL -) ENGINE=MEMORY DEFAULT CHARSET=latin1 -alter table t1 modify v char(10); -show create table t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `v` char(10) DEFAULT NULL, - `c` varchar(10) DEFAULT NULL, - `t` varchar(50) DEFAULT NULL -) ENGINE=MEMORY DEFAULT CHARSET=latin1 -alter table t1 modify t varchar(10); -Warnings: -Warning 1265 Data truncated for column 't' at row 2 -show create table t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `v` char(10) DEFAULT NULL, - `c` varchar(10) DEFAULT NULL, - `t` varchar(10) DEFAULT NULL -) ENGINE=MEMORY DEFAULT CHARSET=latin1 -select concat('*',v,'*',c,'*',t,'*') from t1; -concat('*',v,'*',c,'*',t,'*') -*+*+*+ * -*+*+*+ * -drop table t1,t2,t3; -create table t1 (v varchar(10), c char(10), t varchar(50), key(v), key(c), key(t(10))); -show create table t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `v` varchar(10) DEFAULT NULL, - `c` char(10) DEFAULT NULL, - `t` varchar(50) DEFAULT NULL, - KEY `v` (`v`), - KEY `c` (`c`), - KEY `t` (`t`(10)) -) ENGINE=MEMORY DEFAULT CHARSET=latin1 -select count(*) from t1; -count(*) -270 -insert into t1 values(concat('a',char(1)),concat('a',char(1)),concat('a',char(1))); -select count(*) from t1 where v='a'; -count(*) -10 -select count(*) from t1 where c='a'; -count(*) -10 -select count(*) from t1 where t='a'; -count(*) -10 -select count(*) from t1 where v='a '; -count(*) -10 -select count(*) from t1 where c='a '; -count(*) -10 -select count(*) from t1 where t='a '; -count(*) -10 -select count(*) from t1 where v between 'a' and 'a '; -count(*) -10 -select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; -count(*) -10 -select count(*) from t1 where v like 'a%'; -count(*) -11 -select count(*) from t1 where c like 'a%'; -count(*) -11 -select count(*) from t1 where t like 'a%'; -count(*) -11 -select count(*) from t1 where v like 'a %'; -count(*) -9 -explain select count(*) from t1 where v='a '; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 13 const 10 Using where -explain select count(*) from t1 where c='a '; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref c c 11 const 10 Using where -explain select count(*) from t1 where t='a '; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref t t 13 const 10 Using where -explain select count(*) from t1 where v like 'a%'; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL v NULL NULL NULL 271 Using where -explain select count(*) from t1 where v between 'a' and 'a '; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 13 const 10 Using where -explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 13 const 10 Using where -alter table t1 add unique(v); -ERROR 23000: Duplicate entry '{ ' for key 'v_2' -select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a' order by length(concat('*',v,'*',c,'*',t,'*')); -qq -*a*a*a* -*a *a*a * -*a *a*a * -*a *a*a * -*a *a*a * -*a *a*a * -*a *a*a * -*a *a*a * -*a *a*a * -*a *a*a * -explain select * from t1 where v='a'; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 13 const 10 Using where -select v,count(*) from t1 group by v limit 10; -v count(*) -a 1 -a 10 -b 10 -c 10 -d 10 -e 10 -f 10 -g 10 -h 10 -i 10 -select v,count(t) from t1 group by v limit 10; -v count(t) -a 1 -a 10 -b 10 -c 10 -d 10 -e 10 -f 10 -g 10 -h 10 -i 10 -select v,count(c) from t1 group by v limit 10; -v count(c) -a 1 -a 10 -b 10 -c 10 -d 10 -e 10 -f 10 -g 10 -h 10 -i 10 -select sql_big_result trim(v),count(t) from t1 group by v limit 10; -trim(v) count(t) -a 1 -a 10 -b 10 -c 10 -d 10 -e 10 -f 10 -g 10 -h 10 -i 10 -select sql_big_result trim(v),count(c) from t1 group by v limit 10; -trim(v) count(c) -a 1 -a 10 -b 10 -c 10 -d 10 -e 10 -f 10 -g 10 -h 10 -i 10 -select c,count(*) from t1 group by c limit 10; -c count(*) -a 1 -a 10 -b 10 -c 10 -d 10 -e 10 -f 10 -g 10 -h 10 -i 10 -select c,count(t) from t1 group by c limit 10; -c count(t) -a 1 -a 10 -b 10 -c 10 -d 10 -e 10 -f 10 -g 10 -h 10 -i 10 -select sql_big_result c,count(t) from t1 group by c limit 10; -c count(t) -a 1 -a 10 -b 10 -c 10 -d 10 -e 10 -f 10 -g 10 -h 10 -i 10 -select t,count(*) from t1 group by t limit 10; -t count(*) -a 1 -a 10 -b 10 -c 10 -d 10 -e 10 -f 10 -g 10 -h 10 -i 10 -select t,count(t) from t1 group by t limit 10; -t count(t) -a 1 -a 10 -b 10 -c 10 -d 10 -e 10 -f 10 -g 10 -h 10 -i 10 -select sql_big_result trim(t),count(t) from t1 group by t limit 10; -trim(t) count(t) -a 1 -a 10 -b 10 -c 10 -d 10 -e 10 -f 10 -g 10 -h 10 -i 10 -drop table t1; -create table t1 (a char(10), unique (a)); -insert into t1 values ('a'); -insert into t1 values ('a '); -ERROR 23000: Duplicate entry 'a' for key 'a' -alter table t1 modify a varchar(10); -insert into t1 values ('a '),('a '),('a '),('a '); -ERROR 23000: Duplicate entry 'a ' for key 'a' -insert into t1 values ('a '); -ERROR 23000: Duplicate entry 'a ' for key 'a' -insert into t1 values ('a '); -ERROR 23000: Duplicate entry 'a ' for key 'a' -insert into t1 values ('a '); -ERROR 23000: Duplicate entry 'a ' for key 'a' -update t1 set a='a ' where a like 'a '; -update t1 set a='a ' where a like 'a '; -drop table t1; -create table t1 (v varchar(10), c char(10), t varchar(50), key using btree (v), key using btree (c), key using btree (t(10))); -show create table t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `v` varchar(10) DEFAULT NULL, - `c` char(10) DEFAULT NULL, - `t` varchar(50) DEFAULT NULL, - KEY `v` (`v`) USING BTREE, - KEY `c` (`c`) USING BTREE, - KEY `t` (`t`(10)) USING BTREE -) ENGINE=MEMORY DEFAULT CHARSET=latin1 -select count(*) from t1; -count(*) -270 -insert into t1 values(concat('a',char(1)),concat('a',char(1)),concat('a',char(1))); -select count(*) from t1 where v='a'; -count(*) -10 -select count(*) from t1 where c='a'; -count(*) -10 -select count(*) from t1 where t='a'; -count(*) -10 -select count(*) from t1 where v='a '; -count(*) -10 -select count(*) from t1 where c='a '; -count(*) -10 -select count(*) from t1 where t='a '; -count(*) -10 -select count(*) from t1 where v between 'a' and 'a '; -count(*) -10 -select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; -count(*) -10 -explain select count(*) from t1 where v='a '; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 13 const # Using where -explain select count(*) from t1 where c='a '; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref c c 11 const # Using where -explain select count(*) from t1 where t='a '; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref t t 13 const # Using where -explain select count(*) from t1 where v like 'a%'; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 13 NULL # Using where -explain select count(*) from t1 where v between 'a' and 'a '; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 13 const # Using where -explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 13 const # Using where -alter table t1 add unique(v); -ERROR 23000: Duplicate entry '{ ' for key 'v_2' -select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a' order by length(concat('*',v,'*',c,'*',t,'*')); -qq -*a*a*a* -*a *a*a * -*a *a*a * -*a *a*a * -*a *a*a * -*a *a*a * -*a *a*a * -*a *a*a * -*a *a*a * -*a *a*a * -explain select * from t1 where v='a'; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref v v 13 const # Using where -drop table t1; -create table t1 (a char(10), unique using btree (a)) engine=heap; -insert into t1 values ('a'); -insert into t1 values ('a '); -ERROR 23000: Duplicate entry 'a' for key 'a' -alter table t1 modify a varchar(10); -insert into t1 values ('a '),('a '),('a '),('a '); -ERROR 23000: Duplicate entry 'a ' for key 'a' -insert into t1 values ('a '); -ERROR 23000: Duplicate entry 'a ' for key 'a' -insert into t1 values ('a '); -ERROR 23000: Duplicate entry 'a ' for key 'a' -insert into t1 values ('a '); -ERROR 23000: Duplicate entry 'a ' for key 'a' -update t1 set a='a ' where a like 'a '; -update t1 set a='a ' where a like 'a '; -drop table t1; -create table t1 (v varchar(10), c char(10), t varchar(50), key(v(5)), key(c(5)), key(t(5))); -show create table t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `v` varchar(10) DEFAULT NULL, - `c` char(10) DEFAULT NULL, - `t` varchar(50) DEFAULT NULL, - KEY `v` (`v`(5)), - KEY `c` (`c`(5)), - KEY `t` (`t`(5)) -) ENGINE=MEMORY DEFAULT CHARSET=latin1 -drop table t1; -create table t1 (v varchar(65530), key(v(10))); -show create table t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `v` varchar(65530) DEFAULT NULL, - KEY `v` (`v`(10)) -) ENGINE=MEMORY DEFAULT CHARSET=latin1 -insert into t1 values(repeat('a',65530)); -select length(v) from t1 where v=repeat('a',65530); -length(v) -65530 -drop table t1; -set storage_engine=PBXT; -create table t1 (a bigint unsigned auto_increment primary key, b int, -key (b, a)) engine=heap; -insert t1 (b) values (1),(1),(1),(1),(1),(1),(1),(1); -select * from t1; -a b -1 1 -2 1 -3 1 -4 1 -5 1 -6 1 -7 1 -8 1 -drop table t1; -create table t1 (a int not null, b int not null auto_increment, -primary key(a, b), key(b)) engine=heap; -insert t1 (a) values (1),(1),(1),(1),(1),(1),(1),(1); -select * from t1; -a b -1 1 -1 2 -1 3 -1 4 -1 5 -1 6 -1 7 -1 8 -drop table t1; -create table t1 (a int not null, b int not null auto_increment, -primary key(a, b)) engine=heap; -ERROR 42000: Incorrect table definition; there can be only one auto column and it must be defined as a key -create table t1 (c char(255), primary key(c(90))); -insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); -insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); -ERROR 23000: Duplicate entry 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl' for key 'PRIMARY' -drop table t1; -CREATE TABLE t1 (a int, key(a)) engine=heap; -insert into t1 values (0); -delete from t1; -select * from t1; -a -insert into t1 values (0), (1); -select * from t1 where a = 0; -a -0 -drop table t1; -create table t1 (c char(10)) engine=memory; -create table t2 (c varchar(10)) engine=memory; -show table status like 't_'; -Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MEMORY 10 Fixed 0 11 0 # 0 0 NULL # NULL NULL latin1_swedish_ci NULL -t2 MEMORY 10 Fixed 0 12 0 # 0 0 NULL # NULL NULL latin1_swedish_ci NULL -drop table t1, t2; -CREATE TABLE t1(a VARCHAR(1), b VARCHAR(2), c VARCHAR(256), -KEY(a), KEY(b), KEY(c)) ENGINE=MEMORY; -INSERT INTO t1 VALUES('a','aa',REPEAT('a', 256)),('a','aa',REPEAT('a',256)); -SELECT COUNT(*) FROM t1 WHERE a='a'; -COUNT(*) -2 -SELECT COUNT(*) FROM t1 WHERE b='aa'; -COUNT(*) -2 -SELECT COUNT(*) FROM t1 WHERE c=REPEAT('a',256); -COUNT(*) -2 -DROP TABLE t1; diff --git a/mysql-test/suite/pbxt/r/null_key.result b/mysql-test/suite/pbxt/r/null_key.result index 7ef554af946..a997cf913c9 100644 --- a/mysql-test/suite/pbxt/r/null_key.result +++ b/mysql-test/suite/pbxt/r/null_key.result @@ -428,5 +428,6 @@ Handler_read_last 0 Handler_read_next 2 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 5 DROP TABLE t1,t2,t3,t4; diff --git a/mysql-test/suite/pbxt/r/ps_11bugs.result b/mysql-test/suite/pbxt/r/ps_11bugs.result index dd09e9d14f3..5a2743436e1 100644 --- a/mysql-test/suite/pbxt/r/ps_11bugs.result +++ b/mysql-test/suite/pbxt/r/ps_11bugs.result @@ -121,8 +121,8 @@ insert into t1 values (1); explain select * from t1 where 3 in (select (1+1) union select 1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 index NULL PRIMARY 4 NULL 1 Using index -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used -3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL select * from t1 where 3 in (select (1+1) union select 1); a diff --git a/mysql-test/suite/pbxt/r/select.result b/mysql-test/suite/pbxt/r/select.result index a3ed13f3de0..18ffdd30abe 100644 --- a/mysql-test/suite/pbxt/r/select.result +++ b/mysql-test/suite/pbxt/r/select.result @@ -2789,10 +2789,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away explain select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index select max(key1) from t1 where key1 <= 0.6158; max(key1) 0.6158000230789185 @@ -2811,10 +2811,18 @@ max(key1) min(key2) 0.6158000230789185 1.3761999607086182 select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; max(key1) +<<<<<<< TREE 0.6158000230789185 +======= +0.384499996900558 +>>>>>>> MERGE-SOURCE select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; min(key1) +<<<<<<< TREE 0.37619999051094055 +======= +0.384499996900558 +>>>>>>> MERGE-SOURCE DROP TABLE t1,t2; CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL); INSERT INTO t1 VALUES (10); diff --git a/mysql-test/suite/pbxt/r/update.result b/mysql-test/suite/pbxt/r/update.result index 13d50071bfd..83b284b794d 100644 --- a/mysql-test/suite/pbxt/r/update.result +++ b/mysql-test/suite/pbxt/r/update.result @@ -277,6 +277,7 @@ Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; update t1 set a=9999 order by a limit 1; @@ -292,6 +293,21 @@ Handler_read_last 1 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 2 +<<<<<<< TREE +======= +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 18 +flush status; +delete from t1 order by a limit 1; +show status like 'handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_rnd 1 +Handler_read_rnd_deleted 0 +>>>>>>> MERGE-SOURCE Handler_read_rnd_next 9 flush status; delete from t1 order by a limit 1; @@ -313,8 +329,14 @@ Handler_read_key 0 Handler_read_last 1 Handler_read_next 0 Handler_read_prev 0 +<<<<<<< TREE Handler_read_rnd 0 Handler_read_rnd_next 0 +======= +Handler_read_rnd 1 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 8 +>>>>>>> MERGE-SOURCE alter table t1 disable keys; Warnings: Note 1031 Table storage engine for 't1' doesn't have this option @@ -327,8 +349,14 @@ Handler_read_key 0 Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 +<<<<<<< TREE Handler_read_rnd 0 Handler_read_rnd_next 0 +======= +Handler_read_rnd 1 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 7 +>>>>>>> MERGE-SOURCE select * from t1; a b 0 0 @@ -382,6 +410,7 @@ Handler_read_last 0 Handler_read_next 1 Handler_read_prev 0 Handler_read_rnd 1 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 drop table t1, t2; create table t1(f1 int, `*f2` int); diff --git a/mysql-test/suite/pbxt/r/view_grant.result.THIS b/mysql-test/suite/pbxt/r/view_grant.result.THIS deleted file mode 100644 index cef441efc77..00000000000 --- a/mysql-test/suite/pbxt/r/view_grant.result.THIS +++ /dev/null @@ -1,959 +0,0 @@ -drop database if exists mysqltest; -drop view if exists v1,v2,v3; -grant create view on test.* to test@localhost; -show grants for test@localhost; -Grants for test@localhost -GRANT USAGE ON *.* TO 'test'@'localhost' -GRANT CREATE VIEW ON `test`.* TO 'test'@'localhost' -revoke create view on test.* from test@localhost; -show grants for test@localhost; -Grants for test@localhost -GRANT USAGE ON *.* TO 'test'@'localhost' -drop user test@localhost; -create database mysqltest; -create table mysqltest.t1 (a int, b int); -create table mysqltest.t2 (a int, b int); -grant select on mysqltest.t1 to mysqltest_1@localhost; -grant create view,select on test.* to mysqltest_1@localhost; -create definer=root@localhost view v1 as select * from mysqltest.t1; -ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation -create view v1 as select * from mysqltest.t1; -alter view v1 as select * from mysqltest.t1; -ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 'v1' -create or replace view v1 as select * from mysqltest.t1; -ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 'v1' -create view mysqltest.v2 as select * from mysqltest.t1; -ERROR 42000: CREATE VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v2' -create view v2 as select * from mysqltest.t2; -ERROR 42000: ANY command denied to user 'mysqltest_1'@'localhost' for table 't2' -show create view v1; -View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_1`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `mysqltest`.`t1`.`a` AS `a`,`mysqltest`.`t1`.`b` AS `b` from `mysqltest`.`t1` latin1 latin1_swedish_ci -grant create view,drop,select on test.* to mysqltest_1@localhost; -use test; -alter view v1 as select * from mysqltest.t1; -create or replace view v1 as select * from mysqltest.t1; -revoke all privileges on mysqltest.t1 from mysqltest_1@localhost; -revoke all privileges on test.* from mysqltest_1@localhost; -drop database mysqltest; -drop view test.v1; -create database mysqltest; -create table mysqltest.t1 (a int, b int); -create view mysqltest.v1 (c,d) as select a+1,b+1 from mysqltest.t1; -grant select (c) on mysqltest.v1 to mysqltest_1@localhost; -select c from mysqltest.v1; -c -select d from mysqltest.v1; -ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'd' in table 'v1' -revoke all privileges on mysqltest.v1 from mysqltest_1@localhost; -delete from mysql.user where user='mysqltest_1'; -drop database mysqltest; -create database mysqltest; -create table mysqltest.t1 (a int, b int); -create algorithm=temptable view mysqltest.v1 (c,d) as select a+1,b+1 from mysqltest.t1; -grant select (c) on mysqltest.v1 to mysqltest_1@localhost; -select c from mysqltest.v1; -c -select d from mysqltest.v1; -ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'd' in table 'v1' -revoke all privileges on mysqltest.v1 from mysqltest_1@localhost; -delete from mysql.user where user='mysqltest_1'; -drop database mysqltest; -create database mysqltest; -create table mysqltest.t1 (a int, b int); -create table mysqltest.t2 (a int, b int); -create view mysqltest.v1 (c,d) as select a+1,b+1 from mysqltest.t1; -create algorithm=temptable view mysqltest.v2 (c,d) as select a+1,b+1 from mysqltest.t1; -create view mysqltest.v3 (c,d) as select a+1,b+1 from mysqltest.t2; -create algorithm=temptable view mysqltest.v4 (c,d) as select a+1,b+1 from mysqltest.t2; -grant select on mysqltest.v1 to mysqltest_1@localhost; -grant select on mysqltest.v2 to mysqltest_1@localhost; -grant select on mysqltest.v3 to mysqltest_1@localhost; -grant select on mysqltest.v4 to mysqltest_1@localhost; -select c from mysqltest.v1; -c -select c from mysqltest.v2; -c -select c from mysqltest.v3; -c -select c from mysqltest.v4; -c -show columns from mysqltest.v1; -Field Type Null Key Default Extra -c bigint(12) YES NULL -d bigint(12) YES NULL -show columns from mysqltest.v2; -Field Type Null Key Default Extra -c bigint(12) YES NULL -d bigint(12) YES NULL -explain select c from mysqltest.v1; -ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table -show create view mysqltest.v1; -ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1' -explain select c from mysqltest.v2; -ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table -show create view mysqltest.v2; -ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v2' -explain select c from mysqltest.v3; -ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table -show create view mysqltest.v3; -ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v3' -explain select c from mysqltest.v4; -ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table -show create view mysqltest.v4; -ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v4' -grant select on mysqltest.t1 to mysqltest_1@localhost; -explain select c from mysqltest.v1; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 0 -show create view mysqltest.v1; -ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1' -explain select c from mysqltest.v2; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 -2 DERIVED t1 ALL NULL NULL NULL NULL 0 -show create view mysqltest.v2; -ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v2' -explain select c from mysqltest.v3; -ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table -show create view mysqltest.v3; -ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v3' -explain select c from mysqltest.v4; -ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table -show create view mysqltest.v4; -ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v4' -grant show view on mysqltest.* to mysqltest_1@localhost; -explain select c from mysqltest.v1; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 0 -show create view mysqltest.v1; -View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v1` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` latin1 latin1_swedish_ci -explain select c from mysqltest.v2; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 -2 DERIVED t1 ALL NULL NULL NULL NULL 0 -show create view mysqltest.v2; -View Create View character_set_client collation_connection -v2 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v2` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` latin1 latin1_swedish_ci -explain select c from mysqltest.v3; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 0 -show create view mysqltest.v3; -View Create View character_set_client collation_connection -v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v3` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2` latin1 latin1_swedish_ci -explain select c from mysqltest.v4; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 -2 DERIVED t2 ALL NULL NULL NULL NULL 0 -show create view mysqltest.v4; -View Create View character_set_client collation_connection -v4 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v4` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2` latin1 latin1_swedish_ci -revoke all privileges on mysqltest.* from mysqltest_1@localhost; -delete from mysql.user where user='mysqltest_1'; -drop database mysqltest; -create database mysqltest; -create table mysqltest.t1 (a int, b int, primary key(a)); -insert into mysqltest.t1 values (10,2), (20,3), (30,4), (40,5), (50,10); -create table mysqltest.t2 (x int); -insert into mysqltest.t2 values (3), (4), (5), (6); -create view mysqltest.v1 (a,c) as select a, b+1 from mysqltest.t1; -create view mysqltest.v2 (a,c) as select a, b from mysqltest.t1; -create view mysqltest.v3 (a,c) as select a, b+1 from mysqltest.t1; -grant update (a) on mysqltest.v2 to mysqltest_1@localhost; -grant update on mysqltest.v1 to mysqltest_1@localhost; -grant select on mysqltest.* to mysqltest_1@localhost; -use mysqltest; -update t2,v1 set v1.a=v1.a+v1.c where t2.x=v1.c; -select * from t1 order by a; -a b -13 2 -24 3 -35 4 -46 5 -50 10 -update v1 set a=a+c; -select * from t1 order by a; -a b -16 2 -28 3 -40 4 -52 5 -61 10 -update t2,v2 set v2.a=v2.a+v2.c where t2.x=v2.c; -select * from t1 order by a; -a b -16 2 -31 3 -44 4 -57 5 -61 10 -update v2 set a=a+c; -select * from t1 order by a; -a b -18 2 -34 3 -48 4 -62 5 -71 10 -update t2,v2 set v2.c=v2.a+v2.c where t2.x=v2.c; -ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for column 'c' in table 'v2' -update v2 set c=a+c; -ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for column 'c' in table 'v2' -update t2,v3 set v3.a=v3.a+v3.c where t2.x=v3.c; -ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for table 'v3' -update v3 set a=a+c; -ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for table 'v3' -use test; -REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost; -drop database mysqltest; -create database mysqltest; -create table mysqltest.t1 (a int, b int, primary key(a)); -insert into mysqltest.t1 values (1,2), (2,3), (3,4), (4,5), (5,10); -create table mysqltest.t2 (x int); -insert into mysqltest.t2 values (3), (4), (5), (6); -create view mysqltest.v1 (a,c) as select a, b+1 from mysqltest.t1; -create view mysqltest.v2 (a,c) as select a, b+1 from mysqltest.t1; -grant delete on mysqltest.v1 to mysqltest_1@localhost; -grant select on mysqltest.* to mysqltest_1@localhost; -use mysqltest; -delete from v1 where c < 4; -select * from t1; -a b -2 3 -3 4 -4 5 -5 10 -delete v1 from t2,v1 where t2.x=v1.c; -select * from t1; -a b -5 10 -delete v2 from t2,v2 where t2.x=v2.c; -ERROR 42000: DELETE command denied to user 'mysqltest_1'@'localhost' for table 'v2' -delete from v2 where c < 4; -ERROR 42000: DELETE command denied to user 'mysqltest_1'@'localhost' for table 'v2' -use test; -REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost; -drop database mysqltest; -create database mysqltest; -create table mysqltest.t1 (a int, b int, primary key(a)); -insert into mysqltest.t1 values (1,2), (2,3); -create table mysqltest.t2 (x int, y int); -insert into mysqltest.t2 values (3,4); -create view mysqltest.v1 (a,c) as select a, b from mysqltest.t1; -create view mysqltest.v2 (a,c) as select a, b from mysqltest.t1; -grant insert on mysqltest.v1 to mysqltest_1@localhost; -grant select on mysqltest.* to mysqltest_1@localhost; -use mysqltest; -insert into v1 values (5,6); -select * from t1; -a b -1 2 -2 3 -5 6 -insert into v1 select x,y from t2; -select * from t1; -a b -1 2 -2 3 -5 6 -3 4 -insert into v2 values (5,6); -ERROR 42000: INSERT command denied to user 'mysqltest_1'@'localhost' for table 'v2' -insert into v2 select x,y from t2; -ERROR 42000: INSERT command denied to user 'mysqltest_1'@'localhost' for table 'v2' -use test; -REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost; -drop database mysqltest; -create database mysqltest; -create table mysqltest.t1 (a int, b int); -create table mysqltest.t2 (a int, b int); -grant update on mysqltest.t1 to mysqltest_1@localhost; -grant update(b) on mysqltest.t2 to mysqltest_1@localhost; -grant create view,update on test.* to mysqltest_1@localhost; -create view v1 as select * from mysqltest.t1; -create view v2 as select b from mysqltest.t2; -create view mysqltest.v1 as select * from mysqltest.t1; -ERROR 42000: CREATE VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1' -create view v3 as select a from mysqltest.t2; -ERROR 42000: ANY command denied to user 'mysqltest_1'@'localhost' for column 'a' in table 't2' -create table mysqltest.v3 (b int); -grant create view on mysqltest.v3 to mysqltest_1@localhost; -drop table mysqltest.v3; -create view mysqltest.v3 as select b from mysqltest.t2; -grant create view, update on mysqltest.v3 to mysqltest_1@localhost; -drop view mysqltest.v3; -create view mysqltest.v3 as select b from mysqltest.t2; -create view v4 as select b+1 from mysqltest.t2; -ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'b' in table 't2' -grant create view,update,select on test.* to mysqltest_1@localhost; -create view v4 as select b+1 from mysqltest.t2; -ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'b' in table 't2' -grant update,select(b) on mysqltest.t2 to mysqltest_1@localhost; -create view v4 as select b+1 from mysqltest.t2; -REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost; -drop database mysqltest; -drop view v1,v2,v4; -create database mysqltest; -create table mysqltest.t1 (a int); -grant all privileges on mysqltest.* to mysqltest_1@localhost; -use mysqltest; -create view v1 as select * from t1; -use test; -revoke all privileges on mysqltest.* from mysqltest_1@localhost; -drop database mysqltest; -create database mysqltest; -create table mysqltest.t1 (a int, b int); -grant select on mysqltest.t1 to mysqltest_1@localhost; -grant create view,select on test.* to mysqltest_1@localhost; -create view v1 as select * from mysqltest.t1; -show create view v1; -View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_1`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `mysqltest`.`t1`.`a` AS `a`,`mysqltest`.`t1`.`b` AS `b` from `mysqltest`.`t1` latin1 latin1_swedish_ci -revoke select on mysqltest.t1 from mysqltest_1@localhost; -select * from v1; -ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -grant select on mysqltest.t1 to mysqltest_1@localhost; -select * from v1; -a b -REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost; -drop view v1; -drop database mysqltest; -create database mysqltest; -use mysqltest; -create table t1 (a int); -insert into t1 values (1); -create table t2 (s1 int); -drop function if exists f2; -create function f2 () returns int begin declare v int; select s1 from t2 -into v; return v; end// -create algorithm=TEMPTABLE view v1 as select f2() from t1; -create algorithm=MERGE view v2 as select f2() from t1; -create algorithm=TEMPTABLE SQL SECURITY INVOKER view v3 as select f2() from t1; -create algorithm=MERGE SQL SECURITY INVOKER view v4 as select f2() from t1; -create SQL SECURITY INVOKER view v5 as select * from v4; -grant select on v1 to mysqltest_1@localhost; -grant select on v2 to mysqltest_1@localhost; -grant select on v3 to mysqltest_1@localhost; -grant select on v4 to mysqltest_1@localhost; -grant select on v5 to mysqltest_1@localhost; -use mysqltest; -select * from v1; -f2() -NULL -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed -select * from v2; -f2() -NULL -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed -select * from v3; -ERROR HY000: View 'mysqltest.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -select * from v4; -ERROR HY000: View 'mysqltest.v4' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -select * from v5; -ERROR HY000: View 'mysqltest.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -use test; -drop view v1, v2, v3, v4, v5; -drop function f2; -drop table t1, t2; -use test; -REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost; -drop database mysqltest; -create database mysqltest; -use mysqltest; -create table t1 (a int); -insert into t1 values (1); -create table t2 (s1 int); -drop function if exists f2; -create function f2 () returns int begin declare v int; select s1 from t2 -into v; return v; end// -grant select on t1 to mysqltest_1@localhost; -grant execute on function f2 to mysqltest_1@localhost; -grant create view on mysqltest.* to mysqltest_1@localhost; -use mysqltest; -create algorithm=TEMPTABLE view v1 as select f2() from t1; -create algorithm=MERGE view v2 as select f2() from t1; -create algorithm=TEMPTABLE SQL SECURITY INVOKER view v3 as select f2() from t1; -create algorithm=MERGE SQL SECURITY INVOKER view v4 as select f2() from t1; -use test; -create view v5 as select * from v1; -revoke execute on function f2 from mysqltest_1@localhost; -select * from v1; -ERROR HY000: View 'mysqltest.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -select * from v2; -ERROR HY000: View 'mysqltest.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -select * from v3; -f2() -NULL -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed -select * from v4; -f2() -NULL -Warnings: -Warning 1329 No data - zero rows fetched, selected, or processed -select * from v5; -ERROR HY000: View 'mysqltest.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -drop view v1, v2, v3, v4, v5; -drop function f2; -drop table t1, t2; -use test; -REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost; -drop database mysqltest; -create database mysqltest; -use mysqltest; -create table t1 (a int); -create table v1 (a int); -insert into t1 values (1); -grant select on t1 to mysqltest_1@localhost; -grant select on v1 to mysqltest_1@localhost; -grant create view on mysqltest.* to mysqltest_1@localhost; -drop table v1; -use mysqltest; -create algorithm=TEMPTABLE view v1 as select *, a as b from t1; -create algorithm=MERGE view v2 as select *, a as b from t1; -create algorithm=TEMPTABLE SQL SECURITY INVOKER view v3 as select *, a as b from t1; -create algorithm=MERGE SQL SECURITY INVOKER view v4 as select *, a as b from t1; -create view v5 as select * from v1; -use test; -revoke select on t1 from mysqltest_1@localhost; -select * from v1; -ERROR HY000: View 'mysqltest.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -select * from v2; -ERROR HY000: View 'mysqltest.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -select * from v3; -a b -1 1 -select * from v4; -a b -1 1 -select * from v5; -ERROR HY000: View 'mysqltest.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -drop table t1; -use test; -REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost; -drop database mysqltest; -create database mysqltest; -use mysqltest; -create table t1 (a int); -insert into t1 values (1); -create algorithm=TEMPTABLE view v1 as select *, a as b from t1; -create algorithm=MERGE view v2 as select *, a as b from t1; -create algorithm=TEMPTABLE SQL SECURITY INVOKER view v3 as select *, a as b from t1; -create algorithm=MERGE SQL SECURITY INVOKER view v4 as select *, a as b from t1; -create SQL SECURITY INVOKER view v5 as select * from v4; -grant select on v1 to mysqltest_1@localhost; -grant select on v2 to mysqltest_1@localhost; -grant select on v3 to mysqltest_1@localhost; -grant select on v4 to mysqltest_1@localhost; -grant select on v5 to mysqltest_1@localhost; -use mysqltest; -select * from v1; -a b -1 1 -select * from v2; -a b -1 1 -select * from v3; -ERROR HY000: View 'mysqltest.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -select * from v4; -ERROR HY000: View 'mysqltest.v4' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -select * from v5; -ERROR HY000: View 'mysqltest.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -use test; -drop view v1, v2, v3, v4, v5; -drop table t1; -use test; -REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost; -drop database mysqltest; -drop view if exists v1; -drop table if exists t1; -create table t1 as select * from mysql.user where user=''; -delete from mysql.user where user=''; -flush privileges; -grant all on test.* to 'test14256'@'%'; -use test; -create view v1 as select 42; -show create view v1; -View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`test14256`@`%` SQL SECURITY DEFINER VIEW `v1` AS select 42 AS `42` latin1 latin1_swedish_ci -select definer into @v1def1 from information_schema.views -where table_schema = 'test' and table_name='v1'; -drop view v1; -create definer=`test14256`@`%` view v1 as select 42; -show create view v1; -View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`test14256`@`%` SQL SECURITY DEFINER VIEW `v1` AS select 42 AS `42` latin1 latin1_swedish_ci -select definer into @v1def2 from information_schema.views -where table_schema = 'test' and table_name='v1'; -drop view v1; -select @v1def1, @v1def2, @v1def1=@v1def2; -@v1def1 @v1def2 @v1def1=@v1def2 -test14256@% test14256@% 1 -drop user test14256; -insert into mysql.user select * from t1; -flush privileges; -drop table t1; -create database mysqltest; -use mysqltest; -CREATE TABLE t1 (i INT); -CREATE VIEW v1 AS SELECT * FROM t1; -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 `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci -GRANT SELECT, LOCK TABLES ON mysqltest.* TO mysqltest_1@localhost; -use mysqltest; -LOCK TABLES v1 READ; -SHOW CREATE TABLE v1; -ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1' -UNLOCK TABLES; -use test; -use test; -drop user mysqltest_1@localhost; -drop database mysqltest; -create definer=some_user@`` sql security invoker view v1 as select 1; -Warnings: -Note 1449 The user specified as a definer ('some_user'@'') does not exist -create definer=some_user@localhost sql security invoker view v2 as select 1; -Warnings: -Note 1449 The user specified as a definer ('some_user'@'localhost') does not exist -show create view v1; -View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1` latin1 latin1_swedish_ci -show create view v2; -View Create View character_set_client collation_connection -v2 CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`localhost` SQL SECURITY INVOKER VIEW `v2` AS select 1 AS `1` latin1 latin1_swedish_ci -drop view v1; -drop view v2; -CREATE DATABASE mysqltest1; -CREATE USER readonly@localhost; -CREATE TABLE mysqltest1.t1 (x INT); -INSERT INTO mysqltest1.t1 VALUES (1), (2); -CREATE SQL SECURITY INVOKER VIEW mysqltest1.v_t1 AS SELECT * FROM mysqltest1.t1; -CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_ts AS SELECT * FROM mysqltest1.t1; -CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_ti AS SELECT * FROM mysqltest1.t1; -CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tu AS SELECT * FROM mysqltest1.t1; -CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tus AS SELECT * FROM mysqltest1.t1; -CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_td AS SELECT * FROM mysqltest1.t1; -CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tds AS SELECT * FROM mysqltest1.t1; -GRANT SELECT, INSERT, UPDATE, DELETE ON mysqltest1.v_t1 TO readonly@localhost; -GRANT SELECT ON mysqltest1.v_ts TO readonly@localhost; -GRANT INSERT ON mysqltest1.v_ti TO readonly@localhost; -GRANT UPDATE ON mysqltest1.v_tu TO readonly@localhost; -GRANT UPDATE,SELECT ON mysqltest1.v_tus TO readonly@localhost; -GRANT DELETE ON mysqltest1.v_td TO readonly@localhost; -GRANT DELETE,SELECT ON mysqltest1.v_tds TO readonly@localhost; -SELECT * FROM mysqltest1.v_t1; -ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -INSERT INTO mysqltest1.v_t1 VALUES(4); -ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -DELETE FROM mysqltest1.v_t1 WHERE x = 1; -ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -UPDATE mysqltest1.v_t1 SET x = 3 WHERE x = 2; -ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -UPDATE mysqltest1.v_t1 SET x = 3; -ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -DELETE FROM mysqltest1.v_t1; -ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -SELECT 1 FROM mysqltest1.v_t1; -ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them -SELECT * FROM mysqltest1.t1; -ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for table 't1' -SELECT * FROM mysqltest1.v_ts; -x -1 -2 -SELECT * FROM mysqltest1.v_ts, mysqltest1.t1 WHERE mysqltest1.t1.x = mysqltest1.v_ts.x; -ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for table 't1' -SELECT * FROM mysqltest1.v_ti; -ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for table 'v_ti' -INSERT INTO mysqltest1.v_ts VALUES (100); -ERROR 42000: INSERT command denied to user 'readonly'@'localhost' for table 'v_ts' -INSERT INTO mysqltest1.v_ti VALUES (100); -UPDATE mysqltest1.v_ts SET x= 200 WHERE x = 100; -ERROR 42000: UPDATE command denied to user 'readonly'@'localhost' for table 'v_ts' -UPDATE mysqltest1.v_ts SET x= 200; -ERROR 42000: UPDATE command denied to user 'readonly'@'localhost' for table 'v_ts' -UPDATE mysqltest1.v_tu SET x= 200 WHERE x = 100; -UPDATE mysqltest1.v_tus SET x= 200 WHERE x = 100; -UPDATE mysqltest1.v_tu SET x= 200; -DELETE FROM mysqltest1.v_ts WHERE x= 200; -ERROR 42000: DELETE command denied to user 'readonly'@'localhost' for table 'v_ts' -DELETE FROM mysqltest1.v_ts; -ERROR 42000: DELETE command denied to user 'readonly'@'localhost' for table 'v_ts' -DELETE FROM mysqltest1.v_td WHERE x= 200; -ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for column 'x' in table 'v_td' -DELETE FROM mysqltest1.v_tds WHERE x= 200; -DELETE FROM mysqltest1.v_td; -DROP VIEW mysqltest1.v_tds; -DROP VIEW mysqltest1.v_td; -DROP VIEW mysqltest1.v_tus; -DROP VIEW mysqltest1.v_tu; -DROP VIEW mysqltest1.v_ti; -DROP VIEW mysqltest1.v_ts; -DROP VIEW mysqltest1.v_t1; -DROP TABLE mysqltest1.t1; -DROP USER readonly@localhost; -DROP DATABASE mysqltest1; -CREATE TABLE t1 (a INT PRIMARY KEY); -INSERT INTO t1 VALUES (1), (2), (3); -CREATE DEFINER = 'no-such-user'@localhost VIEW v AS SELECT a from t1; -Warnings: -Note 1449 The user specified as a definer ('no-such-user'@'localhost') does not exist -SHOW CREATE VIEW v; -View Create View character_set_client collation_connection -v CREATE ALGORITHM=UNDEFINED DEFINER=`no-such-user`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `test`.`t1`.`a` AS `a` from `t1` latin1 latin1_swedish_ci -Warnings: -Note 1449 The user specified as a definer ('no-such-user'@'localhost') does not exist -SELECT * FROM v; -ERROR HY000: The user specified as a definer ('no-such-user'@'localhost') does not exist -DROP VIEW v; -DROP TABLE t1; -USE test; -CREATE USER mysqltest_db1@localhost identified by 'PWD'; -GRANT ALL ON mysqltest_db1.* TO mysqltest_db1@localhost WITH GRANT OPTION; -CREATE SCHEMA mysqltest_db1 ; -USE mysqltest_db1 ; -CREATE TABLE t1 (f1 INTEGER); -CREATE VIEW view1 AS -SELECT * FROM t1; -SHOW CREATE VIEW view1; -View Create View character_set_client collation_connection -view1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_db1`@`localhost` SQL SECURITY DEFINER VIEW `view1` AS select `t1`.`f1` AS `f1` from `t1` latin1 latin1_swedish_ci -CREATE VIEW view2 AS -SELECT * FROM view1; -# Here comes a suspicious warning -SHOW CREATE VIEW view2; -View Create View character_set_client collation_connection -view2 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_db1`@`localhost` SQL SECURITY DEFINER VIEW `view2` AS select `view1`.`f1` AS `f1` from `view1` latin1 latin1_swedish_ci -# But the view view2 is usable -SELECT * FROM view2; -f1 -CREATE VIEW view3 AS -SELECT * FROM view2; -SELECT * from view3; -f1 -DROP VIEW mysqltest_db1.view3; -DROP VIEW mysqltest_db1.view2; -DROP VIEW mysqltest_db1.view1; -DROP TABLE mysqltest_db1.t1; -DROP SCHEMA mysqltest_db1; -DROP USER mysqltest_db1@localhost; -CREATE DATABASE test1; -CREATE DATABASE test2; -CREATE TABLE test1.t0 (a VARCHAR(20)) engine=myisam; -CREATE TABLE test2.t1 (a VARCHAR(20)); -CREATE VIEW test2.t3 AS SELECT * FROM test1.t0; -CREATE OR REPLACE VIEW test.v1 AS -SELECT ta.a AS col1, tb.a AS col2 FROM test2.t3 ta, test2.t1 tb; -DROP VIEW test.v1; -DROP VIEW test2.t3; -DROP TABLE test2.t1, test1.t0; -DROP DATABASE test2; -DROP DATABASE test1; -DROP VIEW IF EXISTS v1; -DROP VIEW IF EXISTS v2; -DROP VIEW IF EXISTS v3; -DROP FUNCTION IF EXISTS f1; -DROP FUNCTION IF EXISTS f2; -DROP PROCEDURE IF EXISTS p1; -CREATE SQL SECURITY DEFINER VIEW v1 AS SELECT CURRENT_USER() AS cu; -CREATE FUNCTION f1() RETURNS VARCHAR(77) SQL SECURITY INVOKER -RETURN CURRENT_USER(); -CREATE SQL SECURITY DEFINER VIEW v2 AS SELECT f1() AS cu; -CREATE PROCEDURE p1(OUT cu VARCHAR(77)) SQL SECURITY INVOKER -SET cu= CURRENT_USER(); -CREATE FUNCTION f2() RETURNS VARCHAR(77) SQL SECURITY INVOKER -BEGIN -DECLARE cu VARCHAR(77); -CALL p1(cu); -RETURN cu; -END| -CREATE SQL SECURITY DEFINER VIEW v3 AS SELECT f2() AS cu; -CREATE USER mysqltest_u1@localhost; -GRANT ALL ON test.* TO mysqltest_u1@localhost; - -The following tests should all return 1. - -SELECT CURRENT_USER() = 'mysqltest_u1@localhost'; -CURRENT_USER() = 'mysqltest_u1@localhost' -1 -SELECT f1() = 'mysqltest_u1@localhost'; -f1() = 'mysqltest_u1@localhost' -1 -CALL p1(@cu); -SELECT @cu = 'mysqltest_u1@localhost'; -@cu = 'mysqltest_u1@localhost' -1 -SELECT f2() = 'mysqltest_u1@localhost'; -f2() = 'mysqltest_u1@localhost' -1 -SELECT cu = 'root@localhost' FROM v1; -cu = 'root@localhost' -1 -SELECT cu = 'root@localhost' FROM v2; -cu = 'root@localhost' -1 -SELECT cu = 'root@localhost' FROM v3; -cu = 'root@localhost' -1 -DROP VIEW v3; -DROP FUNCTION f2; -DROP PROCEDURE p1; -DROP FUNCTION f1; -DROP VIEW v2; -DROP VIEW v1; -DROP USER mysqltest_u1@localhost; -CREATE DATABASE db17254; -USE db17254; -CREATE TABLE t1 (f1 INT); -INSERT INTO t1 VALUES (10),(20); -CREATE USER def_17254@localhost; -GRANT SELECT ON db17254.* TO def_17254@localhost; -CREATE USER inv_17254@localhost; -GRANT SELECT ON db17254.t1 TO inv_17254@localhost; -GRANT CREATE VIEW ON db17254.* TO def_17254@localhost; -CREATE VIEW v1 AS SELECT * FROM t1; -DROP USER def_17254@localhost; -for a user -SELECT * FROM v1; -ERROR 42000: SELECT command denied to user 'inv_17254'@'localhost' for table 'v1' -for a superuser -SELECT * FROM v1; -ERROR HY000: The user specified as a definer ('def_17254'@'localhost') does not exist -DROP USER inv_17254@localhost; -DROP DATABASE db17254; -DROP DATABASE IF EXISTS mysqltest_db1; -DROP DATABASE IF EXISTS mysqltest_db2; -DROP USER mysqltest_u1; -DROP USER mysqltest_u2; -CREATE USER mysqltest_u1@localhost; -CREATE USER mysqltest_u2@localhost; -CREATE DATABASE mysqltest_db1; -CREATE DATABASE mysqltest_db2; -GRANT ALL ON mysqltest_db1.* TO mysqltest_u1@localhost WITH GRANT OPTION; -GRANT ALL ON mysqltest_db2.* TO mysqltest_u2@localhost; -CREATE TABLE t1 (i INT); -INSERT INTO t1 VALUES (1); -CREATE VIEW v1 AS SELECT i FROM t1 WHERE 1 IN (SELECT * FROM t1); -CREATE TABLE t2 (s CHAR(7)); -INSERT INTO t2 VALUES ('public'); -GRANT SELECT ON v1 TO mysqltest_u2@localhost; -GRANT SELECT ON t2 TO mysqltest_u2@localhost; -SELECT * FROM mysqltest_db1.v1, mysqltest_db1.t2; -i s -1 public -PREPARE stmt1 FROM "SELECT * FROM mysqltest_db1.t2"; -EXECUTE stmt1; -s -public -PREPARE stmt2 FROM "SELECT * FROM mysqltest_db1.v1, mysqltest_db1.t2"; -EXECUTE stmt2; -i s -1 public -REVOKE SELECT ON t2 FROM mysqltest_u2@localhost; -UPDATE t2 SET s = 'private' WHERE s = 'public'; -SELECT * FROM mysqltest_db1.v1, mysqltest_db1.t2; -ERROR 42000: SELECT command denied to user 'mysqltest_u2'@'localhost' for table 't2' -EXECUTE stmt1; -ERROR 42000: SELECT command denied to user 'mysqltest_u2'@'localhost' for table 't2' -EXECUTE stmt2; -ERROR 42000: SELECT command denied to user 'mysqltest_u2'@'localhost' for table 't2' -REVOKE ALL ON mysqltest_db1.* FROM mysqltest_u1@localhost; -REVOKE ALL ON mysqltest_db2.* FROM mysqltest_u2@localhost; -DROP DATABASE mysqltest_db1; -DROP DATABASE mysqltest_db2; -DROP USER mysqltest_u1@localhost; -DROP USER mysqltest_u2@localhost; -CREATE DATABASE db26813; -USE db26813; -CREATE TABLE t1(f1 INT, f2 INT); -CREATE VIEW v1 AS SELECT f1 FROM t1; -CREATE VIEW v2 AS SELECT f1 FROM t1; -CREATE VIEW v3 AS SELECT f1 FROM t1; -CREATE USER u26813@localhost; -GRANT DROP ON db26813.v1 TO u26813@localhost; -GRANT CREATE VIEW ON db26813.v2 TO u26813@localhost; -GRANT DROP, CREATE VIEW ON db26813.v3 TO u26813@localhost; -GRANT SELECT ON db26813.t1 TO u26813@localhost; -ALTER VIEW v1 AS SELECT f2 FROM t1; -ERROR 42000: CREATE VIEW command denied to user 'u26813'@'localhost' for table 'v1' -ALTER VIEW v2 AS SELECT f2 FROM t1; -ERROR 42000: DROP command denied to user 'u26813'@'localhost' for table 'v2' -ALTER VIEW v3 AS SELECT f2 FROM t1; -ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation -SHOW CREATE VIEW v3; -View Create View character_set_client collation_connection -v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `t1`.`f1` AS `f1` from `t1` latin1 latin1_swedish_ci -DROP USER u26813@localhost; -DROP DATABASE db26813; -# -# Bug#29908 A user can gain additional access through the ALTER VIEW. -# -CREATE DATABASE mysqltest_29908; -USE mysqltest_29908; -CREATE TABLE t1(f1 INT, f2 INT); -CREATE USER u29908_1@localhost; -CREATE DEFINER = u29908_1@localhost VIEW v1 AS SELECT f1 FROM t1; -CREATE DEFINER = u29908_1@localhost SQL SECURITY INVOKER VIEW v2 AS -SELECT f1 FROM t1; -GRANT SELECT, DROP, CREATE VIEW, SHOW VIEW ON mysqltest_29908.v1 TO u29908_1@localhost; -GRANT SELECT, DROP, CREATE VIEW, SHOW VIEW ON mysqltest_29908.v2 TO u29908_1@localhost; -GRANT SELECT ON mysqltest_29908.t1 TO u29908_1@localhost; -CREATE USER u29908_2@localhost; -GRANT SELECT, DROP, CREATE VIEW ON mysqltest_29908.v1 TO u29908_2@localhost; -GRANT SELECT, DROP, CREATE VIEW, SHOW VIEW ON mysqltest_29908.v2 TO u29908_2@localhost; -GRANT SELECT ON mysqltest_29908.t1 TO u29908_2@localhost; -ALTER VIEW v1 AS SELECT f2 FROM t1; -ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation -ALTER VIEW v2 AS SELECT f2 FROM t1; -ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation -SHOW CREATE VIEW v2; -View Create View character_set_client collation_connection -v2 CREATE ALGORITHM=UNDEFINED DEFINER=`u29908_1`@`localhost` SQL SECURITY INVOKER VIEW `v2` AS select `t1`.`f1` AS `f1` from `t1` latin1 latin1_swedish_ci -ALTER VIEW v1 AS SELECT f2 FROM t1; -SHOW CREATE VIEW v1; -View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`u29908_1`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f2` AS `f2` from `t1` latin1 latin1_swedish_ci -ALTER VIEW v2 AS SELECT f2 FROM t1; -SHOW CREATE VIEW v2; -View Create View character_set_client collation_connection -v2 CREATE ALGORITHM=UNDEFINED DEFINER=`u29908_1`@`localhost` SQL SECURITY INVOKER VIEW `v2` AS select `t1`.`f2` AS `f2` from `t1` latin1 latin1_swedish_ci -ALTER VIEW v1 AS SELECT f1 FROM t1; -SHOW CREATE VIEW v1; -View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`u29908_1`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` latin1 latin1_swedish_ci -ALTER VIEW v2 AS SELECT f1 FROM t1; -SHOW CREATE VIEW v2; -View Create View character_set_client collation_connection -v2 CREATE ALGORITHM=UNDEFINED DEFINER=`u29908_1`@`localhost` SQL SECURITY INVOKER VIEW `v2` AS select `t1`.`f1` AS `f1` from `t1` latin1 latin1_swedish_ci -DROP USER u29908_1@localhost; -DROP USER u29908_2@localhost; -DROP DATABASE mysqltest_29908; -####################################################################### -DROP DATABASE IF EXISTS mysqltest1; -DROP DATABASE IF EXISTS mysqltest2; -CREATE DATABASE mysqltest1; -CREATE DATABASE mysqltest2; -CREATE TABLE mysqltest1.t1(c1 INT); -CREATE TABLE mysqltest1.t2(c2 INT); -CREATE TABLE mysqltest1.t3(c3 INT); -CREATE TABLE mysqltest1.t4(c4 INT); -INSERT INTO mysqltest1.t1 VALUES (11), (12), (13), (14); -INSERT INTO mysqltest1.t2 VALUES (21), (22), (23), (24); -INSERT INTO mysqltest1.t3 VALUES (31), (32), (33), (34); -INSERT INTO mysqltest1.t4 VALUES (41), (42), (43), (44); -GRANT SELECT ON mysqltest1.t1 TO mysqltest_u1@localhost; -GRANT INSERT ON mysqltest1.t2 TO mysqltest_u1@localhost; -GRANT SELECT, UPDATE ON mysqltest1.t3 TO mysqltest_u1@localhost; -GRANT SELECT, DELETE ON mysqltest1.t4 TO mysqltest_u1@localhost; -GRANT ALL PRIVILEGES ON mysqltest2.* TO mysqltest_u1@localhost; - ----> connection: bug24040_con -SELECT * FROM mysqltest1.t1; -c1 -11 -12 -13 -14 -INSERT INTO mysqltest1.t2 VALUES(25); -UPDATE mysqltest1.t3 SET c3 = 331 WHERE c3 = 31; -DELETE FROM mysqltest1.t4 WHERE c4 = 44; -CREATE VIEW v1 AS SELECT * FROM mysqltest1.t1; -CREATE VIEW v2 AS SELECT * FROM mysqltest1.t2; -CREATE VIEW v3 AS SELECT * FROM mysqltest1.t3; -CREATE VIEW v4 AS SELECT * FROM mysqltest1.t4; -SELECT * FROM v1; -c1 -11 -12 -13 -14 -INSERT INTO v2 VALUES(26); -UPDATE v3 SET c3 = 332 WHERE c3 = 32; -DELETE FROM v4 WHERE c4 = 43; -CREATE VIEW v12 AS SELECT c1, c2 FROM mysqltest1.t1, mysqltest1.t2; -ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c2' in table 'v12' -CREATE VIEW v13 AS SELECT c1, c3 FROM mysqltest1.t1, mysqltest1.t3; -CREATE VIEW v14 AS SELECT c1, c4 FROM mysqltest1.t1, mysqltest1.t4; -CREATE VIEW v21 AS SELECT c2, c1 FROM mysqltest1.t2, mysqltest1.t1; -ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c1' in table 'v21' -CREATE VIEW v23 AS SELECT c2, c3 FROM mysqltest1.t2, mysqltest1.t3; -ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c3' in table 'v23' -CREATE VIEW v24 AS SELECT c2, c4 FROM mysqltest1.t2, mysqltest1.t4; -ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c4' in table 'v24' -CREATE VIEW v31 AS SELECT c3, c1 FROM mysqltest1.t3, mysqltest1.t1; -CREATE VIEW v32 AS SELECT c3, c2 FROM mysqltest1.t3, mysqltest1.t2; -ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c2' in table 'v32' -CREATE VIEW v34 AS SELECT c3, c4 FROM mysqltest1.t3, mysqltest1.t4; -CREATE VIEW v41 AS SELECT c4, c1 FROM mysqltest1.t4, mysqltest1.t1; -CREATE VIEW v42 AS SELECT c4, c2 FROM mysqltest1.t4, mysqltest1.t2; -ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c2' in table 'v42' -CREATE VIEW v43 AS SELECT c4, c3 FROM mysqltest1.t4, mysqltest1.t3; - ----> connection: default -SELECT * FROM mysqltest1.t1; -c1 -11 -12 -13 -14 -SELECT * FROM mysqltest1.t2; -c2 -21 -22 -23 -24 -25 -26 -SELECT * FROM mysqltest1.t3 order by c3; -c3 -33 -34 -331 -332 -SELECT * FROM mysqltest1.t4; -c4 -41 -42 -DROP DATABASE mysqltest1; -DROP DATABASE mysqltest2; -DROP USER mysqltest_u1@localhost; -End of 5.0 tests. -DROP VIEW IF EXISTS v1; -DROP TABLE IF EXISTS t1; -CREATE TABLE t1 (i INT); -CREATE VIEW v1 AS SELECT * FROM t1; -ALTER VIEW v1 AS SELECT * FROM t1; -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 `t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci -ALTER DEFINER=no_such@user_1 VIEW v1 AS SELECT * FROM t1; -Warnings: -Note 1449 The user specified as a definer ('no_such'@'user_1') does not exist -SHOW CREATE VIEW v1; -View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`no_such`@`user_1` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci -Warnings: -Note 1449 The user specified as a definer ('no_such'@'user_1') does not exist -ALTER ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1; -Warnings: -Note 1449 The user specified as a definer ('no_such'@'user_1') does not exist -SHOW CREATE VIEW v1; -View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=MERGE DEFINER=`no_such`@`user_1` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci -Warnings: -Note 1449 The user specified as a definer ('no_such'@'user_1') does not exist -ALTER ALGORITHM=TEMPTABLE DEFINER=no_such@user_2 VIEW v1 AS SELECT * FROM t1; -Warnings: -Note 1449 The user specified as a definer ('no_such'@'user_2') does not exist -SHOW CREATE VIEW v1; -View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=TEMPTABLE DEFINER=`no_such`@`user_2` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci -Warnings: -Note 1449 The user specified as a definer ('no_such'@'user_2') does not exist -DROP VIEW v1; -DROP TABLE t1; -End of 5.1 tests. diff --git a/mysql-test/suite/percona/percona_flush_contiguous_neighbors-master.opt b/mysql-test/suite/percona/percona_flush_contiguous_neighbors-master.opt new file mode 100644 index 00000000000..075af88054f --- /dev/null +++ b/mysql-test/suite/percona/percona_flush_contiguous_neighbors-master.opt @@ -0,0 +1 @@ +--innodb_flush_neighbor_pages=cont diff --git a/mysql-test/suite/percona/percona_flush_contiguous_neighbors.result b/mysql-test/suite/percona/percona_flush_contiguous_neighbors.result new file mode 100644 index 00000000000..8c6b81f0848 --- /dev/null +++ b/mysql-test/suite/percona/percona_flush_contiguous_neighbors.result @@ -0,0 +1,21 @@ +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (id INT AUTO_INCREMENT, foo CHAR(255), PRIMARY KEY (id)) ENGINE=InnoDB; +INSERT INTO t1(foo) VALUES ('a'), ('b'); +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +DROP TABLE t1; diff --git a/mysql-test/suite/percona/percona_flush_contiguous_neighbors.test b/mysql-test/suite/percona/percona_flush_contiguous_neighbors.test new file mode 100644 index 00000000000..4eb967fcd16 --- /dev/null +++ b/mysql-test/suite/percona/percona_flush_contiguous_neighbors.test @@ -0,0 +1,37 @@ +# Test for innodb_flush_neighbor_pages=contiguous. +# The test is very crude: we simply overflow the buffer pool with such a number of +# new/modified pages that some flushing is bound to happen. + +--source include/have_innodb.inc +--source include/big_test.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (id INT AUTO_INCREMENT, foo CHAR(255), PRIMARY KEY (id)) ENGINE=InnoDB; + +INSERT INTO t1(foo) VALUES ('a'), ('b'); +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; +INSERT INTO t1(foo) SELECT foo FROM t1; + +# TODO: cannot record a stable value here. A check of > 0 should be enough, +# but the variable is not accessible through INFORMATION_SCHEMA currently. +# SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_flushed'; + +DROP TABLE t1; diff --git a/mysql-test/suite/percona/percona_query_response_time-replication.result b/mysql-test/suite/percona/percona_query_response_time-replication.result index c00520110c2..a6e88be6103 100644 --- a/mysql-test/suite/percona/percona_query_response_time-replication.result +++ b/mysql-test/suite/percona/percona_query_response_time-replication.result @@ -100,10 +100,10 @@ SHOW QUERY_RESPONSE_TIME; 131072.000000 0 0.000000 262144.000000 0 0.000000 524288.000000 0 0.000000 - 1048576.00000 0 0.000000 - 2097152.00000 0 0.000000 - 4194304.00000 0 0.000000 - 8388608.00000 0 0.000000 +1048576.000000 0 0.000000 +2097152.000000 0 0.000000 +4194304.000000 0 0.000000 +8388608.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -146,10 +146,10 @@ time count total 131072.000000 0 0.000000 262144.000000 0 0.000000 524288.000000 0 0.000000 - 1048576.00000 0 0.000000 - 2097152.00000 0 0.000000 - 4194304.00000 0 0.000000 - 8388608.00000 0 0.000000 +1048576.000000 0 0.000000 +2097152.000000 0 0.000000 +4194304.000000 0 0.000000 +8388608.000000 0 0.000000 TOO LONG 0 TOO LONG SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default; SET GLOBAL QUERY_RESPONSE_TIME_STATS=default; @@ -251,10 +251,10 @@ SHOW QUERY_RESPONSE_TIME; 131072.000000 0 0.000000 262144.000000 0 0.000000 524288.000000 0 0.000000 - 1048576.00000 0 0.000000 - 2097152.00000 0 0.000000 - 4194304.00000 0 0.000000 - 8388608.00000 0 0.000000 +1048576.000000 0 0.000000 +2097152.000000 0 0.000000 +4194304.000000 0 0.000000 +8388608.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -297,10 +297,10 @@ time count total 131072.000000 0 0.000000 262144.000000 0 0.000000 524288.000000 0 0.000000 - 1048576.00000 0 0.000000 - 2097152.00000 0 0.000000 - 4194304.00000 0 0.000000 - 8388608.00000 0 0.000000 +1048576.000000 0 0.000000 +2097152.000000 0 0.000000 +4194304.000000 0 0.000000 +8388608.000000 0 0.000000 TOO LONG 0 TOO LONG SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default; SET GLOBAL QUERY_RESPONSE_TIME_STATS=default; @@ -375,7 +375,7 @@ SHOW QUERY_RESPONSE_TIME; 1000.000000 0 0.000000 10000.000000 0 0.000000 100000.000000 0 0.000000 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -391,7 +391,7 @@ time count total 1000.000000 0 0.000000 10000.000000 0 0.000000 100000.000000 0 0.000000 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default; SET GLOBAL QUERY_RESPONSE_TIME_STATS=default; @@ -469,7 +469,7 @@ SHOW QUERY_RESPONSE_TIME; 16807.000000 0 0.000000 117649.000000 0 0.000000 823543.000000 0 0.000000 - 5764801.00000 0 0.000000 +5764801.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -488,7 +488,7 @@ time count total 16807.000000 0 0.000000 117649.000000 0 0.000000 823543.000000 0 0.000000 - 5764801.00000 0 0.000000 +5764801.000000 0 0.000000 TOO LONG 0 TOO LONG SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default; SET GLOBAL QUERY_RESPONSE_TIME_STATS=default; @@ -556,7 +556,7 @@ SHOW QUERY_RESPONSE_TIME; 1.000000 34 12.250000 156.000000 33 77.099997 24336.000000 0 0.000000 - 3796416.00000 0 0.000000 +3796416.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -565,7 +565,7 @@ time count total 1.000000 34 12.250000 156.000000 33 77.099997 24336.000000 0 0.000000 - 3796416.00000 0 0.000000 +3796416.000000 0 0.000000 TOO LONG 0 TOO LONG SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default; SET GLOBAL QUERY_RESPONSE_TIME_STATS=default; @@ -632,7 +632,7 @@ SHOW QUERY_RESPONSE_TIME; 0.001000 0 0.000000 1.000000 34 12.250000 1000.000000 33 77.099997 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -640,7 +640,7 @@ time count total 0.001000 0 0.000000 1.000000 34 12.250000 1000.000000 33 77.099997 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default; SET GLOBAL QUERY_RESPONSE_TIME_STATS=default; @@ -709,7 +709,7 @@ SHOW QUERY_RESPONSE_TIME; 0.001000 0 0.000000 1.000000 34 12.250000 1000.000000 33 77.099997 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -717,7 +717,7 @@ time count total 0.001000 0 0.000000 1.000000 34 12.250000 1000.000000 33 77.099997 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default; SET GLOBAL QUERY_RESPONSE_TIME_STATS=default; diff --git a/mysql-test/suite/percona/percona_query_response_time-stored.result b/mysql-test/suite/percona/percona_query_response_time-stored.result index 7385231241e..fb458d6e7ab 100644 --- a/mysql-test/suite/percona/percona_query_response_time-stored.result +++ b/mysql-test/suite/percona/percona_query_response_time-stored.result @@ -80,10 +80,10 @@ SHOW QUERY_RESPONSE_TIME; 131072.000000 0 0.000000 262144.000000 0 0.000000 524288.000000 0 0.000000 - 1048576.00000 0 0.000000 - 2097152.00000 0 0.000000 - 4194304.00000 0 0.000000 - 8388608.00000 0 0.000000 +1048576.000000 0 0.000000 +2097152.000000 0 0.000000 +4194304.000000 0 0.000000 +8388608.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -126,10 +126,10 @@ time count total 131072.000000 0 0.000000 262144.000000 0 0.000000 524288.000000 0 0.000000 - 1048576.00000 0 0.000000 - 2097152.00000 0 0.000000 - 4194304.00000 0 0.000000 - 8388608.00000 0 0.000000 +1048576.000000 0 0.000000 +2097152.000000 0 0.000000 +4194304.000000 0 0.000000 +8388608.000000 0 0.000000 TOO LONG 0 TOO LONG SET SESSION query_exec_time=default; SET SESSION query_exec_time=0.1; @@ -204,10 +204,10 @@ SHOW QUERY_RESPONSE_TIME; 131072.000000 0 0.000000 262144.000000 0 0.000000 524288.000000 0 0.000000 - 1048576.00000 0 0.000000 - 2097152.00000 0 0.000000 - 4194304.00000 0 0.000000 - 8388608.00000 0 0.000000 +1048576.000000 0 0.000000 +2097152.000000 0 0.000000 +4194304.000000 0 0.000000 +8388608.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -250,10 +250,10 @@ time count total 131072.000000 0 0.000000 262144.000000 0 0.000000 524288.000000 0 0.000000 - 1048576.00000 0 0.000000 - 2097152.00000 0 0.000000 - 4194304.00000 0 0.000000 - 8388608.00000 0 0.000000 +1048576.000000 0 0.000000 +2097152.000000 0 0.000000 +4194304.000000 0 0.000000 +8388608.000000 0 0.000000 TOO LONG 0 TOO LONG SET SESSION query_exec_time=default; SET SESSION query_exec_time=0.1; @@ -301,7 +301,7 @@ SHOW QUERY_RESPONSE_TIME; 1000.000000 0 0.000000 10000.000000 0 0.000000 100000.000000 0 0.000000 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -317,7 +317,7 @@ time count total 1000.000000 0 0.000000 10000.000000 0 0.000000 100000.000000 0 0.000000 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SET SESSION query_exec_time=default; SET SESSION query_exec_time=0.1; @@ -368,7 +368,7 @@ SHOW QUERY_RESPONSE_TIME; 16807.000000 0 0.000000 117649.000000 0 0.000000 823543.000000 0 0.000000 - 5764801.00000 0 0.000000 +5764801.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -387,7 +387,7 @@ time count total 16807.000000 0 0.000000 117649.000000 0 0.000000 823543.000000 0 0.000000 - 5764801.00000 0 0.000000 +5764801.000000 0 0.000000 TOO LONG 0 TOO LONG SET SESSION query_exec_time=default; SET SESSION query_exec_time=0.1; @@ -428,7 +428,7 @@ SHOW QUERY_RESPONSE_TIME; 1.000000 55 8.450000 156.000000 11 25.699999 24336.000000 0 0.000000 - 3796416.00000 0 0.000000 +3796416.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -437,7 +437,7 @@ time count total 1.000000 55 8.450000 156.000000 11 25.699999 24336.000000 0 0.000000 - 3796416.00000 0 0.000000 +3796416.000000 0 0.000000 TOO LONG 0 TOO LONG SET SESSION query_exec_time=default; SET SESSION query_exec_time=0.1; @@ -477,7 +477,7 @@ SHOW QUERY_RESPONSE_TIME; 0.001000 0 0.000000 1.000000 55 8.450000 1000.000000 11 25.699999 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -485,7 +485,7 @@ time count total 0.001000 0 0.000000 1.000000 55 8.450000 1000.000000 11 25.699999 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SET SESSION query_exec_time=default; SET SESSION query_exec_time=0.1; @@ -527,7 +527,7 @@ SHOW QUERY_RESPONSE_TIME; 0.001000 0 0.000000 1.000000 55 8.450000 1000.000000 11 25.699999 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -535,7 +535,7 @@ time count total 0.001000 0 0.000000 1.000000 55 8.450000 1000.000000 11 25.699999 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SET SESSION query_exec_time=default; SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default; diff --git a/mysql-test/suite/percona/percona_query_response_time.result b/mysql-test/suite/percona/percona_query_response_time.result index 4c4d50319c0..1eb90d3cdd4 100644 --- a/mysql-test/suite/percona/percona_query_response_time.result +++ b/mysql-test/suite/percona/percona_query_response_time.result @@ -45,10 +45,10 @@ SHOW QUERY_RESPONSE_TIME; 131072.000000 0 0.000000 262144.000000 0 0.000000 524288.000000 0 0.000000 - 1048576.00000 0 0.000000 - 2097152.00000 0 0.000000 - 4194304.00000 0 0.000000 - 8388608.00000 0 0.000000 +1048576.000000 0 0.000000 +2097152.000000 0 0.000000 +4194304.000000 0 0.000000 +8388608.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -91,10 +91,10 @@ time count total 131072.000000 0 0.000000 262144.000000 0 0.000000 524288.000000 0 0.000000 - 1048576.00000 0 0.000000 - 2097152.00000 0 0.000000 - 4194304.00000 0 0.000000 - 8388608.00000 0 0.000000 +1048576.000000 0 0.000000 +2097152.000000 0 0.000000 +4194304.000000 0 0.000000 +8388608.000000 0 0.000000 TOO LONG 0 TOO LONG SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; SET SESSION query_exec_time=0.31; @@ -231,10 +231,10 @@ SHOW QUERY_RESPONSE_TIME; 131072.000000 0 0.000000 262144.000000 0 0.000000 524288.000000 0 0.000000 - 1048576.00000 0 0.000000 - 2097152.00000 0 0.000000 - 4194304.00000 0 0.000000 - 8388608.00000 0 0.000000 +1048576.000000 0 0.000000 +2097152.000000 0 0.000000 +4194304.000000 0 0.000000 +8388608.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -277,10 +277,10 @@ time count total 131072.000000 0 0.000000 262144.000000 0 0.000000 524288.000000 0 0.000000 - 1048576.00000 0 0.000000 - 2097152.00000 0 0.000000 - 4194304.00000 0 0.000000 - 8388608.00000 0 0.000000 +1048576.000000 0 0.000000 +2097152.000000 0 0.000000 +4194304.000000 0 0.000000 +8388608.000000 0 0.000000 TOO LONG 0 TOO LONG SET SESSION query_exec_time=default; SET SESSION query_exec_time=0.1; @@ -328,10 +328,10 @@ SHOW QUERY_RESPONSE_TIME; 131072.000000 0 0.000000 262144.000000 0 0.000000 524288.000000 0 0.000000 - 1048576.00000 0 0.000000 - 2097152.00000 0 0.000000 - 4194304.00000 0 0.000000 - 8388608.00000 0 0.000000 +1048576.000000 0 0.000000 +2097152.000000 0 0.000000 +4194304.000000 0 0.000000 +8388608.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -374,10 +374,10 @@ time count total 131072.000000 0 0.000000 262144.000000 0 0.000000 524288.000000 0 0.000000 - 1048576.00000 0 0.000000 - 2097152.00000 0 0.000000 - 4194304.00000 0 0.000000 - 8388608.00000 0 0.000000 +1048576.000000 0 0.000000 +2097152.000000 0 0.000000 +4194304.000000 0 0.000000 +8388608.000000 0 0.000000 TOO LONG 0 TOO LONG SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; SET SESSION query_exec_time=0.31; @@ -514,10 +514,10 @@ SHOW QUERY_RESPONSE_TIME; 131072.000000 0 0.000000 262144.000000 0 0.000000 524288.000000 0 0.000000 - 1048576.00000 0 0.000000 - 2097152.00000 0 0.000000 - 4194304.00000 0 0.000000 - 8388608.00000 0 0.000000 +1048576.000000 0 0.000000 +2097152.000000 0 0.000000 +4194304.000000 0 0.000000 +8388608.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -560,10 +560,10 @@ time count total 131072.000000 0 0.000000 262144.000000 0 0.000000 524288.000000 0 0.000000 - 1048576.00000 0 0.000000 - 2097152.00000 0 0.000000 - 4194304.00000 0 0.000000 - 8388608.00000 0 0.000000 +1048576.000000 0 0.000000 +2097152.000000 0 0.000000 +4194304.000000 0 0.000000 +8388608.000000 0 0.000000 TOO LONG 0 TOO LONG SET SESSION query_exec_time=default; SET SESSION query_exec_time=0.1; @@ -584,7 +584,7 @@ SHOW QUERY_RESPONSE_TIME; 1000.000000 0 0.000000 10000.000000 0 0.000000 100000.000000 0 0.000000 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -600,7 +600,7 @@ time count total 1000.000000 0 0.000000 10000.000000 0 0.000000 100000.000000 0 0.000000 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; SET SESSION query_exec_time=0.31; @@ -710,7 +710,7 @@ SHOW QUERY_RESPONSE_TIME; 1000.000000 0 0.000000 10000.000000 0 0.000000 100000.000000 0 0.000000 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -726,7 +726,7 @@ time count total 1000.000000 0 0.000000 10000.000000 0 0.000000 100000.000000 0 0.000000 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SET SESSION query_exec_time=default; SET SESSION query_exec_time=0.1; @@ -750,7 +750,7 @@ SHOW QUERY_RESPONSE_TIME; 16807.000000 0 0.000000 117649.000000 0 0.000000 823543.000000 0 0.000000 - 5764801.00000 0 0.000000 +5764801.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -769,7 +769,7 @@ time count total 16807.000000 0 0.000000 117649.000000 0 0.000000 823543.000000 0 0.000000 - 5764801.00000 0 0.000000 +5764801.000000 0 0.000000 TOO LONG 0 TOO LONG SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; SET SESSION query_exec_time=0.31; @@ -882,7 +882,7 @@ SHOW QUERY_RESPONSE_TIME; 16807.000000 0 0.000000 117649.000000 0 0.000000 823543.000000 0 0.000000 - 5764801.00000 0 0.000000 +5764801.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -901,7 +901,7 @@ time count total 16807.000000 0 0.000000 117649.000000 0 0.000000 823543.000000 0 0.000000 - 5764801.00000 0 0.000000 +5764801.000000 0 0.000000 TOO LONG 0 TOO LONG SET SESSION query_exec_time=default; SET SESSION query_exec_time=0.1; @@ -915,7 +915,7 @@ SHOW QUERY_RESPONSE_TIME; 1.000000 0 0.000000 156.000000 0 0.000000 24336.000000 0 0.000000 - 3796416.00000 0 0.000000 +3796416.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -924,7 +924,7 @@ time count total 1.000000 0 0.000000 156.000000 0 0.000000 24336.000000 0 0.000000 - 3796416.00000 0 0.000000 +3796416.000000 0 0.000000 TOO LONG 0 TOO LONG SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; SET SESSION query_exec_time=0.31; @@ -1027,7 +1027,7 @@ SHOW QUERY_RESPONSE_TIME; 1.000000 11 4.050000 156.000000 11 25.699999 24336.000000 0 0.000000 - 3796416.00000 0 0.000000 +3796416.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -1036,7 +1036,7 @@ time count total 1.000000 11 4.050000 156.000000 11 25.699999 24336.000000 0 0.000000 - 3796416.00000 0 0.000000 +3796416.000000 0 0.000000 TOO LONG 0 TOO LONG SET SESSION query_exec_time=default; SET SESSION query_exec_time=0.1; @@ -1049,7 +1049,7 @@ SHOW QUERY_RESPONSE_TIME; 0.001000 0 0.000000 1.000000 0 0.000000 1000.000000 0 0.000000 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -1057,7 +1057,7 @@ time count total 0.001000 0 0.000000 1.000000 0 0.000000 1000.000000 0 0.000000 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; SET SESSION query_exec_time=0.31; @@ -1159,7 +1159,7 @@ SHOW QUERY_RESPONSE_TIME; 0.001000 0 0.000000 1.000000 11 4.050000 1000.000000 11 25.699999 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -1167,7 +1167,7 @@ time count total 0.001000 0 0.000000 1.000000 11 4.050000 1000.000000 11 25.699999 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SET SESSION query_exec_time=default; SET SESSION query_exec_time=0.1; @@ -1182,7 +1182,7 @@ SHOW QUERY_RESPONSE_TIME; 0.001000 0 0.000000 1.000000 0 0.000000 1000.000000 0 0.000000 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -1190,7 +1190,7 @@ time count total 0.001000 0 0.000000 1.000000 0 0.000000 1000.000000 0 0.000000 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; SET SESSION query_exec_time=0.31; @@ -1292,7 +1292,7 @@ SHOW QUERY_RESPONSE_TIME; 0.001000 0 0.000000 1.000000 11 4.050000 1000.000000 11 25.699999 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; time count total @@ -1300,7 +1300,7 @@ time count total 0.001000 0 0.000000 1.000000 11 4.050000 1000.000000 11 25.699999 - 1000000.00000 0 0.000000 +1000000.000000 0 0.000000 TOO LONG 0 TOO LONG SET SESSION query_exec_time=default; SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default; diff --git a/mysql-test/suite/percona/percona_server_variables_debug.result b/mysql-test/suite/percona/percona_server_variables_debug.result index ea1c02e7716..ae02a48c8fa 100644 --- a/mysql-test/suite/percona/percona_server_variables_debug.result +++ b/mysql-test/suite/percona/percona_server_variables_debug.result @@ -109,6 +109,7 @@ INNODB_FILE_FORMAT INNODB_FILE_FORMAT_CHECK INNODB_FILE_FORMAT_MAX INNODB_FILE_PER_TABLE +INNODB_FLUSH_CHECKPOINT_DEBUG INNODB_FLUSH_LOG_AT_TRX_COMMIT INNODB_FLUSH_METHOD INNODB_FLUSH_NEIGHBOR_PAGES @@ -228,6 +229,7 @@ MAX_SP_RECURSION_DEPTH MAX_TMP_TABLES MAX_USER_CONNECTIONS MAX_WRITE_LOCK_COUNT +METADATA_LOCKS_CACHE_SIZE MIN_EXAMINED_ROW_LIMIT MULTI_RANGE_COUNT MYISAM_DATA_POINTER_SIZE diff --git a/mysql-test/suite/percona/percona_server_variables_release.result b/mysql-test/suite/percona/percona_server_variables_release.result index e5965cf7e5e..29ac402c144 100644 --- a/mysql-test/suite/percona/percona_server_variables_release.result +++ b/mysql-test/suite/percona/percona_server_variables_release.result @@ -225,6 +225,7 @@ MAX_SP_RECURSION_DEPTH MAX_TMP_TABLES MAX_USER_CONNECTIONS MAX_WRITE_LOCK_COUNT +METADATA_LOCKS_CACHE_SIZE MIN_EXAMINED_ROW_LIMIT MULTI_RANGE_COUNT MYISAM_DATA_POINTER_SIZE diff --git a/mysql-test/suite/percona/percona_sync_flush.result b/mysql-test/suite/percona/percona_sync_flush.result new file mode 100644 index 00000000000..12335257b32 --- /dev/null +++ b/mysql-test/suite/percona/percona_sync_flush.result @@ -0,0 +1,35 @@ +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (id INT AUTO_INCREMENT, foo CHAR(255), PRIMARY KEY (id)) ENGINE=InnoDB; +SET @@global.innodb_flush_checkpoint_debug=1; +INSERT INTO t1(foo) VALUES ('a'), ('b'); +INSERT INTO t1(foo) SELECT foo FROM t1; +UPDATE t1 SET foo='c'; +INSERT INTO t1(foo) SELECT foo FROM t1; +UPDATE t1 SET foo='c'; +INSERT INTO t1(foo) SELECT foo FROM t1; +UPDATE t1 SET foo='c'; +INSERT INTO t1(foo) SELECT foo FROM t1; +UPDATE t1 SET foo='c'; +INSERT INTO t1(foo) SELECT foo FROM t1; +UPDATE t1 SET foo='c'; +INSERT INTO t1(foo) SELECT foo FROM t1; +UPDATE t1 SET foo='c'; +INSERT INTO t1(foo) SELECT foo FROM t1; +UPDATE t1 SET foo='c'; +INSERT INTO t1(foo) SELECT foo FROM t1; +UPDATE t1 SET foo='c'; +INSERT INTO t1(foo) SELECT foo FROM t1; +UPDATE t1 SET foo='c'; +INSERT INTO t1(foo) SELECT foo FROM t1; +UPDATE t1 SET foo='c'; +INSERT INTO t1(foo) SELECT foo FROM t1; +UPDATE t1 SET foo='c'; +INSERT INTO t1(foo) SELECT foo FROM t1; +UPDATE t1 SET foo='c'; +INSERT INTO t1(foo) SELECT foo FROM t1; +UPDATE t1 SET foo='c'; +INSERT INTO t1(foo) SELECT foo FROM t1; +UPDATE t1 SET foo='c'; +SET @@global.innodb_flush_checkpoint_debug=0; +UPDATE t1 SET foo='d' WHERE foo='c'; +DROP TABLE t1; diff --git a/mysql-test/suite/percona/percona_sync_flush.test b/mysql-test/suite/percona/percona_sync_flush.test new file mode 100644 index 00000000000..35e8d8f92d2 --- /dev/null +++ b/mysql-test/suite/percona/percona_sync_flush.test @@ -0,0 +1,33 @@ +# Test for InnoDB sync state flushing. + +--source include/have_innodb.inc +--source include/have_debug.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (id INT AUTO_INCREMENT, foo CHAR(255), PRIMARY KEY (id)) ENGINE=InnoDB; + +# It is hard to get to InnoDB sync state flushing in MTR with regular workload. Perhaps +# it is possible with many parallel connections, but that would be brittle anyway. +# So, just disable preflushing and checkpointing and issue simple workload. +SET @@global.innodb_flush_checkpoint_debug=1; + +INSERT INTO t1(foo) VALUES ('a'), ('b'); + +let $rep=0; +while ($rep < 14) +{ + INSERT INTO t1(foo) SELECT foo FROM t1; + UPDATE t1 SET foo='c'; + inc $rep; +} + +# By now checkpoint age should be well past sync flush point. Allow +# preflushing/checkpointing again and do some work in order to do the sync flush. +SET @@global.innodb_flush_checkpoint_debug=0; + +UPDATE t1 SET foo='d' WHERE foo='c'; + +DROP TABLE t1; diff --git a/mysql-test/suite/percona/query_cache_enhance.patch/percona_query_cache_with_comments.inc b/mysql-test/suite/percona/query_cache_enhance.patch/percona_query_cache_with_comments.inc index d55e52d5b64..d9804722147 100644 --- a/mysql-test/suite/percona/query_cache_enhance.patch/percona_query_cache_with_comments.inc +++ b/mysql-test/suite/percona/query_cache_enhance.patch/percona_query_cache_with_comments.inc @@ -91,5 +91,27 @@ let $query=select * from t1 -- comment in the end ; --source percona_query_cache_with_comments_eval.inc +let $query=select */* a comment \*/from t1; +--source include/percona_query_cache_with_comments_eval.inc + +let $query=select *# a comment \\ +from t1; +--source include/percona_query_cache_with_comments_eval.inc + +let $query=select *-- a comment \\ +from t1; +--source include/percona_query_cache_with_comments_eval.inc + +let $query=select "\\\\"" /* not a comment */" from t1; +--source include/percona_query_cache_with_comments_eval.inc + +let $query=select "\\\\"" /*! not a comment */" from t1; +--source include/percona_query_cache_with_comments_eval.inc + +# following two queries related to bug #856404. +# There are different queries, but opt_query_cache_strip_comments thinks that they are equal. let $query=select ' \' ' from t1; --source percona_query_cache_with_comments_eval.inc + +let $query=select ' \' /* comment inside quotes with internal backslash quote */' from t1; +--source percona_query_cache_with_comments_eval.inc diff --git a/mysql-test/suite/percona/query_cache_enhance.patch/percona_query_cache_with_comments.result b/mysql-test/suite/percona/query_cache_enhance.patch/percona_query_cache_with_comments.result index 169fdf80fef..d1a6ded08d7 100644 --- a/mysql-test/suite/percona/query_cache_enhance.patch/percona_query_cache_with_comments.result +++ b/mysql-test/suite/percona/query_cache_enhance.patch/percona_query_cache_with_comments.result @@ -831,7 +831,7 @@ show status like "Qcache_hits"; Variable_name Value Qcache_hits 50 ----------------------------------------------------- -select ' \' ' from t1 +select */* a comment \*/from t1 ----------------------------------------------------- show status like "Qcache_queries_in_cache"; Variable_name Value @@ -842,6 +842,167 @@ Qcache_inserts 1 show status like "Qcache_hits"; Variable_name Value Qcache_hits 50 +select */* a comment \*/from t1; +a +1 +2 +3 +select */* a comment \*/from t1; +a +1 +2 +3 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 52 +----------------------------------------------------- +select *# a comment \ +from t1 +----------------------------------------------------- +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 52 +select *# a comment \ +from t1; +a +1 +2 +3 +select *# a comment \ +from t1; +a +1 +2 +3 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 54 +----------------------------------------------------- +select *-- a comment \ +from t1 +----------------------------------------------------- +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 54 +select *-- a comment \ +from t1; +a +1 +2 +3 +select *-- a comment \ +from t1; +a +1 +2 +3 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 56 +----------------------------------------------------- +select "\\"" /* not a comment */" from t1 +----------------------------------------------------- +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 56 +select "\\"" /* not a comment */" from t1; +\" /* not a comment */ +\" /* not a comment */ +\" /* not a comment */ +\" /* not a comment */ +select "\\"" /* not a comment */" from t1; +\" /* not a comment */ +\" /* not a comment */ +\" /* not a comment */ +\" /* not a comment */ +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 2 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 57 +----------------------------------------------------- +select "\\"" /*! not a comment */" from t1 +----------------------------------------------------- +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 2 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 57 +select "\\"" /*! not a comment */" from t1; +\" /*! not a comment */ +\" /*! not a comment */ +\" /*! not a comment */ +\" /*! not a comment */ +select "\\"" /*! not a comment */" from t1; +\" /*! not a comment */ +\" /*! not a comment */ +\" /*! not a comment */ +\" /*! not a comment */ +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 3 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 3 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 58 +----------------------------------------------------- +select ' \' ' from t1 +----------------------------------------------------- +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 3 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 3 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 58 select ' \' ' from t1; ' ' @@ -854,13 +1015,44 @@ select ' \' ' from t1; ' show status like "Qcache_queries_in_cache"; Variable_name Value -Qcache_queries_in_cache 2 +Qcache_queries_in_cache 4 show status like "Qcache_inserts"; Variable_name Value -Qcache_inserts 2 +Qcache_inserts 4 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 59 +----------------------------------------------------- +select ' \' /* comment inside quotes with internal backslash quote */' from t1 +----------------------------------------------------- +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 4 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 4 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 59 +select ' \' /* comment inside quotes with internal backslash quote */' from t1; +' /* comment inside quotes with internal backslash quote */ + ' /* comment inside quotes with internal backslash quote */ + ' /* comment inside quotes with internal backslash quote */ + ' /* comment inside quotes with internal backslash quote */ +select ' \' /* comment inside quotes with internal backslash quote */' from t1; +' /* comment inside quotes with internal backslash quote */ + ' /* comment inside quotes with internal backslash quote */ + ' /* comment inside quotes with internal backslash quote */ + ' /* comment inside quotes with internal backslash quote */ +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 5 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 5 show status like "Qcache_hits"; Variable_name Value -Qcache_hits 51 +Qcache_hits 60 DROP TABLE t1; SET GLOBAL query_cache_size=default; set global query_cache_strip_comments=OFF; diff --git a/mysql-test/suite/percona/query_cache_enhance.patch/percona_query_cache_with_comments_disable.result b/mysql-test/suite/percona/query_cache_enhance.patch/percona_query_cache_with_comments_disable.result index a13a44d9a1c..7e793a942c5 100644 --- a/mysql-test/suite/percona/query_cache_enhance.patch/percona_query_cache_with_comments_disable.result +++ b/mysql-test/suite/percona/query_cache_enhance.patch/percona_query_cache_with_comments_disable.result @@ -830,7 +830,7 @@ show status like "Qcache_hits"; Variable_name Value Qcache_hits 25 ----------------------------------------------------- -select ' \' ' from t1 +select */* a comment \*/from t1 ----------------------------------------------------- show status like "Qcache_queries_in_cache"; Variable_name Value @@ -841,6 +841,167 @@ Qcache_inserts 20 show status like "Qcache_hits"; Variable_name Value Qcache_hits 25 +select */* a comment \*/from t1; +a +1 +2 +3 +select */* a comment \*/from t1; +a +1 +2 +3 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 21 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 21 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 26 +----------------------------------------------------- +select *# a comment \ +from t1 +----------------------------------------------------- +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 21 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 21 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 26 +select *# a comment \ +from t1; +a +1 +2 +3 +select *# a comment \ +from t1; +a +1 +2 +3 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 22 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 22 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 27 +----------------------------------------------------- +select *-- a comment \ +from t1 +----------------------------------------------------- +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 22 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 22 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 27 +select *-- a comment \ +from t1; +a +1 +2 +3 +select *-- a comment \ +from t1; +a +1 +2 +3 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 23 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 23 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 28 +----------------------------------------------------- +select "\\"" /* not a comment */" from t1 +----------------------------------------------------- +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 23 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 23 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 28 +select "\\"" /* not a comment */" from t1; +\" /* not a comment */ +\" /* not a comment */ +\" /* not a comment */ +\" /* not a comment */ +select "\\"" /* not a comment */" from t1; +\" /* not a comment */ +\" /* not a comment */ +\" /* not a comment */ +\" /* not a comment */ +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 24 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 24 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 29 +----------------------------------------------------- +select "\\"" /*! not a comment */" from t1 +----------------------------------------------------- +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 24 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 24 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 29 +select "\\"" /*! not a comment */" from t1; +\" /*! not a comment */ +\" /*! not a comment */ +\" /*! not a comment */ +\" /*! not a comment */ +select "\\"" /*! not a comment */" from t1; +\" /*! not a comment */ +\" /*! not a comment */ +\" /*! not a comment */ +\" /*! not a comment */ +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 25 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 25 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 30 +----------------------------------------------------- +select ' \' ' from t1 +----------------------------------------------------- +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 25 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 25 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 30 select ' \' ' from t1; ' ' @@ -853,13 +1014,44 @@ select ' \' ' from t1; ' show status like "Qcache_queries_in_cache"; Variable_name Value -Qcache_queries_in_cache 21 +Qcache_queries_in_cache 26 show status like "Qcache_inserts"; Variable_name Value -Qcache_inserts 21 +Qcache_inserts 26 show status like "Qcache_hits"; Variable_name Value -Qcache_hits 26 +Qcache_hits 31 +----------------------------------------------------- +select ' \' /* comment inside quotes with internal backslash quote */' from t1 +----------------------------------------------------- +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 26 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 26 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 31 +select ' \' /* comment inside quotes with internal backslash quote */' from t1; +' /* comment inside quotes with internal backslash quote */ + ' /* comment inside quotes with internal backslash quote */ + ' /* comment inside quotes with internal backslash quote */ + ' /* comment inside quotes with internal backslash quote */ +select ' \' /* comment inside quotes with internal backslash quote */' from t1; +' /* comment inside quotes with internal backslash quote */ + ' /* comment inside quotes with internal backslash quote */ + ' /* comment inside quotes with internal backslash quote */ + ' /* comment inside quotes with internal backslash quote */ +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 27 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 27 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 32 DROP TABLE t1; SET GLOBAL query_cache_size=default; set global query_cache_strip_comments=OFF; diff --git a/mysql-test/suite/percona/query_cache_enhance.patch/percona_status_wait_query_cache_mutex.result b/mysql-test/suite/percona/query_cache_enhance.patch/percona_status_wait_query_cache_mutex.result index 678ed685a5b..c243b8ad02f 100644 --- a/mysql-test/suite/percona/query_cache_enhance.patch/percona_status_wait_query_cache_mutex.result +++ b/mysql-test/suite/percona/query_cache_enhance.patch/percona_status_wait_query_cache_mutex.result @@ -3,21 +3,18 @@ flush query cache; flush query cache; reset query cache; flush status; -DROP TABLE IF EXISTS t; -CREATE TABLE t(id INT, number INT); -INSERT INTO t VALUES (0,1); -INSERT INTO t VALUES (1,2); -INSERT INTO t VALUES (2,3); -SET SESSION debug="+d,status_waiting_on_query_cache_mutex_sleep"; -SET DEBUG_SYNC='status_waiting_on_query_cache_mutex SIGNAL thread_ready'; -SELECT number from t where id > 0; -SHOW PROCESSLIST; -Id User Host db Command Time State Info Rows_sent Rows_examined Rows_read -### root ### test Query ### NULL SHOW PROCESSLIST ### ### ### -### root ### test Query ### Waiting on query cache mutex SELECT number from t where id > 0 ### ### ### -SELECT id, info, state FROM INFORMATION_SCHEMA.PROCESSLIST ORDER BY id; -id info state -### SELECT id, info, state FROM INFORMATION_SCHEMA.PROCESSLIST ORDER BY id executing -### SELECT number from t where id > 0 Waiting on query cache mutex -DROP TABLE t; +SET DEBUG_SYNC='after_query_cache_mutex SIGNAL mutex_locked WAIT_FOR unlock_mutex'; +SELECT "mutex_locked_query" as action; +SET DEBUG_SYNC='now WAIT_FOR mutex_locked'; +SET DEBUG_SYNC='before_query_cache_mutex SIGNAL try_lock_mutex'; +SELECT "try_lock_mutex_query" as action; +SET DEBUG_SYNC='now WAIT_FOR try_lock_mutex'; +SELECT SQL_NO_CACHE state FROM INFORMATION_SCHEMA.PROCESSLIST WHERE info='SELECT "try_lock_mutex_query" as action'; +state +Waiting on query cache mutex +SET DEBUG_SYNC='now SIGNAL unlock_mutex'; +action +mutex_locked_query +action +try_lock_mutex_query SET GLOBAL query_cache_size=0; diff --git a/mysql-test/suite/percona/query_cache_enhance.patch/percona_status_wait_query_cache_mutex.test b/mysql-test/suite/percona/query_cache_enhance.patch/percona_status_wait_query_cache_mutex.test index 1e586ca4e7a..b20f088d6ae 100644 --- a/mysql-test/suite/percona/query_cache_enhance.patch/percona_status_wait_query_cache_mutex.test +++ b/mysql-test/suite/percona/query_cache_enhance.patch/percona_status_wait_query_cache_mutex.test @@ -3,29 +3,33 @@ --source include/have_debug_sync.inc SET GLOBAL query_cache_size=1355776; --source include/percona_query_cache_with_comments_clear.inc +--let try_lock_mutex_query=SELECT "try_lock_mutex_query" as action --- disable_warnings -DROP TABLE IF EXISTS t; --- enable_warnings -CREATE TABLE t(id INT, number INT); -INSERT INTO t VALUES (0,1); -INSERT INTO t VALUES (1,2); -INSERT INTO t VALUES (2,3); +--connect (mutex_locked_conn, localhost, root,,) +--connect (try_mutex_lock_conn, localhost, root,,) ---connect (conn,localhost,root,,) +--connection mutex_locked_conn +SET DEBUG_SYNC='after_query_cache_mutex SIGNAL mutex_locked WAIT_FOR unlock_mutex'; +send SELECT "mutex_locked_query" as action; ---connection conn -SET SESSION debug="+d,status_waiting_on_query_cache_mutex_sleep"; -SET DEBUG_SYNC='status_waiting_on_query_cache_mutex SIGNAL thread_ready'; -SEND SELECT number from t where id > 0; +--connection default +SET DEBUG_SYNC='now WAIT_FOR mutex_locked'; + +--connection try_mutex_lock_conn +SET DEBUG_SYNC='before_query_cache_mutex SIGNAL try_lock_mutex'; +send_eval $try_lock_mutex_query; --connection default ---replace_column 1 ### 3 ### 6 ### 9 ### 10 ### 11 ### -SHOW PROCESSLIST; +SET DEBUG_SYNC='now WAIT_FOR try_lock_mutex'; +eval SELECT SQL_NO_CACHE state FROM INFORMATION_SCHEMA.PROCESSLIST WHERE info='$try_lock_mutex_query'; +SET DEBUG_SYNC='now SIGNAL unlock_mutex'; ---replace_column 1 ### -SELECT id, info, state FROM INFORMATION_SCHEMA.PROCESSLIST ORDER BY id; +--connection mutex_locked_conn +reap; +--connection try_mutex_lock_conn +reap; ---disconnect conn -DROP TABLE t; +--connection default +--disconnect mutex_locked_conn +--disconnect try_mutex_lock_conn SET GLOBAL query_cache_size=0; diff --git a/mysql-test/suite/perfschema/r/all_instances.result b/mysql-test/suite/perfschema/r/all_instances.result index 7eb2bc73d8e..59b1950cb88 100644 --- a/mysql-test/suite/perfschema/r/all_instances.result +++ b/mysql-test/suite/perfschema/r/all_instances.result @@ -1,5 +1,8 @@ use performance_schema; -select name from mutex_instances where name not rlike '/(DEBUG_SYNC::mutex)$' group by name; +select name from mutex_instances +where name not rlike '/(DEBUG_SYNC::mutex)$' + and name != 'wait/synch/mutex/mysys/BITMAP::mutex' + group by name; name wait/synch/mutex/archive/archive_mutex wait/synch/mutex/aria/LOCK_trn_list @@ -16,7 +19,6 @@ wait/synch/mutex/blackhole/blackhole wait/synch/mutex/csv/tina wait/synch/mutex/memory/HP_SHARE::intern_lock wait/synch/mutex/myisam/MYISAM_SHARE::intern_lock -wait/synch/mutex/mysys/BITMAP::mutex wait/synch/mutex/mysys/KEY_CACHE::cache_lock wait/synch/mutex/mysys/LOCK_alarm wait/synch/mutex/mysys/LOCK_uuid_generator @@ -51,7 +53,6 @@ wait/synch/mutex/sql/LOCK_global_index_stats wait/synch/mutex/sql/LOCK_global_system_variables wait/synch/mutex/sql/LOCK_global_table_stats wait/synch/mutex/sql/LOCK_global_user_client_stats -wait/synch/mutex/sql/LOCK_manager wait/synch/mutex/sql/LOCK_open wait/synch/mutex/sql/LOCK_plugin wait/synch/mutex/sql/LOCK_prepared_stmt_count @@ -112,7 +113,6 @@ wait/synch/cond/mysys/COND_alarm wait/synch/cond/mysys/my_thread_var::suspend wait/synch/cond/mysys/THR_COND_threads wait/synch/cond/sql/COND_flush_thread_cache -wait/synch/cond/sql/COND_manager wait/synch/cond/sql/COND_queue_state wait/synch/cond/sql/COND_rpl_status wait/synch/cond/sql/COND_server_started diff --git a/mysql-test/suite/perfschema/r/server_init.result b/mysql-test/suite/perfschema/r/server_init.result index 3e67915adcd..5497267080e 100644 --- a/mysql-test/suite/perfschema/r/server_init.result +++ b/mysql-test/suite/perfschema/r/server_init.result @@ -82,7 +82,7 @@ count(name) select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_manager"; count(name) -1 +0 select count(name) from mutex_instances where name like "wait/synch/mutex/sql/LOCK_global_system_variables"; count(name) @@ -170,7 +170,7 @@ count(name) select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_manager"; count(name) -1 +0 select count(name) from cond_instances where name like "wait/synch/cond/sql/COND_thread_cache"; count(name) diff --git a/mysql-test/suite/perfschema/t/all_instances.test b/mysql-test/suite/perfschema/t/all_instances.test index 46b2c06c327..1119f523829 100644 --- a/mysql-test/suite/perfschema/t/all_instances.test +++ b/mysql-test/suite/perfschema/t/all_instances.test @@ -17,7 +17,10 @@ use performance_schema; # "where" filters out instances that can be conditionally compiled out # -select name from mutex_instances where name not rlike '/(DEBUG_SYNC::mutex)$' group by name; +select name from mutex_instances + where name not rlike '/(DEBUG_SYNC::mutex)$' + and name != 'wait/synch/mutex/mysys/BITMAP::mutex' + group by name; # CRYPTO_dynlock_value::lock exists only when building with OpenSSL (not YaSSL). select name from rwlock_instances where name not in ("wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock") diff --git a/mysql-test/suite/plugins/r/pam.result b/mysql-test/suite/plugins/r/pam.result index 1c9036c317e..432fb48eb5a 100644 --- a/mysql-test/suite/plugins/r/pam.result +++ b/mysql-test/suite/plugins/r/pam.result @@ -1,5 +1,7 @@ install plugin pam soname 'auth_pam.so'; create user test_pam identified via pam using 'mariadb_mtr'; +create user pam_test; +grant proxy on pam_test to test_pam; # # athentication is successful, challenge/pin are ok # note that current_user() differts from user() @@ -19,4 +21,5 @@ Enter: not very secret challenge Now, the magic number! PIN: **** drop user test_pam; +drop user pam_test; uninstall plugin pam; diff --git a/mysql-test/suite/plugins/r/unix_socket.result b/mysql-test/suite/plugins/r/unix_socket.result new file mode 100644 index 00000000000..45bf608cc93 --- /dev/null +++ b/mysql-test/suite/plugins/r/unix_socket.result @@ -0,0 +1,30 @@ +install plugin unix_socket soname 'auth_socket.so'; +# +# with named user +# +create user USER identified via unix_socket; +# +# name match = ok +# +select user(), current_user(), database(); +user() current_user() database() +USER@localhost USER@% test +# +# name does not match = failure +# +drop user USER; +# +# and now with anonymous user +# +grant SELECT ON test.* TO '' identified via unix_socket; +# +# name match = ok +# +select user(), current_user(), database(); +user() current_user() database() +USER@localhost @% test +# +# name does not match = failure +# +delete from mysql.user where user=''; +uninstall plugin unix_socket; diff --git a/mysql-test/suite/plugins/t/pam.test b/mysql-test/suite/plugins/t/pam.test index 3f4c563d8dc..2a097b9bfd5 100644 --- a/mysql-test/suite/plugins/t/pam.test +++ b/mysql-test/suite/plugins/t/pam.test @@ -9,9 +9,10 @@ if (!$PAM_SETUP_FOR_MTR) { skip No pam setup for mtr; } ---replace_result .dll .so eval install plugin pam soname '$AUTH_PAM_SO'; create user test_pam identified via pam using 'mariadb_mtr'; +create user pam_test; +grant proxy on pam_test to test_pam; let $plugindir=`SELECT @@global.plugin_dir`; @@ -42,5 +43,6 @@ EOF --remove_file $MYSQLTEST_VARDIR/tmp/pam_good.txt --remove_file $MYSQLTEST_VARDIR/tmp/pam_bad.txt drop user test_pam; +drop user pam_test; uninstall plugin pam; diff --git a/mysql-test/suite/plugins/t/unix_socket.test b/mysql-test/suite/plugins/t/unix_socket.test new file mode 100644 index 00000000000..fc2e6c5b3c6 --- /dev/null +++ b/mysql-test/suite/plugins/t/unix_socket.test @@ -0,0 +1,56 @@ +--source include/not_embedded.inc + +if (!$AUTH_SOCKET_SO) { + skip No auth_socket plugin; +} + +let $plugindir=`SELECT @@global.plugin_dir`; + +eval install plugin unix_socket soname '$AUTH_SOCKET_SO'; + +--echo # +--echo # with named user +--echo # + +--replace_result $USER USER +eval create user $USER identified via unix_socket; + +--write_file $MYSQLTEST_VARDIR/tmp/peercred_test.txt +--replace_result $USER USER +select user(), current_user(), database(); +EOF + +--echo # +--echo # name match = ok +--echo # +--exec $MYSQL_TEST -u $USER --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/peercred_test.txt + +--echo # +--echo # name does not match = failure +--echo # +--error 1 +--exec $MYSQL_TEST -u foobar --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/peercred_test.txt + +--replace_result $USER USER +eval drop user $USER; + +--echo # +--echo # and now with anonymous user +--echo # +grant SELECT ON test.* TO '' identified via unix_socket; +--echo # +--echo # name match = ok +--echo # +--exec $MYSQL_TEST -u $USER --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/peercred_test.txt + +--echo # +--echo # name does not match = failure +--echo # +--error 1 +--exec $MYSQL_TEST -u foobar --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/peercred_test.txt + +# restoring mysql.user to the original state. +delete from mysql.user where user=''; +uninstall plugin unix_socket; +--remove_file $MYSQLTEST_VARDIR/tmp/peercred_test.txt + diff --git a/mysql-test/suite/rpl/r/rpl_cant_read_event_incident.result b/mysql-test/suite/rpl/r/rpl_cant_read_event_incident.result index 1bee6f2ec1a..bcae1c2c62b 100644 --- a/mysql-test/suite/rpl/r/rpl_cant_read_event_incident.result +++ b/mysql-test/suite/rpl/r/rpl_cant_read_event_incident.result @@ -1,12 +1,12 @@ include/master-slave.inc [connection master] +include/stop_slave.inc call mtr.add_suppression("Error in Log_event::read_log_event()"); include/rpl_stop_server.inc [server_number=1] include/rpl_start_server.inc [server_number=1] show binlog events; ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error call mtr.add_suppression("Slave I/O: Got fatal error 1236 from master when reading data from binary log"); -stop slave; reset slave; start slave; include/wait_for_slave_param.inc [Last_IO_Errno] @@ -15,5 +15,5 @@ Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary reset master; stop slave; reset slave; -drop table t; +drop table if exists t; End of the tests diff --git a/mysql-test/suite/rpl/r/rpl_corruption.result b/mysql-test/suite/rpl/r/rpl_corruption.result index 5ecf6b006c9..62f56e70993 100644 --- a/mysql-test/suite/rpl/r/rpl_corruption.result +++ b/mysql-test/suite/rpl/r/rpl_corruption.result @@ -25,14 +25,14 @@ SET GLOBAL debug_dbug="-d,corrupt_read_log_event2"; SET GLOBAL master_verify_checksum=0; SET GLOBAL debug_dbug="+d,corrupt_read_log_event2"; START SLAVE IO_THREAD; -include/wait_for_slave_io_error.inc [errno=1595,1722,1923] +include/wait_for_slave_io_error.inc [errno=1595,1913] SET GLOBAL debug_dbug="-d,corrupt_read_log_event2"; SET GLOBAL debug_dbug= ""; SET GLOBAL master_verify_checksum=1; # 5. Slave. Corruption in network SET GLOBAL debug_dbug="+d,corrupt_queue_event"; START SLAVE IO_THREAD; -include/wait_for_slave_io_error.inc [errno=1595,1722,1923] +include/wait_for_slave_io_error.inc [errno=1595,1913] SET GLOBAL debug_dbug="-d,corrupt_queue_event"; # 6. Slave. Corruption in relay log SET GLOBAL debug_dbug="+d,corrupt_read_log_event_char"; diff --git a/mysql-test/suite/rpl/r/rpl_rotate_purge_deadlock.result b/mysql-test/suite/rpl/r/rpl_rotate_purge_deadlock.result index 34024f89617..1bda3bd3ee1 100644 --- a/mysql-test/suite/rpl/r/rpl_rotate_purge_deadlock.result +++ b/mysql-test/suite/rpl/r/rpl_rotate_purge_deadlock.result @@ -5,6 +5,7 @@ Log_name File_size master-bin.000001 # create table t1 (f text) engine=innodb; SET DEBUG_SYNC = 'at_purge_logs_before_date WAIT_FOR rotated'; +SET DEBUG_SYNC = 'after_purge_logs_before_date SIGNAL continued'; insert into t1 set f=repeat('a', 4096); *** there must be two logs in the list *** show binary logs; @@ -19,11 +20,14 @@ master-bin.000001 # master-bin.000002 # master-bin.000003 # SET DEBUG_SYNC = 'now SIGNAL rotated'; +SET DEBUG_SYNC = 'now WAIT_FOR continued'; SET DEBUG_SYNC = 'RESET'; SET DEBUG_SYNC = 'RESET'; SET DEBUG_SYNC = 'at_purge_logs_before_date WAIT_FOR rotated'; +SET DEBUG_SYNC = 'after_purge_logs_before_date SIGNAL continued'; insert into t1 set f=repeat('b', 4096); SET DEBUG_SYNC = 'now SIGNAL rotated'; +SET DEBUG_SYNC = 'now WAIT_FOR continued'; SET DEBUG_SYNC = 'RESET'; SET DEBUG_SYNC = 'RESET'; drop table t1; diff --git a/mysql-test/suite/rpl/t/rpl_cant_read_event_incident.test b/mysql-test/suite/rpl/t/rpl_cant_read_event_incident.test index 5e88b163d99..7d05ce251f2 100644 --- a/mysql-test/suite/rpl/t/rpl_cant_read_event_incident.test +++ b/mysql-test/suite/rpl/t/rpl_cant_read_event_incident.test @@ -20,9 +20,15 @@ # --source include/not_windows.inc -call mtr.add_suppression("Error in Log_event::read_log_event()"); +--connection slave +# Make sure the slave is stopped while we are messing with master. +# Otherwise we get occasional failures as the slave manages to re-connect +# to the newly started master and we get extra events applied, causing +# conflicts. +--source include/stop_slave.inc --connection master +call mtr.add_suppression("Error in Log_event::read_log_event()"); --let $datadir= `SELECT @@datadir` --let $rpl_server_number= 1 @@ -42,7 +48,6 @@ show binlog events; --connection slave call mtr.add_suppression("Slave I/O: Got fatal error 1236 from master when reading data from binary log"); -stop slave; reset slave; start slave; @@ -64,6 +69,12 @@ reset master; --connection slave stop slave; reset slave; -drop table t; # table was created from binlog. it does not exist on master. +# The table t may have been created on the slave from binlog. It does not exist +# on the master. +# "May", as it depends on whether the SQL thread had time do do the CREATE +# TABLE before we stopped. +--disable_warnings +drop table if exists t; +--enable_warnings --echo End of the tests diff --git a/mysql-test/suite/rpl/t/rpl_corruption.test b/mysql-test/suite/rpl/t/rpl_corruption.test index 458e3f10e67..c5625b4d002 100644 --- a/mysql-test/suite/rpl/t/rpl_corruption.test +++ b/mysql-test/suite/rpl/t/rpl_corruption.test @@ -115,7 +115,11 @@ SET GLOBAL master_verify_checksum=0; SET GLOBAL debug_dbug="+d,corrupt_read_log_event2"; --connection slave START SLAVE IO_THREAD; -let $slave_io_errno= 1595,1722,1923; +# When the checksum error is detected, the slave sets error code 1913 +# (ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE) in queue_event(), then immediately +# sets error 1595 (ER_SLAVE_RELAY_LOG_WRITE_FAILURE) in handle_slave_io(). +# So we usually get 1595, but it is occasionally possible to get 1913. +let $slave_io_errno= 1595,1913; --source include/wait_for_slave_io_error.inc --connection master SET GLOBAL debug_dbug="-d,corrupt_read_log_event2"; @@ -127,7 +131,7 @@ SET GLOBAL master_verify_checksum=1; --connection slave SET GLOBAL debug_dbug="+d,corrupt_queue_event"; START SLAVE IO_THREAD; -let $slave_io_errno= 1595,1722,1923; +let $slave_io_errno= 1595,1913; --source include/wait_for_slave_io_error.inc SET GLOBAL debug_dbug="-d,corrupt_queue_event"; diff --git a/mysql-test/suite/rpl/t/rpl_rotate_purge_deadlock.test b/mysql-test/suite/rpl/t/rpl_rotate_purge_deadlock.test index 429612c405f..a63844b451c 100644 --- a/mysql-test/suite/rpl/t/rpl_rotate_purge_deadlock.test +++ b/mysql-test/suite/rpl/t/rpl_rotate_purge_deadlock.test @@ -20,6 +20,7 @@ connection master; source include/show_binary_logs.inc; create table t1 (f text) engine=innodb; SET DEBUG_SYNC = 'at_purge_logs_before_date WAIT_FOR rotated'; +SET DEBUG_SYNC = 'after_purge_logs_before_date SIGNAL continued'; send insert into t1 set f=repeat('a', 4096); connection master1; @@ -38,6 +39,7 @@ insert into t1 set f=repeat('b', 4096); source include/show_binary_logs.inc; SET DEBUG_SYNC = 'now SIGNAL rotated'; +SET DEBUG_SYNC = 'now WAIT_FOR continued'; SET DEBUG_SYNC = 'RESET'; # the first connection finally completes its INSERT @@ -54,6 +56,7 @@ sync_slave_with_master; connection master; SET DEBUG_SYNC = 'at_purge_logs_before_date WAIT_FOR rotated'; +SET DEBUG_SYNC = 'after_purge_logs_before_date SIGNAL continued'; send insert into t1 set f=repeat('b', 4096); connection master1; @@ -80,6 +83,7 @@ let $wait_condition= --source include/wait_condition.inc SET DEBUG_SYNC = 'now SIGNAL rotated'; +SET DEBUG_SYNC = 'now WAIT_FOR continued'; SET DEBUG_SYNC = 'RESET'; connection master; diff --git a/mysql-test/suite/sys_vars/r/innodb_flush_checkpoint_debug_basic.result b/mysql-test/suite/sys_vars/r/innodb_flush_checkpoint_debug_basic.result new file mode 100644 index 00000000000..e543cc30975 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/innodb_flush_checkpoint_debug_basic.result @@ -0,0 +1,15 @@ +SELECT @@global.innodb_flush_checkpoint_debug; +@@global.innodb_flush_checkpoint_debug +0 +SET @@global.innodb_flush_checkpoint_debug=1; +SELECT @@global.innodb_flush_checkpoint_debug; +@@global.innodb_flush_checkpoint_debug +1 +SET @@global.innodb_flush_checkpoint_debug=0; +SELECT @@global.innodb_flush_checkpoint_debug; +@@global.innodb_flush_checkpoint_debug +0 +SET @@session.innodb_flush_checkpoint_debug=1; +ERROR HY000: Variable 'innodb_flush_checkpoint_debug' is a GLOBAL variable and should be set with SET GLOBAL +SELECT @@session.innodb_flush_checkpoint_debug; +ERROR HY000: Variable 'innodb_flush_checkpoint_debug' is a GLOBAL variable diff --git a/mysql-test/suite/sys_vars/r/innodb_use_sys_malloc_basic.result b/mysql-test/suite/sys_vars/r/innodb_use_sys_malloc_basic.result index 0c2685b1a49..70ecef72042 100644 --- a/mysql-test/suite/sys_vars/r/innodb_use_sys_malloc_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_use_sys_malloc_basic.result @@ -1,7 +1,4 @@ Valid values are 'ON' and 'OFF' -select @@global.innodb_adaptive_flushing in (0, 1); -@@global.innodb_adaptive_flushing in (0, 1) -1 select @@global.innodb_use_sys_malloc; @@global.innodb_use_sys_malloc 1 diff --git a/mysql-test/suite/sys_vars/t/innodb_flush_checkpoint_debug_basic.test b/mysql-test/suite/sys_vars/t/innodb_flush_checkpoint_debug_basic.test new file mode 100644 index 00000000000..093a765e0e5 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/innodb_flush_checkpoint_debug_basic.test @@ -0,0 +1,12 @@ +--source include/have_debug.inc +--source include/have_xtradb.inc + +SELECT @@global.innodb_flush_checkpoint_debug; +SET @@global.innodb_flush_checkpoint_debug=1; +SELECT @@global.innodb_flush_checkpoint_debug; +SET @@global.innodb_flush_checkpoint_debug=0; +SELECT @@global.innodb_flush_checkpoint_debug; +--error ER_GLOBAL_VARIABLE +SET @@session.innodb_flush_checkpoint_debug=1; +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT @@session.innodb_flush_checkpoint_debug; diff --git a/mysql-test/suite/sys_vars/t/innodb_use_sys_malloc_basic.test b/mysql-test/suite/sys_vars/t/innodb_use_sys_malloc_basic.test index 21f3e904547..699773f4a62 100644 --- a/mysql-test/suite/sys_vars/t/innodb_use_sys_malloc_basic.test +++ b/mysql-test/suite/sys_vars/t/innodb_use_sys_malloc_basic.test @@ -5,11 +5,14 @@ --source include/have_innodb.inc +# when running with valgring, mtr uses --innodb-use-sys-malloc=0, +# while below we want to see the default value. +--source include/not_valgrind.inc + # # show the global and session values; # --echo Valid values are 'ON' and 'OFF' -select @@global.innodb_adaptive_flushing in (0, 1); select @@global.innodb_use_sys_malloc; --error ER_INCORRECT_GLOBAL_LOCAL_VAR select @@session.innodb_use_sys_malloc; diff --git a/mysql-test/suite/vcol/r/vcol_select_innodb.result b/mysql-test/suite/vcol/r/vcol_select_innodb.result index f587520f6aa..97bfbbe4eaf 100644 --- a/mysql-test/suite/vcol/r/vcol_select_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_select_innodb.result @@ -152,7 +152,7 @@ a b c 2 -2 -2 explain select * from t3 where a between 1 and 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using index condition +1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using where # SELECT * FROM tbl_name WHERE <non-indexed vcol expr> select * from t3 where b between -2 and -1; a b c @@ -176,7 +176,7 @@ a b c 1 -1 -1 explain select * from t3 where a between 1 and 2 order by b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using filesort +1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort # SELECT * FROM tbl_name WHERE <non-vcol expr> ORDER BY <indexed vcol> select * from t3 where a between 1 and 2 order by c; a b c @@ -184,7 +184,7 @@ a b c 1 -1 -1 explain select * from t3 where a between 1 and 2 order by c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using filesort +1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort # SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-vcol> select * from t3 where b between -2 and -1 order by a; a b c diff --git a/mysql-test/suite/vcol/r/vcol_select_myisam.result b/mysql-test/suite/vcol/r/vcol_select_myisam.result index d4868340ab5..934d047f6bf 100644 --- a/mysql-test/suite/vcol/r/vcol_select_myisam.result +++ b/mysql-test/suite/vcol/r/vcol_select_myisam.result @@ -265,3 +265,33 @@ NULL explain select sum(c) from t1 group by b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort +# +# Bug #806057: join with USING over a virtual column +# +CREATE TABLE t1 (b int); +INSERT INTO t1 VALUES (NULL),( 78), (185), (0), (154); +CREATE TABLE t2 (a int, b int AS (a) VIRTUAL); +INSERT INTO t2 VALUES (187,187), (9,9), (187,187); +Warnings: +Warning 1906 The value specified for computed column 'b' in table 't2' ignored +Warning 1906 The value specified for computed column 'b' in table 't2' ignored +Warning 1906 The value specified for computed column 'b' in table 't2' ignored +EXPLAIN EXTENDED +SELECT * FROM t1 JOIN t2 USING (b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`b` = `test`.`t2`.`b`) +SELECT * FROM t1 JOIN t2 USING (b); +b a +EXPLAIN EXTENDED +SELECT * FROM t1 NATURAL JOIN t2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`b` = `test`.`t2`.`b`) +SELECT * FROM t1 NATURAL JOIN t2; +b a +DROP TABLE t1,t2; diff --git a/mysql-test/suite/vcol/r/vcol_view_innodb.result b/mysql-test/suite/vcol/r/vcol_view_innodb.result index fe666e0e400..c9a4897e230 100644 --- a/mysql-test/suite/vcol/r/vcol_view_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_view_innodb.result @@ -107,7 +107,7 @@ MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1. MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort drop view v1; create view v1 as select c+1 from t1 order by 1 desc limit 2; @@ -119,7 +119,7 @@ MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1. MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort drop view v1; drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_view_myisam.result b/mysql-test/suite/vcol/r/vcol_view_myisam.result index 78c20f79f5e..e3fb2ec61ca 100644 --- a/mysql-test/suite/vcol/r/vcol_view_myisam.result +++ b/mysql-test/suite/vcol/r/vcol_view_myisam.result @@ -107,7 +107,7 @@ MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1. MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort drop view v1; create view v1 as select c+1 from t1 order by 1 desc limit 2; @@ -119,7 +119,7 @@ MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1. MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort drop view v1; drop table t1; diff --git a/mysql-test/suite/vcol/t/vcol_select_myisam.test b/mysql-test/suite/vcol/t/vcol_select_myisam.test index 855e02ac113..c14faba576d 100644 --- a/mysql-test/suite/vcol/t/vcol_select_myisam.test +++ b/mysql-test/suite/vcol/t/vcol_select_myisam.test @@ -48,3 +48,23 @@ eval SET @@session.storage_engine = 'MyISAM'; #------------------------------------------------------------------------------# # Cleanup --source suite/vcol/inc/vcol_cleanup.inc + +--echo # +--echo # Bug #806057: join with USING over a virtual column +--echo # + +CREATE TABLE t1 (b int); +INSERT INTO t1 VALUES (NULL),( 78), (185), (0), (154); + +CREATE TABLE t2 (a int, b int AS (a) VIRTUAL); +INSERT INTO t2 VALUES (187,187), (9,9), (187,187); + +EXPLAIN EXTENDED +SELECT * FROM t1 JOIN t2 USING (b); +SELECT * FROM t1 JOIN t2 USING (b); + +EXPLAIN EXTENDED +SELECT * FROM t1 NATURAL JOIN t2; +SELECT * FROM t1 NATURAL JOIN t2; + +DROP TABLE t1,t2; diff --git a/mysql-test/t/derived_opt.test b/mysql-test/t/derived_opt.test index 42f3ce296e1..c2f831036e1 100644 --- a/mysql-test/t/derived_opt.test +++ b/mysql-test/t/derived_opt.test @@ -202,5 +202,15 @@ RIGHT JOIN ( drop table t1,t2,t3,t4; +--echo # +--echo # LP BUG#910123 MariaDB 5.3.3 causes 1093 error on Drupal +--echo # Fix: force materialization in case of conflict +--echo # +SET optimizer_switch='derived_merge=on'; +CREATE TABLE t1 ( i INT ); +INSERT INTO t1 VALUES ( (SELECT 1 FROM ( SELECT * FROM t1 ) as a) ); +drop table t1; +set optimizer_switch=@save_optimizer_switch; + # The following command must be the last one the file set optimizer_switch=@exit_optimizer_switch; diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test index b674350af0a..95412426aa0 100644 --- a/mysql-test/t/derived_view.test +++ b/mysql-test/t/derived_view.test @@ -1192,7 +1192,7 @@ INSERT INTO t2 VALUES (7), (4); CREATE TABLE t1 (b int NOT NULL); INSERT INTO t1 VALUES (5), (7); CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1; - +SET @save_optimizer_switch=@@optimizer_switch; SET SESSION optimizer_switch='derived_merge=off'; PREPARE st1 FROM @@ -1201,10 +1201,12 @@ EXECUTE st1; EXECUTE st1; DEALLOCATE PREPARE st1; +set SESSION optimizer_switch= @save_optimizer_switch; + DROP VIEW v1; DROP TABLE t1,t2; -SET SESSION optimizer_switch='derived_merge=on'; + --echo # --echo # LP bug #879939: assertion in ha_maria::enable_indexes @@ -1226,7 +1228,7 @@ INSERT INTO t1 VALUES CREATE TABLE t3 (a varchar(35)); INSERT INTO t3 VALUES ('Miami'); - +SET @save_optimizer_switch=@@optimizer_switch; SET optimizer_switch = 'derived_with_keys=on'; SET @@tmp_table_size=1024*4; explain SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b; @@ -1234,7 +1236,7 @@ SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b; SET @@tmp_table_size=1024*1024*16; SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b; SET @@tmp_table_size=default; - +set SESSION optimizer_switch= @save_optimizer_switch; drop table t1,t2,t3; --echo # @@ -1277,6 +1279,40 @@ ORDER BY CONCAT(alias2.col_varchar_nokey); set max_heap_table_size= @tmp_882994; drop table t1,t2,t3; +--echo # +--echo # LP bug #917990: Bad estimate of #rows for derived table with LIMIT +--echo # + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES + (8), (3), (4), (7), (9), (5), (1), (2); + +SELECT * FROM (SELECT * FROM t1 LIMIT 3) t; +EXPLAIN +SELECT * FROM (SELECT * FROM t1 LIMIT 3) t; + +DROP TABLE t1; + +--echo # +--echo # LP BUG#921878 incorrect check of items during columns union types +--echo # aggregation for merged derived tables +--echo # +SET @save_optimizer_switch=@@optimizer_switch; +SET SESSION optimizer_switch='derived_merge=on'; +CREATE TABLE t1 ( a ENUM( 'x', 'y' ) ); +insert into t1 values ('x'); +CREATE TABLE t2 LIKE t1; +insert into t1 values ('y'); +CREATE TABLE t3 LIKE t1; +INSERT INTO t3 + SELECT * FROM ( SELECT * FROM t1 ) AS A + UNION SELECT * FROM t2; +select * from t3; + +drop table t1,t2,t3; + +set SESSION optimizer_switch= @save_optimizer_switch; + # The following command must be the last one the file set optimizer_switch=@exit_optimizer_switch; set join_cache_level=@exit_join_cache_level; diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index 54535470d4c..7a098c44e5b 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -1154,6 +1154,53 @@ drop table t1; --echo End of 5.1 tests --echo # +--echo # Bug #904345: MIN/MAX optimization with constant FALSE condition +--echo # + +CREATE TABLE t1 (a int NOT NULL, KEY(a)); +INSERT INTO t1 VALUES (10), (8), (11), (7), (15), (12), (9); + +CREATE TABLE t2 (a int, b int); +INSERT INTO t2 VALUES + (8,2), (6,9), (8,4), (5,3), (9,1); + +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; + +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10; +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10; + +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE RAND()*0<>0 AND a<10; +SELECT MAX(a) FROM t1 WHERE RAND()*0<>0 AND a<10; + +DROP TABLE t1,t2; + +--echo # +--echo # Bug #879860: MIN/MAX for subquery returning empty set +--echo # + +CREATE TABLE t1 (a int PRIMARY KEY); +INSERT INTO t1 VALUES (1); + +CREATE TABLE t2 (a int NOT NULL); +INSERT INTO t2 VALUES (10); + +CREATE TABLE t3 ( a int, b int); +INSERT INTO t3 VALUES (19,1), (20,5); + +EXPLAIN EXTENDED +SELECT (SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) FROM t3; +SELECT (SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) FROM t3; + +DROP TABLE t1,t2,t3; + +--echo # +--echo End of 5.2 tests + +--echo # --echo # BUG#46680 - Assertion failed in file item_subselect.cc, --echo # line 305 crashing on HAVING subquery --echo # diff --git a/mysql-test/t/innodb_icp.test b/mysql-test/t/innodb_icp.test index 0fb42355f96..d6caa36a88e 100644 --- a/mysql-test/t/innodb_icp.test +++ b/mysql-test/t/innodb_icp.test @@ -12,6 +12,39 @@ set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; --source include/icp_tests.inc +--echo # +--echo # BUG#920132: Assert trx->n_active_thrs == 1 failed at que0que.c line 1050 +--echo # +CREATE TABLE t1 ( a INT ) + ENGINE=InnoDB; +INSERT INTO t1 VALUES (7),(7); + +CREATE TABLE t2 ( b VARCHAR(1) ); +INSERT INTO t2 VALUES ('j'),('v'); + +CREATE TABLE t3 ( + c INT, d VARCHAR(1), e VARCHAR(1), + KEY (d,c) +) ENGINE=InnoDB; +INSERT INTO t3 + VALUES (6,'w','w'), + (1,'v','v'),(7,'s','s'),(4,'l','l'), + (7,'y','y'),(0,'c','c'),(2,'i','i'), + (9,'h','h'),(4,'q','q'),(0,'a','a'), + (9,'v','v'),(1,'u','u'),(3,'s','s'), + (8,'z','z'),(1,'h','h'),(8,'p','p'), + (6,'e','e'),(3,'i','i'),(6,'y','y'); + +SELECT * +FROM t1 INNER JOIN t2 INNER JOIN t3 + ON d = b +WHERE + NOT EXISTS ( SELECT * FROM t3 ) + OR a = c +ORDER BY e; + +DROP TABLE t1,t2,t3; + set optimizer_switch=@innodb_icp_tmp; set storage_engine= @save_storage_engine; diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 4600da9ee17..c6017337c0a 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -1526,12 +1526,14 @@ insert into t2 values (3,1, 'qwerty'),(3,4, 'qwerty'); insert into t2 values (4,1, 'qwerty'),(4,2, 'qwerty'),(4,3, 'qwerty'), (4,4, 'qwerty'); +flush status; set join_cache_level=5; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; explain select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; +show status like "Handler_pushed%"; set join_cache_level=6; select t2.f1, t2.f2, t2.f3 from t1,t2 @@ -1539,6 +1541,7 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; explain select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; +show status like "Handler_pushed%"; set join_cache_level=7; select t2.f1, t2.f2, t2.f3 from t1,t2 @@ -1546,6 +1549,7 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; explain select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; +show status like "Handler_pushed%"; set join_cache_level=8; select t2.f1, t2.f2, t2.f3 from t1,t2 @@ -1553,6 +1557,7 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; explain select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; +show status like "Handler_pushed%"; drop table t1,t2; set join_cache_level=default; @@ -3423,5 +3428,164 @@ SET optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3,t4; +--echo # +--echo # Bug#53305 Duplicate weedout + join buffer (join cache --level=7,8) +--echo # + +create table t1 (uid int, fid int, index(uid)); +insert into t1 values + (1,1), (1,2), (1,3), (1,4), + (2,5), (2,6), (2,7), (2,8), + (3,1), (3,2), (3,9); + +create table t2 (uid int primary key, name varchar(128), index(name)); +insert into t2 values + (1, "A"), (2, "B"), (3, "C"), (4, "D"), (5, "E"), + (6, "F"), (7, "G"), (8, "H"), (9, "I"); + +create table t3 (uid int, fid int, index(uid)); +insert into t3 values + (1,1), (1,2), (1,3),(1,4), + (2,5), (2,6), (2,7), (2,8), + (3,1), (3,2), (3,9); + +set @tmp_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch='semijoin=on'; +set optimizer_switch='materialization=off'; +set optimizer_switch='loosescan=off,firstmatch=off'; +set optimizer_switch='mrr_sort_keys=off'; +set join_cache_level=7; + +create table t4 (uid int primary key, name varchar(128), index(name)); +insert into t4 values + (1, "A"), (2, "B"), (3, "C"), (4, "D"), (5, "E"), + (6, "F"), (7, "G"), (8, "H"), (9, "I"); + +explain select name from t2, t1 + where t1.uid in (select t4.uid from t4, t3 where t3.uid=1 and t4.uid=t3.fid) + and t2.uid=t1.fid; + +--sorted_result +select name from t2, t1 + where t1.uid in (select t4.uid from t4, t3 where t3.uid=1 and t4.uid=t3.fid) + and t2.uid=t1.fid; + +set join_cache_level = default; +set optimizer_switch=@tmp_optimizer_switch; + +drop table t1,t2,t3,t4; + +--echo # +--echo # Bug#50358 - semijoin execution of subquery with outerjoin +--echo # emplying join buffer +--echo # + +CREATE TABLE t1 (i int); +CREATE TABLE t2 (i int); +CREATE TABLE t3 (i int); +INSERT INTO t1 VALUES (1), (2); +INSERT INTO t2 VALUES (6); +INSERT INTO t3 VALUES (1), (2); + +set @tmp_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch='semijoin=on'; +set optimizer_switch='materialization=on'; + +set join_cache_level=0; +EXPLAIN +SELECT * FROM t1 WHERE t1.i IN + (SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i); +SELECT * FROM t1 WHERE t1.i IN + (SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i); + +set join_cache_level=2; +EXPLAIN +SELECT * FROM t1 WHERE t1.i IN + (SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i); +SELECT * FROM t1 WHERE t1.i IN + (SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i); + +set join_cache_level = default; +set optimizer_switch=@tmp_optimizer_switch; + +DROP TABLE t1,t2,t3; + +--echo # +--echo # Bug #12546542: missing row with semijoin=off + join cache +--echo # (LP bug #922971) +--echo # + +CREATE TABLE t1 (a varchar(1024)); +INSERT INTO t1 VALUES ('v'), ('we'); +CREATE TABLE t2 ( + a varchar(1024) CHARACTER SET utf8 DEFAULT NULL, b int, c int +); +INSERT INTO t2 VALUES ('we',4,NULL), ('v',1305673728,6); +CREATE TABLE t3 (b int, c int); +INSERT INTO t3 VALUES (4,4); + +set @tmp_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=off'; +set optimizer_switch='materialization=off'; + +set join_cache_level=0; +EXPLAIN +SELECT * FROM t1 + WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b + WHERE t2.c < 10 OR t3.c > 1); + +SELECT * FROM t1 + WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b + WHERE t2.c < 10 OR t3.c > 1); + +set join_cache_level=2; +EXPLAIN +SELECT * FROM t1 + WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b + WHERE t2.c < 10 OR t3.c > 1); +SELECT * FROM t1 + WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b + WHERE t2.c < 10 OR t3.c > 1); + +set join_cache_level = default; +set optimizer_switch=@tmp_optimizer_switch; + +DROP TABLE t1,t2,t3; + +--echo # +--echo # Bug #925985: LEFT JOIN with optimize_join_buffer_size=off + +--echo # join_buffer_size > join_buffer_space_limit +--echo # + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (5), (3); + +CREATE TABLE t2 (a int, b int); +INSERT INTO t2 VALUES + (3,30), (1,10), (7,70), (2,20), + (3,31), (1,11), (7,71), (2,21), + (3,32), (1,12), (7,72), (2,22); + +CREATE TABLE t3 (b int, c int); +INSERT INTO t3 VALUES (32, 302), (42,400), (30,300); + +set @tmp_optimizer_switch=@@optimizer_switch; +set optimizer_switch='optimize_join_buffer_size=off'; +set join_buffer_space_limit=4096; +set join_buffer_size=4096*2; +set join_cache_level=2; +set optimizer_switch='outer_join_with_cache=on'; + +EXPLAIN +SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a; +SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a; + +set join_buffer_space_limit=default; +set join_buffer_size=default; +set join_cache_level=default; +set optimizer_switch=@tmp_optimizer_switch; + +DROP TABLE t1,t2,t3; + # this must be the last command in the file set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/join_outer_innodb.test b/mysql-test/t/join_outer_innodb.test index 0d47c4ea57b..c5cf66c816b 100644 --- a/mysql-test/t/join_outer_innodb.test +++ b/mysql-test/t/join_outer_innodb.test @@ -61,3 +61,18 @@ ORDER BY pk; DROP TABLE t1,t2; --echo # End BUG#58456 + +# +# Bug #848652: crash with RIGHT JOIN and GROUP BY +# + +CREATE TABLE t1(a int, b int, KEY (a), PRIMARY KEY (b)) ENGINE=InnoDB; + +CREATE TABLE t2 (b int, PRIMARY KEY (b)); +INSERT INTO t2 VALUES (4),(9); + +SELECT STRAIGHT_JOIN t1.a FROM t1 RIGHT JOIN t2 ON t1.b = t2.b + WHERE (t1.b NOT BETWEEN 1 AND 7 OR t1.a IS NULL AND t1.b = t2.b) AND t2.b = 4 +GROUP BY 1; + +DROP TABLE t1,t2; diff --git a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test index 13367cbdcaa..9098ca466b7 100644 --- a/mysql-test/t/key_cache.test +++ b/mysql-test/t/key_cache.test @@ -254,6 +254,22 @@ DROP TABLE t1; # End of 4.1 tests +--echo # +--echo # Bug#12361113: crash when load index into cache +--echo # + +--echo # Note that this creates an empty disabled key cache! +SET GLOBAL key_cache_none.key_cache_block_size = 1024; +CREATE TABLE t1 (a INT, b INTEGER NOT NULL, KEY (b) ) ENGINE = MYISAM; +INSERT INTO t1 VALUES (1, 1); +--error ER_UNKNOWN_KEY_CACHE +CACHE INDEX t1 in key_cache_none; +--echo # The bug crashed the server at LOAD INDEX below. Now it will succeed +--echo # since the default cache is used due to CACHE INDEX failed for +--echo # key_cache_none. +LOAD INDEX INTO CACHE t1; +DROP TABLE t1; + # End of 5.1 tests # diff --git a/mysql-test/t/myisam_icp.test b/mysql-test/t/myisam_icp.test index 0e306a850c5..39a22d00a1a 100644 --- a/mysql-test/t/myisam_icp.test +++ b/mysql-test/t/myisam_icp.test @@ -262,4 +262,133 @@ SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2,t3,t4; +--echo # +--echo # BUG#933412: Server crashes in _mi_put_key_in_record on KILL QUERY with ICP, STRAIGHT_JOIN +--echo # +CREATE TABLE t1 ( + b INT, + c VARCHAR(1) NOT NULL, + d DATETIME, + KEY (c, b) +) ENGINE=MyISAM; +--echo # INSERT some data +--disable_query_log +INSERT INTO t1 ( b, d, c ) VALUES +(4,'2005-01-08 00:00:00','f'), +(1,'2004-05-20 10:45:51','c'),(2,'2006-08-11 21:33:49','e'), +(5,'2003-05-19 00:20:40','a'),(3,'2005-01-03 06:18:39','a'), +(7,'2008-11-25 18:18:14','b'),(6,'2008-11-09 15:53:46','b'), +(9,'2003-03-01 03:40:36','c'),(8,'2003-09-25 23:14:09','d'), +(0,'2007-01-17 09:18:31','f'),(9,'2008-09-08 09:52:24','c'), +(2,'2008-03-10 00:00:00','a'),(0,'2003-03-14 09:31:07','c'), +(4,'2005-04-25 00:00:00','h'),(6,'2001-08-01 05:55:55','e'), +(3,'2005-04-09 01:22:48','f'),(7,'2009-11-12 13:27:22','r'), +(0,'2009-03-28 05:05:28','h'),(15,'2005-05-16 04:35:41','f'), +(7,'2006-03-26 05:19:58','c'),(9,'2002-10-06 02:17:00','g'), +(4,'2007-01-28 03:28:20','b'),(1,'2009-04-22 10:16:40','c'), +(2,'2003-01-01 19:39:00','f'),(0,'2008-05-03 19:16:29','t'), +(2,'2005-01-28 00:00:00','j'),(8,'2004-01-10 00:00:00','w'), +(8,'2000-06-13 21:56:37','a'),(5,'2001-03-21 19:24:49','o'), +(99,'2003-12-20 21:29:06','f'),(0,'1900-01-01 00:00:00','w'), +(7,'2000-12-19 00:00:00','c'),(0,'2000-03-03 06:10:19','l'), +(3,'2000-08-11 00:00:00','q'),(0,'2007-05-25 03:46:41','e'), +(241,'2005-05-17 00:00:00','j'),(4,'2005-11-02 00:44:06','r'), +(43,'2001-07-11 00:00:00','a'),(1,'2008-12-01 18:30:27','z'), +(4,'2004-10-25 00:00:00','i'),(5,'2000-04-08 12:12:01','c'), +(0,'1900-01-01 00:00:00','f'),(9,'2002-05-13 22:47:02','p'), +(1,'2008-10-09 15:39:40','d'),(3,'2004-06-24 00:00:00','d'), +(0,'2008-03-06 00:00:00','r'),(9,'2007-04-16 18:40:03','i'), +(3,'2008-03-16 19:49:37','t'),(7,'2003-07-15 08:11:21','d'), +(8,'2005-02-11 00:04:53','r'),(0,'2002-09-21 00:00:00','y'), +(3,'2004-11-03 00:37:21','z'),(6,'2007-10-18 00:00:00','e'), +(6,'2007-01-21 10:42:56','o'),(5,'2000-03-26 21:21:04','b'), +(9,'2001-03-15 08:08:21','e'),(1,'2001-10-16 12:56:59','a'), +(6,'2004-05-01 23:45:55','o'),(4,'2000-03-04 00:00:00','f'), +(9,'2002-12-03 16:48:28','e'),(8,'2003-01-09 00:36:07','m'), +(1,'2006-06-22 04:32:41','s'),(8,'2008-09-20 05:01:48','q'), +(4,'2006-06-02 22:15:31','g'),(2,'2002-05-14 07:07:42','e'), +(7,'2005-06-05 01:30:42','r'),(127,'2004-05-11 01:56:48','a'), +(210,'2003-11-05 00:41:34','z'),(5,'1900-01-01 00:00:00','h'), +(1,'2006-04-16 00:00:00','f'),(7,'2000-12-17 00:00:00','x'), +(8,'2009-05-09 20:43:07','b'),(175,'2008-11-26 16:33:09','p'), +(0,'2002-05-09 21:18:44','v'),(8,'2002-06-01 11:32:25','k'), +(1,'2008-11-09 23:56:00','a'),(0,'2008-01-08 10:18:46','c'), +(2,'2005-04-16 00:00:00','o'),(5,'2002-08-25 00:00:00','b'), +(64,'2005-12-05 21:51:52','b'),(4,'2005-08-10 00:00:00','i'), +(6,'2006-03-23 00:00:00','d'),(9,'2007-01-27 00:00:00','i'), +(8,'2008-08-16 00:00:00','a'),(7,'2003-01-16 12:13:18','k'), +(0,'2003-06-22 00:00:00','v'),(5,'2008-06-20 05:43:56','u'), +(8,'2004-09-23 18:57:17','e'),(1,'2000-12-26 00:00:00','y'), +(4,'2009-06-01 13:00:28','e'),(1,'2009-11-18 06:28:48','m'), +(0,'2004-06-12 10:01:10','e'),(2,'2005-10-16 01:48:55','e'), +(5,'2001-12-23 09:50:21','l'),(6,'1900-01-01 00:00:00','a'), +(1,'2001-10-28 00:00:00','d'),(1,'2008-07-12 23:30:19','s'), +(0,'2002-10-11 16:51:16','r'),(4,'2007-09-18 06:27:10','x'), +(1,'2007-02-21 12:28:14','e'),(6,'2001-09-16 00:00:00','f'), +(0,'2007-09-20 02:25:45','c'),(0,'2006-08-07 03:25:56','j'), +(8,'2006-12-04 20:20:32','t'),(7,'2007-09-05 10:13:10','i'), +(9,'2006-04-12 17:59:57','t'),(2,'2009-04-28 00:06:09','b'), +(8,'2000-01-07 00:00:00','b'),(7,'2000-03-25 10:04:41','k'), +(4,'2000-07-10 00:44:55','w'),(9,'2007-09-22 14:26:26','j'), +(9,'2003-09-11 22:41:17','a'),(0,'2004-06-07 13:52:32','c'), +(8,'2008-10-09 00:00:00','p'),(1,'2007-04-01 00:00:00','c'), +(9,'2000-12-05 00:00:00','i'),(3,'1900-01-01 00:00:00','a'), +(3,'2005-12-24 21:50:54','e'),(8,'2009-07-21 19:34:55','n'), +(9,'2005-11-13 17:57:56','d'),(7,'2004-10-07 06:41:39','l'), +(1,'2004-11-20 08:05:08','u'),(3,'2005-05-25 00:00:00','r'), +(1,'2006-09-02 14:16:41','u'),(8,'2006-01-07 00:00:00','a'), +(9,'2003-04-05 00:54:20','w'),(2,'2003-12-22 00:00:00','a'), +(9,'2006-04-16 17:31:40','e'),(6,'2005-02-10 14:22:46','e'), +(7,'2004-04-27 05:54:52','p'),(1,'2005-12-07 00:00:00','t'), +(5,'2004-04-03 20:56:28','d'),(4,'2000-09-07 05:17:16','h'), +(2,'2004-08-04 16:10:42','i'),(1,'2007-03-04 00:00:00','b'), +(9,'1900-01-01 00:00:00','d'),(1,'2000-05-12 23:02:50','m'), +(2,'1900-01-01 00:00:00','l'),(1,'1900-01-01 00:00:00','k'), +(4,'2000-07-14 01:25:18','d'),(5,'2009-08-21 00:00:00','w'), +(6,'2009-05-25 13:33:54','f'),(7,'2006-06-13 00:00:00','e'), +(8,'1900-01-01 00:00:00','a'),(6,'2004-02-24 00:00:00','j'), +(0,'2003-05-21 07:03:46','k'),(9,'1900-01-01 00:00:00','e'), +(2,'1900-01-01 00:00:00','y'),(2,'2000-12-22 00:00:00','e'), +(3,'2003-09-26 00:00:00','f'),(2,'2001-01-13 08:20:19','h'), +(9,'2008-09-23 20:03:28','n'),(5,'2007-03-20 02:41:38','s'), +(1,'2009-02-14 10:27:18','a'),(0,'2001-08-10 17:44:05','s'), +(3,'2008-01-20 12:49:54','v'),(1,'2001-05-05 09:09:59','r'); +--enable_query_log +CREATE TABLE t2 ( a INT ) ENGINE=MyISAM; +INSERT INTO t2 VALUES + (7),(3),(7),(3); + +# 'con2' will be the connection that will run all the KILLable statements +--connect (con2,127.0.0.1,root,,test) + +--let $run = 300 +--let $con_id = `SELECT CONNECTION_ID()` + +--echo # Now run a number of ICP queries while trying to kill them +--disable_query_log +--disable_result_log +while ($run) +{ + --send + SELECT * FROM t1 AS alias1 STRAIGHT_JOIN t1 AS alias2 + ON alias2.c = alias1.c + WHERE alias2.b >= 9; + + --connect (con1,127.0.0.1,root,,test) + --eval KILL QUERY $con_id + --disconnect con1 + + --dec $run + + --connection con2 + --error 0,ER_QUERY_INTERRUPTED + --reap +} +--enable_result_log +--enable_query_log +--disconnect con2 +--connection default +DROP TABLE t1,t2; + set optimizer_switch=@myisam_icp_tmp; + diff --git a/mysql-test/t/myisam_mrr.test b/mysql-test/t/myisam_mrr.test index 1e070ec9a34..28385c61b0f 100644 --- a/mysql-test/t/myisam_mrr.test +++ b/mysql-test/t/myisam_mrr.test @@ -268,5 +268,58 @@ set @@join_cache_level= @tmp_730133_jcl; set @@optimizer_switch= @tmp_730133_os; drop table t1; +--echo # +--echo # Test of MRR handler counters +--echo # +flush status; +show status like 'Handler_mrr%'; +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (a int, b int, filler char(200), key(a)); +insert into t1 +select A.a+10*B.a+100*C.a+1000*D.a, 123,'filler' from t0 A, t0 B, t0 C, t0 D; + +explain select sum(b) from t1 where a < 10; +--echo # This should show one MRR scan and no re-fills: +flush status; +select sum(b) from t1 where a < 10; +show status like 'handler_mrr%'; + +set @mrr_buffer_size_save= @@mrr_buffer_size; +--disable_warnings +set mrr_buffer_size=128; +--enable_warnings + +explain select sum(b) from t1 where a < 1600; +--echo # This should show one MRR scan and one extra rowid sort: +flush status; +select sum(b) from t1 where a < 1600; +show status like 'handler_mrr%'; +set @@mrr_buffer_size= @mrr_buffer_size_save; + +--echo #Now, let's check BKA: +set @join_cache_level_save= @@join_cache_level; +set @join_buffer_size_save= @@join_buffer_size; +set join_cache_level=6; + +explain select sum(t1.b) from t0,t1 where t0.a=t1.a; +flush status; +select sum(t1.b) from t0,t1 where t0.a=t1.a; +show status like 'handler_mrr%'; + +--disable_warnings +set join_buffer_size=10; +--enable_warnings +explain select sum(t1.b) from t0,t1 where t0.a=t1.a; +flush status; +select sum(t1.b) from t0,t1 where t0.a=t1.a; +--replace_result 1 1or2 2 1or2 +show status like 'handler_mrr%'; + +set join_cache_level= @join_cache_level_save; +set join_buffer_size= @join_buffer_size_save; + +drop table t0, t1; + ## This must be last line in the file: set optimizer_switch= @myisam_mrr_tmp; diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index ef88b89e8d8..c0025f9e742 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -147,6 +147,7 @@ SET NAMES DEFAULT; call mtr.add_suppression("@003f.frm' \\(errno: 22\\)"); --echo mysqlcheck --default-character-set="latin1" --databases test # Error returned depends on platform, replace it with "Table doesn't exist" +call mtr.add_suppression("Can't find file: '..test.@003f.frm'"); --replace_result "Can't find file: './test/@003f.frm' (errno: 22)" "Table doesn't exist" "Table 'test.?' doesn't exist" "Table doesn't exist" --exec $MYSQL_CHECK --default-character-set="latin1" --databases test --echo mysqlcheck --default-character-set="utf8" --databases test diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 302d79b6b13..424dd35a819 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -2249,8 +2249,12 @@ INSERT INTO b12809202_db.t2 VALUES (1), (2), (3); --echo # commit starting 5.5. --echo --echo #### Dump starts here #### +# We only need to check the --verbose output to verify that "start transaction" +# happens after "logs flushed". We redirect normal output, as otherwise the +# mixing of normal (stdout) and --verbose (stderr) output will happen in random +# order depending on stdio internal buffer size. --replace_regex /-- Server version.*// /-- MySQL dump .*// /-- Dump completed on .*/-- Dump completed/ ---exec $MYSQL_DUMP --verbose --single-transaction --flush-log b12809202_db 2>&1 +--exec $MYSQL_DUMP --verbose --single-transaction --flush-log b12809202_db 2>&1 > $MYSQLTEST_VARDIR/tmp/bug61854.sql --echo --echo #### Dump ends here #### diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 82116558717..a6f50107cbe 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -1562,7 +1562,6 @@ select 1 order by max(1) + min(1); --echo End of 5.1 tests - --echo # --echo # Bug #38745: MySQL 5.1 optimizer uses filesort for ORDER BY --echo # when it should use index @@ -1585,3 +1584,32 @@ SELECT t1.*, t2.* FROM t1 JOIN t2 ON t1.i1 = t2.i2 ORDER BY t1.i1 LIMIT 5; DROP TABLE t1, t2, t3; + +--echo # +--echo # Fix of LP BUG#793589 Wrong result with double ORDER BY +--echo # +CREATE TABLE t1 ( b int) ; +INSERT INTO t1 VALUES (8),(9); + +CREATE TABLE t2 ( a int, b int, PRIMARY KEY (a)) ; +INSERT INTO t2 VALUES (6,7),(7,7),(8,1),(9,7),(10,1),(11,5),(12,2),(13,0),(14,1),(15,8),(16,1),(17,1),(18,9),(19,1),(20,5); + +SELECT t2.b AS field1 FROM t1, t2 WHERE t1.b = t2.a GROUP BY field1 ORDER BY t1.b, field1; +SELECT t2.b, t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b, t2.b; +SELECT t2.b,t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +SELECT t2.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; + +--echo # field1 removed from ORDER BY +explain extended +SELECT t2.b AS field1 FROM t1, t2 WHERE t1.b = t2.a GROUP BY field1 ORDER BY t1.b, field1; +explain extended +SELECT t2.b, t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b, t2.b; +explain extended +SELECT t2.b,t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +explain extended +SELECT t2.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; + + +drop table t1,t2; + +--echo End of 5.2 tests diff --git a/mysql-test/t/partition_key_cache.test b/mysql-test/t/partition_key_cache.test index 4beb9506b05..067eb7fae59 100644 --- a/mysql-test/t/partition_key_cache.test +++ b/mysql-test/t/partition_key_cache.test @@ -239,6 +239,34 @@ CACHE INDEX t2 INDEX (`inx_b`) IN hot_cache; CACHE INDEX t1 PARTITION (p0) KEY (`inx_b`) IN hot_cache; CACHE INDEX t1 INDEX (`inx_b`) IN hot_cache; DROP TABLE t1,t2; + +--echo # +--echo # Bug#12361113: crash when load index into cache +--echo # +--echo # Note that this creates an empty disabled key cache! +SET GLOBAL key_cache_none.key_cache_block_size = 1024; +CREATE TABLE t1 (a INT, b INTEGER NOT NULL, KEY (b) ) +ENGINE = MYISAM +PARTITION BY HASH(a) PARTITIONS 2; +INSERT INTO t1 VALUES (1, 1); +--error ER_UNKNOWN_KEY_CACHE +CACHE INDEX t1 IN key_cache_none; +--error ER_UNKNOWN_KEY_CACHE +CACHE INDEX t1 PARTITION (p0) IN key_cache_none; +--error ER_UNKNOWN_KEY_CACHE +CACHE INDEX t1 PARTITION (p1) IN key_cache_none; +--error ER_UNKNOWN_KEY_CACHE +CACHE INDEX t1 PARTITION (p0) KEY (`b`) IN key_cache_none; +--error ER_UNKNOWN_KEY_CACHE +CACHE INDEX t1 PARTITION (p1) KEY (`b`) IN key_cache_none; +--echo # The bug crashed the server at LOAD INDEX below. Now it will succeed +--echo # since the default cache is used due to CACHE INDEX failed for +--echo # key_cache_none. +LOAD INDEX INTO CACHE t1; +DROP TABLE t1; + + +--echo # Clean up SET GLOBAL hot_cache.key_buffer_size = 0; SET GLOBAL warm_cache.key_buffer_size = 0; SET @@global.cold_cache.key_buffer_size = 0; diff --git a/mysql-test/t/partition_pruning.test b/mysql-test/t/partition_pruning.test index da41b8e9428..1c8a4d254a8 100644 --- a/mysql-test/t/partition_pruning.test +++ b/mysql-test/t/partition_pruning.test @@ -1106,12 +1106,14 @@ show status like 'Handler_read_key'; flush status; delete from t2 where b > 5; show status like 'Handler_read_rnd_next'; +show status like 'Handler_read_rnd_deleted'; show status like 'Handler_read_key'; show status like 'Handler_read_prev'; show status like 'Handler_read_next'; flush status; delete from t2 where b < 5 or b > 3; show status like 'Handler_read_rnd_next'; +show status like 'Handler_read_rnd_deleted'; show status like 'Handler_read_key'; show status like 'Handler_read_prev'; show status like 'Handler_read_next'; diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 746d6bad896..e4e26da7031 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -1406,6 +1406,20 @@ DROP TABLE t1; --echo End of 5.1 tests +--echo # +--echo # LP Bug #533117: Wrong use_count in SEL_ARG trees +--echo # (Bug #58731) +--echo # + +create table t1 (a int, b int, c int, key idx (a,b,c)); +insert into t1 values (0,0,0), (2,2,0), (1,1,1), (2,2,1); + +explain +select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; +select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; + +drop table t1; + # # lp:750117 Bogus warning with aggregate and datetime column # @@ -1459,4 +1473,3 @@ SELECT * FROM t1 ignore index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' SELECT * FROM t1 force index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 )); DROP TABLE t1; - diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test index 76769e78d90..9395323d32b 100644 --- a/mysql-test/t/status.test +++ b/mysql-test/t/status.test @@ -369,6 +369,16 @@ show status like 'Handler%'; show status like '%tmp%'; drop table t1; +# +# Test of handler status counts +# +CREATE TABLE t1 (i int(11) DEFAULT NULL, KEY i (i) ) ENGINE=MyISAM; +insert into t1 values (1),(2),(3),(4),(5); +flush status; +select * from t1 where i=5 union select * from t1 where i=5; +show status like "handler%"; +drop table t1; + # End of 5.3 tests # Restore global concurrent_insert value. Keep in the end of the test file. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index cb43eb9f646..40ecfead133 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3519,6 +3519,8 @@ SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; ## First a simpler query, illustrating the transformation ## '1 < some (...)' => '1 < max(...)' +EXPLAIN EXTENDED +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); ## The query which made the server crash. @@ -4431,8 +4433,6 @@ WHERE t1.a = d1.a; DROP TABLE t1; ---echo End of 5.1 tests. - # # Bug #47904 Incorrect results w/ table subquery, derived SQs, and LEFT JOIN on index # @@ -4879,11 +4879,141 @@ INSERT INTO t3 VALUES (0),(0); SELECT a1.f3 AS r FROM t2 AS a1 , t1 WHERE a1.f3 < ALL ( SELECT f3 FROM t3 WHERE f3 = 1 ) ; DROP TABLE t1, t2, t3; +--echo # +--echo # Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER +--echo # + +CREATE TABLE t1(a1 int); +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2(a1 int); +INSERT INTO t2 VALUES (3); + +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; + +## All these are subject to the transformation +## '1 < some (...)' => '1 < max(...)' +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); + +SET SESSION sql_mode=@old_sql_mode; + +DROP TABLE t1, t2; + +create table t2(i int); +insert into t2 values(0); + +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; + +CREATE VIEW v1 AS +SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2 +; + +CREATE TABLE t1 ( + pk int NOT NULL, + col_varchar_key varchar(1) DEFAULT NULL, + PRIMARY KEY (pk), + KEY col_varchar_key (col_varchar_key) +); + +SELECT t1.pk +FROM t1 +WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 ) +; + +SET SESSION sql_mode=@old_sql_mode; + +drop table t2, t1; +drop view v1; + +--echo # +--echo # BUG#50257: Missing info in REF column of the EXPLAIN +--echo # lines for subselects +--echo # + +CREATE TABLE t1 (a INT, b INT, INDEX (a)); +INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20); + +EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t; +EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7); + +DROP TABLE t1; + +--echo # +--echo # BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS) +--echo # (duplicate of LP bug #888456) +--echo # + +CREATE TABLE t1 (f1 varchar(1)); +INSERT INTO t1 VALUES ('v'),('s'); + +CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key)); +INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'), +('d'),('y'),('t'),('d'),('s'); + +EXPLAIN +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 + WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 + WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 + WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 + WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); + +DROP TABLE t1,t2; + +--echo # +--echo # LP bug 919427: EXPLAIN for a query over a single-row table +--echo # with IN subquery in WHERE condition +--echo # + +CREATE TABLE ot ( + col_int_nokey int(11), + col_varchar_nokey varchar(1) +) ; +INSERT INTO ot VALUES (1,'x'); + +CREATE TABLE it1( + col_int_key int(11), + col_varchar_key varchar(1), + KEY idx_cvk_cik (col_varchar_key,col_int_key) +); +INSERT INTO it1 VALUES (NULL,'x'), (NULL,'f'); + +CREATE TABLE it2 ( + col_int_key int(11), + col_varchar_key varchar(1), + col_varchar_key2 varchar(1), + KEY idx_cvk_cvk2_cik (col_varchar_key, col_varchar_key2, col_int_key), + KEY idx_cvk_cik (col_varchar_key, col_int_key) +); +INSERT INTO it2 VALUES (NULL,'x','x'), (NULL,'f','f'); + +EXPLAIN +SELECT col_int_nokey FROM ot + WHERE col_varchar_nokey IN + (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +SELECT col_int_nokey FROM ot + WHERE col_varchar_nokey IN + (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); + +EXPLAIN +SELECT col_int_nokey FROM ot + WHERE (col_varchar_nokey, 'x') IN + (SELECT col_varchar_key, col_varchar_key2 FROM it2); +SELECT col_int_nokey FROM ot + WHERE (col_varchar_nokey, 'x') IN + (SELECT col_varchar_key, col_varchar_key2 FROM it2); + +DROP TABLE ot,it1,it2; + --echo End of 5.2 tests --echo # --echo # BUG#779885: Crash in eliminate_item_equal with materialization=on in ---echo # maria-5.3 --echo # CREATE TABLE t1 ( f1 int ); @@ -4936,32 +5066,6 @@ SET optimizer_switch=@save_optimizer_switch; drop table t1, t2, t3; ---echo End of 5.3 tests - ---echo # ---echo # Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER ---echo # - -CREATE TABLE t1(a1 int); -INSERT INTO t1 VALUES (1),(2); - -CREATE TABLE t2(a1 int); -INSERT INTO t2 VALUES (3); - -SELECT @@session.sql_mode INTO @old_sql_mode; -SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; - -## All these are subject to the transformation -## '1 < some (...)' => '1 < max(...)' -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); -SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); - -SET SESSION sql_mode=@old_sql_mode; - -DROP TABLE t1, t2; - --echo # --echo # BUG#50257: Missing info in REF column of the EXPLAIN --echo # lines for subselects @@ -4982,6 +5086,55 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7); DROP TABLE t1; --echo # +--echo # Bug#11764086: Null left operand to NOT IN in WHERE clause +--echo # behaves differently than real NULL +--echo # + +CREATE TABLE parent (id int); +INSERT INTO parent VALUES (1), (2); + +CREATE TABLE child (parent_id int, other int); +INSERT INTO child VALUES (1,NULL); + +--echo # Offending query (c.parent_id is NULL for null-complemented rows only) + +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( + SELECT parent_id + FROM child + WHERE parent_id = 3 + ); + +--echo # Some syntactic variations with IS FALSE and IS NOT TRUE + +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( + SELECT parent_id + FROM child + WHERE parent_id = 3 + ) IS NOT TRUE; + +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( + SELECT parent_id + FROM child + WHERE parent_id = 3 + ) IS FALSE; + +DROP TABLE parent, child; + +--echo # End of test for bug#11764086. + +--echo # --echo # Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET || --echo # BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX --echo # @@ -5279,6 +5432,17 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; drop table t1,t2,t3; +--echo # +--echo # LP BUG#905353 Wrong non-empty result with a constant table, +--echo # aggregate function in subquery, MyISAM or Aria +--echo # + +CREATE TABLE t1 ( a INT ) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1); + +SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 ); + +drop table t1; --echo # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test index f34cf5ba338..6b8a757b9e8 100644 --- a/mysql-test/t/subselect_sj.test +++ b/mysql-test/t/subselect_sj.test @@ -1136,6 +1136,262 @@ WHERE (int_nokey, pk) DROP TABLE t1, t2, t3; +--echo # +--echo # BUG#53060: LooseScan semijoin strategy does not return all rows +--echo # + +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=on,materialization=off'; +set optimizer_switch='firstmatch=off,loosescan=on'; + +CREATE TABLE t1 (i INTEGER); +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +CREATE TABLE t2 (i INTEGER, j INTEGER, KEY k(i, j)); +INSERT INTO t2 VALUES (1, 0), (1, 1), (2, 0), (2, 1); + +EXPLAIN +SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0); +SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0); + +DROP TABLE t1, t2; + +set optimizer_switch=@save_optimizer_switch; + +--echo # +--echo # BUG#49453: re-execution of prepared statement with view +--echo # and semijoin crashes +--echo # + +CREATE TABLE t1 (city VARCHAR(50), country_id INT); +CREATE TABLE t2 (country_id INT, country VARCHAR(50)); + +INSERT INTO t1 VALUES + ('Batna',2),('Bchar',2),('Skikda',2),('Tafuna',3),('Algeria',2) ; +INSERT INTO t2 VALUES (2,'Algeria'),(2,'AlgeriaDup'),(3,'XAmerican Samoa'); + +CREATE VIEW v1 AS + SELECT country_id as vf_country_id + FROM t2 + WHERE LEFT(country,1) = "A"; + +PREPARE stmt FROM " +SELECT city, country_id +FROM t1 +WHERE country_id IN (SELECT vf_country_id FROM v1); +"; + +--echo +EXECUTE stmt; +EXECUTE stmt; + +DROP TABLE t1,t2; +DROP VIEW v1; + +--echo # +--echo # Bug#54437 Extra rows with LEFT JOIN + semijoin +--echo # + +create table t1 (a int); +create table t2 (a int); +create table t3 (a int); +insert into t1 values(1),(1); +insert into t2 values(1),(1),(1),(1); +insert into t3 values(2),(2); + +set @save_optimizer_switch=@@optimizer_switch; + +set optimizer_switch='materialization=off'; + +set optimizer_switch='semijoin=off'; +explain +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); + +set optimizer_switch='semijoin=on'; +explain +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); + +set optimizer_switch=@save_optimizer_switch; + +drop table t1,t2,t3; + +--echo # +--echo # Bug#55955: crash in MEMORY engine with IN(LEFT JOIN (JOIN)) +--echo # + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); +CREATE TABLE t3 (a INT); +INSERT INTO t1 VALUES(1),(1); +INSERT INTO t2 VALUES(1),(1); +INSERT INTO t3 VALUES(2),(2); + +set @save_optimizer_switch=@@optimizer_switch; + +set optimizer_switch='semijoin=off,materialization=off'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a + FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a + FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); + +set optimizer_switch='semijoin=off,materialization=on'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a + FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a + FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); + +set optimizer_switch='semijoin=on,materialization=off'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a + FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a + FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); + +set optimizer_switch=@save_optimizer_switch; + +DROP TABLE t1,t2,t3; + +--echo # +--echo # BUG#52329 - Wrong result: subquery materialization, IN, +--echo # non-null field followed by nullable +--echo # + +CREATE TABLE t1 (a1 CHAR(8) NOT NULL, a2 char(8) NOT NULL); + +CREATE TABLE t2a (b1 char(8), b2 char(8)); +CREATE TABLE t2b (b1 CHAR(8), b2 char(8) NOT NULL); +CREATE TABLE t2c (b1 CHAR(8) NOT NULL, b2 char(8)); + +INSERT INTO t1 VALUES ('1 - 12', '2 - 22'); + +INSERT INTO t2a VALUES ('1 - 11', '2 - 21'), + ('1 - 11', '2 - 21'), + ('1 - 12', '2 - 22'), + ('1 - 12', '2 - 22'), + ('1 - 13', '2 - 23'); + +INSERT INTO t2b SELECT * FROM t2a; +INSERT INTO t2c SELECT * FROM t2a; + +set @save_optimizer_switch=@@optimizer_switch; + +set optimizer_switch='semijoin=off,materialization=on'; + +SELECT * FROM t1 +WHERE (a1, a2) IN ( + SELECT b1, b2 FROM t2c WHERE b1 > '0' GROUP BY b1, b2); + +SELECT * FROM t1 +WHERE (a1, a2) IN ( + SELECT b1, b2 FROM t2a WHERE b1 > '0'); + + +SELECT * FROM t1 +WHERE (a1, a2) IN ( + SELECT b1, b2 FROM t2b WHERE b1 > '0'); + + +SELECT * FROM t1 +WHERE (a1, a2) IN ( + SELECT b1, b2 FROM t2c WHERE b1 > '0'); + +set optimizer_switch=@save_optimizer_switch; + +DROP TABLE t1,t2a,t2b,t2c; + +--echo # +--echo # Bug#57623: subquery within before insert trigger causes crash (sj=on) +--echo # + +CREATE TABLE ot1(a INT); +CREATE TABLE ot2(a INT); +CREATE TABLE ot3(a INT); +CREATE TABLE it1(a INT); + +INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7); +INSERT INTO ot2 VALUES(0),(2),(4),(6); +INSERT INTO ot3 VALUES(0),(3),(6); +INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7); + +let $query= +SELECT * +FROM ot1 + LEFT JOIN + (ot2 JOIN ot3 on ot2.a=ot3.a) + ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); + +set @save_optimizer_switch=@@optimizer_switch; + +set optimizer_switch='semijoin=on'; + +set optimizer_switch='materialization=off'; +eval explain $query; +eval $query; +eval prepare s from '$query'; +execute s; +execute s; +deallocate prepare s; + +set optimizer_switch='materialization=on'; +eval explain $query; +eval $query; +eval prepare s from '$query'; +execute s; +execute s; +deallocate prepare s; + +set optimizer_switch=@save_optimizer_switch; + +DROP TABLE ot1, ot2, ot3, it1; + +--echo # +--echo # Bug#59919/11766739: Crash in tmp_table_param::init() with semijoin=on +--echo # + +CREATE TABLE t1 (f1 INTEGER) ENGINE=MyISAM; +CREATE TABLE t2 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM; +CREATE TABLE t3 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM; + +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1,1), (2,1); +INSERT INTO t3 VALUES + (1,1), (2,1), (5,4), (7,3), (8,2), (8,1), (7,3), + (9,5), (4,3), (7,2), (7,7), (3,1), (5,8), (9,7); + +set @save_optimizer_switch=@@optimizer_switch; + +set optimizer_switch='semijoin=off,materialization=on'; +EXPLAIN +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 + FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 + FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); + +set optimizer_switch='semijoin=on,materialization=on'; +EXPLAIN +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 + FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 + FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); + +set optimizer_switch=@save_optimizer_switch; + +DROP TABLE t1, t2, t3 ; + +--echo # --echo # --echo # BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 --echo # @@ -2017,5 +2273,63 @@ SELECT a, COUNT(*) FROM t1 DROP TABLE t1, t2, t3; +--echo # +--echo # BUG#920255: Wrong result (extra rows) with loosescan and IN subquery +--echo # +CREATE TABLE t1 ( a INT PRIMARY KEY, b INT, KEY(b) ); +INSERT INTO t1 VALUES + (1,2),(2,1),(3,3),(4,2),(5,5), + (6,3),(7,1),(8,4),(9,3),(10,2); + +CREATE TABLE t2 ( c INT, d INT, UNIQUE KEY(c) ); +INSERT INTO t2 VALUES + (1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1); + +SELECT a, b, d FROM t1, t2 +WHERE ( b, d ) IN + ( SELECT b, d FROM t1, t2 WHERE b = c ); + +DROP TABLE t1, t2; + +--echo # +--echo # BUG#920713: Wrong result (missing rows) with firstmatch+BNL, IN subquery, ... +--echo # +# t1 should be MyISAM or InnoDB +CREATE TABLE t1 ( a VARCHAR(1) ) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('e'),('w'),('a'),('h'),('x'),('k'),('g'); +CREATE TABLE t2 ( b INT, c VARCHAR(1) ); +INSERT INTO t2 VALUES (0,'j'),(8,'v'); + +#SET debug_optimizer_prefer_join_prefix= 'alias2,alias4,alias1,alias3'; + +SELECT * FROM t1 alias1, t2 alias2 +WHERE alias2.c IN ( + SELECT alias4.c FROM t1 alias3, t2 alias4 +); + +DROP TABLE t1, t2; + +--echo # +--echo # BUG#923246: Loosescan reports different result than other semijoin methods +--echo # +set @tmp_923246= @@optimizer_switch; +set optimizer_switch='mrr=on,materialization=off'; + +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t1 (kp1 int, kp2 int, c int, filler char(100), key(kp1, kp2)); +insert into t1 select A.a+10*(B.a+10*C.a), 0, 0, 'filler' from t0 A, t0 B, t0 C; +insert into t1 select * from t1 where kp1 < 20; + +create table t3 (a int); +insert into t3 select A.a + 10*B.a from t0 A, t0 B; + +select * from t3 where a in (select kp1 from t1 where kp1<20); +explain select * from t3 where a in (select kp1 from t1 where kp1<20); + +drop table t0,t1,t3; +set optimizer_switch= @tmp_923246; + # The following command must be the last one the file set optimizer_switch=@subselect_sj_tmp; diff --git a/mysql-test/t/subselect_sj2.test b/mysql-test/t/subselect_sj2.test index a77a70bbe4e..ede631f32be 100644 --- a/mysql-test/t/subselect_sj2.test +++ b/mysql-test/t/subselect_sj2.test @@ -1079,5 +1079,19 @@ SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a DROP VIEW v1; DROP TABLE t1,t2,t3,t4; +--echo # +--echo # BUG#912538: Wrong result (missing rows) with semijoin=on, firstmatch=on, ... +--echo # +CREATE TABLE t1 ( a INT NOT NULL, UNIQUE KEY(a) ); +INSERT INTO t1 VALUES (1),(2),(3),(4); + +# t2 needs to be InnoDB +CREATE TABLE t2 ( b INT, c INT ) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,1); + +SELECT * FROM t1, t2 WHERE c IN (SELECT c FROM t1, t2 WHERE a = b); + +DROP TABLE t1,t2; + --echo # This must be the last in the file: set optimizer_switch=@subselect_sj2_tmp; diff --git a/mysql-test/t/subselect_sj_jcl6.test b/mysql-test/t/subselect_sj_jcl6.test index 4eeaa465b11..e86ed017951 100644 --- a/mysql-test/t/subselect_sj_jcl6.test +++ b/mysql-test/t/subselect_sj_jcl6.test @@ -88,6 +88,124 @@ set join_cache_level=default; DROP TABLE t1,t2,t3; +--echo # +--echo # BUG#912513: Wrong result (missing rows) with join_cache_hashed+materialization+semijoin=on +--echo # +set @os_912513= @@optimizer_switch; +set @jcl_912513= @@join_cache_level; +SET optimizer_switch = 'semijoin=on,materialization=on,join_cache_hashed=on'; +SET join_cache_level = 3; + +CREATE TABLE t1 ( a INT, b INT, KEY(a) ); +INSERT INTO t1 VALUES + (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7); + +CREATE TABLE t2 ( c INT ); +INSERT INTO t2 VALUES (1),(2),(3),(4),(5),(6),(7); + +SELECT alias1.* FROM + t1 AS alias1 INNER JOIN t1 AS alias2 + ON alias2.a = alias1.b +WHERE alias1.b IN ( + SELECT a FROM t1, t2 + ); + +DROP table t1, t2; +set @@optimizer_switch= @os_912513; +set @@join_cache_level= @jcl_912513; + +--echo # End + +--echo # +--echo # BUG#934342: outer join + semijoin materialization +--echo # + join_cache_level > 2 +--echo # + +CREATE TABLE t1 (a varchar(1), b varchar(1), INDEX idx_a(a) ); +INSERT INTO t1 VALUES ('v','v'), ('w','w'), ('t','t'); + +CREATE TABLE t2 (c varchar(1), INDEX idx_c(c) ); +INSERT INTO t2 VALUES ('v'), ('v'), ('s'), ('j'); + +CREATE TABLE t3 (c varchar(1), d varchar(1), INDEX idx_c(c) ); +INSERT INTO t3 VALUES ('v','v'), ('v','v'), ('s','s'), ('j','j'); +INSERT INTO t3 VALUES ('m','m'), ('d','d'), ('k','k'), ('m','m'); + +set @tmp_otimizer_switch= @@optimizer_switch; +set @tmp_join_cache_level=@@join_cache_level; +set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on'; + +set join_cache_level=0; + +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); + +EXPLAIN +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); + +set join_cache_level=6; + +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); + +EXPLAIN +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); + +set optimizer_switch=@tmp_optimizer_switch; +set join_cache_level=@tmp_join_cache_level; + +DROP TABLE t1,t2,t3; + +--echo # End + +--echo # +--echo # BUG#934348: GROUP BY with HAVING + semijoin materialization +--echo # + join_cache_level > 2 +--echo # + +CREATE TABLE t1 (a varchar(1), INDEX idx_a(a)); +INSERT INTO t1 VALUES ('c'), ('v'), ('c'); + +CREATE TABLE t2 (b varchar(1)); +INSERT INTO t2 VALUES ('v'), ('c'); + +set @tmp_otimizer_switch= @@optimizer_switch; +set @tmp_join_cache_level=@@join_cache_level; +set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on'; + +set join_cache_level=0; + +EXPLAIN +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) + GROUP BY a HAVING a != 'z'; +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) + GROUP BY a HAVING a != 'z'; + +set join_cache_level=6; + +EXPLAIN +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) + GROUP BY a HAVING a != 'z'; +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) + GROUP BY a HAVING a != 'z'; + +set optimizer_switch=@tmp_optimizer_switch; +set join_cache_level=@tmp_join_cache_level; + +DROP TABLE t1,t2; + --echo # End set join_cache_level=default; diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index 2a5b0f56877..0d04b3f984a 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -1510,6 +1510,55 @@ SELECT * FROM t1 LEFT JOIN t2 ON ( a = b ) DROP TABLE t1,t2; +--echo # +--echo # BUG#922254: Assertion `0' failed at item_cmpfunc.cc:5899: Item* Item_equal::get_first(JOIN_TAB*, Item*) +--echo # +CREATE TABLE t1 ( a VARCHAR(3) ); +CREATE TABLE t2 ( b VARCHAR(3), c VARCHAR(8), KEY(c) ); +INSERT INTO t2 VALUES ('USA','Abilene'),('USA','Akron'); + +EXPLAIN +SELECT * FROM + ( SELECT * FROM t1 ) AS alias1, + t2 AS alias2 +WHERE b = a AND a IN ( + SELECT alias3.c + FROM t2 AS alias3, t2 AS alias4 + WHERE alias4.c = alias3.b +); + +DROP TABLE t1,t2; + +--echo # +--echo # BUG#928048: Query containing IN subquery with OR in the where clause returns a wrong result +--echo # +create table t1 (a int, b int); +insert into t1 values (7,5), (3,3), (5,4), (9,3); + +create table t2 (a int, b int, index i_a(a)); + +insert into t2 values + (4,2), (7,9), (7,4), (3,1), (5,3), (3,1), (9,4), (8,1); + +explain select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); +select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); + +drop table t1,t2; + +--echo # +--echo # BUG#933407: Valgrind warnings in mark_as_null_row with materialization+semijoin, STRAIGHT_JOIN, impossible WHERE +--echo # +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0),(8); + +SELECT STRAIGHT_JOIN MIN(a) FROM t1 +WHERE a IN ( + SELECT a FROM t1 + WHERE 'condition'='impossible' + ); + +DROP TABLE t1; + --echo # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/t/sum_distinct.test b/mysql-test/t/sum_distinct.test index c58155a8e25..633a72fddc8 100644 --- a/mysql-test/t/sum_distinct.test +++ b/mysql-test/t/sum_distinct.test @@ -93,3 +93,15 @@ SELECT SUM(DISTINCT id) FROM t1; SELECT SUM(DISTINCT id % 11) FROM t1; DROP TABLE t1; + +--echo # +--echo # Bug #777654: empty subselect in FROM clause returning +--echo # SUM(DISTINCT) over non-nullable field +--echo # + +CREATE TABLE t1 (a int NOT NULL) ; + +SELECT SUM(DISTINCT a) FROM t1; +SELECT * FROM (SELECT SUM(DISTINCT a) FROM t1) AS t; + +DROP TABLE t1; diff --git a/mysql-test/t/table_elim.test b/mysql-test/t/table_elim.test index dc32618eb8c..26b98c9023b 100644 --- a/mysql-test/t/table_elim.test +++ b/mysql-test/t/table_elim.test @@ -521,4 +521,22 @@ EXPLAIN SELECT alias1.* FROM t3 LEFT JOIN v1 as alias1 ON ( t3.a = alias1.b ); drop view v1; DROP TABLE t1,t2,t3; +--echo # +--echo # BUG#919878: Assertion `!eliminated_tables... +--echo # +CREATE TABLE t1 ( a INT ); +INSERT INTO t1 VALUES (1); + +CREATE TABLE t2 + ( b INT, UNIQUE INDEX(b) ); +INSERT INTO t2 VALUES (1),(2); + +EXPLAIN EXTENDED + SELECT * FROM t2 + WHERE b IN ( + SELECT SUM(a) FROM t1 LEFT JOIN t2 ON b=a + ); + +DROP TABLE t1,t2; + SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/variables-big.test b/mysql-test/t/variables-big.test index 60d83e92c0a..58098f4c879 100644 --- a/mysql-test/t/variables-big.test +++ b/mysql-test/t/variables-big.test @@ -74,5 +74,3 @@ SET SESSION transaction_prealloc_size=1024*1024*1024*5; SHOW PROCESSLIST; --enable_warnings -SET @@session.transaction_prealloc_size= @def_var; - diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 5fd8da745e4..79c733ed791 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -4018,6 +4018,59 @@ drop table t1,t2; --echo # ----------------------------------------------------------------- --echo # -- End of 5.1 tests. --echo # ----------------------------------------------------------------- +--echo # +--echo # Bug #794005: crash in st_table::mark_virtual_columns_for_write +--echo # + +CREATE TABLE t1 (a int); +insert into t1 values (1); +CREATE TABLE t2 (a int); +insert into t2 values (1); + +CREATE VIEW v2 AS SELECT * FROM t2; +CREATE VIEW v1 AS SELECT * FROM v2; +CREATE VIEW v3 AS SELECT t2.a,v1.a as b FROM t2,v1 where t2.a=v1.a; +CREATE OR REPLACE ALGORITHM = TEMPTABLE VIEW v2 AS SELECT * FROM t1; + +--error ER_NON_UPDATABLE_TABLE +UPDATE v1 SET a = 10; +--error ER_NON_INSERTABLE_TABLE +REPLACE v1 SET a = 10; +--error ER_NON_INSERTABLE_TABLE +INSERT into v1 values (20); +--error ER_NON_UPDATABLE_TABLE +DELETE from v1; +--error ER_NON_UPDATABLE_TABLE +UPDATE v3 SET b= 10; +--error ER_NON_INSERTABLE_TABLE +REPLACE v3 SET b= 10; +--error ER_NON_INSERTABLE_TABLE +INSERT into v3(b) values (20); +--error ER_VIEW_DELETE_MERGE_VIEW +DELETE from v3 where b=20; +--error ER_VIEW_DELETE_MERGE_VIEW +DELETE from v3 where a=20; +--error ER_NON_UPDATABLE_TABLE +DELETE v1 from v1,t1 where v1.a=t1.a; +UPDATE v3 SET a = 10; +REPLACE v3 SET a = 11; +INSERT INTO v3(a) values (20); + +select * from t1; +select * from t2; + +CREATE OR REPLACE ALGORITHM = MERGE VIEW v2 AS SELECT * FROM t2; +DELETE from v1 where a=11; +DELETE v1 from v1,t1 where v1.a=t1.a; +select * from t1; +select * from t2; + +DROP VIEW v1,v2,v3; +DROP TABLE t1,t2; + +--echo # ----------------------------------------------------------------- +--echo # -- End of 5.2 tests. +--echo # ----------------------------------------------------------------- --echo # --echo # Bug #59696 Optimizer does not use equalities for conditions over view @@ -4493,4 +4546,8 @@ SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM DROP VIEW v2; DROP TABLE t1, t2, t3; +--echo # ----------------------------------------------------------------- +--echo # -- End of 5.3 tests. +--echo # ----------------------------------------------------------------- + SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index 6ee1167621a..b0d754211cd 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -413,133 +413,19 @@ fun:__libc_start_main } -{ - dlclose memory loss from udf_free - Memcheck:Leak - fun:calloc - fun:_dlerror_run - fun:dlclose - fun:_Z8udf_freev -} - -{ - dlsym memory loss from udf_free on SuSE 11.1 x64 variant 2 - Memcheck:Leak - fun:calloc - obj:/lib*/ld-*.so - fun:dlclose - fun:udf_free -} - -{ - dlclose memory loss from plugin variant 1 - Memcheck:Leak - fun:calloc - fun:_dlerror_run - fun:dlclose - fun:plugin_dl_del(st_mysql_lex_string const*) -} - -{ - dlclose memory loss from plugin variant 2 - Memcheck:Leak - fun:malloc - fun:_dl_close_worker - fun:_dl_close - fun:_dl_catch_error - fun:_dlerror_run - fun:dlclose - fun:_Z15free_plugin_memP12st_plugin_dl - fun:_Z13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 3 - Memcheck:Leak - fun:malloc - fun:_dl_scope_free - fun:_dl_close_worker - fun:_dl_close - fun:_dl_catch_error - fun:_dlerror_run - fun:dlclose - fun:_Z15free_plugin_memP12st_plugin_dl - fun:_Z13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 4 - Memcheck:Leak - fun:malloc - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/libdl-*.so - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl - fun:_ZL13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 5 - Memcheck:Leak - fun:malloc - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/libdl-*.so - fun:dlclose -} - -{ - dlclose memory loss from plugin variant 6, seen on Ubuntu Jaunty i686 - Memcheck:Leak - fun:malloc - fun:_dl_scope_free - fun:_dl_close_worker - fun:_dl_close - fun:dlclose_doit - fun:_dl_catch_error - fun:_dlerror_run - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl - fun:_ZL13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 7, seen on Ubuntu Jaunty i686 - Memcheck:Leak - fun:malloc - fun:_dl_close_worker - fun:_dl_close - fun:dlclose_doit - fun:_dl_catch_error - fun:_dlerror_run - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl - fun:_ZL13plugin_dl_delPK19st_mysql_lex_string -} +# +# dlclose can allocate memory for error message, the memory will be +# freed by dlerror or other dl* function. +# { - dlclose memory loss from plugin variant 8 + memory "loss" from dlclose error messages Memcheck:Leak - fun:calloc - fun:_dlerror_run + fun:*alloc + ... fun:dlclose - fun:_Z15free_plugin_memP12st_plugin_dl - fun:_Z13plugin_dl_delPK19st_mysql_lex_string } -{ - dlclose memory loss from plugin variant 9 - Memcheck:Leak - fun:calloc - fun:_dlerror_run - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl - fun:_ZL13plugin_dl_delPK19st_mysql_lex_string -} { dlclose memory loss from plugin variant 10 diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c index b01b109c666..74dae29f235 100644 --- a/mysys/my_gethwaddr.c +++ b/mysys/my_gethwaddr.c @@ -100,14 +100,14 @@ my_bool my_gethwaddr(uchar *to) uint i; for (i= 0; res && i < ifc.ifc_len / sizeof(ifr[0]); i++) { -#ifdef SIOCGIFHWADDR +#ifdef __linux__ if (ioctl(fd, SIOCGIFHWADDR, &ifr[i]) >= 0) res= memcpy_and_test(to, (uchar *)&ifr[i].ifr_hwaddr.sa_data, ETHER_ADDR_LEN); #else /* - A bug in OpenSolaris prevents non-root from getting a mac address: - http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4720634 + A bug in OpenSolaris used to prevent non-root from getting a mac address: + {no url. Oracle killed the old OpenSolaris bug database} Thus, we'll use an alternative method and extract the address from the arp table. diff --git a/mysys/my_init.c b/mysys/my_init.c index abb0c0d7824..bb72d0e0426 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -1,5 +1,6 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates + Copyright (c) 2009, 2011, Monty Program 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 diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c index 30c9fafcb82..db51195db25 100644 --- a/mysys/stacktrace.c +++ b/mysys/stacktrace.c @@ -163,7 +163,7 @@ void my_print_stacktrace(uchar* stack_bottom __attribute__((unused)), my_safe_printf_stderr("%s", "Error when traversing the stack, stack appears corrupt.\n"); else - my_safe_printf_stderr("%s" + my_safe_printf_stderr("%s", "Please read " "http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n" "and follow instructions on how to resolve the stack trace.\n" @@ -499,10 +499,11 @@ static void add_to_symbol_path(char *path, size_t path_buffer_size, } /* - Get symbol path - semicolon-separated list of directories to search for debug - symbols. We expect PDB in the same directory as corresponding exe or dll, - so the path is build from directories of the loaded modules. If environment - variable _NT_SYMBOL_PATH is set, it's value appended to the symbol search path + Get symbol path - semicolon-separated list of directories to search + for debug symbols. We expect PDB in the same directory as + corresponding exe or dll, so the path is build from directories of + the loaded modules. If environment variable _NT_SYMBOL_PATH is set, + it's value appended to the symbol search path */ static void get_symbol_path(char *path, size_t size) { @@ -640,9 +641,9 @@ void my_print_stacktrace(uchar* unused1, ulong unused2) if(!have_module) { /* - ModuleInfo structure has been "compatibly" extended in releases after XP, - and its size was increased. To make XP dbghelp.dll function - happy, pretend passing the old structure. + ModuleInfo structure has been "compatibly" extended in + releases after XP, and its size was increased. To make XP + dbghelp.dll function happy, pretend passing the old structure. */ module.SizeOfStruct= MODULE64_SIZE_WINXP; have_module= SymGetModuleInfo64(hProcess, addr, &module); diff --git a/mysys/wqueue.c b/mysys/wqueue.c index b6f52ba5c31..2fcced14f77 100644 --- a/mysys/wqueue.c +++ b/mysys/wqueue.c @@ -1,3 +1,19 @@ +/* + Copyright (c) 2007, 2008, Sun Microsystems, Inc, + Copyright (c) 2011, 2012, Monty Program 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 */ #include <wqueue.h> diff --git a/plugin/auth_dialog/dialog.c b/plugin/auth_dialog/dialog.c index 2026369bc26..0fa5ab93a35 100644 --- a/plugin/auth_dialog/dialog.c +++ b/plugin/auth_dialog/dialog.c @@ -148,6 +148,8 @@ static int perform_dialog(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) if (res) return CR_ERROR; + first= 0; + /* repeat unless it was the last question */ } while ((cmd & 1) != 1); diff --git a/plugin/auth_pam/Makefile.am b/plugin/auth_pam/Makefile.am deleted file mode 100644 index be20d393781..00000000000 --- a/plugin/auth_pam/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -EXTRA_LTLIBRARIES = auth_pam.la libauth_pam.la - -pkgplugindir=$(pkglibdir)/plugin -AM_CPPFLAGS = -I$(top_srcdir)/include - -pkgplugin_LTLIBRARIES = @plugin_auth_pam_shared_target@ -auth_pam_la_LDFLAGS = -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices -lpam -auth_pam_la_CFLAGS = -shared -DMYSQL_DYNAMIC_PLUGIN -auth_pam_la_SOURCES = auth_pam.c - -noinst_LTLIBRARIES = @plugin_auth_pam_static_target@ -libauth_pam_la_LDFLAGS = -lpam -libauth_pam_la_SOURCES = auth_pam.c - -EXTRA_DIST = plug.in - diff --git a/plugin/auth_pam/auth_pam.c b/plugin/auth_pam/auth_pam.c index 45c49975f6e..fbe2edff449 100644 --- a/plugin/auth_pam/auth_pam.c +++ b/plugin/auth_pam/auth_pam.c @@ -1,5 +1,22 @@ +/* + Copyright (c) 2011, 2012, Monty Program 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 */ + #include <mysql/plugin_auth.h> #include <string.h> +#include <my_config.h> #include <security/pam_appl.h> #include <security/pam_modules.h> @@ -8,6 +25,24 @@ struct param { MYSQL_PLUGIN_VIO *vio; }; +/* It least solaris doesn't have strndup */ + +#ifndef HAVE_STRNDUP +char *strndup(const char *from, size_t length) +{ + char *ptr; + size_t max_length= strlen(from); + if (length > max_length) + length= max_length; + if ((ptr= (char*) malloc(length+1)) != 0) + { + memcpy((char*) ptr, (char*) from, length); + ptr[length]=0; + } + return ptr; +} +#endif + static int conv(int n, const struct pam_message **msg, struct pam_response **resp, void *data) { @@ -71,13 +106,21 @@ static int conv(int n, const struct pam_message **msg, #define DO(X) if ((status = (X)) != PAM_SUCCESS) goto end +#ifdef SOLARIS +typedef void** pam_get_item_3_arg; +#else +typedef const void** pam_get_item_3_arg; +#endif + static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) { pam_handle_t *pamh = NULL; int status; const char *new_username; struct param param; - struct pam_conv c = { &conv, ¶m }; + /* The following is written in such a way to make also solaris happy */ + struct pam_conv pam_start_arg = { &conv, NULL }; + pam_start_arg.appdata_ptr= (char*) ¶m; /* get the service name, as specified in @@ -90,10 +133,10 @@ static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) param.ptr = param.buf + 1; param.vio = vio; - DO( pam_start(service, info->user_name, &c, &pamh) ); + DO( pam_start(service, info->user_name, &pam_start_arg, &pamh) ); DO( pam_authenticate (pamh, 0) ); DO( pam_acct_mgmt(pamh, 0) ); - DO( pam_get_item(pamh, PAM_USER, (const void**)&new_username) ); + DO( pam_get_item(pamh, PAM_USER, (pam_get_item_3_arg) &new_username) ); if (new_username && strcmp(new_username, info->user_name)) strncpy(info->authenticated_as, new_username, @@ -104,7 +147,7 @@ end: return status == PAM_SUCCESS ? CR_OK : CR_ERROR; } -static struct st_mysql_auth pam_info = +static struct st_mysql_auth info = { MYSQL_AUTHENTICATION_INTERFACE_VERSION, "dialog", @@ -114,7 +157,7 @@ static struct st_mysql_auth pam_info = maria_declare_plugin(pam) { MYSQL_AUTHENTICATION_PLUGIN, - &pam_info, + &info, "pam", "Sergei Golubchik", "PAM based authentication", diff --git a/plugin/auth_pam/plug.in b/plugin/auth_pam/plug.in deleted file mode 100644 index 05af6ce6461..00000000000 --- a/plugin/auth_pam/plug.in +++ /dev/null @@ -1,4 +0,0 @@ -MYSQL_PLUGIN(auth_pam, [PAM Authentication Plugin], [PAM Authentication Plugin]) -MYSQL_PLUGIN_DYNAMIC(auth_pam, [auth_pam.la]) - -AC_CHECK_HEADER([security/pam_appl.h],,[MYSQL_PLUGIN_WITHOUT(auth_pam)]) diff --git a/plugin/auth_pam/testing/pam_mariadb_mtr.c b/plugin/auth_pam/testing/pam_mariadb_mtr.c index 73defe30112..8ad1e18e696 100644 --- a/plugin/auth_pam/testing/pam_mariadb_mtr.c +++ b/plugin/auth_pam/testing/pam_mariadb_mtr.c @@ -1,4 +1,6 @@ /* + This code is in the public domain and has no copyright. + Pam module to test pam authentication plugin. Used in pam.test. Linux only. diff --git a/plugin/auth_socket/auth_socket.c b/plugin/auth_socket/auth_socket.c index dbc8513e5dd..41cb1039fd2 100644 --- a/plugin/auth_socket/auth_socket.c +++ b/plugin/auth_socket/auth_socket.c @@ -89,7 +89,7 @@ mysql_declare_plugin(socket_auth) { MYSQL_AUTHENTICATION_PLUGIN, &socket_auth_handler, - "auth_socket", + "unix_socket", "Sergei Golubchik", "Unix Socket based authentication", PLUGIN_LICENSE_GPL, @@ -106,7 +106,7 @@ maria_declare_plugin(socket_auth) { MYSQL_AUTHENTICATION_PLUGIN, &socket_auth_handler, - "auth_socket", + "unix_socket", "Sergei Golubchik", "Unix Socket based authentication", PLUGIN_LICENSE_GPL, diff --git a/plugin/feedback/Makefile.am b/plugin/feedback/Makefile.am deleted file mode 100644 index 7d2a61d593f..00000000000 --- a/plugin/feedback/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -pkgplugindir = $(pkglibdir)/plugin -INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \ - -I$(top_srcdir)/regex -I$(top_srcdir)/sql - -EXTRA_LTLIBRARIES = feedback.la libfeedback.la -pkgplugin_LTLIBRARIES = @plugin_feedback_shared_target@ -feedback_la_LDFLAGS = -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices -feedback_la_CXXFLAGS = -shared -DMYSQL_DYNAMIC_PLUGIN -feedback_la_SOURCES = feedback.cc utils.cc url_base.cc url_http.cc \ - sender_thread.cc - -noinst_LTLIBRARIES = @plugin_feedback_static_target@ -libfeedback_la_SOURCES= feedback.cc utils.cc url_base.cc url_http.cc \ - sender_thread.cc - -noinst_HEADERS = feedback.h -EXTRA_DIST = CMakeLists.txt plug.in - diff --git a/plugin/feedback/feedback.cc b/plugin/feedback/feedback.cc index d7342eaa109..f093fd4df25 100644 --- a/plugin/feedback/feedback.cc +++ b/plugin/feedback/feedback.cc @@ -138,6 +138,7 @@ static LEX_STRING vars_filter[]= { {C_STRING_WITH_LEN("ft\\_m%")}, {C_STRING_WITH_LEN("have\\_%")}, {C_STRING_WITH_LEN("%\\_size")}, + {C_STRING_WITH_LEN("innodb_f%")}, {C_STRING_WITH_LEN("%\\_length%")}, {C_STRING_WITH_LEN("%\\_timeout")}, {C_STRING_WITH_LEN("large\\_%")}, diff --git a/plugin/feedback/plug.in b/plugin/feedback/plug.in deleted file mode 100644 index 88a4448321d..00000000000 --- a/plugin/feedback/plug.in +++ /dev/null @@ -1,28 +0,0 @@ -MYSQL_PLUGIN(feedback,[MariaDB User Feedback Plugin], - [MariaDB User Feedback Plugin]) - -dnl Although it's not exactly obvious, top-level CMakeLists.txt parses plug.in -dnl files, in particular looking for what the library name should be. It uses -dnl regexp that matches MYSQL_PLUGIN_DYNAMIC or MYSQL_PLUGIN_STATIC, followed -dnl by an open parenthesys, and the plugin name. Having engine name enclosed in -dnl square brackets below causes this regexp to fail and as a result feedback -dnl plugin will not be considered for dynamic builds on Windows. -dnl Unfortunately, feedback cannot be built dynamically on Windows, because it -dnl needs to access server internals that aren't designed for plugin use and -dnl aren't marked with MYSQL_PLUGIN_IMPORT. -MYSQL_PLUGIN_DYNAMIC([feedback], [feedback.la]) -ifelse(index(AC_PACKAGE_NAME, [MariaDB]), -1, [], [ - -dnl MariaDB and MySQL define static plugins differently. -dnl I only support MariaDB here, for now. -MYSQL_PLUGIN_STATIC(feedback, [libfeedback.la]) - -]) - -dnl MariaDB before 5.5 needs this define: -MYSQL_PLUGIN_DEFINE(feedback, [WITH_FEEDBACK_PLUGIN]) - -MYSQL_PLUGIN_ACTIONS(feedback, [ - AC_CHECK_HEADERS([netdb.h sys/utsname.h]) -]) - diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index fe5ea28fa5c..5636484ac72 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -340,9 +340,4 @@ IF(WIN32) mysql_upgrade_service.cc COMPONENT Server) TARGET_LINK_LIBRARIES(mysql_upgrade_service mysys winservice) -ENDIF() - -ADD_CUSTOM_TARGET(show-dist-name - COMMAND ${CMAKE_COMMAND} -E echo "${CPACK_PACKAGE_FILE_NAME}" -) - +ENDIF(WIN32) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index f04c33ce90b..36d5da94b11 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4069,6 +4069,8 @@ int ha_partition::rnd_next(uchar *buf) int result= HA_ERR_END_OF_FILE; uint part_id= m_part_spec.start_part; DBUG_ENTER("ha_partition::rnd_next"); + + /* upper level will increment this once again at end of call */ decrement_statistics(&SSV::ha_read_rnd_next_count); if (NO_CURRENT_PART_ID == part_id) diff --git a/sql/handler.cc b/sql/handler.cc index 8c2756977cf..5f8a64e486c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4617,6 +4617,27 @@ int handler::compare_key2(key_range *range) } +/** + ICP callback - to be called by an engine to check the pushed condition +*/ +extern "C" enum icp_result handler_index_cond_check(void* h_arg) +{ + handler *h= (handler*)h_arg; + THD *thd= h->table->in_use; + enum icp_result res; + + if (thd_killed(thd)) + return ICP_ABORTED_BY_USER; + + if (h->end_range && h->compare_key2(h->end_range) > 0) + return ICP_OUT_OF_RANGE; + h->increment_statistics(&SSV::ha_pushed_index_cond_checks); + if ((res= h->pushed_idx_cond->val_int()? ICP_MATCH : ICP_NO_MATCH) == + ICP_NO_MATCH) + h->increment_statistics(&SSV::ha_pushed_index_cond_filtered); + return res; +} + int handler::index_read_idx_map(uchar * buf, uint index, const uchar * key, key_part_map keypart_map, enum ha_rkey_function find_flag) diff --git a/sql/handler.h b/sql/handler.h index b52ee6a7279..0ff1a8db01d 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1638,6 +1638,8 @@ public: {} }; +extern "C" enum icp_result handler_index_cond_check(void* h_arg); + uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map); /* bitmap with first N+1 bits set @@ -2857,6 +2859,8 @@ public: { return ht; } inline int ha_write_tmp_row(uchar *buf); inline int ha_update_tmp_row(const uchar * old_data, uchar * new_data); + + friend enum icp_result handler_index_cond_check(void* h_arg); }; #include "multi_range_read.h" diff --git a/sql/item.cc b/sql/item.cc index 02cbe9b7f49..de4716350c2 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5378,7 +5378,8 @@ bool Item_field::set_no_const_sub(uchar *arg) Item *Item_field::replace_equal_field(uchar *arg) { - if (item_equal && item_equal == (Item_equal *) arg) + REPLACE_EQUAL_FIELD_ARG* param= (REPLACE_EQUAL_FIELD_ARG*)arg; + if (item_equal && item_equal == param->item_equal) { Item *const_item= item_equal->get_const(); if (const_item) @@ -5387,7 +5388,8 @@ Item *Item_field::replace_equal_field(uchar *arg) return this; return const_item; } - Item_field *subst= (Item_field *)(item_equal->get_first(this)); + Item_field *subst= + (Item_field *)(item_equal->get_first(param->context_tab, this)); if (subst) subst= (Item_field *) (subst->real_item()); if (subst && !field->eq(subst->field)) @@ -9467,13 +9469,13 @@ void Item_type_holder::get_full_info(Item *item) DBUG_ASSERT((enum_set_typelib && get_real_type(item) == MYSQL_TYPE_NULL) || (!enum_set_typelib && - item->type() == Item::FIELD_ITEM && - (get_real_type(item) == MYSQL_TYPE_ENUM || - get_real_type(item) == MYSQL_TYPE_SET) && - ((Field_enum*)((Item_field *) item)->field)->typelib)); + item->real_item()->type() == Item::FIELD_ITEM && + (get_real_type(item->real_item()) == MYSQL_TYPE_ENUM || + get_real_type(item->real_item()) == MYSQL_TYPE_SET) && + ((Field_enum*)((Item_field *) item->real_item())->field)->typelib)); if (!enum_set_typelib) { - enum_set_typelib= ((Field_enum*)((Item_field *) item)->field)->typelib; + enum_set_typelib= ((Field_enum*)((Item_field *) item->real_item())->field)->typelib; } } } @@ -9558,18 +9560,22 @@ void Item_ref::update_used_tables() } -table_map Item_direct_view_ref::used_tables() const +table_map Item_direct_view_ref::used_tables() const { - return get_depended_from() ? + return get_depended_from() ? OUTER_REF_TABLE_BIT : - (view->merged ? (*ref)->used_tables() : view->table->map); + ((view->merged || !view->table) ? + (*ref)->used_tables() : + view->table->map); } -table_map Item_direct_view_ref::not_null_tables() const +table_map Item_direct_view_ref::not_null_tables() const { - return get_depended_from() ? + return get_depended_from() ? 0 : - (view->merged ? (*ref)->not_null_tables() : view->table->map); + ((view->merged || !view->table) ? + (*ref)->not_null_tables() : + view->table->map); } /* @@ -9583,6 +9589,8 @@ table_map Item_ref_null_helper::used_tables() const } +#ifndef DBUG_OFF + /* Debugger help function */ static char dbug_item_print_buf[256]; @@ -9599,6 +9607,9 @@ const char *dbug_print_item(Item *item) else return "Couldn't fit into buffer"; } + +#endif /*DBUG_OFF*/ + /***************************************************************************** ** Instantiate templates *****************************************************************************/ diff --git a/sql/item.h b/sql/item.h index 4732a1a4657..4af2038aa55 100644 --- a/sql/item.h +++ b/sql/item.h @@ -471,6 +471,16 @@ typedef enum monotonicity_info class sp_rcontext; +class Item_equal; + +struct st_join_table* const NO_PARTICULAR_TAB= (struct st_join_table*)0x1; + +typedef struct replace_equal_field_arg +{ + Item_equal *item_equal; + struct st_join_table *context_tab; +} REPLACE_EQUAL_FIELD_ARG; + class Settable_routine_parameter { public: @@ -1283,6 +1293,7 @@ public: virtual Item *equal_fields_propagator(uchar * arg) { return this; } virtual bool set_no_const_sub(uchar *arg) { return FALSE; } + /* arg points to REPLACE_EQUAL_FIELD_ARG object */ virtual Item *replace_equal_field(uchar * arg) { return this; } /* Check if an expression value has allowed arguments, like DATE/DATETIME @@ -3890,6 +3901,12 @@ public: return example->is_expensive_processor(arg); } virtual void set_null(); + bool walk(Item_processor processor, bool walk_subquery, uchar *arg) + { + if (example && example->walk(processor, walk_subquery, arg)) + return TRUE; + return (this->*processor)(arg); + } }; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index b3954c55394..4ea5e9534a8 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5804,7 +5804,7 @@ longlong Item_equal::val_int() void Item_equal::fix_length_and_dec() { - Item *item= get_first(NULL); + Item *item= get_first(NO_PARTICULAR_TAB, NULL); eval_item= cmp_item::get_comparator(item->cmp_type(), item, item->collation.collation); } @@ -5904,7 +5904,7 @@ CHARSET_INFO *Item_equal::compare_collation() @retval 0 if no field found. */ -Item* Item_equal::get_first(Item *field_item) +Item* Item_equal::get_first(JOIN_TAB *context, Item *field_item) { Item_equal_fields_iterator it(*this); Item *item; @@ -5932,18 +5932,24 @@ Item* Item_equal::get_first(Item *field_item) in presense of SJM nests. */ - TABLE_LIST *emb_nest= field->table->pos_in_table_list->embedding; + TABLE_LIST *emb_nest; + if (context != NO_PARTICULAR_TAB) + emb_nest= context->emb_sj_nest; + else + emb_nest= field->table->pos_in_table_list->embedding; if (emb_nest && emb_nest->sj_mat_info && emb_nest->sj_mat_info->is_used) { /* - It's a field from an materialized semi-join. We can substitute it only - for a field from the same semi-join. Find the first of such items. + It's a field from an materialized semi-join. We can substitute it for + - a constant item + - a field from the same semi-join + Find the first of such items: */ - while ((item= it++)) { - if (it.get_curr_field()->table->pos_in_table_list->embedding == emb_nest) + if (item->const_item() || + it.get_curr_field()->table->pos_in_table_list->embedding == emb_nest) { /* If we found given field then return NULL to avoid unnecessary diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 7b2193b1acd..384c91d5d2e 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1705,7 +1705,7 @@ public: /** Add a non-constant item to the multiple equality */ void add(Item *f) { equal_items.push_back(f); } bool contains(Field *field); - Item* get_first(Item *field); + Item* get_first(struct st_join_table *context, Item *field); /** Get number of field items / references to field items in this object */ uint n_field_items() { return equal_items.elements-test(with_const); } void merge(Item_equal *item); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 5f78cdf167b..50625286348 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1271,7 +1271,8 @@ void Item_exists_subselect::fix_length_and_dec() We need only 1 row to determine existence (i.e. any EXISTS that is not an IN always requires LIMIT 1) */ - unit->global_parameters->select_limit= new Item_int((int32) 1); + thd->change_item_tree(&unit->global_parameters->select_limit, + new Item_int((int32) 1)); DBUG_PRINT("info", ("Set limit to 1")); DBUG_VOID_RETURN; } @@ -1597,7 +1598,6 @@ Item_in_subselect::single_value_transformer(JOIN *join) (Item**)optimizer->get_cache(), (char *)"<no matter>", (char *)in_left_expr_name); - } DBUG_RETURN(false); @@ -1684,10 +1684,6 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join) DBUG_EXECUTE("where", print_where(item, "rewrite with MIN/MAX", QT_ORDINARY);); - if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) - { - select_lex->set_non_agg_field_used(false); - } save_allow_sum_func= thd->lex->allow_sum_func; thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level; @@ -2244,7 +2240,12 @@ bool Item_in_subselect::create_in_to_exists_cond(JOIN *join_arg) /* The IN=>EXISTS transformation makes non-correlated subqueries correlated. */ - join_arg->select_lex->uncacheable|= UNCACHEABLE_DEPENDENT_INJECTED; + if (!left_expr->const_item() || left_expr->is_expensive()) + { + join_arg->select_lex->uncacheable|= UNCACHEABLE_DEPENDENT_INJECTED; + join_arg->select_lex->master_unit()->uncacheable|= + UNCACHEABLE_DEPENDENT_INJECTED; + } /* The uncacheable property controls a number of actions, e.g. whether to save/restore (via init_save_join_tab/restore_tmp) the original JOIN for @@ -2510,6 +2511,7 @@ bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref) left_expr && !left_expr->fixed && left_expr->fix_fields(thd_arg, &left_expr)) return TRUE; + else if (Item_subselect::fix_fields(thd_arg, ref)) return TRUE; fixed= TRUE; @@ -3159,6 +3161,8 @@ bool subselect_uniquesubquery_engine::copy_ref_key() for (store_key **copy= tab->ref.key_copy ; *copy ; copy++) { + if ((*copy)->store_key_is_const()) + continue; tab->ref.key_err= (*copy)->copy(); /* diff --git a/sql/item_sum.cc b/sql/item_sum.cc index c0284e730a8..afe4f34bd05 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1129,13 +1129,12 @@ Item_sum_num::fix_fields(THD *thd, Item **ref) return TRUE; decimals=0; - maybe_null=0; + maybe_null= sum_func() != COUNT_FUNC; for (uint i=0 ; i < arg_count ; i++) { if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1)) return TRUE; set_if_bigger(decimals, args[i]->decimals); - maybe_null |= args[i]->maybe_null; } result_field=0; max_length=float_length(decimals); @@ -1647,7 +1646,7 @@ double Item_sum_avg::val_real() my_decimal *Item_sum_avg::val_decimal(my_decimal *val) { - my_decimal sum_buff, cnt; + my_decimal cnt; const my_decimal *sum_dec; DBUG_ASSERT(fixed == 1); if (aggr) diff --git a/sql/log.cc b/sql/log.cc index af400c19f4a..577297fa1a4 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2230,7 +2230,6 @@ static int find_uniq_filename(char *name) char *start, *end; int error= 0; DBUG_ENTER("find_uniq_filename"); - LINT_INIT(number); length= dirname_part(buff, name, &buf_length); start= name + length; @@ -5372,6 +5371,7 @@ void MYSQL_BIN_LOG::purge() { purge_logs_before_date(purge_time); } + DEBUG_SYNC(current_thd, "after_purge_logs_before_date"); } #endif } diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc index d8dc45d38c7..29e7faa630d 100644 --- a/sql/multi_range_read.cc +++ b/sql/multi_range_read.cc @@ -482,6 +482,10 @@ void Mrr_ordered_index_reader::resume_read() /** Fill the buffer with (lookup_tuple, range_id) pairs and sort + + @return + 0 OK, the buffer is non-empty and sorted + HA_ERR_END_OF_FILE Source exhausted, the buffer is empty. */ int Mrr_ordered_index_reader::refill_buffer(bool initial) @@ -518,6 +522,13 @@ int Mrr_ordered_index_reader::refill_buffer(bool initial) if (source_exhausted && key_buffer->is_empty()) DBUG_RETURN(HA_ERR_END_OF_FILE); + if (!initial) + { + /* This is a non-initial buffer fill and we've got a non-empty buffer */ + THD *thd= current_thd; + status_var_increment(thd->status_var.ha_mrr_extra_key_sorts); + } + key_buffer->sort((key_buffer->type() == Lifo_buffer::FORWARD)? (qsort2_cmp)Mrr_ordered_index_reader::compare_keys_reverse : (qsort2_cmp)Mrr_ordered_index_reader::compare_keys, @@ -592,6 +603,7 @@ int Mrr_ordered_rndpos_reader::init(handler *h_arg, int Mrr_ordered_rndpos_reader::refill_buffer(bool initial) { int res; + bool first_call= initial; DBUG_ENTER("Mrr_ordered_rndpos_reader::refill_buffer"); if (index_reader_exhausted) @@ -609,6 +621,14 @@ int Mrr_ordered_rndpos_reader::refill_buffer(bool initial) initial= FALSE; index_reader_needs_refill= FALSE; } + + if (!first_call && !index_reader_exhausted) + { + /* Ok, this was a successful buffer refill operation */ + THD *thd= current_thd; + status_var_increment(thd->status_var.ha_mrr_extra_rowid_sorts); + } + DBUG_RETURN(res); } @@ -841,8 +861,7 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, strategy= disk_strategy= &reader_factory.ordered_rndpos_reader; } - if (is_mrr_assoc) - status_var_increment(thd->status_var.ha_multi_range_read_init_count); + status_var_increment(thd->status_var.ha_multi_range_read_init_count); full_buf= buf->buffer; full_buf_end= buf->buffer_end; diff --git a/sql/multi_range_read.h b/sql/multi_range_read.h index 1b72e71944d..dcba92aab16 100644 --- a/sql/multi_range_read.h +++ b/sql/multi_range_read.h @@ -1,3 +1,19 @@ +/* + Copyright (c) 2009, 2011, Monty Program 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 */ + /** @defgroup DS-MRR declarations @{ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index cc0ee652b16..e5b9a6e6312 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -340,7 +340,7 @@ static volatile bool ready_to_exit; static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0; static my_bool opt_short_log_format= 0; static uint kill_cached_threads, wake_thread; - ulong max_used_connections; +ulong max_used_connections; static volatile ulong cached_thread_count= 0; static char *mysqld_user, *mysqld_chroot; static char *default_character_set_name; @@ -680,6 +680,7 @@ char *opt_logname, *opt_slow_logname, *opt_bin_logname; my_bool opt_stack_trace; static volatile sig_atomic_t kill_in_progress; +my_bool opt_expect_abort= 0; static my_bool opt_bootstrap, opt_myisam_log; static int cleanup_done; static ulong opt_specialflag; @@ -1240,7 +1241,6 @@ static int mysql_init_variables(void); static int get_options(int *argc_ptr, char ***argv_ptr); static bool add_terminator(DYNAMIC_ARRAY *options); extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *); -static void set_server_version(void); static int init_thread_environment(); static char *get_relative_path(const char *path); static int fix_paths(void); @@ -1883,7 +1883,6 @@ static void clean_up_mutexes() mysql_mutex_destroy(&LOCK_delayed_insert); mysql_mutex_destroy(&LOCK_delayed_status); mysql_mutex_destroy(&LOCK_delayed_create); - mysql_mutex_destroy(&LOCK_manager); mysql_mutex_destroy(&LOCK_crypt); mysql_mutex_destroy(&LOCK_user_conn); mysql_mutex_destroy(&LOCK_connection_count); @@ -1914,7 +1913,6 @@ static void clean_up_mutexes() mysql_cond_destroy(&COND_thread_count); mysql_cond_destroy(&COND_thread_cache); mysql_cond_destroy(&COND_flush_thread_cache); - mysql_cond_destroy(&COND_manager); mysql_mutex_destroy(&LOCK_server_started); mysql_cond_destroy(&COND_server_started); mysql_mutex_destroy(&LOCK_prepare_ordered); @@ -3776,8 +3774,6 @@ static int init_thread_environment() &LOCK_delayed_status, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_delayed_create, &LOCK_delayed_create, MY_MUTEX_INIT_SLOW); - mysql_mutex_init(key_LOCK_manager, - &LOCK_manager, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_crypt, &LOCK_crypt, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_user_conn, &LOCK_user_conn, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_active_mi, &LOCK_active_mi, MY_MUTEX_INIT_FAST); @@ -3826,7 +3822,6 @@ static int init_thread_environment() mysql_cond_init(key_COND_thread_count, &COND_thread_count, NULL); mysql_cond_init(key_COND_thread_cache, &COND_thread_cache, NULL); mysql_cond_init(key_COND_flush_thread_cache, &COND_flush_thread_cache, NULL); - mysql_cond_init(key_COND_manager, &COND_manager, NULL); #ifdef HAVE_REPLICATION mysql_mutex_init(key_LOCK_rpl_status, &LOCK_rpl_status, MY_MUTEX_INIT_FAST); mysql_cond_init(key_COND_rpl_status, &COND_rpl_status, NULL); @@ -6874,21 +6869,30 @@ SHOW_VAR status_vars[]= { {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS}, {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS}, {"Handler_discover", (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS}, +#if 0 + /* Made 3 counters below temporarily invisible until we agree upon their names */ + {"Handler_mrr_extra_key_sorts", (char*) offsetof(STATUS_VAR, ha_mrr_extra_key_sorts), SHOW_LONG_STATUS}, + {"Handler_mrr_extra_rowid_sorts", (char*) offsetof(STATUS_VAR, ha_mrr_extra_rowid_sorts), SHOW_LONG_STATUS}, + {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_multi_range_read_init_count), SHOW_LONG_STATUS}, +#endif {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS}, + {"Handler_pushed_index_cond_checks",(char*) offsetof(STATUS_VAR, ha_pushed_index_cond_checks), SHOW_LONG_STATUS}, + {"Handler_pushed_index_cond_filtered",(char*) offsetof(STATUS_VAR, ha_pushed_index_cond_filtered), SHOW_LONG_STATUS}, {"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS}, {"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS}, {"Handler_read_last", (char*) offsetof(STATUS_VAR, ha_read_last_count), SHOW_LONG_STATUS}, {"Handler_read_next", (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS}, {"Handler_read_prev", (char*) offsetof(STATUS_VAR, ha_read_prev_count), SHOW_LONG_STATUS}, {"Handler_read_rnd", (char*) offsetof(STATUS_VAR, ha_read_rnd_count), SHOW_LONG_STATUS}, + {"Handler_read_rnd_deleted", (char*) offsetof(STATUS_VAR, ha_read_rnd_deleted_count), SHOW_LONG_STATUS}, {"Handler_read_rnd_next", (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count), SHOW_LONG_STATUS}, {"Handler_rollback", (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS}, {"Handler_savepoint", (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS}, {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS}, - {"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS}, - {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS}, {"Handler_tmp_update", (char*) offsetof(STATUS_VAR, ha_tmp_update_count), SHOW_LONG_STATUS}, {"Handler_tmp_write", (char*) offsetof(STATUS_VAR, ha_tmp_write_count), SHOW_LONG_STATUS}, + {"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS}, + {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS}, {"Key", (char*) &show_default_keycache, SHOW_FUNC}, {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS}, {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG}, @@ -7903,7 +7907,7 @@ static int get_options(int *argc_ptr, char ***argv_ptr) (MYSQL_SERVER_SUFFIX is set by the compilation environment) */ -static void set_server_version(void) +void set_server_version(void) { char *end= strxmov(server_version, MYSQL_SERVER_VERSION, MYSQL_SERVER_SUFFIX_STR, NullS); diff --git a/sql/mysqld.h b/sql/mysqld.h index 9246ea90fa1..296b747b1ce 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -501,6 +501,8 @@ get_thread_running() return num_thread_running; } +void set_server_version(void); + #if defined(MYSQL_DYNAMIC_PLUGIN) && defined(_WIN32) extern "C" THD *_current_thd_noinline(); #define _current_thd() _current_thd_noinline() @@ -534,6 +536,7 @@ extern scheduler_functions *thread_scheduler, *extra_thread_scheduler; extern char *opt_log_basename; extern my_bool opt_master_verify_checksum; extern my_bool opt_stack_trace; +extern my_bool opt_expect_abort; extern my_bool opt_slave_sql_verify_checksum; extern ulong binlog_checksum_options; extern bool max_user_connections_checking; diff --git a/sql/opt_index_cond_pushdown.cc b/sql/opt_index_cond_pushdown.cc index bec3bf6dab6..df9dae8e442 100644 --- a/sql/opt_index_cond_pushdown.cc +++ b/sql/opt_index_cond_pushdown.cc @@ -1,3 +1,19 @@ +/* + Copyright (c) 2009, 2012, Monty Program 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 */ + #include "sql_select.h" #include "sql_test.h" @@ -329,13 +345,23 @@ void push_index_cond(JOIN_TAB *tab, uint keyno) { DBUG_ENTER("push_index_cond"); Item *idx_cond; - + + /* + Backported the following from MySQL 5.6: + 6. The index is not a clustered index. The performance improvement + of pushing an index condition on a clustered key is much lower + than on a non-clustered key. This restriction should be + re-evaluated when WL#6061 is implemented. + */ if ((tab->table->file->index_flags(keyno, 0, 1) & HA_DO_INDEX_COND_PUSHDOWN) && optimizer_flag(tab->join->thd, OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN) && tab->join->thd->lex->sql_command != SQLCOM_UPDATE_MULTI && tab->join->thd->lex->sql_command != SQLCOM_DELETE_MULTI && - tab->type != JT_CONST && tab->type != JT_SYSTEM) + tab->type != JT_CONST && tab->type != JT_SYSTEM && + !(keyno == tab->table->s->primary_key && // (6) + tab->table->file->primary_key_is_clustered())) // (6) + { DBUG_EXECUTE("where", print_where(tab->select_cond, "full cond", QT_ORDINARY);); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 9fb29512b83..a004e7700c7 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -578,6 +578,14 @@ public: increment_use_count(1); use_count++; } + void incr_refs_all() + { + for (SEL_ARG *pos=first(); pos ; pos=pos->next) + { + pos->increment_use_count(1); + } + use_count++; + } void free_tree() { for (SEL_ARG *pos=first(); pos ; pos=pos->next) @@ -1117,9 +1125,11 @@ int SEL_IMERGE::and_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree, for (SEL_TREE** or_tree= trees; or_tree != trees_next; or_tree++) { SEL_TREE *res_or_tree= 0; - if (!(res_or_tree= new SEL_TREE())) + SEL_TREE *and_tree= 0; + if (!(res_or_tree= new SEL_TREE()) || + !(and_tree= new SEL_TREE(tree, TRUE, param))) return (-1); - if (!and_range_trees(param, *or_tree, tree, res_or_tree)) + if (!and_range_trees(param, *or_tree, and_tree, res_or_tree)) { if (new_imerge->or_sel_tree(param, res_or_tree)) return (-1); @@ -1332,7 +1342,7 @@ SEL_TREE::SEL_TREE(SEL_TREE *arg, bool without_merges, for (uint idx= 0; idx < param->keys; idx++) { if ((keys[idx]= arg->keys[idx])) - keys[idx]->incr_refs(); + keys[idx]->incr_refs_all(); } if (without_merges) diff --git a/sql/opt_range_mrr.cc b/sql/opt_range_mrr.cc index 160b783715c..a4345059f85 100644 --- a/sql/opt_range_mrr.cc +++ b/sql/opt_range_mrr.cc @@ -1,3 +1,18 @@ +/* + Copyright (c) 2009, 2011, Monty Program 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 */ /**************************************************************************** MRR Range Sequence Interface implementation that walks a SEL_ARG* tree. diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 3b1991d1686..72c2f0442cf 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -1,3 +1,19 @@ +/* + Copyright (c) 2010, 2012, Monty Program 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 */ + /** @file @@ -4080,7 +4096,8 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, { uint i; DBUG_ENTER("setup_semijoin_dups_elimination"); - + + join->complex_firstmatch_tables= table_map(0); POSITION *pos= join->best_positions + join->const_tables; for (i= join->const_tables ; i < join->top_join_tab_count; ) @@ -4099,6 +4116,11 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, { /* We jump from the last table to the first one */ tab->loosescan_match_tab= tab + pos->n_sj_tables - 1; + + /* LooseScan requires records to be produced in order */ + if (tab->select && tab->select->quick) + tab->select->quick->need_sorted_output(); + for (uint j= i; j < i + pos->n_sj_tables; j++) join->join_tab[j].inside_loosescan_range= TRUE; @@ -4108,6 +4130,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, for (uint kp=0; kp < pos->loosescan_picker.loosescan_parts; kp++) keylen += tab->table->key_info[keyno].key_part[kp].store_length; + tab->loosescan_key= keyno; tab->loosescan_key_len= keylen; if (pos->n_sj_tables > 1) tab[pos->n_sj_tables - 1].do_firstmatch= tab; @@ -4163,16 +4186,46 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, } case SJ_OPT_FIRST_MATCH: { - JOIN_TAB *j, *jump_to= tab-1; + JOIN_TAB *j; + JOIN_TAB *jump_to= tab-1; + + bool complex_range= FALSE; + table_map tables_in_range= table_map(0); + for (j= tab; j != tab + pos->n_sj_tables; j++) { - /* - NOTE: this loop probably doesn't do the right thing for the case - where FirstMatch's duplicate-generating range is interleaved with - "unrelated" tables (as specified in WL#3750, section 2.2). - */ + tables_in_range |= j->table->map; if (!j->emb_sj_nest) - jump_to= tab; + { + /* + Got a table that's not within any semi-join nest. This is a case + like this: + + SELECT * FROM ot1, nt1 WHERE ot1.col IN (SELECT expr FROM it1, it2) + + with a join order of + + +----- FirstMatch range ----+ + | | + ot1 it1 nt1 nt2 it2 it3 ... + | ^ + | +-------- 'j' points here + +------------- SJ_OPT_FIRST_MATCH was set for this table as + it's the first one that produces duplicates + + */ + DBUG_ASSERT(j != tab); /* table ntX must have an itX before it */ + + /* + If the table right before us is an inner table (like it1 in the + picture), it should be set to jump back to previous outer-table + */ + if (j[-1].emb_sj_nest) + j[-1].do_firstmatch= jump_to; + + jump_to= j; /* Jump back to us */ + complex_range= TRUE; + } else { j->first_sj_inner_tab= tab; @@ -4182,6 +4235,9 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, j[-1].do_firstmatch= jump_to; i+= pos->n_sj_tables; pos+= pos->n_sj_tables; + + if (complex_range) + join->complex_firstmatch_tables|= tables_in_range; break; } case SJ_OPT_NONE: diff --git a/sql/opt_subselect.h b/sql/opt_subselect.h index c211fc67c84..a12e0c11620 100644 --- a/sql/opt_subselect.h +++ b/sql/opt_subselect.h @@ -1,4 +1,20 @@ /* + Copyright (c) 2010, 2012, Monty Program 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 */ + +/* Semi-join subquery optimization code definitions */ @@ -279,7 +295,7 @@ public: }; -void advance_sj_state(JOIN *join, const table_map remaining_tables, uint idx, +extern void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx, double *current_record_count, double *current_read_time, POSITION *loose_scan_pos); void restore_prev_sj_state(const table_map remaining_tables, diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index cda35895a3d..7087a85d13a 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -627,7 +627,12 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo, if (!cond) DBUG_RETURN(TRUE); Field *field= field_part->field; - if (!(cond->used_tables() & field->table->map)) + if (cond->used_tables() & OUTER_REF_TABLE_BIT) + { + DBUG_RETURN(FALSE); + } + if (!(cond->used_tables() & field->table->map) && + test(cond->used_tables() & ~PSEUDO_TABLE_BITS)) { /* Condition doesn't restrict the used table */ DBUG_RETURN(!cond->const_item()); diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc index 3de73c3d4cc..33164c1ed12 100644 --- a/sql/opt_table_elimination.cc +++ b/sql/opt_table_elimination.cc @@ -1,3 +1,19 @@ +/* + Copyright (c) 2009, 2011, Monty Program 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 */ + /** @file diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index fe75b209ab1..dd50854d818 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -1,4 +1,5 @@ -/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2011, Oracle and/or its affiliates. + Copyright (c) 2011, Monty Program 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 @@ -30,7 +31,7 @@ #endif /* - We are handling signals in this file. + We are handling signals/exceptions in this file. Any global variables we read should be 'volatile sig_atomic_t' to guarantee that we read some consistent value. */ @@ -44,23 +45,27 @@ extern volatile sig_atomic_t ld_assume_kernel_is_set; extern const char *optimizer_switch_names[]; /** - * Handler for fatal signals + * Handler for fatal signals on POSIX, exception handler on Windows. * * Fatal events (seg.fault, bus error etc.) will trigger * this signal handler. The handler will try to dump relevant * debugging information to stderr and dump a core image. * - * Signal handlers can only use a set of 'safe' system calls - * and library functions. A list of safe calls in POSIX systems + * POSIX : Signal handlers should, if possible, only use a set of 'safe' system + * calls and library functions. A list of safe calls in POSIX systems * are available at: * http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html - * For MS Windows, guidelines are available at: - * http://msdn.microsoft.com/en-us/library/xdkz3x12(v=vs.71).aspx * - * @param sig Signal number + * @param sig Signal number /Exception code */ extern "C" sig_handler handle_fatal_signal(int sig) { + time_t curr_time; + struct tm tm; +#ifdef HAVE_STACKTRACE + THD *thd; +#endif + if (segfaulted) { my_safe_printf_stderr("Fatal " SIGNAL_FMT " while backtracing\n", sig); @@ -69,43 +74,40 @@ extern "C" sig_handler handle_fatal_signal(int sig) segfaulted = 1; -#ifdef __WIN__ - SYSTEMTIME utc_time; - GetSystemTime(&utc_time); - const long hrs= utc_time.wHour; - const long mins= utc_time.wMinute; - const long secs= utc_time.wSecond; + curr_time= my_time(0); + localtime_r(&curr_time, &tm); + + my_safe_printf_stderr("%02d%02d%02d %2d:%02d:%02d ", + tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + if (opt_expect_abort +#ifdef _WIN32 + && sig == EXCEPTION_BREAKPOINT /* __debugbreak in my_sigabrt_hander() */ #else - /* Using time() instead of my_time() to avoid looping */ - const time_t curr_time= time(NULL); - /* Calculate time of day */ - const long tmins = curr_time / 60; - const long thrs = tmins / 60; - const long hrs = thrs % 24; - const long mins = tmins % 60; - const long secs = curr_time % 60; + && sig == SIGABRT #endif + ) + { + fprintf(stderr,"[Note] mysqld did an expected abort\n"); + goto end; + } - char hrs_buf[3]= "00"; - char mins_buf[3]= "00"; - char secs_buf[3]= "00"; - my_safe_itoa(10, hrs, &hrs_buf[2]); - my_safe_itoa(10, mins, &mins_buf[2]); - my_safe_itoa(10, secs, &secs_buf[2]); - - my_safe_printf_stderr("%s:%s:%s UTC - mysqld got " SIGNAL_FMT " ;\n", - hrs_buf, mins_buf, secs_buf, sig); + my_safe_printf_stderr("[ERROR] mysqld got " SIGNAL_FMT " ;\n",sig); my_safe_printf_stderr("%s", "This could be because you hit a bug. It is also possible that this binary\n" "or one of the libraries it was linked against is corrupt, improperly built,\n" - "or misconfigured. This error can also be caused by malfunctioning hardware.\n"); + "or misconfigured. This error can also be caused by malfunctioning hardware.\n\n"); + + my_safe_printf_stderr("%s", + "To report this bug, see http://kb.askmonty.org/en/reporting-bugs\n\n"); my_safe_printf_stderr("%s", "We will try our best to scrape up some info that will hopefully help\n" "diagnose the problem, but since we have already crashed, \n" "something is definitely wrong and this may fail.\n\n"); + set_server_version(); my_safe_printf_stderr("Server version: %s\n", server_version); my_safe_printf_stderr("key_buffer_size=%lu\n", @@ -153,7 +155,7 @@ extern "C" sig_handler handle_fatal_signal(int sig) #endif /* HAVE_LINUXTHREADS */ #ifdef HAVE_STACKTRACE - THD *thd=current_thd; + thd= current_thd; if (opt_stack_trace) { @@ -268,15 +270,19 @@ extern "C" sig_handler handle_fatal_signal(int sig) if (test_flags & TEST_CORE_ON_SIGNAL) { my_safe_printf_stderr("%s", "Writing a core file\n"); + fflush(stderr); my_write_core(sig); } #endif +end: #ifndef __WIN__ /* Quit, without running destructors (etc.) On Windows, do not terminate, but pass control to exception filter. */ _exit(1); // Using _exit(), since exit() is not async signal safe +#else + return; #endif } diff --git a/sql/slave.cc b/sql/slave.cc index 98b75bc6dad..2b73cad1d7b 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2927,9 +2927,8 @@ pthread_handler_t handle_slave_io(void *arg) if (init_slave_thread(thd, SLAVE_THD_IO)) { mysql_cond_broadcast(&mi->start_cond); - mysql_mutex_unlock(&mi->run_lock); sql_print_error("Failed during slave I/O thread initialization"); - goto err; + goto err_during_init; } mysql_mutex_lock(&LOCK_thread_count); threads.append(thd); @@ -3232,6 +3231,7 @@ err: thd_proc_info(thd, "Waiting for slave mutex on exit"); mysql_mutex_lock(&mi->run_lock); +err_during_init: /* Forget the relay log's format */ delete mi->rli.relay_log.description_event_for_queue; mi->rli.relay_log.description_event_for_queue= 0; @@ -3357,10 +3357,9 @@ pthread_handler_t handle_slave_sql(void *arg) will be stuck if we fail here */ mysql_cond_broadcast(&rli->start_cond); - mysql_mutex_unlock(&rli->run_lock); rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, "Failed during slave thread initialization"); - goto err; + goto err_during_init; } thd->init_for_queries(); thd->temporary_tables = rli->save_temporary_tables; // restore temp tables @@ -3613,6 +3612,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ thd->reset_db(NULL, 0); thd_proc_info(thd, "Waiting for slave mutex on exit"); mysql_mutex_lock(&rli->run_lock); +err_during_init: /* We need data_lock, at least to wake up any waiting master_pos_wait() */ mysql_mutex_lock(&rli->data_lock); DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 92747066121..15c3999be54 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -8399,22 +8399,9 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, ulong client_capabilities= uint2korr(net->read_pos); if (client_capabilities & CLIENT_PROTOCOL_41) { - if (pkt_len < 32) + if (pkt_len < 4) return packet_error; client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16; - thd->max_client_packet_length= uint4korr(net->read_pos+4); - DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8])); - if (thd_init_client_charset(thd, (uint) net->read_pos[8])) - return packet_error; - thd->update_charset(); - end= (char*) net->read_pos + 32; - } - else - { - if (pkt_len < 5) - return packet_error; - thd->max_client_packet_length= uint3korr(net->read_pos+2); - end= (char*) net->read_pos+5; } /* Disable those bits which are not supported by the client. */ @@ -8446,6 +8433,28 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, } } + if (client_capabilities & CLIENT_PROTOCOL_41) + { + if (pkt_len < 32) + return packet_error; + thd->max_client_packet_length= uint4korr(net->read_pos+4); + DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8])); + if (thd_init_client_charset(thd, (uint) net->read_pos[8])) + return packet_error; + thd->update_charset(); + end= (char*) net->read_pos+32; + } + else + { + if (pkt_len < 5) + return packet_error; + thd->max_client_packet_length= uint3korr(net->read_pos+2); + end= (char*) net->read_pos+5; + } + + if (end >= (char*) net->read_pos+ pkt_len +2) + return packet_error; + if (thd->client_capabilities & CLIENT_IGNORE_SPACE) thd->variables.sql_mode|= MODE_IGNORE_SPACE; if (thd->client_capabilities & CLIENT_INTERACTIVE) diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index f01e279333d..5897d74582a 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -935,6 +935,11 @@ bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, DBUG_RETURN(TRUE); } mysql_mutex_unlock(&LOCK_global_system_variables); + if (!key_cache->key_cache_inited) + { + my_error(ER_UNKNOWN_KEY_CACHE, MYF(0), key_cache_name->str); + DBUG_RETURN(true); + } check_opt.key_cache= key_cache; DBUG_RETURN(mysql_admin_table(thd, tables, &check_opt, "assign_to_keycache", TL_READ_NO_INSERT, 0, 0, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 1d215f5aa40..3167cb7363d 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1923,14 +1923,15 @@ TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, t_name= table->table_name; t_alias= table->alias; +retry: DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name)); - for (;;) + for (TABLE_LIST *tl= table_list;;) { /* Table is unique if it is present only once in the global list of tables and once in the list of table locks. */ - if (! (res= find_table_in_global_list(table_list, d_name, t_name))) + if (! (res= find_table_in_global_list(tl, d_name, t_name))) break; /* Skip if same underlying table. */ @@ -1961,10 +1962,23 @@ TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, (exclude_from_table_unique_test) or prelocking placeholder. */ next: - table_list= res->next_global; + tl= res->next_global; DBUG_PRINT("info", ("found same copy of table or table which we should skip")); } + if (res && res->belong_to_derived) + { + /* Try to fix */ + TABLE_LIST *derived= res->belong_to_derived; + if (derived->is_merged_derived()) + { + DBUG_PRINT("info", + ("convert merged to materialization to resolve the conflict")); + derived->change_refs_to_fields(); + derived->set_materialized_derived(); + } + goto retry; + } DBUG_RETURN(res); } @@ -7363,11 +7377,16 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, if (!(eq_cond= new Item_func_eq(item_ident_1, item_ident_2))) goto err; /* Out of memory. */ + if (field_1 && field_1->vcol_info) + field_1->table->mark_virtual_col(field_1); + if (field_2 && field_2->vcol_info) + field_2->table->mark_virtual_col(field_2); + /* Add the new equi-join condition to the ON clause. Notice that fix_fields() is applied to all ON conditions in setup_conds() so we don't do it here. - */ + */ add_join_on((table_ref_1->outer_join & JOIN_TYPE_RIGHT ? table_ref_1 : table_ref_2), eq_cond); @@ -8085,7 +8104,8 @@ bool setup_tables(THD *thd, Name_resolution_context *context, while ((table_list= ti++)) { TABLE *table= table_list->table; - table->pos_in_table_list= table_list; + if (table) + table->pos_in_table_list= table_list; if (first_select_table && table_list->top_table() == first_select_table) { @@ -8098,7 +8118,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context, { table_list->jtbm_table_no= tablenr; } - else + else if (table) { table->pos_in_table_list= table_list; setup_table_map(table, table_list, tablenr); diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 0a1185a9924..9c86b2838c4 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1463,10 +1463,10 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", In case the wait time can't be determined there is an upper limit which causes try_lock() to abort with a time out. - The 'TRUE' parameter indicate that the lock is allowed to timeout + The 'TIMEOUT' parameter indicate that the lock is allowed to timeout */ - if (try_lock(thd, Query_cache::WAIT)) + if (try_lock(thd, Query_cache::TIMEOUT)) DBUG_VOID_RETURN; if (query_cache_size == 0) { @@ -1674,6 +1674,17 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length) if (is_disabled() || thd->locked_tables_mode || thd->variables.query_cache_type == 0) goto err; + + /* + The following can only happen for prepared statements that was found + during parsing or later that the query was not cacheable. + */ + if (!thd->lex->safe_to_cache_query) + { + DBUG_PRINT("qcache", ("SELECT is non-cacheable")); + goto err; + } + DBUG_ASSERT(query_cache_size != 0); // otherwise cache would be disabled thd->query_cache_is_applicable= 1; @@ -1959,6 +1970,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", faster. */ thd->query_cache_is_applicable= 0; // Query can't be cached + thd->lex->safe_to_cache_query= 0; // For prepared statements BLOCK_UNLOCK_RD(query_block); DBUG_RETURN(-1); } @@ -1975,6 +1987,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", table_list.db, table_list.alias)); unlock(); thd->query_cache_is_applicable= 0; // Query can't be cached + thd->lex->safe_to_cache_query= 0; // For prepared statements BLOCK_UNLOCK_RD(query_block); DBUG_RETURN(-1); // Privilege error } @@ -1984,6 +1997,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", table_list.db, table_list.alias)); BLOCK_UNLOCK_RD(query_block); thd->query_cache_is_applicable= 0; // Query can't be cached + thd->lex->safe_to_cache_query= 0; // For prepared statements goto err_unlock; // Parse query } #endif /*!NO_EMBEDDED_ACCESS_CHECKS*/ @@ -2007,7 +2021,13 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", table->key_length()); } else + { + /* + As this can change from call to call, don't reset set + thd->lex->safe_to_cache_query + */ thd->query_cache_is_applicable= 0; // Query can't be cached + } /* End the statement transaction potentially started by engine. */ trans_rollback_stmt(thd); goto err_unlock; // Parse query @@ -3901,6 +3921,7 @@ Query_cache::process_and_count_tables(THD *thd, TABLE_LIST *tables_used, DBUG_PRINT("qcache", ("Don't cache statement as it refers to " "tables with column privileges.")); thd->query_cache_is_applicable= 0; // Query can't be cached + thd->lex->safe_to_cache_query= 0; // For prepared statements DBUG_RETURN(0); } #endif @@ -4037,6 +4058,10 @@ my_bool Query_cache::ask_handler_allowance(THD *thd, { DBUG_PRINT("qcache", ("Handler does not allow caching for %s.%s", tables_used->db, tables_used->alias)); + /* + As this can change from call to call, don't reset set + thd->lex->safe_to_cache_query + */ thd->query_cache_is_applicable= 0; // Query can't be cached DBUG_RETURN(1); } diff --git a/sql/sql_cache.h b/sql/sql_cache.h index 9d713d012f5..134fd055110 100644 --- a/sql/sql_cache.h +++ b/sql/sql_cache.h @@ -443,8 +443,8 @@ protected: uint def_query_hash_size = QUERY_CACHE_DEF_QUERY_HASH_SIZE, uint def_table_hash_size = QUERY_CACHE_DEF_TABLE_HASH_SIZE); - bool is_disabled(void) { return m_cache_status != OK; } - bool is_disable_in_progress(void) + inline bool is_disabled(void) { return m_cache_status != OK; } + inline bool is_disable_in_progress(void) { return m_cache_status == DISABLE_REQUEST; } /* initialize cache (mutex) */ diff --git a/sql/sql_class.h b/sql/sql_class.h index 2538e73572a..980189ae9e0 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -585,12 +585,15 @@ typedef struct system_status_var ulong ha_read_prev_count; ulong ha_read_rnd_count; ulong ha_read_rnd_next_count; + ulong ha_read_rnd_deleted_count; /* This number doesn't include calls to the default implementation and calls made by range access. The intent is to count only calls made by BatchedKeyAccess. */ ulong ha_multi_range_read_init_count; + ulong ha_mrr_extra_key_sorts; + ulong ha_mrr_extra_rowid_sorts; ulong ha_rollback_count; ulong ha_update_count; @@ -599,6 +602,8 @@ typedef struct system_status_var ulong ha_tmp_update_count; ulong ha_tmp_write_count; ulong ha_prepare_count; + ulong ha_pushed_index_cond_checks; + ulong ha_pushed_index_cond_filtered; ulong ha_discover_count; ulong ha_savepoint_count; ulong ha_savepoint_rollback_count; @@ -4217,10 +4222,17 @@ inline int handler::ha_ft_read(uchar *buf) inline int handler::ha_rnd_next(uchar *buf) { MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, TRUE); - increment_statistics(&SSV::ha_read_rnd_next_count); int error= rnd_next(buf); if (!error) + { update_rows_read(); + increment_statistics(&SSV::ha_read_rnd_next_count); + } + else if (error == HA_ERR_RECORD_DELETED) + increment_statistics(&SSV::ha_read_rnd_deleted_count); + else + increment_statistics(&SSV::ha_read_rnd_next_count); + table->status=error ? STATUS_NOT_FOUND: 0; MYSQL_READ_ROW_DONE(error); return error; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index f48724236d4..ff88bf7c0f8 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -76,7 +76,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE)) DBUG_RETURN(TRUE); - if (!table_list->updatable) + if (!table_list->single_table_updatable()) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE"); DBUG_RETURN(TRUE); @@ -476,7 +476,8 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) setup_conds(thd, table_list, select_lex->leaf_tables, conds) || setup_ftfuncs(select_lex)) DBUG_RETURN(TRUE); - if (!table_list->updatable || check_key_in_view(thd, table_list)) + if (!table_list->single_table_updatable() || + check_key_in_view(thd, table_list)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE"); DBUG_RETURN(TRUE); @@ -572,7 +573,7 @@ int mysql_multi_delete_prepare(THD *thd) DBUG_RETURN(TRUE); } - if (!target_tbl->correspondent_table->updatable || + if (!target_tbl->correspondent_table->single_table_updatable() || check_key_in_view(thd, target_tbl->correspondent_table)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 13985becff7..9f06c99c472 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -483,7 +483,7 @@ bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived) return mysql_derived_prepare(thd, lex, derived); if (!derived->is_multitable()) { - if (!derived->updatable) + if (!derived->single_table_updatable()) return derived->create_field_translation(thd); if (derived->merge_underlying_list) { @@ -750,7 +750,7 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived) if (!derived->is_merged_derived()) { JOIN *join= first_select->join; - unit->set_limit(first_select); + unit->set_limit(unit->global_parameters); unit->optimized= TRUE; if ((res= join->optimize())) goto err; @@ -865,7 +865,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) } else { - unit->set_limit(first_select); + unit->set_limit(unit->global_parameters); if (unit->select_limit_cnt == HA_POS_ERROR) first_select->options&= ~OPTION_FOUND_ROWS; diff --git a/sql/sql_expression_cache.h b/sql/sql_expression_cache.h index 32aecc61dc9..48a8e33a787 100644 --- a/sql/sql_expression_cache.h +++ b/sql/sql_expression_cache.h @@ -1,3 +1,19 @@ +/* + Copyright (c) 2010, 2011, Monty Program 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 */ + #ifndef SQL_EXPRESSION_CACHE_INCLUDED #define SQL_EXPRESSION_CACHE_INCLUDED diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index c7423d9bada..2209a62d7ed 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -118,7 +118,8 @@ static bool check_view_insertability(THD *thd, TABLE_LIST *view); */ bool check_view_single_update(List<Item> &fields, List<Item> *values, - TABLE_LIST *view, table_map *map) + TABLE_LIST *view, table_map *map, + bool insert) { /* it is join view => we need to find the table for update */ List_iterator_fast<Item> it(fields); @@ -156,6 +157,14 @@ bool check_view_single_update(List<Item> &fields, List<Item> *values, */ tbl->table->insert_values= view->table->insert_values; view->table= tbl->table; + if (!tbl->single_table_updatable()) + { + if (insert) + my_error(ER_NON_INSERTABLE_TABLE, MYF(0), view->alias, "INSERT"); + else + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), view->alias, "UPDATE"); + return TRUE; + } *map= tables; return FALSE; @@ -200,7 +209,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, { TABLE *table= table_list->table; - if (!table_list->updatable) + if (!table_list->single_table_updatable()) { my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias, "INSERT"); return -1; @@ -276,7 +285,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, if (check_view_single_update(fields, fields_and_values_from_different_maps ? (List<Item>*) 0 : &values, - table_list, map)) + table_list, map, true)) return -1; table= table_list->table; } @@ -363,7 +372,7 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list, if (insert_table_list->is_view() && insert_table_list->is_merged_derived() && check_view_single_update(update_fields, &update_values, - insert_table_list, map)) + insert_table_list, map, false)) return -1; if (table->timestamp_field) @@ -1255,7 +1264,7 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, bool insert_into_view= (table_list->view != 0); DBUG_ENTER("mysql_prepare_insert_check_table"); - if (!table_list->updatable) + if (!table_list->single_table_updatable()) { my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias, "INSERT"); DBUG_RETURN(TRUE); diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 3600bbbb65f..f4fe8790bf7 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -899,6 +899,8 @@ int JOIN_CACHE::alloc_buffer() curr_buff_space_sz+= cache->get_join_buffer_size(); } } + curr_min_buff_space_sz+= min_buff_size; + curr_buff_space_sz+= buff_size; if (curr_min_buff_space_sz > join_buff_space_limit || (curr_buff_space_sz > join_buff_space_limit && @@ -2110,16 +2112,6 @@ enum_nested_loop_state JOIN_CACHE::join_records(bool skip_last) if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS) goto finish; } - if (outer_join_first_inner) - { - /* - All null complemented rows have been already generated for all - outer records from join buffer. Restore the state of the - first_unmatched values to 0 to avoid another null complementing. - */ - for (tab= join_tab->first_inner; tab <= join_tab->last_inner; tab++) - tab->first_unmatched= 0; - } if (skip_last) { @@ -2132,6 +2124,16 @@ enum_nested_loop_state JOIN_CACHE::join_records(bool skip_last) } finish: + if (outer_join_first_inner) + { + /* + All null complemented rows have been already generated for all + outer records from join buffer. Restore the state of the + first_unmatched values to 0 to avoid another null complementing. + */ + for (tab= join_tab->first_inner; tab <= join_tab->last_inner; tab++) + tab->first_unmatched= 0; + } restore_last_record(); reset(TRUE); DBUG_PRINT("exit", ("rc: %d", rc)); @@ -2575,6 +2577,15 @@ void JOIN_CACHE::print_explain_comment(String *str) str->append(STRING_WITH_LEN(")")); } +/** + get thread handle. +*/ + +THD *JOIN_CACHE::thd() +{ + return join->thd; +} + static void add_mrr_explain_info(String *str, uint mrr_mode, handler *file) { @@ -4014,7 +4025,11 @@ bool bka_skip_index_tuple(range_seq_t rseq, range_id_t range_info) { DBUG_ENTER("bka_skip_index_tuple"); JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) rseq; - bool res= cache->skip_index_tuple(range_info); + THD *thd= cache->thd(); + bool res; + status_var_increment(thd->status_var.ha_pushed_index_cond_checks); + if ((res= cache->skip_index_tuple(range_info))) + status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); DBUG_RETURN(res); } @@ -4489,7 +4504,12 @@ bool bkah_skip_index_tuple(range_seq_t rseq, range_id_t range_info) { DBUG_ENTER("bka_unique_skip_index_tuple"); JOIN_CACHE_BKAH *cache= (JOIN_CACHE_BKAH *) rseq; - DBUG_RETURN(cache->skip_index_tuple(range_info)); + THD *thd= cache->thd(); + bool res; + status_var_increment(thd->status_var.ha_pushed_index_cond_checks); + if ((res= cache->skip_index_tuple(range_info))) + status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); + DBUG_RETURN(res); } diff --git a/sql/sql_join_cache.h b/sql/sql_join_cache.h index c153689bb99..6953f6881ee 100644 --- a/sql/sql_join_cache.h +++ b/sql/sql_join_cache.h @@ -1,4 +1,20 @@ /* + Copyright (c) 2011, 2012, Monty Program 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 */ + +/* This file contains declarations for implementations of block based join algorithms */ @@ -550,7 +566,7 @@ public: BNL_JOIN_ALG, /* Block Nested Loop Join algorithm */ BNLH_JOIN_ALG, /* Block Nested Loop Hash Join algorithm */ BKA_JOIN_ALG, /* Batched Key Access Join algorithm */ - BKAH_JOIN_ALG, /* Batched Key Access with Hash Table Join Algorithm */ + BKAH_JOIN_ALG /* Batched Key Access with Hash Table Join Algorithm */ }; /* @@ -643,6 +659,8 @@ public: /* Add a comment on the join algorithm employed by the join cache */ virtual void print_explain_comment(String *str); + THD *thd(); + virtual ~JOIN_CACHE() {} void reset_join(JOIN *j) { join= j; } void free() diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 04de1325480..56e05c3dcad 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2847,7 +2847,7 @@ void st_select_lex_unit::set_limit(st_select_lex *sl) DBUG_ASSERT(fix_fields_successful); } - val= fix_fields_successful ? item->val_uint() : HA_POS_ERROR; + val= fix_fields_successful ? item->val_uint() : 0; } else val= ULL(0); @@ -3167,6 +3167,7 @@ void LEX::cleanup_after_one_table_open() if (all_selects_list != &select_lex) { derived_tables= 0; + select_lex.exclude_from_table_unique_test= false; /* cleunup underlying units (units of VIEW) */ for (SELECT_LEX_UNIT *un= select_lex.first_inner_unit(); un; diff --git a/sql/sql_lifo_buffer.h b/sql/sql_lifo_buffer.h index 34f9624436d..5b7ddf35474 100644 --- a/sql/sql_lifo_buffer.h +++ b/sql/sql_lifo_buffer.h @@ -1,3 +1,19 @@ +/* + Copyright (c) 2010, 2011, Monty Program 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 */ + /** @defgroup Bi-directional LIFO buffers used by DS-MRR implementation @{ diff --git a/sql/sql_list.h b/sql/sql_list.h index 7bd72cba359..6cc05ff1f62 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -260,7 +260,12 @@ public: last= &first; return tmp->info; } - inline void disjoin(base_list *list) + /* + Remove from this list elements that are contained in the passed list. + We assume that the passed list is a tail of this list (that is, the whole + list_node* elements are shared). + */ + inline void disjoin(const base_list *list) { list_node **prev= &first; list_node *node= first; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index aab9ea76499..33d1741b5ec 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -235,7 +235,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, INSERT_ACL | UPDATE_ACL, FALSE)) DBUG_RETURN(-1); if (!table_list->table || // do not suport join view - !table_list->updatable || // and derived tables + !table_list->single_table_updatable() || // and derived tables check_key_in_view(thd, table_list)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD"); diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc index 221ba56130a..e9ac55730d3 100644 --- a/sql/sql_manager.cc +++ b/sql/sql_manager.cc @@ -43,6 +43,7 @@ static struct handler_cb * volatile cb_list; bool mysql_manager_submit(void (*action)()) { bool result= FALSE; + DBUG_ASSERT(manager_thread_in_use); struct handler_cb * volatile *cb; mysql_mutex_lock(&LOCK_manager); cb= &cb_list; @@ -74,8 +75,9 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) pthread_detach_this_thread(); manager_thread = pthread_self(); + mysql_cond_init(key_COND_manager, &COND_manager,NULL); + mysql_mutex_init(key_LOCK_manager, &LOCK_manager, NULL); manager_thread_in_use = 1; - for (;;) { mysql_mutex_lock(&LOCK_manager); @@ -122,6 +124,8 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) } } manager_thread_in_use = 0; + mysql_mutex_destroy(&LOCK_manager); + mysql_cond_destroy(&COND_manager); DBUG_LEAVE; // Can't use DBUG_RETURN after my_thread_end my_thread_end(); return (NULL); @@ -149,14 +153,14 @@ void stop_handle_manager() { DBUG_ENTER("stop_handle_manager"); abort_manager = true; - mysql_mutex_lock(&LOCK_manager); if (manager_thread_in_use) { + mysql_mutex_lock(&LOCK_manager); DBUG_PRINT("quit", ("initiate shutdown of handle manager thread: 0x%lx", (ulong)manager_thread)); mysql_cond_signal(&COND_manager); + mysql_mutex_unlock(&LOCK_manager); } - mysql_mutex_unlock(&LOCK_manager); DBUG_VOID_RETURN; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7092ea3bb6c..167abfeedc6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6674,13 +6674,23 @@ static uint kill_threads_for_user(THD *thd, LEX_USER *user, if (!threads_to_kill.is_empty()) { List_iterator_fast<THD> it(threads_to_kill); - THD *ptr; - while ((ptr= it++)) + THD *next_ptr; + THD *ptr= it++; + do { ptr->awake(kill_signal); + /* + Careful here: The list nodes are allocated on the memroots of the + THDs to be awakened. + But those THDs may be terminated and deleted as soon as we release + LOCK_thd_data, which will make the list nodes invalid. + Since the operation "it++" dereferences the "next" pointer of the + previous list node, we need to do this while holding LOCK_thd_data. + */ + next_ptr= it++; mysql_mutex_unlock(&ptr->LOCK_thd_data); (*rows)++; - } + } while ((ptr= next_ptr)); } DBUG_RETURN(0); } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index f5a2f409dfc..da9dcc053cf 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1365,7 +1365,7 @@ static int mysql_test_update(Prepared_statement *stmt, if (table_list->handle_derived(thd->lex, DT_PREPARE)) goto error; - if (!table_list->updatable) + if (!table_list->single_table_updatable()) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE"); goto error; @@ -1439,7 +1439,7 @@ static bool mysql_test_delete(Prepared_statement *stmt, if (mysql_handle_derived(thd->lex, DT_PREPARE)) goto error; - if (!table_list->updatable) + if (!table_list->single_table_updatable()) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE"); goto error; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f22510bb2b7..4c02f19926f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -131,7 +131,8 @@ static COND *build_equal_items(THD *thd, COND *cond, COND_EQUAL *inherited, List<TABLE_LIST> *join_list, COND_EQUAL **cond_equal_ref); -static COND* substitute_for_best_equal_field(COND *cond, +static COND* substitute_for_best_equal_field(JOIN_TAB *context_tab, + COND *cond, COND_EQUAL *cond_equal, void *table_join_idx); static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, @@ -1254,7 +1255,8 @@ JOIN::optimize() */ if (conds) { - conds= substitute_for_best_equal_field(conds, cond_equal, map2table); + conds= substitute_for_best_equal_field(NO_PARTICULAR_TAB, conds, + cond_equal, map2table); conds->update_used_tables(); DBUG_EXECUTE("where", print_where(conds, @@ -1271,7 +1273,8 @@ JOIN::optimize() { if (*tab->on_expr_ref) { - *tab->on_expr_ref= substitute_for_best_equal_field(*tab->on_expr_ref, + *tab->on_expr_ref= substitute_for_best_equal_field(NO_PARTICULAR_TAB, + *tab->on_expr_ref, tab->cond_equal, map2table); (*tab->on_expr_ref)->update_used_tables(); @@ -1292,9 +1295,20 @@ JOIN::optimize() Item *ref_item= *ref_item_ptr; if (!ref_item->used_tables() && !(select_options & SELECT_DESCRIBE)) continue; - COND_EQUAL *equals= tab->first_inner ? tab->first_inner->cond_equal : - cond_equal; - ref_item= substitute_for_best_equal_field(ref_item, equals, map2table); + COND_EQUAL *equals= cond_equal; + JOIN_TAB *first_inner= tab->first_inner; + while (equals) + { + ref_item= substitute_for_best_equal_field(tab, ref_item, + equals, map2table); + if (first_inner) + { + equals= first_inner->cond_equal; + first_inner= first_inner->first_upper; + } + else + equals= 0; + } ref_item->update_used_tables(); if (*ref_item_ptr != ref_item) { @@ -3596,6 +3610,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, for (i= 0; i < join->table_count ; i++) records*= join->best_positions[i].records_read ? (ha_rows)join->best_positions[i].records_read : 1; + set_if_smaller(records, unit->select_limit_cnt); join->select_lex->increase_derived_records(records); } } @@ -8997,7 +9012,7 @@ void revise_cache_usage(JOIN_TAB *join_tab) first_inner; first_inner= first_inner->first_upper) { - for (tab= end_tab-1; tab >= first_inner; tab--) + for (tab= end_tab; tab >= first_inner; tab--) set_join_cache_denial(tab); end_tab= first_inner; } @@ -9005,7 +9020,7 @@ void revise_cache_usage(JOIN_TAB *join_tab) else if (join_tab->first_sj_inner_tab) { first_inner= join_tab->first_sj_inner_tab; - for (tab= join_tab-1; tab >= first_inner; tab--) + for (tab= join_tab; tab >= first_inner; tab--) { set_join_cache_denial(tab); } @@ -9247,6 +9262,9 @@ uint check_join_cache_usage(JOIN_TAB *tab, if (tab->use_quick == 2) goto no_join_cache; + + if (tab->table->map & join->complex_firstmatch_tables) + goto no_join_cache; /* Don't use join cache if we're inside a join tab range covered by LooseScan @@ -9304,7 +9322,7 @@ uint check_join_cache_usage(JOIN_TAB *tab, Check whether table tab and the previous one belong to the same nest of inner tables and if so do not use join buffer when joining table tab. */ - if (tab->first_inner) + if (tab->first_inner && tab != tab->first_inner) { for (JOIN_TAB *first_inner= tab[-1].first_inner; first_inner; @@ -9314,7 +9332,7 @@ uint check_join_cache_usage(JOIN_TAB *tab, goto no_join_cache; } } - else if (tab->first_sj_inner_tab && + else if (tab->first_sj_inner_tab && tab != tab->first_sj_inner_tab && tab->first_sj_inner_tab == tab[-1].first_sj_inner_tab) goto no_join_cache; } @@ -9457,7 +9475,7 @@ void check_join_cache_usage_for_tables(JOIN *join, ulonglong options, { tab->used_join_cache_level= join->max_allowed_join_cache_level; } - + uint idx= join->const_tables; for (tab= first_linear_tab(join, WITHOUT_CONST_TABLES); tab; @@ -9542,6 +9560,8 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after) bool statistics= test(!(join->select_options & SELECT_DESCRIBE)); bool sorted= 1; + join->complex_firstmatch_tables= table_map(0); + if (!join->select_lex->sj_nests.is_empty() && setup_semijoin_dups_elimination(join, options, no_jbuf_after)) DBUG_RETURN(TRUE); /* purecov: inspected */ @@ -10422,6 +10442,15 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, } + /* + Cleanup to avoid interference of calls of this function for + ORDER BY and GROUP BY + */ + for (JOIN_TAB *tab= join->join_tab + join->const_tables; + tab < join->join_tab + join->table_count; + tab++) + tab->cached_eq_ref_table= FALSE; + prev_ptr= &first_order; *simple_order= *join->join_tab[join->const_tables].on_expr_ref ? 0 : 1; @@ -10551,10 +10580,22 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables, if (send_row) { + /* + Set all tables to have NULL row. This is needed as we will be evaluating + HAVING condition. + */ List_iterator<TABLE_LIST> ti(tables); TABLE_LIST *table; while ((table= ti++)) - mark_as_null_row(table->table); // All fields are NULL + { + /* + Don't touch semi-join materialization tables, as the above join_free() + call has freed them (and HAVING clause can't have references to them + anyway). + */ + if (!table->is_jtbm()) + mark_as_null_row(table->table); // All fields are NULL + } if (having && !having->walk(&Item::clear_sum_processor, FALSE, NULL) && having->val_int() == 0) @@ -11582,7 +11623,7 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, else { TABLE_LIST *emb_nest; - head= item_equal->get_first(NULL); + head= item_equal->get_first(NO_PARTICULAR_TAB, NULL); it++; if ((emb_nest= embedding_sjm(head))) { @@ -11609,7 +11650,7 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, } /* - Check if "item_field=head" equality is already guaranteed to be true + Check if "field_item=head" equality is already guaranteed to be true on upper AND-levels. */ if (upper) @@ -11621,7 +11662,8 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, Item_equal_fields_iterator li(*item_equal); while ((item= li++) != field_item) { - if (item->find_item_equal(upper_levels) == upper) + if (embedding_sjm(item) == field_sjm && + item->find_item_equal(upper_levels) == upper) break; } } @@ -11691,6 +11733,7 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, return cond; } + /** Substitute every field reference in a condition by the best equal field and eliminate all multiple equality predicates. @@ -11705,6 +11748,9 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, After this the function retrieves all other conjuncted predicates substitute every field reference by the field reference to the first equal field or equal constant if there are any. + + @param context_tab Join tab that 'cond' will be attached to, or + NO_PARTICULAR_TAB. See notes above. @param cond condition to process @param cond_equal multiple equalities to take into consideration @param table_join_idx index to tables determining field preference @@ -11715,11 +11761,37 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, new fields in multiple equality item of lower levels. We want the order in them to comply with the order of upper levels. + context_tab may be used to specify which join tab `cond` will be + attached to. There are two possible cases: + + 1. context_tab != NO_PARTICULAR_TAB + We're doing substitution for an Item which will be evaluated in the + context of a particular item. For example, if the optimizer does a + ref access on "tbl1.key= expr" then + = equality substitution will be perfomed on 'expr' + = it is known in advance that 'expr' will be evaluated when + table t1 is accessed. + Note that in this kind of substution we never have to replace Item_equal + objects. For example, for + + t.key= func(col1=col2 AND col2=const) + + we will not build Item_equal or do equality substution (if we decide to, + this function will need to be fixed to handle it) + + 2. context_tab == NO_PARTICULAR_TAB + We're doing substitution in WHERE/ON condition, which is not yet + attached to any particular join_tab. We will use information about the + chosen join order to make "optimal" substitions, i.e. those that allow + to apply filtering as soon as possible. See eliminate_item_equal() and + Item_equal::get_first() for details. + @return The transformed condition */ -static COND* substitute_for_best_equal_field(COND *cond, +static COND* substitute_for_best_equal_field(JOIN_TAB *context_tab, + COND *cond, COND_EQUAL *cond_equal, void *table_join_idx) { @@ -11735,7 +11807,7 @@ static COND* substitute_for_best_equal_field(COND *cond, if (and_level) { cond_equal= &((Item_cond_and *) cond)->cond_equal; - cond_list->disjoin((List<Item> *) &cond_equal->current_level); + cond_list->disjoin((List<Item> *) &cond_equal->current_level);/* remove Item_equal objects from the AND. */ List_iterator_fast<Item_equal> it(cond_equal->current_level); while ((item_equal= it++)) @@ -11748,7 +11820,8 @@ static COND* substitute_for_best_equal_field(COND *cond, Item *item; while ((item= li++)) { - Item *new_item= substitute_for_best_equal_field(item, cond_equal, + Item *new_item= substitute_for_best_equal_field(context_tab, + item, cond_equal, table_join_idx); /* This works OK with PS/SP re-execution as changes are made to @@ -11795,7 +11868,8 @@ static COND* substitute_for_best_equal_field(COND *cond, List_iterator_fast<Item_equal> it(cond_equal->current_level); while((item_equal= it++)) { - cond= cond->transform(&Item::replace_equal_field, (uchar *) item_equal); + REPLACE_EQUAL_FIELD_ARG arg= {item_equal, context_tab}; + cond= cond->transform(&Item::replace_equal_field, (uchar *) &arg); } cond_equal= cond_equal->upper_levels; } @@ -12768,9 +12842,8 @@ optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list, multiple equality contains a constant. */ DBUG_EXECUTE("where", print_where(conds, "original", QT_ORDINARY);); - conds= build_equal_items(join->thd, conds, NULL, join_list, - &join->cond_equal); - DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY);); + conds= build_equal_items(join->thd, conds, NULL, join_list, cond_equal); + DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY);); /* change field = field to field = const for each found field = const */ propagate_cond_constants(thd, (I_List<COND_CMP> *) 0, conds, conds); @@ -15589,7 +15662,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) if (join_tab->loosescan_match_tab && join_tab->loosescan_match_tab->found_match) { - KEY *key= join_tab->table->key_info + join_tab->index; + KEY *key= join_tab->table->key_info + join_tab->loosescan_key; key_copy(join_tab->loosescan_buf, join_tab->table->record[0], key, join_tab->loosescan_key_len); skip_over= TRUE; @@ -15599,7 +15672,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) if (skip_over && !error) { - if(!key_cmp(join_tab->table->key_info[join_tab->index].key_part, + if(!key_cmp(join_tab->table->key_info[join_tab->loosescan_key].key_part, join_tab->loosescan_buf, join_tab->loosescan_key_len)) { /* @@ -18395,7 +18468,6 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, table->sort.io_cache= NULL; select->cleanup(); // filesort did select - tab->select= 0; table->quick_keys.clear_all(); // as far as we cleanup select->quick table->intersect_keys.clear_all(); table->sort.io_cache= tablesort_result_cache; @@ -21392,6 +21464,8 @@ static void print_table_array(THD *thd, (curr->nested_join && !(curr->nested_join->used_tables & ~eliminated_tables)))) { + /* as of 5.5, print_join doesnt put eliminated elements into array */ + DBUG_ASSERT(0); continue; } @@ -21417,6 +21491,21 @@ static void print_table_array(THD *thd, } +/* + Check if the passed table is + - a base table which was eliminated, or + - a join nest which only contained eliminated tables (and so was eliminated, + too) +*/ + +static bool is_eliminated_table(table_map eliminated_tables, TABLE_LIST *tbl) +{ + return eliminated_tables && + ((tbl->table && (tbl->table->map & eliminated_tables)) || + (tbl->nested_join && !(tbl->nested_join->used_tables & + ~eliminated_tables))); +} + /** Print joins from the FROM clause. @@ -21438,8 +21527,14 @@ static void print_join(THD *thd, uint non_const_tables= 0; for (TABLE_LIST *t= ti++; t ; t= ti++) - if (!t->optimized_away) + { + /* + See comment in print_table_array() about the second part of the + condition + */ + if (!t->optimized_away && !is_eliminated_table(eliminated_tables, t)) non_const_tables++; + } if (!non_const_tables) { str->append(STRING_WITH_LEN("dual")); @@ -21454,7 +21549,7 @@ static void print_join(THD *thd, TABLE_LIST *tmp, **t= table + (non_const_tables - 1); while ((tmp= ti++)) { - if (tmp->optimized_away) + if (tmp->optimized_away || is_eliminated_table(eliminated_tables, tmp)) continue; *t--= tmp; } diff --git a/sql/sql_select.h b/sql/sql_select.h index 644828fa08c..2f7d31de404 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -374,6 +374,12 @@ typedef struct st_join_table { /* Buffer to save index tuple to be able to skip duplicates */ uchar *loosescan_buf; + /* + Index used by LooseScan (we store it here separately because ref access + stores it in tab->ref.key, while range scan stores it in tab->index, etc) + */ + uint loosescan_key; + /* Length of key tuple (depends on #keyparts used) to store in the above */ uint loosescan_key_len; @@ -986,6 +992,13 @@ public: /* We also maintain a stack of join optimization states in * join->positions[] */ /******* Join optimization state members end *******/ + + /* + Tables within complex firstmatch ranges (i.e. those where inner tables are + interleaved with outer tables). Join buffering cannot be used for these. + */ + table_map complex_firstmatch_tables; + /* The cost of best complete join plan found so far during optimization, after optimization phase - cost of picked join order (not taking into @@ -1440,6 +1453,7 @@ public: virtual ~store_key() {} /** Not actually needed */ virtual enum Type type() const=0; virtual const char *name() const=0; + virtual bool store_key_is_const() { return false; } /** @brief sets ignore truncation warnings mode and calls the real copy method @@ -1593,6 +1607,7 @@ public: enum Type type() const { return CONST_ITEM_STORE_KEY; } const char *name() const { return "const"; } + bool store_key_is_const() { return true; } protected: enum store_key_result copy_inner() @@ -1688,7 +1703,7 @@ void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab, double *outer_rec_count, double *reopt_cost); Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field, bool *inherited_fl); -bool test_if_ref(COND *root_cond, +extern bool test_if_ref(Item *, Item_field *left_item,Item *right_item); inline bool optimizer_flag(THD *thd, uint flag) diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 584ebd904a8..9b6d3a8dda5 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -964,6 +964,7 @@ bool st_select_lex::cleanup() } non_agg_fields.empty(); inner_refs_list.empty(); + exclude_from_table_unique_test= FALSE; DBUG_RETURN(error); } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 99cac9f40e7..5fa30c91417 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -304,7 +304,7 @@ int mysql_update(THD *thd, thd_proc_info(thd, "init"); table= table_list->table; - if (!table_list->updatable) + if (!table_list->single_table_updatable()) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE"); DBUG_RETURN(1); @@ -1246,7 +1246,7 @@ int mysql_multi_update_prepare(THD *thd) /* if table will be updated then check that it is unique */ if (table->map & tables_for_update) { - if (!tl->updatable || check_key_in_view(thd, tl)) + if (!tl->single_table_updatable() || check_key_in_view(thd, tl)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), tl->alias, "UPDATE"); DBUG_RETURN(TRUE); diff --git a/sql/table.cc b/sql/table.cc index 53e5872bfe4..8f4f034bf2a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4053,6 +4053,28 @@ bool TABLE_LIST::prep_where(THD *thd, Item **conds, DBUG_RETURN(FALSE); } +/** + Check that table/view is updatable and if it has single + underlying tables/views it is also updatable + + @return Result of the check. +*/ + +bool TABLE_LIST::single_table_updatable() +{ + if (!updatable) + return false; + if (view_tables && view_tables->elements == 1) + { + /* + We need to check deeply only single table views. Multi-table views + will be turned to multi-table updates and then checked by leaf tables + */ + return view_tables->head()->single_table_updatable(); + } + return true; +} + /* Merge ON expressions for a view @@ -4702,6 +4724,36 @@ bool TABLE_LIST::prepare_security(THD *thd) DBUG_RETURN(FALSE); } +#ifndef DBUG_OFF +void TABLE_LIST::set_check_merged() +{ + DBUG_ASSERT(derived); + /* + It is not simple to check all, but at least this should be checked: + this select is not excluded or the exclusion came from above. + */ + DBUG_ASSERT(!derived->first_select()->exclude_from_table_unique_test || + derived->outer_select()-> + exclude_from_table_unique_test); +} +#endif + +void TABLE_LIST::set_check_materialized() +{ + DBUG_ASSERT(derived); + if (!derived->first_select()->exclude_from_table_unique_test) + derived->set_unique_exclude(); + else + { + /* + The subtree should be already excluded + */ + DBUG_ASSERT(!derived->first_select()->first_inner_unit() || + derived->first_select()->first_inner_unit()->first_select()-> + exclude_from_table_unique_test); + } +} + Natural_join_column::Natural_join_column(Field_translator *field_param, TABLE_LIST *tab) @@ -4828,6 +4880,7 @@ Item *Field_iterator_table::create_item(THD *thd) { select->non_agg_fields.push_back(item); item->marker= select->cur_pos_in_select_list; + select->set_non_agg_field_used(true); } return item; } @@ -5532,6 +5585,12 @@ void TABLE::mark_virtual_columns_for_write(bool insert_fl) Field **vfield_ptr, *tmp_vfield; bool bitmap_updated= FALSE; + if (!vfield) + return; + + if (!vfield) + return; + for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++) { tmp_vfield= *vfield_ptr; @@ -6293,8 +6352,9 @@ bool TABLE_LIST::init_derived(THD *thd, bool init_view) */ if (is_materialized_derived()) { - unit->master_unit()->set_unique_exclude(); + set_check_materialized(); } + /* Create field translation for mergeable derived tables/views. For derived tables field translation can be created only after diff --git a/sql/table.h b/sql/table.h index a327d625387..77a7f8cf6a9 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1983,16 +1983,18 @@ struct TABLE_LIST inline void set_merged_derived() { derived_type= ((derived_type & DTYPE_MASK) | - DTYPE_TABLE | DTYPE_MERGE); + DTYPE_TABLE | DTYPE_MERGE); + set_check_merged(); } inline bool is_materialized_derived() { return (derived_type & DTYPE_MATERIALIZE); } - inline void set_materialized_derived() + void set_materialized_derived() { derived_type= ((derived_type & DTYPE_MASK) | - DTYPE_TABLE | DTYPE_MATERIALIZE); + DTYPE_TABLE | DTYPE_MATERIALIZE); + set_check_materialized(); } inline bool is_multitable() { @@ -2033,9 +2035,17 @@ struct TABLE_LIST int fetch_number_of_rows(); bool change_refs_to_fields(); + bool single_table_updatable(); + private: bool prep_check_option(THD *thd, uint8 check_opt_type); bool prep_where(THD *thd, Item **conds, bool no_where_clause); + void set_check_materialized(); +#ifndef DBUG_OFF + void set_check_merged(); +#else + inline void set_check_merged() {} +#endif /** See comments for set_metadata_id() */ enum enum_table_ref_type m_table_ref_type; /** See comments for set_metadata_id() */ diff --git a/sql/winservice.c b/sql/winservice.c index 51a5a07a820..1f41cf61ea4 100644 --- a/sql/winservice.c +++ b/sql/winservice.c @@ -1,4 +1,20 @@ /* + Copyright (c) 2011, 2012, Monty Program 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 */ + +/* Get Properties of an existing mysqld Windows service */ @@ -116,7 +132,7 @@ int get_mysql_service_properties(const wchar_t *bin_path, wcscat(mysqld_path, L".exe"); if(wcsicmp(file_part, L"mysqld.exe") != 0 && - wcsicmp(file_part, L"mysqld.exe") != 0 && + wcsicmp(file_part, L"mysqld-debug.exe") != 0 && wcsicmp(file_part, L"mysqld-nt.exe") != 0) { /* The service executable is not mysqld. */ @@ -244,4 +260,4 @@ int get_mysql_service_properties(const wchar_t *bin_path, end: LocalFree((HLOCAL)args); return retval; -}
\ No newline at end of file +} diff --git a/sql/winservice.h b/sql/winservice.h index 8957413783f..fca7b129de5 100644 --- a/sql/winservice.h +++ b/sql/winservice.h @@ -1,4 +1,20 @@ /*
+ Copyright (c) 2011, 2012, Monty Program 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 */
+
+/*
Extract properties of a windows service binary path
*/
#ifdef __cplusplus
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index b5ec94ba503..2c178fb7055 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1187,17 +1187,6 @@ int ha_archive::unpack_row(azio_stream *file_to_read, uchar *record) /* Copy null bits */ const uchar *ptr= record_buffer->buffer; - /* - Field::unpack() is not called when field is NULL. For VARCHAR - Field::unpack() only unpacks as much bytes as occupied by field - value. In these cases respective memory area on record buffer is - not initialized. - - These uninitialized areas may be accessed by CHECKSUM TABLE or - by optimizer using temporary table (BUG#12997905). We may remove - this memset() when they're fixed. - */ - memset(record, 0, table->s->reclength); memcpy(record, ptr, table->s->null_bytes); ptr+= table->s->null_bytes; for (Field **field=table->field ; *field ; field++) diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index e529ecbb7a0..04b5fd8d19d 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -252,7 +252,18 @@ IF(WITH_INNODB) SET(WITH_INNOBASE_STORAGE_ENGINE TRUE) ENDIF() + +# On solaris, reduce symbol visibility, so loader does not mix +# the same symbols from builtin innodb and from shared one. +# Only required for old GCC (3.4.3) that does not support hidden visibility +IF(CMAKE_SYSTEM_NAME MATCHES "SunOS" AND CMAKE_COMPILER_IS_GNUCC + AND NOT HAVE_VISIBILITY_HIDDEN) + SET(LINKER_SCRIPT "-Wl,-M${CMAKE_CURRENT_SOURCE_DIR}/plugin_exports") +ELSE() + SET(LINKER_SCRIPT) +ENDIF() + MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE MODULE_ONLY MODULE_OUTPUT_NAME ha_innodb - LINK_LIBRARIES ${ZLIB_LIBRARY}) + LINK_LIBRARIES ${ZLIB_LIBRARY} ${LINKER_SCRIPT}) diff --git a/storage/innobase/plugin_exports b/storage/innobase/plugin_exports new file mode 100644 index 00000000000..03b8cf8c217 --- /dev/null +++ b/storage/innobase/plugin_exports @@ -0,0 +1,11 @@ +{ + global: + _mysql_plugin_interface_version_; + _mysql_sizeof_struct_st_plugin_; + _mysql_plugin_declarations_; + thd_wait_service; + my_snprintf_service; + thd_alloc_service; + local: + *; +}; diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 0e319874837..585fe4a0492 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -2208,21 +2208,6 @@ int ha_maria::delete_row(const uchar * buf) return maria_delete(file, buf); } -C_MODE_START - -ICP_RESULT index_cond_func_maria(void *arg) -{ - ha_maria *h= (ha_maria*)arg; - if (h->end_range) - { - if (h->compare_key2(h->end_range) > 0) - return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */ - } - return h->pushed_idx_cond->val_int() ? ICP_MATCH : ICP_NO_MATCH; -} - -C_MODE_END - int ha_maria::index_read_map(uchar * buf, const uchar * key, key_part_map keypart_map, enum ha_rkey_function find_flag) @@ -2242,7 +2227,7 @@ int ha_maria::index_read_idx_map(uchar * buf, uint index, const uchar * key, /* Use the pushed index condition if it matches the index we're scanning */ end_range= NULL; if (index == pushed_idx_cond_keyno) - ma_set_index_cond_func(file, index_cond_func_maria, this); + ma_set_index_cond_func(file, handler_index_cond_check, this); error= maria_rkey(file, buf, index, key, keypart_map, find_flag); @@ -2323,7 +2308,7 @@ int ha_maria::index_init(uint idx, bool sorted) { active_index=idx; if (pushed_idx_cond_keyno == idx) - ma_set_index_cond_func(file, index_cond_func_maria, this); + ma_set_index_cond_func(file, handler_index_cond_check, this); return 0; } @@ -3754,7 +3739,7 @@ Item *ha_maria::idx_cond_push(uint keyno_arg, Item* idx_cond_arg) pushed_idx_cond= idx_cond_arg; in_range_check_pushed_down= TRUE; if (active_index == pushed_idx_cond_keyno) - ma_set_index_cond_func(file, index_cond_func_maria, this); + ma_set_index_cond_func(file, handler_index_cond_check, this); return NULL; } diff --git a/storage/maria/ma_checkpoint.c b/storage/maria/ma_checkpoint.c index addb014969a..2f5ba72a40e 100644 --- a/storage/maria/ma_checkpoint.c +++ b/storage/maria/ma_checkpoint.c @@ -913,6 +913,9 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon) */ } translog_unlock(); + if (state_copy == state_copies) + break; /* Nothing to do */ + /** We are going to flush these states. Before, all records describing how to undo such state must be @@ -937,13 +940,13 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon) if (translog_flush(state_copies_horizon)) goto err; /* now we have cached states and they are WAL-safe*/ - state_copies_end= state_copy; + state_copies_end= state_copy-1; state_copy= state_copies; } /* locate our state among these cached ones */ for ( ; state_copy->index != i; state_copy++) - DBUG_ASSERT(state_copy < state_copies_end); + DBUG_ASSERT(state_copy <= state_copies_end); /* OS file descriptors are ints which we stored in 4 bytes */ compile_time_assert(sizeof(int) <= 4); diff --git a/storage/maria/ma_servicethread.c b/storage/maria/ma_servicethread.c index 06abaa88ea1..e5c949a7571 100644 --- a/storage/maria/ma_servicethread.c +++ b/storage/maria/ma_servicethread.c @@ -1,3 +1,19 @@ +/* + Copyright (c) 2009, 2011, Monty Program 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 */ + #include "maria_def.h" #include "ma_servicethread.h" diff --git a/storage/maria/ma_servicethread.h b/storage/maria/ma_servicethread.h index 246e2302d0f..ed578d93c24 100644 --- a/storage/maria/ma_servicethread.h +++ b/storage/maria/ma_servicethread.h @@ -1,3 +1,19 @@ +/* + Copyright (c) 2009, 2011, Monty Program 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 */ + #include <my_pthread.h> enum ma_service_thread_state {THREAD_RUNNING, THREAD_DYING, THREAD_DEAD}; diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 9e92e9c6262..87fccb6f449 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1645,27 +1645,11 @@ int ha_myisam::delete_row(const uchar *buf) } -C_MODE_START - -ICP_RESULT index_cond_func_myisam(void *arg) -{ - ha_myisam *h= (ha_myisam*)arg; - if (h->end_range) - { - if (h->compare_key2(h->end_range) > 0) - return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */ - } - return (ICP_RESULT) test(h->pushed_idx_cond->val_int()); -} - -C_MODE_END - - int ha_myisam::index_init(uint idx, bool sorted) { active_index=idx; if (pushed_idx_cond_keyno == idx) - mi_set_index_cond_func(file, index_cond_func_myisam, this); + mi_set_index_cond_func(file, handler_index_cond_check, this); return 0; } @@ -1711,7 +1695,7 @@ int ha_myisam::index_read_idx_map(uchar *buf, uint index, const uchar *key, /* Use the pushed index condition if it matches the index we're scanning */ end_range= NULL; if (index == pushed_idx_cond_keyno) - mi_set_index_cond_func(file, index_cond_func_myisam, this); + mi_set_index_cond_func(file, handler_index_cond_check, this); res= mi_rkey(file, buf, index, key, keypart_map, find_flag); mi_set_index_cond_func(file, NULL, 0); return res; @@ -2267,7 +2251,7 @@ Item *ha_myisam::idx_cond_push(uint keyno_arg, Item* idx_cond_arg) pushed_idx_cond= idx_cond_arg; in_range_check_pushed_down= TRUE; if (active_index == pushed_idx_cond_keyno) - mi_set_index_cond_func(file, index_cond_func_myisam, this); + mi_set_index_cond_func(file, handler_index_cond_check, this); return NULL; } diff --git a/storage/myisam/mi_preload.c b/storage/myisam/mi_preload.c index 5c974cbea0e..767858a6ea0 100644 --- a/storage/myisam/mi_preload.c +++ b/storage/myisam/mi_preload.c @@ -53,6 +53,9 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves) if (!keys || !mi_is_any_key_active(key_map) || key_file_length == pos) DBUG_RETURN(0); + /* Preload into a non initialized key cache should never happen. */ + DBUG_ASSERT(share->key_cache->key_cache_inited); + block_length= keyinfo[0].block_length; if (ignore_leaves) diff --git a/storage/myisam/mi_rkey.c b/storage/myisam/mi_rkey.c index b1c0c0a4829..b70922b0505 100644 --- a/storage/myisam/mi_rkey.c +++ b/storage/myisam/mi_rkey.c @@ -158,7 +158,11 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, mi_yield_and_check_if_killed(info, inx)) { /* Aborted by user */ + DBUG_ASSERT(info->lastpos == HA_OFFSET_ERROR && + my_errno == HA_ERR_ABORTED_BY_USER); + res= ICP_ERROR; buf= 0; /* Fast abort */ + break; } } if (res == ICP_OUT_OF_RANGE) @@ -180,7 +184,7 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, } else { - DBUG_ASSERT(info->lastpos= HA_OFFSET_ERROR); + DBUG_ASSERT(info->lastpos == HA_OFFSET_ERROR); } } if (share->concurrent_insert) diff --git a/storage/oqgraph/graphcore.cc b/storage/oqgraph/graphcore.cc index 0b856ac253f..ba179989ea3 100644 --- a/storage/oqgraph/graphcore.cc +++ b/storage/oqgraph/graphcore.cc @@ -414,7 +414,7 @@ namespace open_query { if (record_weight && u != v) { typename graph_traits<Graph>::out_edge_iterator ei, ei_end; - for (tie(ei, ei_end)= out_edges(v, g); ei != ei_end; ++ei) + for (boost::tuples::tie(ei, ei_end)= out_edges(v, g); ei != ei_end; ++ei) { if (target(*ei, g) == u) { @@ -479,14 +479,14 @@ namespace open_query if (in_degree(dest, g) >= out_degree(orig, g)) { graph_traits<Graph>::out_edge_iterator ei, ei_end; - tie(ei, ei_end)= out_edges(orig, g); + boost::tuples::tie(ei, ei_end)= out_edges(orig, g); if ((ei= find_if(ei, ei_end, target_equals(dest, g))) != ei_end) return *ei; } else { graph_traits<Graph>::in_edge_iterator ei, ei_end; - tie(ei, ei_end)= in_edges(dest, g); + boost::tuples::tie(ei, ei_end)= in_edges(dest, g); if ((ei= find_if(ei, ei_end, source_equals(orig, g))) != ei_end) return *ei; } @@ -727,7 +727,7 @@ namespace open_query if ((cursor= new (std::nothrow) stack_cursor(share)) && orig) { graph_traits<Graph>::out_edge_iterator ei, ei_end; - for (tie(ei, ei_end)= out_edges(*orig, share->g); ei != ei_end; ++ei) + for (boost::tuples::tie(ei, ei_end)= out_edges(*orig, share->g); ei != ei_end; ++ei) { Vertex v= target(*ei, share->g); static_cast<stack_cursor*>(cursor)-> @@ -741,7 +741,7 @@ namespace open_query dest) { graph_traits<Graph>::in_edge_iterator ei, ei_end; - for (tie(ei, ei_end)= in_edges(*dest, share->g); ei != ei_end; ++ei) + for (boost::tuples::tie(ei, ei_end)= in_edges(*dest, share->g); ei != ei_end; ++ei) { Vertex v= source(*ei, share->g); static_cast<stack_cursor*>(cursor)-> @@ -876,7 +876,7 @@ namespace open_query switch (ALGORITHM & op) { case DIJKSTRAS: - dijkstra_shortest_paths(r, *dest, + dijkstra_shortest_paths(r.m_g, *dest, weight_map( share->weightmap ). @@ -1067,7 +1067,7 @@ int edges_cursor::fetch_row(const row &row_info, row &result) edge_iterator it, end; reference ref; size_t count= position; - for (tie(it, end)= edges(share->g); count && it != end; ++it, --count) + for (boost::tuples::tie(it, end)= edges(share->g); count && it != end; ++it, --count) ; if (it != end) ref= reference(position+1, *it); diff --git a/storage/pbxt/CMakeLists.txt b/storage/pbxt/CMakeLists.txt index 6ddb679bc36..8e78f81ab4a 100644 --- a/storage/pbxt/CMakeLists.txt +++ b/storage/pbxt/CMakeLists.txt @@ -22,6 +22,11 @@ # # This file is used to make the Windows version +IF(NOT WITH_PBXT_STORAGE_ENGINE) + SET(WITHOUT_PBXT 1) +ENDIF(NOT WITH_PBXT_STORAGE_ENGINE) + + SET(PBXT_SOURCES src/bsearch_xt.cc src/bsearch_xt.h diff --git a/storage/xtradb/btr/btr0btr.c b/storage/xtradb/btr/btr0btr.c index ca98afc04ad..433b062bcec 100644 --- a/storage/xtradb/btr/btr0btr.c +++ b/storage/xtradb/btr/btr0btr.c @@ -1523,7 +1523,7 @@ btr_free_root( } ut_a(block); - btr_search_drop_page_hash_index(block, NULL); + btr_search_drop_page_hash_index(block); header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP; #ifdef UNIV_BTR_DEBUG @@ -1592,7 +1592,7 @@ btr_page_reorganize_low( #ifndef UNIV_HOTBACKUP if (UNIV_LIKELY(!recovery)) { - btr_search_drop_page_hash_index(block, index); + btr_search_drop_page_hash_index(block); } block->check_index_page_at_flush = TRUE; @@ -1760,7 +1760,7 @@ btr_page_empty( ut_a(!page_zip || page_zip_validate(page_zip, page)); #endif /* UNIV_ZIP_DEBUG */ - btr_search_drop_page_hash_index(block, index); + btr_search_drop_page_hash_index(block); btr_blob_dbg_remove(page, index, "btr_page_empty"); /* Recreate the page: note that global data on page (possible @@ -3093,7 +3093,7 @@ btr_lift_page_up( mem_heap_free(heap); } - btr_search_drop_page_hash_index(block, index); + btr_search_drop_page_hash_index(block); /* Make the father empty */ btr_page_empty(father_block, father_page_zip, index, page_level, mtr); @@ -3317,7 +3317,7 @@ err_exit: goto err_exit; } - btr_search_drop_page_hash_index(block, index); + btr_search_drop_page_hash_index(block); /* Remove the page from the level list */ btr_level_list_remove(space, zip_size, page, index, mtr); @@ -3358,7 +3358,7 @@ err_exit: goto err_exit; } - btr_search_drop_page_hash_index(block, index); + btr_search_drop_page_hash_index(block); #ifdef UNIV_BTR_DEBUG if (UNIV_LIKELY_NULL(merge_page_zip)) { @@ -3473,7 +3473,7 @@ btr_discard_only_page_on_level( ut_a(btr_page_get_next(page, mtr) == FIL_NULL); ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); - btr_search_drop_page_hash_index(block, index); + btr_search_drop_page_hash_index(block); btr_page_get_father(index, block, mtr, &cursor); father = btr_cur_get_block(&cursor); @@ -3578,7 +3578,7 @@ btr_discard_page( page = buf_block_get_frame(block); ut_a(page_is_comp(merge_page) == page_is_comp(page)); - btr_search_drop_page_hash_index(block, index); + btr_search_drop_page_hash_index(block); if (left_page_no == FIL_NULL && !page_is_leaf(page)) { diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c index 717663a123a..43313474071 100644 --- a/storage/xtradb/btr/btr0cur.c +++ b/storage/xtradb/btr/btr0cur.c @@ -488,8 +488,6 @@ btr_cur_search_to_nth_level( cursor->flag = BTR_CUR_BINARY; cursor->index = index; - cursor->ibuf_cnt = ULINT_UNDEFINED; - #ifndef BTR_CUR_ADAPT guess = NULL; #else @@ -800,21 +798,8 @@ retry_page_get: /* We're doing a search on an ibuf tree and we're one level above the leaf page. */ - ulint is_min_rec; - ut_ad(level == 0); - is_min_rec = rec_get_info_bits(node_ptr, 0) - & REC_INFO_MIN_REC_FLAG; - - if (!is_min_rec) { - cursor->ibuf_cnt - = ibuf_rec_get_counter(node_ptr); - - ut_a(cursor->ibuf_cnt <= 0xFFFF - || cursor->ibuf_cnt == ULINT_UNDEFINED); - } - buf_mode = BUF_GET; rw_latch = RW_NO_LATCH; goto retry_page_get; @@ -2007,7 +1992,7 @@ btr_cur_update_in_place( was_delete_marked = rec_get_deleted_flag( rec, page_is_comp(buf_block_get_frame(block))); - is_hashed = block->is_hashed; + is_hashed = (block->index != NULL); if (is_hashed) { /* TO DO: Can we skip this if none of the fields @@ -3683,16 +3668,11 @@ btr_record_not_null_field_in_rec( } for (i = 0; i < n_unique; i++) { - ulint rec_len; - - rec_get_nth_field_offs(offsets, i, &rec_len); - - if (rec_len != UNIV_SQL_NULL) { - n_not_null[i]++; - } else { - /* Break if we hit the first NULL value */ + if (rec_offs_nth_sql_null(offsets, i)) { break; } + + n_not_null[i]++; } } @@ -3840,8 +3820,7 @@ btr_estimate_number_of_different_key_vals( if (n_not_null) { btr_record_not_null_field_in_rec( - n_cols, offsets_next_rec, - n_not_null); + n_cols, offsets_next_rec, n_not_null); } total_external_size diff --git a/storage/xtradb/btr/btr0pcur.c b/storage/xtradb/btr/btr0pcur.c index 081ef9c9457..e6a9ddcf43e 100644 --- a/storage/xtradb/btr/btr0pcur.c +++ b/storage/xtradb/btr/btr0pcur.c @@ -253,6 +253,8 @@ btr_pcur_restore_position_func( cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE, index, latch_mode, btr_pcur_get_btr_cur(cursor), mtr); + cursor->latch_mode = latch_mode; + cursor->pos_state = BTR_PCUR_IS_POSITIONED; cursor->block_when_stored = btr_pcur_get_block(cursor); return(FALSE); diff --git a/storage/xtradb/btr/btr0sea.c b/storage/xtradb/btr/btr0sea.c index f27afe216ec..bddbcc79dd6 100644 --- a/storage/xtradb/btr/btr0sea.c +++ b/storage/xtradb/btr/btr0sea.c @@ -44,15 +44,11 @@ Created 2/17/1996 Heikki Tuuri #include "ha0ha.h" #include "srv0srv.h" /** Flag: has the search system been enabled? -Protected by btr_search_latch and btr_search_enabled_mutex. */ +Protected by btr_search_latch. */ UNIV_INTERN char btr_search_enabled = TRUE; -UNIV_INTERN ibool btr_search_fully_disabled = FALSE; UNIV_INTERN ulint btr_search_index_num = 1; -/** Mutex protecting btr_search_enabled */ -static mutex_t btr_search_enabled_mutex; - #ifdef UNIV_PFS_MUTEX /* Key to register btr_search_enabled_mutex with performance schema */ UNIV_INTERN mysql_pfs_key_t btr_search_enabled_mutex_key; @@ -186,8 +182,6 @@ btr_search_sys_create( //rw_lock_create(btr_search_latch_key, &btr_search_latch, // SYNC_SEARCH_SYS); - mutex_create(btr_search_enabled_mutex_key, - &btr_search_enabled_mutex, SYNC_SEARCH_SYS_CONF); btr_search_sys = mem_alloc(sizeof(btr_search_sys_t)); @@ -238,27 +232,40 @@ void btr_search_disable(void) /*====================*/ { - mutex_enter(&btr_search_enabled_mutex); + dict_table_t* table; + ulint i; + + mutex_enter(&dict_sys->mutex); btr_search_x_lock_all(); - /* Disable access to hash index, also tell ha_insert_for_fold() - stop adding new nodes to hash index, but still allow updating - existing nodes */ btr_search_enabled = FALSE; - /* Clear all block->is_hashed flags and remove all entries - from btr_search_sys->hash_index. */ - buf_pool_drop_hash_index(); + /* Clear the index->search_info->ref_count of every index in + the data dictionary cache. */ + for (table = UT_LIST_GET_FIRST(dict_sys->table_LRU); table; + table = UT_LIST_GET_NEXT(table_LRU, table)) { + + dict_index_t* index; + + for (index = dict_table_get_first_index(table); index; + index = dict_table_get_next_index(index)) { - /* hash index has been cleaned up, disallow any operation to - the hash index */ - btr_search_fully_disabled = TRUE; + index->search_info->ref_count = 0; + } + } + + mutex_exit(&dict_sys->mutex); - /* btr_search_enabled_mutex should guarantee this. */ - ut_ad(!btr_search_enabled); + /* Set all block->index = NULL. */ + buf_pool_clear_hash_index(); + + /* Clear the adaptive hash index. */ + for (i = 0; i < btr_search_index_num; i++) { + hash_table_clear(btr_search_sys->hash_index[i]); + mem_heap_empty(btr_search_sys->hash_index[i]->heap); + } btr_search_x_unlock_all(); - mutex_exit(&btr_search_enabled_mutex); } /********************************************************************//** @@ -268,14 +275,11 @@ void btr_search_enable(void) /*====================*/ { - mutex_enter(&btr_search_enabled_mutex); btr_search_x_lock_all(); btr_search_enabled = TRUE; - btr_search_fully_disabled = FALSE; btr_search_x_unlock_all(); - mutex_exit(&btr_search_enabled_mutex); } /*****************************************************************//** @@ -499,7 +503,7 @@ btr_search_update_block_hash_info( && (block->n_bytes == info->n_bytes) && (block->left_side == info->left_side)) { - if ((block->is_hashed) + if ((block->index) && (block->curr_n_fields == info->n_fields) && (block->curr_n_bytes == info->n_bytes) && (block->curr_left_side == info->left_side)) { @@ -528,7 +532,7 @@ btr_search_update_block_hash_info( / BTR_SEARCH_PAGE_BUILD_LIMIT) && (info->n_hash_potential >= BTR_SEARCH_BUILD_LIMIT)) { - if ((!block->is_hashed) + if ((!block->index) || (block->n_hash_helps > 2 * page_get_n_recs(block->frame)) || (block->n_fields != block->curr_n_fields) @@ -560,9 +564,9 @@ btr_search_update_hash_ref( buf_block_t* block, /*!< in: buffer block where cursor positioned */ btr_cur_t* cursor) /*!< in: cursor */ { + dict_index_t* index; ulint fold; - rec_t* rec; - index_id_t index_id; + const rec_t* rec; ut_ad(cursor->flag == BTR_CUR_HASH_FAIL); #ifdef UNIV_SYNC_DEBUG @@ -573,13 +577,15 @@ btr_search_update_hash_ref( ut_ad(page_align(btr_cur_get_rec(cursor)) == buf_block_get_frame(block)); - if (!block->is_hashed) { + index = block->index; + + if (!index) { return; } - ut_a(block->index == cursor->index); - ut_a(!dict_index_is_ibuf(cursor->index)); + ut_a(index == cursor->index); + ut_a(!dict_index_is_ibuf(index)); if ((info->n_hash_potential > 0) && (block->curr_n_fields == info->n_fields) @@ -596,12 +602,11 @@ btr_search_update_hash_ref( return; } - index_id = cursor->index->id; fold = rec_fold(rec, - rec_get_offsets(rec, cursor->index, offsets_, + rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap), block->curr_n_fields, - block->curr_n_bytes, index_id); + block->curr_n_bytes, index->id); if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } @@ -870,7 +875,7 @@ btr_search_guess_on_hash( { buf_pool_t* buf_pool; buf_block_t* block; - rec_t* rec; + const rec_t* rec; ulint fold; index_id_t index_id; #ifdef notdefined @@ -956,7 +961,7 @@ btr_search_guess_on_hash( ut_ad(page_rec_is_user_rec(rec)); - btr_cur_position(index, rec, block, cursor); + btr_cur_position(index, (rec_t*) rec, block, cursor); /* Check the validity of the guess within the page */ @@ -1058,11 +1063,10 @@ UNIV_INTERN void btr_search_drop_page_hash_index( /*============================*/ - buf_block_t* block, /*!< in: block containing index page, + buf_block_t* block) /*!< in: block containing index page, s- or x-latched, or an index page for which we know that block->buf_fix_count == 0 */ - dict_index_t* index_in) { hash_table_t* table; ulint n_fields; @@ -1080,24 +1084,14 @@ btr_search_drop_page_hash_index( const dict_index_t* index; ulint* offsets; -#ifdef UNIV_SYNC_DEBUG - if (index_in) { - ut_ad(!rw_lock_own(btr_search_get_latch(index_in->id), RW_LOCK_SHARED)); - ut_ad(!rw_lock_own(btr_search_get_latch(index_in->id), RW_LOCK_EX)); - } -#endif /* UNIV_SYNC_DEBUG */ - retry: - if (index_in) { - index = index_in; - rw_lock_s_lock(btr_search_get_latch(index->id)); - } else if (btr_search_index_num > 1) { + if (btr_search_index_num > 1) { rw_lock_t* btr_search_latch; /* FIXME: This may be optimistic implementation still. */ btr_search_latch = (rw_lock_t*)(block->btr_search_latch); if (UNIV_LIKELY(!btr_search_latch)) { - if (block->is_hashed) { + if (block->index) { goto retry; } return; @@ -1107,7 +1101,7 @@ retry: rw_lock_s_unlock(btr_search_latch); goto retry; } - if (UNIV_LIKELY(!block->is_hashed)) { + if (UNIV_LIKELY(!block->index)) { rw_lock_s_unlock(btr_search_latch); goto retry; } @@ -1116,18 +1110,16 @@ retry: } else { /* btr_search_index_num == 1 */ /* btr_search_latch is only one and able to obtain - before evaluating block->is_hashed. */ + before evaluating block->index. */ rw_lock_s_lock(btr_search_latch_part[0]); - if (UNIV_LIKELY(!block->is_hashed)) { + if (UNIV_LIKELY(!block->index)) { rw_lock_s_unlock(btr_search_latch_part[0]); return; } index = block->index; } - page = block->frame; - - if (UNIV_LIKELY(!block->is_hashed)) { + if (UNIV_LIKELY(!index)) { rw_lock_s_unlock(btr_search_get_latch(index->id)); @@ -1155,6 +1147,7 @@ retry: ut_a(n_fields + n_bytes > 0); + page = block->frame; n_recs = page_get_n_recs(page); /* Calculate and cache fold values into an array for fast deletion @@ -1203,7 +1196,7 @@ next_rec: rw_lock_x_lock(btr_search_get_latch(index->id)); - if (UNIV_UNLIKELY(!block->is_hashed)) { + if (UNIV_UNLIKELY(!block->index)) { /* Someone else has meanwhile dropped the hash index */ goto cleanup; @@ -1231,10 +1224,9 @@ next_rec: ut_a(index->search_info->ref_count > 0); index->search_info->ref_count--; - block->is_hashed = FALSE; block->index = NULL; block->btr_search_latch = NULL; - + cleanup: #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG if (UNIV_UNLIKELY(block->n_pointers)) { @@ -1309,7 +1301,7 @@ retry: if (buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE || block->index != index - || !block->is_hashed) { + || !block->index) { continue; } @@ -1375,7 +1367,7 @@ next_rec: rw_lock_x_lock(btr_search_get_latch(index->id)); - if (UNIV_UNLIKELY(!block->is_hashed)) { + if (UNIV_UNLIKELY(!block->index)) { goto cleanup; } @@ -1400,7 +1392,6 @@ next_rec: ut_a(index->search_info->ref_count > 0); index->search_info->ref_count--; - block->is_hashed = FALSE; block->index = NULL; block->btr_search_latch = NULL; @@ -1434,8 +1425,8 @@ cleanup: } /********************************************************************//** -Drops a page hash index when a page is freed from a fseg to the file system. -Drops possible hash index if the page happens to be in the buffer pool. */ +Drops a possible page hash index when a page is evicted from the buffer pool +or freed in a file segment. */ UNIV_INTERN void btr_search_drop_page_hash_when_freed( @@ -1448,32 +1439,23 @@ btr_search_drop_page_hash_when_freed( buf_block_t* block; mtr_t mtr; - if (!buf_page_peek_if_search_hashed(space, page_no)) { - - return; - } - mtr_start(&mtr); - /* We assume that if the caller has a latch on the page, then the - caller has already dropped the hash index for the page, and we never - get here. Therefore we can acquire the s-latch to the page without - having to fear a deadlock. */ + /* If the caller has a latch on the page, then the caller must + have a x-latch on the page and it must have already dropped + the hash index for the page. Because of the x-latch that we + are possibly holding, we cannot s-latch the page, but must + (recursively) x-latch it, even though we are only reading. */ - block = buf_page_get_gen(space, zip_size, page_no, RW_S_LATCH, NULL, + block = buf_page_get_gen(space, zip_size, page_no, RW_X_LATCH, NULL, BUF_PEEK_IF_IN_POOL, __FILE__, __LINE__, &mtr); - /* Because the buffer pool mutex was released by - buf_page_peek_if_search_hashed(), it is possible that the - block was removed from the buffer pool by another thread - before buf_page_get_gen() got a chance to acquire the buffer - pool mutex again. Thus, we must check for a NULL return. */ - if (UNIV_LIKELY(block != NULL)) { + if (block && block->index) { buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH); - btr_search_drop_page_hash_index(block, NULL); + btr_search_drop_page_hash_index(block); } mtr_commit(&mtr); @@ -1501,7 +1483,6 @@ btr_search_build_page_hash_index( rec_t* next_rec; ulint fold; ulint next_fold; - index_id_t index_id; ulint n_cached; ulint n_recs; ulint* folds; @@ -1526,13 +1507,13 @@ btr_search_build_page_hash_index( rw_lock_s_lock(btr_search_get_latch(index->id)); - if (block->is_hashed && ((block->curr_n_fields != n_fields) + if (block->index && ((block->curr_n_fields != n_fields) || (block->curr_n_bytes != n_bytes) || (block->curr_left_side != left_side))) { rw_lock_s_unlock(btr_search_get_latch(index->id)); - btr_search_drop_page_hash_index(block, index); + btr_search_drop_page_hash_index(block); } else { rw_lock_s_unlock(btr_search_get_latch(index->id)); } @@ -1565,7 +1546,7 @@ btr_search_build_page_hash_index( n_cached = 0; - index_id = btr_page_get_index_id(page); + ut_a(index->id == btr_page_get_index_id(page)); rec = page_rec_get_next(page_get_infimum_rec(page)); @@ -1580,7 +1561,7 @@ btr_search_build_page_hash_index( } } - fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id); + fold = rec_fold(rec, offsets, n_fields, n_bytes, index->id); if (left_side) { @@ -1607,7 +1588,7 @@ btr_search_build_page_hash_index( offsets = rec_get_offsets(next_rec, index, offsets, n_fields + (n_bytes > 0), &heap); next_fold = rec_fold(next_rec, offsets, n_fields, - n_bytes, index_id); + n_bytes, index->id); if (fold != next_fold) { /* Insert an entry into the hash index */ @@ -1632,13 +1613,13 @@ btr_search_build_page_hash_index( rw_lock_x_lock(btr_search_get_latch(index->id)); - if (UNIV_UNLIKELY(btr_search_fully_disabled)) { + if (UNIV_UNLIKELY(!btr_search_enabled)) { goto exit_func; } - if (block->is_hashed && ((block->curr_n_fields != n_fields) - || (block->curr_n_bytes != n_bytes) - || (block->curr_left_side != left_side))) { + if (block->index && ((block->curr_n_fields != n_fields) + || (block->curr_n_bytes != n_bytes) + || (block->curr_left_side != left_side))) { goto exit_func; } @@ -1647,11 +1628,10 @@ btr_search_build_page_hash_index( rebuild hash index for a page that is already hashed, we have to take care not to increment the counter in that case. */ - if (!block->is_hashed) { + if (!block->index) { index->search_info->ref_count++; } - block->is_hashed = TRUE; block->n_hash_helps = 0; block->curr_n_fields = n_fields; @@ -1700,23 +1680,24 @@ btr_search_move_or_delete_hash_entries( ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX)); ut_ad(rw_lock_own(&(new_block->lock), RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ - ut_a(!new_block->is_hashed || new_block->index == index); - ut_a(!block->is_hashed || block->index == index); - ut_a(!(new_block->is_hashed || block->is_hashed) - || !dict_index_is_ibuf(index)); rw_lock_s_lock(btr_search_get_latch(index->id)); - if (new_block->is_hashed) { + ut_a(!new_block->index || new_block->index == index); + ut_a(!block->index || block->index == index); + ut_a(!(new_block->index || block->index) + || !dict_index_is_ibuf(index)); + + if (new_block->index) { rw_lock_s_unlock(btr_search_get_latch(index->id)); - btr_search_drop_page_hash_index(block, index); + btr_search_drop_page_hash_index(block); return; } - if (block->is_hashed) { + if (block->index) { n_fields = block->curr_n_fields; n_bytes = block->curr_n_bytes; @@ -1753,42 +1734,48 @@ btr_search_update_hash_on_delete( { hash_table_t* table; buf_block_t* block; - rec_t* rec; + const rec_t* rec; ulint fold; - index_id_t index_id; + dict_index_t* index; ulint offsets_[REC_OFFS_NORMAL_SIZE]; mem_heap_t* heap = NULL; rec_offs_init(offsets_); - rec = btr_cur_get_rec(cursor); - block = btr_cur_get_block(cursor); #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ - if (!block->is_hashed) { + index = block->index; + + if (!index) { return; } - ut_a(block->index == cursor->index); + ut_a(index == cursor->index); ut_a(block->curr_n_fields + block->curr_n_bytes > 0); - ut_a(!dict_index_is_ibuf(cursor->index)); + ut_a(!dict_index_is_ibuf(index)); table = btr_search_get_hash_index(cursor->index->id); - index_id = cursor->index->id; - fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, offsets_, + rec = btr_cur_get_rec(cursor); + + fold = rec_fold(rec, rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap), - block->curr_n_fields, block->curr_n_bytes, index_id); + block->curr_n_fields, block->curr_n_bytes, index->id); if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } + rw_lock_x_lock(btr_search_get_latch(cursor->index->id)); - ha_search_and_delete_if_found(table, fold, rec); + if (block->index) { + ut_a(block->index == index); + + ha_search_and_delete_if_found(table, fold, rec); + } rw_lock_x_unlock(btr_search_get_latch(cursor->index->id)); } @@ -1806,6 +1793,7 @@ btr_search_update_hash_node_on_insert( { hash_table_t* table; buf_block_t* block; + dict_index_t* index; rec_t* rec; rec = btr_cur_get_rec(cursor); @@ -1816,16 +1804,25 @@ btr_search_update_hash_node_on_insert( ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ - if (!block->is_hashed) { + index = block->index; + + if (!index) { return; } - ut_a(block->index == cursor->index); - ut_a(!dict_index_is_ibuf(cursor->index)); + ut_a(cursor->index == index); + ut_a(!dict_index_is_ibuf(index)); rw_lock_x_lock(btr_search_get_latch(cursor->index->id)); + if (!block->index) { + + goto func_exit; + } + + ut_a(block->index == index); + if ((cursor->flag == BTR_CUR_HASH) && (cursor->n_fields == block->curr_n_fields) && (cursor->n_bytes == block->curr_n_bytes) @@ -1836,6 +1833,7 @@ btr_search_update_hash_node_on_insert( ha_search_and_update_if_found(table, cursor->fold, rec, block, page_rec_get_next(rec)); +func_exit: rw_lock_x_unlock(btr_search_get_latch(cursor->index->id)); } else { rw_lock_x_unlock(btr_search_get_latch(cursor->index->id)); @@ -1857,10 +1855,10 @@ btr_search_update_hash_on_insert( { hash_table_t* table; buf_block_t* block; + dict_index_t* index; rec_t* rec; rec_t* ins_rec; rec_t* next_rec; - index_id_t index_id; ulint fold; ulint ins_fold; ulint next_fold = 0; /* remove warning (??? bug ???) */ @@ -1885,15 +1883,15 @@ btr_search_update_hash_on_insert( ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ - if (!block->is_hashed) { + index = block->index; + + if (!index) { return; } - ut_a(block->index == cursor->index); - ut_a(!dict_index_is_ibuf(cursor->index)); - - index_id = cursor->index->id; + ut_a(index == cursor->index); + ut_a(!dict_index_is_ibuf(index)); n_fields = block->curr_n_fields; n_bytes = block->curr_n_bytes; @@ -1902,28 +1900,32 @@ btr_search_update_hash_on_insert( ins_rec = page_rec_get_next(rec); next_rec = page_rec_get_next(ins_rec); - offsets = rec_get_offsets(ins_rec, cursor->index, offsets, + offsets = rec_get_offsets(ins_rec, index, offsets, ULINT_UNDEFINED, &heap); - ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, index_id); + ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, index->id); if (!page_rec_is_supremum(next_rec)) { - offsets = rec_get_offsets(next_rec, cursor->index, offsets, + offsets = rec_get_offsets(next_rec, index, offsets, n_fields + (n_bytes > 0), &heap); next_fold = rec_fold(next_rec, offsets, n_fields, - n_bytes, index_id); + n_bytes, index->id); } if (!page_rec_is_infimum(rec)) { - offsets = rec_get_offsets(rec, cursor->index, offsets, + offsets = rec_get_offsets(rec, index, offsets, n_fields + (n_bytes > 0), &heap); - fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id); + fold = rec_fold(rec, offsets, n_fields, n_bytes, index->id); } else { if (left_side) { - rw_lock_x_lock(btr_search_get_latch(index_id)); + rw_lock_x_lock(btr_search_get_latch(index->id)); locked = TRUE; + if (!btr_search_enabled) { + goto function_exit; + } + ha_insert_for_fold(table, ins_fold, block, ins_rec); } @@ -1934,9 +1936,13 @@ btr_search_update_hash_on_insert( if (!locked) { - rw_lock_x_lock(btr_search_get_latch(index_id)); + rw_lock_x_lock(btr_search_get_latch(index->id)); locked = TRUE; + + if (!btr_search_enabled) { + goto function_exit; + } } if (!left_side) { @@ -1952,9 +1958,13 @@ check_next_rec: if (!left_side) { if (!locked) { - rw_lock_x_lock(btr_search_get_latch(index_id)); + rw_lock_x_lock(btr_search_get_latch(index->id)); locked = TRUE; + + if (!btr_search_enabled) { + goto function_exit; + } } ha_insert_for_fold(table, ins_fold, block, ins_rec); @@ -1967,9 +1977,13 @@ check_next_rec: if (!locked) { - rw_lock_x_lock(btr_search_get_latch(index_id)); + rw_lock_x_lock(btr_search_get_latch(index->id)); locked = TRUE; + + if (!btr_search_enabled) { + goto function_exit; + } } if (!left_side) { @@ -1977,7 +1991,7 @@ check_next_rec: ha_insert_for_fold(table, ins_fold, block, ins_rec); /* fputs("Hash insert for ", stderr); - dict_index_name_print(stderr, cursor->index); + dict_index_name_print(stderr, index); fprintf(stderr, " fold %lu\n", ins_fold); */ } else { @@ -1990,7 +2004,7 @@ function_exit: mem_heap_free(heap); } if (locked) { - rw_lock_x_unlock(btr_search_get_latch(index_id)); + rw_lock_x_unlock(btr_search_get_latch(index->id)); } } @@ -2082,21 +2096,20 @@ btr_search_validate(void) ut_a(!dict_index_is_ibuf(block->index)); - offsets = rec_get_offsets((const rec_t*) node->data, + page_index_id = btr_page_get_index_id(block->frame); + + offsets = rec_get_offsets(node->data, block->index, offsets, block->curr_n_fields + (block->curr_n_bytes > 0), &heap); - page_index_id = btr_page_get_index_id(block->frame); - - if (UNIV_UNLIKELY - (!block->is_hashed || node->fold - != rec_fold((rec_t*)(node->data), - offsets, - block->curr_n_fields, - block->curr_n_bytes, - page_index_id))) { + if (!block->index || node->fold + != rec_fold(node->data, + offsets, + block->curr_n_fields, + block->curr_n_bytes, + page_index_id)) { const page_t* page = block->frame; ok = FALSE; @@ -2112,20 +2125,19 @@ btr_search_validate(void) node->data, (ullint) page_index_id, (ulong) node->fold, - (ulong) rec_fold((rec_t*)(node->data), + (ulong) rec_fold(node->data, offsets, block->curr_n_fields, block->curr_n_bytes, page_index_id)); fputs("InnoDB: Record ", stderr); - rec_print_new(stderr, (rec_t*)node->data, - offsets); + rec_print_new(stderr, node->data, offsets); fprintf(stderr, "\nInnoDB: on that page." - " Page mem address %p, is hashed %lu," + " Page mem address %p, is hashed %p," " n fields %lu, n bytes %lu\n" "InnoDB: side %lu\n", - (void*) page, (ulong) block->is_hashed, + (void*) page, (void*) block->index, (ulong) block->curr_n_fields, (ulong) block->curr_n_bytes, (ulong) block->curr_left_side); diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c index 7b228eaa11f..11b079dd0ef 100644 --- a/storage/xtradb/buf/buf0buf.c +++ b/storage/xtradb/buf/buf0buf.c @@ -57,7 +57,7 @@ Created 11/5/1995 Heikki Tuuri /* prototypes for new functions added to ha_innodb.cc */ trx_t* innobase_get_trx(); -inline void _increment_page_get_statistics(buf_block_t* block, trx_t* trx) +static inline void _increment_page_get_statistics(buf_block_t* block, trx_t* trx) { ulint block_hash; ulint block_hash_byte; @@ -917,6 +917,16 @@ pfs_register_buffer_block( rwlock->pfs_psi = (PSI_server) ? PSI_server->init_rwlock(buf_block_lock_key, rwlock) : NULL; + +# ifdef UNIV_SYNC_DEBUG + rwlock = &block->debug_latch; + ut_a(!rwlock->pfs_psi); + rwlock->pfs_psi = (PSI_server) + ? PSI_server->init_rwlock(buf_block_debug_latch_key, + rwlock) + : NULL; +# endif /* UNIV_SYNC_DEBUG */ + # endif /* UNIV_PFS_RWLOCK */ block++; } @@ -952,8 +962,6 @@ buf_block_init( block->index = NULL; block->btr_search_latch = NULL; - block->is_hashed = FALSE; - #ifdef UNIV_DEBUG block->page.in_page_hash = FALSE; block->page.in_zip_hash = FALSE; @@ -980,17 +988,24 @@ buf_block_init( mutex_create(PFS_NOT_INSTRUMENTED, &block->mutex, SYNC_BUF_BLOCK); rw_lock_create(PFS_NOT_INSTRUMENTED, &block->lock, SYNC_LEVEL_VARYING); + +# ifdef UNIV_SYNC_DEBUG + rw_lock_create(PFS_NOT_INSTRUMENTED, + &block->debug_latch, SYNC_NO_ORDER_CHECK); +# endif /* UNIV_SYNC_DEBUG */ + #else /* PFS_SKIP_BUFFER_MUTEX_RWLOCK || PFS_GROUP_BUFFER_SYNC */ mutex_create(buffer_block_mutex_key, &block->mutex, SYNC_BUF_BLOCK); rw_lock_create(buf_block_lock_key, &block->lock, SYNC_LEVEL_VARYING); + +# ifdef UNIV_SYNC_DEBUG + rw_lock_create(buf_block_debug_latch_key, + &block->debug_latch, SYNC_NO_ORDER_CHECK); +# endif /* UNIV_SYNC_DEBUG */ #endif /* PFS_SKIP_BUFFER_MUTEX_RWLOCK || PFS_GROUP_BUFFER_SYNC */ ut_ad(rw_lock_validate(&(block->lock))); -#ifdef UNIV_SYNC_DEBUG - rw_lock_create(buf_block_debug_latch_key, - &block->debug_latch, SYNC_NO_ORDER_CHECK); -#endif /* UNIV_SYNC_DEBUG */ } /********************************************************************//** @@ -1317,6 +1332,26 @@ buf_pool_free_instance( { buf_chunk_t* chunk; buf_chunk_t* chunks; + buf_page_t* bpage; + + bpage = UT_LIST_GET_LAST(buf_pool->LRU); + while (bpage != NULL) { + buf_page_t* prev_bpage = UT_LIST_GET_PREV(LRU, bpage); + enum buf_page_state state = buf_page_get_state(bpage); + + ut_ad(buf_page_in_file(bpage)); + ut_ad(bpage->in_LRU_list); + + if (state != BUF_BLOCK_FILE_PAGE) { + /* We must not have any dirty block except + when doing a fast shutdown. */ + ut_ad(state == BUF_BLOCK_ZIP_PAGE + || srv_fast_shutdown == 2); + buf_page_free_descriptor(bpage); + } + + bpage = prev_bpage; + } chunks = buf_pool->chunks; chunk = chunks + buf_pool->n_chunks; @@ -1392,87 +1427,13 @@ buf_pool_free( } /********************************************************************//** -Drops adaptive hash index for a buffer pool instance. */ -static -void -buf_pool_drop_hash_index_instance( -/*==============================*/ - buf_pool_t* buf_pool, /*!< in: buffer pool instance */ - ibool* released_search_latch) /*!< out: flag for signalling - whether the search latch was - released */ -{ - buf_chunk_t* chunks = buf_pool->chunks; - buf_chunk_t* chunk = chunks + buf_pool->n_chunks; - - while (--chunk >= chunks) { - ulint i; - buf_block_t* block = chunk->blocks; - - for (i = chunk->size; i--; block++) { - /* block->is_hashed cannot be modified - when we have an x-latch on btr_search_latch; - see the comment in buf0buf.h */ - - if (!block->is_hashed) { - continue; - } - - /* To follow the latching order, we - have to release btr_search_latch - before acquiring block->latch. */ - btr_search_x_unlock_all(); - /* When we release the search latch, - we must rescan all blocks, because - some may become hashed again. */ - *released_search_latch = TRUE; - - rw_lock_x_lock(&block->lock); - - /* This should be guaranteed by the - callers, which will be holding - btr_search_enabled_mutex. */ - ut_ad(!btr_search_enabled); - - /* Because we did not buffer-fix the - block by calling buf_block_get_gen(), - it is possible that the block has been - allocated for some other use after - btr_search_latch was released above. - We do not care which file page the - block is mapped to. All we want to do - is to drop any hash entries referring - to the page. */ - - /* It is possible that - block->page.state != BUF_FILE_PAGE. - Even that does not matter, because - btr_search_drop_page_hash_index() will - check block->is_hashed before doing - anything. block->is_hashed can only - be set on uncompressed file pages. */ - - btr_search_drop_page_hash_index(block, NULL); - - rw_lock_x_unlock(&block->lock); - - btr_search_x_lock_all(); - - ut_ad(!btr_search_enabled); - } - } -} - -/********************************************************************//** -Drops the adaptive hash index. To prevent a livelock, this function -is only to be called while holding btr_search_latch and while -btr_search_enabled == FALSE. */ +Clears the adaptive hash index on all pages in the buffer pool. */ UNIV_INTERN void -buf_pool_drop_hash_index(void) -/*==========================*/ +buf_pool_clear_hash_index(void) +/*===========================*/ { - ibool released_search_latch; + ulint p; #ifdef UNIV_SYNC_DEBUG ulint j; @@ -1483,21 +1444,34 @@ buf_pool_drop_hash_index(void) #endif /* UNIV_SYNC_DEBUG */ ut_ad(!btr_search_enabled); - do { - ulint i; + for (p = 0; p < srv_buf_pool_instances; p++) { + buf_pool_t* buf_pool = buf_pool_from_array(p); + buf_chunk_t* chunks = buf_pool->chunks; + buf_chunk_t* chunk = chunks + buf_pool->n_chunks; - released_search_latch = FALSE; + while (--chunk >= chunks) { + buf_block_t* block = chunk->blocks; + ulint i = chunk->size; - for (i = 0; i < srv_buf_pool_instances; i++) { - buf_pool_t* buf_pool; + for (; i--; block++) { + dict_index_t* index = block->index; - buf_pool = buf_pool_from_array(i); + /* We can set block->index = NULL + when we have an x-latch on btr_search_latch; + see the comment in buf0buf.h */ - buf_pool_drop_hash_index_instance( - buf_pool, &released_search_latch); - } + if (!index) { + /* Not hashed */ + continue; + } - } while (released_search_latch); + block->index = NULL; +# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG + block->n_pointers = 0; +# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ + } + } + } } /********************************************************************//** @@ -1638,12 +1612,12 @@ buf_pool_watch_set( rw_lock_x_lock(&buf_pool->page_hash_latch); bpage = buf_page_hash_get_low(buf_pool, space, offset, fold); - if (bpage) { + + if (UNIV_LIKELY_NULL(bpage)) { + block_mutex = buf_page_get_mutex_enter(bpage); ut_a(block_mutex); - } - if (UNIV_LIKELY_NULL(bpage)) { if (!buf_pool_watch_is_sentinel(buf_pool, bpage)) { /* The page was loaded meanwhile. */ rw_lock_x_unlock(&buf_pool->page_hash_latch); @@ -1895,40 +1869,6 @@ buf_reset_check_index_page_at_flush( rw_lock_s_unlock(&buf_pool->page_hash_latch); } -/********************************************************************//** -Returns the current state of is_hashed of a page. FALSE if the page is -not in the pool. NOTE that this operation does not fix the page in the -pool if it is found there. -@return TRUE if page hash index is built in search system */ -UNIV_INTERN -ibool -buf_page_peek_if_search_hashed( -/*===========================*/ - ulint space, /*!< in: space id */ - ulint offset) /*!< in: page number */ -{ - buf_block_t* block; - ibool is_hashed; - buf_pool_t* buf_pool = buf_pool_get(space, offset); - - //buf_pool_mutex_enter(buf_pool); - rw_lock_s_lock(&buf_pool->page_hash_latch); - - block = (buf_block_t*) buf_page_hash_get(buf_pool, space, offset); - - if (!block || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) { - is_hashed = FALSE; - } else { - ut_ad(!buf_pool_watch_is_sentinel(buf_pool, &block->page)); - is_hashed = block->is_hashed; - } - - //buf_pool_mutex_exit(buf_pool); - rw_lock_s_unlock(&buf_pool->page_hash_latch); - - return(is_hashed); -} - #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG /********************************************************************//** Sets file_page_was_freed TRUE if the page is found in the buffer pool. @@ -2218,7 +2158,6 @@ buf_block_init_low( block->btr_search_latch = NULL; block->n_hash_helps = 0; - block->is_hashed = FALSE; block->n_fields = 1; block->n_bytes = 0; block->left_side = TRUE; @@ -4473,6 +4412,9 @@ buf_pool_validate_instance( ut_a(rw_lock_is_locked(&block->lock, RW_LOCK_EX)); break; + + case BUF_IO_PIN: + break; } n_lru++; @@ -4502,6 +4444,7 @@ buf_pool_validate_instance( ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE); switch (buf_page_get_io_fix(b)) { case BUF_IO_NONE: + case BUF_IO_PIN: /* All clean blocks should be I/O-unfixed. */ break; case BUF_IO_READ: @@ -4541,6 +4484,7 @@ buf_pool_validate_instance( switch (buf_page_get_io_fix(b)) { case BUF_IO_NONE: case BUF_IO_READ: + case BUF_IO_PIN: break; case BUF_IO_WRITE: switch (buf_page_get_flush_type(b)) { diff --git a/storage/xtradb/buf/buf0flu.c b/storage/xtradb/buf/buf0flu.c index 73a9ff96289..d776a274d14 100644 --- a/storage/xtradb/buf/buf0flu.c +++ b/storage/xtradb/buf/buf0flu.c @@ -1399,6 +1399,7 @@ buf_flush_try_neighbors( ulint high; ulint count = 0; buf_pool_t* buf_pool = buf_pool_get(space, offset); + ibool is_forward_scan; ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST); @@ -1429,7 +1430,32 @@ buf_flush_try_neighbors( high = fil_space_get_size(space); } - for (i = low; i < high; i++) { + if (srv_flush_neighbor_pages == 2) { + + /* In the case of contiguous flush where the requested page + does not fall at the start of flush area, first scan backward + from the page and later forward from it. */ + is_forward_scan = (offset == low); + } + else { + is_forward_scan = TRUE; + } + +scan: + if (srv_flush_neighbor_pages == 2) { + if (is_forward_scan) { + i = offset; + } + else { + i = offset - 1; + } + } + else { + i = low; + } + + for (; is_forward_scan ? (i < high) : (i >= low); + is_forward_scan ? i++ : i--) { buf_page_t* bpage; @@ -1460,6 +1486,12 @@ buf_flush_try_neighbors( //buf_pool_mutex_exit(buf_pool); rw_lock_s_unlock(&buf_pool->page_hash_latch); + if (srv_flush_neighbor_pages == 2) { + + /* This is contiguous neighbor page flush and + the pages here are not contiguous. */ + break; + } continue; } @@ -1495,6 +1527,22 @@ buf_flush_try_neighbors( } //buf_pool_mutex_exit(buf_pool); rw_lock_s_unlock(&buf_pool->page_hash_latch); + + if (srv_flush_neighbor_pages == 2) { + + /* We are trying to do the contiguous neighbor page + flush, but the last page we checked was unflushable, + making a "hole" in the flush, so stop this attempt. */ + break; + } + } + + if (!is_forward_scan) { + + /* Backward scan done, now do the forward scan */ + ut_a (srv_flush_neighbor_pages == 2); + is_forward_scan = TRUE; + goto scan; } return(count); @@ -1988,6 +2036,22 @@ buf_flush_list( buf_pool = buf_pool_from_array(i); + if (lsn_limit != IB_ULONGLONG_MAX) { + buf_page_t* bpage; + + buf_flush_list_mutex_enter(buf_pool); + bpage = UT_LIST_GET_LAST(buf_pool->flush_list); + if (!bpage + || bpage->oldest_modification >= lsn_limit) { + + buf_flush_list_mutex_exit(buf_pool); + continue; + } else { + + buf_flush_list_mutex_exit(buf_pool); + } + } + if (!buf_flush_start(buf_pool, BUF_FLUSH_LIST)) { /* We have two choices here. If lsn_limit was specified then skipping an instance of buffer diff --git a/storage/xtradb/buf/buf0lru.c b/storage/xtradb/buf/buf0lru.c index a5a811f7afe..ecad1cf1e64 100644 --- a/storage/xtradb/buf/buf0lru.c +++ b/storage/xtradb/buf/buf0lru.c @@ -68,8 +68,12 @@ allowed to point to either end of the LRU list. */ /** When dropping the search hash index entries before deleting an ibd file, we build a local array of pages belonging to that tablespace -in the buffer pool. Following is the size of that array. */ -#define BUF_LRU_DROP_SEARCH_HASH_SIZE 1024 +in the buffer pool. Following is the size of that array. +We also release buf_pool->mutex after scanning this many pages of the +flush_list when dropping a table. This is to ensure that other threads +are not blocked for extended period of time when using very large +buffer pools. */ +#define BUF_LRU_DROP_SEARCH_SIZE 1024 /** If we switch on the InnoDB monitor because there are too few available frames in the buffer pool, we set this to TRUE */ @@ -222,7 +226,7 @@ buf_LRU_drop_page_hash_batch( ulint i; ut_ad(arr != NULL); - ut_ad(count <= BUF_LRU_DROP_SEARCH_HASH_SIZE); + ut_ad(count <= BUF_LRU_DROP_SEARCH_SIZE); for (i = 0; i < count; ++i) { btr_search_drop_page_hash_when_freed(space_id, zip_size, @@ -256,7 +260,7 @@ buf_LRU_drop_page_hash_for_tablespace( } page_arr = ut_malloc( - sizeof(ulint) * BUF_LRU_DROP_SEARCH_HASH_SIZE); + sizeof(ulint) * BUF_LRU_DROP_SEARCH_SIZE); //buf_pool_mutex_enter(buf_pool); mutex_enter(&buf_pool->LRU_list_mutex); @@ -293,7 +297,7 @@ next_page: //mutex_enter(&((buf_block_t*) bpage)->mutex); is_fixed = bpage->buf_fix_count > 0 - || !((buf_block_t*) bpage)->is_hashed; + || !((buf_block_t*) bpage)->index; //mutex_exit(&((buf_block_t*) bpage)->mutex); if (is_fixed) { @@ -304,12 +308,14 @@ next_page: /* Store the page number so that we can drop the hash index in a batch later. */ page_arr[num_entries] = bpage->offset; + mutex_exit(block_mutex); - ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE); + ut_a(num_entries < BUF_LRU_DROP_SEARCH_SIZE); + ++num_entries; - if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) { + if (num_entries < BUF_LRU_DROP_SEARCH_SIZE) { goto next_page; } @@ -366,39 +372,42 @@ next_page: } /******************************************************************//** -Invalidates all pages belonging to a given tablespace inside a specific +Remove all dirty pages belonging to a given tablespace inside a specific buffer pool instance when we are deleting the data file(s) of that -tablespace. */ +tablespace. The pages still remain a part of LRU and are evicted from +the list as they age towards the tail of the LRU. */ static void -buf_LRU_invalidate_tablespace_buf_pool_instance( -/*============================================*/ +buf_LRU_remove_dirty_pages_for_tablespace( +/*======================================*/ buf_pool_t* buf_pool, /*!< buffer pool instance */ ulint id) /*!< in: space id */ { buf_page_t* bpage; ibool all_freed; + ulint i; scan_again: //buf_pool_mutex_enter(buf_pool); mutex_enter(&buf_pool->LRU_list_mutex); rw_lock_x_lock(&buf_pool->page_hash_latch); + buf_flush_list_mutex_enter(buf_pool); all_freed = TRUE; - bpage = UT_LIST_GET_LAST(buf_pool->LRU); + for (bpage = UT_LIST_GET_LAST(buf_pool->flush_list), i = 0; + bpage != NULL; ++i) { - while (bpage != NULL) { buf_page_t* prev_bpage; mutex_t* block_mutex = NULL; ut_a(buf_page_in_file(bpage)); - prev_bpage = UT_LIST_GET_PREV(LRU, bpage); + prev_bpage = UT_LIST_GET_PREV(flush_list, bpage); /* bpage->space and bpage->io_fix are protected by - buf_pool_mutex and block_mutex. It is safe to check - them while holding buf_pool_mutex only. */ + buf_pool->mutex and block_mutex. It is safe to check + them while holding buf_pool->mutex only. */ if (buf_page_get_space(bpage) != id) { /* Skip this block, as it does not belong to @@ -411,90 +420,97 @@ scan_again: all_freed = FALSE; goto next_page; - } else { - block_mutex = buf_page_get_mutex_enter(bpage); - - if (!block_mutex) { - /* It may be impossible case... - Something wrong, so will be scan_again */ + } - all_freed = FALSE; - goto next_page; - } + /* We have to release the flush_list_mutex to obey the + latching order. We are however guaranteed that the page + will stay in the flush_list because buf_flush_remove() + needs buf_pool->mutex as well. */ + buf_flush_list_mutex_exit(buf_pool); + block_mutex = buf_page_get_mutex_enter(bpage); - if (bpage->buf_fix_count > 0) { + if (!block_mutex) { + /* It may be impossible case... + Something wrong, so will be scan_again */ + all_freed = FALSE; + goto next_page; + } - mutex_exit(block_mutex); - /* We cannot remove this page during - this scan yet; maybe the system is - currently reading it in, or flushing - the modifications to the file */ + if (bpage->buf_fix_count > 0) { + mutex_exit(block_mutex); + buf_flush_list_mutex_enter(buf_pool); - all_freed = FALSE; + /* We cannot remove this page during + this scan yet; maybe the system is + currently reading it in, or flushing + the modifications to the file */ - goto next_page; - } + all_freed = FALSE; + goto next_page; } - ut_ad(mutex_own(block_mutex)); + ut_ad(bpage->oldest_modification != 0); -#ifdef UNIV_DEBUG - if (buf_debug_prints) { - fprintf(stderr, - "Dropping space %lu page %lu\n", - (ulong) buf_page_get_space(bpage), - (ulong) buf_page_get_page_no(bpage)); + buf_flush_remove(bpage); + + mutex_exit(block_mutex); + buf_flush_list_mutex_enter(buf_pool); +next_page: + bpage = prev_bpage; + + if (!bpage) { + break; } -#endif - if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) { - /* This is a compressed-only block - descriptor. Do nothing. */ - } else if (((buf_block_t*) bpage)->is_hashed) { - ulint page_no; - ulint zip_size; - //buf_pool_mutex_exit(buf_pool); - mutex_exit(&buf_pool->LRU_list_mutex); - rw_lock_x_unlock(&buf_pool->page_hash_latch); + /* Every BUF_LRU_DROP_SEARCH_SIZE iterations in the + loop we release buf_pool->mutex to let other threads + do their job. */ + if (i < BUF_LRU_DROP_SEARCH_SIZE) { + continue; + } - zip_size = buf_page_get_zip_size(bpage); - page_no = buf_page_get_page_no(bpage); + /* We IO-fix the block to make sure that the block + stays in its position in the flush_list. */ + if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) { + /* Block is already IO-fixed. We don't + want to change the value. Lets leave + this block alone. */ + continue; + } - mutex_exit(block_mutex); + buf_flush_list_mutex_exit(buf_pool); + block_mutex = buf_page_get_mutex(bpage); + mutex_enter(block_mutex); + buf_page_set_sticky(bpage); + mutex_exit(block_mutex); - /* Note that the following call will acquire - an S-latch on the page */ + /* Now it is safe to release the buf_pool->mutex. */ + //buf_pool_mutex_exit(buf_pool); + mutex_exit(&buf_pool->LRU_list_mutex); + rw_lock_x_unlock(&buf_pool->page_hash_latch); - btr_search_drop_page_hash_when_freed( - id, zip_size, page_no); - goto scan_again; - } + os_thread_yield(); + //buf_pool_mutex_enter(buf_pool); + mutex_enter(&buf_pool->LRU_list_mutex); + rw_lock_x_lock(&buf_pool->page_hash_latch); - if (bpage->oldest_modification != 0) { - buf_flush_remove(bpage); - } + mutex_enter(block_mutex); + buf_page_unset_sticky(bpage); + mutex_exit(block_mutex); - /* Remove from the LRU list. */ + buf_flush_list_mutex_enter(buf_pool); + ut_ad(bpage->in_flush_list); - if (buf_LRU_block_remove_hashed_page(bpage, TRUE) - != BUF_BLOCK_ZIP_FREE) { - buf_LRU_block_free_hashed_page((buf_block_t*) bpage, TRUE); - mutex_exit(block_mutex); - } else { - /* The block_mutex should have been released - by buf_LRU_block_remove_hashed_page() when it - returns BUF_BLOCK_ZIP_FREE. */ - ut_ad(block_mutex == &buf_pool->zip_mutex); - ut_ad(!mutex_own(block_mutex)); - } -next_page: - bpage = prev_bpage; + i = 0; } - //buf_pool_mutex_exit(buf_pool); +// buf_pool_mutex_exit(buf_pool); mutex_exit(&buf_pool->LRU_list_mutex); rw_lock_x_unlock(&buf_pool->page_hash_latch); + buf_flush_list_mutex_exit(buf_pool); + + ut_ad(buf_flush_validate(buf_pool)); if (!all_freed) { os_thread_sleep(20000); @@ -525,7 +541,7 @@ buf_LRU_invalidate_tablespace( buf_pool = buf_pool_from_array(i); buf_LRU_drop_page_hash_for_tablespace(buf_pool, id); - buf_LRU_invalidate_tablespace_buf_pool_instance(buf_pool, id); + buf_LRU_remove_dirty_pages_for_tablespace(buf_pool, id); } } @@ -567,7 +583,7 @@ buf_LRU_mark_space_was_deleted( for (k = chunk->size; k--; block++) { if (buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE - || !block->is_hashed + || !block->index || buf_page_get_space(&block->page) != id) { continue; } @@ -575,7 +591,7 @@ buf_LRU_mark_space_was_deleted( btr_search_s_unlock_all(); rw_lock_x_lock(&block->lock); - btr_search_drop_page_hash_index(block, NULL); + btr_search_drop_page_hash_index(block); rw_lock_x_unlock(&block->lock); btr_search_s_lock_all(); @@ -1726,8 +1742,7 @@ not_freed: /* Prevent buf_page_get_gen() from decompressing the block while we release buf_pool->mutex and block_mutex. */ - b->buf_fix_count++; - b->io_fix = BUF_IO_READ; + buf_page_set_sticky(b); mutex_exit(&buf_pool->zip_mutex); } @@ -1744,7 +1759,7 @@ not_freed: UNIV_MEM_VALID(((buf_block_t*) bpage)->frame, UNIV_PAGE_SIZE); - btr_search_drop_page_hash_index((buf_block_t*) bpage, NULL); + btr_search_drop_page_hash_index((buf_block_t*) bpage); UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame, UNIV_PAGE_SIZE); @@ -1772,8 +1787,7 @@ not_freed: if (b) { mutex_enter(&buf_pool->zip_mutex); - b->buf_fix_count--; - buf_page_set_io_fix(b, BUF_IO_NONE); + buf_page_unset_sticky(b); mutex_exit(&buf_pool->zip_mutex); } diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c index 07f22e4d1d6..98cf88455bd 100644 --- a/storage/xtradb/dict/dict0dict.c +++ b/storage/xtradb/dict/dict0dict.c @@ -919,6 +919,11 @@ dict_index_find_on_id_low( dict_table_t* table; dict_index_t* index; + /* This can happen if the system tablespace is the wrong page size */ + if (dict_sys == NULL) { + return(NULL); + } + table = UT_LIST_GET_FIRST(dict_sys->table_LRU); while (table) { diff --git a/storage/xtradb/dict/dict0load.c b/storage/xtradb/dict/dict0load.c index 47f969727fb..5303557548b 100644 --- a/storage/xtradb/dict/dict0load.c +++ b/storage/xtradb/dict/dict0load.c @@ -849,7 +849,7 @@ loop: object and check that the .ibd file exists. */ fil_open_single_table_tablespace(FALSE, space_id, - flags, name); + flags, name, NULL); } mem_free(name); @@ -1904,7 +1904,7 @@ err_exit: if (!fil_open_single_table_tablespace( TRUE, table->space, table->flags == DICT_TF_COMPACT ? 0 : - table->flags & ~(~0 << DICT_TF_BITS), name)) { + table->flags & ~(~0 << DICT_TF_BITS), name, NULL)) { /* We failed to find a sensible tablespace file */ diff --git a/storage/xtradb/fil/fil0fil.c b/storage/xtradb/fil/fil0fil.c index 41b61be0b5b..8cabf13e2c4 100644 --- a/storage/xtradb/fil/fil0fil.c +++ b/storage/xtradb/fil/fil0fil.c @@ -1827,36 +1827,44 @@ fil_write_flushed_lsn_to_data_files( } /*******************************************************************//** -Reads the flushed lsn and arch no fields from a data file at database -startup. */ +Reads the flushed lsn, arch no, and tablespace flag fields from a data +file at database startup. */ UNIV_INTERN void -fil_read_flushed_lsn_and_arch_log_no( -/*=================================*/ +fil_read_first_page( +/*================*/ os_file_t data_file, /*!< in: open data file */ ibool one_read_already, /*!< in: TRUE if min and max parameters below already contain sensible data */ + ulint* flags, /*!< out: tablespace flags */ #ifdef UNIV_LOG_ARCHIVE - ulint* min_arch_log_no, /*!< in/out: */ - ulint* max_arch_log_no, /*!< in/out: */ + ulint* min_arch_log_no, /*!< out: min of archived + log numbers in data files */ + ulint* max_arch_log_no, /*!< out: max of archived + log numbers in data files */ #endif /* UNIV_LOG_ARCHIVE */ - ib_uint64_t* min_flushed_lsn, /*!< in/out: */ - ib_uint64_t* max_flushed_lsn) /*!< in/out: */ + ib_uint64_t* min_flushed_lsn, /*!< out: min of flushed + lsn values in data files */ + ib_uint64_t* max_flushed_lsn) /*!< out: max of flushed + lsn values in data files */ { byte* buf; - byte* buf2; + page_t* page; ib_uint64_t flushed_lsn; - buf2 = ut_malloc(2 * UNIV_PAGE_SIZE); + buf = ut_malloc(2 * UNIV_PAGE_SIZE); /* Align the memory for a possible read from a raw device */ - buf = ut_align(buf2, UNIV_PAGE_SIZE); + page = ut_align(buf, UNIV_PAGE_SIZE); - os_file_read(data_file, buf, 0, 0, UNIV_PAGE_SIZE); + os_file_read(data_file, page, 0, 0, UNIV_PAGE_SIZE); - flushed_lsn = mach_read_from_8(buf + FIL_PAGE_FILE_FLUSH_LSN); + *flags = mach_read_from_4(page + + FSP_HEADER_OFFSET + FSP_SPACE_FLAGS); - ut_free(buf2); + flushed_lsn = mach_read_from_8(page + FIL_PAGE_FILE_FLUSH_LSN); + + ut_free(buf); if (!one_read_already) { *min_flushed_lsn = flushed_lsn; @@ -3174,8 +3182,11 @@ fil_open_single_table_tablespace( accessing the first page of the file */ ulint id, /*!< in: space id */ ulint flags, /*!< in: tablespace flags */ - const char* name) /*!< in: table name in the + const char* name, /*!< in: table name in the databasename/tablename format */ + trx_t* trx) /*!< in: transaction. This is only used + for IMPORT TABLESPACE, must be NULL + otherwise */ { os_file_t file; char* filepath; @@ -3393,6 +3404,11 @@ skip_info: /* over write space id of all pages */ rec_offs_init(offsets_); + /* Unlock the data dictionary to not block queries + accessing other tables */ + ut_a(trx); + row_mysql_unlock_data_dictionary(trx); + fprintf(stderr, "InnoDB: Progress in %%:"); for (offset = 0; offset < free_limit_bytes; @@ -3594,6 +3610,9 @@ skip_write: fprintf(stderr, " done.\n"); + /* Reacquire the data dictionary lock */ + row_mysql_lock_data_dictionary(trx); + /* update SYS_INDEXES set root page */ index = dict_table_get_first_index(table); while (index) { diff --git a/storage/xtradb/fsp/fsp0fsp.c b/storage/xtradb/fsp/fsp0fsp.c index 5e3959a3c7f..6102c5decd8 100644 --- a/storage/xtradb/fsp/fsp0fsp.c +++ b/storage/xtradb/fsp/fsp0fsp.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -11,8 +11,8 @@ 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 +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA *****************************************************************************/ @@ -50,67 +50,6 @@ Created 11/29/1995 Heikki Tuuri #include "dict0mem.h" #include "trx0sys.h" -#define FSP_HEADER_OFFSET FIL_PAGE_DATA /* Offset of the space header - within a file page */ - -/* The data structures in files are defined just as byte strings in C */ -typedef byte fsp_header_t; -typedef byte xdes_t; - -/* SPACE HEADER - ============ - -File space header data structure: this data structure is contained in the -first page of a space. The space for this header is reserved in every extent -descriptor page, but used only in the first. */ - -/*-------------------------------------*/ -#define FSP_SPACE_ID 0 /* space id */ -#define FSP_NOT_USED 4 /* this field contained a value up to - which we know that the modifications - in the database have been flushed to - the file space; not used now */ -#define FSP_SIZE 8 /* Current size of the space in - pages */ -#define FSP_FREE_LIMIT 12 /* Minimum page number for which the - free list has not been initialized: - the pages >= this limit are, by - definition, free; note that in a - single-table tablespace where size - < 64 pages, this number is 64, i.e., - we have initialized the space - about the first extent, but have not - physically allocted those pages to the - file */ -#define FSP_SPACE_FLAGS 16 /* table->flags & ~DICT_TF_COMPACT */ -#define FSP_FRAG_N_USED 20 /* number of used pages in the - FSP_FREE_FRAG list */ -#define FSP_FREE 24 /* list of free extents */ -#define FSP_FREE_FRAG (24 + FLST_BASE_NODE_SIZE) - /* list of partially free extents not - belonging to any segment */ -#define FSP_FULL_FRAG (24 + 2 * FLST_BASE_NODE_SIZE) - /* list of full extents not belonging - to any segment */ -#define FSP_SEG_ID (24 + 3 * FLST_BASE_NODE_SIZE) - /* 8 bytes which give the first unused - segment id */ -#define FSP_SEG_INODES_FULL (32 + 3 * FLST_BASE_NODE_SIZE) - /* list of pages containing segment - headers, where all the segment inode - slots are reserved */ -#define FSP_SEG_INODES_FREE (32 + 4 * FLST_BASE_NODE_SIZE) - /* list of pages containing segment - headers, where not all the segment - header slots are reserved */ -/*-------------------------------------*/ -/* File space header size */ -#define FSP_HEADER_SIZE (32 + 5 * FLST_BASE_NODE_SIZE) - -#define FSP_FREE_ADD 4 /* this many free extents are added - to the free list from above - FSP_FREE_LIMIT at a time */ - /* FILE SEGMENT INODE ================== diff --git a/storage/xtradb/ha/ha0ha.c b/storage/xtradb/ha/ha0ha.c index b28995553e0..2f5051e541f 100644 --- a/storage/xtradb/ha/ha0ha.c +++ b/storage/xtradb/ha/ha0ha.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -89,41 +89,6 @@ ha_create_func( } /*************************************************************//** -Empties a hash table and frees the memory heaps. */ -UNIV_INTERN -void -ha_clear( -/*=====*/ - hash_table_t* table) /*!< in, own: hash table */ -{ - ulint i; - ulint n; - - ut_ad(table); - ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); -#ifdef UNIV_SYNC_DEBUG - /* cannot identificate which btr_search_latch[i] for now */ - //ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE)); -#endif /* UNIV_SYNC_DEBUG */ - -#ifndef UNIV_HOTBACKUP - /* Free the memory heaps. */ - n = table->n_mutexes; - - for (i = 0; i < n; i++) { - mem_heap_free(table->heaps[i]); - } -#endif /* !UNIV_HOTBACKUP */ - - /* Clear the hash table. */ - n = hash_get_n_cells(table); - - for (i = 0; i < n; i++) { - hash_get_nth_cell(table, i)->node = NULL; - } -} - -/*************************************************************//** Inserts an entry into a hash table. If an entry with the same fold number is found, its node is updated to point to the new data, and no new node is inserted. If btr_search_enabled is set to FALSE, we will only allow @@ -141,7 +106,7 @@ ha_insert_for_fold_func( #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* block, /*!< in: buffer block containing the data */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - void* data) /*!< in: data, must not be NULL */ + const rec_t* data) /*!< in: data, must not be NULL */ { hash_cell_t* cell; ha_node_t* node; @@ -154,7 +119,11 @@ ha_insert_for_fold_func( #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG ut_a(block->frame == page_align(data)); #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ +#ifdef UNIV_SYNC_DEBUG + ut_ad(rw_lock_own(block->btr_search_latch, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ ASSERT_HASH_MUTEX_OWN(table, fold); + ut_ad(btr_search_enabled); hash = hash_calc_hash(fold, table); @@ -174,7 +143,6 @@ ha_insert_for_fold_func( prev_block->n_pointers--; block->n_pointers++; } - ut_ad(!btr_search_fully_disabled); # endif /* !UNIV_HOTBACKUP */ prev_node->block = block; @@ -187,13 +155,6 @@ ha_insert_for_fold_func( prev_node = prev_node->next; } - /* We are in the process of disabling hash index, do not add - new chain node */ - if (!btr_search_enabled) { - ut_ad(!btr_search_fully_disabled); - return(TRUE); - } - /* We have to allocate a new chain node */ node = mem_heap_alloc(hash_get_heap(table, fold), sizeof(ha_node_t)); @@ -251,6 +212,10 @@ ha_delete_hash_node( { ut_ad(table); ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); +#ifdef UNIV_SYNC_DEBUG + // ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ + ut_ad(btr_search_enabled); #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG # ifndef UNIV_HOTBACKUP if (table->adaptive) { @@ -273,11 +238,11 @@ ha_search_and_update_if_found_func( /*===============================*/ hash_table_t* table, /*!< in/out: hash table */ ulint fold, /*!< in: folded value of the searched data */ - void* data, /*!< in: pointer to the data */ + const rec_t* data, /*!< in: pointer to the data */ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* new_block,/*!< in: block containing new_data */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - void* new_data)/*!< in: new pointer to the data */ + const rec_t* new_data)/*!< in: new pointer to the data */ { ha_node_t* node; @@ -287,6 +252,13 @@ ha_search_and_update_if_found_func( #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG ut_a(new_block->frame == page_align(new_data)); #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ +#ifdef UNIV_SYNC_DEBUG + // ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ + + if (!btr_search_enabled) { + return; + } node = ha_search_with_data(table, fold, data); @@ -323,6 +295,10 @@ ha_remove_all_nodes_to_page( ut_ad(table); ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); ASSERT_HASH_MUTEX_OWN(table, fold); +#ifdef UNIV_SYNC_DEBUG + // ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ + ut_ad(btr_search_enabled); node = ha_chain_get_first(table, fold); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 3aa5ff1622d..ba5a7e1c3e0 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -3035,7 +3035,6 @@ skip_overwrite: /* Get the current high water mark format. */ innobase_file_format_max = (char*) trx_sys_file_format_max_get(); - btr_search_fully_disabled = (!btr_search_enabled); DBUG_RETURN(FALSE); error: DBUG_RETURN(TRUE); @@ -5839,8 +5838,7 @@ no_commit: switch (sql_command) { case SQLCOM_LOAD: - if ((trx->duplicates - & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))) { + if (trx->duplicates) { goto set_max_autoinc; } @@ -6128,8 +6126,7 @@ ha_innobase::update_row( && table->next_number_field && new_row == table->record[0] && thd_sql_command(user_thd) == SQLCOM_INSERT - && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE)) - == TRX_DUP_IGNORE) { + && trx->duplicates) { ulonglong auto_inc; ulonglong col_max_value; @@ -6515,6 +6512,7 @@ ha_innobase::index_read( (byte*) key_ptr, (ulint) key_len, prebuilt->trx); + DBUG_ASSERT(prebuilt->search_tuple->n_fields > 0); } else { /* We position the cursor to the last or the first entry in the index */ @@ -6616,7 +6614,6 @@ ha_innobase::innobase_get_index( dict_index_t* index = 0; DBUG_ENTER("innobase_get_index"); - ha_statistic_increment(&SSV::ha_read_key_count); if (keynr != MAX_KEY && table->s->keys > 0) { key = table->key_info + keynr; @@ -6630,13 +6627,13 @@ ha_innobase::innobase_get_index( table. Only print message if the index translation table exists */ if (share->idx_trans_tbl.index_mapping) { - sql_print_error("InnoDB could not find " - "index %s key no %u for " - "table %s through its " - "index translation table", - key ? key->name : "NULL", - keynr, - prebuilt->table->name); + sql_print_warning("InnoDB could not find " + "index %s key no %u for " + "table %s through its " + "index translation table", + key ? key->name : "NULL", + keynr, + prebuilt->table->name); } index = dict_table_get_index_on_name(prebuilt->table, @@ -8465,6 +8462,9 @@ ha_innobase::records_in_range( (const uchar*) 0), (ulint) (min_key ? min_key->length : 0), prebuilt->trx); + DBUG_ASSERT(min_key + ? range_start->n_fields > 0 + : range_start->n_fields == 0); row_sel_convert_mysql_key_to_innobase( range_end, (byte*) key_val_buff2, @@ -8473,6 +8473,9 @@ ha_innobase::records_in_range( (const uchar*) 0), (ulint) (max_key ? max_key->length : 0), prebuilt->trx); + DBUG_ASSERT(max_key + ? range_end->n_fields > 0 + : range_end->n_fields == 0); mode1 = convert_search_mode_to_innobase(min_key ? min_key->flag : HA_READ_KEY_EXACT); @@ -9217,7 +9220,10 @@ ha_innobase::check( putc('\n', stderr); #endif - if (!btr_validate_index(index, prebuilt->trx)) { + /* If this is an index being created, break */ + if (*index->name == TEMP_INDEX_PREFIX) { + break; + } else if (!btr_validate_index(index, prebuilt->trx)) { is_ok = FALSE; innobase_format_name( @@ -9770,6 +9776,7 @@ ha_innobase::extra( break; case HA_EXTRA_RESET_STATE: reset_template(); + thd_to_trx(ha_thd())->duplicates = 0; break; case HA_EXTRA_NO_KEYREAD: prebuilt->read_just_key = 0; @@ -9787,19 +9794,18 @@ ha_innobase::extra( parameters below. We must not invoke update_thd() either, because the calling threads may change. CAREFUL HERE, OR MEMORY CORRUPTION MAY OCCUR! */ - case HA_EXTRA_IGNORE_DUP_KEY: + case HA_EXTRA_INSERT_WITH_UPDATE: thd_to_trx(ha_thd())->duplicates |= TRX_DUP_IGNORE; break; + case HA_EXTRA_NO_IGNORE_DUP_KEY: + thd_to_trx(ha_thd())->duplicates &= ~TRX_DUP_IGNORE; + break; case HA_EXTRA_WRITE_CAN_REPLACE: thd_to_trx(ha_thd())->duplicates |= TRX_DUP_REPLACE; break; case HA_EXTRA_WRITE_CANNOT_REPLACE: thd_to_trx(ha_thd())->duplicates &= ~TRX_DUP_REPLACE; break; - case HA_EXTRA_NO_IGNORE_DUP_KEY: - thd_to_trx(ha_thd())->duplicates &= - ~(TRX_DUP_IGNORE | TRX_DUP_REPLACE); - break; default:/* Do nothing */ ; } @@ -12549,10 +12555,42 @@ static MYSQL_SYSVAR_ULINT(checkpoint_age_target, srv_checkpoint_age_target, "Control soft limit of checkpoint age. (0 : not control)", NULL, NULL, 0, 0, ~0UL, 0); -static MYSQL_SYSVAR_ULINT(flush_neighbor_pages, srv_flush_neighbor_pages, - PLUGIN_VAR_RQCMDARG, - "Enable/Disable flushing also neighbor pages. 0:disable 1:enable", - NULL, NULL, 1, 0, 1, 0); +static +void +innodb_flush_neighbor_pages_update( + THD* thd, + struct st_mysql_sys_var* var, + void* var_ptr, + const void* save) +{ + *(long *)var_ptr = (*(long *)save) % 3; +} + +const char *flush_neighbor_pages_names[]= +{ + "none", /* 0 */ + "area", + "cont", /* 2 */ + /* For compatibility with the older patch */ + "0", /* "none" + 3 */ + "1", /* "area" + 3 */ + "2", /* "cont" + 3 */ + NullS +}; + +TYPELIB flush_neighbor_pages_typelib= +{ + array_elements(flush_neighbor_pages_names) - 1, + "flush_neighbor_pages_typelib", + flush_neighbor_pages_names, + NULL +}; + +static MYSQL_SYSVAR_ENUM(flush_neighbor_pages, srv_flush_neighbor_pages, + PLUGIN_VAR_RQCMDARG, "Neighbor page flushing behaviour: none: do not flush, " + "[area]: flush selected pages one-by-one, " + "cont: flush a contiguous block of pages", NULL, + innodb_flush_neighbor_pages_update, 1, &flush_neighbor_pages_typelib); static void @@ -12618,6 +12656,14 @@ static MYSQL_SYSVAR_ENUM(adaptive_flushing_method, srv_adaptive_flushing_method, "Choose method of innodb_adaptive_flushing. (native, [estimate], keep_average)", NULL, innodb_adaptive_flushing_method_update, 1, &adaptive_flushing_method_typelib); +#ifdef UNIV_DEBUG +static MYSQL_SYSVAR_ULONG(flush_checkpoint_debug, srv_flush_checkpoint_debug, + PLUGIN_VAR_RQCMDARG, + "Debug flags for InnoDB flushing and checkpointing (0=none," + "1=stop preflush and checkpointing)", + NULL, NULL, 0, 0, 1, 0); +#endif + static MYSQL_SYSVAR_ULONG(import_table_from_xtrabackup, srv_expand_import, PLUGIN_VAR_RQCMDARG, "Enable/Disable converting automatically *.ibd files when import tablespace.", @@ -12764,6 +12810,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(purge_threads), MYSQL_SYSVAR(purge_batch_size), MYSQL_SYSVAR(rollback_segments), +#ifdef UNIV_DEBUG + MYSQL_SYSVAR(flush_checkpoint_debug), +#endif MYSQL_SYSVAR(corrupt_table_action), MYSQL_SYSVAR(lazy_drop_table), MYSQL_SYSVAR(fake_changes), @@ -13017,28 +13066,6 @@ bool ha_innobase::is_thd_killed() * Index Condition Pushdown interface implementation */ -/*************************************************************//** -InnoDB index push-down condition check -@return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */ -extern "C" UNIV_INTERN -enum icp_result -innobase_index_cond( -/*================*/ - void* file) /*!< in/out: pointer to ha_innobase */ -{ - ha_innobase *h= (ha_innobase*) file; - - if (h->is_thd_killed()) - return ICP_ABORTED_BY_USER; - - if (h->end_range) - { - if (h->compare_key2(h->end_range) > 0) - return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */ - } - return h->pushed_idx_cond->val_int()? ICP_MATCH : ICP_NO_MATCH; -} - /** Attempt to push down an index condition. * @param[in] keyno MySQL key number * @param[in] idx_cond Index condition to be checked diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h index 628ba536eb9..7e11e72b7c1 100644 --- a/storage/xtradb/handler/ha_innodb.h +++ b/storage/xtradb/handler/ha_innodb.h @@ -227,6 +227,7 @@ class ha_innobase: public handler bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes); bool check_if_supported_virtual_columns(void) { return TRUE; } + private: /** Builds a 'template' to the prebuilt struct. diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc index 72ff5f7198b..3b87b860a4a 100644 --- a/storage/xtradb/handler/i_s.cc +++ b/storage/xtradb/handler/i_s.cc @@ -3916,7 +3916,7 @@ i_s_innodb_buffer_pool_pages_index_fill( table->field[2]->store(block->page.offset, TRUE); table->field[3]->store(page_get_n_recs(frame), TRUE); table->field[4]->store(page_get_data_size(frame), TRUE); - table->field[5]->store(block->is_hashed, TRUE); + table->field[5]->store(block->index != NULL, TRUE); table->field[6]->store(block->page.access_time, TRUE); table->field[7]->store(block->page.newest_modification != 0, TRUE); table->field[8]->store(block->page.oldest_modification != 0, TRUE); diff --git a/storage/xtradb/ibuf/ibuf0ibuf.c b/storage/xtradb/ibuf/ibuf0ibuf.c index 7def360867d..00b7ea7347d 100644 --- a/storage/xtradb/ibuf/ibuf0ibuf.c +++ b/storage/xtradb/ibuf/ibuf0ibuf.c @@ -254,11 +254,20 @@ ibuf_count_check( list of the ibuf */ /* @} */ +#define IBUF_REC_FIELD_SPACE 0 /*!< in the pre-4.1 format, + the page number. later, the space_id */ +#define IBUF_REC_FIELD_MARKER 1 /*!< starting with 4.1, a marker + consisting of 1 byte that is 0 */ +#define IBUF_REC_FIELD_PAGE 2 /*!< starting with 4.1, the + page number */ +#define IBUF_REC_FIELD_METADATA 3 /* the metadata field */ +#define IBUF_REC_FIELD_USER 4 /* first user field */ + /* Various constants for checking the type of an ibuf record and extracting data from it. For details, see the description of the record format at the top of this file. */ -/** @name Format of the fourth column of an insert buffer record +/** @name Format of the IBUF_REC_FIELD_METADATA of an insert buffer record The fourth column in the MySQL 5.5 format contains an operation type, counter, and some flags. */ /* @{ */ @@ -1275,13 +1284,13 @@ ibuf_rec_get_page_no_func( ut_ad(ibuf_inside(mtr)); ut_ad(rec_get_n_fields_old(rec) > 2); - field = rec_get_nth_field_old(rec, 1, &len); + field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_MARKER, &len); if (len == 1) { /* This is of the >= 4.1.x record format */ ut_a(trx_sys_multiple_tablespace_format); - field = rec_get_nth_field_old(rec, 2, &len); + field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_PAGE, &len); } else { ut_a(trx_doublewrite_must_reset_space_ids); ut_a(!trx_sys_multiple_tablespace_format); @@ -1321,13 +1330,13 @@ ibuf_rec_get_space_func( ut_ad(ibuf_inside(mtr)); ut_ad(rec_get_n_fields_old(rec) > 2); - field = rec_get_nth_field_old(rec, 1, &len); + field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_MARKER, &len); if (len == 1) { /* This is of the >= 4.1.x record format */ ut_a(trx_sys_multiple_tablespace_format); - field = rec_get_nth_field_old(rec, 0, &len); + field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_SPACE, &len); ut_a(len == 4); return(mach_read_from_4(field)); @@ -1377,9 +1386,9 @@ ibuf_rec_get_info_func( || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX)); ut_ad(ibuf_inside(mtr)); fields = rec_get_n_fields_old(rec); - ut_a(fields > 4); + ut_a(fields > IBUF_REC_FIELD_USER); - types = rec_get_nth_field_old(rec, 3, &len); + types = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len); info_len_local = len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE; @@ -1405,7 +1414,8 @@ ibuf_rec_get_info_func( ut_a(op_local < IBUF_OP_COUNT); ut_a((len - info_len_local) == - (fields - 4) * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE); + (fields - IBUF_REC_FIELD_USER) + * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE); if (op) { *op = op_local; @@ -1449,7 +1459,7 @@ ibuf_rec_get_op_type_func( ut_ad(ibuf_inside(mtr)); ut_ad(rec_get_n_fields_old(rec) > 2); - (void) rec_get_nth_field_old(rec, 1, &len); + (void) rec_get_nth_field_old(rec, IBUF_REC_FIELD_MARKER, &len); if (len > 1) { /* This is a < 4.1.x format record */ @@ -1478,12 +1488,12 @@ ibuf_rec_get_counter( const byte* ptr; ulint len; - if (rec_get_n_fields_old(rec) < 4) { + if (rec_get_n_fields_old(rec) <= IBUF_REC_FIELD_METADATA) { return(ULINT_UNDEFINED); } - ptr = rec_get_nth_field_old(rec, 3, &len); + ptr = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len); if (len >= 2) { @@ -1708,7 +1718,7 @@ ibuf_build_entry_from_ibuf_rec_func( || mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_S_FIX)); ut_ad(ibuf_inside(mtr)); - data = rec_get_nth_field_old(ibuf_rec, 1, &len); + data = rec_get_nth_field_old(ibuf_rec, IBUF_REC_FIELD_MARKER, &len); if (len > 1) { /* This a < 4.1.x format record */ @@ -1720,13 +1730,13 @@ ibuf_build_entry_from_ibuf_rec_func( ut_a(trx_sys_multiple_tablespace_format); ut_a(*data == 0); - ut_a(rec_get_n_fields_old(ibuf_rec) > 4); + ut_a(rec_get_n_fields_old(ibuf_rec) > IBUF_REC_FIELD_USER); - n_fields = rec_get_n_fields_old(ibuf_rec) - 4; + n_fields = rec_get_n_fields_old(ibuf_rec) - IBUF_REC_FIELD_USER; tuple = dtuple_create(heap, n_fields); - types = rec_get_nth_field_old(ibuf_rec, 3, &len); + types = rec_get_nth_field_old(ibuf_rec, IBUF_REC_FIELD_METADATA, &len); ibuf_rec_get_info(mtr, ibuf_rec, NULL, &comp, &info_len, NULL); @@ -1740,7 +1750,8 @@ ibuf_build_entry_from_ibuf_rec_func( for (i = 0; i < n_fields; i++) { field = dtuple_get_nth_field(tuple, i); - data = rec_get_nth_field_old(ibuf_rec, i + 4, &len); + data = rec_get_nth_field_old( + ibuf_rec, i + IBUF_REC_FIELD_USER, &len); dfield_set_data(field, data, len); @@ -1787,7 +1798,7 @@ ibuf_rec_get_size( field_offset = 2; types_offset = DATA_ORDER_NULL_TYPE_BUF_SIZE; } else { - field_offset = 4; + field_offset = IBUF_REC_FIELD_USER; types_offset = DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE; } @@ -1848,7 +1859,7 @@ ibuf_rec_get_volume_func( ut_ad(ibuf_inside(mtr)); ut_ad(rec_get_n_fields_old(ibuf_rec) > 2); - data = rec_get_nth_field_old(ibuf_rec, 1, &len); + data = rec_get_nth_field_old(ibuf_rec, IBUF_REC_FIELD_MARKER, &len); pre_4_1 = (len > 1); if (pre_4_1) { @@ -1871,7 +1882,8 @@ ibuf_rec_get_volume_func( ut_a(trx_sys_multiple_tablespace_format); ut_a(*data == 0); - types = rec_get_nth_field_old(ibuf_rec, 3, &len); + types = rec_get_nth_field_old( + ibuf_rec, IBUF_REC_FIELD_METADATA, &len); ibuf_rec_get_info(mtr, ibuf_rec, &op, &comp, &info_len, NULL); @@ -1901,7 +1913,8 @@ ibuf_rec_get_volume_func( } types += info_len; - n_fields = rec_get_n_fields_old(ibuf_rec) - 4; + n_fields = rec_get_n_fields_old(ibuf_rec) + - IBUF_REC_FIELD_USER; } data_size = ibuf_rec_get_size(ibuf_rec, types, n_fields, pre_4_1, comp); @@ -1956,11 +1969,11 @@ ibuf_entry_build( n_fields = dtuple_get_n_fields(entry); - tuple = dtuple_create(heap, n_fields + 4); + tuple = dtuple_create(heap, n_fields + IBUF_REC_FIELD_USER); /* 1) Space Id */ - field = dtuple_get_nth_field(tuple, 0); + field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_SPACE); buf = mem_heap_alloc(heap, 4); @@ -1970,7 +1983,7 @@ ibuf_entry_build( /* 2) Marker byte */ - field = dtuple_get_nth_field(tuple, 1); + field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_MARKER); buf = mem_heap_alloc(heap, 1); @@ -1982,7 +1995,7 @@ ibuf_entry_build( /* 3) Page number */ - field = dtuple_get_nth_field(tuple, 2); + field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_PAGE); buf = mem_heap_alloc(heap, 4); @@ -2030,10 +2043,7 @@ ibuf_entry_build( ulint fixed_len; const dict_field_t* ifield; - /* We add 4 below because we have the 4 extra fields at the - start of an ibuf record */ - - field = dtuple_get_nth_field(tuple, i + 4); + field = dtuple_get_nth_field(tuple, i + IBUF_REC_FIELD_USER); entry_field = dtuple_get_nth_field(entry, i); dfield_copy(field, entry_field); @@ -2066,13 +2076,13 @@ ibuf_entry_build( /* 4) Type info, part #2 */ - field = dtuple_get_nth_field(tuple, 3); + field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_METADATA); dfield_set_data(field, type_info, ti - type_info); /* Set all the types in the new tuple binary */ - dtuple_set_types_binary(tuple, n_fields + 4); + dtuple_set_types_binary(tuple, n_fields + IBUF_REC_FIELD_USER); return(tuple); } @@ -2132,11 +2142,11 @@ ibuf_new_search_tuple_build( ut_a(trx_sys_multiple_tablespace_format); - tuple = dtuple_create(heap, 3); + tuple = dtuple_create(heap, IBUF_REC_FIELD_METADATA); /* Store the space id in tuple */ - field = dtuple_get_nth_field(tuple, 0); + field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_SPACE); buf = mem_heap_alloc(heap, 4); @@ -2146,7 +2156,7 @@ ibuf_new_search_tuple_build( /* Store the new format record marker byte */ - field = dtuple_get_nth_field(tuple, 1); + field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_MARKER); buf = mem_heap_alloc(heap, 1); @@ -2156,7 +2166,7 @@ ibuf_new_search_tuple_build( /* Store the page number in tuple */ - field = dtuple_get_nth_field(tuple, 2); + field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_PAGE); buf = mem_heap_alloc(heap, 4); @@ -2164,7 +2174,7 @@ ibuf_new_search_tuple_build( dfield_set_data(field, buf, 4); - dtuple_set_types_binary(tuple, 3); + dtuple_set_types_binary(tuple, IBUF_REC_FIELD_METADATA); return(tuple); } @@ -2833,8 +2843,10 @@ ibuf_get_volume_buffered_hash( ulint fold; ulint bitmask; - len = ibuf_rec_get_size(rec, types, rec_get_n_fields_old(rec) - 4, - FALSE, comp); + len = ibuf_rec_get_size( + rec, types, + rec_get_n_fields_old(rec) - IBUF_REC_FIELD_USER, + FALSE, comp); fold = ut_fold_binary(data, len); hash += (fold / (CHAR_BIT * sizeof *hash)) % size; @@ -2886,8 +2898,8 @@ ibuf_get_volume_buffered_count_func( ut_ad(ibuf_inside(mtr)); n_fields = rec_get_n_fields_old(rec); - ut_ad(n_fields > 4); - n_fields -= 4; + ut_ad(n_fields > IBUF_REC_FIELD_USER); + n_fields -= IBUF_REC_FIELD_USER; rec_get_nth_field_offs_old(rec, 1, &len); /* This function is only invoked when buffering new @@ -2896,7 +2908,7 @@ ibuf_get_volume_buffered_count_func( ut_a(len == 1); ut_ad(trx_sys_multiple_tablespace_format); - types = rec_get_nth_field_old(rec, 3, &len); + types = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len); switch (UNIV_EXPECT(len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE, IBUF_REC_INFO_SIZE)) { @@ -3208,7 +3220,7 @@ ibuf_update_max_tablespace_id(void) } else { rec = btr_pcur_get_rec(&pcur); - field = rec_get_nth_field_old(rec, 0, &len); + field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_SPACE, &len); ut_a(len == 4); @@ -3230,10 +3242,12 @@ ibuf_update_max_tablespace_id(void) ibuf_get_entry_counter_low_func(rec,space,page_no) #endif /****************************************************************//** -Helper function for ibuf_set_entry_counter. Checks if rec is for (space, -page_no), and if so, reads counter value from it and returns that + 1. -Otherwise, returns 0. -@return new counter value, or 0 */ +Helper function for ibuf_get_entry_counter_func. Checks if rec is for +(space, page_no), and if so, reads counter value from it and returns +that + 1. +@retval ULINT_UNDEFINED if the record does not contain any counter +@retval 0 if the record is not for (space, page_no) +@retval 1 + previous counter value, otherwise */ static ulint ibuf_get_entry_counter_low_func( @@ -3254,7 +3268,7 @@ ibuf_get_entry_counter_low_func( || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX)); ut_ad(rec_get_n_fields_old(rec) > 2); - field = rec_get_nth_field_old(rec, 1, &len); + field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_MARKER, &len); if (UNIV_UNLIKELY(len != 1)) { /* pre-4.1 format */ @@ -3267,7 +3281,7 @@ ibuf_get_entry_counter_low_func( ut_a(trx_sys_multiple_tablespace_format); /* Check the tablespace identifier. */ - field = rec_get_nth_field_old(rec, 0, &len); + field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_SPACE, &len); ut_a(len == 4); if (mach_read_from_4(field) != space) { @@ -3276,7 +3290,7 @@ ibuf_get_entry_counter_low_func( } /* Check the page offset. */ - field = rec_get_nth_field_old(rec, 2, &len); + field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_PAGE, &len); ut_a(len == 4); if (mach_read_from_4(field) != page_no) { @@ -3285,7 +3299,7 @@ ibuf_get_entry_counter_low_func( } /* Check if the record contains a counter field. */ - field = rec_get_nth_field_old(rec, 3, &len); + field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len); switch (len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE) { default: @@ -3301,147 +3315,61 @@ ibuf_get_entry_counter_low_func( } } +#ifdef UNIV_DEBUG +# define ibuf_get_entry_counter(space,page_no,rec,mtr,exact_leaf) \ + ibuf_get_entry_counter_func(space,page_no,rec,mtr,exact_leaf) +#else /* UNIV_DEBUG */ +# define ibuf_get_entry_counter(space,page_no,rec,mtr,exact_leaf) \ + ibuf_get_entry_counter_func(space,page_no,rec,exact_leaf) +#endif + /****************************************************************//** -Set the counter field in entry to the correct value based on the current +Calculate the counter field for an entry based on the current last record in ibuf for (space, page_no). -@return FALSE if we should abort this insertion to ibuf */ +@return the counter field, or ULINT_UNDEFINED +if we should abort this insertion to ibuf */ static -ibool -ibuf_set_entry_counter( -/*===================*/ - dtuple_t* entry, /*!< in/out: entry to patch */ +ulint +ibuf_get_entry_counter_func( +/*========================*/ ulint space, /*!< in: space id of entry */ ulint page_no, /*!< in: page number of entry */ - btr_pcur_t* pcur, /*!< in: pcur positioned on the record - found by btr_pcur_open(.., entry, - PAGE_CUR_LE, ..., pcur, ...) */ - ibool is_optimistic, /*!< in: is this an optimistic insert */ - mtr_t* mtr) /*!< in: mtr */ + const rec_t* rec, /*!< in: the record preceding the + insertion point */ +#ifdef UNIV_DEBUG + mtr_t* mtr, /*!< in: mini-transaction */ +#endif /* UNIV_DEBUG */ + ibool only_leaf) /*!< in: TRUE if this is the only + leaf page that can contain entries + for (space,page_no), that is, there + was no exact match for (space,page_no) + in the node pointer */ { - dfield_t* field; - byte* data; - ulint counter = 0; - - /* pcur points to either a user rec or to a page's infimum record. */ ut_ad(ibuf_inside(mtr)); - ut_ad(mtr_memo_contains(mtr, btr_pcur_get_block(pcur), - MTR_MEMO_PAGE_X_FIX)); - ut_ad(page_validate(btr_pcur_get_page(pcur), ibuf->index)); - - if (btr_pcur_is_on_user_rec(pcur)) { - - counter = ibuf_get_entry_counter_low( - mtr, btr_pcur_get_rec(pcur), space, page_no); - - if (UNIV_UNLIKELY(counter == ULINT_UNDEFINED)) { - /* The record lacks a counter field. - Such old records must be merged before - new records can be buffered. */ - - return(FALSE); - } - } else if (btr_pcur_is_before_first_in_tree(pcur, mtr)) { - /* Ibuf tree is either completely empty, or the insert - position is at the very first record of a non-empty tree. In - either case we have no previous records for (space, - page_no). */ - - counter = 0; - } else if (btr_pcur_is_before_first_on_page(pcur)) { - btr_cur_t* cursor = btr_pcur_get_btr_cur(pcur); - - if (cursor->low_match < 3) { - /* If low_match < 3, we know that the father node - pointer did not contain the searched for (space, - page_no), which means that the search ended on the - right page regardless of the counter value, and - since we're at the infimum record, there are no - existing records. */ - - counter = 0; - } else { - rec_t* rec; - const page_t* page; - buf_block_t* block; - page_t* prev_page; - ulint prev_page_no; - - ut_a(cursor->ibuf_cnt != ULINT_UNDEFINED); - - page = btr_pcur_get_page(pcur); - prev_page_no = btr_page_get_prev(page, mtr); - - ut_a(prev_page_no != FIL_NULL); - - block = buf_page_get( - IBUF_SPACE_ID, 0, prev_page_no, - RW_X_LATCH, mtr); + ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)); + ut_ad(page_validate(page_align(rec), ibuf->index)); - buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE); - - prev_page = buf_block_get_frame(block); - - rec = page_rec_get_prev( - page_get_supremum_rec(prev_page)); - - ut_ad(page_rec_is_user_rec(rec)); - - counter = ibuf_get_entry_counter_low( - mtr, rec, space, page_no); - - if (UNIV_UNLIKELY(counter == ULINT_UNDEFINED)) { - /* The record lacks a counter field. - Such old records must be merged before - new records can be buffered. */ - - return(FALSE); - } - - if (counter < cursor->ibuf_cnt) { - /* Search ended on the wrong page. */ - - if (is_optimistic) { - /* In an optimistic insert, we can - shift the insert position to the left - page, since it only needs an X-latch - on the page itself, which the - original search acquired for us. */ - - btr_cur_position( - ibuf->index, rec, block, - btr_pcur_get_btr_cur(pcur)); - } else { - /* We can't shift the insert - position to the left page in a - pessimistic insert since it would - require an X-latch on the left - page's left page, so we have to - abort. */ - - return(FALSE); - } - } else { - /* The counter field in the father node is - the same as we would insert; we don't know - whether the insert should go to this page or - the left page (the later fields can differ), - so refuse the insert. */ - - return(FALSE); - } - } + if (page_rec_is_supremum(rec)) { + /* This is just for safety. The record should be a + page infimum or a user record. */ + ut_ad(0); + return(ULINT_UNDEFINED); + } else if (!page_rec_is_infimum(rec)) { + return(ibuf_get_entry_counter_low(mtr, rec, space, page_no)); + } else if (only_leaf + || fil_page_get_prev(page_align(rec)) == FIL_NULL) { + /* The parent node pointer did not contain the + searched for (space, page_no), which means that the + search ended on the correct page regardless of the + counter value, and since we're at the infimum record, + there are no existing records. */ + return(0); } else { - /* The cursor is not positioned at or before a user record. */ - return(FALSE); + /* We used to read the previous page here. It would + break the latching order, because the caller has + buffer-fixed an insert buffer bitmap page. */ + return(ULINT_UNDEFINED); } - - /* Patch counter value in already built entry. */ - field = dtuple_get_nth_field(entry, 3); - data = dfield_get_data(field); - - mach_write_to_2(data + IBUF_REC_OFFSET_COUNTER, counter); - - return(TRUE); } /*********************************************************************//** @@ -3650,16 +3578,27 @@ fail_exit: } } - /* Patch correct counter value to the entry to insert. This can - change the insert position, which can result in the need to abort in - some cases. */ - if (!no_counter - && !ibuf_set_entry_counter(ibuf_entry, space, page_no, &pcur, - mode == BTR_MODIFY_PREV, &mtr)) { + if (!no_counter) { + /* Patch correct counter value to the entry to + insert. This can change the insert position, which can + result in the need to abort in some cases. */ + ulint counter = ibuf_get_entry_counter( + space, page_no, btr_pcur_get_rec(&pcur), &mtr, + btr_pcur_get_btr_cur(&pcur)->low_match + < IBUF_REC_FIELD_METADATA); + dfield_t* field; + + if (counter == ULINT_UNDEFINED) { bitmap_fail: - ibuf_mtr_commit(&bitmap_mtr); + ibuf_mtr_commit(&bitmap_mtr); + goto fail_exit; + } - goto fail_exit; + field = dtuple_get_nth_field( + ibuf_entry, IBUF_REC_FIELD_METADATA); + mach_write_to_2( + (byte*) dfield_get_data(field) + + IBUF_REC_OFFSET_COUNTER, counter); } /* Set the bitmap bit denoting that the insert buffer contains @@ -4003,7 +3942,7 @@ ibuf_insert_to_index_page( ut_ad(ibuf_inside(mtr)); ut_ad(dtuple_check_typed(entry)); - ut_ad(!buf_block_align(page)->is_hashed); + ut_ad(!buf_block_align(page)->index); if (UNIV_UNLIKELY(dict_table_is_comp(index->table) != (ibool)!!page_is_comp(page))) { diff --git a/storage/xtradb/include/btr0cur.h b/storage/xtradb/include/btr0cur.h index be918439f59..4f33aacc48e 100644 --- a/storage/xtradb/include/btr0cur.h +++ b/storage/xtradb/include/btr0cur.h @@ -743,24 +743,6 @@ struct btr_cur_struct { NULL */ ulint fold; /*!< fold value used in the search if flag is BTR_CUR_HASH */ - /*----- Delete buffering -------*/ - ulint ibuf_cnt; /* in searches done on insert buffer - trees, this contains the "counter" - value (the first two bytes of the - fourth field) extracted from the - page above the leaf page, from the - father node pointer that pointed to - the leaf page. in other words, it - contains the minimum counter value - for records to be inserted on the - chosen leaf page. If for some reason - this can't be read, or if the search - ended on the leftmost leaf page in - the tree (in which case the father - node pointer had the 'minimum - record' flag set), this is - ULINT_UNDEFINED. */ - /*------------------------------*/ /* @} */ btr_path_t* path_arr; /*!< in estimating the number of rows in range, we store in this array diff --git a/storage/xtradb/include/btr0pcur.h b/storage/xtradb/include/btr0pcur.h index f605c476844..140f94466db 100644 --- a/storage/xtradb/include/btr0pcur.h +++ b/storage/xtradb/include/btr0pcur.h @@ -263,14 +263,6 @@ btr_pcur_commit_specify_mtr( /*========================*/ btr_pcur_t* pcur, /*!< in: persistent cursor */ mtr_t* mtr); /*!< in: mtr to commit */ -/**************************************************************//** -Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES. -@return TRUE if detached */ -UNIV_INLINE -ibool -btr_pcur_is_detached( -/*=================*/ - btr_pcur_t* pcur); /*!< in: persistent cursor */ /*********************************************************//** Moves the persistent cursor to the next record in the tree. If no records are left, the cursor stays 'after last in tree'. diff --git a/storage/xtradb/include/btr0pcur.ic b/storage/xtradb/include/btr0pcur.ic index d86601e5a32..054ce753c7d 100644 --- a/storage/xtradb/include/btr0pcur.ic +++ b/storage/xtradb/include/btr0pcur.ic @@ -389,38 +389,6 @@ btr_pcur_commit_specify_mtr( } /**************************************************************//** -Sets the pcur latch mode to BTR_NO_LATCHES. */ -UNIV_INLINE -void -btr_pcur_detach( -/*============*/ - btr_pcur_t* pcur) /*!< in: persistent cursor */ -{ - ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED); - - pcur->latch_mode = BTR_NO_LATCHES; - - pcur->pos_state = BTR_PCUR_WAS_POSITIONED; -} - -/**************************************************************//** -Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES. -@return TRUE if detached */ -UNIV_INLINE -ibool -btr_pcur_is_detached( -/*=================*/ - btr_pcur_t* pcur) /*!< in: persistent cursor */ -{ - if (pcur->latch_mode == BTR_NO_LATCHES) { - - return(TRUE); - } - - return(FALSE); -} - -/**************************************************************//** Sets the old_rec_buf field to NULL. */ UNIV_INLINE void diff --git a/storage/xtradb/include/btr0sea.h b/storage/xtradb/include/btr0sea.h index 9e82602934e..d9f2cf9c81b 100644 --- a/storage/xtradb/include/btr0sea.h +++ b/storage/xtradb/include/btr0sea.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -137,11 +137,10 @@ UNIV_INTERN void btr_search_drop_page_hash_index( /*============================*/ - buf_block_t* block, /*!< in: block containing index page, + buf_block_t* block); /*!< in: block containing index page, s- or x-latched, or an index page for which we know that block->buf_fix_count == 0 */ - dict_index_t* index_in); /************************************************************************ Drops a page hash index based on index */ UNIV_INTERN @@ -150,8 +149,8 @@ btr_search_drop_page_hash_index_on_index( /*=====================================*/ dict_index_t* index); /* in: record descriptor */ /********************************************************************//** -Drops a page hash index when a page is freed from a fseg to the file system. -Drops possible hash index if the page happens to be in the buffer pool. */ +Drops a possible page hash index when a page is evicted from the buffer pool +or freed in a file segment. */ UNIV_INTERN void btr_search_drop_page_hash_when_freed( @@ -235,19 +234,6 @@ void btr_search_s_unlock_all(void); /*==========================*/ - -/** Flag: has the search system been enabled? -Protected by btr_search_latch and btr_search_enabled_mutex. */ -extern char btr_search_enabled; - -extern ulint btr_search_index_num; - -/** Flag: whether the search system has completed its disabling process, -It is set to TRUE right after buf_pool_drop_hash_index() in -btr_search_disable(), indicating hash index entries are cleaned up. -Protected by btr_search_latch and btr_search_enabled_mutex. */ -extern ibool btr_search_fully_disabled; - /** The search info struct in an index */ struct btr_search_struct{ ulint ref_count; /*!< Number of blocks in this index tree @@ -316,26 +302,6 @@ struct btr_search_sys_struct{ /** The adaptive hash index */ extern btr_search_sys_t* btr_search_sys; -/** @brief The latch protecting the adaptive search system - -This latch protects the -(1) hash index; -(2) columns of a record to which we have a pointer in the hash index; - -but does NOT protect: - -(3) next record offset field in a record; -(4) next or previous records on the same page. - -Bear in mind (3) and (4) when using the hash index. -*/ -//extern rw_lock_t* btr_search_latch_temp; - -extern rw_lock_t** btr_search_latch_part; - -/** The latch protecting the adaptive search system */ -//#define btr_search_latch (*btr_search_latch_temp) - #ifdef UNIV_SEARCH_PERF_STAT /** Number of successful adaptive hash index lookups */ extern ulint btr_search_n_succ; diff --git a/storage/xtradb/include/btr0types.h b/storage/xtradb/include/btr0types.h index 07c06fb18d7..6f515c3f58c 100644 --- a/storage/xtradb/include/btr0types.h +++ b/storage/xtradb/include/btr0types.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -30,6 +30,7 @@ Created 2/17/1996 Heikki Tuuri #include "rem0types.h" #include "page0types.h" +#include "sync0rw.h" /** Persistent cursor */ typedef struct btr_pcur_struct btr_pcur_t; @@ -38,6 +39,32 @@ typedef struct btr_cur_struct btr_cur_t; /** B-tree search information for the adaptive hash index */ typedef struct btr_search_struct btr_search_t; +/** @brief The latch protecting the adaptive search system + +This latch protects the +(1) hash index; +(2) columns of a record to which we have a pointer in the hash index; + +but does NOT protect: + +(3) next record offset field in a record; +(4) next or previous records on the same page. + +Bear in mind (3) and (4) when using the hash index. +*/ +//extern rw_lock_t* btr_search_latch_temp; + +extern rw_lock_t** btr_search_latch_part; + +/** The latch protecting the adaptive search system */ +//#define btr_search_latch (*btr_search_latch_temp) + +/** Flag: has the search system been enabled? +Protected by btr_search_latch. */ +extern char btr_search_enabled; + +extern ulint btr_search_index_num; + #ifdef UNIV_BLOB_DEBUG # include "buf0types.h" /** An index->blobs entry for keeping track of off-page column references */ diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h index d85dac5cc91..0ea74fb9eb2 100644 --- a/storage/xtradb/include/buf0buf.h +++ b/storage/xtradb/include/buf0buf.h @@ -244,13 +244,11 @@ buf_pool_free( ulint n_instances); /*!< in: numbere of instances to free */ /********************************************************************//** -Drops the adaptive hash index. To prevent a livelock, this function -is only to be called while holding btr_search_latch and while -btr_search_enabled == FALSE. */ +Clears the adaptive hash index on all pages in the buffer pool. */ UNIV_INTERN void -buf_pool_drop_hash_index(void); -/*==========================*/ +buf_pool_clear_hash_index(void); +/*===========================*/ /********************************************************************//** Relocate a buffer control block. Relocates the block on the LRU list @@ -583,17 +581,6 @@ buf_page_peek_if_too_old( /*=====================*/ const buf_page_t* bpage); /*!< in: block to make younger */ /********************************************************************//** -Returns the current state of is_hashed of a page. FALSE if the page is -not in the pool. NOTE that this operation does not fix the page in the -pool if it is found there. -@return TRUE if page hash index is built in search system */ -UNIV_INTERN -ibool -buf_page_peek_if_search_hashed( -/*===========================*/ - ulint space, /*!< in: space id */ - ulint offset);/*!< in: page number */ -/********************************************************************//** Gets the youngest modification log sequence number for a frame. Returns zero if not file page or no modification occurred yet. @return newest modification to page */ @@ -952,7 +939,27 @@ buf_block_set_io_fix( /*=================*/ buf_block_t* block, /*!< in/out: control block */ enum buf_io_fix io_fix);/*!< in: io_fix state */ - +/*********************************************************************//** +Makes a block sticky. A sticky block implies that even after we release +the buf_pool->mutex and the block->mutex: +* it cannot be removed from the flush_list +* the block descriptor cannot be relocated +* it cannot be removed from the LRU list +Note that: +* the block can still change its position in the LRU list +* the next and previous pointers can change. */ +UNIV_INLINE +void +buf_page_set_sticky( +/*================*/ + buf_page_t* bpage); /*!< in/out: control block */ +/*********************************************************************//** +Removes stickiness of a block. */ +UNIV_INLINE +void +buf_page_unset_sticky( +/*==================*/ + buf_page_t* bpage); /*!< in/out: control block */ /********************************************************************//** Determine if a buffer block can be relocated in memory. The block can be dirty, but it must not be I/O-fixed or bufferfixed. */ @@ -1569,13 +1576,16 @@ struct buf_block_struct{ /* @} */ /** @name Hash search fields - These 6 fields may only be modified when we have + These 5 fields may only be modified when we have an x-latch on btr_search_latch AND - we are holding an s-latch or x-latch on buf_block_struct::lock or - we know that buf_block_struct::buf_fix_count == 0. An exception to this is when we init or create a page - in the buffer pool in buf0buf.c. */ + in the buffer pool in buf0buf.c. + + Another exception is that assigning block->index = NULL + is allowed whenever holding an x-latch on btr_search_latch. */ /* @{ */ @@ -1584,21 +1594,21 @@ struct buf_block_struct{ pointers in the adaptive hash index pointing to this frame */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - volatile unsigned is_hashed:1; /*!< TRUE if hash index has - already been built on this - page; note that it does not - guarantee that the index is - complete, though: there may - have been hash collisions, - record deletions, etc. */ unsigned curr_n_fields:10;/*!< prefix length for hash indexing: number of full fields */ unsigned curr_n_bytes:15;/*!< number of bytes in hash indexing */ unsigned curr_left_side:1;/*!< TRUE or FALSE in hash indexing */ - dict_index_t* index; /*!< Index for which the adaptive - hash index has been created. */ - volatile rw_lock_t* btr_search_latch; + dict_index_t* index; /*!< Index for which the + adaptive hash index has been + created, or NULL if the page + does not exist in the + index. Note that it does not + guarantee that the index is + complete, though: there may + have been hash collisions, + record deletions, etc. */ + volatile rw_lock_t* btr_search_latch; /* @} */ # ifdef UNIV_SYNC_DEBUG /** @name Debug fields */ diff --git a/storage/xtradb/include/buf0buf.ic b/storage/xtradb/include/buf0buf.ic index 98d575075ba..55d89b66375 100644 --- a/storage/xtradb/include/buf0buf.ic +++ b/storage/xtradb/include/buf0buf.ic @@ -444,6 +444,7 @@ buf_page_get_io_fix( case BUF_IO_NONE: case BUF_IO_READ: case BUF_IO_WRITE: + case BUF_IO_PIN: return(io_fix); } ut_error; @@ -494,6 +495,49 @@ buf_block_set_io_fix( buf_page_set_io_fix(&block->page, io_fix); } +/*********************************************************************//** +Makes a block sticky. A sticky block implies that even after we release +the buf_pool->mutex and the block->mutex: +* it cannot be removed from the flush_list +* the block descriptor cannot be relocated +* it cannot be removed from the LRU list +Note that: +* the block can still change its position in the LRU list +* the next and previous pointers can change. */ +UNIV_INLINE +void +buf_page_set_sticky( +/*================*/ + buf_page_t* bpage) /*!< in/out: control block */ +{ +#ifdef UNIV_DEBUG + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + ut_ad(mutex_own(&buf_pool->LRU_list_mutex)); +#endif + ut_ad(mutex_own(buf_page_get_mutex(bpage))); + ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_NONE); + + bpage->io_fix = BUF_IO_PIN; +} + +/*********************************************************************//** +Removes stickiness of a block. */ +UNIV_INLINE +void +buf_page_unset_sticky( +/*==================*/ + buf_page_t* bpage) /*!< in/out: control block */ +{ +#ifdef UNIV_DEBUG + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + ut_ad(mutex_own(&buf_pool->LRU_list_mutex)); +#endif + ut_ad(mutex_own(buf_page_get_mutex(bpage))); + ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_PIN); + + bpage->io_fix = BUF_IO_NONE; +} + /********************************************************************//** Determine if a buffer block can be relocated in memory. The block can be dirty, but it must not be I/O-fixed or bufferfixed. */ diff --git a/storage/xtradb/include/buf0types.h b/storage/xtradb/include/buf0types.h index 156093aad01..d140936a886 100644 --- a/storage/xtradb/include/buf0types.h +++ b/storage/xtradb/include/buf0types.h @@ -57,7 +57,10 @@ enum buf_flush { enum buf_io_fix { BUF_IO_NONE = 0, /**< no pending I/O */ BUF_IO_READ, /**< read pending */ - BUF_IO_WRITE /**< write pending */ + BUF_IO_WRITE, /**< write pending */ + BUF_IO_PIN /**< disallow relocation of + block and its removal of from + the flush_list */ }; /** Parameters of binary buddy system for compressed pages (buf0buddy.h) */ diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h index 840a9fbb13a..92fdca0db1b 100644 --- a/storage/xtradb/include/fil0fil.h +++ b/storage/xtradb/include/fil0fil.h @@ -34,6 +34,7 @@ Created 10/25/1995 Heikki Tuuri #include "sync0rw.h" #include "ibuf0types.h" #endif /* !UNIV_HOTBACKUP */ +#include "trx0types.h" /** When mysqld is run, the default directory "." is the mysqld datadir, but in the MySQL Embedded Server Library and ibbackup it is not the default @@ -329,18 +330,23 @@ Reads the flushed lsn and arch no fields from a data file at database startup. */ UNIV_INTERN void -fil_read_flushed_lsn_and_arch_log_no( -/*=================================*/ +fil_read_first_page( +/*================*/ os_file_t data_file, /*!< in: open data file */ ibool one_read_already, /*!< in: TRUE if min and max parameters below already contain sensible data */ + ulint* flags, /*!< out: tablespace flags */ #ifdef UNIV_LOG_ARCHIVE - ulint* min_arch_log_no, /*!< in/out: */ - ulint* max_arch_log_no, /*!< in/out: */ + ulint* min_arch_log_no, /*!< out: min of archived + log numbers in data files */ + ulint* max_arch_log_no, /*!< out: max of archived + log numbers in data files */ #endif /* UNIV_LOG_ARCHIVE */ - ib_uint64_t* min_flushed_lsn, /*!< in/out: */ - ib_uint64_t* max_flushed_lsn); /*!< in/out: */ + ib_uint64_t* min_flushed_lsn, /*!< out: min of flushed + lsn values in data files */ + ib_uint64_t* max_flushed_lsn); /*!< out: max of flushed + lsn values in data files */ /*******************************************************************//** Increments the count of pending insert buffer page merges, if space is not being deleted. @@ -474,8 +480,11 @@ fil_open_single_table_tablespace( accessing the first page of the file */ ulint id, /*!< in: space id */ ulint flags, /*!< in: tablespace flags */ - const char* name); /*!< in: table name in the + const char* name, /*!< in: table name in the databasename/tablename format */ + trx_t* trx); /*!< in: transaction. This is only used + for IMPORT TABLESPACE, must be NULL + otherwise */ /********************************************************************//** It is possible, though very improbable, that the lsn's in the tablespace to be imported have risen above the current system lsn, if a lengthy purge, ibuf diff --git a/storage/xtradb/include/fsp0fsp.h b/storage/xtradb/include/fsp0fsp.h index 7abd3914eda..d5e235aa870 100644 --- a/storage/xtradb/include/fsp0fsp.h +++ b/storage/xtradb/include/fsp0fsp.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -11,8 +11,8 @@ 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 +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA *****************************************************************************/ @@ -34,6 +34,90 @@ Created 12/18/1995 Heikki Tuuri #include "page0types.h" #include "fsp0types.h" +/* @defgroup fsp_flags InnoDB Tablespace Flag Constants @{ */ + +/** Number of flag bits used to indicate the tablespace page size */ +#define FSP_FLAGS_WIDTH_PAGE_SSIZE 4 +/** Zero relative shift position of the PAGE_SSIZE field */ +#define FSP_FLAGS_POS_PAGE_SSIZE 6 +/** Bit mask of the PAGE_SSIZE field */ +#define FSP_FLAGS_MASK_PAGE_SSIZE \ + ((~(~0 << FSP_FLAGS_WIDTH_PAGE_SSIZE)) \ + << FSP_FLAGS_POS_PAGE_SSIZE) +/** Return the value of the PAGE_SSIZE field */ +#define FSP_FLAGS_GET_PAGE_SSIZE(flags) \ + ((flags & FSP_FLAGS_MASK_PAGE_SSIZE) \ + >> FSP_FLAGS_POS_PAGE_SSIZE) + +/* @} */ + +/* @defgroup Tablespace Header Constants (moved from fsp0fsp.c) @{ */ + +/** Offset of the space header within a file page */ +#define FSP_HEADER_OFFSET FIL_PAGE_DATA + +/* The data structures in files are defined just as byte strings in C */ +typedef byte fsp_header_t; +typedef byte xdes_t; + +/* SPACE HEADER + ============ + +File space header data structure: this data structure is contained in the +first page of a space. The space for this header is reserved in every extent +descriptor page, but used only in the first. */ + +/*-------------------------------------*/ +#define FSP_SPACE_ID 0 /* space id */ +#define FSP_NOT_USED 4 /* this field contained a value up to + which we know that the modifications + in the database have been flushed to + the file space; not used now */ +#define FSP_SIZE 8 /* Current size of the space in + pages */ +#define FSP_FREE_LIMIT 12 /* Minimum page number for which the + free list has not been initialized: + the pages >= this limit are, by + definition, free; note that in a + single-table tablespace where size + < 64 pages, this number is 64, i.e., + we have initialized the space + about the first extent, but have not + physically allocted those pages to the + file */ +#define FSP_SPACE_FLAGS 16 /* fsp_space_t.flags, similar to + dict_table_t::flags */ +#define FSP_FRAG_N_USED 20 /* number of used pages in the + FSP_FREE_FRAG list */ +#define FSP_FREE 24 /* list of free extents */ +#define FSP_FREE_FRAG (24 + FLST_BASE_NODE_SIZE) + /* list of partially free extents not + belonging to any segment */ +#define FSP_FULL_FRAG (24 + 2 * FLST_BASE_NODE_SIZE) + /* list of full extents not belonging + to any segment */ +#define FSP_SEG_ID (24 + 3 * FLST_BASE_NODE_SIZE) + /* 8 bytes which give the first unused + segment id */ +#define FSP_SEG_INODES_FULL (32 + 3 * FLST_BASE_NODE_SIZE) + /* list of pages containing segment + headers, where all the segment inode + slots are reserved */ +#define FSP_SEG_INODES_FREE (32 + 4 * FLST_BASE_NODE_SIZE) + /* list of pages containing segment + headers, where not all the segment + header slots are reserved */ +/*-------------------------------------*/ +/* File space header size */ +#define FSP_HEADER_SIZE (32 + 5 * FLST_BASE_NODE_SIZE) + +#define FSP_FREE_ADD 4 /* this many free extents are added + to the free list from above + FSP_FREE_LIMIT at a time */ +/* @} */ + +/* @} */ + /**********************************************************************//** Initializes the file space system. */ UNIV_INTERN @@ -352,6 +436,18 @@ fseg_print( mtr_t* mtr); /*!< in: mtr */ #endif /* UNIV_BTR_PRINT */ +/********************************************************************//** +Extract the page size from tablespace flags. +This feature, storing the page_ssize into the tablespace flags, is added +to InnoDB 5.6.4. This is here only to protect against a crash if a newer +database is opened with this code branch. +@return page size of the tablespace in bytes */ +UNIV_INLINE +ulint +fsp_flags_get_page_size( +/*====================*/ + ulint flags); /*!< in: tablespace flags */ + #ifndef UNIV_NONINL #include "fsp0fsp.ic" #endif diff --git a/storage/xtradb/include/fsp0fsp.ic b/storage/xtradb/include/fsp0fsp.ic index 434c370b527..c92111a9d89 100644 --- a/storage/xtradb/include/fsp0fsp.ic +++ b/storage/xtradb/include/fsp0fsp.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -11,8 +11,8 @@ 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 +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA *****************************************************************************/ @@ -43,3 +43,31 @@ fsp_descr_page( return(UNIV_UNLIKELY((page_no & (zip_size - 1)) == FSP_XDES_OFFSET)); } +/********************************************************************//** +Extract the page size from tablespace flags. +This feature, storing the page_ssize into the tablespace flags, is added +to InnoDB 5.6.4. This is here only to protect against a crash if a newer +database is opened with this code branch. +@return page size of the tablespace in bytes */ +UNIV_INLINE +ulint +fsp_flags_get_page_size( +/*====================*/ + ulint flags) /*!< in: tablespace flags */ +{ + ulint page_size = 0; + ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags); + + /* Convert from a 'log2 minus 9' to a page size in bytes. */ + if (UNIV_UNLIKELY(ssize)) { + page_size = (512 << ssize); + + ut_ad(page_size <= UNIV_PAGE_SIZE); + } else { + /* If the page size was not stored, then it is the + original 16k. */ + page_size = UNIV_PAGE_SIZE; + } + + return(page_size); +} diff --git a/storage/xtradb/include/ha0ha.h b/storage/xtradb/include/ha0ha.h index 3299000bf3c..8bba564d153 100644 --- a/storage/xtradb/include/ha0ha.h +++ b/storage/xtradb/include/ha0ha.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -31,13 +31,14 @@ Created 8/18/1994 Heikki Tuuri #include "hash0hash.h" #include "page0types.h" #include "buf0types.h" +#include "rem0types.h" /*************************************************************//** Looks for an element in a hash table. @return pointer to the data of the first hash table node in chain having the fold number, NULL if not found */ UNIV_INLINE -void* +const rec_t* ha_search_and_get_data( /*===================*/ hash_table_t* table, /*!< in: hash table */ @@ -51,11 +52,11 @@ ha_search_and_update_if_found_func( /*===============================*/ hash_table_t* table, /*!< in/out: hash table */ ulint fold, /*!< in: folded value of the searched data */ - void* data, /*!< in: pointer to the data */ + const rec_t* data, /*!< in: pointer to the data */ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* new_block,/*!< in: block containing new_data */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - void* new_data);/*!< in: new pointer to the data */ + const rec_t* new_data);/*!< in: new pointer to the data */ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG /** Looks for an element when we know the pointer to the data and @@ -114,14 +115,6 @@ chosen to be a slightly bigger prime number. #endif /* UNIV_SYNC_DEBUG */ /*************************************************************//** -Empties a hash table and frees the memory heaps. */ -UNIV_INTERN -void -ha_clear( -/*=====*/ - hash_table_t* table); /*!< in, own: hash table */ - -/*************************************************************//** Inserts an entry into a hash table. If an entry with the same fold number is found, its node is updated to point to the new data, and no new node is inserted. @@ -138,7 +131,7 @@ ha_insert_for_fold_func( #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* block, /*!< in: buffer block containing the data */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - void* data); /*!< in: data, must not be NULL */ + const rec_t* data); /*!< in: data, must not be NULL */ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG /** @@ -174,7 +167,7 @@ ha_search_and_delete_if_found( /*==========================*/ hash_table_t* table, /*!< in: hash table */ ulint fold, /*!< in: folded value of the searched data */ - void* data); /*!< in: pointer to the data */ + const rec_t* data); /*!< in: pointer to the data */ #ifndef UNIV_HOTBACKUP /*****************************************************************//** Removes from the chain determined by fold all nodes whose data pointer @@ -217,7 +210,7 @@ struct ha_node_struct { #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* block; /*!< buffer block containing the data, or NULL */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - void* data; /*!< pointer to the data */ + const rec_t* data; /*!< pointer to the data */ ulint fold; /*!< fold value for the data */ }; diff --git a/storage/xtradb/include/ha0ha.ic b/storage/xtradb/include/ha0ha.ic index 734403c4cd9..f224776c134 100644 --- a/storage/xtradb/include/ha0ha.ic +++ b/storage/xtradb/include/ha0ha.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -25,6 +25,7 @@ Created 8/18/1994 Heikki Tuuri #include "ut0rnd.h" #include "mem0mem.h" +#include "btr0types.h" /***********************************************************//** Deletes a hash node. */ @@ -39,10 +40,10 @@ ha_delete_hash_node( Gets a hash node data. @return pointer to the data */ UNIV_INLINE -void* +const rec_t* ha_node_get_data( /*=============*/ - ha_node_t* node) /*!< in: hash chain node */ + const ha_node_t* node) /*!< in: hash chain node */ { return(node->data); } @@ -57,7 +58,7 @@ ha_node_set_data_func( #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* block, /*!< in: buffer block containing the data */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - void* data) /*!< in: pointer to the data */ + const rec_t* data) /*!< in: pointer to the data */ { #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG node->block = block; @@ -107,39 +108,10 @@ ha_chain_get_first( /*************************************************************//** Looks for an element in a hash table. -@return pointer to the first hash table node in chain having the fold -number, NULL if not found */ -UNIV_INLINE -ha_node_t* -ha_search( -/*======*/ - hash_table_t* table, /*!< in: hash table */ - ulint fold) /*!< in: folded value of the searched data */ -{ - ha_node_t* node; - - ASSERT_HASH_MUTEX_OWN(table, fold); - - node = ha_chain_get_first(table, fold); - - while (node) { - if (node->fold == fold) { - - return(node); - } - - node = ha_chain_get_next(node); - } - - return(NULL); -} - -/*************************************************************//** -Looks for an element in a hash table. @return pointer to the data of the first hash table node in chain having the fold number, NULL if not found */ UNIV_INLINE -void* +const rec_t* ha_search_and_get_data( /*===================*/ hash_table_t* table, /*!< in: hash table */ @@ -148,6 +120,10 @@ ha_search_and_get_data( ha_node_t* node; ASSERT_HASH_MUTEX_OWN(table, fold); +#ifdef UNIV_SYNC_DEBUG +// ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_SHARED)); +#endif /* UNIV_SYNC_DEBUG */ + ut_ad(btr_search_enabled); node = ha_chain_get_first(table, fold); @@ -172,12 +148,14 @@ ha_search_with_data( /*================*/ hash_table_t* table, /*!< in: hash table */ ulint fold, /*!< in: folded value of the searched data */ - void* data) /*!< in: pointer to the data */ + const rec_t* data) /*!< in: pointer to the data */ { ha_node_t* node; ASSERT_HASH_MUTEX_OWN(table, fold); + ut_ad(btr_search_enabled); + node = ha_chain_get_first(table, fold); while (node) { @@ -202,11 +180,15 @@ ha_search_and_delete_if_found( /*==========================*/ hash_table_t* table, /*!< in: hash table */ ulint fold, /*!< in: folded value of the searched data */ - void* data) /*!< in: pointer to the data */ + const rec_t* data) /*!< in: pointer to the data */ { ha_node_t* node; ASSERT_HASH_MUTEX_OWN(table, fold); +#ifdef UNIV_SYNC_DEBUG +// ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ + ut_ad(btr_search_enabled); node = ha_search_with_data(table, fold, data); diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h index 2ec0861c837..2e200ba7f43 100644 --- a/storage/xtradb/include/ha_prototypes.h +++ b/storage/xtradb/include/ha_prototypes.h @@ -259,9 +259,8 @@ innobase_get_at_most_n_mbchars( /*************************************************************//** InnoDB index push-down condition check @return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */ -UNIV_INTERN enum icp_result -innobase_index_cond( +handler_index_cond_check( /*================*/ void* file) /*!< in/out: pointer to ha_innobase */ __attribute__((nonnull, warn_unused_result)); diff --git a/storage/xtradb/include/page0page.h b/storage/xtradb/include/page0page.h index c1c659e2b70..1b9f9c84225 100644 --- a/storage/xtradb/include/page0page.h +++ b/storage/xtradb/include/page0page.h @@ -893,6 +893,7 @@ page_parse_create( ulint comp, /*!< in: nonzero=compact page format */ buf_block_t* block, /*!< in: block or NULL */ mtr_t* mtr); /*!< in: mtr or NULL */ +#ifndef UNIV_HOTBACKUP /************************************************************//** Prints record contents including the data relevant only in the index page context. */ @@ -902,6 +903,7 @@ page_rec_print( /*===========*/ const rec_t* rec, /*!< in: physical record */ const ulint* offsets);/*!< in: record descriptor */ +# ifdef UNIV_BTR_PRINT /***************************************************************//** This is used to print the contents of the directory for debugging purposes. */ @@ -941,6 +943,8 @@ page_print( in directory */ ulint rn); /*!< in: print rn first and last records in directory */ +# endif /* UNIV_BTR_PRINT */ +#endif /* !UNIV_HOTBACKUP */ /***************************************************************//** The following is used to validate a record on a page. This function differs from rec_validate as it can also check the n_owned field and diff --git a/storage/xtradb/include/row0upd.ic b/storage/xtradb/include/row0upd.ic index 11db82f64da..10646241125 100644 --- a/storage/xtradb/include/row0upd.ic +++ b/storage/xtradb/include/row0upd.ic @@ -28,7 +28,6 @@ Created 12/27/1996 Heikki Tuuri # include "trx0trx.h" # include "trx0undo.h" # include "row0row.h" -# include "btr0sea.h" #endif /* !UNIV_HOTBACKUP */ #include "page0zip.h" diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h index 6f985eacdf3..b660f7ea104 100644 --- a/storage/xtradb/include/srv0srv.h +++ b/storage/xtradb/include/srv0srv.h @@ -243,7 +243,7 @@ extern long long srv_ibuf_max_size; extern ulong srv_ibuf_active_contract; extern ulong srv_ibuf_accel_rate; extern ulint srv_checkpoint_age_target; -extern ulint srv_flush_neighbor_pages; +extern ulong srv_flush_neighbor_pages; extern ulint srv_deprecated_enable_unsafe_group_commit; extern ulong srv_read_ahead; extern ulong srv_adaptive_flushing_method; @@ -288,6 +288,9 @@ extern ibool srv_print_lock_waits; extern ibool srv_print_buf_io; extern ibool srv_print_log_io; extern ibool srv_print_latch_waits; + +extern ulong srv_flush_checkpoint_debug; + #else /* UNIV_DEBUG */ # define srv_print_thread_releases FALSE # define srv_print_lock_waits FALSE diff --git a/storage/xtradb/include/sync0rw.h b/storage/xtradb/include/sync0rw.h index 6420bc5d3bf..971099c91f5 100644 --- a/storage/xtradb/include/sync0rw.h +++ b/storage/xtradb/include/sync0rw.h @@ -543,7 +543,7 @@ mutex. */ UNIV_INTERN void rw_lock_debug_mutex_enter(void); -/*==========================*/ +/*===========================*/ /******************************************************************//** Releases the debug mutex. */ UNIV_INTERN @@ -634,7 +634,8 @@ struct rw_lock_struct { }; #ifdef UNIV_SYNC_DEBUG -/** The structure for storing debug info of an rw-lock */ +/** The structure for storing debug info of an rw-lock. All access to this +structure must be protected by rw_lock_debug_mutex_enter(). */ struct rw_lock_debug_struct { os_thread_id_t thread_id; /*!< The thread id of the thread which diff --git a/storage/xtradb/include/sync0rw.ic b/storage/xtradb/include/sync0rw.ic index a6dfa603c59..3eaa6172631 100644 --- a/storage/xtradb/include/sync0rw.ic +++ b/storage/xtradb/include/sync0rw.ic @@ -406,6 +406,7 @@ rw_lock_s_lock_func( #ifdef UNIV_SYNC_DEBUG ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED)); /* see NOTE above */ + ut_ad(!rw_lock_own(lock, RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ /* TODO: study performance of UNIV_LIKELY branch prediction hints. */ diff --git a/storage/xtradb/include/sync0sync.h b/storage/xtradb/include/sync0sync.h index 6440a670f14..f9434ed54be 100644 --- a/storage/xtradb/include/sync0sync.h +++ b/storage/xtradb/include/sync0sync.h @@ -674,7 +674,6 @@ or row lock! */ #define SYNC_LOG_FLUSH_ORDER 156 #define SYNC_RECV 168 #define SYNC_WORK_QUEUE 162 -#define SYNC_SEARCH_SYS_CONF 161 /* for assigning btr_search_enabled */ #define SYNC_SEARCH_SYS 160 /* NOTE that if we have a memory heap that can be extended to the buffer pool, its logical level is diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h index a03f7aceafa..eded5c303fa 100644 --- a/storage/xtradb/include/trx0trx.h +++ b/storage/xtradb/include/trx0trx.h @@ -494,6 +494,7 @@ struct trx_struct{ this is set to 1 then registered should also be set to 1. This is used in the XA code */ + unsigned called_commit_ordered:1;/* 1 if innobase_commit_ordered has run. */ /*------------------------------*/ ulint isolation_level;/* TRX_ISO_REPEATABLE_READ, ... */ ulint check_foreigns; /* normally TRUE, but if the user diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index 0287ea40509..1a48d68d0d7 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -54,7 +54,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_BUGFIX 8 #ifndef PERCONA_INNODB_VERSION -#define PERCONA_INNODB_VERSION 20.1 +#define PERCONA_INNODB_VERSION 24.1 #endif /* The following is the InnoDB version as shown in diff --git a/storage/xtradb/log/log0log.c b/storage/xtradb/log/log0log.c index d9676707cfd..af0c801a4ec 100644 --- a/storage/xtradb/log/log0log.c +++ b/storage/xtradb/log/log0log.c @@ -1693,10 +1693,13 @@ log_preflush_pool_modified_pages( recv_apply_hashed_log_recs(TRUE); } + retry: n_pages = buf_flush_list(ULINT_MAX, new_oldest); - if (sync) { - buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST); + if (sync && n_pages != 0) { + //buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST); + os_thread_sleep(100000); + goto retry; } if (n_pages == ULINT_UNDEFINED) { @@ -2020,6 +2023,13 @@ log_checkpoint( { ib_uint64_t oldest_lsn; +#ifdef UNIV_DEBUG + if (srv_flush_checkpoint_debug == 1) { + + return TRUE; + } +#endif + if (recv_recovery_is_on()) { recv_apply_hashed_log_recs(TRUE); } @@ -2124,7 +2134,11 @@ log_make_checkpoint_at( physical write will always be made to log files */ { - /* Preflush pages synchronously */ +#ifdef UNIV_DEBUG + if (srv_flush_checkpoint_debug == 1) + return; +#endif +/* Preflush pages synchronously */ while (!log_preflush_pool_modified_pages(lsn, TRUE)); @@ -2216,7 +2230,13 @@ log_checkpoint_margin(void) ibool checkpoint_sync; ibool do_checkpoint; ibool success; -loop: + +#ifdef UNIV_DEBUG + if (srv_flush_checkpoint_debug == 1) + return; +#endif + + loop: sync = FALSE; checkpoint_sync = FALSE; do_checkpoint = FALSE; @@ -2239,13 +2259,15 @@ loop: /* A flush is urgent: we have to do a synchronous preflush */ sync = TRUE; - advance = 2 * (age - log->max_modified_age_sync); + advance = age - log->max_modified_age_sync; } else if (age > log_max_modified_age_async()) { /* A flush is not urgent: we do an asynchronous preflush */ advance = age - log_max_modified_age_async(); + log->check_flush_or_checkpoint = FALSE; } else { advance = 0; + log->check_flush_or_checkpoint = FALSE; } checkpoint_age = log->lsn - log->last_checkpoint_lsn; @@ -2262,9 +2284,9 @@ loop: do_checkpoint = TRUE; - log->check_flush_or_checkpoint = FALSE; + //log->check_flush_or_checkpoint = FALSE; } else { - log->check_flush_or_checkpoint = FALSE; + //log->check_flush_or_checkpoint = FALSE; } mutex_exit(&(log->mutex)); @@ -2272,6 +2294,7 @@ loop: if (advance) { ib_uint64_t new_oldest = oldest_lsn + advance; +retry: success = log_preflush_pool_modified_pages(new_oldest, sync); /* If the flush succeeded, this thread has done its part @@ -2286,7 +2309,7 @@ loop: log->check_flush_or_checkpoint = TRUE; mutex_exit(&(log->mutex)); - goto loop; + goto retry; } } @@ -3164,7 +3187,11 @@ void log_check_margins(void) /*===================*/ { -loop: +#ifdef UNIV_DEBUG + if (srv_flush_checkpoint_debug == 1) + return; +#endif + loop: log_flush_margin(); log_checkpoint_margin(); diff --git a/storage/xtradb/page/page0page.c b/storage/xtradb/page/page0page.c index 17f6c6bbc36..4858929082a 100644 --- a/storage/xtradb/page/page0page.c +++ b/storage/xtradb/page/page0page.c @@ -215,12 +215,6 @@ page_set_max_trx_id( { page_t* page = buf_block_get_frame(block); #ifndef UNIV_HOTBACKUP - const ibool is_hashed = block->is_hashed; - - if (is_hashed) { - rw_lock_x_lock(btr_search_get_latch(block->index->id)); - } - ut_ad(!mtr || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); #endif /* !UNIV_HOTBACKUP */ @@ -241,12 +235,6 @@ page_set_max_trx_id( } else { mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), trx_id); } - -#ifndef UNIV_HOTBACKUP - if (is_hashed) { - rw_lock_x_unlock(btr_search_get_latch(block->index->id)); - } -#endif /* !UNIV_HOTBACKUP */ } /************************************************************//** @@ -1603,13 +1591,14 @@ page_rec_print( " n_owned: %lu; heap_no: %lu; next rec: %lu\n", (ulong) rec_get_n_owned_old(rec), (ulong) rec_get_heap_no_old(rec), - (ulong) rec_get_next_offs(rec, TRUE)); + (ulong) rec_get_next_offs(rec, FALSE)); } page_rec_check(rec); rec_validate(rec, offsets); } +# ifdef UNIV_BTR_PRINT /***************************************************************//** This is used to print the contents of the directory for debugging purposes. */ @@ -1770,6 +1759,7 @@ page_print( page_dir_print(page, dn); page_print_list(block, index, rn); } +# endif /* UNIV_BTR_PRINT */ #endif /* !UNIV_HOTBACKUP */ /***************************************************************//** diff --git a/storage/xtradb/page/page0zip.c b/storage/xtradb/page/page0zip.c index fc9f30ed94e..d4b0dd8339d 100644 --- a/storage/xtradb/page/page0zip.c +++ b/storage/xtradb/page/page0zip.c @@ -4456,7 +4456,7 @@ page_zip_reorganize( #ifndef UNIV_HOTBACKUP temp_block = buf_block_alloc(buf_pool); - btr_search_drop_page_hash_index(block, index); + btr_search_drop_page_hash_index(block); block->check_index_page_at_flush = TRUE; #else /* !UNIV_HOTBACKUP */ ut_ad(block == back_block1); diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c index 9bda27e4b1f..adc75bd5760 100644 --- a/storage/xtradb/row/row0ins.c +++ b/storage/xtradb/row/row0ins.c @@ -437,11 +437,9 @@ row_ins_cascade_calc_update_vec( dict_table_t* table = foreign->foreign_table; dict_index_t* index = foreign->foreign_index; upd_t* update; - upd_field_t* ufield; dict_table_t* parent_table; dict_index_t* parent_index; upd_t* parent_update; - upd_field_t* parent_ufield; ulint n_fields_updated; ulint parent_field_no; ulint i; @@ -477,13 +475,15 @@ row_ins_cascade_calc_update_vec( dict_index_get_nth_col_no(parent_index, i)); for (j = 0; j < parent_update->n_fields; j++) { - parent_ufield = parent_update->fields + j; + const upd_field_t* parent_ufield + = &parent_update->fields[j]; if (parent_ufield->field_no == parent_field_no) { ulint min_size; const dict_col_t* col; ulint ufield_len; + upd_field_t* ufield; col = dict_index_get_nth_col(index, i); @@ -985,10 +985,9 @@ row_ins_foreign_check_on_constraint( goto nonstandard_exit_func; } - if ((node->is_delete - && (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL)) - || (!node->is_delete - && (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL))) { + if (node->is_delete + ? (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL) + : (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL)) { /* Build the appropriate update vector which sets foreign->n_fields first fields in rec to SQL NULL */ @@ -997,6 +996,8 @@ row_ins_foreign_check_on_constraint( update->info_bits = 0; update->n_fields = foreign->n_fields; + UNIV_MEM_INVALID(update->fields, + update->n_fields * sizeof *update->fields); for (i = 0; i < foreign->n_fields; i++) { upd_field_t* ufield = &update->fields[i]; @@ -1665,7 +1666,7 @@ row_ins_scan_sec_index_for_duplicate( ulint n_fields_cmp; btr_pcur_t pcur; ulint err = DB_SUCCESS; - unsigned allow_duplicates; + ulint allow_duplicates; mtr_t mtr; mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; @@ -1696,7 +1697,7 @@ row_ins_scan_sec_index_for_duplicate( btr_pcur_open(index, entry, PAGE_CUR_GE, BTR_SEARCH_LEAF, &pcur, &mtr); - allow_duplicates = thr_get_trx(thr)->duplicates & TRX_DUP_IGNORE; + allow_duplicates = thr_get_trx(thr)->duplicates; /* Scan index records and check if there is a duplicate */ @@ -1830,7 +1831,7 @@ row_ins_duplicate_error_in_clust( sure that in roll-forward we get the same duplicate errors as in original execution */ - if (trx->duplicates & TRX_DUP_IGNORE) { + if (trx->duplicates) { /* If the SQL-query will update or replace duplicate key we will take X-lock for @@ -1874,7 +1875,7 @@ row_ins_duplicate_error_in_clust( offsets = rec_get_offsets(rec, cursor->index, offsets, ULINT_UNDEFINED, &heap); - if (trx->duplicates & TRX_DUP_IGNORE) { + if (trx->duplicates) { /* If the SQL-query will update or replace duplicate key we will take X-lock for diff --git a/storage/xtradb/row/row0mysql.c b/storage/xtradb/row/row0mysql.c index ac424ded6cb..63252ed01b3 100644 --- a/storage/xtradb/row/row0mysql.c +++ b/storage/xtradb/row/row0mysql.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 2000, 2011, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -291,21 +291,21 @@ row_mysql_pad_col( /* space=0x0020 */ pad_end = pad + len; ut_a(!(len % 2)); - do { + while (pad < pad_end) { *pad++ = 0x00; *pad++ = 0x20; - } while (pad < pad_end); + }; break; case 4: /* space=0x00000020 */ pad_end = pad + len; ut_a(!(len % 4)); - do { + while (pad < pad_end) { *pad++ = 0x00; *pad++ = 0x00; *pad++ = 0x00; *pad++ = 0x20; - } while (pad < pad_end); + } break; } } @@ -2736,7 +2736,7 @@ row_import_tablespace_for_mysql( success = fil_open_single_table_tablespace( TRUE, table->space, table->flags == DICT_TF_COMPACT ? 0 : table->flags, - table->name); + table->name, trx); if (success) { table->ibd_file_missing = FALSE; table->tablespace_discarded = FALSE; @@ -4119,6 +4119,7 @@ end: trx->error_state = DB_SUCCESS; trx_general_rollback_for_mysql(trx, NULL); trx->error_state = DB_SUCCESS; + err = DB_ERROR; goto funct_exit; } diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c index c7308ccb765..f4a91e68024 100644 --- a/storage/xtradb/row/row0sel.c +++ b/storage/xtradb/row/row0sel.c @@ -3263,16 +3263,15 @@ row_sel_pop_cached_row_for_mysql( } /********************************************************************//** -Pushes a row for MySQL to the fetch cache. -@return TRUE on success, FALSE if the record contains incomplete BLOBs */ -UNIV_INLINE __attribute__((warn_unused_result)) -ibool -row_sel_push_cache_row_for_mysql( -/*=============================*/ - byte* mysql_rec, /*!< in/out: MySQL record */ +Get the last fetch cache buffer from the queue. +@return pointer to buffer. */ +UNIV_INLINE +byte* +row_sel_fetch_last_buf( +/*===================*/ row_prebuilt_t* prebuilt) /*!< in/out: prebuilt struct */ { - ut_ad(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE); + ut_a(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE); ut_a(!prebuilt->templ_contains_blob); if (UNIV_UNLIKELY(prebuilt->fetch_cache[0] == NULL)) { @@ -3301,15 +3300,28 @@ row_sel_push_cache_row_for_mysql( UNIV_MEM_INVALID(prebuilt->fetch_cache[prebuilt->n_fetch_cached], prebuilt->mysql_row_len); - memcpy(prebuilt->fetch_cache[prebuilt->n_fetch_cached], - mysql_rec, prebuilt->mysql_row_len); + return(prebuilt->fetch_cache[prebuilt->n_fetch_cached]); +} - if (++prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE) { - return(FALSE); +/********************************************************************//** +Pushes a row for MySQL to the fetch cache. */ +UNIV_INLINE +void +row_sel_push_cache_row_for_mysql( +/*=============================*/ + byte* mysql_rec, /*!< in/out: MySQL record */ + row_prebuilt_t* prebuilt) /*!< in/out: prebuilt struct */ +{ + /* For non ICP code path the row should already exist in the + next fetch cache slot. */ + + if (prebuilt->idx_cond != NULL) { + byte* dest = row_sel_fetch_last_buf(prebuilt); + + ut_memcpy(dest, mysql_rec, prebuilt->mysql_row_len); } - row_sel_pop_cached_row_for_mysql(mysql_rec, prebuilt); - return(TRUE); + ++prebuilt->n_fetch_cached; } /*********************************************************************//** @@ -3435,7 +3447,7 @@ row_search_idx_cond_check( index, if the case of the column has been updated in the past, or a record has been deleted and a record inserted in a different case. */ - result = innobase_index_cond(prebuilt->idx_cond); + result = handler_index_cond_check(prebuilt->idx_cond); switch (result) { case ICP_MATCH: /* Convert the remaining fields to MySQL format. @@ -3459,6 +3471,7 @@ row_search_idx_cond_check( } ut_error; + return(ICP_ABORTED_BY_USER); /* Keep compiler happy */ } /********************************************************************//** @@ -4735,9 +4748,16 @@ requires_clust_rec: not cache rows because there the cursor is a scrollable cursor. */ + ut_a(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE); + + /* We only convert from InnoDB row format to MySQL row + format when ICP is disabled. */ + if (!prebuilt->idx_cond - && !row_sel_store_mysql_rec(buf, prebuilt, result_rec, - result_rec != rec, offsets)) { + && !row_sel_store_mysql_rec( + row_sel_fetch_last_buf(prebuilt), + prebuilt, result_rec, + result_rec != rec, offsets)) { /* Only fresh inserts may contain incomplete externally stored columns. Pretend that such records do not exist. Such records may only be @@ -4746,8 +4766,12 @@ requires_clust_rec: transaction. Rollback happens at a lower level, not here. */ goto next_rec; - } else if (row_sel_push_cache_row_for_mysql(buf, prebuilt)) { - goto next_rec; + } + + row_sel_push_cache_row_for_mysql(buf, prebuilt); + + if (prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE) { + goto next_rec; } } else { if (UNIV_UNLIKELY diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c index 0c07d75b39a..3476743a692 100644 --- a/storage/xtradb/srv/srv0srv.c +++ b/storage/xtradb/srv/srv0srv.c @@ -446,7 +446,7 @@ UNIV_INTERN ulong srv_ibuf_accel_rate = 100; #define PCT_IBUF_IO(pct) ((ulint) (srv_io_capacity * srv_ibuf_accel_rate * ((double) pct / 10000.0))) UNIV_INTERN ulint srv_checkpoint_age_target = 0; -UNIV_INTERN ulint srv_flush_neighbor_pages = 1; /* 0:disable 1:enable */ +UNIV_INTERN ulong srv_flush_neighbor_pages = 1; /* 0:disable 1:area 2:contiguous */ UNIV_INTERN ulint srv_deprecated_enable_unsafe_group_commit = 0; UNIV_INTERN ulong srv_read_ahead = 3; /* 1: random 2: linear 3: Both */ @@ -471,6 +471,9 @@ UNIV_INTERN ibool srv_print_lock_waits = FALSE; UNIV_INTERN ibool srv_print_buf_io = FALSE; UNIV_INTERN ibool srv_print_log_io = FALSE; UNIV_INTERN ibool srv_print_latch_waits = FALSE; + +UNIV_INTERN ulong srv_flush_checkpoint_debug = 0; + #endif /* UNIV_DEBUG */ UNIV_INTERN ulint srv_n_rows_inserted = 0; @@ -1253,7 +1256,7 @@ retry: static void srv_conc_exit_innodb_timer_based(trx_t* trx) { - (void) os_atomic_increment_lint(&srv_conc_n_threads, -1); + (void) os_atomic_increment_lint(&srv_conc_n_threads, -1); trx->declared_to_be_inside_innodb = FALSE; trx->n_tickets_to_enter_innodb = 0; return; @@ -1475,7 +1478,7 @@ srv_conc_force_enter_innodb( ut_ad(srv_conc_n_threads >= 0); #ifdef HAVE_ATOMIC_BUILTINS if (srv_thread_concurrency_timer_based) { - (void) os_atomic_increment_lint(&srv_conc_n_threads, 1); + (void) os_atomic_increment_lint(&srv_conc_n_threads, 1); trx->declared_to_be_inside_innodb = TRUE; trx->n_tickets_to_enter_innodb = 1; return; @@ -3625,11 +3628,18 @@ retry_flush_batch: PCT_IO(10), IB_ULONGLONG_MAX); } - srv_main_thread_op_info = "making checkpoint"; +#ifdef UNIV_DEBUG + if (srv_flush_checkpoint_debug != 1) { +#endif - /* Make a new checkpoint about once in 10 seconds */ + srv_main_thread_op_info = "making checkpoint"; - log_checkpoint(TRUE, FALSE, TRUE); + /* Make a new checkpoint about once in 10 seconds */ + + log_checkpoint(TRUE, FALSE, TRUE); +#ifdef UNIV_DEBUG + } +#endif srv_main_thread_op_info = "reserving kernel mutex"; @@ -3708,6 +3718,10 @@ background_loop: } mutex_exit(&kernel_mutex); +#ifdef UNIV_DEBUG + if (srv_flush_checkpoint_debug == 1) + goto skip_flush; +#endif flush_loop: srv_main_thread_op_info = "flushing buffer pool pages"; srv_main_flush_loops++; @@ -3748,6 +3762,9 @@ flush_loop: goto flush_loop; } +#ifdef UNIV_DEBUG +skip_flush: +#endif srv_main_thread_op_info = "reserving kernel mutex"; mutex_enter(&kernel_mutex); diff --git a/storage/xtradb/srv/srv0start.c b/storage/xtradb/srv/srv0start.c index 4083eb75b83..99916610c21 100644 --- a/storage/xtradb/srv/srv0start.c +++ b/storage/xtradb/srv/srv0start.c @@ -735,6 +735,7 @@ open_or_create_data_files( ibool one_created = FALSE; ulint size; ulint size_high; + ulint flags; ulint rounded_size_pages; char name[10000]; @@ -917,12 +918,31 @@ open_or_create_data_files( return(DB_ERROR); } skip_size_check: - fil_read_flushed_lsn_and_arch_log_no( - files[i], one_opened, + fil_read_first_page( + files[i], one_opened, &flags, #ifdef UNIV_LOG_ARCHIVE min_arch_log_no, max_arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ min_flushed_lsn, max_flushed_lsn); + + if (UNIV_PAGE_SIZE + != fsp_flags_get_page_size(flags)) { + + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Error: data file %s" + " uses page size %lu,\n", + name, + fsp_flags_get_page_size(flags)); + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: but the only supported" + " page size in this release is=%lu\n", + (ulong) UNIV_PAGE_SIZE); + + return(DB_ERROR); + } + one_opened = TRUE; } else { /* We created the data file and now write it full of @@ -1060,8 +1080,8 @@ skip_size_check: (ulong) TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9); } - fil_read_flushed_lsn_and_arch_log_no( - files[i], one_opened, + fil_read_first_page( + files[i], one_opened, &flags, #ifdef UNIV_LOG_ARCHIVE min_arch_log_no, max_arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ diff --git a/storage/xtradb/sync/sync0rw.c b/storage/xtradb/sync/sync0rw.c index e561ae319a5..8884812d84d 100644 --- a/storage/xtradb/sync/sync0rw.c +++ b/storage/xtradb/sync/sync0rw.c @@ -623,6 +623,9 @@ rw_lock_x_lock_func( ibool spinning = FALSE; ut_ad(rw_lock_validate(lock)); +#ifdef UNIV_SYNC_DEBUG + ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED)); +#endif /* UNIV_SYNC_DEBUG */ i = 0; @@ -710,7 +713,7 @@ mutex. */ UNIV_INTERN void rw_lock_debug_mutex_enter(void) -/*==========================*/ +/*===========================*/ { loop: if (0 == mutex_enter_nowait(&rw_lock_debug_mutex)) { @@ -937,11 +940,13 @@ rw_lock_list_print_info( putc('\n', file); } + rw_lock_debug_mutex_enter(); info = UT_LIST_GET_FIRST(lock->debug_list); while (info != NULL) { rw_lock_debug_print(file, info); info = UT_LIST_GET_NEXT(list, info); } + rw_lock_debug_mutex_exit(); } #ifndef INNODB_RW_LOCKS_USE_ATOMICS mutex_exit(&(lock->mutex)); @@ -985,11 +990,13 @@ rw_lock_print( putc('\n', stderr); } + rw_lock_debug_mutex_enter(); info = UT_LIST_GET_FIRST(lock->debug_list); while (info != NULL) { rw_lock_debug_print(stderr, info); info = UT_LIST_GET_NEXT(list, info); } + rw_lock_debug_mutex_exit(); } } diff --git a/storage/xtradb/sync/sync0sync.c b/storage/xtradb/sync/sync0sync.c index b38e2183b0f..d2c4617d65c 100644 --- a/storage/xtradb/sync/sync0sync.c +++ b/storage/xtradb/sync/sync0sync.c @@ -1222,7 +1222,6 @@ sync_thread_add_level( case SYNC_OUTER_ANY_LATCH: case SYNC_FILE_FORMAT_TAG: case SYNC_DOUBLEWRITE: - case SYNC_SEARCH_SYS_CONF: case SYNC_TRX_LOCK_HEAP: case SYNC_KERNEL: case SYNC_IBUF_BITMAP_MUTEX: diff --git a/strings/decimal.c b/strings/decimal.c index c0021da6570..1a99816b914 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -2293,7 +2293,11 @@ static int do_div_mod(const decimal_t *from1, const decimal_t *from2, DBUG_ASSERT(buf0 < to->buf + to->len); *buf0=(dec1)guess; } +#ifdef WORKAROUND_GCC_4_3_2_BUG + dcarry= *(volatile dec1 *)start1; +#else dcarry= *start1; +#endif start1++; } if (mod) diff --git a/win/packaging/heidisql.cmake b/win/packaging/heidisql.cmake index 94a287cba08..f826c9a6633 100644 --- a/win/packaging/heidisql.cmake +++ b/win/packaging/heidisql.cmake @@ -1,4 +1,4 @@ -SET(HEIDISQL_BASE_NAME "HeidiSQL_6.0_Portable")
+SET(HEIDISQL_BASE_NAME "HeidiSQL_7.0_Portable")
SET(HEIDISQL_ZIP "${HEIDISQL_BASE_NAME}.zip")
SET(HEIDISQL_URL "http://heidisql.googlecode.com/files/${HEIDISQL_ZIP}")
SET(HEIDISQL_DOWNLOAD_DIR ${THIRD_PARTY_DOWNLOAD_LOCATION}/${HEIDISQL_BASE_NAME})
|