diff options
191 files changed, 4360 insertions, 1056 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 58b6cc62e9f..5d95bb568cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -181,6 +181,12 @@ IF(UNIX) ENDIF() OPTION (WITH_UNIT_TESTS "Compile MySQL with unit tests" ON) +IF (WITHOUT_SERVER) + SET (SKIP_COMPONENTS "Server|IniFiles|SuportFiles|Readme") +ELSE() + SET (SKIP_COMPONENTS "N-O-N-E") +ENDIF() + OPTION(NOT_FOR_DISTRIBUTION "Allow linking with GPLv2-incompatible system libraries. Only set it you never plan to distribute the resulting binaries" OFF) INCLUDE(check_compiler_flag) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 4c8709bfca6..14656705805 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -82,7 +82,7 @@ ulong bytes_sent = 0L, bytes_received = 0L; ulong mysqld_net_retry_count = 10L; ulong open_files_limit; ulong opt_binlog_rows_event_max_size; -uint test_flags = 0; +ulonglong test_flags = 0; static uint opt_protocol= 0; static FILE *result_file; static char *result_file_name= 0; diff --git a/cmake/dtrace.cmake b/cmake/dtrace.cmake index d7ab0f31991..bb45eaf865b 100644 --- a/cmake/dtrace.cmake +++ b/cmake/dtrace.cmake @@ -46,6 +46,10 @@ MACRO(CHECK_DTRACE) AND NOT CMAKE_SYSTEM_NAME MATCHES "SunOS") SET(ENABLE_DTRACE ON CACHE BOOL "Enable dtrace") ENDIF() + # On GNU/Hurd, dtrace is not supported + IF(DTRACE AND CMAKE_SYSTEM_NAME MATCHES "GNU") + SET(ENABLE_DTRACE OFF CACHE BOOL "Disable dtrace") + ENDIF() SET(HAVE_DTRACE ${ENABLE_DTRACE}) IF(CMAKE_SYSTEM_NAME MATCHES "SunOS") IF(CMAKE_SIZEOF_VOID_P EQUAL 4) diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake index 5ca147d0d60..d9d12371830 100644 --- a/cmake/install_macros.cmake +++ b/cmake/install_macros.cmake @@ -115,7 +115,12 @@ FUNCTION(INSTALL_SCRIPT) SET(COMP) ENDIF() + IF (COMP MATCHES ${SKIP_COMPONENTS}) + RETURN() + ENDIF() + INSTALL(PROGRAMS ${script} DESTINATION ${ARG_DESTINATION} ${COMP}) + INSTALL_MANPAGE(${script}) ENDFUNCTION() @@ -132,6 +137,10 @@ FUNCTION(INSTALL_DOCUMENTATION) SET(destination ${INSTALL_DOCDIR}) ENDIF() + IF (ARG_COMPONENT MATCHES ${SKIP_COMPONENTS}) + RETURN() + ENDIF() + STRING(TOUPPER ${ARG_COMPONENT} COMPUP) IF(CPACK_COMPONENT_${COMPUP}_GROUP) SET(group ${CPACK_COMPONENT_${COMPUP}_GROUP}) diff --git a/cmake/mysql_add_executable.cmake b/cmake/mysql_add_executable.cmake index de4d49a7cd1..c61a23a978f 100644 --- a/cmake/mysql_add_executable.cmake +++ b/cmake/mysql_add_executable.cmake @@ -75,6 +75,9 @@ FUNCTION (MYSQL_ADD_EXECUTABLE) ELSE() SET(COMP COMPONENT Client) ENDIF() + IF (COMP MATCHES ${SKIP_COMPONENTS}) + RETURN() + ENDIF() MYSQL_INSTALL_TARGETS(${target} DESTINATION ${ARG_DESTINATION} ${COMP}) ENDIF() ENDFUNCTION() diff --git a/cmake/package_name.cmake b/cmake/package_name.cmake index 4930a6bf40a..a8bd1596f47 100644 --- a/cmake/package_name.cmake +++ b/cmake/package_name.cmake @@ -77,6 +77,9 @@ IF(NOT VERSION) SET(DEFAULT_MACHINE "i386") ENDIF() ENDIF() + ELSEIF(CMAKE_SYSTEM_NAME MATCHES "GNU") + SET(DEFAULT_PLATFORM "GNU") + SET(DEFAULT_MACHINE "i386") ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Darwin") IF(CMAKE_OSX_DEPLOYMENT_TARGET) SET(DEFAULT_PLATFORM "osx${CMAKE_OSX_DEPLOYMENT_TARGET}") diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc index 3d713776dc4..8b474c37e4b 100644 --- a/extra/mariabackup/backup_copy.cc +++ b/extra/mariabackup/backup_copy.cc @@ -471,6 +471,21 @@ struct datafile_cur_t { size_t buf_size; size_t buf_read; size_t buf_offset; + + explicit datafile_cur_t(const char* filename = NULL) : + file(), thread_n(0), orig_buf(NULL), buf(NULL), buf_size(0), + buf_read(0), buf_offset(0) + { + memset(rel_path, 0, sizeof rel_path); + if (filename) { + strncpy(abs_path, filename, sizeof abs_path); + abs_path[(sizeof abs_path) - 1] = 0; + } else { + abs_path[0] = '\0'; + } + rel_path[0] = '\0'; + memset(&statinfo, 0, sizeof statinfo); + } }; static @@ -489,9 +504,7 @@ datafile_open(const char *file, datafile_cur_t *cursor, uint thread_n) { bool success; - memset(cursor, 0, sizeof(datafile_cur_t)); - - strncpy(cursor->abs_path, file, sizeof(cursor->abs_path)); + new (cursor) datafile_cur_t(file); /* Get the relative path for the destination tablespace name, i.e. the one that can be appended to the backup root directory. Non-system @@ -630,11 +643,14 @@ static int mkdirp(const char *pathname, int Flags, myf MyFlags) { - char parent[PATH_MAX], *p; + char *parent, *p; + int len = strlen(pathname) + 1; /* make a parent directory path */ - strncpy(parent, pathname, sizeof(parent)); - parent[sizeof(parent) - 1] = 0; + if (!(parent= (char *)malloc(len))) + return(-1); + strncpy(parent, pathname, len); + parent[len-1]= 0; for (p = parent + strlen(parent); !is_path_separator(*p) && p != parent; p--); @@ -643,19 +659,23 @@ mkdirp(const char *pathname, int Flags, myf MyFlags) /* try to make parent directory */ if (p != parent && mkdirp(parent, Flags, MyFlags) != 0) { + free(parent); return(-1); } /* make this one if parent has been made */ if (my_mkdir(pathname, Flags, MyFlags) == 0) { + free(parent); return(0); } /* if it already exists that is fine */ if (errno == EEXIST) { + free(parent); return(0); } + free(parent); return(-1); } @@ -665,17 +685,24 @@ bool equal_paths(const char *first, const char *second) { #ifdef HAVE_REALPATH - char real_first[PATH_MAX]; - char real_second[PATH_MAX]; + char *real_first, *real_second; + int result; - if (realpath(first, real_first) == NULL) { + real_first = realpath(first, 0); + if (real_first == NULL) { return false; } - if (realpath(second, real_second) == NULL) { + + real_second = realpath(second, 0); + if (real_second == NULL) { + free(real_first); return false; } - return (strcmp(real_first, real_second) == 0); + result = strcmp(real_first, real_second); + free(real_first); + free(real_second); + return result == 0; #else return strcmp(first, second) == 0; #endif diff --git a/extra/mariabackup/wsrep.cc b/extra/mariabackup/wsrep.cc index fac1fdcf583..c3ad1b53a21 100644 --- a/extra/mariabackup/wsrep.cc +++ b/extra/mariabackup/wsrep.cc @@ -75,8 +75,7 @@ xb_write_galera_info(bool incremental_prepare) return; } - memset(&xid, 0, sizeof(xid)); - xid.formatID = -1; + xid.null(); if (!trx_rseg_read_wsrep_checkpoint(xid)) { diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 33a8e638ccf..9f6b48a0a05 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -1363,7 +1363,7 @@ static int prepare_export() // which is* unfortunately* still necessary to get mysqld up if (strncmp(orig_argv1,"--defaults-file=",16) == 0) { - sprintf(cmdline, + snprintf(cmdline, sizeof cmdline, IF_WIN("\"","") "\"%s\" --mysqld \"%s\" " " --defaults-extra-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=." " --innodb --innodb-fast-shutdown=0" diff --git a/include/m_ctype.h b/include/m_ctype.h index fc51ebd3c8b..a4aa5b51218 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -370,7 +370,7 @@ typedef int (*my_charset_conv_mb_wc)(CHARSET_INFO *, my_wc_t *, typedef int (*my_charset_conv_wc_mb)(CHARSET_INFO *, my_wc_t, uchar *, uchar *); typedef size_t (*my_charset_conv_case)(CHARSET_INFO *, - char *, size_t, char *, size_t); + const char *, size_t, char *, size_t); /* A structure to return the statistics of a native string copying, @@ -725,9 +725,11 @@ size_t my_copy_fix_mb(CHARSET_INFO *cs, /* Functions for 8bit */ extern size_t my_caseup_str_8bit(CHARSET_INFO *, char *); extern size_t my_casedn_str_8bit(CHARSET_INFO *, char *); -extern size_t my_caseup_8bit(CHARSET_INFO *, char *src, size_t srclen, +extern size_t my_caseup_8bit(CHARSET_INFO *, + const char *src, size_t srclen, char *dst, size_t dstlen); -extern size_t my_casedn_8bit(CHARSET_INFO *, char *src, size_t srclen, +extern size_t my_casedn_8bit(CHARSET_INFO *, + const char *src, size_t srclen, char *dst, size_t dstlen); extern int my_strcasecmp_8bit(CHARSET_INFO * cs, const char *, const char *); @@ -821,17 +823,17 @@ int my_charlen_8bit(CHARSET_INFO *, const uchar *str, const uchar *end); /* Functions for multibyte charsets */ extern size_t my_caseup_str_mb(CHARSET_INFO *, char *); extern size_t my_casedn_str_mb(CHARSET_INFO *, char *); -extern size_t my_caseup_mb(CHARSET_INFO *, char *src, size_t srclen, - char *dst, size_t dstlen); -extern size_t my_casedn_mb(CHARSET_INFO *, char *src, size_t srclen, - char *dst, size_t dstlen); -extern size_t my_caseup_mb_varlen(CHARSET_INFO *, char *src, size_t srclen, - char *dst, size_t dstlen); -extern size_t my_casedn_mb_varlen(CHARSET_INFO *, char *src, size_t srclen, - char *dst, size_t dstlen); -extern size_t my_caseup_ujis(CHARSET_INFO *, char *src, size_t srclen, +extern size_t my_caseup_mb(CHARSET_INFO *, + const char *src, size_t srclen, + char *dst, size_t dstlen); +extern size_t my_casedn_mb(CHARSET_INFO *, + const char *src, size_t srclen, + char *dst, size_t dstlen); +extern size_t my_caseup_ujis(CHARSET_INFO *, + const char *src, size_t srclen, char *dst, size_t dstlen); -extern size_t my_casedn_ujis(CHARSET_INFO *, char *src, size_t srclen, +extern size_t my_casedn_ujis(CHARSET_INFO *, + const char *src, size_t srclen, char *dst, size_t dstlen); extern int my_strcasecmp_mb(CHARSET_INFO * cs,const char *, const char *); diff --git a/include/sql_common.h b/include/sql_common.h index bbf459e1e55..ca7d2618bb9 100644 --- a/include/sql_common.h +++ b/include/sql_common.h @@ -1,7 +1,7 @@ #ifndef SQL_COMMON_INCLUDED #define SQL_COMMON_INCLUDED -/* Copyright (c) 2003, 2012, Oracle and/or its affiliates. - Copyright (c) 2010, 2012, Monty Program Ab +/* Copyright (c) 2003, 2018, Oracle and/or its affiliates. + Copyright (c) 2010, 2018, MariaDB 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/mysql-test/include/ctype_mdev13118.inc b/mysql-test/include/ctype_mdev13118.inc new file mode 100644 index 00000000000..efcb57299df --- /dev/null +++ b/mysql-test/include/ctype_mdev13118.inc @@ -0,0 +1,15 @@ +--echo # +--echo # MDEV-13118 Wrong results with LOWER and UPPER and subquery +--echo # + +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +--sorted_result +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +--sorted_result +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/main/bootstrap.test b/mysql-test/main/bootstrap.test index 1ae9b13e050..414deede892 100644 --- a/mysql-test/main/bootstrap.test +++ b/mysql-test/main/bootstrap.test @@ -106,3 +106,12 @@ use test; EOF --exec $MYSQLD_BOOTSTRAP_CMD --ignore-db-dirs='some_dir' --ignore-db-dirs='some_dir' < $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1 --remove_file $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql + +# +# MDEV-13397 MariaDB upgrade fail when using default_time_zone +# +--write_file $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql +use test; +EOF +--exec $MYSQLD_BOOTSTRAP_CMD --default-time-zone=Europe/Moscow < $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1 +--remove_file $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql diff --git a/mysql-test/main/ctype_binary.result b/mysql-test/main/ctype_binary.result index 0afe5298411..8059e02611e 100644 --- a/mysql-test/main/ctype_binary.result +++ b/mysql-test/main/ctype_binary.result @@ -3048,6 +3048,29 @@ DROP TABLE t1; SELECT _binary 0x7E, _binary X'7E', _binary B'01111110'; _binary 0x7E _binary X'7E' _binary B'01111110' ~ ~ ~ +SET NAMES utf8, character_set_connection=binary; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varbinary(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +abcdefghi-abcdefghi +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/main/ctype_binary.test b/mysql-test/main/ctype_binary.test index 8da4eaff572..155d8548f77 100644 --- a/mysql-test/main/ctype_binary.test +++ b/mysql-test/main/ctype_binary.test @@ -24,6 +24,9 @@ SET NAMES binary; --echo # SELECT _binary 0x7E, _binary X'7E', _binary B'01111110'; +SET NAMES utf8, character_set_connection=binary; +--source include/ctype_mdev13118.inc + --echo # --echo # End of 10.0 tests --echo # diff --git a/mysql-test/main/ctype_eucjpms.result b/mysql-test/main/ctype_eucjpms.result index bc7b4b9ef9d..507d0021a1f 100644 --- a/mysql-test/main/ctype_eucjpms.result +++ b/mysql-test/main/ctype_eucjpms.result @@ -33844,6 +33844,29 @@ HEX(a) CHAR_LENGTH(a) DROP TABLE t1; SELECT _eucjpms 0x8EA0; ERROR HY000: Invalid eucjpms character string: '8EA0' +SET NAMES eucjpms; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET eucjpms DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/main/ctype_eucjpms.test b/mysql-test/main/ctype_eucjpms.test index c69abc32a03..867ca809dbf 100644 --- a/mysql-test/main/ctype_eucjpms.test +++ b/mysql-test/main/ctype_eucjpms.test @@ -537,6 +537,8 @@ DROP TABLE t1; --error ER_INVALID_CHARACTER_STRING SELECT _eucjpms 0x8EA0; +SET NAMES eucjpms; +--source include/ctype_mdev13118.inc --echo # --echo # End of 10.0 tests diff --git a/mysql-test/main/ctype_euckr.result b/mysql-test/main/ctype_euckr.result index 3fb6f98b2eb..cc50ddd20be 100644 --- a/mysql-test/main/ctype_euckr.result +++ b/mysql-test/main/ctype_euckr.result @@ -25405,6 +25405,35 @@ A1A1A1A1A1A120202020202020202020202020202020202020 # End of 5.6 tests # # +# Start of 10.0 tests +# +SET NAMES utf8, character_set_connection=euckr; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET euckr DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; +# +# End of 10.0 tests +# +# # Start of 10.2 tests # # diff --git a/mysql-test/main/ctype_euckr.test b/mysql-test/main/ctype_euckr.test index 950c60c47e5..46955360217 100644 --- a/mysql-test/main/ctype_euckr.test +++ b/mysql-test/main/ctype_euckr.test @@ -197,6 +197,16 @@ set collation_connection=euckr_bin; --echo # End of 5.6 tests --echo # +--echo # +--echo # Start of 10.0 tests +--echo # + +SET NAMES utf8, character_set_connection=euckr; +--source include/ctype_mdev13118.inc + +--echo # +--echo # End of 10.0 tests +--echo # --echo # --echo # Start of 10.2 tests diff --git a/mysql-test/main/ctype_gbk.result b/mysql-test/main/ctype_gbk.result index 5244d6eb333..4e5c9695415 100644 --- a/mysql-test/main/ctype_gbk.result +++ b/mysql-test/main/ctype_gbk.result @@ -5077,6 +5077,29 @@ E05C5B E05B DROP TABLE t1; # Start of ctype_E05C.inc +SET NAMES utf8, character_set_connection=gbk; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET gbk DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # MDEV-9886 Illegal mix of collations with a view comparing a field to a binary constant # diff --git a/mysql-test/main/ctype_gbk.test b/mysql-test/main/ctype_gbk.test index a3dc7f4af44..d9d0a4d0ee4 100644 --- a/mysql-test/main/ctype_gbk.test +++ b/mysql-test/main/ctype_gbk.test @@ -199,6 +199,9 @@ let $ctype_unescape_combinations=selected; SET NAMES gbk; --source include/ctype_E05C.inc +SET NAMES utf8, character_set_connection=gbk; +--source include/ctype_mdev13118.inc + --echo # --echo # MDEV-9886 Illegal mix of collations with a view comparing a field to a binary constant --echo # diff --git a/mysql-test/main/ctype_latin1.result b/mysql-test/main/ctype_latin1.result index d5906cb74dd..43a84275629 100644 --- a/mysql-test/main/ctype_latin1.result +++ b/mysql-test/main/ctype_latin1.result @@ -8022,6 +8022,29 @@ a 0 DROP VIEW v1; DROP TABLE t1; +SET NAMES latin1; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/main/ctype_latin1.test b/mysql-test/main/ctype_latin1.test index 38f147708b8..61df80e2186 100644 --- a/mysql-test/main/ctype_latin1.test +++ b/mysql-test/main/ctype_latin1.test @@ -262,6 +262,9 @@ SELECT * FROM v1; DROP VIEW v1; DROP TABLE t1; +SET NAMES latin1; +--source include/ctype_mdev13118.inc + --echo # --echo # End of 10.0 tests diff --git a/mysql-test/main/ctype_ucs.result b/mysql-test/main/ctype_ucs.result index a6e324b538f..bfcb8b73245 100644 --- a/mysql-test/main/ctype_ucs.result +++ b/mysql-test/main/ctype_ucs.result @@ -5686,6 +5686,29 @@ c2 YWJjZGVmZ2hp-YWJjZGVmZ2hp DROP TABLE t1; SET optimizer_switch=@save_optimizer_switch; +SET NAMES utf8, character_set_connection=ucs2; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET ucs2 DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/main/ctype_ucs.test b/mysql-test/main/ctype_ucs.test index 9592e27f8e1..d0d463c0340 100644 --- a/mysql-test/main/ctype_ucs.test +++ b/mysql-test/main/ctype_ucs.test @@ -992,6 +992,10 @@ DROP TABLE t1; SET optimizer_switch=@save_optimizer_switch; +SET NAMES utf8, character_set_connection=ucs2; +--source include/ctype_mdev13118.inc + + --echo # --echo # End of 10.0 tests --echo # diff --git a/mysql-test/main/ctype_ujis.result b/mysql-test/main/ctype_ujis.result index cb9de83fedc..0b1cf606f0b 100644 --- a/mysql-test/main/ctype_ujis.result +++ b/mysql-test/main/ctype_ujis.result @@ -26149,6 +26149,29 @@ HEX(a) CHAR_LENGTH(a) DROP TABLE t1; SELECT _ujis 0x8EA0; ERROR HY000: Invalid ujis character string: '8EA0' +SET NAMES ujis; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET ujis DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/main/ctype_ujis.test b/mysql-test/main/ctype_ujis.test index ff9c61c05ba..cf247763b46 100644 --- a/mysql-test/main/ctype_ujis.test +++ b/mysql-test/main/ctype_ujis.test @@ -1368,6 +1368,10 @@ DROP TABLE t1; SELECT _ujis 0x8EA0; +SET NAMES ujis; +--source include/ctype_mdev13118.inc + + --echo # --echo # End of 10.0 tests --echo # diff --git a/mysql-test/main/ctype_utf16.result b/mysql-test/main/ctype_utf16.result index 8de21a14bd9..a105017b726 100644 --- a/mysql-test/main/ctype_utf16.result +++ b/mysql-test/main/ctype_utf16.result @@ -2142,6 +2142,29 @@ EXECUTE stmt USING @arg00; CONCAT(_utf16'a' COLLATE utf16_unicode_ci, ?) aÿ DEALLOCATE PREPARE stmt; +SET NAMES utf8, character_set_connection=utf16; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET utf16 DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/main/ctype_utf16.test b/mysql-test/main/ctype_utf16.test index 526f5251055..504e62e3e89 100644 --- a/mysql-test/main/ctype_utf16.test +++ b/mysql-test/main/ctype_utf16.test @@ -870,6 +870,11 @@ SET @arg00=_binary 0x00FF; EXECUTE stmt USING @arg00; DEALLOCATE PREPARE stmt; + +SET NAMES utf8, character_set_connection=utf16; +--source include/ctype_mdev13118.inc + + --echo # --echo # End of 10.0 tests --echo # diff --git a/mysql-test/main/ctype_utf16le.result b/mysql-test/main/ctype_utf16le.result index 0fedff7d3bf..6d8d7ddca2a 100644 --- a/mysql-test/main/ctype_utf16le.result +++ b/mysql-test/main/ctype_utf16le.result @@ -2326,6 +2326,35 @@ DFFFFFDFFFFF9CFFFF9DFFFF9EFFFF # End of 5.6 tests # # +# Start of 10.0 tests +# +SET NAMES utf8, character_set_connection=utf16le; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET utf16le DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; +# +# Start of 10.0 tests +# +# # Start of 10.1 tests # # diff --git a/mysql-test/main/ctype_utf16le.test b/mysql-test/main/ctype_utf16le.test index 79cf875852a..b8728b52db2 100644 --- a/mysql-test/main/ctype_utf16le.test +++ b/mysql-test/main/ctype_utf16le.test @@ -747,6 +747,19 @@ SET NAMES utf8, collation_connection=utf16le_bin; --echo # End of 5.6 tests --echo # + +--echo # +--echo # Start of 10.0 tests +--echo # + + +SET NAMES utf8, character_set_connection=utf16le; +--source include/ctype_mdev13118.inc + +--echo # +--echo # Start of 10.0 tests +--echo # + --echo # --echo # Start of 10.1 tests --echo # diff --git a/mysql-test/main/ctype_utf32.result b/mysql-test/main/ctype_utf32.result index 59ce4c2f445..28b9caf6ffe 100644 --- a/mysql-test/main/ctype_utf32.result +++ b/mysql-test/main/ctype_utf32.result @@ -2241,6 +2241,29 @@ EXECUTE stmt USING @arg00; CONCAT(_utf32'a' COLLATE utf32_unicode_ci, ?) aÿ DEALLOCATE PREPARE stmt; +SET NAMEs utf8, character_set_connection=utf32; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET utf32 DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/main/ctype_utf32.test b/mysql-test/main/ctype_utf32.test index 6f036898d15..2e739ebfdbc 100644 --- a/mysql-test/main/ctype_utf32.test +++ b/mysql-test/main/ctype_utf32.test @@ -983,6 +983,14 @@ SET @arg00=_binary 0x00FF; EXECUTE stmt USING @arg00; DEALLOCATE PREPARE stmt; + +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET NAMEs utf8, character_set_connection=utf32; +--source include/ctype_mdev13118.inc + + --echo # --echo # End of 10.0 tests --echo # diff --git a/mysql-test/main/ctype_utf8.result b/mysql-test/main/ctype_utf8.result index 10d0efeff3c..d696ff78831 100644 --- a/mysql-test/main/ctype_utf8.result +++ b/mysql-test/main/ctype_utf8.result @@ -10286,6 +10286,29 @@ SELECT * FROM v1; c ß DROP VIEW v1; +SET NAMES utf8; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET utf8 DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/main/ctype_utf8.test b/mysql-test/main/ctype_utf8.test index 20a60d370a0..6f8657dacb5 100644 --- a/mysql-test/main/ctype_utf8.test +++ b/mysql-test/main/ctype_utf8.test @@ -1890,6 +1890,13 @@ SELECT * FROM v1; DROP VIEW v1; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET NAMES utf8; +--source include/ctype_mdev13118.inc + + --echo # --echo # End of 10.0 tests --echo # diff --git a/mysql-test/main/ctype_utf8mb4.result b/mysql-test/main/ctype_utf8mb4.result index 7e5e99354ea..27ffd5552fa 100644 --- a/mysql-test/main/ctype_utf8mb4.result +++ b/mysql-test/main/ctype_utf8mb4.result @@ -3478,6 +3478,29 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; SET NAMES default; +SET NAMES utf8mb4; +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=_latin1'derived_merge=on'; +CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `t` varchar(10) CHARACTER SET utf8mb4 DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI'); +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub; +c2 +abcdefghi-abcdefghi +abcdefghi-abcdefghi +SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub; +c2 +ABCDEFGHI-ABCDEFGHI +ABCDEFGHI-ABCDEFGHI +DROP TABLE t1; +SET optimizer_switch=@save_optimizer_switch; # # End of 10.0 tests # diff --git a/mysql-test/main/ctype_utf8mb4.test b/mysql-test/main/ctype_utf8mb4.test index 545347fcd26..9cf87d12340 100644 --- a/mysql-test/main/ctype_utf8mb4.test +++ b/mysql-test/main/ctype_utf8mb4.test @@ -1959,6 +1959,14 @@ DROP TABLE t1; SET NAMES default; + +# +# MDEV-13118 Wrong results with LOWER and UPPER and subquery +# +SET NAMES utf8mb4; +--source include/ctype_mdev13118.inc + + --echo # --echo # End of 10.0 tests --echo # diff --git a/mysql-test/main/derived.result b/mysql-test/main/derived.result index ebbc08aa958..f0d0289c1ce 100644 --- a/mysql-test/main/derived.result +++ b/mysql-test/main/derived.result @@ -1053,6 +1053,7 @@ INSERT INTO t2 VALUES (NULL),(NULL); CREATE TABLE t3 (c VARCHAR(1024) CHARACTER SET utf8, d INT) ENGINE=MyISAM; CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v3 AS SELECT * FROM t3; INSERT INTO t3 VALUES ('abc',NULL),('def',4); +set @save_join_cache_level= @@join_cache_level; SET join_cache_level= 8; explain SELECT * FROM v1, t2, v3 WHERE a = c AND b = d; @@ -1082,6 +1083,38 @@ i drop procedure pr; drop view v1; drop table t1; +set @@join_cache_level= @save_join_cache_level; +# +# MDEV-16307: Incorrect results when using BNLH join instead of BNL join with views +# +CREATE TABLE t1 (c1 text, c2 int); +INSERT INTO t1 VALUES ('a',1), ('c',3), ('g',7), ('d',4), ('c',3); +CREATE TABLE t2 (c1 text, c2 int); +INSERT INTO t2 VALUES ('b',2), ('c',3); +CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; +explain SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 5 +SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1; +c1 c2 c1 c2 +c 3 c 3 +c 3 c 3 +set @save_join_cache_level= @@join_cache_level; +set @@join_cache_level=4; +explain SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where +1 PRIMARY <derived2> hash_ALL NULL #hash#$hj 3 test.t2.c1 5 Using where; Using join buffer (flat, BNLH join) +2 DERIVED t1 ALL NULL NULL NULL NULL 5 +SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1; +c1 c2 c1 c2 +c 3 c 3 +c 3 c 3 +drop table t1,t2; +drop view v1; +set @@join_cache_level= @save_join_cache_level; # end of 5.5 # # Start of 10.1 tests diff --git a/mysql-test/main/derived.test b/mysql-test/main/derived.test index 466d79af409..6c51f23c51e 100644 --- a/mysql-test/main/derived.test +++ b/mysql-test/main/derived.test @@ -913,6 +913,7 @@ CREATE TABLE t3 (c VARCHAR(1024) CHARACTER SET utf8, d INT) ENGINE=MyISAM; CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v3 AS SELECT * FROM t3; INSERT INTO t3 VALUES ('abc',NULL),('def',4); +set @save_join_cache_level= @@join_cache_level; SET join_cache_level= 8; explain SELECT * FROM v1, t2, v3 WHERE a = c AND b = d; @@ -935,7 +936,27 @@ call pr(2); drop procedure pr; drop view v1; drop table t1; +set @@join_cache_level= @save_join_cache_level; +--echo # +--echo # MDEV-16307: Incorrect results when using BNLH join instead of BNL join with views +--echo # + +CREATE TABLE t1 (c1 text, c2 int); +INSERT INTO t1 VALUES ('a',1), ('c',3), ('g',7), ('d',4), ('c',3); +CREATE TABLE t2 (c1 text, c2 int); +INSERT INTO t2 VALUES ('b',2), ('c',3); +CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; + +explain SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1; +SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1; +set @save_join_cache_level= @@join_cache_level; +set @@join_cache_level=4; +explain SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1; +SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1; +drop table t1,t2; +drop view v1; +set @@join_cache_level= @save_join_cache_level; --echo # end of 5.5 --echo # diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index 0cd8b4cb844..a2268ced84f 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -15960,3 +15960,69 @@ f c 9 1 DROP VIEW v1; DROP TABLE t1; +# +# MDEV-15087: error from inexpensive subquery before check +# for condition pushdown into derived +# +CREATE TABLE t1 (i1 int, v1 varchar(1)); +INSERT INTO t1 VALUES (7,'x'); +CREATE TABLE t2 (i1 int); +INSERT INTO t2 VALUES (8); +CREATE TABLE t3 (i1 int ,v1 varchar(1), v2 varchar(1)); +INSERT INTO t3 VALUES (4, 'v','v'),(62,'v','k'),(7, 'n', NULL); +SELECT 1 +FROM (t1 AS a1 +JOIN (((SELECT DISTINCT t3.* +FROM t3) AS a2 +JOIN t1 ON (t1.v1 = a2.v2))) ON (t1.v1 = a2.v1)) +WHERE (SELECT BIT_COUNT(t2.i1) +FROM (t2 JOIN t3)) IS NULL; +ERROR 21000: Subquery returns more than 1 row +DROP TABLE t1, t2, t3; +# +# MDEV-16614 signal 7 after calling stored procedure, that uses regexp +# +CREATE PROCEDURE p1(m1 varchar(5), m2 varchar(5)) +BEGIN +SELECT a FROM +(SELECT "aa" a) t +JOIN (SELECT "aa" b) t1 on t.a=t1.b +WHERE t.a regexp m1 and t1.b regexp m2 +GROUP BY a; +END$$ +CALL p1('a','a'); +a +aa +DROP PROCEDURE p1; +CREATE PROCEDURE p1(m1 varchar(5)) +BEGIN +SELECT a FROM (SELECT "aa" a) t WHERE t.a regexp m1; +END$$ +CALL p1('a'); +a +aa +DROP PROCEDURE p1; +SELECT a FROM (SELECT "aa" a) t WHERE REGEXP_INSTR(t.a, (SELECT MAX('aa') FROM DUAL LIMIT 1)); +a +aa +CREATE OR REPLACE FUNCTION f1(a VARCHAR(10), b VARCHAR(10)) RETURNS INT +BEGIN +RETURN 1; +END;$$ +CREATE OR REPLACE PROCEDURE p1(m1 varchar(5)) +BEGIN +SELECT a FROM (SELECT "aa" a) t WHERE f1(t.a, m1); +END$$ +CALL p1('a'); +a +aa +DROP PROCEDURE p1; +DROP FUNCTION f1; +CREATE OR REPLACE FUNCTION f1(a VARCHAR(10), b VARCHAR(10)) RETURNS INT +BEGIN +RETURN 1; +END;$$ +SELECT a FROM (SELECT "aa" a) t WHERE f1(t.a, (SELECT MAX('aa') FROM DUAL LIMIT 1)); +a +aa +DROP FUNCTION f1; diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test index e51646a9764..0c3a542f907 100644 --- a/mysql-test/main/derived_cond_pushdown.test +++ b/mysql-test/main/derived_cond_pushdown.test @@ -2906,3 +2906,83 @@ SELECT * FROM ( SELECT STRAIGHT_JOIN f, COUNT(*) as c FROM v1 GROUP BY f ) AS s; DROP VIEW v1; DROP TABLE t1; + +--echo # +--echo # MDEV-15087: error from inexpensive subquery before check +--echo # for condition pushdown into derived +--echo # + +CREATE TABLE t1 (i1 int, v1 varchar(1)); +INSERT INTO t1 VALUES (7,'x'); + +CREATE TABLE t2 (i1 int); +INSERT INTO t2 VALUES (8); + +CREATE TABLE t3 (i1 int ,v1 varchar(1), v2 varchar(1)); +INSERT INTO t3 VALUES (4, 'v','v'),(62,'v','k'),(7, 'n', NULL); + +--error ER_SUBQUERY_NO_1_ROW +SELECT 1 +FROM (t1 AS a1 + JOIN (((SELECT DISTINCT t3.* + FROM t3) AS a2 + JOIN t1 ON (t1.v1 = a2.v2))) ON (t1.v1 = a2.v1)) +WHERE (SELECT BIT_COUNT(t2.i1) + FROM (t2 JOIN t3)) IS NULL; + +DROP TABLE t1, t2, t3; + +--echo # +--echo # MDEV-16614 signal 7 after calling stored procedure, that uses regexp +--echo # + +DELIMITER $$; +CREATE PROCEDURE p1(m1 varchar(5), m2 varchar(5)) +BEGIN +SELECT a FROM + (SELECT "aa" a) t + JOIN (SELECT "aa" b) t1 on t.a=t1.b +WHERE t.a regexp m1 and t1.b regexp m2 +GROUP BY a; +END$$ +DELIMITER ;$$ +CALL p1('a','a'); +DROP PROCEDURE p1; + + +DELIMITER $$; +CREATE PROCEDURE p1(m1 varchar(5)) +BEGIN + SELECT a FROM (SELECT "aa" a) t WHERE t.a regexp m1; +END$$ +DELIMITER ;$$ +CALL p1('a'); +DROP PROCEDURE p1; + + +SELECT a FROM (SELECT "aa" a) t WHERE REGEXP_INSTR(t.a, (SELECT MAX('aa') FROM DUAL LIMIT 1)); + + +DELIMITER $$; +CREATE OR REPLACE FUNCTION f1(a VARCHAR(10), b VARCHAR(10)) RETURNS INT +BEGIN + RETURN 1; +END;$$ +CREATE OR REPLACE PROCEDURE p1(m1 varchar(5)) +BEGIN + SELECT a FROM (SELECT "aa" a) t WHERE f1(t.a, m1); +END$$ +DELIMITER ;$$ +CALL p1('a'); +DROP PROCEDURE p1; +DROP FUNCTION f1; + + +DELIMITER $$; +CREATE OR REPLACE FUNCTION f1(a VARCHAR(10), b VARCHAR(10)) RETURNS INT +BEGIN + RETURN 1; +END;$$ +DELIMITER ;$$ +SELECT a FROM (SELECT "aa" a) t WHERE f1(t.a, (SELECT MAX('aa') FROM DUAL LIMIT 1)); +DROP FUNCTION f1; diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index 84aee70663e..6a1745ece9c 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -761,6 +761,12 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; # +# MDEV-16054 simple json functions flatline cpu on garbage input. +# +select json_array(1,uuid(),compress(5.140264e+307)); +json_array(1,uuid(),compress(5.140264e+307)) +NULL +# # End of 10.2 tests # # diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index eddf64a0052..8f5cc02d616 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -423,6 +423,12 @@ SHOW CREATE TABLE t1; DROP TABLE t1; --echo # +--echo # MDEV-16054 simple json functions flatline cpu on garbage input. +--echo # + +select json_array(1,uuid(),compress(5.140264e+307)); + +--echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/main/grant.result b/mysql-test/main/grant.result index 1279bcdd41e..ba2d595a50e 100644 --- a/mysql-test/main/grant.result +++ b/mysql-test/main/grant.result @@ -1757,6 +1757,7 @@ drop user mysqltest@localhost; disconnect user1; drop database mysqltest; use test; +call mtr.add_suppression("Can't open and lock privilege tables"); FLUSH PRIVILEGES without procs_priv table. RENAME TABLE mysql.procs_priv TO mysql.procs_gone; FLUSH PRIVILEGES; @@ -1850,8 +1851,6 @@ BEGIN SET @x = 0; REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT; END ;|| -Warnings: -Warning 1404 Failed to grant EXECUTE and ALTER ROUTINE privileges connection default; SHOW GRANTS FOR 'user1'@'localhost'; Grants for user1@localhost @@ -1862,6 +1861,7 @@ SHOW GRANTS FOR 'user2'; Grants for user2@% GRANT USAGE ON *.* TO 'user2'@'%' GRANT CREATE, CREATE ROUTINE ON `db1`.* TO 'user2'@'%' +GRANT EXECUTE, ALTER ROUTINE ON PROCEDURE `db1`.`proc2` TO 'user2'@'%' disconnect con1; disconnect con2; DROP PROCEDURE db1.proc1; diff --git a/mysql-test/main/grant.test b/mysql-test/main/grant.test index cb4254fe8c6..c3bb987acc8 100644 --- a/mysql-test/main/grant.test +++ b/mysql-test/main/grant.test @@ -1598,6 +1598,9 @@ use test; # # Bug#16470 crash on grant if old grant tables # + +call mtr.add_suppression("Can't open and lock privilege tables"); + --echo FLUSH PRIVILEGES without procs_priv table. RENAME TABLE mysql.procs_priv TO mysql.procs_gone; FLUSH PRIVILEGES; diff --git a/mysql-test/main/join.result b/mysql-test/main/join.result index 046674d5569..1fc47041dfd 100644 --- a/mysql-test/main/join.result +++ b/mysql-test/main/join.result @@ -1506,6 +1506,46 @@ DROP VIEW v2; DROP TABLE t1,t2; SET optimizer_switch=@save_optimizer_switch; # +# MDEV-16512 +# Server crashes in find_field_in_table_ref on 2nd execution of SP referring to +# non-existing field +# +CREATE TABLE t (i INT); +CREATE PROCEDURE p() SELECT t1.f FROM t AS t1 JOIN t AS t2 USING (f); +CALL p; +ERROR 42S22: Unknown column 'f' in 'from clause' +CALL p; +ERROR 42S22: Unknown column 'f' in 'from clause' +FLUSH TABLES; +CALL p; +ERROR 42S22: Unknown column 'f' in 'from clause' +DROP TABLE t; +CREATE TABLE t (f INT); +CALL p; +ERROR 42S22: Unknown column 'f' in 'from clause' +DROP TABLE t; +CREATE TABLE t (i INT); +CALL p; +ERROR 42S22: Unknown column 'f' in 'from clause' +DROP PROCEDURE p; +DROP TABLE t; +CREATE TABLE t1 (a INT, b INT); +CREATE TABLE t2 (a INT); +CREATE TABLE t3 (a INT, c INT); +CREATE TABLE t4 (a INT, c INT); +CREATE TABLE t5 (a INT, c INT); +CREATE PROCEDURE p1() SELECT c FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a) +LEFT JOIN t5 USING (a)) USING (a); +CALL p1; +ERROR 23000: Column 'c' in field list is ambiguous +CALL p1; +ERROR 23000: Column 'c' in field list is ambiguous +DROP PROCEDURE p1; +DROP TABLE t1,t2,t3,t4,t5; +# +# End of MariaDB 5.5 tests +# +# # Bug #35268: Parser can't handle STRAIGHT_JOIN with USING # CREATE TABLE t1 (a int); diff --git a/mysql-test/main/join.test b/mysql-test/main/join.test index e07a3665920..8a088de91cc 100644 --- a/mysql-test/main/join.test +++ b/mysql-test/main/join.test @@ -1161,6 +1161,59 @@ DROP TABLE t1,t2; SET optimizer_switch=@save_optimizer_switch; --echo # +--echo # MDEV-16512 +--echo # Server crashes in find_field_in_table_ref on 2nd execution of SP referring to +--echo # non-existing field +--echo # + +CREATE TABLE t (i INT); +CREATE PROCEDURE p() SELECT t1.f FROM t AS t1 JOIN t AS t2 USING (f); +--error ER_BAD_FIELD_ERROR +CALL p; +--error ER_BAD_FIELD_ERROR +CALL p; +FLUSH TABLES; +--error ER_BAD_FIELD_ERROR +CALL p; +DROP TABLE t; + +# +# Fix the table definition to match the using +# + +CREATE TABLE t (f INT); +# +# The following shouldn't fail as the table is now matching the using +# +--error ER_BAD_FIELD_ERROR +CALL p; +DROP TABLE t; +CREATE TABLE t (i INT); +--error ER_BAD_FIELD_ERROR +CALL p; +DROP PROCEDURE p; +DROP TABLE t; + +CREATE TABLE t1 (a INT, b INT); +CREATE TABLE t2 (a INT); +CREATE TABLE t3 (a INT, c INT); +CREATE TABLE t4 (a INT, c INT); +CREATE TABLE t5 (a INT, c INT); +CREATE PROCEDURE p1() SELECT c FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a) +LEFT JOIN t5 USING (a)) USING (a); +--error ER_NON_UNIQ_ERROR +CALL p1; +--error ER_NON_UNIQ_ERROR +CALL p1; +DROP PROCEDURE p1; +DROP TABLE t1,t2,t3,t4,t5; + +--echo # +--echo # End of MariaDB 5.5 tests +--echo # + + +--echo # --echo # Bug #35268: Parser can't handle STRAIGHT_JOIN with USING --echo # diff --git a/mysql-test/main/join_cache.result b/mysql-test/main/join_cache.result index eea397402ad..fde6e0fec6b 100644 --- a/mysql-test/main/join_cache.result +++ b/mysql-test/main/join_cache.result @@ -5925,6 +5925,39 @@ SET join_buffer_space_limit= default; set optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t4,t5,t2; # +# MDEV-16603: BNLH for query with materialized semi-join +# +set join_cache_level=4; +CREATE TABLE t1 ( i1 int, v1 varchar(1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (7,'x'); +CREATE TABLE t2 (i1 int, v1 varchar(1), KEY v1 (v1,i1)) ENGINE=InnoDB; +INSERT INTO t2 VALUES +(NULL,'x'),(1,'x'),(3,'x'),(5,'x'),(8,'x'),(48,'x'), +(228,'x'),(3,'y'),(1,'z'),(9,'z'); +CREATE TABLE temp +SELECT t1.i1 AS f1, t1.v1 AS f2 FROM (t2 JOIN t1 ON (t1.v1 = t2.v1)); +SELECT * FROM temp +WHERE (f1,f2) IN (SELECT t1.i1, t1.v1 FROM (t2 JOIN t1 ON (t1.v1 = t2.v1))); +f1 f2 +7 x +7 x +7 x +7 x +7 x +7 x +7 x +EXPLAIN EXTENDED SELECT * FROM temp +WHERE (f1,f2) IN (SELECT t1.i1, t1.v1 FROM (t2 JOIN t1 ON (t1.v1 = t2.v1))); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1 100.00 +1 PRIMARY temp hash_ALL NULL #hash#$hj 9 test.t1.i1,test.t1.v1 7 100.00 Using where; Using join buffer (flat, BNLH join) +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 1 100.00 Using where +2 MATERIALIZED t2 hash_index v1 #hash#v1:v1 4:9 test.t1.v1 10 10.00 Using index; Using join buffer (flat, BNLH join) +Warnings: +Note 1003 select `test`.`temp`.`f1` AS `f1`,`test`.`temp`.`f2` AS `f2` from `test`.`temp` semi join (`test`.`t2` join `test`.`t1`) where `test`.`temp`.`f1` = `test`.`t1`.`i1` and `test`.`t2`.`v1` = `test`.`t1`.`v1` and `test`.`temp`.`f2` = `test`.`t1`.`v1` +DROP TABLE t1,t2,temp; +SET join_cache_level = default; +# # MDEV-5123 Remove duplicated conditions pushed both to join_tab->select_cond and join_tab->cache_select->cond for blocked joins. # set join_cache_level=default; diff --git a/mysql-test/main/join_cache.test b/mysql-test/main/join_cache.test index b775725903c..df89fc30dee 100644 --- a/mysql-test/main/join_cache.test +++ b/mysql-test/main/join_cache.test @@ -3870,6 +3870,37 @@ set optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t4,t5,t2; --echo # +--echo # MDEV-16603: BNLH for query with materialized semi-join +--echo # + +--source include/have_innodb.inc + +set join_cache_level=4; + +CREATE TABLE t1 ( i1 int, v1 varchar(1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (7,'x'); + +CREATE TABLE t2 (i1 int, v1 varchar(1), KEY v1 (v1,i1)) ENGINE=InnoDB; + +INSERT INTO t2 VALUES + (NULL,'x'),(1,'x'),(3,'x'),(5,'x'),(8,'x'),(48,'x'), + (228,'x'),(3,'y'),(1,'z'),(9,'z'); + +CREATE TABLE temp +SELECT t1.i1 AS f1, t1.v1 AS f2 FROM (t2 JOIN t1 ON (t1.v1 = t2.v1)); + +let $q = +SELECT * FROM temp +WHERE (f1,f2) IN (SELECT t1.i1, t1.v1 FROM (t2 JOIN t1 ON (t1.v1 = t2.v1))); + +eval $q; +eval EXPLAIN EXTENDED $q; + +DROP TABLE t1,t2,temp; + +SET join_cache_level = default; + +--echo # --echo # MDEV-5123 Remove duplicated conditions pushed both to join_tab->select_cond and join_tab->cache_select->cond for blocked joins. --echo # @@ -3958,5 +3989,4 @@ drop table t1, t2; set join_buffer_size = default; # The following command must be the last one the file -# this must be the last command in the file set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/main/join_outer.result b/mysql-test/main/join_outer.result index 6753349dece..9245111369f 100644 --- a/mysql-test/main/join_outer.result +++ b/mysql-test/main/join_outer.result @@ -2460,5 +2460,55 @@ id sid id 1 NULL NULL 2 NULL NULL drop table t1, t2; +# +# MDEV-16726: SELECT with STRAGHT JOIN containing NESTED RIGHT JOIN +# converted to INNER JOIN with first constant inner table +# +CREATE TABLE t1 ( +pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1), KEY v1 (v1,i1) +) engine=MyISAM; +INSERT INTO t1 VALUES +(8,3,'c','c'),(9,4,'z','z'),(10,3,'i','i'),(11,186,'x','x'), +(14,226,'m','m'),(15,133,'p','p'); +CREATE TABLE t2 ( +pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1) +) engine=MyISAM; +INSERT INTO t2 VALUES (10,6,'p','p'); +EXPLAIN EXTENDED +SELECT STRAIGHT_JOIN t2.v2 +FROM +(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) +RIGHT JOIN +(t2,t1) +ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select straight_join 'p' AS `v2` from `test`.`t1` join `test`.`t1` `tb1` left join `test`.`t1` `tb2` on(multiple equal(NULL, NULL)) where 0 order by NULL +EXPLAIN EXTENDED +SELECT STRAIGHT_JOIN t2.v2 +FROM +(t2,t1) +LEFT JOIN +(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) +ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select straight_join 'p' AS `v2` from `test`.`t1` join `test`.`t1` `tb1` left join `test`.`t1` `tb2` on(multiple equal(NULL, NULL)) where 0 order by NULL +SELECT STRAIGHT_JOIN DISTINCT t2.v2 +FROM +(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) +RIGHT JOIN +(t2,t1) +ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; +v2 +DROP TABLE t1,t2; # end of 5.5 tests SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/main/join_outer.test b/mysql-test/main/join_outer.test index 34b0551a32e..6d20c089bd9 100644 --- a/mysql-test/main/join_outer.test +++ b/mysql-test/main/join_outer.test @@ -1992,6 +1992,54 @@ select * from t1 t on t.id=r.id ; drop table t1, t2; +--echo # +--echo # MDEV-16726: SELECT with STRAGHT JOIN containing NESTED RIGHT JOIN +--echo # converted to INNER JOIN with first constant inner table +--echo # + +CREATE TABLE t1 ( + pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1), KEY v1 (v1,i1) +) engine=MyISAM; +INSERT INTO t1 VALUES + (8,3,'c','c'),(9,4,'z','z'),(10,3,'i','i'),(11,186,'x','x'), + (14,226,'m','m'),(15,133,'p','p'); + +CREATE TABLE t2 ( + pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1) +) engine=MyISAM; +INSERT INTO t2 VALUES (10,6,'p','p'); + +EXPLAIN EXTENDED +SELECT STRAIGHT_JOIN t2.v2 +FROM + (t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) + RIGHT JOIN + (t2,t1) + ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; + +EXPLAIN EXTENDED +SELECT STRAIGHT_JOIN t2.v2 +FROM + (t2,t1) + LEFT JOIN + (t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) + ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; + +SELECT STRAIGHT_JOIN DISTINCT t2.v2 +FROM + (t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) + RIGHT JOIN + (t2,t1) + ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; + +DROP TABLE t1,t2; + --echo # end of 5.5 tests SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/main/join_outer_jcl6.result b/mysql-test/main/join_outer_jcl6.result index 9ff501baf6a..cb582b1399f 100644 --- a/mysql-test/main/join_outer_jcl6.result +++ b/mysql-test/main/join_outer_jcl6.result @@ -2471,6 +2471,56 @@ id sid id 1 NULL NULL 2 NULL NULL drop table t1, t2; +# +# MDEV-16726: SELECT with STRAGHT JOIN containing NESTED RIGHT JOIN +# converted to INNER JOIN with first constant inner table +# +CREATE TABLE t1 ( +pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1), KEY v1 (v1,i1) +) engine=MyISAM; +INSERT INTO t1 VALUES +(8,3,'c','c'),(9,4,'z','z'),(10,3,'i','i'),(11,186,'x','x'), +(14,226,'m','m'),(15,133,'p','p'); +CREATE TABLE t2 ( +pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1) +) engine=MyISAM; +INSERT INTO t2 VALUES (10,6,'p','p'); +EXPLAIN EXTENDED +SELECT STRAIGHT_JOIN t2.v2 +FROM +(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) +RIGHT JOIN +(t2,t1) +ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select straight_join 'p' AS `v2` from `test`.`t1` join `test`.`t1` `tb1` left join `test`.`t1` `tb2` on(multiple equal(NULL, NULL)) where 0 order by NULL +EXPLAIN EXTENDED +SELECT STRAIGHT_JOIN t2.v2 +FROM +(t2,t1) +LEFT JOIN +(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) +ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select straight_join 'p' AS `v2` from `test`.`t1` join `test`.`t1` `tb1` left join `test`.`t1` `tb2` on(multiple equal(NULL, NULL)) where 0 order by NULL +SELECT STRAIGHT_JOIN DISTINCT t2.v2 +FROM +(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) +RIGHT JOIN +(t2,t1) +ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; +v2 +DROP TABLE t1,t2; # end of 5.5 tests SET optimizer_switch=@save_optimizer_switch; set join_cache_level=default; diff --git a/mysql-test/main/rename.result b/mysql-test/main/rename.result index 3ee9dd593d4..da9e4b62ecd 100644 --- a/mysql-test/main/rename.result +++ b/mysql-test/main/rename.result @@ -144,3 +144,7 @@ select * from t2; a 1 drop table tmp,t2; +create table t1 (a int) engine=memory; +rename table t1 to non_existent.t2; +ERROR 42000: Unknown database 'non_existent' +drop table t1; diff --git a/mysql-test/main/rename.test b/mysql-test/main/rename.test index 67732d5b5b9..215ecbcbb18 100644 --- a/mysql-test/main/rename.test +++ b/mysql-test/main/rename.test @@ -141,3 +141,10 @@ select * from tmp; select * from t2; drop table tmp,t2; +# +# MDEV-11741 handler::ha_reset(): Assertion `bitmap_is_set_all(&table->s->all_set)' failed or server crash in mi_reset or buffer overrun or unexpected ER_CANT_REMOVE_ALL_FIELDS +# +create table t1 (a int) engine=memory; +--error ER_BAD_DB_ERROR +rename table t1 to non_existent.t2; +drop table t1; diff --git a/mysql-test/main/sp_notembedded.result b/mysql-test/main/sp_notembedded.result index 190f8f78d23..8edb9e79b70 100644 --- a/mysql-test/main/sp_notembedded.result +++ b/mysql-test/main/sp_notembedded.result @@ -228,8 +228,6 @@ FLUSH PRIVILEGES; connect con1, localhost, mysqltest_1,,; connection con1; CREATE PROCEDURE p1(i INT) BEGIN END; -Warnings: -Warning 1404 Failed to grant EXECUTE and ALTER ROUTINE privileges disconnect con1; connection default; DROP PROCEDURE p1; diff --git a/mysql-test/main/stat_tables.result b/mysql-test/main/stat_tables.result index fcced761283..ceadb61feea 100644 --- a/mysql-test/main/stat_tables.result +++ b/mysql-test/main/stat_tables.result @@ -516,4 +516,133 @@ use test; drop database db1; drop database db2; drop table t1; +# +# MDEV-16552: [10.0] ASAN global-buffer-overflow in is_stat_table / statistics_for_tables_is_needed +# +SET use_stat_tables = PREFERABLY; +SELECT CONVERT_TZ( '1991-09-20 10:11:02', '+00:00', 'GMT' ); +CONVERT_TZ( '1991-09-20 10:11:02', '+00:00', 'GMT' ) +NULL +set use_stat_tables=@save_use_stat_tables; +# +# MDEV-16757: manual addition of min/max statistics for BLOB +# +SET use_stat_tables= PREFERABLY; +CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze Warning Engine-independent statistics are not collected for column 't' +test.t1 analyze status OK +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +DELETE FROM mysql.column_stats +WHERE db_name='test' AND table_name='t1' AND column_name='t'; +INSERT INTO mysql.column_stats VALUES +('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL); +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 t bar foo 0.0000 3.0000 1.0000 0 NULL NULL +SELECT pk FROM t1; +pk +1 +2 +DROP TABLE t1; +set use_stat_tables=@save_use_stat_tables; +# +# MDEV-16760: CREATE OR REPLACE TABLE after ANALYZE TABLE +# +SET use_stat_tables= PREFERABLY; +CREATE TABLE t1 (pk int PRIMARY KEY, c varchar(32)); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +SELECT * FROM t1; +pk c +1 foo +2 bar +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 c bar foo 0.0000 3.0000 1.0000 0 NULL NULL +CREATE OR REPLACE TABLE t1 (pk int PRIMARY KEY, a char(7)); +SELECT * FROM t1; +pk a +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +DROP TABLE t1; +set use_stat_tables=@save_use_stat_tables; +# +# MDEV-16757: manual addition of min/max statistics for BLOB +# +SET use_stat_tables= PREFERABLY; +CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze Warning Engine-independent statistics are not collected for column 't' +test.t1 analyze status OK +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +DELETE FROM mysql.column_stats +WHERE db_name='test' AND table_name='t1' AND column_name='t'; +INSERT INTO mysql.column_stats VALUES +('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL); +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 t bar foo 0.0000 3.0000 1.0000 0 NULL NULL +SELECT pk FROM t1; +pk +1 +2 +DROP TABLE t1; +set use_stat_tables=@save_use_stat_tables; +# +# MDEV-16760: CREATE OR REPLACE TABLE after ANALYZE TABLE +# +SET use_stat_tables= PREFERABLY; +CREATE TABLE t1 (pk int PRIMARY KEY, c varchar(32)); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +SELECT * FROM t1; +pk c +1 foo +2 bar +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 c bar foo 0.0000 3.0000 1.0000 0 NULL NULL +CREATE OR REPLACE TABLE t1 (pk int PRIMARY KEY, a char(7)); +SELECT * FROM t1; +pk a +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +DROP TABLE t1; +set use_stat_tables=@save_use_stat_tables; +# +# MDEV-16711:CREATE OR REPLACE TABLE introducing BLOB column +# +SET use_stat_tables= PREFERABLY; +CREATE TABLE t1 (pk INT PRIMARY KEY, t CHAR(60)); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY, t TEXT); +SELECT MAX(pk) FROM t1; +MAX(pk) +NULL +DROP TABLE t1; set use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/main/stat_tables.test b/mysql-test/main/stat_tables.test index 4cbaa9e27c8..2c9c1eca7d3 100644 --- a/mysql-test/main/stat_tables.test +++ b/mysql-test/main/stat_tables.test @@ -305,4 +305,116 @@ drop database db1; drop database db2; drop table t1; +--echo # +--echo # MDEV-16552: [10.0] ASAN global-buffer-overflow in is_stat_table / statistics_for_tables_is_needed +--echo # + +SET use_stat_tables = PREFERABLY; +SELECT CONVERT_TZ( '1991-09-20 10:11:02', '+00:00', 'GMT' ); +set use_stat_tables=@save_use_stat_tables; + +--echo # +--echo # MDEV-16757: manual addition of min/max statistics for BLOB +--echo # + +SET use_stat_tables= PREFERABLY; + +CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +--sorted_result +SELECT * FROM mysql.column_stats; +DELETE FROM mysql.column_stats + WHERE db_name='test' AND table_name='t1' AND column_name='t'; +INSERT INTO mysql.column_stats VALUES + ('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL); +--sorted_result +SELECT * FROM mysql.column_stats; + +SELECT pk FROM t1; + +DROP TABLE t1; + +set use_stat_tables=@save_use_stat_tables; + +--echo # +--echo # MDEV-16760: CREATE OR REPLACE TABLE after ANALYZE TABLE +--echo # + +SET use_stat_tables= PREFERABLY; + +CREATE TABLE t1 (pk int PRIMARY KEY, c varchar(32)); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +SELECT * FROM t1; +SELECT * FROM mysql.column_stats; + +CREATE OR REPLACE TABLE t1 (pk int PRIMARY KEY, a char(7)); +SELECT * FROM t1; +SELECT * FROM mysql.column_stats; + +DROP TABLE t1; + +set use_stat_tables=@save_use_stat_tables; + +--echo # +--echo # MDEV-16757: manual addition of min/max statistics for BLOB +--echo # + +SET use_stat_tables= PREFERABLY; + +CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +--sorted_result +SELECT * FROM mysql.column_stats; +DELETE FROM mysql.column_stats + WHERE db_name='test' AND table_name='t1' AND column_name='t'; +INSERT INTO mysql.column_stats VALUES + ('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL); +--sorted_result +SELECT * FROM mysql.column_stats; + +SELECT pk FROM t1; + +DROP TABLE t1; + +set use_stat_tables=@save_use_stat_tables; + +--echo # +--echo # MDEV-16760: CREATE OR REPLACE TABLE after ANALYZE TABLE +--echo # + +SET use_stat_tables= PREFERABLY; + +CREATE TABLE t1 (pk int PRIMARY KEY, c varchar(32)); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +SELECT * FROM t1; +SELECT * FROM mysql.column_stats; + +CREATE OR REPLACE TABLE t1 (pk int PRIMARY KEY, a char(7)); +SELECT * FROM t1; +SELECT * FROM mysql.column_stats; + +DROP TABLE t1; + +set use_stat_tables=@save_use_stat_tables; + + +--echo # +--echo # MDEV-16711:CREATE OR REPLACE TABLE introducing BLOB column +--echo # + +SET use_stat_tables= PREFERABLY; + +CREATE TABLE t1 (pk INT PRIMARY KEY, t CHAR(60)); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY, t TEXT); + +SELECT MAX(pk) FROM t1; + +DROP TABLE t1; + set use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/main/stat_tables_innodb.result b/mysql-test/main/stat_tables_innodb.result index 42443bfcb72..7b98ca4259f 100644 --- a/mysql-test/main/stat_tables_innodb.result +++ b/mysql-test/main/stat_tables_innodb.result @@ -543,6 +543,135 @@ use test; drop database db1; drop database db2; drop table t1; +# +# MDEV-16552: [10.0] ASAN global-buffer-overflow in is_stat_table / statistics_for_tables_is_needed +# +SET use_stat_tables = PREFERABLY; +SELECT CONVERT_TZ( '1991-09-20 10:11:02', '+00:00', 'GMT' ); +CONVERT_TZ( '1991-09-20 10:11:02', '+00:00', 'GMT' ) +NULL +set use_stat_tables=@save_use_stat_tables; +# +# MDEV-16757: manual addition of min/max statistics for BLOB +# +SET use_stat_tables= PREFERABLY; +CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze Warning Engine-independent statistics are not collected for column 't' +test.t1 analyze status OK +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +DELETE FROM mysql.column_stats +WHERE db_name='test' AND table_name='t1' AND column_name='t'; +INSERT INTO mysql.column_stats VALUES +('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL); +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 t bar foo 0.0000 3.0000 1.0000 0 NULL NULL +SELECT pk FROM t1; +pk +1 +2 +DROP TABLE t1; +set use_stat_tables=@save_use_stat_tables; +# +# MDEV-16760: CREATE OR REPLACE TABLE after ANALYZE TABLE +# +SET use_stat_tables= PREFERABLY; +CREATE TABLE t1 (pk int PRIMARY KEY, c varchar(32)); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +SELECT * FROM t1; +pk c +1 foo +2 bar +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 c bar foo 0.0000 3.0000 1.0000 0 NULL NULL +CREATE OR REPLACE TABLE t1 (pk int PRIMARY KEY, a char(7)); +SELECT * FROM t1; +pk a +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +DROP TABLE t1; +set use_stat_tables=@save_use_stat_tables; +# +# MDEV-16757: manual addition of min/max statistics for BLOB +# +SET use_stat_tables= PREFERABLY; +CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze Warning Engine-independent statistics are not collected for column 't' +test.t1 analyze status OK +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +DELETE FROM mysql.column_stats +WHERE db_name='test' AND table_name='t1' AND column_name='t'; +INSERT INTO mysql.column_stats VALUES +('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL); +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 t bar foo 0.0000 3.0000 1.0000 0 NULL NULL +SELECT pk FROM t1; +pk +1 +2 +DROP TABLE t1; +set use_stat_tables=@save_use_stat_tables; +# +# MDEV-16760: CREATE OR REPLACE TABLE after ANALYZE TABLE +# +SET use_stat_tables= PREFERABLY; +CREATE TABLE t1 (pk int PRIMARY KEY, c varchar(32)); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +SELECT * FROM t1; +pk c +1 foo +2 bar +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 c bar foo 0.0000 3.0000 1.0000 0 NULL NULL +CREATE OR REPLACE TABLE t1 (pk int PRIMARY KEY, a char(7)); +SELECT * FROM t1; +pk a +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +DROP TABLE t1; +set use_stat_tables=@save_use_stat_tables; +# +# MDEV-16711:CREATE OR REPLACE TABLE introducing BLOB column +# +SET use_stat_tables= PREFERABLY; +CREATE TABLE t1 (pk INT PRIMARY KEY, t CHAR(60)); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY, t TEXT); +SELECT MAX(pk) FROM t1; +MAX(pk) +NULL +DROP TABLE t1; set use_stat_tables=@save_use_stat_tables; set optimizer_switch=@save_optimizer_switch_for_stat_tables_test; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/main/subselect_mat.result b/mysql-test/main/subselect_mat.result index 4d425d0fe5c..1a5f0c8e93b 100644 --- a/mysql-test/main/subselect_mat.result +++ b/mysql-test/main/subselect_mat.result @@ -2391,6 +2391,99 @@ ec70316637232000158bbfc8bcbe5d60 ebb4620037332000158bbfc8bcbe5d89 DROP TABLE t1,t2,t3; set optimizer_switch=@save_optimizer_switch; +# +# MDEV-16751: Server crashes in st_join_table::cleanup or +# TABLE_LIST::is_with_table_recursive_reference with join_cache_level>2 +# +set @save_join_cache_level= @@join_cache_level; +set join_cache_level=4; +CREATE TABLE t1 ( id int NOT NULL); +INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19); +CREATE TABLE t2 (i1 int NOT NULL, i2 int NOT NULL) ; +INSERT INTO t2 VALUES (11,11),(12,12),(13,13); +explain +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 +1 PRIMARY t1 hash_ALL NULL #hash#$hj 4 test.t2.i1 9 Using where; Using join buffer (flat, BNLH join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +1 +1 +1 +1 +set @@join_cache_level= @save_join_cache_level; +alter table t1 add key(id); +explain +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 +1 PRIMARY t1 ref id id 4 test.t2.i1 2 Using index +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +1 +1 +1 +1 +drop table t1,t2; +# +# MDEV-15454: Nested SELECT IN returns wrong results +# +CREATE TABLE t1 ( a int NOT NULL PRIMARY KEY); +CREATE TABLE t2 ( a int, b int ); +INSERT INTO t2 VALUES (7878, 96),(3465, 96),(1403, 96),(4189, 96),(8732, 96), (5,96); +CREATE TABLE t3 (c int unsigned NOT NULL, b int unsigned NOT NULL, PRIMARY KEY (c,b)); +INSERT INTO t3 (c, b) VALUES (27, 96); +CREATE PROCEDURE prepare_data() +BEGIN +DECLARE i INT DEFAULT 1; +WHILE i < 1000 DO +INSERT INTO t1 (a) VALUES (i); +INSERT INTO t2 (a,b) VALUES (i,56); +INSERT INTO t3 (c,b) VALUES (i,i); +SET i = i + 1; +END WHILE; +END$$ +CALL prepare_data(); +SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27); +a +7878 +3465 +1403 +4189 +8732 +5 +set @save_optimizer_switch= @@optimizer_switch; +SET optimizer_switch='materialization=off'; +SELECT t1.a FROM t1 +WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27)) LIMIT 5; +a +5 +SET optimizer_switch='materialization=on'; +SELECT t1.a FROM t1 +WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27)) LIMIT 5; +a +5 +drop procedure prepare_data; +set @@optimizer_switch= @save_optimizer_switch; +drop table t1,t2,t3; +CREATE TABLE t1 ( id int NOT NULL, key(id)); +INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19); +CREATE TABLE t2 (i1 int NOT NULL, i2 int NOT NULL); +INSERT INTO t2 VALUES (11,11),(12,12),(13,13); +CREATE VIEW v1 AS SELECT t2.i1 FROM t2 where t2.i1 = t2.i2; +explain SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 +1 PRIMARY t1 ref id id 4 test.t2.i1 2 Using index +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); +1 +1 +1 +1 +drop table t1,t2; +drop view v1; # End of 5.5 tests # # MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT diff --git a/mysql-test/main/subselect_mat_cost_bugs.result b/mysql-test/main/subselect_mat_cost_bugs.result index 658722112d2..6377ae556d2 100644 --- a/mysql-test/main/subselect_mat_cost_bugs.result +++ b/mysql-test/main/subselect_mat_cost_bugs.result @@ -442,7 +442,7 @@ SELECT i2 FROM t2 RIGHT JOIN t3 ON (c3 = c2) WHERE pk3 = i1 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 t3 const PRIMARY PRIMARY 4 const 1 -2 DEPENDENT SUBQUERY t2 index NULL i2 11 NULL 2 Using where; Using index +2 DEPENDENT SUBQUERY t2 index i2 i2 11 NULL 2 Using where; Using index DROP TABLE t1,t2,t3; # # MDEV-7599: in-to-exists chosen after min/max optimization diff --git a/mysql-test/main/subselect_sj2_mat.result b/mysql-test/main/subselect_sj2_mat.result index 62248536e34..884451d7dff 100644 --- a/mysql-test/main/subselect_sj2_mat.result +++ b/mysql-test/main/subselect_sj2_mat.result @@ -1728,6 +1728,57 @@ id 13 drop table t1; # +# MDEV-15982: Incorrect results when subquery is materialized +# +CREATE TABLE `t1` (`id` int(32) NOT NULL primary key); +INSERT INTO `t1` VALUES +(45), (46), (47), (48), (49), (50), (51), (52), (53), (54), (55), (56), (57), (58), (59), (60), (61), (62), +(63), (64), (65), (66), (67), (68), (69), (70), (71), (72), (73), (74), (75), (76), (77), (78), (79), (80), +(81), (82), (83), (84), (85), (86), (87), (88), (89), (90), (91), (92),(93),(94),(95),(96), (97), (98), +(99), (100), (101), (102), (103), (104), (105), (106), (107), (108), (109), (110), (111), (112), (113), +(114), (115), (116), (117), (118), (119), (120), (121), (122), (123), (124), (125), (126), (127), (128), +(129), (130), (131), (132), (133), (134), (135), (136), (137), (138), (139), (140), (141), (142), (143), (144), (145), (146), +(147), (148), (149), (150), (151), (152), (153), (154), (155), (156), (157), (158), (159), (160), (161), +(162), (163), (164), (165), (166), (167), (168), (169), (170), (171), (172), (173), +(174), (175), (176), (177), (178), (179), (180), (181), (182), (183), (2), (3), (4), (5), (6), (19), (35), +(7), (20), (8), (36), (219), (22), (10), (23), (37), (11), (24); +CREATE TABLE `t2` (`type` int , `id` int(32) NOT NULL primary key); +INSERT INTO `t2` VALUES +(2,2),(2,3),(1,4),(2,5),(1,6),(1,19),(5,7),(1,20),(1,8),(1,21),(1,9), +(1,22),(2,10),(1,23),(2,11),(1,24),(1,12),(1,25),(2,13),(2,26),(2,14), +(2,27),(1,15),(1,28),(3,16),(1,29),(2,17),(1,30),(5,18),(2,1); +CREATE TABLE `t3` (`ref_id` int(32) unsigned ,`type` varchar(80),`id` int(32) NOT NULL ); +INSERT INTO `t3` VALUES +(1,'incident',31),(2,'faux pas',32), +(5,'oopsies',33),(3,'deniable',34), +(11,'wasntme',35),(10,'wasntme',36), +(17,'faux pas',37),(13,'unlikely',38), +(13,'improbable',39),(14,'incident',40), +(26,'problem',41),(14,'problem',42), +(26,'incident',43),(27,'incident',44); +explain +SELECT t2.id FROM t2,t1 +WHERE t2.id IN (SELECT t3.ref_id FROM t3,t1 where t3.id = t1.id) and t2.id = t1.id; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 30 Using index +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 Using where +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t2.id 1 Using index +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 14 +2 MATERIALIZED t1 eq_ref PRIMARY PRIMARY 4 test.t3.id 1 Using index +SELECT t2.id FROM t2,t1 +WHERE t2.id IN (SELECT t3.ref_id FROM t3,t1 where t3.id = t1.id) and t2.id = t1.id; +id +10 +11 +set optimizer_switch='materialization=off'; +SELECT t2.id FROM t2,t1 +WHERE t2.id IN (SELECT t3.ref_id FROM t3,t1 where t3.id = t1.id) and t2.id = t1.id; +id +11 +10 +set optimizer_switch='materialization=on'; +DROP TABLE t1,t2,t3; +# # MDEV-15247: Crash when SET NAMES 'utf8' is set # CREATE TABLE t1 ( diff --git a/mysql-test/main/subselect_sj2_mat.test b/mysql-test/main/subselect_sj2_mat.test index bba436078e3..6ae687aa99a 100644 --- a/mysql-test/main/subselect_sj2_mat.test +++ b/mysql-test/main/subselect_sj2_mat.test @@ -347,6 +347,55 @@ WHERE ( drop table t1; --echo # +--echo # MDEV-15982: Incorrect results when subquery is materialized +--echo # + +CREATE TABLE `t1` (`id` int(32) NOT NULL primary key); +INSERT INTO `t1` VALUES +(45), (46), (47), (48), (49), (50), (51), (52), (53), (54), (55), (56), (57), (58), (59), (60), (61), (62), +(63), (64), (65), (66), (67), (68), (69), (70), (71), (72), (73), (74), (75), (76), (77), (78), (79), (80), +(81), (82), (83), (84), (85), (86), (87), (88), (89), (90), (91), (92),(93),(94),(95),(96), (97), (98), +(99), (100), (101), (102), (103), (104), (105), (106), (107), (108), (109), (110), (111), (112), (113), +(114), (115), (116), (117), (118), (119), (120), (121), (122), (123), (124), (125), (126), (127), (128), +(129), (130), (131), (132), (133), (134), (135), (136), (137), (138), (139), (140), (141), (142), (143), (144), (145), (146), +(147), (148), (149), (150), (151), (152), (153), (154), (155), (156), (157), (158), (159), (160), (161), +(162), (163), (164), (165), (166), (167), (168), (169), (170), (171), (172), (173), +(174), (175), (176), (177), (178), (179), (180), (181), (182), (183), (2), (3), (4), (5), (6), (19), (35), +(7), (20), (8), (36), (219), (22), (10), (23), (37), (11), (24); + +CREATE TABLE `t2` (`type` int , `id` int(32) NOT NULL primary key); +INSERT INTO `t2` VALUES +(2,2),(2,3),(1,4),(2,5),(1,6),(1,19),(5,7),(1,20),(1,8),(1,21),(1,9), +(1,22),(2,10),(1,23),(2,11),(1,24),(1,12),(1,25),(2,13),(2,26),(2,14), +(2,27),(1,15),(1,28),(3,16),(1,29),(2,17),(1,30),(5,18),(2,1); + +CREATE TABLE `t3` (`ref_id` int(32) unsigned ,`type` varchar(80),`id` int(32) NOT NULL ); +INSERT INTO `t3` VALUES +(1,'incident',31),(2,'faux pas',32), +(5,'oopsies',33),(3,'deniable',34), +(11,'wasntme',35),(10,'wasntme',36), +(17,'faux pas',37),(13,'unlikely',38), +(13,'improbable',39),(14,'incident',40), +(26,'problem',41),(14,'problem',42), +(26,'incident',43),(27,'incident',44); + +explain +SELECT t2.id FROM t2,t1 + WHERE t2.id IN (SELECT t3.ref_id FROM t3,t1 where t3.id = t1.id) and t2.id = t1.id; + +SELECT t2.id FROM t2,t1 + WHERE t2.id IN (SELECT t3.ref_id FROM t3,t1 where t3.id = t1.id) and t2.id = t1.id; + +set optimizer_switch='materialization=off'; + +SELECT t2.id FROM t2,t1 + WHERE t2.id IN (SELECT t3.ref_id FROM t3,t1 where t3.id = t1.id) and t2.id = t1.id; +set optimizer_switch='materialization=on'; + +DROP TABLE t1,t2,t3; + + +--echo # --echo # MDEV-15247: Crash when SET NAMES 'utf8' is set --echo # diff --git a/mysql-test/main/subselect_sj_mat.result b/mysql-test/main/subselect_sj_mat.result index 9e1870875ce..5ba68f095fd 100644 --- a/mysql-test/main/subselect_sj_mat.result +++ b/mysql-test/main/subselect_sj_mat.result @@ -2431,6 +2431,99 @@ ec70316637232000158bbfc8bcbe5d60 ebb4620037332000158bbfc8bcbe5d89 DROP TABLE t1,t2,t3; set optimizer_switch=@save_optimizer_switch; +# +# MDEV-16751: Server crashes in st_join_table::cleanup or +# TABLE_LIST::is_with_table_recursive_reference with join_cache_level>2 +# +set @save_join_cache_level= @@join_cache_level; +set join_cache_level=4; +CREATE TABLE t1 ( id int NOT NULL); +INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19); +CREATE TABLE t2 (i1 int NOT NULL, i2 int NOT NULL) ; +INSERT INTO t2 VALUES (11,11),(12,12),(13,13); +explain +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 +1 PRIMARY t1 hash_ALL NULL #hash#$hj 4 test.t2.i1 9 Using where; Using join buffer (flat, BNLH join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +1 +1 +1 +1 +set @@join_cache_level= @save_join_cache_level; +alter table t1 add key(id); +explain +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 +1 PRIMARY t1 ref id id 4 test.t2.i1 2 Using index +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +1 +1 +1 +1 +drop table t1,t2; +# +# MDEV-15454: Nested SELECT IN returns wrong results +# +CREATE TABLE t1 ( a int NOT NULL PRIMARY KEY); +CREATE TABLE t2 ( a int, b int ); +INSERT INTO t2 VALUES (7878, 96),(3465, 96),(1403, 96),(4189, 96),(8732, 96), (5,96); +CREATE TABLE t3 (c int unsigned NOT NULL, b int unsigned NOT NULL, PRIMARY KEY (c,b)); +INSERT INTO t3 (c, b) VALUES (27, 96); +CREATE PROCEDURE prepare_data() +BEGIN +DECLARE i INT DEFAULT 1; +WHILE i < 1000 DO +INSERT INTO t1 (a) VALUES (i); +INSERT INTO t2 (a,b) VALUES (i,56); +INSERT INTO t3 (c,b) VALUES (i,i); +SET i = i + 1; +END WHILE; +END$$ +CALL prepare_data(); +SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27); +a +7878 +3465 +1403 +4189 +8732 +5 +set @save_optimizer_switch= @@optimizer_switch; +SET optimizer_switch='materialization=off'; +SELECT t1.a FROM t1 +WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27)) LIMIT 5; +a +5 +SET optimizer_switch='materialization=on'; +SELECT t1.a FROM t1 +WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27)) LIMIT 5; +a +5 +drop procedure prepare_data; +set @@optimizer_switch= @save_optimizer_switch; +drop table t1,t2,t3; +CREATE TABLE t1 ( id int NOT NULL, key(id)); +INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19); +CREATE TABLE t2 (i1 int NOT NULL, i2 int NOT NULL); +INSERT INTO t2 VALUES (11,11),(12,12),(13,13); +CREATE VIEW v1 AS SELECT t2.i1 FROM t2 where t2.i1 = t2.i2; +explain SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 +1 PRIMARY t1 ref id id 4 test.t2.i1 2 Using index +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); +1 +1 +1 +1 +drop table t1,t2; +drop view v1; # End of 5.5 tests # # MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT diff --git a/mysql-test/main/subselect_sj_mat.test b/mysql-test/main/subselect_sj_mat.test index bfd3b28a5b2..7853b528e8f 100644 --- a/mysql-test/main/subselect_sj_mat.test +++ b/mysql-test/main/subselect_sj_mat.test @@ -2157,6 +2157,85 @@ eval $q; DROP TABLE t1,t2,t3; set optimizer_switch=@save_optimizer_switch; +--echo # +--echo # MDEV-16751: Server crashes in st_join_table::cleanup or +--echo # TABLE_LIST::is_with_table_recursive_reference with join_cache_level>2 +--echo # + +set @save_join_cache_level= @@join_cache_level; +set join_cache_level=4; +CREATE TABLE t1 ( id int NOT NULL); +INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19); + +CREATE TABLE t2 (i1 int NOT NULL, i2 int NOT NULL) ; +INSERT INTO t2 VALUES (11,11),(12,12),(13,13); + +explain +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); + +set @@join_cache_level= @save_join_cache_level; +alter table t1 add key(id); + +explain +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); +SELECT 1 FROM t1 where t1.id IN (SELECT t2.i1 FROM t2 WHERE t2.i1 = t2.i2); + +drop table t1,t2; + +--echo # +--echo # MDEV-15454: Nested SELECT IN returns wrong results +--echo # + +CREATE TABLE t1 ( a int NOT NULL PRIMARY KEY); + +CREATE TABLE t2 ( a int, b int ); +INSERT INTO t2 VALUES (7878, 96),(3465, 96),(1403, 96),(4189, 96),(8732, 96), (5,96); + +CREATE TABLE t3 (c int unsigned NOT NULL, b int unsigned NOT NULL, PRIMARY KEY (c,b)); +INSERT INTO t3 (c, b) VALUES (27, 96); + +DELIMITER $$; +CREATE PROCEDURE prepare_data() +BEGIN + DECLARE i INT DEFAULT 1; + WHILE i < 1000 DO + INSERT INTO t1 (a) VALUES (i); + INSERT INTO t2 (a,b) VALUES (i,56); + INSERT INTO t3 (c,b) VALUES (i,i); + SET i = i + 1; + END WHILE; +END$$ +DELIMITER ;$$ + +CALL prepare_data(); + +SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27); + +set @save_optimizer_switch= @@optimizer_switch; +SET optimizer_switch='materialization=off'; + +SELECT t1.a FROM t1 +WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27)) LIMIT 5; + +SET optimizer_switch='materialization=on'; + +SELECT t1.a FROM t1 +WHERE t1.a IN (SELECT t2.a FROM t2 WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.c= 27)) LIMIT 5; + +drop procedure prepare_data; +set @@optimizer_switch= @save_optimizer_switch; +drop table t1,t2,t3; + +CREATE TABLE t1 ( id int NOT NULL, key(id)); +INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19); +CREATE TABLE t2 (i1 int NOT NULL, i2 int NOT NULL); +INSERT INTO t2 VALUES (11,11),(12,12),(13,13); +CREATE VIEW v1 AS SELECT t2.i1 FROM t2 where t2.i1 = t2.i2; +explain SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); +SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1); +drop table t1,t2; +drop view v1; --echo # End of 5.5 tests --echo # --echo # MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT diff --git a/mysql-test/main/union.result b/mysql-test/main/union.result index 39cd68ae851..a41148f2600 100644 --- a/mysql-test/main/union.result +++ b/mysql-test/main/union.result @@ -2134,6 +2134,22 @@ DROP VIEW v1; UNION (SELECT 2, 2); ERROR 42S02: Table 'test.v1' doesn't exist +# +# Bug#27197235 USER VARIABLE + UINON + DECIMAL COLUMN RETURNS +# WRONG VALUES +# +SET NAMES utf8; +SET @advertAcctId = 1000003; +select @advertAcctId as a from dual union all select 1.0 from dual; +a +1000003.0 +1.0 +SET NAMES latin1; +SET @advertAcctId = 1000003; +select @advertAcctId as a from dual union all select 1.0 from dual; +a +1000003.0 +1.0 End of 5.5 tests # # WL#1763 Avoid creating temporary table in UNION ALL diff --git a/mysql-test/main/union.test b/mysql-test/main/union.test index b9b38271f83..878d7118ef5 100644 --- a/mysql-test/main/union.test +++ b/mysql-test/main/union.test @@ -1470,6 +1470,21 @@ DROP VIEW v1; UNION (SELECT 2, 2); +--echo # +--echo # Bug#27197235 USER VARIABLE + UINON + DECIMAL COLUMN RETURNS +--echo # WRONG VALUES +--echo # + +let $old_charset= `SELECT @@character_set_client`; + +SET NAMES utf8; +SET @advertAcctId = 1000003; +select @advertAcctId as a from dual union all select 1.0 from dual; + +eval SET NAMES $old_charset; +SET @advertAcctId = 1000003; +select @advertAcctId as a from dual union all select 1.0 from dual; + --echo End of 5.5 tests --echo # diff --git a/mysql-test/suite/binlog/include/check_binlog_size.inc b/mysql-test/suite/binlog/include/check_binlog_size.inc new file mode 100644 index 00000000000..9df161ec843 --- /dev/null +++ b/mysql-test/suite/binlog/include/check_binlog_size.inc @@ -0,0 +1,31 @@ +# This file runs the query and checks +# whether the size of binlog is increased or not +# If size is changed it issue die command +# Parameters +# $sql_query = query to run + +#Only last row of show binlog events matter +--let $tmp= 0 +--let $counter= 1 +while ($tmp != "No such row") +{ + --let $initial_binlog_size= $tmp + --let $tmp= query_get_value(show binary logs, File_size, $counter) + --inc $counter +} + +--eval $sql_query + +--let $tmp= 0 +--let $counter= 1 +while ($tmp != "No such row") +{ + --let $current_binlog_size= $tmp + --let $tmp= query_get_value(show binary logs, File_size, $counter) + --inc $counter +} + +if ($initial_binlog_size != $current_binlog_size) +{ + die "Binlog size changed"; +} diff --git a/mysql-test/suite/binlog/r/binlog_tmp_table_row.result b/mysql-test/suite/binlog/r/binlog_tmp_table_row.result new file mode 100644 index 00000000000..71bd75d89cb --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_tmp_table_row.result @@ -0,0 +1,7 @@ +RESET MASTER; +#Create table test +create temporary table t1(a int, b int); +#Add index test +create index index_a on t1(a); +#drop index test +drop index index_a on t1; diff --git a/mysql-test/suite/binlog/t/binlog_tmp_table_row.test b/mysql-test/suite/binlog/t/binlog_tmp_table_row.test new file mode 100644 index 00000000000..ce11c880679 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_tmp_table_row.test @@ -0,0 +1,30 @@ +# ==== Purpose ==== +# +# Test if statements used temporary tables are not binlogged in the case of +# binlog_format=row +# +# ==== Method ==== +# +# We will see if binlog file size is increased or not, It should be constant for the +# entire period of test. +# +# ==== Related bugs ==== +# +# Mdev-9266 +# +source include/have_log_bin.inc; +source include/have_binlog_format_row.inc; + +RESET MASTER; + +--echo #Create table test +--let $sql_query= create temporary table t1(a int, b int) +--source suite/binlog/include/check_binlog_size.inc + +--echo #Add index test +--let $sql_query= create index index_a on t1(a) +--source suite/binlog/include/check_binlog_size.inc + +--echo #drop index test +--let $sql_query= drop index index_a on t1 +--source suite/binlog/include/check_binlog_size.inc diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql.result b/mysql-test/suite/funcs_1/r/is_columns_mysql.result index 5d4e8fdf19d..f5452e0c8e8 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result @@ -125,13 +125,13 @@ def mysql innodb_index_stats sample_size 7 NULL YES bigint NULL NULL 20 0 NULL N def mysql innodb_index_stats stat_description 8 NULL NO varchar 1024 3072 NULL NULL NULL utf8 utf8_bin varchar(1024) select,insert,update,references NEVER NULL def mysql innodb_index_stats stat_name 5 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8_bin varchar(64) PRI select,insert,update,references NEVER NULL def mysql innodb_index_stats stat_value 6 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select,insert,update,references NEVER NULL -def mysql innodb_index_stats table_name 2 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8_bin varchar(64) PRI select,insert,update,references NEVER NULL +def mysql innodb_index_stats table_name 2 NULL NO varchar 199 597 NULL NULL NULL utf8 utf8_bin varchar(199) PRI select,insert,update,references NEVER NULL def mysql innodb_table_stats clustered_index_size 5 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select,insert,update,references NEVER NULL def mysql innodb_table_stats database_name 1 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8_bin varchar(64) PRI select,insert,update,references NEVER NULL def mysql innodb_table_stats last_update 3 current_timestamp() NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update current_timestamp() select,insert,update,references NEVER NULL def mysql innodb_table_stats n_rows 4 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select,insert,update,references NEVER NULL def mysql innodb_table_stats sum_of_other_index_sizes 6 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select,insert,update,references NEVER NULL -def mysql innodb_table_stats table_name 2 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8_bin varchar(64) PRI select,insert,update,references NEVER NULL +def mysql innodb_table_stats table_name 2 NULL NO varchar 199 597 NULL NULL NULL utf8 utf8_bin varchar(199) PRI select,insert,update,references NEVER NULL def mysql plugin dl 2 '' NO varchar 128 384 NULL NULL NULL utf8 utf8_general_ci varchar(128) select,insert,update,references NEVER NULL def mysql plugin name 1 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) PRI select,insert,update,references NEVER NULL def mysql proc aggregate 21 'NONE' NO enum 5 15 NULL NULL NULL utf8 utf8_general_ci enum('NONE','GROUP') select,insert,update,references NEVER NULL @@ -462,7 +462,7 @@ NULL mysql help_topic help_category_id smallint NULL NULL NULL NULL smallint(5) NULL mysql index_stats prefix_arity int NULL NULL NULL NULL int(11) unsigned NULL mysql index_stats avg_frequency decimal NULL NULL NULL NULL decimal(12,4) 3.0000 mysql innodb_index_stats database_name varchar 64 192 utf8 utf8_bin varchar(64) -3.0000 mysql innodb_index_stats table_name varchar 64 192 utf8 utf8_bin varchar(64) +3.0000 mysql innodb_index_stats table_name varchar 199 597 utf8 utf8_bin varchar(199) 3.0000 mysql innodb_index_stats index_name varchar 64 192 utf8 utf8_bin varchar(64) NULL mysql innodb_index_stats last_update timestamp NULL NULL NULL NULL timestamp 3.0000 mysql innodb_index_stats stat_name varchar 64 192 utf8 utf8_bin varchar(64) @@ -470,7 +470,7 @@ NULL mysql innodb_index_stats stat_value bigint NULL NULL NULL NULL bigint(20) u NULL mysql innodb_index_stats sample_size bigint NULL NULL NULL NULL bigint(20) unsigned 3.0000 mysql innodb_index_stats stat_description varchar 1024 3072 utf8 utf8_bin varchar(1024) 3.0000 mysql innodb_table_stats database_name varchar 64 192 utf8 utf8_bin varchar(64) -3.0000 mysql innodb_table_stats table_name varchar 64 192 utf8 utf8_bin varchar(64) +3.0000 mysql innodb_table_stats table_name varchar 199 597 utf8 utf8_bin varchar(199) NULL mysql innodb_table_stats last_update timestamp NULL NULL NULL NULL timestamp NULL mysql innodb_table_stats n_rows bigint NULL NULL NULL NULL bigint(20) unsigned NULL mysql innodb_table_stats clustered_index_size bigint NULL NULL NULL NULL bigint(20) unsigned diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 322eff3506f..c3b5e070158 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -36,3 +36,4 @@ galera_kill_applier : race condition at the start of the test galera_ist_progress: MDEV-15236 galera_ist_progress fails when trying to read transfer status galera_concurrent_ctas : MDEV-15845 Test failure on galera.galera_concurrent_ctas pxc-421: Lock timeout exceeded +galera_sst_mysqldump_with_key : MDEV-16890 Galera test failure diff --git a/mysql-test/suite/galera/r/galera_bf_background_statistics.result b/mysql-test/suite/galera/r/galera_bf_background_statistics.result new file mode 100644 index 00000000000..c2c3fce2b14 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_bf_background_statistics.result @@ -0,0 +1,33 @@ +SELECT @@innodb_stats_persistent; +@@innodb_stats_persistent +1 +CREATE TABLE t1 (f1 INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, f2 INTEGER DEFAULT 1) ENGINE=InnoDB; +INSERT INTO t1(f1) values (NULL); +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +SELECT count(1) from t1; +count(1) +16384 +connection node_2; +SET AUTOCOMMIT=OFF; +INSERT INTO t1 VALUES (9999999,NULL); +SELECT SLEEP(1000);; +connection node_1; +ALTER TABLE t1 CHANGE f2 f2 INTEGER NOT NULL DEFAULT 1; +connection node_2; +ERROR 40001: Deadlock: wsrep aborted transaction +wsrep_local_aborts_increment +1 +DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_sst_mysqldump_with_key.result b/mysql-test/suite/galera/r/galera_sst_mysqldump_with_key.result index 93ab4a3f3d4..02dde169911 100644 --- a/mysql-test/suite/galera/r/galera_sst_mysqldump_with_key.result +++ b/mysql-test/suite/galera/r/galera_sst_mysqldump_with_key.result @@ -14,7 +14,7 @@ CREATE USER sslsst; GRANT ALL PRIVILEGES ON *.* TO sslsst; GRANT USAGE ON *.* TO sslsst REQUIRE SSL; SET GLOBAL wsrep_sst_auth = 'sslsst:'; -Performing State Transfer on a server that has been temporarily disconnected +Performing State Transfer on a server that has been shut down cleanly and restarted connection node_1; CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; SET AUTOCOMMIT=OFF; @@ -34,8 +34,7 @@ INSERT INTO t1 VALUES ('node2_committed_before'); INSERT INTO t1 VALUES ('node2_committed_before'); INSERT INTO t1 VALUES ('node2_committed_before'); COMMIT; -Unloading wsrep provider ... -SET GLOBAL wsrep_provider = 'none'; +Shutting down server ... connection node_1; SET AUTOCOMMIT=OFF; START TRANSACTION; @@ -51,7 +50,7 @@ INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); INSERT INTO t1 VALUES ('node1_to_be_committed_after'); -connect node_1a_galera_st_disconnect_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connect node_1a_galera_st_shutdown_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); @@ -60,7 +59,7 @@ INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); connection node_2; -Loading wsrep provider ... +Starting server ... SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES ('node2_committed_after'); @@ -84,7 +83,7 @@ INSERT INTO t1 VALUES ('node1_committed_after'); INSERT INTO t1 VALUES ('node1_committed_after'); INSERT INTO t1 VALUES ('node1_committed_after'); COMMIT; -connection node_1a_galera_st_disconnect_slave; +connection node_1a_galera_st_shutdown_slave; INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); @@ -109,6 +108,210 @@ COUNT(*) = 0 DROP TABLE t1; COMMIT; SET AUTOCOMMIT=ON; +Performing State Transfer on a server that has been killed and restarted +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +Killing server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_kill_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Performing --wsrep-recover ... +Starting server ... +Using --wsrep-start-position when starting mysqld ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_kill_slave; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +Performing State Transfer on a server that has been killed and restarted +while a DDL was in progress on it +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +connection node_2; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +SET GLOBAL debug_dbug = 'd,sync.alter_opened_table'; +connection node_1; +ALTER TABLE t1 ADD COLUMN f2 INTEGER; +connection node_2; +SET wsrep_sync_wait = 0; +Killing server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_kill_slave_ddl, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Performing --wsrep-recover ... +connection node_2; +Starting server ... +Using --wsrep-start-position when starting mysqld ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_kill_slave_ddl; +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +COUNT(*) = 2 +1 +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +COUNT(*) = 2 +1 +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +SET GLOBAL debug_dbug = $debug_orig; connection node_1; CALL mtr.add_suppression("Slave SQL: Error 'The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement' on query"); DROP USER sst; diff --git a/mysql-test/suite/galera/t/galera_bf_background_statistics.opt b/mysql-test/suite/galera/t/galera_bf_background_statistics.opt new file mode 100644 index 00000000000..f9b1414a974 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_bf_background_statistics.opt @@ -0,0 +1 @@ +--innodb_stats_persistent=ON diff --git a/mysql-test/suite/galera/t/galera_bf_background_statistics.test b/mysql-test/suite/galera/t/galera_bf_background_statistics.test new file mode 100644 index 00000000000..a9a98b1b567 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_bf_background_statistics.test @@ -0,0 +1,49 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc + +# +# Test a local transaction being aborted by a slave one while it is running a SLEEP() +# + +SELECT @@innodb_stats_persistent; + +CREATE TABLE t1 (f1 INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, f2 INTEGER DEFAULT 1) ENGINE=InnoDB; +INSERT INTO t1(f1) values (NULL); +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +INSERT INTO t1(f1) select NULL from t1; +SELECT count(1) from t1; + +--connection node_2 +SET AUTOCOMMIT=OFF; +--let $wsrep_local_bf_aborts_before = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'` +INSERT INTO t1 VALUES (9999999,NULL); +--send SELECT SLEEP(1000); + +--connection node_1 +ALTER TABLE t1 CHANGE f2 f2 INTEGER NOT NULL DEFAULT 1; + +--connection node_2 +--error ER_LOCK_DEADLOCK +--reap + +--let $wsrep_local_bf_aborts_after = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'` + +# Check that wsrep_local_bf_aborts has been incremented by exactly 1 +--disable_query_log +--eval SELECT $wsrep_local_bf_aborts_after - $wsrep_local_bf_aborts_before = 1 AS wsrep_local_aborts_increment; +--enable_query_log + +DROP TABLE t1; + diff --git a/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.test b/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.test index 0dbc63b531c..57244cb50c7 100644 --- a/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.test +++ b/mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.test @@ -19,7 +19,12 @@ GRANT USAGE ON *.* TO sslsst REQUIRE SSL; SET GLOBAL wsrep_sst_auth = 'sslsst:'; ---source suite/galera/include/galera_st_disconnect_slave.inc +# We set the required mysqldump SST options here so that they are used every time the server is restarted during the test +--let $start_mysqld_params = --wsrep_sst_auth=sst:'sslsst:' --wsrep_sst_method=mysqldump --wsrep-sst-receive-address=127.0.0.1:$NODE_MYPORT_2 --skip-grant-tables + +--source suite/galera/include/galera_st_shutdown_slave.inc +--source suite/galera/include/galera_st_kill_slave.inc +--source suite/galera/include/galera_st_kill_slave_ddl.inc --source include/auto_increment_offset_restore.inc --source suite/galera/include/galera_sst_restore.inc diff --git a/mysql-test/suite/innodb/r/default_row_format_compatibility.result b/mysql-test/suite/innodb/r/default_row_format_compatibility.result index 765e25c776e..5070fa33a2e 100644 --- a/mysql-test/suite/innodb/r/default_row_format_compatibility.result +++ b/mysql-test/suite/innodb/r/default_row_format_compatibility.result @@ -25,7 +25,7 @@ SET GLOBAL innodb_default_row_format=Dynamic; CREATE TABLE tab(a INT) ENGINE=InnoDB; ALTER TABLE tab DISCARD TABLESPACE; ALTER TABLE tab IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x1) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x1; .cfg file uses ROW_FORMAT=COMPACT) DROP TABLE tab; SET GLOBAL innodb_default_row_format=Compact; SELECT @@innodb_default_row_format; diff --git a/mysql-test/suite/innodb/r/innodb-wl5522.result b/mysql-test/suite/innodb/r/innodb-wl5522.result index 1ed857af473..62f03292baa 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522.result @@ -115,7 +115,7 @@ ALTER TABLE t2 DISCARD TABLESPACE; db.opt t2.frm ALTER TABLE t2 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x1) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x1; .cfg file uses ROW_FORMAT=COMPACT) ALTER TABLE t2 IMPORT TABLESPACE; ERROR HY000: Schema mismatch (Expected FSP_SPACE_FLAGS=0x*, .ibd file contains 0x*.) DROP TABLE t2; @@ -603,7 +603,7 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x1 and the meta-data file has 0x0) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x1 and the meta-data file has 0x0; .cfg file uses ROW_FORMAT=REDUNDANT) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -615,7 +615,19 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x0) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x0; .cfg file uses ROW_FORMAT=REDUNDANT) +unlink: t1.ibd +unlink: t1.cfg +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table `t1` +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x29 and the meta-data file has 0x0; .cfg file uses ROW_FORMAT=REDUNDANT) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -789,7 +801,7 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x0 and the meta-data file has 0x1) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x0 and the meta-data file has 0x1; .cfg file uses ROW_FORMAT=COMPACT) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -801,7 +813,19 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x1) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x1; .cfg file uses ROW_FORMAT=COMPACT) +unlink: t1.ibd +unlink: t1.cfg +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table `t1` +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x29 and the meta-data file has 0x1; .cfg file uses ROW_FORMAT=COMPACT) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -978,7 +1002,7 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x1 and the meta-data file has 0x21) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x1 and the meta-data file has 0x21; .cfg file uses ROW_FORMAT=DYNAMIC) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -990,7 +1014,19 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x0 and the meta-data file has 0x21) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x0 and the meta-data file has 0x21; .cfg file uses ROW_FORMAT=DYNAMIC) +unlink: t1.ibd +unlink: t1.cfg +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table `t1` +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x29 and the meta-data file has 0x21; .cfg file uses ROW_FORMAT=DYNAMIC) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -1049,6 +1085,220 @@ c1 c2 42 1 43 1 DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +INSERT INTO t1(c2) VALUES(1); +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` int(11) DEFAULT NULL, + PRIMARY KEY (`c1`), + KEY `idx` (`c2`) +) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED +SELECT * FROM t1; +c1 c2 +1 1 +2 1 +3 1 +4 1 +6 1 +7 1 +8 1 +9 1 +13 1 +14 1 +15 1 +16 1 +17 1 +18 1 +19 1 +20 1 +28 1 +29 1 +30 1 +31 1 +32 1 +33 1 +34 1 +35 1 +36 1 +37 1 +38 1 +39 1 +40 1 +41 1 +42 1 +43 1 +FLUSH TABLES t1 FOR EXPORT; +backup: t1 +UNLOCK TABLES; +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table `t1` +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +unlink: t1.cfg +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` int(11) DEFAULT NULL, + PRIMARY KEY (`c1`), + KEY `idx` (`c2`) +) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED +SELECT * FROM t1; +c1 c2 +1 1 +2 1 +3 1 +4 1 +6 1 +7 1 +8 1 +9 1 +13 1 +14 1 +15 1 +16 1 +17 1 +18 1 +19 1 +20 1 +28 1 +29 1 +30 1 +31 1 +32 1 +33 1 +34 1 +35 1 +36 1 +37 1 +38 1 +39 1 +40 1 +41 1 +42 1 +43 1 +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table `t1` +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x0 and the meta-data file has 0x29; .cfg file uses ROW_FORMAT=COMPRESSED) +unlink: t1.ibd +unlink: t1.cfg +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPACT; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table `t1` +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x1 and the meta-data file has 0x29; .cfg file uses ROW_FORMAT=COMPRESSED) +unlink: t1.ibd +unlink: t1.cfg +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table `t1` +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x29; .cfg file uses ROW_FORMAT=COMPRESSED) +unlink: t1.ibd +unlink: t1.cfg +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB +ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table `t1` +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x23 and the meta-data file has 0x29; .cfg file uses ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8) +unlink: t1.ibd +unlink: t1.cfg +DROP TABLE t1; +CREATE TABLE t1( +c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DISCARD TABLESPACE; +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table `t1` +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +unlink: t1.cfg +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` int(11) DEFAULT NULL, + PRIMARY KEY (`c1`), + KEY `idx` (`c2`) +) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED +SELECT * FROM t1; +c1 c2 +1 1 +2 1 +3 1 +4 1 +6 1 +7 1 +8 1 +9 1 +13 1 +14 1 +15 1 +16 1 +17 1 +18 1 +19 1 +20 1 +28 1 +29 1 +30 1 +31 1 +32 1 +33 1 +34 1 +35 1 +36 1 +37 1 +38 1 +39 1 +40 1 +41 1 +42 1 +43 1 +DROP TABLE t1; call mtr.add_suppression("Got error -1 when reading table '.*'"); call mtr.add_suppression("InnoDB: Error: tablespace id and flags in file '.*'.*"); call mtr.add_suppression("InnoDB: The table .* doesn't have a corresponding tablespace, it was discarded"); diff --git a/mysql-test/suite/innodb/r/row_format_redundant.result b/mysql-test/suite/innodb/r/row_format_redundant.result index 63172897927..8852bfd8e6a 100644 --- a/mysql-test/suite/innodb/r/row_format_redundant.result +++ b/mysql-test/suite/innodb/r/row_format_redundant.result @@ -72,7 +72,7 @@ DROP TABLE t1; Warnings: Warning 1932 Table 'test.t1' doesn't exist in engine DROP TABLE t2,t3; -FOUND 49 /\[ERROR\] InnoDB: Table `test`\.`t1` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=511\b/ in mysqld.1.err +FOUND 50 /\[ERROR\] InnoDB: Table `test`\.`t1` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=511\b/ in mysqld.1.err ib_buffer_pool ib_logfile0 ib_logfile1 diff --git a/mysql-test/suite/innodb/t/innodb-wl5522.test b/mysql-test/suite/innodb/t/innodb-wl5522.test index 66dfaac0996..24dad21b3af 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5522.test +++ b/mysql-test/suite/innodb/t/innodb-wl5522.test @@ -485,7 +485,7 @@ SELECT * FROM t1; DROP TABLE t1; # -# Row format tests [EXPORT REDUNDANT - IMPORT COMPACT & DYNAMIC] +# EXPORT ROW_FORMAT=REDUNDANT # CREATE TABLE t1( c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -587,6 +587,29 @@ EOF DROP TABLE t1; +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + # This should be OK. CREATE TABLE t1( c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -615,7 +638,7 @@ SELECT * FROM t1; DROP TABLE t1; # -# Row format tests [EXPORT COMPACT - IMPORT REDUNDANT & DYNAMIC] +# EXPORT ROW_FORMAT=COMPACT # CREATE TABLE t1( c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -717,6 +740,29 @@ EOF DROP TABLE t1; +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + # This should be OK. CREATE TABLE t1( c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -746,7 +792,7 @@ SELECT * FROM t1; DROP TABLE t1; # -# Row format tests [EXPORT DYNAMIC- IMPORT REDUNDANT & DYNAMIC] +# EXPORT ROW_FORMAT=DYNAMIC # CREATE TABLE t1( c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -848,6 +894,29 @@ EOF DROP TABLE t1; +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + # This should be OK. CREATE TABLE t1( c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -876,6 +945,185 @@ SELECT * FROM t1; DROP TABLE t1; +# +# EXPORT ROW_FORMAT=COMPRESSED +# +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; + +INSERT INTO t1(c2) VALUES(1); +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; +INSERT INTO t1(c2) SELECT c2 FROM t1; + +SHOW CREATE TABLE t1; +SELECT * FROM t1; + +FLUSH TABLES t1 FOR EXPORT; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_backup_tablespaces("test", "t1"); +EOF + +UNLOCK TABLES; + +DROP TABLE t1; + +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +ALTER TABLE t1 IMPORT TABLESPACE; +CHECK TABLE t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_cleanup("test", "t1"); +EOF + +SHOW CREATE TABLE t1; +SELECT * FROM t1; + +DROP TABLE t1; + +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPACT; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + + +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB + ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_unlink_tablespace("test", "t1"); +EOF + +DROP TABLE t1; + +# This should be OK. +CREATE TABLE t1( + c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + c2 INT, INDEX idx(c2)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; + +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +ALTER TABLE t1 IMPORT TABLESPACE; +CHECK TABLE t1; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_cleanup("test", "t1"); +EOF + +SHOW CREATE TABLE t1; +SELECT * FROM t1; + +DROP TABLE t1; + call mtr.add_suppression("Got error -1 when reading table '.*'"); call mtr.add_suppression("InnoDB: Error: tablespace id and flags in file '.*'.*"); call mtr.add_suppression("InnoDB: The table .* doesn't have a corresponding tablespace, it was discarded"); diff --git a/mysql-test/suite/innodb_fts/r/fts_kill_query.result b/mysql-test/suite/innodb_fts/r/fts_kill_query.result new file mode 100644 index 00000000000..53ad9b3a37c --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/fts_kill_query.result @@ -0,0 +1,9 @@ +CREATE TABLE t1 (a VARCHAR(7), b text, FULLTEXT KEY idx (a,b)) ENGINE=InnoDB; +COMMIT; +SELECT COUNT(*) FROM t1 +WHERE MATCH (a,b) AGAINST ('foo bar' IN BOOLEAN MODE); +connect con1,localhost,root,,; +KILL QUERY @id; +disconnect con1; +connection default; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/r/sync_ddl.result b/mysql-test/suite/innodb_fts/r/sync_ddl.result new file mode 100644 index 00000000000..441954dc77b --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/sync_ddl.result @@ -0,0 +1,105 @@ +CREATE TABLE t1 ( +id INT AUTO_INCREMENT NOT NULL PRIMARY KEY, +value VARCHAR(1024) +) ENGINE=InnoDB; +CREATE FULLTEXT INDEX idx1 ON t1(value); +SET @save_debug = @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_sync_before_syncing,ib_trunc_sleep_before_fts_cache_clear'; +INSERT INTO t1 (value) VALUES +('By default or with the IN NATURAL LANGUAGE MODE modifier') +; +TRUNCATE TABLE t1; +DROP TABLE t1; +SET GLOBAL debug_dbug = @save_debug; +CREATE TABLE t1 ( +id INT AUTO_INCREMENT NOT NULL PRIMARY KEY, +value VARCHAR(1024) +) ENGINE=InnoDB; +CREATE FULLTEXT INDEX idx1 ON t1(value); +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_write_words_before_select_index,ib_trunc_sleep_before_fts_cache_clear'; +INSERT INTO t1 (value) VALUES +('By default or with the IN NATURAL LANGUAGE MODE modifier'), +('performs a natural language search for a string'), +('collection is a set of one or more columns included'), +('returns a relevance value; that is, a similarity measure'), +('and the text in that row in the columns named in'), +('By default, the search is performed in case-insensitive'), +('sensitive full-text search, use a binary collation '), +('example, a column that uses the latin1 character'), +('collation of latin1_bin to make it case sensitive') +; +TRUNCATE TABLE t1; +DROP TABLE t1; +SET GLOBAL debug_dbug = @save_debug; +CREATE TABLE t1 ( +value VARCHAR(1024) +) ENGINE=InnoDB; +CREATE FULLTEXT INDEX idx1 ON t1(value); +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep'; +INSERT INTO t1 (value) VALUES +('By default or with the IN NATURAL LANGUAGE MODE modifier'), +('performs a natural language search for a string'), +('collection is a set of one or more columns included'), +('returns a relevance value; that is, a similarity measure'), +('and the text in that row in the columns named in'), +('By default, the search is performed in case-insensitive'), +('sensitive full-text search, use a binary collation '), +('example, a column that uses the latin1 character'), +('collation of latin1_bin to make it case sensitive') +; +DROP INDEX idx1 ON t1; +DROP TABLE t1; +SET GLOBAL debug_dbug = @save_debug; +CREATE TABLE t1 ( +value VARCHAR(1024) +) ENGINE=InnoDB; +CREATE FULLTEXT INDEX idx1 ON t1(value); +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep'; +INSERT INTO t1 (value) VALUES +('By default or with the IN NATURAL LANGUAGE MODE modifier'), +('performs a natural language search for a string'), +('collection is a set of one or more columns included'), +('returns a relevance value; that is, a similarity measure'), +('and the text in that row in the columns named in'), +('By default, the search is performed in case-insensitive'), +('sensitive full-text search, use a binary collation '), +('example, a column that uses the latin1 character'), +('collation of latin1_bin to make it case sensitive') +; +ALTER TABLE t1 +DROP INDEX idx1, +ALGORITHM=INPLACE; +DROP TABLE t1; +SET GLOBAL debug_dbug = @save_debug; +CREATE TABLE t1 ( +value VARCHAR(1024) +) ENGINE=InnoDB; +CREATE FULLTEXT INDEX idx1 ON t1(value); +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep'; +INSERT INTO t1 (value) VALUES +('example, a column that uses the latin1 character'), +('collation of latin1_bin to make it case sensitive') +; +ALTER TABLE t1 +DROP INDEX idx1, +ALGORITHM=COPY; +DROP TABLE t1; +SET GLOBAL debug_dbug = @save_debug; +CREATE TABLE t1 ( +id1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +value VARCHAR(1024) +) ENGINE=InnoDB; +CREATE FULLTEXT INDEX idx1 ON t1(value); +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep'; +INSERT INTO t1 (value) VALUES +('example, a column that uses the latin1 character'), +('collation of latin1_bin to make it case sensitive') +; +ALTER TABLE t1 +DROP COLUMN id1, +ADD COLUMN id2 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +DROP INDEX idx1, +ADD FULLTEXT INDEX idx2(value), +ALGORITHM=INPLACE; +DROP TABLE t1; +SET GLOBAL debug_dbug = @save_debug; diff --git a/mysql-test/suite/innodb_fts/t/fts_kill_query.test b/mysql-test/suite/innodb_fts/t/fts_kill_query.test new file mode 100644 index 00000000000..3dda29a3876 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/fts_kill_query.test @@ -0,0 +1,30 @@ +--source include/have_innodb.inc + +CREATE TABLE t1 (a VARCHAR(7), b text, FULLTEXT KEY idx (a,b)) ENGINE=InnoDB; + +--disable_query_log +BEGIN; +let $n=1000; +while ($n) { +INSERT INTO t1 VALUES('foo bar','boo far'); +dec $n; +} +--enable_query_log +COMMIT; + +let $id = `SELECT CONNECTION_ID()`; +send SELECT COUNT(*) FROM t1 +WHERE MATCH (a,b) AGAINST ('foo bar' IN BOOLEAN MODE); + +connect (con1,localhost,root,,); +let $ignore= `SELECT @id := $ID`; +KILL QUERY @id; +disconnect con1; + +connection default; +# The following would return a result set if the KILL was not fast enough. +--disable_result_log +--error 0,ER_QUERY_INTERRUPTED,HA_ERR_ABORTED_BY_USER +reap; +--enable_result_log +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/t/sync_ddl.test b/mysql-test/suite/innodb_fts/t/sync_ddl.test new file mode 100644 index 00000000000..2950297d5bb --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/sync_ddl.test @@ -0,0 +1,177 @@ +# +# BUG#27082268 FTS synchronization issues +# + +--source include/have_innodb.inc +--source include/have_debug.inc + +#-------------------------------------- +# Check FTS_sync vs TRUNCATE (1) +#-------------------------------------- + +CREATE TABLE t1 ( + id INT AUTO_INCREMENT NOT NULL PRIMARY KEY, + value VARCHAR(1024) + ) ENGINE=InnoDB; + +CREATE FULLTEXT INDEX idx1 ON t1(value); + +SET @save_debug = @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_sync_before_syncing,ib_trunc_sleep_before_fts_cache_clear'; + +INSERT INTO t1 (value) VALUES + ('By default or with the IN NATURAL LANGUAGE MODE modifier') + ; + +TRUNCATE TABLE t1; + +DROP TABLE t1; + +SET GLOBAL debug_dbug = @save_debug; + +#-------------------------------------- +# Check FTS sync vs DROP INDEX (2) +#-------------------------------------- + +CREATE TABLE t1 ( + id INT AUTO_INCREMENT NOT NULL PRIMARY KEY, + value VARCHAR(1024) + ) ENGINE=InnoDB; + +CREATE FULLTEXT INDEX idx1 ON t1(value); + +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_write_words_before_select_index,ib_trunc_sleep_before_fts_cache_clear'; + +INSERT INTO t1 (value) VALUES + ('By default or with the IN NATURAL LANGUAGE MODE modifier'), + ('performs a natural language search for a string'), + ('collection is a set of one or more columns included'), + ('returns a relevance value; that is, a similarity measure'), + ('and the text in that row in the columns named in'), + ('By default, the search is performed in case-insensitive'), + ('sensitive full-text search, use a binary collation '), + ('example, a column that uses the latin1 character'), + ('collation of latin1_bin to make it case sensitive') + ; + +TRUNCATE TABLE t1; + +DROP TABLE t1; + +SET GLOBAL debug_dbug = @save_debug; + +#-------------------------------------- +# Check FTS sync vs DROP INDEX +#-------------------------------------- + +CREATE TABLE t1 ( + value VARCHAR(1024) + ) ENGINE=InnoDB; + +CREATE FULLTEXT INDEX idx1 ON t1(value); + +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep'; + +INSERT INTO t1 (value) VALUES + ('By default or with the IN NATURAL LANGUAGE MODE modifier'), + ('performs a natural language search for a string'), + ('collection is a set of one or more columns included'), + ('returns a relevance value; that is, a similarity measure'), + ('and the text in that row in the columns named in'), + ('By default, the search is performed in case-insensitive'), + ('sensitive full-text search, use a binary collation '), + ('example, a column that uses the latin1 character'), + ('collation of latin1_bin to make it case sensitive') + ; + +DROP INDEX idx1 ON t1; + +DROP TABLE t1; + +SET GLOBAL debug_dbug = @save_debug; + +#-------------------------------------- +# Check FTS sync vs ALTER TABLE DROP INDEX (INPLACE) +#-------------------------------------- + +CREATE TABLE t1 ( + value VARCHAR(1024) + ) ENGINE=InnoDB; + +CREATE FULLTEXT INDEX idx1 ON t1(value); + +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep'; + +INSERT INTO t1 (value) VALUES + ('By default or with the IN NATURAL LANGUAGE MODE modifier'), + ('performs a natural language search for a string'), + ('collection is a set of one or more columns included'), + ('returns a relevance value; that is, a similarity measure'), + ('and the text in that row in the columns named in'), + ('By default, the search is performed in case-insensitive'), + ('sensitive full-text search, use a binary collation '), + ('example, a column that uses the latin1 character'), + ('collation of latin1_bin to make it case sensitive') + ; + +ALTER TABLE t1 + DROP INDEX idx1, + ALGORITHM=INPLACE; + +DROP TABLE t1; + +SET GLOBAL debug_dbug = @save_debug; + +#-------------------------------------- +# Check FTS sync vs ALTER TABLE DROP INDEX (COPY) +#-------------------------------------- + +CREATE TABLE t1 ( + value VARCHAR(1024) + ) ENGINE=InnoDB; + +CREATE FULLTEXT INDEX idx1 ON t1(value); + +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep'; + +INSERT INTO t1 (value) VALUES + ('example, a column that uses the latin1 character'), + ('collation of latin1_bin to make it case sensitive') + ; + +ALTER TABLE t1 + DROP INDEX idx1, + ALGORITHM=COPY; + +DROP TABLE t1; + +SET GLOBAL debug_dbug = @save_debug; + +#-------------------------------------- +# Check FTS sync vs ALTER TABLE (INPLACE, new cluster) +#-------------------------------------- + +CREATE TABLE t1 ( + id1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + value VARCHAR(1024) + ) ENGINE=InnoDB; + +CREATE FULLTEXT INDEX idx1 ON t1(value); + +SET GLOBAL debug_dbug = '+d,fts_instrument_sync_request,fts_instrument_msg_sync_sleep'; + +INSERT INTO t1 (value) VALUES + ('example, a column that uses the latin1 character'), + ('collation of latin1_bin to make it case sensitive') + ; + +ALTER TABLE t1 + DROP COLUMN id1, + ADD COLUMN id2 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + DROP INDEX idx1, + ADD FULLTEXT INDEX idx2(value), + ALGORITHM=INPLACE; + +DROP TABLE t1; + +SET GLOBAL debug_dbug = @save_debug; diff --git a/mysql-test/suite/innodb_gis/r/create_spatial_index.result b/mysql-test/suite/innodb_gis/r/create_spatial_index.result index fe46ef2e2f8..1af03c251bf 100644 --- a/mysql-test/suite/innodb_gis/r/create_spatial_index.result +++ b/mysql-test/suite/innodb_gis/r/create_spatial_index.result @@ -1286,7 +1286,7 @@ CREATE SPATIAL INDEX idx2 ON t1(c1); DROP TABLE t1; CREATE TABLE mysql.innodb_table_stats ( database_name varchar(64) COLLATE utf8_bin NOT NULL, -table_name varchar(64) COLLATE utf8_bin NOT NULL, +table_name varchar(199) COLLATE utf8_bin NOT NULL, last_update timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, n_rows bigint(20) unsigned NOT NULL, clustered_index_size bigint(20) unsigned NOT NULL, diff --git a/mysql-test/suite/innodb_gis/t/create_spatial_index.test b/mysql-test/suite/innodb_gis/t/create_spatial_index.test index f8626b3c052..7ddece9ad86 100644 --- a/mysql-test/suite/innodb_gis/t/create_spatial_index.test +++ b/mysql-test/suite/innodb_gis/t/create_spatial_index.test @@ -1168,7 +1168,7 @@ CREATE SPATIAL INDEX idx2 ON t1(c1); DROP TABLE t1; CREATE TABLE mysql.innodb_table_stats ( database_name varchar(64) COLLATE utf8_bin NOT NULL, - table_name varchar(64) COLLATE utf8_bin NOT NULL, + table_name varchar(199) COLLATE utf8_bin NOT NULL, last_update timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, n_rows bigint(20) unsigned NOT NULL, clustered_index_size bigint(20) unsigned NOT NULL, diff --git a/mysql-test/suite/parts/r/truncate_locked.result b/mysql-test/suite/parts/r/truncate_locked.result new file mode 100644 index 00000000000..54a3722938e --- /dev/null +++ b/mysql-test/suite/parts/r/truncate_locked.result @@ -0,0 +1,7 @@ +create table t1 (i int) engine=myisam partition by hash(i) partitions 2 ; +lock table t1 write; +truncate table t1; +desc t1; +Field Type Null Key Default Extra +i int(11) YES NULL +drop table t1; diff --git a/mysql-test/suite/parts/t/truncate_locked.test b/mysql-test/suite/parts/t/truncate_locked.test new file mode 100644 index 00000000000..4ff1016fb05 --- /dev/null +++ b/mysql-test/suite/parts/t/truncate_locked.test @@ -0,0 +1,10 @@ +# +# MDEV-15551 Server hangs or assertion `strcmp(share->unique_file_name,filename) || share->last_version' fails in test_if_reopen or unexpected ER_LOCK_DEADLOCK +# +--source include/have_partition.inc +create table t1 (i int) engine=myisam partition by hash(i) partitions 2 ; +lock table t1 write; +truncate table t1; +desc t1; +drop table t1; + diff --git a/mysql-test/suite/sys_vars/r/innodb_log_optimize_ddl_basic.result b/mysql-test/suite/sys_vars/r/innodb_log_optimize_ddl_basic.result new file mode 100644 index 00000000000..993bb13ebf0 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/innodb_log_optimize_ddl_basic.result @@ -0,0 +1,39 @@ +SELECT COUNT(@@GLOBAL.innodb_log_optimize_ddl); +COUNT(@@GLOBAL.innodb_log_optimize_ddl) +1 +1 Expected +SELECT COUNT(@@SESSION.innodb_log_optimize_ddl); +ERROR HY000: Variable 'innodb_log_optimize_ddl' is a GLOBAL variable +Expected error 'Variable is a GLOBAL variable' +SELECT @@GLOBAL.innodb_log_optimize_ddl; +@@GLOBAL.innodb_log_optimize_ddl +1 +SELECT @@GLOBAL.innodb_log_optimize_ddl INTO @innodb_log_optimize_ddl_save; +SET @@GLOBAL.innodb_log_optimize_ddl = ON; +SET @@GLOBAL.innodb_log_optimize_ddl = OFF; +SET @@GLOBAL.innodb_log_optimize_ddl = 13; +ERROR 42000: Variable 'innodb_log_optimize_ddl' can't be set to the value of '13' +SET @@GLOBAL.innodb_log_optimize_ddl = 'ABC'; +ERROR 42000: Variable 'innodb_log_optimize_ddl' can't be set to the value of 'ABC' +SELECT @@GLOBAL.innodb_log_optimize_ddl = 0 +OR @@GLOBAL.innodb_log_optimize_ddl = 1 AS col; +col +1 +1 Expected +SELECT @@innodb_log_optimize_ddl = @@GLOBAL.innodb_log_optimize_ddl AS col; +col +1 +1 Expected +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='innodb_log_optimize_ddl'; +VARIABLE_VALUE +OFF +SHOW VARIABLES WHERE VARIABLE_NAME='innodb_log_optimize_ddl'; +Variable_name Value +innodb_log_optimize_ddl OFF +SELECT @@local.innodb_log_optimize_ddl; +ERROR HY000: Variable 'innodb_log_optimize_ddl' is a GLOBAL variable +Expected error 'Variable is a GLOBAL variable' +SELECT innodb_log_optimize_ddl; +ERROR 42S22: Unknown column 'innodb_log_optimize_ddl' in 'field list' +SET GLOBAL innodb_log_optimize_ddl = @innodb_log_optimize_ddl_save; diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result index c42bf1f241c..87e2012b61f 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -586,6 +586,20 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME CORE_FILE +SESSION_VALUE NULL +GLOBAL_VALUE ON +GLOBAL_VALUE_ORIGIN COMPILE-TIME +DEFAULT_VALUE NULL +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE BOOLEAN +VARIABLE_COMMENT write a core-file on crashes +NUMERIC_MIN_VALUE NULL +NUMERIC_MAX_VALUE NULL +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST OFF,ON +READ_ONLY YES +COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME DATADIR SESSION_VALUE NULL GLOBAL_VALUE PATH diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index 54193bdf083..2be956ec1b7 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -586,6 +586,20 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME CORE_FILE +SESSION_VALUE NULL +GLOBAL_VALUE ON +GLOBAL_VALUE_ORIGIN COMPILE-TIME +DEFAULT_VALUE NULL +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE BOOLEAN +VARIABLE_COMMENT write a core-file on crashes +NUMERIC_MIN_VALUE NULL +NUMERIC_MAX_VALUE NULL +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST OFF,ON +READ_ONLY YES +COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME DATADIR SESSION_VALUE NULL GLOBAL_VALUE PATH diff --git a/mysql-test/suite/sys_vars/t/innodb_log_optimize_ddl_basic.test b/mysql-test/suite/sys_vars/t/innodb_log_optimize_ddl_basic.test new file mode 100644 index 00000000000..8e7612b0d9e --- /dev/null +++ b/mysql-test/suite/sys_vars/t/innodb_log_optimize_ddl_basic.test @@ -0,0 +1,65 @@ +############# suite/sys_vars/t/innodb_log_optimize_ddl_basic.test ############# +# # +# Variable Name: innodb_log_optimize_ddl # +# Scope: Global # +# Access Type: Dynamic # +# Data Type: boolean # +# # +# The variable was introduced by # +# MDEV-16809 Allow full redo logging for ALTER TABLE # +# # +############################################################################### + +--source include/have_innodb.inc + +#### Reveal that the global innodb system variable exists +SELECT COUNT(@@GLOBAL.innodb_log_optimize_ddl); +--echo 1 Expected + +#### Reveal that no session innodb system variable exists +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT COUNT(@@SESSION.innodb_log_optimize_ddl); +--echo Expected error 'Variable is a GLOBAL variable' + +#### Display the default value +SELECT @@GLOBAL.innodb_log_optimize_ddl; + +SELECT @@GLOBAL.innodb_log_optimize_ddl INTO @innodb_log_optimize_ddl_save; +#### Check if the value can be set +SET @@GLOBAL.innodb_log_optimize_ddl = ON; +SET @@GLOBAL.innodb_log_optimize_ddl = OFF; + +#### Check if disallowed values are refused +--error ER_WRONG_VALUE_FOR_VAR +SET @@GLOBAL.innodb_log_optimize_ddl = 13; +--error ER_WRONG_VALUE_FOR_VAR +SET @@GLOBAL.innodb_log_optimize_ddl = 'ABC'; + +#### Check if the initial value was in the range of supported values +# We use 0 and 1 in order to avoid a warning. +SELECT @@GLOBAL.innodb_log_optimize_ddl = 0 + OR @@GLOBAL.innodb_log_optimize_ddl = 1 AS col; +--echo 1 Expected + +#### Check if the value presented without GLOBAL point is the same +SELECT @@innodb_log_optimize_ddl = @@GLOBAL.innodb_log_optimize_ddl AS col; +--echo 1 Expected + +#### Show the value presented in information_schema and SHOW VARIABLES +# We do not want to get and than maybe suppress the print of +# Warning 1292 Truncated incorrect DOUBLE value: 'OFF' +# and so we simply print the value and do not compare. +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='innodb_log_optimize_ddl'; +SHOW VARIABLES WHERE VARIABLE_NAME='innodb_log_optimize_ddl'; + +#### Show that variants with @@local. and without @@ do not exist. +--Error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT @@local.innodb_log_optimize_ddl; +--echo Expected error 'Variable is a GLOBAL variable' +--Error ER_BAD_FIELD_ERROR +SELECT innodb_log_optimize_ddl; + +#### Restore the initial value +SET GLOBAL innodb_log_optimize_ddl = @innodb_log_optimize_ddl_save; + diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index 3def1bd083b..a5b65f5315c 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -626,6 +626,19 @@ } # +# Warning caused by small memory leak in _dl_init +# + +{ + dl_init memory leak + Memcheck:Leak + fun:malloc + obj:*/libstdc++.so* + fun:call_init.part* + fun:_dl_init +} + +# # In glibc (checked version 2.7), inet_ntoa allocates an 18-byte # per-thread static buffer for the return value. That memory is freed # at thread exit, however if called from the main thread, Valgrind diff --git a/mysys/my_rename.c b/mysys/my_rename.c index 09e7eafa980..17f693629a8 100644 --- a/mysys/my_rename.c +++ b/mysys/my_rename.c @@ -39,7 +39,10 @@ int my_rename(const char *from, const char *to, myf MyFlags) if (link(from, to) || unlink(from)) { #endif - my_errno=errno; + if (errno == ENOENT && !access(from, F_OK)) + my_errno= ENOTDIR; + else + my_errno= errno; error = -1; if (MyFlags & (MY_FAE+MY_WME)) my_error(EE_LINK, MYF(ME_BELL+ME_WAITTANG),from,to,my_errno); diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index fe14edba139..464c00d57da 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -91,6 +91,7 @@ SET(ADD_GIS_SP_EOL ";") CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/maria_add_gis_sp.sql.in ${CMAKE_CURRENT_BINARY_DIR}/maria_add_gis_sp_bootstrap.sql ESCAPE_QUOTES @ONLY) +IF (NOT WITHOUT_SERVER) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/mysql_system_tables.sql ${CMAKE_CURRENT_SOURCE_DIR}/mysql_system_tables_data.sql @@ -104,6 +105,7 @@ INSTALL(FILES ${FIX_PRIVILEGES_SQL} DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Server ) +ENDIF() # TCMalloc hacks IF(MALLOC_LIB) diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index de2ab3983b3..fb3b32251ed 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -242,6 +242,11 @@ cannot_find_file() echo "If you don't want to do a full install, you can use the --srcdir" echo "option to only install the mysql database and privilege tables" echo + echo "If you compiled from source, you need to either run 'make install' to" + echo "copy the software into the correct location ready for operation." + echo "If you don't want to do a full install, you can use the --srcdir" + echo "option to only install the mysql database and privilege tables" + echo echo "If you are using a binary release, you must either be at the top" echo "level of the extracted archive, or pass the --basedir option" echo "pointing to that location." @@ -341,7 +346,7 @@ else basedir="@prefix@" bindir="@bindir@" resolveip="$bindir/resolveip" - mysqld="@libexecdir@/mysqld" + mysqld="@sbindir@/mysqld" srcpkgdatadir="@pkgdatadir@" buildpkgdatadir="@pkgdatadir@" plugindir="@pkgplugindir@" diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index 6f42e432d7a..9f8af61752f 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -1,4 +1,4 @@ --- Copyright (c) 2007, 2013, Oracle and/or its affiliates. +-- Copyright (c) 2007, 2018, Oracle and/or its affiliates. -- Copyright (c) 2008, 2014, Monty Program Ab & SkySQL Ab -- -- This program is free software; you can redistribute it and/or modify @@ -107,7 +107,7 @@ CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_b SET @create_innodb_table_stats="CREATE TABLE IF NOT EXISTS innodb_table_stats ( database_name VARCHAR(64) NOT NULL, - table_name VARCHAR(64) NOT NULL, + table_name VARCHAR(199) NOT NULL, last_update TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, n_rows BIGINT UNSIGNED NOT NULL, clustered_index_size BIGINT UNSIGNED NOT NULL, @@ -117,7 +117,7 @@ SET @create_innodb_table_stats="CREATE TABLE IF NOT EXISTS innodb_table_stats ( SET @create_innodb_index_stats="CREATE TABLE IF NOT EXISTS innodb_index_stats ( database_name VARCHAR(64) NOT NULL, - table_name VARCHAR(64) NOT NULL, + table_name VARCHAR(199) NOT NULL, index_name VARCHAR(64) NOT NULL, last_update TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, /* there are at least: diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index 51c7e544228..5372408fd0d 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -1,5 +1,5 @@ -- Copyright (C) 2003, 2013 Oracle and/or its affiliates. --- Copyright (C) 2010, 2015 MariaDB Corporation Ab. +-- Copyright (C) 2010, 2018 MariaDB Corporation -- -- 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 @@ -28,15 +28,24 @@ set sql_mode=''; set storage_engine=MyISAM; set enforce_storage_engine=NULL; -ALTER TABLE user add File_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL; +ALTER TABLE user add File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; # Detect whether or not we had the Grant_priv column SET @hadGrantPriv:=0; SELECT @hadGrantPriv:=1 FROM user WHERE Grant_priv LIKE '%'; -ALTER TABLE user add Grant_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add References_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Index_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Alter_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL; -ALTER TABLE host add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Index_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Alter_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL; -ALTER TABLE db add Grant_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add References_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Index_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Alter_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL; +ALTER TABLE user add Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; +ALTER TABLE host add Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; +ALTER TABLE db add Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + add Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; # Fix privileges for old tables UPDATE user SET Grant_priv=File_priv,References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv WHERE @hadGrantPriv = 0; @@ -48,11 +57,11 @@ UPDATE host SET References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Cr # Adding columns needed by GRANT .. REQUIRE (openssl) ALTER TABLE user -ADD ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci NOT NULL, +ADD ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL, ADD ssl_cipher BLOB NOT NULL, ADD x509_issuer BLOB NOT NULL, ADD x509_subject BLOB NOT NULL; -ALTER TABLE user MODIFY ssl_type enum('','ANY','X509', 'SPECIFIED') NOT NULL; +ALTER TABLE user MODIFY ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL; # # tables_priv @@ -63,9 +72,9 @@ ALTER TABLE tables_priv ALTER TABLE tables_priv MODIFY Host char(60) NOT NULL default '', MODIFY Db char(64) NOT NULL default '', - MODIFY User char(80) NOT NULL default '', + MODIFY User char(80) binary NOT NULL default '', MODIFY Table_name char(64) NOT NULL default '', - MODIFY Grantor char(141) NOT NULL default '', + MODIFY Grantor char(141) COLLATE utf8_bin NOT NULL default '', ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; @@ -91,7 +100,7 @@ ALTER TABLE columns_priv ALTER TABLE columns_priv MODIFY Host char(60) NOT NULL default '', MODIFY Db char(64) NOT NULL default '', - MODIFY User char(80) NOT NULL default '', + MODIFY User char(80) binary NOT NULL default '', MODIFY Table_name char(64) NOT NULL default '', MODIFY Column_name char(64) NOT NULL default '', ENGINE=MyISAM, @@ -162,7 +171,7 @@ alter table func comment='User defined functions'; # and reset all char columns to correct width ALTER TABLE user MODIFY Host char(60) NOT NULL default '', - MODIFY User char(80) NOT NULL default '', + MODIFY User char(80) binary NOT NULL default '', ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; # In MySQL 5.7.6 the Password column is removed. Recreate it to preserve the number @@ -198,7 +207,7 @@ ALTER TABLE user ALTER TABLE db MODIFY Host char(60) NOT NULL default '', MODIFY Db char(64) NOT NULL default '', - MODIFY User char(80) NOT NULL default '', + MODIFY User char(80) binary NOT NULL default '', ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; ALTER TABLE db MODIFY Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, @@ -462,7 +471,7 @@ ALTER TABLE proc MODIFY db MODIFY definer char(141) collate utf8_bin DEFAULT '' NOT NULL, MODIFY comment - char(64) collate utf8_bin DEFAULT '' NOT NULL; + text collate utf8_bin NOT NULL; ALTER TABLE proc ADD character_set_client char(32) collate utf8_bin DEFAULT NULL @@ -540,19 +549,18 @@ ALTER TABLE proc ADD aggregate enum('NONE', 'GROUP') DEFAULT 'NONE' NOT NULL SET @hadEventPriv := 0; SELECT @hadEventPriv :=1 FROM user WHERE Event_priv LIKE '%'; -ALTER TABLE user add Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL AFTER Create_user_priv; +ALTER TABLE user ADD Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL AFTER Create_user_priv; ALTER TABLE user MODIFY Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL AFTER Create_user_priv; UPDATE user SET Event_priv=Super_priv WHERE @hadEventPriv = 0; -ALTER TABLE db add Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL; +ALTER TABLE db ADD Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL; ALTER TABLE db MODIFY Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL; # # EVENT table # -ALTER TABLE event DROP PRIMARY KEY; -ALTER TABLE event ADD PRIMARY KEY(db, name); +ALTER TABLE event DROP PRIMARY KEY, ADD PRIMARY KEY(db, name); # Add sql_mode column just in case. ALTER TABLE event ADD sql_mode set ('IGNORE_BAD_TABLE_OPTIONS') AFTER on_completion; # Update list of sql_mode values. @@ -594,8 +602,8 @@ ALTER TABLE event MODIFY sql_mode ) DEFAULT '' NOT NULL AFTER on_completion; ALTER TABLE event MODIFY name char(64) CHARACTER SET utf8 NOT NULL default ''; -ALTER TABLE event MODIFY COLUMN originator INT UNSIGNED NOT NULL; ALTER TABLE event ADD COLUMN originator INT UNSIGNED NOT NULL AFTER comment; +ALTER TABLE event MODIFY COLUMN originator INT UNSIGNED NOT NULL; ALTER TABLE event MODIFY COLUMN status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED'; @@ -674,12 +682,14 @@ ALTER TABLE db modify Delete_history_priv enum('N','Y') COLLATE utf8_general_ci UPDATE user SET Delete_history_priv = Super_priv WHERE @had_user_delete_history_priv = 0; -ALTER TABLE user ADD plugin char(64) DEFAULT '', ADD authentication_string TEXT; +ALTER TABLE user ADD plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL, + ADD authentication_string TEXT NOT NULL; +ALTER TABLE user MODIFY plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL, + MODIFY authentication_string TEXT NOT NULL; ALTER TABLE user ADD password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; ALTER TABLE user ADD is_role enum('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; ALTER TABLE user ADD default_role char(80) binary DEFAULT '' NOT NULL; ALTER TABLE user ADD max_statement_time decimal(12,6) DEFAULT 0 NOT NULL; -ALTER TABLE user MODIFY plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL, MODIFY authentication_string TEXT NOT NULL; -- Somewhere above, we ran ALTER TABLE user .... CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin. -- we want password_expired column to have collation utf8_general_ci. ALTER TABLE user MODIFY password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; @@ -722,13 +732,13 @@ set @str=replace(@str, "innodb_index_stats", "innodb_table_stats"); prepare stmt from @str; execute stmt; -# update timestamp fields in the innodb stat tables -set @str="alter table mysql.innodb_index_stats modify last_update timestamp not null default current_timestamp on update current_timestamp"; +# update table_name and timestamp fields in the innodb stat tables +set @str="alter table mysql.innodb_index_stats modify last_update timestamp not null default current_timestamp on update current_timestamp, modify table_name varchar(199)"; set @str=if(@have_innodb <> 0, @str, "set @dummy = 0"); prepare stmt from @str; execute stmt; -set @str="alter table mysql.innodb_table_stats modify last_update timestamp not null default current_timestamp on update current_timestamp"; +set @str="alter table mysql.innodb_table_stats modify last_update timestamp not null default current_timestamp on update current_timestamp, modify table_name varchar(199)"; set @str=if(@have_innodb <> 0, @str, "set @dummy = 0"); prepare stmt from @str; execute stmt; diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh index c6515a3986b..2ab70cdd4c3 100644 --- a/scripts/mysqld_multi.sh +++ b/scripts/mysqld_multi.sh @@ -30,7 +30,7 @@ $opt_example = 0; $opt_help = 0; $opt_log = undef(); $opt_mysqladmin = "@bindir@/mysqladmin"; -$opt_mysqld = "@libexecdir@/mysqld"; +$opt_mysqld = "@sbindir@/mysqld"; $opt_no_log = 0; $opt_password = undef(); $opt_tcp_ip = 0; diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index aee2f0b7f64..8173db26291 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -33,7 +33,6 @@ ssystag="" XTRABACKUP_PID="" SST_PORT="" REMOTEIP="" -REMOTEHOST="" tcert="" tpem="" tkey="" @@ -219,7 +218,7 @@ get_transfer() tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tpem},cafile=${tcert}${sockopt} stdio" else wsrep_log_info "Encrypting with cert=${tpem}, cafile=${tcert}" - tcmd="socat -u stdio openssl-connect:${REMOTEHOST}:${TSST_PORT},cert=${tpem},cafile=${tcert}${sockopt}" + tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${tpem},cafile=${tcert}${sockopt}" fi elif [[ $encrypt -eq 3 ]];then wsrep_log_info "Using openssl based encryption with socat: with key and crt" @@ -242,7 +241,7 @@ get_transfer() tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${tpem},key=${tkey},verify=0${sockopt}" else wsrep_log_info "Encrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}" - tcmd="socat -u stdio openssl-connect:${REMOTEHOST}:${TSST_PORT},cert=${tpem},key=${tkey},cafile=${tcert}${sockopt}" + tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${tpem},key=${tkey},cafile=${tcert}${sockopt}" fi fi @@ -512,10 +511,6 @@ setup_ports() if [[ "$WSREP_SST_OPT_ROLE" == "donor" ]];then SST_PORT=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $2 }') REMOTEIP=$(echo $WSREP_SST_OPT_ADDR | awk -F ':' '{ print $1 }') - REMOTEHOST=$(getent hosts $REMOTEIP | awk '{ print $2 }') - if [[ -z $REMOTEHOST ]];then - REMOTEHOST=$REMOTEIP - fi lsn=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $4 }') sst_ver=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $5 }') else @@ -638,6 +633,27 @@ send_donor() } +monitor_process() +{ + local sst_stream_pid=$1 + + while true ; do + + if ! ps --pid "${WSREP_SST_OPT_PARENT}" &>/dev/null; then + wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly." + kill -- -"${WSREP_SST_OPT_PARENT}" + exit 32 + fi + + if ! ps --pid "${sst_stream_pid}" &>/dev/null; then + break + fi + + sleep 0.1 + + done +} + wsrep_check_programs "$INNOBACKUPEX_BIN" rm -f "${MAGIC_FILE}" @@ -923,7 +939,7 @@ then MAGIC_FILE="${DATA}/${INFO_FILE}" wsrep_log_info "Waiting for SST streaming to complete!" - wait $jpid + monitor_process $jpid get_proc diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index 7fc83c1139c..6b1f9c7871f 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -375,6 +375,8 @@ EOF then wsrep_log_error \ "Parent mysqld process (PID:$MYSQLD_PID) terminated unexpectedly." + kill -- -"${MYSQLD_PID}" + sleep 1 exit 32 fi diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh index 79442d415e9..11977249569 100644 --- a/scripts/wsrep_sst_xtrabackup-v2.sh +++ b/scripts/wsrep_sst_xtrabackup-v2.sh @@ -795,6 +795,27 @@ check_for_version() fi } +monitor_process() +{ + local sst_stream_pid=$1 + + while true ; do + + if ! ps --pid "${WSREP_SST_OPT_PARENT}" &>/dev/null; then + wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly." + kill -- -"${WSREP_SST_OPT_PARENT}" + exit 32 + fi + + if ! ps --pid "${sst_stream_pid}" &>/dev/null; then + break + fi + + sleep 0.1 + + done +} + wsrep_check_programs "$INNOBACKUPEX_BIN" @@ -1093,7 +1114,7 @@ then MAGIC_FILE="${DATA}/${INFO_FILE}" wsrep_log_info "Waiting for SST streaming to complete!" - wait $jpid + monitor_process $jpid get_proc diff --git a/sql-common/client.c b/sql-common/client.c index 8bbe08a504a..1d354cefb0b 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1458,6 +1458,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, if ((pkt_len= cli_safe_read(mysql)) == packet_error) DBUG_RETURN(0); + if (pkt_len == 0) DBUG_RETURN(0); if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), MYF(MY_WME | MY_ZEROFILL)))) { @@ -2576,6 +2577,9 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, enum enum_ssl_init_error ssl_init_error; const char *cert_error; unsigned long ssl_error; +#ifdef EMBEDDED_LIBRARY + DBUG_ASSERT(0); // embedded should not do SSL connect +#endif /* Send mysql->client_flag, max_packet_size - unencrypted otherwise diff --git a/sql/field.cc b/sql/field.cc index 4c0f1b0560b..61bc2daef8d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8217,7 +8217,13 @@ int Field_blob::store(const char *from,size_t length,CHARSET_INFO *cs) return 0; } - if (table->blob_storage) // GROUP_CONCAT with ORDER BY | DISTINCT + /* + For min/max fields of statistical data 'table' is set to NULL. + It could not be otherwise as this data is shared by many instances + of the same base table. + */ + + if (table && table->blob_storage) // GROUP_CONCAT with ORDER BY | DISTINCT { DBUG_ASSERT(!f_is_hex_escape(flags)); DBUG_ASSERT(field_charset == cs); diff --git a/sql/handler.cc b/sql/handler.cc index 4f152cfd99c..81b305220df 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -6772,7 +6772,7 @@ int del_global_index_stats_for_table(THD *thd, uchar* cache_key, size_t cache_ke /* Remove a table from global table statistics */ -int del_global_table_stat(THD *thd, LEX_CSTRING *db, LEX_CSTRING *table) +int del_global_table_stat(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table) { TABLE_STATS *table_stats; int res = 0; diff --git a/sql/handler.h b/sql/handler.h index ce8711bd5ab..c6d7ef5870a 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -2,7 +2,7 @@ #define HANDLER_INCLUDED /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2009, 2017, MariaDB Corporation. + Copyright (c) 2009, 2018, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -818,7 +818,7 @@ struct xid_t { bqual_length= b; memcpy(data, d, g+b); } - bool is_null() { return formatID == -1; } + bool is_null() const { return formatID == -1; } void null() { formatID= -1; } my_xid quick_get_my_xid() { @@ -4829,5 +4829,5 @@ void print_keydup_error(TABLE *table, KEY *key, const char *msg, myf errflag); void print_keydup_error(TABLE *table, KEY *key, myf errflag); int del_global_index_stat(THD *thd, TABLE* table, KEY* key_info); -int del_global_table_stat(THD *thd, LEX_CSTRING *db, LEX_CSTRING *table); +int del_global_table_stat(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table); #endif /* HANDLER_INCLUDED */ diff --git a/sql/item.cc b/sql/item.cc index 5f5b60d1eda..f07e907db09 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2016, Oracle and/or its affiliates. + Copyright (c) 2000, 2018, Oracle and/or its affiliates. Copyright (c) 2010, 2018, MariaDB Corporation This program is free software; you can redistribute it and/or modify diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index c321b826ea4..599d638d601 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -2834,16 +2834,7 @@ public: bool fix_length_and_dec(); const char *func_name() const { return "regexp"; } enum precedence precedence() const { return CMP_PRECEDENCE; } - Item *get_copy(THD *thd) - { return get_item_copy<Item_func_regex>(thd, this); } - Item *build_clone(THD *thd) - { - Item_func_regex *clone= (Item_func_regex*) Item_bool_func::build_clone(thd); - if (clone) - clone->re.reset(); - return clone; - } - + Item *get_copy(THD *) { return 0; } void print(String *str, enum_query_type query_type) { print_op(str, query_type); @@ -2883,8 +2874,7 @@ public: bool fix_fields(THD *thd, Item **ref); bool fix_length_and_dec(); const char *func_name() const { return "regexp_instr"; } - Item *get_copy(THD *thd) - { return get_item_copy<Item_func_regexp_instr>(thd, this); } + Item *get_copy(THD *thd) { return 0; } }; diff --git a/sql/item_func.h b/sql/item_func.h index b4f3cce612d..af29e14fe3a 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -2946,15 +2946,7 @@ public: { return TRUE; } - Item *get_copy(THD *thd) - { return get_item_copy<Item_func_sp>(thd, this); } - Item *build_clone(THD *thd) - { - Item_func_sp *clone= (Item_func_sp *) Item_func::build_clone(thd); - if (clone) - clone->sp_result_field= NULL; - return clone; - } + Item *get_copy(THD *) { return 0; } bool eval_not_null_tables(void *opt_arg) { not_null_tables_cache= 0; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index c914c6cbdf8..1590576ddf4 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1570,32 +1570,18 @@ String *Item_str_conv::val_str(String *str) { DBUG_ASSERT(fixed == 1); String *res; - if (!(res=args[0]->val_str(str))) - { - null_value=1; /* purecov: inspected */ - return 0; /* purecov: inspected */ - } - null_value=0; - if (multiply == 1) - { - size_t len; - res= copy_if_not_alloced(&tmp_value, res, res->length()); - len= converter(collation.collation, (char*) res->ptr(), res->length(), - (char*) res->ptr(), res->length()); - DBUG_ASSERT(len <= res->length()); - res->length(len); - } - else - { - size_t len= res->length() * multiply; - tmp_value.alloc(len); - tmp_value.set_charset(collation.collation); - len= converter(collation.collation, (char*) res->ptr(), res->length(), - (char*) tmp_value.ptr(), len); - tmp_value.length(len); - res= &tmp_value; - } - return res; + uint32 alloced_length, len; + + if ((null_value= (!(res= args[0]->val_str(&tmp_value)) || + str->alloc((alloced_length= res->length() * multiply))))) + return 0; + + len= converter(collation.collation, (char*) res->ptr(), res->length(), + (char*) str->ptr(), alloced_length); + DBUG_ASSERT(len <= alloced_length); + str->set_charset(collation.collation); + str->length(len); + return str; } @@ -1798,7 +1784,7 @@ String *Item_func_substr_index::val_str(String *str) DBUG_ASSERT(fixed == 1); char buff[MAX_FIELD_WIDTH]; String tmp(buff,sizeof(buff),system_charset_info); - String *res= args[0]->val_str(str); + String *res= args[0]->val_str(&tmp_value); String *delimiter= args[1]->val_str(&tmp); int32 count= (int32) args[2]->val_int(); uint offset; @@ -1847,20 +1833,31 @@ String *Item_func_substr_index::val_str(String *str) if (pass == 0) /* count<0 */ { c+=n+1; - if (c<=0) return res; /* not found, return original string */ + if (c<=0) + { + str->copy(res->ptr(), res->length(), collation.collation); + return str; // not found, return the original string + } ptr=res->ptr(); } else { - if (c) return res; /* Not found, return original string */ + if (c) + { + str->copy(res->ptr(), res->length(), collation.collation); + return str; // not found, return the original string + } if (count>0) /* return left part */ { - tmp_value.set(*res,0,(ulong) (ptr-res->ptr())); + str->copy(res->ptr(), (uint32) (ptr-res->ptr()), collation.collation); + return str; } else /* return right part */ { - ptr+= delimiter_length; - tmp_value.set(*res,(ulong) (ptr-res->ptr()), (ulong) (strend-ptr)); + ptr+= delimiter_length; + str->copy(res->ptr() + (ptr-res->ptr()), (uint32) (strend - ptr), + collation.collation); + return str; } } } @@ -1872,13 +1869,16 @@ String *Item_func_substr_index::val_str(String *str) { // start counting from the beginning for (offset=0; ; offset+= delimiter_length) { - if ((int) (offset= res->strstr(*delimiter, offset)) < 0) - return res; // Didn't find, return org string - if (!--count) - { - tmp_value.set(*res,0,offset); - break; - } + if ((int) (offset= res->strstr(*delimiter, offset)) < 0) + { + str->copy(res->ptr(), res->length(), collation.collation); + return str; // not found, return the original string + } + if (!--count) + { + str->copy(res->ptr(), offset, collation.collation); + return str; + } } } else @@ -1893,30 +1893,32 @@ String *Item_func_substr_index::val_str(String *str) address space less than where the found substring is located in res */ - if ((int) (offset= res->strrstr(*delimiter, offset)) < 0) - return res; // Didn't find, return org string + if ((int) (offset= res->strrstr(*delimiter, offset)) < 0) + { + str->copy(res->ptr(), res->length(), collation.collation); + return str; // not found, return the original string + } /* At this point, we've searched for the substring the number of times as supplied by the index value */ - if (!++count) - { - offset+= delimiter_length; - tmp_value.set(*res,offset,res->length()- offset); - break; - } + if (!++count) + { + offset+= delimiter_length; + str->copy(res->ptr() + offset, res->length() - offset, + collation.collation); + return str; + } } if (count) - return res; // Didn't find, return org string + { + str->copy(res->ptr(), res->length(), collation.collation); + return str; // not found, return the original string + } } } - /* - We always mark tmp_value as const so that if val_str() is called again - on this object, we don't disrupt the contents of tmp_value when it was - derived from another String. - */ - tmp_value.mark_as_const(); - return (&tmp_value); + DBUG_ASSERT(0); + return NULL; } /* diff --git a/sql/log.cc b/sql/log.cc index 609f7d8e1fc..1ffa6f7588f 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2746,14 +2746,14 @@ void MYSQL_LOG::close(uint exiting) if (log_type == LOG_BIN && mysql_file_sync(log_file.file, MYF(MY_WME)) && ! write_error) { write_error= 1; - sql_print_error(ER_THD_OR_DEFAULT(current_thd, ER_ERROR_ON_WRITE), name, errno); + sql_print_error(ER_DEFAULT(ER_ERROR_ON_WRITE), name, errno); } if (!(exiting & LOG_CLOSE_DELAYED_CLOSE) && mysql_file_close(log_file.file, MYF(MY_WME)) && ! write_error) { write_error= 1; - sql_print_error(ER_THD_OR_DEFAULT(current_thd, ER_ERROR_ON_WRITE), name, errno); + sql_print_error(ER_DEFAULT(ER_ERROR_ON_WRITE), name, errno); } } @@ -2937,7 +2937,7 @@ err: if (!write_error) { write_error= 1; - sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno); + sql_print_error(ER_DEFAULT(ER_ERROR_ON_WRITE), name, errno); } mysql_mutex_unlock(&LOCK_log); return TRUE; @@ -8474,8 +8474,7 @@ void MYSQL_BIN_LOG::close(uint exiting) ! write_error) { write_error= 1; - sql_print_error(ER_THD_OR_DEFAULT(current_thd, ER_ERROR_ON_WRITE), - index_file_name, errno); + sql_print_error(ER_DEFAULT(ER_ERROR_ON_WRITE), index_file_name, errno); } } log_state= (exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index dab0fab35e0..e689087e1f8 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -484,7 +484,7 @@ my_bool opt_master_verify_checksum= 0; my_bool opt_slave_sql_verify_checksum= 1; const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS}; volatile sig_atomic_t calling_initgroups= 0; /**< Used in SIGSEGV handler. */ -uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options; +uint mysqld_port, select_errors, dropping_tables, ha_open_options; uint mysqld_extra_port; uint mysqld_port_timeout; ulong delay_key_write_options; @@ -512,6 +512,7 @@ ulonglong max_binlog_cache_size=0; ulong slave_max_allowed_packet= 0; ulonglong binlog_stmt_cache_size=0; ulonglong max_binlog_stmt_cache_size=0; +ulonglong test_flags; ulonglong query_cache_size=0; ulong query_cache_limit=0; ulong executed_events=0; @@ -5754,6 +5755,11 @@ int win_main(int argc, char **argv) int mysqld_main(int argc, char **argv) #endif { +#ifndef _WIN32 + /* We can't close stdin just now, because it may be booststrap mode. */ + bool please_close_stdin= fcntl(STDIN_FILENO, F_GETFD) >= 0; +#endif + /* Perform basic thread library and malloc initialization, to be able to read defaults files and parse options. @@ -6151,7 +6157,7 @@ int mysqld_main(int argc, char **argv) #ifndef _WIN32 // try to keep fd=0 busy - if (!freopen("/dev/null", "r", stdin)) + if (please_close_stdin && !freopen("/dev/null", "r", stdin)) { // fall back on failure fclose(stdin); diff --git a/sql/mysqld.h b/sql/mysqld.h index 4a392eaf196..6c0c7308d91 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -169,7 +169,8 @@ extern ulong opt_tc_log_size, tc_log_max_pages_used, tc_log_page_size; extern ulong tc_log_page_waits; extern my_bool relay_log_purge, opt_innodb_safe_binlog, opt_innodb; extern my_bool relay_log_recovery; -extern uint test_flags,select_errors,ha_open_options; +extern uint select_errors,ha_open_options; +extern ulonglong test_flags; extern uint protocol_version, mysqld_port, dropping_tables; extern ulong delay_key_write_options; extern char *opt_logname, *opt_slow_logname, *opt_bin_logname, diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 576ef5009b5..c289fb2bc85 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -110,7 +110,7 @@ void sql_print_error(const char *format,...); extern, but as it's hard to include sql_priv.h here, we have to live with this for a while. */ -extern uint test_flags; +extern ulonglong test_flags; extern ulong bytes_sent, bytes_received, net_big_packet_count; #ifdef HAVE_QUERY_CACHE #define USE_QUERY_CACHE diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 7669610c696..13c0ce0c157 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -441,6 +441,7 @@ bool subquery_types_allow_materialization(Item_in_subselect *in_subs); static bool replace_where_subcondition(JOIN *, Item **, Item *, Item *, bool); static int subq_sj_candidate_cmp(Item_in_subselect* el1, Item_in_subselect* el2, void *arg); +static void reset_equality_number_for_subq_conds(Item * cond); static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred); static bool convert_subq_to_jtbm(JOIN *parent_join, Item_in_subselect *subq_pred, bool *remove); @@ -815,6 +816,9 @@ int check_and_do_in_subquery_rewrites(JOIN *join) details) * require that compared columns have exactly the same type. This is a temporary measure to avoid BUG#36752-type problems. + + JOIN_TAB::keyuse_is_valid_for_access_in_chosen_plan expects that for Semi Join Materialization + Scan all the items in the select list of the IN Subquery are of the type Item::FIELD_ITEM. */ static @@ -1429,6 +1433,67 @@ static int subq_sj_candidate_cmp(Item_in_subselect* el1, Item_in_subselect* el2, } +/** + @brief + reset the value of the field in_eqaulity_no for all Item_func_eq + items in the where clause of the subquery. + + Look for in_equality_no description in Item_func_eq class + + DESCRIPTION + Lets have an example: + SELECT t1.a FROM t1 WHERE t1.a IN + (SELECT t2.a FROM t2 where t2.b IN + (select t3.b from t3 where t3.c=27 )) + + So for such a query we have the parent, child and + grandchild select. + + So for the equality t2.b = t3.b we set the value for in_equality_no to + 0 according to its description. Wewe do the same for t1.a = t2.a. + But when we look at the child select (with the grandchild select merged), + the query would be + + SELECT t1.a FROM t1 WHERE t1.a IN + (SELECT t2.a FROM t2 where t2.b = t3.b and t3.c=27) + + and then when the child select is merged into the parent select the query + would look like + + SELECT t1.a FROM t1, semi-join-nest(t2,t3) + WHERE t1.a =t2.a and t2.b = t3.b and t3.c=27 + + Still we would have in_equality_no set for t2.b = t3.b + though it does not take part in the semi-join equality for the parent select, + so we should reset its value to UINT_MAX. + + @param cond WHERE clause of the subquery +*/ + +static void reset_equality_number_for_subq_conds(Item * cond) +{ + if (!cond) + return; + if (cond->type() == Item::COND_ITEM) + { + List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); + Item *item; + while ((item=li++)) + { + if (item->type() == Item::FUNC_ITEM && + ((Item_func*)item)->functype()== Item_func::EQ_FUNC) + ((Item_func_eq*)item)->in_equality_no= UINT_MAX; + } + } + else + { + if (cond->type() == Item::FUNC_ITEM && + ((Item_func*)cond)->functype()== Item_func::EQ_FUNC) + ((Item_func_eq*)cond)->in_equality_no= UINT_MAX; + } + return; +} + /* Convert a subquery predicate into a TABLE_LIST semi-join nest @@ -1693,6 +1758,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred) */ sj_nest->sj_in_exprs= subq_pred->left_expr->cols(); sj_nest->nested_join->sj_outer_expr_list.empty(); + reset_equality_number_for_subq_conds(sj_nest->sj_on_expr); if (subq_pred->left_expr->cols() == 1) { @@ -3505,7 +3571,8 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) first= tablenr - sjm->tables + 1; join->best_positions[first].n_sj_tables= sjm->tables; join->best_positions[first].sj_strategy= SJ_OPT_MATERIALIZE; - join->sjm_lookup_tables|= s->table->map; + for (uint i= first; i < first+ sjm->tables; i++) + join->sjm_lookup_tables |= join->best_positions[i].table->table->map; } else if (pos->sj_strategy == SJ_OPT_MATERIALIZE_SCAN) { diff --git a/sql/share/CMakeLists.txt b/sql/share/CMakeLists.txt index 1461c57c5c3..2980e6153f5 100644 --- a/sql/share/CMakeLists.txt +++ b/sql/share/CMakeLists.txt @@ -45,12 +45,14 @@ SET(files errmsg-utf8.txt ) -FOREACH (dir ${dirs}) - INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${dir} - DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Server) -ENDFOREACH() INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/charsets DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Common PATTERN "languages.html" EXCLUDE ) -INSTALL(FILES ${files} DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Server) +IF (NOT WITHOUT_SERVER) + FOREACH (dir ${dirs}) + INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${dir} + DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Server) + ENDFOREACH() + INSTALL(FILES ${files} DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Server) +ENDIF() diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index d00ee3e07ef..a28dcd5addd 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. +/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. Copyright (c) 2009, 2018, MariaDB This program is free software; you can redistribute it and/or modify @@ -10984,17 +10984,12 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, if (!(combo=(LEX_USER*) thd->alloc(sizeof(LEX_USER)))) DBUG_RETURN(TRUE); - combo->user.str= sctx->user; + combo->user.str= (char *) sctx->priv_user; mysql_mutex_lock(&acl_cache->lock); - if ((au= find_user_wild(combo->host.str=(char*)sctx->host_or_ip, combo->user.str))) - goto found_acl; - if ((au= find_user_wild(combo->host.str=(char*)sctx->host, combo->user.str))) - goto found_acl; - if ((au= find_user_wild(combo->host.str=(char*)sctx->ip, combo->user.str))) - goto found_acl; - if ((au= find_user_wild(combo->host.str=(char*)"%", combo->user.str))) + if ((au= find_user_wild(combo->host.str= (char *) sctx->priv_host, + combo->user.str))) goto found_acl; mysql_mutex_unlock(&acl_cache->lock); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 943d66d55f2..15cfba80340 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -6851,6 +6851,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join, Query_arena *arena, backup; bool result= TRUE; List<Natural_join_column> *non_join_columns; + List<Natural_join_column> *join_columns; DBUG_ENTER("store_natural_using_join_columns"); DBUG_ASSERT(!natural_using_join->join_columns); @@ -6858,7 +6859,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join, arena= thd->activate_stmt_arena_if_needed(&backup); if (!(non_join_columns= new List<Natural_join_column>) || - !(natural_using_join->join_columns= new List<Natural_join_column>)) + !(join_columns= new List<Natural_join_column>)) goto err; /* Append the columns of the first join operand. */ @@ -6867,7 +6868,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join, nj_col_1= it_1.get_natural_column_ref(); if (nj_col_1->is_common) { - natural_using_join->join_columns->push_back(nj_col_1, thd->mem_root); + join_columns->push_back(nj_col_1, thd->mem_root); /* Reset the common columns for the next call to mark_common_columns. */ nj_col_1->is_common= FALSE; } @@ -6888,7 +6889,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join, { const char *using_field_name_ptr= using_field_name->c_ptr(); List_iterator_fast<Natural_join_column> - it(*(natural_using_join->join_columns)); + it(*join_columns); Natural_join_column *common_field; for (;;) @@ -6921,7 +6922,8 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join, } if (non_join_columns->elements > 0) - natural_using_join->join_columns->append(non_join_columns); + join_columns->append(non_join_columns); + natural_using_join->join_columns= join_columns; natural_using_join->is_join_columns_complete= TRUE; result= FALSE; @@ -7153,7 +7155,6 @@ static bool setup_natural_join_row_types(THD *thd, DBUG_PRINT("info", ("using cached setup_natural_join_row_types")); DBUG_RETURN(false); } - context->select_lex->first_natural_join_processing= false; List_iterator_fast<TABLE_LIST> table_ref_it(*from_clause); TABLE_LIST *table_ref; /* Current table reference. */ @@ -7198,6 +7199,7 @@ static bool setup_natural_join_row_types(THD *thd, change on re-execution */ context->natural_join_first_table= context->first_name_resolution_table; + context->select_lex->first_natural_join_processing= false; DBUG_RETURN (false); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d8f4f492903..c1ec9ff94e6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -736,6 +736,9 @@ void init_update_queries(void) /* We don't want to replicate DROP for temp tables in row format */ sql_command_flags[SQLCOM_DROP_TABLE]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT; sql_command_flags[SQLCOM_DROP_SEQUENCE]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT; + /* We don't want to replicate CREATE/DROP INDEX for temp tables in row format */ + sql_command_flags[SQLCOM_CREATE_INDEX]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT; + sql_command_flags[SQLCOM_DROP_INDEX]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT; /* One can change replication mode with SET */ sql_command_flags[SQLCOM_SET_OPTION]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT; @@ -1597,10 +1600,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (thd->wsrep_conflict_state == ABORTED && command != COM_STMT_CLOSE && command != COM_QUIT) { + mysql_mutex_unlock(&thd->LOCK_thd_data); my_message(ER_LOCK_DEADLOCK, "Deadlock: wsrep aborted transaction", MYF(0)); WSREP_DEBUG("Deadlock error for: %s", thd->query()); - mysql_mutex_unlock(&thd->LOCK_thd_data); thd->reset_killed(); thd->mysys_var->abort = 0; thd->wsrep_conflict_state = NO_CONFLICT; @@ -7905,36 +7908,46 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, thd->lex->sql_command != SQLCOM_SELECT && (thd->wsrep_retry_counter < thd->variables.wsrep_retry_autocommit)) { - WSREP_DEBUG("wsrep retrying AC query: %s", + mysql_mutex_unlock(&thd->LOCK_thd_data); + WSREP_DEBUG("wsrep retrying AC query: %s", (thd->query()) ? thd->query() : "void"); /* Performance Schema Interface instrumentation, end */ MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); thd->m_statement_psi= NULL; thd->m_digest= NULL; + // Released thd->LOCK_thd_data above as below could end up + // close_thread_tables()/close_open_tables()/close_thread_table()/mysql_mutex_lock(&thd->LOCK_thd_data) close_thread_tables(thd); + mysql_mutex_lock(&thd->LOCK_thd_data); thd->wsrep_conflict_state= RETRY_AUTOCOMMIT; thd->wsrep_retry_counter++; // grow wsrep_copy_query(thd); thd->set_time(); parser_state->reset(rawbuf, length); + mysql_mutex_unlock(&thd->LOCK_thd_data); } else { - WSREP_DEBUG("%s, thd: %lld is_AC: %d, retry: %lu - %lu SQL: %s", - (thd->wsrep_conflict_state == ABORTED) ? + mysql_mutex_unlock(&thd->LOCK_thd_data); + // This does dirty read to wsrep variables but it is only a debug code + WSREP_DEBUG("%s, thd: %lld is_AC: %d, retry: %lu - %lu SQL: %s", + (thd->wsrep_conflict_state == ABORTED) ? "BF Aborted" : "cert failure", (longlong) thd->thread_id, is_autocommit, - thd->wsrep_retry_counter, + thd->wsrep_retry_counter, thd->variables.wsrep_retry_autocommit, thd->query()); my_message(ER_LOCK_DEADLOCK, "Deadlock: wsrep aborted transaction", MYF(0)); + + mysql_mutex_lock(&thd->LOCK_thd_data); thd->wsrep_conflict_state= NO_CONFLICT; if (thd->wsrep_conflict_state != REPLAYING) thd->wsrep_retry_counter= 0; // reset + mysql_mutex_unlock(&thd->LOCK_thd_data); } - mysql_mutex_unlock(&thd->LOCK_thd_data); + thd->reset_killed(); } else @@ -7970,6 +7983,7 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, #endif /* WITH_WSREP */ } + /* When you modify mysql_parse(), you may need to modify mysql_test_parse_for_slave() in this same file. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d036fc318f9..e7a4289ca22 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1675,6 +1675,13 @@ JOIN::optimize_inner() conds= optimize_cond(this, conds, join_list, FALSE, &cond_value, &cond_equal, OPT_LINK_EQUAL_FIELDS); + if (thd->is_error()) + { + error= 1; + DBUG_PRINT("error",("Error from optimize_cond")); + DBUG_RETURN(1); + } + if (thd->lex->sql_command == SQLCOM_SELECT && optimizer_flag(thd, OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED)) { @@ -1713,13 +1720,6 @@ JOIN::optimize_inner() if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE)) DBUG_RETURN(1); } - - if (unlikely(thd->is_error())) - { - error= 1; - DBUG_PRINT("error",("Error from optimize_cond")); - DBUG_RETURN(1); - } { having= optimize_cond(this, having, join_list, TRUE, @@ -4570,8 +4570,8 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, int ref_changed; do { - more_const_tables_found: ref_changed = 0; + more_const_tables_found: found_ref=0; /* @@ -4740,7 +4740,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, } } } - } while (join->const_table_map & found_ref && ref_changed); + } while (ref_changed); join->sort_by_table= get_sort_by_table(join->order, join->group_list, join->select_lex->leaf_tables, @@ -8977,8 +8977,13 @@ bool JOIN_TAB::keyuse_is_valid_for_access_in_chosen_plan(JOIN *join, st_select_lex *sjm_sel= emb_sj_nest->sj_subq_pred->unit->first_select(); for (uint i= 0; i < sjm_sel->item_list.elements; i++) { - if (sjm_sel->ref_pointer_array[i] == keyuse->val) - return true; + DBUG_ASSERT(sjm_sel->ref_pointer_array[i]->real_item()->type() == Item::FIELD_ITEM); + if (keyuse->val->real_item()->type() == Item::FIELD_ITEM) + { + Field *field = ((Item_field*)sjm_sel->ref_pointer_array[i]->real_item())->field; + if (field->eq(((Item_field*)keyuse->val->real_item())->field)) + return true; + } } return false; } @@ -9626,7 +9631,6 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, if (first_keyuse) { key_parts++; - first_keyuse= FALSE; } else { @@ -9636,7 +9640,7 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, if (curr->keypart == keyuse->keypart && !(~used_tables & curr->used_tables) && join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, - keyuse) && + curr) && are_tables_local(join_tab, curr->used_tables)) break; } @@ -9644,6 +9648,7 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, key_parts++; } } + first_keyuse= FALSE; keyuse++; } while (keyuse->table == table && keyuse->is_for_hash_join()); if (!key_parts) diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 00ed7fb0202..ea18484f8a4 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -3060,6 +3060,39 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables) /** + @breif + Cleanup of min/max statistical values for table share +*/ + +void delete_stat_values_for_table_share(TABLE_SHARE *table_share) +{ + TABLE_STATISTICS_CB *stats_cb= &table_share->stats_cb; + Table_statistics *table_stats= stats_cb->table_stats; + if (!table_stats) + return; + Column_statistics *column_stats= table_stats->column_stats; + if (!column_stats) + return; + + for (Field **field_ptr= table_share->field; + *field_ptr; + field_ptr++, column_stats++) + { + if (column_stats->min_value) + { + delete column_stats->min_value; + column_stats->min_value= NULL; + } + if (column_stats->max_value) + { + delete column_stats->max_value; + column_stats->max_value= NULL; + } + } +} + + +/** @brief Check whether any statistics is to be read for tables from a table list @@ -3289,7 +3322,7 @@ int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables) The function is called when executing the statement DROP TABLE 'tab'. */ -int delete_statistics_for_table(THD *thd, LEX_CSTRING *db, LEX_CSTRING *tab) +int delete_statistics_for_table(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *tab) { int err; enum_binlog_format save_binlog_format; diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h index 7ec742b70db..c2700eaee41 100644 --- a/sql/sql_statistics.h +++ b/sql/sql_statistics.h @@ -92,9 +92,10 @@ int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables); int collect_statistics_for_table(THD *thd, TABLE *table); int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *share, bool is_safe); +void delete_stat_values_for_table_share(TABLE_SHARE *table_share); int alloc_statistics_for_table(THD *thd, TABLE *table); int update_statistics_for_table(THD *thd, TABLE *table); -int delete_statistics_for_table(THD *thd, LEX_CSTRING *db, LEX_CSTRING *tab); +int delete_statistics_for_table(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *tab); int delete_statistics_for_column(THD *thd, TABLE *tab, Field *col); int delete_statistics_for_index(THD *thd, TABLE *tab, KEY *key_info, bool ext_prefixes_only); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index dbf400b53d7..daf8491a67f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4862,6 +4862,8 @@ int create_table_impl(THD *thd, { if (options.or_replace()) { + (void) delete_statistics_for_table(thd, db, table_name); + TABLE_LIST table_list; table_list.init_one_table(db, table_name, 0, TL_WRITE_ALLOW_WRITE); table_list.table= create_info->table; @@ -5485,13 +5487,13 @@ mysql_rename_table(handlerton *base, const LEX_CSTRING *old_db, } delete file; - if (unlikely(error)) - { - if (error == HA_ERR_WRONG_COMMAND) - my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE"); - else - my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error); - } + if (error == HA_ERR_WRONG_COMMAND) + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE"); + else if (error == ENOTDIR) + my_error(ER_BAD_DB_ERROR, MYF(0), new_db->str); + else if (error) + my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error); + else if (!(flags & FN_IS_TMP)) mysql_audit_rename_table(thd, old_db, old_name, new_db, new_name); diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index cf91d6d2189..201825d4593 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -350,7 +350,8 @@ bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref, { DEBUG_SYNC(thd, "upgrade_lock_for_truncate"); /* To remove the table from the cache we need an exclusive lock. */ - if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DROP)) + if (wait_while_table_is_used(thd, table, + *hton_can_recreate ? HA_EXTRA_PREPARE_FOR_DROP : HA_EXTRA_NOT_USED)) DBUG_RETURN(TRUE); m_ticket_downgrade= table->mdl_ticket; /* Close if table is going to be recreated. */ diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 28e8f3f6938..8858259c863 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -471,6 +471,10 @@ bool check_has_super(sys_var *self, THD *thd, set_var *var) return false; } +static Sys_var_bit Sys_core_file("core_file", "write a core-file on crashes", + READ_ONLY GLOBAL_VAR(test_flags), NO_CMD_LINE, + TEST_CORE_ON_SIGNAL, DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, + 0,0,0); static bool binlog_format_check(sys_var *self, THD *thd, set_var *var) { diff --git a/sql/table.cc b/sql/table.cc index 8dedb926141..d66df730467 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -6174,7 +6174,7 @@ Field_iterator_table_ref::get_or_create_column_ref(THD *thd, TABLE_LIST *parent_ nj_col= natural_join_it.column_ref(); DBUG_ASSERT(nj_col); } - DBUG_ASSERT(!nj_col->table_field || + DBUG_ASSERT(!nj_col->table_field || !nj_col->table_field->field || nj_col->table_ref->table == nj_col->table_field->field->table); /* @@ -6223,7 +6223,7 @@ Field_iterator_table_ref::get_or_create_column_ref(THD *thd, TABLE_LIST *parent_ RETURN # Pointer to a column of a natural join (or its operand) - NULL No memory to allocate the column + NULL We didn't originally have memory to allocate the column */ Natural_join_column * @@ -6239,7 +6239,7 @@ Field_iterator_table_ref::get_natural_column_ref() */ nj_col= natural_join_it.column_ref(); DBUG_ASSERT(nj_col && - (!nj_col->table_field || + (!nj_col->table_field || !nj_col->table_field->field || nj_col->table_ref->table == nj_col->table_field->field->table)); return nj_col; } @@ -7114,6 +7114,14 @@ void TABLE::create_key_part_by_field(KEY_PART_INFO *key_part_info, The function checks whether a possible key satisfies the constraints imposed on the keys of any temporary table. + We need to filter out BLOB columns here, because ref access optimizer creates + KEYUSE objects for equalities for non-key columns for two puproses: + 1. To discover possible keys for derived_with_keys optimization + 2. To do hash joins + For the purpose of #1, KEYUSE objects are not created for "blob_column=..." . + However, they might be created for #2. In order to catch that case, we filter + them out here. + @return TRUE if the key is valid @return FALSE otherwise */ @@ -7129,11 +7137,12 @@ bool TABLE::check_tmp_key(uint key, uint key_parts, { uint fld_idx= next_field_no(arg); reg_field= field + fld_idx; + if ((*reg_field)->type() == MYSQL_TYPE_BLOB) + return FALSE; uint fld_store_len= (uint16) (*reg_field)->key_length(); if ((*reg_field)->real_maybe_null()) fld_store_len+= HA_KEY_NULL_LENGTH; - if ((*reg_field)->type() == MYSQL_TYPE_BLOB || - (*reg_field)->real_type() == MYSQL_TYPE_VARCHAR || + if ((*reg_field)->real_type() == MYSQL_TYPE_VARCHAR || (*reg_field)->type() == MYSQL_TYPE_GEOMETRY) fld_store_len+= HA_KEY_BLOB_LENGTH; key_len+= fld_store_len; diff --git a/sql/table_cache.cc b/sql/table_cache.cc index 2c5d25c0308..61e54c8f0f9 100644 --- a/sql/table_cache.cc +++ b/sql/table_cache.cc @@ -50,6 +50,7 @@ #include "lf.h" #include "table.h" #include "sql_base.h" +#include "sql_statistics.h" /** Configuration. */ @@ -991,6 +992,7 @@ void tdc_release_share(TABLE_SHARE *share) } if (share->tdc->flushed || tdc_records() > tdc_size) { + delete_stat_values_for_table_share(share); mysql_mutex_unlock(&LOCK_unused_shares); tdc_delete_share_from_hash(share->tdc); DBUG_VOID_RETURN; diff --git a/sql/tztime.cc b/sql/tztime.cc index 61fbee1731a..177521e5a55 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1653,7 +1653,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) { /* If we are in bootstrap mode we should not load time zone tables */ return_val= time_zone_tables_exist= 0; - goto end_with_setting_default_tz; + goto end_with_cleanup; } /* diff --git a/sql/wsrep_binlog.cc b/sql/wsrep_binlog.cc index cafd41b2653..0cbcdcd64aa 100644 --- a/sql/wsrep_binlog.cc +++ b/sql/wsrep_binlog.cc @@ -322,13 +322,28 @@ int wsrep_write_cache(wsrep_t* const wsrep, void wsrep_dump_rbr_buf(THD *thd, const void* rbr_buf, size_t buf_len) { - char filename[PATH_MAX]= {0}; - int len= snprintf(filename, PATH_MAX, "%s/GRA_%lld_%lld.log", + int len= snprintf(NULL, 0, "%s/GRA_%lld_%lld.log", wsrep_data_home_dir, (longlong) thd->thread_id, (longlong) wsrep_thd_trx_seqno(thd)); - if (len >= PATH_MAX) + if (len < 0) { - WSREP_ERROR("RBR dump path too long: %d, skipping dump.", len); + WSREP_ERROR("snprintf error: %d, skipping dump.", len); + return; + } + /* + len doesn't count the \0 end-of-string. Use len+1 below + to alloc and pass as an argument to snprintf. + */ + + char *filename= (char *)malloc(len+1); + int len1= snprintf(filename, len+1, "%s/GRA_%lld_%lld.log", + wsrep_data_home_dir, (longlong) thd->thread_id, + (long long)wsrep_thd_trx_seqno(thd)); + + if (len > len1) + { + WSREP_ERROR("RBR dump path truncated: %d, skipping dump.", len); + free(filename); return; } @@ -347,6 +362,7 @@ void wsrep_dump_rbr_buf(THD *thd, const void* rbr_buf, size_t buf_len) WSREP_ERROR("Failed to open file '%s': %d (%s)", filename, errno, strerror(errno)); } + free(filename); } /* @@ -452,19 +468,34 @@ void wsrep_dump_rbr_buf_with_header(THD *thd, const void *rbr_buf, { DBUG_ENTER("wsrep_dump_rbr_buf_with_header"); - char filename[PATH_MAX]= {0}; File file; IO_CACHE cache; Log_event_writer writer(&cache, 0); Format_description_log_event *ev= 0; - int len= my_snprintf(filename, PATH_MAX, "%s/GRA_%lld_%lld_v2.log", - wsrep_data_home_dir, (longlong) thd->thread_id, - (long long) wsrep_thd_trx_seqno(thd)); + longlong thd_trx_seqno= (long long)wsrep_thd_trx_seqno(thd); + int len= snprintf(NULL, 0, "%s/GRA_%lld_%lld_v2.log", + wsrep_data_home_dir, (longlong)thd->thread_id, + thd_trx_seqno); + /* + len doesn't count the \0 end-of-string. Use len+1 below + to alloc and pass as an argument to snprintf. + */ + char *filename; + if (len < 0 || !(filename= (char*)malloc(len+1))) + { + WSREP_ERROR("snprintf error: %d, skipping dump.", len); + DBUG_VOID_RETURN; + } + + int len1= snprintf(filename, len+1, "%s/GRA_%lld_%lld_v2.log", + wsrep_data_home_dir, (longlong) thd->thread_id, + thd_trx_seqno); - if (len >= PATH_MAX) + if (len > len1) { - WSREP_ERROR("RBR dump path too long: %d, skipping dump.", len); + WSREP_ERROR("RBR dump path truncated: %d, skipping dump.", len); + free(filename); DBUG_VOID_RETURN; } @@ -505,6 +536,7 @@ cleanup2: end_io_cache(&cache); cleanup1: + free(filename); mysql_file_close(file, MYF(MY_WME)); if (!thd->wsrep_applier) delete ev; diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 7a90373e252..76b27c91d01 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1480,6 +1480,25 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table, } } +static const char* wsrep_get_query_or_msg(const THD* thd) +{ + switch(thd->lex->sql_command) + { + case SQLCOM_CREATE_USER: + return "CREATE USER"; + case SQLCOM_GRANT: + return "GRANT"; + case SQLCOM_REVOKE: + return "REVOKE"; + case SQLCOM_SET_OPTION: + if (thd->lex->definer) + return "SET PASSWORD"; + /* fallthrough */ + default: + return thd->query(); + } +} + /* returns: 0: statement was replicated as TOI @@ -1502,7 +1521,8 @@ static int wsrep_TOI_begin(THD *thd, const char *db_, const char *table_, } WSREP_DEBUG("TO BEGIN: %lld, %d : %s", (long long)wsrep_thd_trx_seqno(thd), - thd->wsrep_exec_mode, thd->query() ); + thd->wsrep_exec_mode, wsrep_get_query_or_msg(thd)); + switch (thd->lex->sql_command) { case SQLCOM_CREATE_VIEW: @@ -1576,8 +1596,8 @@ static void wsrep_TOI_end(THD *thd) { wsrep_status_t ret; wsrep_to_isolation--; - WSREP_DEBUG("TO END: %lld, %d : %s", (long long)wsrep_thd_trx_seqno(thd), - thd->wsrep_exec_mode, (thd->query()) ? thd->query() : "void"); + WSREP_DEBUG("TO END: %lld, %d: %s", (long long)wsrep_thd_trx_seqno(thd), + thd->wsrep_exec_mode, wsrep_get_query_or_msg(thd)); wsrep_set_SE_checkpoint(thd->wsrep_trx_meta.gtid.uuid, thd->wsrep_trx_meta.gtid.seqno); diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index d5b0344c456..8816a31330e 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -192,8 +192,7 @@ void wsrep_sst_grab () // Wait for end of SST bool wsrep_sst_wait () { - struct timespec wtime = {WSREP_TIMEDWAIT_SECONDS, 0}; - uint32 total_wtime = 0; + double total_wtime = 0; if (mysql_mutex_lock (&LOCK_wsrep_sst)) abort(); @@ -202,14 +201,18 @@ bool wsrep_sst_wait () while (!sst_complete) { + struct timespec wtime; + set_timespec(wtime, WSREP_TIMEDWAIT_SECONDS); + time_t start_time = time(NULL); mysql_cond_timedwait (&COND_wsrep_sst, &LOCK_wsrep_sst, &wtime); + time_t end_time = time(NULL); if (!sst_complete) { - total_wtime += wtime.tv_sec; - WSREP_DEBUG("Waiting for SST to complete. waited %u secs.", total_wtime); + total_wtime += difftime(end_time, start_time); + WSREP_DEBUG("Waiting for SST to complete. current seqno: %ld waited %f secs.", local_seqno, total_wtime); service_manager_extend_timeout(WSREP_EXTEND_TIMEOUT_INTERVAL, - "WSREP state transfer ongoing, current seqno: %ld", local_seqno); + "WSREP state transfer ongoing, current seqno: %ld waited %f secs", local_seqno, total_wtime); } } @@ -1365,19 +1368,22 @@ void wsrep_SE_init_grab() void wsrep_SE_init_wait() { - struct timespec wtime = {WSREP_TIMEDWAIT_SECONDS, 0}; - uint32 total_wtime=0; + double total_wtime=0; while (SE_initialized == false) { + struct timespec wtime; + set_timespec(wtime, WSREP_TIMEDWAIT_SECONDS); + time_t start_time = time(NULL); mysql_cond_timedwait (&COND_wsrep_sst_init, &LOCK_wsrep_sst_init, &wtime); + time_t end_time = time(NULL); if (!SE_initialized) { - total_wtime += wtime.tv_sec; - WSREP_DEBUG("Waiting for SST to complete. waited %u secs.", total_wtime); + total_wtime += difftime(end_time, start_time); + WSREP_DEBUG("Waiting for SST to complete. current seqno: %ld waited %f secs.", local_seqno, total_wtime); service_manager_extend_timeout(WSREP_EXTEND_TIMEOUT_INTERVAL, - "WSREP SE initialization ongoing."); + "WSREP state transfer ongoing, current seqno: %ld waited %f secs", local_seqno, total_wtime); } } diff --git a/sql/wsrep_xid.cc b/sql/wsrep_xid.cc index 618c98eade7..2834100568a 100644 --- a/sql/wsrep_xid.cc +++ b/sql/wsrep_xid.cc @@ -156,15 +156,14 @@ bool wsrep_get_SE_checkpoint(wsrep_uuid_t& uuid, wsrep_seqno_t& seqno) seqno= WSREP_SEQNO_UNDEFINED; XID xid; - memset(&xid, 0, sizeof(xid)); - xid.formatID= -1; + xid.null(); if (wsrep_get_SE_checkpoint(xid)) { return true; } - if (xid.formatID == -1) // nil XID + if (xid.is_null()) { return false; } diff --git a/storage/connect/filamvct.cpp b/storage/connect/filamvct.cpp index a660461e9ee..71174c3530f 100644 --- a/storage/connect/filamvct.cpp +++ b/storage/connect/filamvct.cpp @@ -65,11 +65,6 @@ extern int num_read, num_there; // Statistics static int num_write; -#if defined(UNIX) -// Add dummy strerror (NGC) -char *strerror(int num); -#endif // UNIX - /***********************************************************************/ /* Header containing block info for not split VEC tables. */ /* Block and last values can be calculated from NumRec and Nrec. */ diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 11dc5b43059..3d8d08573f7 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2012, Facebook Inc. Copyright (c) 2015, 2018, MariaDB Corporation. @@ -65,6 +65,8 @@ Created 10/16/1994 Heikki Tuuri #include "lock0lock.h" #include "zlib.h" #include "srv0start.h" +#include "mysql_com.h" +#include "dict0stats.h" /** Buffered B-tree operation types, introduced as part of delete buffering. */ enum btr_op_t { @@ -781,13 +783,15 @@ btr_cur_will_modify_tree( first record and following compress might delete the record and causes the uppper level node_ptr modification. */ + const ulint n_recs = page_get_n_recs(page); + if (lock_intention <= BTR_INTENTION_BOTH) { ulint margin; /* check delete will cause. (BTR_INTENTION_BOTH or BTR_INTENTION_DELETE) */ /* first, 2nd, 2nd-last and last records are 4 records */ - if (page_get_n_recs(page) < 5) { + if (n_recs < 5) { return(true); } @@ -833,8 +837,7 @@ btr_cur_will_modify_tree( /* Once we invoke the btr_cur_limit_optimistic_insert_debug, we should check it here in advance, since the max allowable records in a page is limited. */ - LIMIT_OPTIMISTIC_INSERT_DEBUG(page_get_n_recs(page), - return(true)); + LIMIT_OPTIMISTIC_INSERT_DEBUG(n_recs, return true); /* needs 2 records' space for the case the single split and insert cannot fit. @@ -847,18 +850,16 @@ btr_cur_will_modify_tree( || max_size < rec_size * 2) { return(true); } - /* TODO: optimize this condition for compressed page. - this is based on the worst compress rate. - currently looking only uncompressed page, but we can look - also compressed page page_zip_available() if already in the - buffer pool */ + + /* TODO: optimize this condition for ROW_FORMAT=COMPRESSED. + This is based on the worst case, and we could invoke + page_zip_available() on the block->page.zip. */ /* needs 2 records' space also for worst compress rate. */ if (page_size.is_compressed() && page_zip_empty_size(index->n_fields, page_size.physical()) - < rec_size * 2 + page_get_data_size(page) - + page_dir_calc_reserved_space( - ulint(page_get_n_recs(page)) + 2) + 1) { + <= rec_size * 2 + page_get_data_size(page) + + page_dir_calc_reserved_space(n_recs + 2)) { return(true); } } @@ -893,6 +894,114 @@ btr_cur_need_opposite_intention( return(false); } +/** +@param[in] index b-tree +@return maximum size of a node pointer record in bytes */ +static ulint btr_node_ptr_max_size(const dict_index_t* index) +{ + if (dict_index_is_ibuf(index)) { + /* cannot estimate accurately */ + /* This is universal index for change buffer. + The max size of the entry is about max key length * 2. + (index key + primary key to be inserted to the index) + (The max key length is UNIV_PAGE_SIZE / 16 * 3 at + ha_innobase::max_supported_key_length(), + considering MAX_KEY_LENGTH = 3072 at MySQL imposes + the 3500 historical InnoDB value for 16K page size case.) + For the universal index, node_ptr contains most of the entry. + And 512 is enough to contain ibuf columns and meta-data */ + return srv_page_size / 8 * 3 + 512; + } + + /* Each record has page_no, length of page_no and header. */ + ulint comp = dict_table_is_comp(index->table); + ulint rec_max_size = comp + ? REC_NODE_PTR_SIZE + 1 + REC_N_NEW_EXTRA_BYTES + + UT_BITS_IN_BYTES(index->n_nullable) + : REC_NODE_PTR_SIZE + 2 + REC_N_OLD_EXTRA_BYTES + + 2 * index->n_fields; + + /* Compute the maximum possible record size. */ + for (ulint i = 0; i < dict_index_get_n_unique_in_tree(index); i++) { + const dict_field_t* field + = dict_index_get_nth_field(index, i); + const dict_col_t* col + = dict_field_get_col(field); + ulint field_max_size; + ulint field_ext_max_size; + + /* Determine the maximum length of the index field. */ + + field_max_size = dict_col_get_fixed_size(col, comp); + if (field_max_size) { + /* dict_index_add_col() should guarantee this */ + ut_ad(!field->prefix_len + || field->fixed_len == field->prefix_len); + /* Fixed lengths are not encoded + in ROW_FORMAT=COMPACT. */ + rec_max_size += field_max_size; + continue; + } + + field_max_size = dict_col_get_max_size(col); + if (UNIV_UNLIKELY(!field_max_size)) { + /* SYS_FOREIGN.ID is defined as CHAR in the + InnoDB internal SQL parser, which translates + into the incorrect VARCHAR(0). InnoDB does + not enforce maximum lengths of columns, so + that is why any data can be inserted in the + first place. + + Likewise, SYS_FOREIGN.FOR_NAME, + SYS_FOREIGN.REF_NAME, SYS_FOREIGN_COLS.ID, are + defined as CHAR, and also they are part of a key. */ + + ut_ad(!strcmp(index->table->name.m_name, + "SYS_FOREIGN") + || !strcmp(index->table->name.m_name, + "SYS_FOREIGN_COLS")); + ut_ad(!comp); + + rec_max_size += (srv_page_size == UNIV_PAGE_SIZE_MAX) + ? REDUNDANT_REC_MAX_DATA_SIZE + : page_get_free_space_of_empty(FALSE) / 2; + } else if (field_max_size == NAME_LEN && i == 1 + && (!strcmp(index->table->name.m_name, + TABLE_STATS_NAME) + || !strcmp(index->table->name.m_name, + INDEX_STATS_NAME))) { + ut_ad(!strcmp(field->name, "table_name")); + /* Interpret "table_name" as VARCHAR(199) even + if it was incorrectly defined as VARCHAR(64). + While the caller of ha_innobase enforces the + maximum length on any data written, the InnoDB + internal SQL parser will happily write as much + data as is provided. The purpose of this hack + is to avoid InnoDB hangs after persistent + statistics on partitioned tables are + deleted. */ + field_max_size = 199 * SYSTEM_CHARSET_MBMAXLEN; + } + field_ext_max_size = field_max_size < 256 ? 1 : 2; + + if (field->prefix_len + && field->prefix_len < field_max_size) { + field_max_size = field->prefix_len; + } + + if (comp) { + /* Add the extra size for ROW_FORMAT=COMPACT. + For ROW_FORMAT=REDUNDANT, these bytes were + added to rec_max_size before this loop. */ + rec_max_size += field_ext_max_size; + } + + rec_max_size += field_max_size; + } + + return rec_max_size; +} + /********************************************************************//** Searches an index tree and positions a tree cursor on a given level. NOTE: n_fields_cmp in tuple must be set so that it cannot be compared @@ -1218,7 +1327,7 @@ btr_cur_search_to_nth_level_func( page_id_t page_id(index->table->space->id, index->page); if (root_leaf_rw_latch == RW_X_LATCH) { - node_ptr_max_size = dict_index_node_ptr_max_size(index); + node_ptr_max_size = btr_node_ptr_max_size(index); } up_match = 0; @@ -2327,7 +2436,7 @@ btr_cur_open_at_index_side_func( const page_size_t page_size(index->table->space->flags); if (root_leaf_rw_latch == RW_X_LATCH) { - node_ptr_max_size = dict_index_node_ptr_max_size(index); + node_ptr_max_size = btr_node_ptr_max_size(index); } height = ULINT_UNDEFINED; @@ -2685,7 +2794,7 @@ btr_cur_open_at_rnd_pos_func( dberr_t err = DB_SUCCESS; if (root_leaf_rw_latch == RW_X_LATCH) { - node_ptr_max_size = dict_index_node_ptr_max_size(index); + node_ptr_max_size = btr_node_ptr_max_size(index); } height = ULINT_UNDEFINED; @@ -5657,23 +5766,45 @@ discard_page: } } - page_cur_delete_rec(btr_cur_get_page_cur(cursor), index, offsets, mtr); + /* SPATIAL INDEX never use SX locks; we can allow page merges + while holding X lock on the spatial index tree. + Do not allow merges of non-leaf B-tree pages unless it is + safe to do so. */ + { + const bool allow_merge = page_is_leaf(page) + || dict_index_is_spatial(index) + || btr_cur_will_modify_tree( + index, page, BTR_INTENTION_DELETE, rec, + btr_node_ptr_max_size(index), + block->page.size, mtr); + page_cur_delete_rec(btr_cur_get_page_cur(cursor), index, + offsets, mtr); #ifdef UNIV_ZIP_DEBUG - ut_a(!page_zip || page_zip_validate(page_zip, page, index)); + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); #endif /* UNIV_ZIP_DEBUG */ -return_after_reservations: - /* btr_check_node_ptr() needs parent block latched */ - ut_ad(!parent_latched || btr_check_node_ptr(index, block, mtr)); + ut_ad(!parent_latched + || btr_check_node_ptr(index, block, mtr)); + + if (!ret && btr_cur_compress_recommendation(cursor, mtr)) { + if (UNIV_LIKELY(allow_merge)) { + ret = btr_cur_compress_if_useful( + cursor, FALSE, mtr); + } else { + ib::warn() << "Not merging page " + << block->page.id + << " in index " << index->name + << " of " << index->table->name; + ut_ad(!"MDEV-14637"); + } + } + } +return_after_reservations: *err = DB_SUCCESS; mem_heap_free(heap); - if (ret == FALSE) { - ret = btr_cur_compress_if_useful(cursor, FALSE, mtr); - } - if (!srv_read_only_mode && page_is_leaf(page) && !dict_index_is_online_ddl(index)) { diff --git a/storage/innobase/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc index 27a45654966..f932195897c 100644 --- a/storage/innobase/buf/buf0buddy.cc +++ b/storage/innobase/buf/buf0buddy.cc @@ -124,7 +124,7 @@ buf_buddy_stamp_free( buf_buddy_free_t* buf, /*!< in/out: block to stamp */ ulint i) /*!< in: block size */ { - ut_d(memset(buf, static_cast<int>(i), BUF_BUDDY_LOW << i)); + ut_d(memset(&buf->stamp.bytes, int(i), BUF_BUDDY_LOW << i)); buf_buddy_mem_invalid(buf, i); mach_write_to_4(buf->stamp.bytes + BUF_BUDDY_STAMP_OFFSET, BUF_BUDDY_STAMP_FREE); diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index f053c170c0e..bd64334c3ba 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -2258,7 +2258,7 @@ buf_page_realloc( mutex_enter(&new_block->mutex); memcpy(new_block->frame, block->frame, srv_page_size); - memcpy(&new_block->page, &block->page, sizeof block->page); + new (&new_block->page) buf_page_t(block->page); /* relocate LRU list */ ut_ad(block->page.in_LRU_list); @@ -3389,7 +3389,7 @@ buf_relocate( } #endif /* UNIV_DEBUG */ - memcpy(dpage, bpage, sizeof *dpage); + new (dpage) buf_page_t(*bpage); /* Important that we adjust the hazard pointer before removing bpage from LRU list. */ diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc index a0c4baad64d..7ede67fd0e4 100644 --- a/storage/innobase/buf/buf0dump.cc +++ b/storage/innobase/buf/buf0dump.cc @@ -262,7 +262,7 @@ buf_dump( #define SHOULD_QUIT() (SHUTTING_DOWN() && obey_shutdown) char full_filename[OS_FILE_MAX_PATH]; - char tmp_filename[OS_FILE_MAX_PATH]; + char tmp_filename[OS_FILE_MAX_PATH + sizeof "incomplete"]; char now[32]; FILE* f; ulint i; diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index ebd5c2a828b..125c5beb47c 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -1610,7 +1610,7 @@ func_exit: } else if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE) { b = buf_page_alloc_descriptor(); ut_a(b); - memcpy(b, bpage, sizeof *b); + new (b) buf_page_t(*bpage); } ut_ad(buf_pool_mutex_own(buf_pool)); diff --git a/storage/innobase/dict/dict0defrag_bg.cc b/storage/innobase/dict/dict0defrag_bg.cc index 949bbbc0d74..69038d4cb77 100644 --- a/storage/innobase/dict/dict0defrag_bg.cc +++ b/storage/innobase/dict/dict0defrag_bg.cc @@ -39,27 +39,13 @@ static ib_mutex_t defrag_pool_mutex; static mysql_pfs_key_t defrag_pool_mutex_key; #endif -/** Indices whose defrag stats need to be saved to persistent storage.*/ -struct defrag_pool_item_t { - table_id_t table_id; - index_id_t index_id; -}; - -/** Allocator type, used by std::vector */ -typedef ut_allocator<defrag_pool_item_t> - defrag_pool_allocator_t; - -/** The multitude of tables to be defragmented- an STL vector */ -typedef std::vector<defrag_pool_item_t, defrag_pool_allocator_t> - defrag_pool_t; - /** Iterator type for iterating over the elements of objects of type defrag_pool_t. */ typedef defrag_pool_t::iterator defrag_pool_iterator_t; /** Pool where we store information on which tables are to be processed by background defragmentation. */ -static defrag_pool_t* defrag_pool; +defrag_pool_t defrag_pool; extern bool dict_stats_start_shutdown; @@ -70,14 +56,6 @@ dict_defrag_pool_init(void) /*=======================*/ { ut_ad(!srv_read_only_mode); - /* JAN: TODO: MySQL 5.7 PSI - const PSI_memory_key key2 = mem_key_dict_defrag_pool_t; - - defrag_pool = UT_NEW(defrag_pool_t(defrag_pool_allocator_t(key2)), key2); - - recalc_pool->reserve(RECALC_POOL_INITIAL_SLOTS); - */ - defrag_pool = new std::vector<defrag_pool_item_t, defrag_pool_allocator_t>(); /* We choose SYNC_STATS_DEFRAG to be below SYNC_FSP_PAGE. */ mutex_create(LATCH_ID_DEFRAGMENT_MUTEX, &defrag_pool_mutex); @@ -92,10 +70,7 @@ dict_defrag_pool_deinit(void) { ut_ad(!srv_read_only_mode); - defrag_pool->clear(); mutex_free(&defrag_pool_mutex); - - UT_DELETE(defrag_pool); } /*****************************************************************//** @@ -115,16 +90,16 @@ dict_stats_defrag_pool_get( mutex_enter(&defrag_pool_mutex); - if (defrag_pool->empty()) { + if (defrag_pool.empty()) { mutex_exit(&defrag_pool_mutex); return(false); } - defrag_pool_item_t& item = defrag_pool->back(); + defrag_pool_item_t& item = defrag_pool.back(); *table_id = item.table_id; *index_id = item.index_id; - defrag_pool->pop_back(); + defrag_pool.pop_back(); mutex_exit(&defrag_pool_mutex); @@ -149,8 +124,8 @@ dict_stats_defrag_pool_add( mutex_enter(&defrag_pool_mutex); /* quit if already in the list */ - for (defrag_pool_iterator_t iter = defrag_pool->begin(); - iter != defrag_pool->end(); + for (defrag_pool_iterator_t iter = defrag_pool.begin(); + iter != defrag_pool.end(); ++iter) { if ((*iter).table_id == index->table->id && (*iter).index_id == index->id) { @@ -161,7 +136,7 @@ dict_stats_defrag_pool_add( item.table_id = index->table->id; item.index_id = index->id; - defrag_pool->push_back(item); + defrag_pool.push_back(item); mutex_exit(&defrag_pool_mutex); @@ -183,14 +158,14 @@ dict_stats_defrag_pool_del( mutex_enter(&defrag_pool_mutex); - defrag_pool_iterator_t iter = defrag_pool->begin(); - while (iter != defrag_pool->end()) { + defrag_pool_iterator_t iter = defrag_pool.begin(); + while (iter != defrag_pool.end()) { if ((table && (*iter).table_id == table->id) || (index && (*iter).table_id == index->table->id && (*iter).index_id == index->id)) { /* erase() invalidates the iterator */ - iter = defrag_pool->erase(iter); + iter = defrag_pool.erase(iter); if (index) break; } else { @@ -252,7 +227,7 @@ void dict_defrag_process_entries_from_defrag_pool() /*==========================================*/ { - while (defrag_pool->size() && !dict_stats_start_shutdown) { + while (defrag_pool.size() && !dict_stats_start_shutdown) { dict_stats_process_entry_from_defrag_pool(); } } diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index f088e6d356c..51190ff2ef6 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -2089,93 +2089,6 @@ dict_col_name_is_reserved( } /****************************************************************//** -Return maximum size of the node pointer record. -@return maximum size of the record in bytes */ -ulint -dict_index_node_ptr_max_size( -/*=========================*/ - const dict_index_t* index) /*!< in: index */ -{ - ulint comp; - ulint i; - /* maximum possible storage size of a record */ - ulint rec_max_size; - - if (dict_index_is_ibuf(index)) { - /* cannot estimate accurately */ - /* This is universal index for change buffer. - The max size of the entry is about max key length * 2. - (index key + primary key to be inserted to the index) - (The max key length is srv_page_size / 16 * 3 at - ha_innobase::max_supported_key_length(), - considering MAX_KEY_LENGTH = 3072 at MySQL imposes - the 3500 historical InnoDB value for 16K page size case.) - For the universal index, node_ptr contains most of the entry. - And 512 is enough to contain ibuf columns and meta-data */ - return(srv_page_size / 8 * 3 + 512); - } - - comp = dict_table_is_comp(index->table); - - /* Each record has page_no, length of page_no and header. */ - rec_max_size = comp - ? REC_NODE_PTR_SIZE + 1 + REC_N_NEW_EXTRA_BYTES - : REC_NODE_PTR_SIZE + 2 + REC_N_OLD_EXTRA_BYTES; - - if (comp) { - /* Include the "null" flags in the - maximum possible record size. */ - rec_max_size += UT_BITS_IN_BYTES(unsigned(index->n_nullable)); - } else { - /* For each column, include a 2-byte offset and a - "null" flag. */ - rec_max_size += 2 * unsigned(index->n_fields); - } - - /* Compute the maximum possible record size. */ - for (i = 0; i < dict_index_get_n_unique_in_tree(index); i++) { - const dict_field_t* field - = dict_index_get_nth_field(index, i); - const dict_col_t* col - = dict_field_get_col(field); - ulint field_max_size; - ulint field_ext_max_size; - - /* Determine the maximum length of the index field. */ - - field_max_size = dict_col_get_fixed_size(col, comp); - if (field_max_size) { - /* dict_index_add_col() should guarantee this */ - ut_ad(!field->prefix_len - || field->fixed_len == field->prefix_len); - /* Fixed lengths are not encoded - in ROW_FORMAT=COMPACT. */ - rec_max_size += field_max_size; - continue; - } - - field_max_size = dict_col_get_max_size(col); - field_ext_max_size = field_max_size < 256 ? 1 : 2; - - if (field->prefix_len - && field->prefix_len < field_max_size) { - field_max_size = field->prefix_len; - } - - if (comp) { - /* Add the extra size for ROW_FORMAT=COMPACT. - For ROW_FORMAT=REDUNDANT, these bytes were - added to rec_max_size before this loop. */ - rec_max_size += field_ext_max_size; - } - - rec_max_size += field_max_size; - } - - return(rec_max_size); -} - -/****************************************************************//** If a record of this index might not fit on a single B-tree page, return TRUE. @return TRUE if the index record could become too big */ @@ -6460,8 +6373,17 @@ dict_table_schema_check( compare column types and flags */ /* check length for exact match */ - if (req_schema->columns[i].len != table->cols[j].len) { - + if (req_schema->columns[i].len == table->cols[j].len) { + } else if (!strcmp(req_schema->table_name, TABLE_STATS_NAME) + || !strcmp(req_schema->table_name, + INDEX_STATS_NAME)) { + ut_ad(table->cols[j].len < req_schema->columns[i].len); + ib::warn() << "Table " << req_schema->table_name + << " has length mismatch in the" + << " column name " + << req_schema->columns[i].name + << ". Please run mysql_upgrade"; + } else { CREATE_TYPES_NAMES(); snprintf(errstr, errstr_sz, diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 51dcdc9e140..69eebab8e17 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2009, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2009, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2015, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -108,9 +108,7 @@ where n=1..n_uniq. @} */ /* names of the tables from the persistent statistics storage */ -#define TABLE_STATS_NAME "mysql/innodb_table_stats" #define TABLE_STATS_NAME_PRINT "mysql.innodb_table_stats" -#define INDEX_STATS_NAME "mysql/innodb_index_stats" #define INDEX_STATS_NAME_PRINT "mysql.innodb_index_stats" #ifdef UNIV_STATS_DEBUG @@ -181,7 +179,7 @@ dict_stats_persistent_storage_check( DATA_NOT_NULL, 192}, {"table_name", DATA_VARMYSQL, - DATA_NOT_NULL, 192}, + DATA_NOT_NULL, 597}, {"last_update", DATA_FIXBINARY, DATA_NOT_NULL, 4}, @@ -209,7 +207,7 @@ dict_stats_persistent_storage_check( DATA_NOT_NULL, 192}, {"table_name", DATA_VARMYSQL, - DATA_NOT_NULL, 192}, + DATA_NOT_NULL, 597}, {"index_name", DATA_VARMYSQL, DATA_NOT_NULL, 192}, diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index 6fde5654dd1..f15e98b8a4d 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2018, MariaDB Corporation. 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 @@ -32,6 +32,12 @@ Created Apr 25, 2012 Vasil Dimov #include "srv0start.h" #include "ut0new.h" #include "fil0fil.h" +#ifdef WITH_WSREP +# include "mysql/service_wsrep.h" +# include "wsrep.h" +# include "log.h" +# include "wsrep_mysqld.h" +#endif #include <vector> @@ -76,41 +82,31 @@ typedef recalc_pool_t::iterator /** Pool where we store information on which tables are to be processed by background statistics gathering. */ -static recalc_pool_t* recalc_pool; - - -/*****************************************************************//** -Initialize the recalc pool, called once during thread initialization. */ -static -void -dict_stats_recalc_pool_init() -/*=========================*/ -{ - ut_ad(!srv_read_only_mode); - /* JAN: TODO: MySQL 5.7 PSI - const PSI_memory_key key = mem_key_dict_stats_bg_recalc_pool_t; - - recalc_pool = UT_NEW(recalc_pool_t(recalc_pool_allocator_t(key)), key); - - recalc_pool->reserve(RECALC_POOL_INITIAL_SLOTS); - */ - recalc_pool = new std::vector<table_id_t, recalc_pool_allocator_t>(); -} +static recalc_pool_t recalc_pool; +/** Whether the global data structures have been initialized */ +static bool stats_initialised; /*****************************************************************//** Free the resources occupied by the recalc pool, called once during thread de-initialization. */ -static -void -dict_stats_recalc_pool_deinit() -/*===========================*/ +static void dict_stats_recalc_pool_deinit() { ut_ad(!srv_read_only_mode); - recalc_pool->clear(); - - UT_DELETE(recalc_pool); - recalc_pool = NULL; + recalc_pool.clear(); + defrag_pool.clear(); + /* + recalc_pool may still have its buffer allocated. It will free it when + its destructor is called. + The problem is, memory leak detector is run before the recalc_pool's + destructor is invoked, and will report recalc_pool's buffer as leaked + memory. To avoid that, we force recalc_pool to surrender its buffer + to empty_pool object, which will free it when leaving this function: + */ + recalc_pool_t recalc_empty_pool; + defrag_pool_t defrag_empty_pool; + recalc_pool.swap(recalc_empty_pool); + defrag_pool.swap(defrag_empty_pool); } /*****************************************************************//** @@ -130,8 +126,8 @@ dict_stats_recalc_pool_add( mutex_enter(&recalc_pool_mutex); /* quit if already in the list */ - for (recalc_pool_iterator_t iter = recalc_pool->begin(); - iter != recalc_pool->end(); + for (recalc_pool_iterator_t iter = recalc_pool.begin(); + iter != recalc_pool.end(); ++iter) { if (*iter == table->id) { @@ -140,18 +136,25 @@ dict_stats_recalc_pool_add( } } - recalc_pool->push_back(table->id); + recalc_pool.push_back(table->id); mutex_exit(&recalc_pool_mutex); os_event_set(dict_stats_event); } +#ifdef WITH_WSREP +/** Update the table modification counter and if necessary, +schedule new estimates for table and index statistics to be calculated. +@param[in,out] table persistent or temporary table +@param[in] thd current session */ +void dict_stats_update_if_needed(dict_table_t* table, THD* thd) +#else /** Update the table modification counter and if necessary, schedule new estimates for table and index statistics to be calculated. @param[in,out] table persistent or temporary table */ -void -dict_stats_update_if_needed(dict_table_t* table) +void dict_stats_update_if_needed_func(dict_table_t* table) +#endif { ut_ad(table->stat_initialized); ut_ad(!mutex_own(&dict_sys->mutex)); @@ -163,6 +166,15 @@ dict_stats_update_if_needed(dict_table_t* table) if (counter > n_rows / 10 /* 10% */ && dict_stats_auto_recalc_is_enabled(table)) { +#ifdef WITH_WSREP + if (thd && wsrep_on(thd) && wsrep_thd_is_BF(thd, 0)) { + WSREP_DEBUG("Avoiding background statistics" + " calculation for table %s", + table->name.m_name); + return; + } +#endif /* WITH_WSREP */ + dict_stats_recalc_pool_add(table); table->stat_modified_counter = 0; } @@ -200,14 +212,14 @@ dict_stats_recalc_pool_get( mutex_enter(&recalc_pool_mutex); - if (recalc_pool->empty()) { + if (recalc_pool.empty()) { mutex_exit(&recalc_pool_mutex); return(false); } - *id = recalc_pool->at(0); + *id = recalc_pool.at(0); - recalc_pool->erase(recalc_pool->begin()); + recalc_pool.erase(recalc_pool.begin()); mutex_exit(&recalc_pool_mutex); @@ -229,13 +241,13 @@ dict_stats_recalc_pool_del( ut_ad(table->id > 0); - for (recalc_pool_iterator_t iter = recalc_pool->begin(); - iter != recalc_pool->end(); + for (recalc_pool_iterator_t iter = recalc_pool.begin(); + iter != recalc_pool.end(); ++iter) { if (*iter == table->id) { /* erase() invalidates the iterator */ - recalc_pool->erase(iter); + recalc_pool.erase(iter); break; } } @@ -274,7 +286,6 @@ dict_stats_thread_init() dict_stats_event = os_event_create(0); dict_stats_shutdown_event = os_event_create(0); - ut_d(dict_stats_disabled_event = os_event_create(0)); /* The recalc_pool_mutex is acquired from: @@ -293,9 +304,8 @@ dict_stats_thread_init() mutex_create(LATCH_ID_RECALC_POOL, &recalc_pool_mutex); - dict_stats_recalc_pool_init(); dict_defrag_pool_init(); - + stats_initialised = true; } /*****************************************************************//** @@ -308,10 +318,12 @@ dict_stats_thread_deinit() ut_a(!srv_read_only_mode); ut_ad(!srv_dict_stats_thread_active); - if (recalc_pool == NULL) { + if (!stats_initialised) { return; } + stats_initialised = false; + dict_stats_recalc_pool_deinit(); dict_defrag_pool_deinit(); diff --git a/storage/innobase/fts/fts0ast.cc b/storage/innobase/fts/fts0ast.cc index 82c4438196b..d6695cec5be 100644 --- a/storage/innobase/fts/fts0ast.cc +++ b/storage/innobase/fts/fts0ast.cc @@ -1,6 +1,7 @@ /***************************************************************************** -Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, MariaDB Corporation. 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 @@ -28,6 +29,7 @@ Created 2007/3/16 Sunny Bains. #include "fts0ast.h" #include "fts0pars.h" #include "fts0fts.h" +#include "row0sel.h" /* The FTS ast visit pass. */ enum fts_ast_visit_pass_t { @@ -602,6 +604,7 @@ fts_ast_visit( bool revisit = false; bool will_be_ignored = false; fts_ast_visit_pass_t visit_pass = FTS_PASS_FIRST; + const trx_t* trx = node->trx; start_node = node->list.head; @@ -700,6 +703,10 @@ fts_ast_visit( } } + if (trx_is_interrupted(trx)) { + return DB_INTERRUPTED; + } + if (revisit) { /* Exist pass processes the skipped FTS_EXIST operation. */ for (node = start_node; diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index d874725c374..7c26614b309 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2016, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -202,7 +202,7 @@ FTS auxiliary INDEX table and clear the cache at the end. @param[in,out] sync sync state @param[in] unlock_cache whether unlock cache lock when write node @param[in] wait whether wait when a sync is in progress -@param[in] has_dict whether has dict operation lock +@param[in] has_dict whether has dict operation lock @return DB_SUCCESS if all OK */ static dberr_t @@ -860,37 +860,28 @@ fts_drop_index( err = fts_drop_index_tables(trx, index); - for(;;) { - bool retry = false; - if (index->index_fts_syncing) { - retry = true; - } - if (!retry){ - fts_free(table); - break; - } + while (index->index_fts_syncing + && !trx_is_interrupted(trx)) { DICT_BG_YIELD(trx); } + + fts_free(table); + return(err); } - for(;;) { - bool retry = false; - if (index->index_fts_syncing) { - retry = true; - } - if (!retry){ - current_doc_id = table->fts->cache->next_doc_id; - first_doc_id = table->fts->cache->first_doc_id; - fts_cache_clear(table->fts->cache); - fts_cache_destroy(table->fts->cache); - table->fts->cache = fts_cache_create(table); - table->fts->cache->next_doc_id = current_doc_id; - table->fts->cache->first_doc_id = first_doc_id; - break; - } + while (index->index_fts_syncing + && !trx_is_interrupted(trx)) { DICT_BG_YIELD(trx); } + + current_doc_id = table->fts->cache->next_doc_id; + first_doc_id = table->fts->cache->first_doc_id; + fts_cache_clear(table->fts->cache); + fts_cache_destroy(table->fts->cache); + table->fts->cache = fts_cache_create(table); + table->fts->cache->next_doc_id = current_doc_id; + table->fts->cache->first_doc_id = first_doc_id; } else { fts_cache_t* cache = table->fts->cache; fts_index_cache_t* index_cache; @@ -900,18 +891,14 @@ fts_drop_index( index_cache = fts_find_index_cache(cache, index); if (index_cache != NULL) { - for(;;) { - bool retry = false; - if (index->index_fts_syncing) { - retry = true; - } - if (!retry && index_cache->words) { - fts_words_free(index_cache->words); - rbt_free(index_cache->words); - break; - } + while (index->index_fts_syncing + && !trx_is_interrupted(trx)) { DICT_BG_YIELD(trx); } + if (index_cache->words) { + fts_words_free(index_cache->words); + rbt_free(index_cache->words); + } ib_vector_remove(cache->indexes, *(void**) index_cache); } @@ -4048,6 +4035,9 @@ fts_sync_write_words( word = rbt_value(fts_tokenizer_word_t, rbt_node); + DBUG_EXECUTE_IF("fts_instrument_write_words_before_select_index", + os_thread_sleep(300000);); + selected = fts_select_index( index_cache->charset, word->text.f_str, word->text.f_len); @@ -4332,7 +4322,7 @@ FTS auxiliary INDEX table and clear the cache at the end. @param[in,out] sync sync state @param[in] unlock_cache whether unlock cache lock when write node @param[in] wait whether wait when a sync is in progress -@param[in] has_dict whether has dict operation lock +@param[in] has_dict whether has dict operation lock @return DB_SUCCESS if all OK */ static dberr_t @@ -4398,15 +4388,13 @@ begin_sync: continue; } + DBUG_EXECUTE_IF("fts_instrument_sync_before_syncing", + os_thread_sleep(300000);); index_cache->index->index_fts_syncing = true; - DBUG_EXECUTE_IF("fts_instrument_sync_sleep_drop_waits", - os_thread_sleep(10000000); - ); error = fts_sync_index(sync, index_cache); - if (error != DB_SUCCESS && !sync->interrupted) { - + if (error != DB_SUCCESS) { goto end_sync; } } @@ -4441,8 +4429,8 @@ end_sync: } rw_lock_x_lock(&cache->lock); - /* Clear fts syncing flags of any indexes incase sync is - interrupeted */ + /* Clear fts syncing flags of any indexes in case sync is + interrupted */ for (i = 0; i < ib_vector_size(cache->indexes); ++i) { static_cast<fts_index_cache_t*>( ib_vector_get(cache->indexes, i)) diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index 4d93451a40d..77115049903 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -62,12 +62,6 @@ static const ulint FTS_WORD_NODES_INIT_SIZE = 64; /** Last time we did check whether system need a sync */ static ib_time_t last_check_sync_time; -#if 0 -/** Check each table in round robin to see whether they'd -need to be "optimized" */ -static ulint fts_optimize_sync_iterator = 0; -#endif - /** State of a table within the optimization sub system. */ enum fts_state_t { FTS_STATE_LOADED, @@ -79,17 +73,11 @@ enum fts_state_t { /** FTS optimize thread message types. */ enum fts_msg_type_t { - FTS_MSG_START, /*!< Start optimizing thread */ - - FTS_MSG_PAUSE, /*!< Pause optimizing thread */ - FTS_MSG_STOP, /*!< Stop optimizing and exit thread */ FTS_MSG_ADD_TABLE, /*!< Add table to the optimize thread's work queue */ - FTS_MSG_OPTIMIZE_TABLE, /*!< Optimize a table */ - FTS_MSG_DEL_TABLE, /*!< Remove a table from the optimize threads work queue */ FTS_MSG_SYNC_TABLE /*!< Sync fts cache of a table */ @@ -234,7 +222,7 @@ struct fts_msg_t { /** The number of words to read and optimize in a single pass. */ ulong fts_num_word_optimize; -// FIXME +/** Whether to enable additional FTS diagnostic printout. */ char fts_enable_diag_print; /** ZLib compressed block size.*/ @@ -2554,12 +2542,9 @@ fts_optimize_create_msg( return(msg); } -/**********************************************************************//** -Add the table to add to the OPTIMIZER's list. */ -void -fts_optimize_add_table( -/*===================*/ - dict_table_t* table) /*!< in: table to add */ +/** Add the table to add to the OPTIMIZER's list. +@param[in] table table to add */ +void fts_optimize_add_table(dict_table_t* table) { fts_msg_t* msg; @@ -2575,28 +2560,6 @@ fts_optimize_add_table( ib_wqueue_add(fts_optimize_wq, msg, msg->heap); } -#if 0 -/**********************************************************************//** -Optimize a table. */ -static -void -fts_optimize_do_table( -/*==================*/ - dict_table_t* table) /*!< in: table to optimize */ -{ - fts_msg_t* msg; - - /* Optimizer thread could be shutdown */ - if (!fts_optimize_wq) { - return; - } - - msg = fts_optimize_create_msg(FTS_MSG_OPTIMIZE_TABLE, table); - - ib_wqueue_add(fts_optimize_wq, msg, msg->heap); -} -#endif - /**********************************************************************//** Remove the table from the OPTIMIZER's list. We do wait for acknowledgement from the consumer of the message. */ @@ -2672,53 +2635,6 @@ fts_optimize_request_sync_table( } /**********************************************************************//** -Find the slot for a particular table. -@return slot if found else NULL. */ -static -fts_slot_t* -fts_optimize_find_slot( -/*===================*/ - ib_vector_t* tables, /*!< in: vector of tables */ - const dict_table_t* table) /*!< in: table to add */ -{ - ulint i; - - for (i = 0; i < ib_vector_size(tables); ++i) { - fts_slot_t* slot; - - slot = static_cast<fts_slot_t*>(ib_vector_get(tables, i)); - - if (slot->table == table) { - return(slot); - } - } - - return(NULL); -} - -/**********************************************************************//** -Start optimizing table. */ -static -void -fts_optimize_start_table( -/*=====================*/ - ib_vector_t* tables, /*!< in/out: vector of tables */ - dict_table_t* table) /*!< in: table to optimize */ -{ - fts_slot_t* slot; - - slot = fts_optimize_find_slot(tables, table); - - if (slot == NULL) { - ib::error() << "Table " << table->name << " not registered" - " with the optimize thread."; - } else { - slot->last_run = 0; - slot->completed = 0; - } -} - -/**********************************************************************//** Add the table to the vector if it doesn't already exist. */ static ibool @@ -2900,57 +2816,6 @@ fts_is_sync_needed( return(false); } -#if 0 -/*********************************************************************//** -Check whether a table needs to be optimized. */ -static -void -fts_optimize_need_sync( -/*===================*/ - ib_vector_t* tables) /*!< in: list of tables */ -{ - dict_table_t* table = NULL; - fts_slot_t* slot; - ulint num_table = ib_vector_size(tables); - - if (!num_table) { - return; - } - - if (fts_optimize_sync_iterator >= num_table) { - fts_optimize_sync_iterator = 0; - } - - slot = ib_vector_get(tables, fts_optimize_sync_iterator); - table = slot->table; - - if (!table) { - return; - } - - ut_ad(table->fts); - - if (table->fts->cache) { - ulint deleted = table->fts->cache->deleted; - - if (table->fts->cache->added - >= fts_optimize_add_threshold) { - fts_sync_table(table); - } else if (deleted >= fts_optimize_delete_threshold) { - fts_optimize_do_table(table); - - mutex_enter(&table->fts->cache->deleted_lock); - table->fts->cache->deleted -= deleted; - mutex_exit(&table->fts->cache->deleted_lock); - } - } - - fts_optimize_sync_iterator++; - - return; -} -#endif - /** Sync fts cache of a table @param[in] table_id table id */ void @@ -2963,7 +2828,7 @@ fts_optimize_sync_table( if (table) { if (dict_table_has_fts_index(table) && table->fts->cache) { - fts_sync_table(table, true, false, true); + fts_sync_table(table, true, false, false); } dict_table_close(table, FALSE, FALSE); @@ -3031,8 +2896,7 @@ DECLARE_THREAD(fts_optimize_thread)( fts_msg_t* msg; msg = static_cast<fts_msg_t*>( - ib_wqueue_timedwait(wq, - FTS_QUEUE_WAIT_IN_USECS)); + ib_wqueue_timedwait(wq, FTS_QUEUE_WAIT_IN_USECS)); /* Timeout ? */ if (msg == NULL) { @@ -3044,12 +2908,6 @@ DECLARE_THREAD(fts_optimize_thread)( } switch (msg->type) { - case FTS_MSG_START: - break; - - case FTS_MSG_PAUSE: - break; - case FTS_MSG_STOP: done = TRUE; break; @@ -3064,15 +2922,6 @@ DECLARE_THREAD(fts_optimize_thread)( } break; - case FTS_MSG_OPTIMIZE_TABLE: - if (!done) { - fts_optimize_start_table( - fts_slots, - static_cast<dict_table_t*>( - msg->ptr)); - } - break; - case FTS_MSG_DEL_TABLE: if (fts_optimize_del_table( fts_slots, static_cast<fts_msg_del_t*>( @@ -3087,6 +2936,10 @@ DECLARE_THREAD(fts_optimize_thread)( break; case FTS_MSG_SYNC_TABLE: + DBUG_EXECUTE_IF( + "fts_instrument_msg_sync_sleep", + os_thread_sleep(300000);); + fts_optimize_sync_table( *static_cast<table_id_t*>(msg->ptr)); break; @@ -3149,7 +3002,7 @@ fts_optimize_init(void) ut_ad(!srv_read_only_mode); /* For now we only support one optimize thread. */ - ut_a(fts_optimize_wq == NULL); + ut_a(!fts_optimize_wq); /* Create FTS optimize work queue */ fts_optimize_wq = ib_wqueue_create(); diff --git a/storage/innobase/fts/fts0pars.cc b/storage/innobase/fts/fts0pars.cc index e4d1bba2be6..56cc8d6052c 100644 --- a/storage/innobase/fts/fts0pars.cc +++ b/storage/innobase/fts/fts0pars.cc @@ -88,7 +88,7 @@ extern int fts_lexer(YYSTYPE*, fts_lexer_t*); extern int fts_blexer(YYSTYPE*, yyscan_t); extern int fts_tlexer(YYSTYPE*, yyscan_t); -typedef int (*fts_scan)(); + extern int ftserror(const char* p); @@ -103,8 +103,8 @@ extern int ftserror(const char* p); #define YYTOKENFREE(token) fts_ast_string_free((token)) -typedef int (*fts_scanner_alt)(YYSTYPE* val, yyscan_t yyscanner); -typedef int (*fts_scanner)(); + +typedef int (*fts_scanner)(YYSTYPE* val, yyscan_t yyscanner); struct fts_lexer_t { fts_scanner scanner; @@ -1948,7 +1948,7 @@ fts_lexer_create( reinterpret_cast<const char*>(query), static_cast<int>(query_len), fts_lexer->yyscanner); - fts_lexer->scanner = reinterpret_cast<fts_scan>(fts_blexer); + fts_lexer->scanner = fts_blexer; /* FIXME: Debugging */ /* fts0bset_debug(1 , fts_lexer->yyscanner); */ } else { @@ -1957,7 +1957,7 @@ fts_lexer_create( reinterpret_cast<const char*>(query), static_cast<int>(query_len), fts_lexer->yyscanner); - fts_lexer->scanner = reinterpret_cast<fts_scan>(fts_tlexer); + fts_lexer->scanner = fts_tlexer; } return(fts_lexer); @@ -1971,7 +1971,7 @@ fts_lexer_free( /*===========*/ fts_lexer_t* fts_lexer) { - if (fts_lexer->scanner == (fts_scan) fts_blexer) { + if (fts_lexer->scanner == fts_blexer) { fts0blex_destroy(fts_lexer->yyscanner); } else { fts0tlex_destroy(fts_lexer->yyscanner); @@ -1988,9 +1988,9 @@ fts_lexer( YYSTYPE* val, fts_lexer_t* fts_lexer) { - fts_scanner_alt func_ptr; + fts_scanner func_ptr; - func_ptr = (fts_scanner_alt) fts_lexer->scanner; + func_ptr = fts_lexer->scanner; return(func_ptr(val, fts_lexer->yyscanner)); } diff --git a/storage/innobase/fts/fts0pars.y b/storage/innobase/fts/fts0pars.y index 1f4ec9922e3..4db72ca65ad 100644 --- a/storage/innobase/fts/fts0pars.y +++ b/storage/innobase/fts/fts0pars.y @@ -36,7 +36,7 @@ extern int fts_lexer(YYSTYPE*, fts_lexer_t*); extern int fts_blexer(YYSTYPE*, yyscan_t); extern int fts_tlexer(YYSTYPE*, yyscan_t); -typedef int (*fts_scan)(); + extern int ftserror(const char* p); @@ -49,8 +49,8 @@ extern int ftserror(const char* p); #define YYPARSE_PARAM state #define YYLEX_PARAM ((fts_ast_state_t*) state)->lexer -typedef int (*fts_scanner_alt)(YYSTYPE* val, yyscan_t yyscanner); -typedef int (*fts_scanner)(); + +typedef int (*fts_scanner)(YYSTYPE* val, yyscan_t yyscanner); struct fts_lexer_struct { fts_scanner scanner; @@ -238,13 +238,13 @@ fts_lexer_create( if (boolean_mode) { fts0blex_init(&fts_lexer->yyscanner); fts0b_scan_bytes((char*) query, (int) query_len, fts_lexer->yyscanner); - fts_lexer->scanner = (fts_scan) fts_blexer; + fts_lexer->scanner = fts_blexer; /* FIXME: Debugging */ /* fts0bset_debug(1 , fts_lexer->yyscanner); */ } else { fts0tlex_init(&fts_lexer->yyscanner); fts0t_scan_bytes((char*) query, (int) query_len, fts_lexer->yyscanner); - fts_lexer->scanner = (fts_scan) fts_tlexer; + fts_lexer->scanner = fts_tlexer; } return(fts_lexer); @@ -258,7 +258,7 @@ fts_lexer_free( /*===========*/ fts_lexer_t* fts_lexer) { - if (fts_lexer->scanner == (fts_scan) fts_blexer) { + if (fts_lexer->scanner == fts_blexer) { fts0blex_destroy(fts_lexer->yyscanner); } else { fts0tlex_destroy(fts_lexer->yyscanner); @@ -275,9 +275,9 @@ fts_lexer( YYSTYPE* val, fts_lexer_t* fts_lexer) { - fts_scanner_alt func_ptr; + fts_scanner func_ptr; - func_ptr = (fts_scanner_alt) fts_lexer->scanner; + func_ptr = fts_lexer->scanner; return(func_ptr(val, fts_lexer->yyscanner)); } diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc index 6a0496bedcd..5ae8e28974e 100644 --- a/storage/innobase/fts/fts0que.cc +++ b/storage/innobase/fts/fts0que.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2007, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -3920,6 +3920,7 @@ fts_query_can_optimize( } /** FTS Query entry point. +@param[in,out] trx transaction @param[in] index fts index to search @param[in] flags FTS search mode @param[in] query_str FTS query @@ -3928,6 +3929,7 @@ fts_query_can_optimize( @return DB_SUCCESS if successful otherwise error code */ dberr_t fts_query( + trx_t* trx, dict_index_t* index, uint flags, const byte* query_str, @@ -3940,7 +3942,7 @@ fts_query( ulint lc_query_str_len; ulint result_len; bool boolean_mode; - trx_t* query_trx; + trx_t* query_trx; /* FIXME: use provided trx */ CHARSET_INFO* charset; ulint start_time_ms; bool will_be_ignored = false; @@ -4055,6 +4057,7 @@ fts_query( /* Parse the input query string. */ if (fts_query_parse(&query, lc_query_str, result_len)) { fts_ast_node_t* ast = query.root; + ast->trx = trx; /* Optimize query to check if it's a single term */ fts_query_can_optimize(&query, flags); @@ -4068,6 +4071,11 @@ fts_query( query.error = fts_ast_visit( FTS_NONE, ast, fts_query_visitor, &query, &will_be_ignored); + if (query.error == DB_INTERRUPTED) { + error = DB_INTERRUPTED; + ut_free(lc_query_str); + goto func_exit; + } /* If query expansion is requested, extend the search with first search pass result */ @@ -4094,6 +4102,15 @@ fts_query( ut_zalloc_nokey(sizeof(**result))); } + if (trx_is_interrupted(trx)) { + error = DB_INTERRUPTED; + ut_free(lc_query_str); + if (*result) { + fts_query_free_result(*result); + } + goto func_exit; + } + ut_free(lc_query_str); if (fts_enable_diag_print && (*result)) { diff --git a/storage/innobase/gis/gis0rtree.cc b/storage/innobase/gis/gis0rtree.cc index eac904e5b24..146d1616347 100644 --- a/storage/innobase/gis/gis0rtree.cc +++ b/storage/innobase/gis/gis0rtree.cc @@ -658,7 +658,7 @@ rtr_adjust_upper_level( /* Create a memory heap where the data tuple is stored */ heap = mem_heap_create(1024); - memset(&cursor, 0, sizeof(cursor)); + cursor.init(); cursor.thr = sea_cur->thr; @@ -1367,7 +1367,7 @@ rtr_ins_enlarge_mbr( rtr_page_cal_mbr(index, block, &new_mbr, heap); /* Get father block. */ - memset(&cursor, 0, sizeof(cursor)); + cursor.init(); offsets = rtr_page_get_father_block( NULL, heap, index, block, mtr, btr_cur, &cursor); diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc index 67b2feb7af6..b137a768830 100644 --- a/storage/innobase/gis/gis0sea.cc +++ b/storage/innobase/gis/gis0sea.cc @@ -1546,7 +1546,7 @@ rtr_copy_buf( will be copied. It is also undefined what will happen with the newly memcpy()ed mutex if the source mutex was acquired by (another) thread while it was copied. */ - memcpy(&matches->block.page, &block->page, sizeof(buf_page_t)); + new (&matches->block.page) buf_page_t(block->page); matches->block.frame = block->frame; matches->block.unzip_LRU = block->unzip_LRU; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 2b7c700dd55..e2b61b627de 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -5324,15 +5324,16 @@ ha_innobase::max_supported_key_length() const switch (srv_page_size) { case 4096: - return(768); + /* Hack: allow mysql.innodb_index_stats to be created. */ + /* FIXME: rewrite this API, and in sql_table.cc consider + that in index-organized tables (such as InnoDB), secondary + index records will be padded with the PRIMARY KEY, instead + of some short ROWID or record heap address. */ + return(1173); case 8192: return(1536); default: -#ifdef WITH_WSREP - return(3500); -#else return(3500); -#endif } } @@ -10071,8 +10072,7 @@ ha_innobase::ft_init_ext( const_cast<char*>(query)); // FIXME: support ft_init_ext_with_hints(), pass LIMIT - // FIXME: use trx - dberr_t error = fts_query(index, flags, q, query_len, &result); + dberr_t error = fts_query(trx, index, flags, q, query_len, &result); if (error != DB_SUCCESS) { my_error(convert_error_code_to_mysql(error, 0, NULL), MYF(0)); @@ -13266,6 +13266,36 @@ innobase_rename_table( row_mysql_lock_data_dictionary(trx); + dict_table_t* table = dict_table_open_on_name(norm_from, TRUE, FALSE, + DICT_ERR_IGNORE_NONE); + + /* Since DICT_BG_YIELD has sleep for 250 milliseconds, + Convert lock_wait_timeout unit from second to 250 milliseconds */ + long int lock_wait_timeout = thd_lock_wait_timeout(trx->mysql_thd) * 4; + if (table != NULL) { + for (dict_index_t* index = dict_table_get_first_index(table); + index != NULL; + index = dict_table_get_next_index(index)) { + + if (index->type & DICT_FTS) { + /* Found */ + while (index->index_fts_syncing + && !trx_is_interrupted(trx) + && (lock_wait_timeout--) > 0) { + DICT_BG_YIELD(trx); + } + } + } + dict_table_close(table, TRUE, FALSE); + } + + /* FTS sync is in progress. We shall timeout this operation */ + if (lock_wait_timeout < 0) { + error = DB_LOCK_WAIT_TIMEOUT; + row_mysql_unlock_data_dictionary(trx); + DBUG_RETURN(error); + } + error = row_rename_table_for_mysql(norm_from, norm_to, trx, TRUE); if (error != DB_SUCCESS) { @@ -13395,6 +13425,10 @@ ha_innobase::rename_table( my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to); error = DB_ERROR; + } else if (error == DB_LOCK_WAIT_TIMEOUT) { + my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0), to); + + error = DB_LOCK_WAIT; } DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL)); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 3f251b2f6f6..a8cbee11c8e 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -9431,24 +9431,24 @@ ha_innobase::commit_inplace_alter_table( trx_t* trx = ctx0->trx; bool fail = false; - if (new_clustered) { - for (inplace_alter_handler_ctx** pctx = ctx_array; - *pctx; pctx++) { - ha_innobase_inplace_ctx* ctx - = static_cast<ha_innobase_inplace_ctx*>(*pctx); - DBUG_ASSERT(ctx->need_rebuild()); + /* Stop background FTS operations. */ + for (inplace_alter_handler_ctx** pctx = ctx_array; + *pctx; pctx++) { + ha_innobase_inplace_ctx* ctx + = static_cast<ha_innobase_inplace_ctx*>(*pctx); + + DBUG_ASSERT(new_clustered == ctx->need_rebuild()); + if (new_clustered) { if (ctx->old_table->fts) { ut_ad(!ctx->old_table->fts->add_wq); - fts_optimize_remove_table( - ctx->old_table); + fts_optimize_remove_table(ctx->old_table); } + } - if (ctx->new_table->fts) { - ut_ad(!ctx->new_table->fts->add_wq); - fts_optimize_remove_table( - ctx->new_table); - } + if (ctx->new_table->fts) { + ut_ad(!ctx->new_table->fts->add_wq); + fts_optimize_remove_table(ctx->new_table); } } @@ -9495,41 +9495,39 @@ ha_innobase::commit_inplace_alter_table( /* Make a concurrent Drop fts Index to wait until sync of that fts index is happening in the background */ - for (;;) { + for (int retry_count = 0;;) { bool retry = false; for (inplace_alter_handler_ctx** pctx = ctx_array; *pctx; pctx++) { - int count =0; ha_innobase_inplace_ctx* ctx = static_cast<ha_innobase_inplace_ctx*>(*pctx); DBUG_ASSERT(new_clustered == ctx->need_rebuild()); if (dict_fts_index_syncing(ctx->old_table)) { - count++; - if (count == 100) { - fprintf(stderr, - "Drop index waiting for background sync" - "to finish\n"); - } retry = true; + break; } if (new_clustered && dict_fts_index_syncing(ctx->new_table)) { - count++; - if (count == 100) { - fprintf(stderr, - "Drop index waiting for background sync" - "to finish\n"); - } retry = true; + break; } } - if (!retry) { + if (!retry) { break; } + /* Print a message if waiting for a long time. */ + if (retry_count < 100) { + retry_count++; + } else { + ib::info() << "Drop index waiting for background sync" + " to finish"; + retry_count = 0; + } + DICT_BG_YIELD(trx); } @@ -9806,6 +9804,11 @@ foreign_fail: ut_a(fts_check_cached_index(ctx->old_table)); DBUG_INJECT_CRASH("ib_commit_inplace_crash_fail", crash_fail_inject_count++); + + /* Restart the FTS background operations. */ + if (ctx->old_table->fts) { + fts_optimize_add_table(ctx->old_table); + } } row_mysql_unlock_data_dictionary(trx); @@ -9889,8 +9892,6 @@ foreign_fail: (*pctx); DBUG_ASSERT(ctx->need_rebuild() == new_clustered); - bool add_fts = false; - /* Publish the created fulltext index, if any. Note that a fulltext index can be created without creating the clustered index, if there already exists @@ -9905,14 +9906,14 @@ foreign_fail: is left unset when a drop proceeds the add. */ DICT_TF2_FLAG_SET(ctx->new_table, DICT_TF2_FTS); fts_add_index(index, ctx->new_table); - add_fts = true; } } ut_d(dict_table_check_for_dup_indexes( ctx->new_table, CHECK_ALL_COMPLETE)); - if (add_fts) { + /* Start/Restart the FTS background operations. */ + if (ctx->new_table->fts) { fts_optimize_add_table(ctx->new_table); } diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 25dd9e9993d..f0df1bc9839 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -1359,12 +1359,14 @@ i_s_cmp_fill_low( page0zip.cc. */ table->field[1]->store(zip_stat->compressed, true); table->field[2]->store(zip_stat->compressed_ok, true); - table->field[3]->store(zip_stat->compressed_usec / 1000000, true); + table->field[3]->store(zip_stat->compressed_usec / 1000000, + true); table->field[4]->store(zip_stat->decompressed, true); - table->field[5]->store(zip_stat->decompressed_usec / 1000000, true); + table->field[5]->store(zip_stat->decompressed_usec / 1000000, + true); if (reset) { - memset(zip_stat, 0, sizeof *zip_stat); + new (zip_stat) page_zip_stat_t(); } if (schema_table_store_record(thd, table)) { diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h index dc1f6dd82d8..f87370be70c 100644 --- a/storage/innobase/include/btr0cur.h +++ b/storage/innobase/include/btr0cur.h @@ -955,6 +955,26 @@ struct btr_cur_t { rtr_info_t* rtr_info; /*!< rtree search info */ btr_cur_t():thr(NULL), rtr_info(NULL) {} /* default values */ + /** Zero-initialize all fields */ + void init() + { + index = NULL; + memset(&page_cur, 0, sizeof page_cur); + purge_node = NULL; + left_block = NULL; + thr = NULL; + flag = btr_cur_method(0); + tree_height = 0; + up_match = 0; + up_bytes = 0; + low_match = 0; + low_bytes = 0; + n_fields = 0; + n_bytes = 0; + fold = 0; + path_arr = NULL; + rtr_info = NULL; + } }; /******************************************************//** diff --git a/storage/innobase/include/btr0pcur.h b/storage/innobase/include/btr0pcur.h index f478d3fa876..747ad676e33 100644 --- a/storage/innobase/include/btr0pcur.h +++ b/storage/innobase/include/btr0pcur.h @@ -538,6 +538,18 @@ struct btr_pcur_t{ /** old_rec_buf size if old_rec_buf is not NULL */ ulint buf_size; + btr_pcur_t() : + btr_cur(), latch_mode(0), old_stored(false), old_rec(NULL), + old_n_fields(0), rel_pos(btr_pcur_pos_t(0)), + block_when_stored(NULL), + modify_clock(0), withdraw_clock(0), + pos_state(BTR_PCUR_NOT_POSITIONED), + search_mode(PAGE_CUR_UNSUPP), trx_if_known(NULL), + old_rec_buf(NULL), buf_size(0) + { + btr_cur.init(); + } + /** Return the index of this persistent cursor */ dict_index_t* index() const { return(btr_cur.index); } }; diff --git a/storage/innobase/include/dict0defrag_bg.h b/storage/innobase/include/dict0defrag_bg.h index 8d77a461dc9..ddef139853c 100644 --- a/storage/innobase/include/dict0defrag_bg.h +++ b/storage/innobase/include/dict0defrag_bg.h @@ -33,6 +33,25 @@ Created 25/08/2016 Jan Lindström #include "os0event.h" #include "os0thread.h" + +/** Indices whose defrag stats need to be saved to persistent storage.*/ +struct defrag_pool_item_t { + table_id_t table_id; + index_id_t index_id; +}; + +/** Allocator type, used by std::vector */ +typedef ut_allocator<defrag_pool_item_t> + defrag_pool_allocator_t; + +/** The multitude of tables to be defragmented- an STL vector */ +typedef std::vector<defrag_pool_item_t, defrag_pool_allocator_t> + defrag_pool_t; + +/** Pool where we store information on which tables are to be processed +by background defragmentation. */ +extern defrag_pool_t defrag_pool; + /*****************************************************************//** Initialize the defrag pool, called once during thread initialization. */ void diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 66b64f96128..3dcf290a276 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -1862,14 +1862,6 @@ const char* dict_tf_to_row_format_string( /*=========================*/ ulint table_flag); /*!< in: row format setting */ -/****************************************************************//** -Return maximum size of the node pointer record. -@return maximum size of the record in bytes */ -ulint -dict_index_node_ptr_max_size( -/*=========================*/ - const dict_index_t* index) /*!< in: index */ - MY_ATTRIBUTE((warn_unused_result)); /** encode number of columns and number of virtual columns in one 4 bytes value. We could do this because the number of columns in diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 8d7c9d47e9f..3e06def55b0 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -771,6 +771,9 @@ struct dict_field_t{ column if smaller than DICT_ANTELOPE_MAX_INDEX_COL_LEN */ + /** Zero-initialize all fields */ + dict_field_t() : col(NULL), name(NULL), prefix_len(0), fixed_len(0) {} + /** Check whether two index fields are equivalent. @param[in] old the other index field @return whether the index fields are equivalent */ diff --git a/storage/innobase/include/dict0stats.h b/storage/innobase/include/dict0stats.h index 5dd53c46d1b..407e0221110 100644 --- a/storage/innobase/include/dict0stats.h +++ b/storage/innobase/include/dict0stats.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2009, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2009, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -32,6 +32,9 @@ Created Jan 06, 2010 Vasil Dimov #include "dict0types.h" #include "trx0types.h" +#define TABLE_STATS_NAME "mysql/innodb_table_stats" +#define INDEX_STATS_NAME "mysql/innodb_index_stats" + enum dict_stats_upd_option_t { DICT_STATS_RECALC_PERSISTENT,/* (re) calculate the statistics using a precise and slow @@ -110,12 +113,21 @@ dict_stats_deinit( dict_table_t* table) /*!< in/out: table */ MY_ATTRIBUTE((nonnull)); +#ifdef WITH_WSREP +/** Update the table modification counter and if necessary, +schedule new estimates for table and index statistics to be calculated. +@param[in,out] table persistent or temporary table +@param[in] thd current session */ +void dict_stats_update_if_needed(dict_table_t* table, THD* thd) + MY_ATTRIBUTE((nonnull(1))); +#else /** Update the table modification counter and if necessary, schedule new estimates for table and index statistics to be calculated. @param[in,out] table persistent or temporary table */ -void -dict_stats_update_if_needed(dict_table_t* table) +void dict_stats_update_if_needed_func(dict_table_t* table) MY_ATTRIBUTE((nonnull)); +# define dict_stats_update_if_needed(t,thd) dict_stats_update_if_needed_func(t) +#endif /*********************************************************************//** Calculates new estimates for table and index statistics. The statistics diff --git a/storage/innobase/include/fts0ast.h b/storage/innobase/include/fts0ast.h index b5187ce2a41..2a2b25c36bd 100644 --- a/storage/innobase/include/fts0ast.h +++ b/storage/innobase/include/fts0ast.h @@ -1,6 +1,7 @@ /***************************************************************************** -Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2016, 2018, MariaDB Corporation. 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 @@ -296,6 +297,8 @@ struct fts_ast_node_t { fts_ast_node_t* next_alloc; /*!< For tracking allocations */ bool visited; /*!< whether this node is already processed */ + /** current transaction */ + const trx_t* trx; /* Used by plugin parser */ fts_ast_node_t* up_node; /*!< Direct up node */ bool go_up; /*!< Flag if go one level up */ diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index be2fe7e040b..068720c1947 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2016, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -561,6 +561,7 @@ fts_commit( MY_ATTRIBUTE((warn_unused_result)); /** FTS Query entry point. +@param[in,out] trx transaction @param[in] index fts index to search @param[in] flags FTS search mode @param[in] query_str FTS query @@ -569,6 +570,7 @@ fts_commit( @return DB_SUCCESS if successful otherwise error code */ dberr_t fts_query( + trx_t* trx, dict_index_t* index, uint flags, const byte* query_str, @@ -711,6 +713,12 @@ fts_drop_index_tables( dict_index_t* index) /*!< in: Index to drop */ MY_ATTRIBUTE((warn_unused_result)); +/** Add the table to add to the OPTIMIZER's list. +@param[in] table table to add */ +void +fts_optimize_add_table( + dict_table_t* table); + /******************************************************************//** Remove the table from the OPTIMIZER's list. We do wait for acknowledgement from the consumer of the message. */ diff --git a/storage/innobase/include/fts0priv.h b/storage/innobase/include/fts0priv.h index aef6e816461..d045c9d3c72 100644 --- a/storage/innobase/include/fts0priv.h +++ b/storage/innobase/include/fts0priv.h @@ -1,7 +1,7 @@ /***************************************************************************** -Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, 2018, MariaDB Corporation. 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 @@ -512,13 +512,6 @@ fts_get_table_id( MY_ATTRIBUTE((warn_unused_result)); /******************************************************************//** -Add the table to add to the OPTIMIZER's list. */ -void -fts_optimize_add_table( -/*===================*/ - dict_table_t* table); /*!< in: table to add */ - -/******************************************************************//** Construct the prefix name of an FTS table. @return own: table name, must be freed with ut_free() */ char* diff --git a/storage/innobase/include/row0ftsort.h b/storage/innobase/include/row0ftsort.h index 25204895f1a..3ae5d5bc175 100644 --- a/storage/innobase/include/row0ftsort.h +++ b/storage/innobase/include/row0ftsort.h @@ -122,6 +122,16 @@ struct fts_tokenize_ctx { dfield_t sort_field[FTS_NUM_FIELDS_SORT]; /*!< in: sort field */ fts_token_list_t fts_token_list; + + fts_tokenize_ctx() : + processed_len(0), init_pos(0), buf_used(0), + rows_added(), cached_stopword(NULL), sort_field(), + fts_token_list() + { + memset(rows_added, 0, sizeof rows_added); + memset(sort_field, 0, sizeof sort_field); + UT_LIST_INIT(fts_token_list, &row_fts_token_t::token_list); + } }; typedef struct fts_tokenize_ctx fts_tokenize_ctx_t; diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index ffa4967b9de..bf1d245a65e 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -41,7 +41,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 5 #define INNODB_VERSION_MINOR 7 -#define INNODB_VERSION_BUGFIX 22 +#define INNODB_VERSION_BUGFIX 23 /* The following is the InnoDB version as shown in SELECT plugin_version FROM information_schema.plugins; diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 4d93f2c449c..461dec3ee29 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1750,7 +1750,10 @@ lock_rec_enqueue_waiting( lock_prdt_set_prdt(lock, prdt); } - if (const trx_t* victim = + if ( +#ifdef UNIV_DEBUG + const trx_t* victim = +#endif DeadlockChecker::check_and_resolve(lock, trx)) { ut_ad(victim == trx); lock_reset_lock_and_trx_wait(lock); diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index c6da047e8c5..208fe356fbe 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -2496,30 +2496,15 @@ os_file_fsync_posix( os_thread_sleep(200000); break; - case EIO: - - ++failures; - ut_a(failures < 1000); - - if (!(failures % 100)) { - - ib::warn() - << "fsync(): " - << "An error occurred during " - << "synchronization," - << " retrying"; - } - - /* 0.2 sec */ - os_thread_sleep(200000); - break; - case EINTR: ++failures; ut_a(failures < 2000); break; + case EIO: + ib::error() << "fsync() returned EIO, aborting"; + /* fall through */ default: ut_error; break; @@ -3325,7 +3310,8 @@ os_file_get_status_posix( { int ret = stat(path, statinfo); - if (ret && (errno == ENOENT || errno == ENOTDIR)) { + if (ret && (errno == ENOENT || errno == ENOTDIR + || errno == ENAMETOOLONG)) { /* file does not exist */ return(DB_NOT_FOUND); @@ -4665,7 +4651,8 @@ os_file_get_status_win32( { int ret = _stat64(path, statinfo); - if (ret && (errno == ENOENT || errno == ENOTDIR)) { + if (ret && (errno == ENOENT || errno == ENOTDIR + || errno == ENAMETOOLONG)) { /* file does not exist */ return(DB_NOT_FOUND); diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc index 4341886d775..a351a1ae01b 100644 --- a/storage/innobase/row/row0ftsort.cc +++ b/storage/innobase/row/row0ftsort.cc @@ -805,7 +805,6 @@ DECLARE_THREAD(fts_parallel_tokenization)( merge_file = psort_info->merge_file; blob_heap = mem_heap_create(512); memset(&doc, 0, sizeof(doc)); - memset(&t_ctx, 0, sizeof(t_ctx)); memset(mycount, 0, FTS_NUM_AUX_INDEX * sizeof(int)); doc.charset = fts_index_get_charset( diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 0357804f617..aab445cb197 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2012, 2018, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2015, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -113,19 +113,19 @@ struct row_index_t { struct row_import { row_import() UNIV_NOTHROW : - m_table(), - m_version(), - m_hostname(), - m_table_name(), - m_autoinc(), + m_table(NULL), + m_version(0), + m_hostname(NULL), + m_table_name(NULL), + m_autoinc(0), m_page_size(0, 0, false), - m_flags(), - m_n_cols(), - m_cols(), - m_col_names(), - m_n_indexes(), - m_indexes(), - m_missing(true) {} + m_flags(0), + m_n_cols(0), + m_cols(NULL), + m_col_names(NULL), + m_n_indexes(0), + m_indexes(NULL), + m_missing(true) { } ~row_import() UNIV_NOTHROW; @@ -1227,17 +1227,63 @@ row_import::match_schema( { /* Do some simple checks. */ - if ((m_table->flags ^ m_flags) & ~DICT_TF_MASK_DATA_DIR) { + if (ulint mismatch = (m_table->flags ^ m_flags) + & ~DICT_TF_MASK_DATA_DIR) { + const char* msg; + if (mismatch & DICT_TF_MASK_ZIP_SSIZE) { + if ((m_table->flags & DICT_TF_MASK_ZIP_SSIZE) + && (m_flags & DICT_TF_MASK_ZIP_SSIZE)) { + switch (m_flags & DICT_TF_MASK_ZIP_SSIZE) { + case 0U << DICT_TF_POS_ZIP_SSIZE: + goto uncompressed; + case 1U << DICT_TF_POS_ZIP_SSIZE: + msg = "ROW_FORMAT=COMPRESSED" + " KEY_BLOCK_SIZE=1"; + break; + case 2U << DICT_TF_POS_ZIP_SSIZE: + msg = "ROW_FORMAT=COMPRESSED" + " KEY_BLOCK_SIZE=2"; + break; + case 3U << DICT_TF_POS_ZIP_SSIZE: + msg = "ROW_FORMAT=COMPRESSED" + " KEY_BLOCK_SIZE=4"; + break; + case 4U << DICT_TF_POS_ZIP_SSIZE: + msg = "ROW_FORMAT=COMPRESSED" + " KEY_BLOCK_SIZE=8"; + break; + case 5U << DICT_TF_POS_ZIP_SSIZE: + msg = "ROW_FORMAT=COMPRESSED" + " KEY_BLOCK_SIZE=16"; + break; + default: + msg = "strange KEY_BLOCK_SIZE"; + } + } else if (m_flags & DICT_TF_MASK_ZIP_SSIZE) { + msg = "ROW_FORMAT=COMPRESSED"; + } else { + goto uncompressed; + } + } else { +uncompressed: + msg = (m_flags & DICT_TF_MASK_ATOMIC_BLOBS) + ? "ROW_FORMAT=DYNAMIC" + : (m_flags & DICT_TF_MASK_COMPACT) + ? "ROW_FORMAT=COMPACT" + : "ROW_FORMAT=REDUNDANT"; + } + ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, "Table flags don't match, server table has 0x%x" - " and the meta-data file has 0x" ULINTPFx, - m_table->flags, m_flags); + " and the meta-data file has 0x" ULINTPFx ";" + " .cfg file uses %s", + m_table->flags, m_flags, msg); return(DB_ERROR); } else if (m_table->n_cols != m_n_cols) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, - "Number of columns don't match, table has %u" - " columns but the tablespace meta-data file has " + "Number of columns don't match, table has %u " + "columns but the tablespace meta-data file has " ULINTPF " columns", m_table->n_cols, m_n_cols); @@ -1686,7 +1732,6 @@ PageConverter::update_records( while (!m_rec_iter.end()) { rec_t* rec = m_rec_iter.current(); - ibool deleted = rec_get_deleted_flag(rec, comp); /* For the clustered index we have to adjust the BLOB @@ -2359,8 +2404,6 @@ row_import_cfg_read_index_fields( dict_field_t* field = index->m_fields; - memset(field, 0x0, sizeof(*field) * n_fields); - for (ulint i = 0; i < n_fields; ++i, ++field) { byte* ptr = row; @@ -2378,6 +2421,8 @@ row_import_cfg_read_index_fields( return(DB_IO_ERROR); } + new (field) dict_field_t(); + field->prefix_len = mach_read_from_4(ptr); ptr += sizeof(ib_uint32_t); @@ -3787,8 +3832,6 @@ row_import_for_mysql( row_import cfg; - memset(&cfg, 0x0, sizeof(cfg)); - err = row_import_read_cfg(table, trx->mysql_thd, cfg); /* Check if the table column definitions match the contents diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 37ae828d09d..c6ac98f1082 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1660,7 +1660,8 @@ row_ins_check_foreign_constraint( if (check_table == NULL || !check_table->is_readable() - || check_index == NULL) { + || check_index == NULL + || check_table->space->is_being_truncated) { if (!srv_read_only_mode && check_ref) { FILE* ef = dict_foreign_err_file; diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 49ac2638ef8..a3c3d0eaaa6 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -72,6 +72,13 @@ Created 9/17/2000 Heikki Tuuri #include <deque> #include <vector> +#ifdef WITH_WSREP +#include "mysql/service_wsrep.h" +#include "wsrep.h" +#include "log.h" +#include "wsrep_mysqld.h" +#endif + /** Provide optional 4.x backwards compatibility for 5.0 and above */ ibool row_rollback_on_timeout = FALSE; @@ -1568,7 +1575,7 @@ error_exit: memcpy(prebuilt->row_id, node->sys_buf, DATA_ROW_ID_LEN); } - dict_stats_update_if_needed(table); + dict_stats_update_if_needed(table, trx->mysql_thd); trx->op_info = ""; if (blob_heap != NULL) { @@ -1952,7 +1959,7 @@ row_update_for_mysql(row_prebuilt_t* prebuilt) } if (update_statistics) { - dict_stats_update_if_needed(prebuilt->table); + dict_stats_update_if_needed(prebuilt->table, trx->mysql_thd); } else { /* Always update the table modification counter. */ prebuilt->table->stat_modified_counter++; @@ -2195,7 +2202,7 @@ static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node) case DB_SUCCESS: srv_stats.n_rows_inserted.inc( static_cast<size_t>(trx->id)); - dict_stats_update_if_needed(table); + dict_stats_update_if_needed(table, trx->mysql_thd); goto exit; } } @@ -2288,7 +2295,8 @@ row_update_cascade_for_mysql( } if (stats) { - dict_stats_update_if_needed(node->table); + dict_stats_update_if_needed(node->table, + trx->mysql_thd); } else { /* Always update the table modification counter. */ diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index 79ce3057cd7..e2bbb5a3d5e 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -1156,9 +1156,9 @@ row_purge_record_func( /*==================*/ purge_node_t* node, /*!< in: row purge node */ trx_undo_rec_t* undo_rec, /*!< in: record to purge */ -#ifdef UNIV_DEBUG +#if defined UNIV_DEBUG || defined WITH_WSREP const que_thr_t*thr, /*!< in: query thread */ -#endif /* UNIV_DEBUG */ +#endif /* UNIV_DEBUG || WITH_WSREP */ bool updated_extern) /*!< in: whether external columns were updated */ { @@ -1179,7 +1179,9 @@ row_purge_record_func( if (purged) { if (node->table->stat_initialized && srv_stats_include_delete_marked) { - dict_stats_update_if_needed(node->table); + dict_stats_update_if_needed( + node->table, + thr->graph->trx->mysql_thd); } MONITOR_INC(MONITOR_N_DEL_ROW_PURGE); } @@ -1214,13 +1216,13 @@ row_purge_record_func( return(purged); } -#ifdef UNIV_DEBUG +#if defined UNIV_DEBUG || defined WITH_WSREP # define row_purge_record(node,undo_rec,thr,updated_extern) \ row_purge_record_func(node,undo_rec,thr,updated_extern) -#else /* UNIV_DEBUG */ +#else /* UNIV_DEBUG || WITH_WSREP */ # define row_purge_record(node,undo_rec,thr,updated_extern) \ row_purge_record_func(node,undo_rec,updated_extern) -#endif /* UNIV_DEBUG */ +#endif /* UNIV_DEBUG || WITH_WSREP */ /***********************************************************//** Fetches an undo log record and does the purge for the recorded operation. diff --git a/storage/innobase/row/row0trunc.cc b/storage/innobase/row/row0trunc.cc index abd037e4a49..65170a10f57 100644 --- a/storage/innobase/row/row0trunc.cc +++ b/storage/innobase/row/row0trunc.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2013, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2013, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -1181,6 +1181,11 @@ row_truncate_complete( { bool is_file_per_table = dict_table_is_file_per_table(table); + /* Add the table back to FTS optimize background thread. */ + if (table->fts) { + fts_optimize_add_table(table); + } + row_mysql_unlock_data_dictionary(trx); DEBUG_SYNC_C("ib_trunc_table_trunc_completing"); @@ -1507,6 +1512,9 @@ row_truncate_update_system_tables( /* Reset the Doc ID in cache to 0 */ if (has_internal_doc_id && table->fts->cache != NULL) { + DBUG_EXECUTE_IF("ib_trunc_sleep_before_fts_cache_clear", + os_thread_sleep(10000000);); + table->fts->fts_status |= TABLE_DICT_LOCKED; fts_update_next_doc_id(trx, table, NULL, 0); fts_cache_clear(table->fts->cache); @@ -1754,6 +1762,10 @@ row_truncate_table_for_mysql( } if (!table->is_temporary()) { + if (table->fts) { + fts_optimize_remove_table(table); + } + trx_set_dict_operation(trx, TRX_DICT_OP_TABLE); } diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc index cbcb4eb8d1d..2067e957f3c 100644 --- a/storage/innobase/row/row0uins.cc +++ b/storage/innobase/row/row0uins.cc @@ -273,8 +273,6 @@ row_undo_ins_remove_sec_low( enum row_search_result search_result; const bool modify_leaf = mode == BTR_MODIFY_LEAF; - memset(&pcur, 0, sizeof(pcur)); - row_mtr_start(&mtr, index, !modify_leaf); if (modify_leaf) { @@ -631,7 +629,8 @@ row_undo_ins( already be holding dict_sys->mutex, which would be acquired when updating statistics. */ if (!dict_locked) { - dict_stats_update_if_needed(node->table); + dict_stats_update_if_needed( + node->table, node->trx->mysql_thd); } } } diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index 64d771d7d94..90bce6c8be6 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -1351,7 +1351,8 @@ rollback_clust: already be holding dict_sys->mutex, which would be acquired when updating statistics. */ if (update_statistics && !dict_locked) { - dict_stats_update_if_needed(node->table); + dict_stats_update_if_needed( + node->table, node->trx->mysql_thd); } else { node->table->stat_modified_counter++; } diff --git a/storage/innobase/sync/sync0rw.cc b/storage/innobase/sync/sync0rw.cc index ab4814f3177..d5b0537c095 100644 --- a/storage/innobase/sync/sync0rw.cc +++ b/storage/innobase/sync/sync0rw.cc @@ -1042,86 +1042,52 @@ rw_lock_own( return(false); } -/** For collecting the debug information for a thread's rw-lock */ -typedef std::vector<rw_lock_debug_t*> Infos; - -/** Get the thread debug info -@param[in] infos The rw-lock mode owned by the threads -@param[in] lock rw-lock to check -@return the thread debug info or NULL if not found */ -void -rw_lock_get_debug_info(const rw_lock_t* lock, Infos* infos) -{ - rw_lock_debug_t* info = NULL; - - ut_ad(rw_lock_validate(lock)); - - rw_lock_debug_mutex_enter(); - - for (info = UT_LIST_GET_FIRST(lock->debug_list); - info != NULL; - info = UT_LIST_GET_NEXT(list, info)) { - - if (os_thread_eq(info->thread_id, os_thread_get_curr_id())) { - - infos->push_back(info); - } - } - - rw_lock_debug_mutex_exit(); -} - /** Checks if the thread has locked the rw-lock in the specified mode, with the pass value == 0. @param[in] lock rw-lock @param[in] flags specify lock types with OR of the rw_lock_flag_t values @return true if locked */ -bool -rw_lock_own_flagged( - const rw_lock_t* lock, - rw_lock_flags_t flags) +bool rw_lock_own_flagged(const rw_lock_t* lock, rw_lock_flags_t flags) { - Infos infos; - - rw_lock_get_debug_info(lock, &infos); - - Infos::const_iterator end = infos.end(); - - for (Infos::const_iterator it = infos.begin(); it != end; ++it) { + ut_ad(rw_lock_validate(lock)); - const rw_lock_debug_t* info = *it; + rw_lock_debug_mutex_enter(); - if (info->pass) { + for (rw_lock_debug_t* info = UT_LIST_GET_FIRST(lock->debug_list); + info != NULL; + info = UT_LIST_GET_NEXT(list, info)) { + if (!os_thread_eq(info->thread_id, os_thread_get_curr_id()) + || info->pass) { continue; } - ut_ad(os_thread_eq(info->thread_id, os_thread_get_curr_id())); - switch (info->lock_type) { case RW_LOCK_S: - - if (flags & RW_LOCK_FLAG_S) { - return(true); + if (!(flags & RW_LOCK_FLAG_S)) { + continue; } break; case RW_LOCK_X: - - if (flags & RW_LOCK_FLAG_X) { - return(true); + if (!(flags & RW_LOCK_FLAG_X)) { + continue; } break; case RW_LOCK_SX: - - if (flags & RW_LOCK_FLAG_SX) { - return(true); + if (!(flags & RW_LOCK_FLAG_SX)) { + continue; } + break; } + + rw_lock_debug_mutex_exit(); + return true; } - return(false); + rw_lock_debug_mutex_exit(); + return false; } /***************************************************************//** @@ -1222,28 +1188,31 @@ rw_lock_t::locked_from() const the same thread can call X lock recursively. */ std::ostringstream msg; - Infos infos; + bool written = false; - rw_lock_get_debug_info(this, &infos); + ut_ad(rw_lock_validate(this)); - ulint i = 0; - Infos::const_iterator end = infos.end(); - - for (Infos::const_iterator it = infos.begin(); it != end; ++it, ++i) { - - const rw_lock_debug_t* info = *it; + rw_lock_debug_mutex_enter(); - ut_ad(os_thread_eq(info->thread_id, os_thread_get_curr_id())); + for (rw_lock_debug_t* info = UT_LIST_GET_FIRST(debug_list); + info != NULL; + info = UT_LIST_GET_NEXT(list, info)) { + if (!os_thread_eq(info->thread_id, os_thread_get_curr_id())) { + continue; + } - if (i > 0) { + if (written) { msg << ", "; } + written = true; + msg << info->file_name << ":" << info->line; } - return(msg.str()); + rw_lock_debug_mutex_exit(); + return(msg.str()); } /** Print the rw-lock information. diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc index 81ad85dca7d..0e56af81ed4 100644 --- a/storage/innobase/trx/trx0rseg.cc +++ b/storage/innobase/trx/trx0rseg.cc @@ -545,9 +545,7 @@ trx_rseg_array_init() *trx_sys.recovered_binlog_filename = '\0'; trx_sys.recovered_binlog_offset = 0; #ifdef WITH_WSREP - memset(&trx_sys.recovered_wsrep_xid, 0, - sizeof trx_sys.recovered_wsrep_xid); - trx_sys.recovered_wsrep_xid.formatID = -1; + trx_sys.recovered_wsrep_xid.null(); #endif for (ulint rseg_id = 0; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) { diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index c13ccdf53ed..5b3e4f04bd5 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -955,8 +955,7 @@ trx_start_low( } #ifdef WITH_WSREP - memset(trx->xid, 0, sizeof(xid_t)); - trx->xid->formatID = -1; + trx->xid->null(); #endif /* WITH_WSREP */ /* The initial value for trx->no: TRX_ID_MAX is used in diff --git a/storage/mroonga/vendor/groonga/config.h.cmake b/storage/mroonga/vendor/groonga/config.h.cmake index bfd0cbdc012..ec67c5eea23 100644 --- a/storage/mroonga/vendor/groonga/config.h.cmake +++ b/storage/mroonga/vendor/groonga/config.h.cmake @@ -107,6 +107,7 @@ #cmakedefine HAVE_SIGNAL_H #cmakedefine HAVE_SYS_MMAN_H #cmakedefine HAVE_SYS_PARAM_H +#cmakedefine HAVE_SYS_POLL_H #cmakedefine HAVE_SYS_RESOURCE_H #cmakedefine HAVE_SYS_SELECT_H #cmakedefine HAVE_SYS_SOCKET_H diff --git a/storage/mroonga/vendor/groonga/lib/ts/ts_expr_node.c b/storage/mroonga/vendor/groonga/lib/ts/ts_expr_node.c index 44378cfae25..a3d838c327f 100644 --- a/storage/mroonga/vendor/groonga/lib/ts/ts_expr_node.c +++ b/storage/mroonga/vendor/groonga/lib/ts/ts_expr_node.c @@ -562,7 +562,7 @@ inline static grn_ts_bool grn_ts_op_not_equal_float(grn_ts_float lhs, grn_ts_float rhs) { /* To suppress warnings, "lhs != rhs" is not used. */ - return (lhs < rhs) || (lhs > rhs); + return !grn_ts_op_equal_float(lhs, rhs); } /* grn_ts_op_not_equal_time() returns lhs != rhs. */ diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 2ad81f85e7e..d9b34c86095 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2000, 2018, Oracle and/or its affiliates. Copyright (c) 2009, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify @@ -1330,10 +1330,14 @@ int ha_myisam::repair(THD *thd, HA_CHECK ¶m, bool do_optimize) if (file->s->base.auto_key) update_auto_increment_key(¶m, file, 1); if (optimize_done) + { + mysql_mutex_lock(&share->intern_lock); error = update_state_info(¶m, file, UPDATE_TIME | UPDATE_OPEN_COUNT | (local_testflag & T_STATISTICS ? UPDATE_STAT : 0)); + mysql_mutex_unlock(&share->intern_lock); + } info(HA_STATUS_NO_LOCK | HA_STATUS_TIME | HA_STATUS_VARIABLE | HA_STATUS_CONST); if (rows != file->state->records && ! (param.testflag & T_VERY_SILENT)) diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index a73f999fc05..eab001c995a 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. +/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. 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 @@ -4475,6 +4475,10 @@ int update_state_info(HA_CHECK *param, MI_INFO *info,uint update) int error; uint r_locks=share->r_locks,w_locks=share->w_locks; share->r_locks= share->w_locks= share->tot_locks= 0; + + DBUG_EXECUTE_IF("simulate_incorrect_share_wlock_value", + DEBUG_SYNC_C("after_share_wlock_set_to_0");); + error=_mi_writeinfo(info,WRITEINFO_NO_UNLOCK); share->r_locks=r_locks; share->w_locks=w_locks; diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c index d2c74cf9980..b348429fd3c 100644 --- a/storage/myisam/mi_locking.c +++ b/storage/myisam/mi_locking.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2009, 2018, MariaDB Corporation This program is free software; you can redistribute it and/or modify @@ -236,6 +236,10 @@ int mi_lock_database(MI_INFO *info, int lock_type) info->invalidator=info->s->invalidator; share->w_locks++; share->tot_locks++; + + DBUG_EXECUTE_IF("simulate_incorrect_share_wlock_value", + DEBUG_SYNC_C("after_share_wlock_increment");); + info->s->in_use= list_add(info->s->in_use, &info->in_use); break; default: diff --git a/storage/rocksdb/build_rocksdb.cmake b/storage/rocksdb/build_rocksdb.cmake index 8f01024be63..0f1b77e255d 100644 --- a/storage/rocksdb/build_rocksdb.cmake +++ b/storage/rocksdb/build_rocksdb.cmake @@ -376,7 +376,9 @@ SET(SOURCES) FOREACH(s ${ROCKSDB_SOURCES}) list(APPEND SOURCES ${ROCKSDB_SOURCE_DIR}/${s}) ENDFOREACH() - +IF(MSVC) + add_definitions(-DHAVE_SSE42 -DHAVE_PCLMUL) +ENDIF() IF(CMAKE_VERSION VERSION_GREATER "2.8.10") STRING(TIMESTAMP GIT_DATE_TIME "%Y-%m-%d %H:%M:%S") ENDIF() diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 612fdbab38c..9be1ce43aab 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -218,11 +218,11 @@ static size_t my_case_str_bin(CHARSET_INFO *cs __attribute__((unused)), static size_t my_case_bin(CHARSET_INFO *cs __attribute__((unused)), - char *src __attribute__((unused)), - size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) + const char *src, size_t srclen, + char *dst, size_t dstlen) { + DBUG_ASSERT(srclen <= dstlen); + memcpy(dst, src, srclen); return srclen; } diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index 1af182db9aa..f4f7d041239 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -10028,8 +10028,8 @@ static MY_CHARSET_HANDLER my_charset_handler= my_mb_ctype_mb, my_caseup_str_mb, my_casedn_str_mb, - my_caseup_mb_varlen, /* UPPER() can reduce length: Turkish DOTLESS i -> I */ - my_casedn_mb, /* LOWER() does not change length, use simple version*/ + my_caseup_mb, /* UPPER() can reduce length: Turkish DOTLESS i -> I */ + my_casedn_mb, /* LOWER() does not change length */ my_snprintf_8bit, my_long10_to_str_8bit, my_longlong10_to_str_8bit, diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index 3fd481664fb..1fd80445180 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -71,81 +71,8 @@ get_case_info_for_ch(CHARSET_INFO *cs, uint page, uint offs) /* - For character sets which don't change octet length in case conversion. -*/ -size_t my_caseup_mb(CHARSET_INFO * cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) -{ - register uint32 l; - register char *srcend= src + srclen; - register const uchar *map= cs->to_upper; - - DBUG_ASSERT(cs->caseup_multiply == 1); - DBUG_ASSERT(src == dst && srclen == dstlen); - DBUG_ASSERT(cs->mbmaxlen == 2); - - while (src < srcend) - { - if ((l=my_ismbchar(cs, src, srcend))) - { - MY_UNICASE_CHARACTER *ch; - if ((ch= get_case_info_for_ch(cs, (uchar) src[0], (uchar) src[1]))) - { - *src++= ch->toupper >> 8; - *src++= ch->toupper & 0xFF; - } - else - src+= l; - } - else - { - *src=(char) map[(uchar) *src]; - src++; - } - } - return srclen; -} - - -size_t my_casedn_mb(CHARSET_INFO * cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) -{ - register uint32 l; - register char *srcend= src + srclen; - register const uchar *map=cs->to_lower; - - DBUG_ASSERT(cs->casedn_multiply == 1); - DBUG_ASSERT(src == dst && srclen == dstlen); - DBUG_ASSERT(cs->mbmaxlen == 2); - - while (src < srcend) - { - if ((l= my_ismbchar(cs, src, srcend))) - { - MY_UNICASE_CHARACTER *ch; - if ((ch= get_case_info_for_ch(cs, (uchar) src[0], (uchar) src[1]))) - { - *src++= ch->tolower >> 8; - *src++= ch->tolower & 0xFF; - } - else - src+= l; - } - else - { - *src= (char) map[(uchar)*src]; - src++; - } - } - return srclen; -} - - -/* - Case folding functions for character set - where case conversion can change string octet length. + Case folding functions for CJK character set. + Case conversion can optionally reduce string octet length. For example, in EUCKR, _euckr 0xA9A5 == "LATIN LETTER DOTLESS I" (Turkish letter) is upper-cased to to @@ -153,13 +80,14 @@ size_t my_casedn_mb(CHARSET_INFO * cs, char *src, size_t srclen, Length is reduced in this example from two bytes to one byte. */ static size_t -my_casefold_mb_varlen(CHARSET_INFO *cs, - char *src, size_t srclen, - char *dst, size_t dstlen __attribute__((unused)), - const uchar *map, - size_t is_upper) +my_casefold_mb(CHARSET_INFO *cs, + const char *src, size_t srclen, + char *dst, size_t dstlen __attribute__((unused)), + const uchar *map, + size_t is_upper) { - char *srcend= src + srclen, *dst0= dst; + const char *srcend= src + srclen; + char *dst0= dst; DBUG_ASSERT(cs->mbmaxlen == 2); @@ -193,22 +121,22 @@ my_casefold_mb_varlen(CHARSET_INFO *cs, size_t -my_casedn_mb_varlen(CHARSET_INFO * cs, char *src, size_t srclen, +my_casedn_mb(CHARSET_INFO * cs, const char *src, size_t srclen, char *dst, size_t dstlen) { DBUG_ASSERT(dstlen >= srclen * cs->casedn_multiply); DBUG_ASSERT(src != dst || cs->casedn_multiply == 1); - return my_casefold_mb_varlen(cs, src, srclen, dst, dstlen, cs->to_lower, 0); + return my_casefold_mb(cs, src, srclen, dst, dstlen, cs->to_lower, 0); } size_t -my_caseup_mb_varlen(CHARSET_INFO * cs, char *src, size_t srclen, - char *dst, size_t dstlen) +my_caseup_mb(CHARSET_INFO * cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { DBUG_ASSERT(dstlen >= srclen * cs->caseup_multiply); DBUG_ASSERT(src != dst || cs->caseup_multiply == 1); - return my_casefold_mb_varlen(cs, src, srclen, dst, dstlen, cs->to_upper, 1); + return my_casefold_mb(cs, src, srclen, dst, dstlen, cs->to_upper, 1); } diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 314438bcdf9..518f6f9842f 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -236,28 +236,26 @@ size_t my_casedn_str_8bit(CHARSET_INFO * cs,char *str) } -size_t my_caseup_8bit(CHARSET_INFO * cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) +size_t my_caseup_8bit(CHARSET_INFO * cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { - char *end= src + srclen; + const char *end= src + srclen; register const uchar *map= cs->to_upper; - DBUG_ASSERT(src == dst && srclen == dstlen); + DBUG_ASSERT(srclen <= dstlen); for ( ; src != end ; src++) - *src= (char) map[(uchar) *src]; + *dst++= (char) map[(uchar) *src]; return srclen; } -size_t my_casedn_8bit(CHARSET_INFO * cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) +size_t my_casedn_8bit(CHARSET_INFO * cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { - char *end= src + srclen; + const char *end= src + srclen; register const uchar *map=cs->to_lower; - DBUG_ASSERT(src == dst && srclen == dstlen); + DBUG_ASSERT(srclen <= dstlen); for ( ; src != end ; src++) - *src= (char) map[(uchar) *src]; + *dst++= (char) map[(uchar) *src]; return srclen; } diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 42eeb68c871..7596b7f2168 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1359,25 +1359,26 @@ my_tosort_utf16(MY_UNICASE_INFO *uni_plane, my_wc_t *wc) static size_t -my_caseup_utf16(CHARSET_INFO *cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) +my_caseup_utf16(CHARSET_INFO *cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { my_wc_t wc; my_charset_conv_mb_wc mb_wc= cs->cset->mb_wc; my_charset_conv_wc_mb wc_mb= cs->cset->wc_mb; int res; - char *srcend= src + srclen; + const char *srcend= src + srclen; + char *dstend= dst + dstlen; MY_UNICASE_INFO *uni_plane= cs->caseinfo; - DBUG_ASSERT(src == dst && srclen == dstlen); + DBUG_ASSERT(srclen <= dstlen); while ((src < srcend) && (res= mb_wc(cs, &wc, (uchar *) src, (uchar *) srcend)) > 0) { my_toupper_utf16(uni_plane, &wc); - if (res != wc_mb(cs, wc, (uchar *) src, (uchar *) srcend)) + if (res != wc_mb(cs, wc, (uchar *) dst, (uchar *) dstend)) break; src+= res; + dst+= res; } return srclen; } @@ -1416,25 +1417,26 @@ my_hash_sort_utf16(CHARSET_INFO *cs, const uchar *s, size_t slen, static size_t -my_casedn_utf16(CHARSET_INFO *cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) +my_casedn_utf16(CHARSET_INFO *cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { my_wc_t wc; my_charset_conv_mb_wc mb_wc= cs->cset->mb_wc; my_charset_conv_wc_mb wc_mb= cs->cset->wc_mb; int res; - char *srcend= src + srclen; + const char *srcend= src + srclen; + char *dstend= dst + dstlen; MY_UNICASE_INFO *uni_plane= cs->caseinfo; - DBUG_ASSERT(src == dst && srclen == dstlen); + DBUG_ASSERT(srclen <= dstlen); while ((src < srcend) && (res= mb_wc(cs, &wc, (uchar *) src, (uchar *) srcend)) > 0) { my_tolower_utf16(uni_plane, &wc); - if (res != wc_mb(cs, wc, (uchar *) src, (uchar *) srcend)) + if (res != wc_mb(cs, wc, (uchar *) dst, (uchar *) dstend)) break; src+= res; + dst+= res; } return srclen; } @@ -2231,23 +2233,24 @@ my_lengthsp_utf32(CHARSET_INFO *cs __attribute__((unused)), static size_t -my_caseup_utf32(CHARSET_INFO *cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) +my_caseup_utf32(CHARSET_INFO *cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { my_wc_t wc; int res; - char *srcend= src + srclen; + const char *srcend= src + srclen; + char *dstend= dst + dstlen; MY_UNICASE_INFO *uni_plane= cs->caseinfo; - DBUG_ASSERT(src == dst && srclen == dstlen); + DBUG_ASSERT(srclen <= dstlen); while ((src < srcend) && (res= my_utf32_uni(cs, &wc, (uchar *)src, (uchar*) srcend)) > 0) { my_toupper_utf32(uni_plane, &wc); - if (res != my_uni_utf32(cs, wc, (uchar*) src, (uchar*) srcend)) + if (res != my_uni_utf32(cs, wc, (uchar*) dst, (uchar*) dstend)) break; src+= res; + dst+= res; } return srclen; } @@ -2287,22 +2290,23 @@ my_hash_sort_utf32(CHARSET_INFO *cs, const uchar *s, size_t slen, static size_t -my_casedn_utf32(CHARSET_INFO *cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) +my_casedn_utf32(CHARSET_INFO *cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { my_wc_t wc; int res; - char *srcend= src + srclen; + const char *srcend= src + srclen; + char *dstend= dst + dstlen; MY_UNICASE_INFO *uni_plane= cs->caseinfo; - DBUG_ASSERT(src == dst && srclen == dstlen); + DBUG_ASSERT(srclen <= dstlen); while ((res= my_utf32_uni(cs, &wc, (uchar*) src, (uchar*) srcend)) > 0) { my_tolower_utf32(uni_plane,&wc); - if (res != my_uni_utf32(cs, wc, (uchar*) src, (uchar*) srcend)) + if (res != my_uni_utf32(cs, wc, (uchar*) dst, (uchar*) dstend)) break; src+= res; + dst+= res; } return srclen; } @@ -3081,23 +3085,24 @@ my_tosort_ucs2(MY_UNICASE_INFO *uni_plane, my_wc_t *wc) *wc= page[*wc & 0xFF].sort; } -static size_t my_caseup_ucs2(CHARSET_INFO *cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) +static size_t my_caseup_ucs2(CHARSET_INFO *cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { my_wc_t wc; int res; - char *srcend= src + srclen; + const char *srcend= src + srclen; + char *dstend= dst + dstlen; MY_UNICASE_INFO *uni_plane= cs->caseinfo; - DBUG_ASSERT(src == dst && srclen == dstlen); + DBUG_ASSERT(srclen <= dstlen); while ((src < srcend) && (res= my_ucs2_uni(cs, &wc, (uchar *)src, (uchar*) srcend)) > 0) { my_toupper_ucs2(uni_plane, &wc); - if (res != my_uni_ucs2(cs, wc, (uchar*) src, (uchar*) srcend)) + if (res != my_uni_ucs2(cs, wc, (uchar*) dst, (uchar*) dstend)) break; src+= res; + dst+= res; } return srclen; } @@ -3131,23 +3136,24 @@ static void my_hash_sort_ucs2(CHARSET_INFO *cs, const uchar *s, size_t slen, my_hash_sort_ucs2_nopad(cs, s, lengthsp, nr1, nr2); } -static size_t my_casedn_ucs2(CHARSET_INFO *cs, char *src, size_t srclen, - char *dst __attribute__((unused)), - size_t dstlen __attribute__((unused))) +static size_t my_casedn_ucs2(CHARSET_INFO *cs, const char *src, size_t srclen, + char *dst, size_t dstlen) { my_wc_t wc; int res; - char *srcend= src + srclen; + const char *srcend= src + srclen; + char *dstend= dst + dstlen; MY_UNICASE_INFO *uni_plane= cs->caseinfo; - DBUG_ASSERT(src == dst && srclen == dstlen); + DBUG_ASSERT(srclen <= dstlen); while ((src < srcend) && (res= my_ucs2_uni(cs, &wc, (uchar*) src, (uchar*) srcend)) > 0) { my_tolower_ucs2(uni_plane, &wc); - if (res != my_uni_ucs2(cs, wc, (uchar*) src, (uchar*) srcend)) + if (res != my_uni_ucs2(cs, wc, (uchar*) dst, (uchar*) dstend)) break; src+= res; + dst+= res; } return srclen; } diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index 4c553d15526..2da603687ef 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -67161,12 +67161,12 @@ get_case_info_for_ch(CHARSET_INFO *cs, uint plane, uint page, uint offs) */ static size_t my_casefold_ujis(CHARSET_INFO *cs, - char *src, size_t srclen, + const char *src, size_t srclen, char *dst, size_t dstlen __attribute__((unused)), const uchar * const map, size_t is_upper) { - char *srcend= src + srclen, *dst0= dst; + const char *srcend= src + srclen, *dst0= dst; while (src < srcend) { @@ -67208,7 +67208,7 @@ my_casefold_ujis(CHARSET_INFO *cs, LOWER() */ size_t -my_casedn_ujis(CHARSET_INFO * cs, char *src, size_t srclen, +my_casedn_ujis(CHARSET_INFO * cs, const char *src, size_t srclen, char *dst, size_t dstlen) { DBUG_ASSERT(dstlen >= srclen * cs->casedn_multiply); @@ -67221,7 +67221,7 @@ my_casedn_ujis(CHARSET_INFO * cs, char *src, size_t srclen, UPPER() */ size_t -my_caseup_ujis(CHARSET_INFO * cs, char *src, size_t srclen, +my_caseup_ujis(CHARSET_INFO * cs, const char *src, size_t srclen, char *dst, size_t dstlen) { DBUG_ASSERT(dstlen >= srclen * cs->caseup_multiply); diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index cd6ddaaa196..c525ee97b65 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -5140,12 +5140,13 @@ my_toupper_utf8mb3(MY_UNICASE_INFO *uni_plane, my_wc_t *wc) } -static size_t my_caseup_utf8(CHARSET_INFO *cs, char *src, size_t srclen, +static size_t my_caseup_utf8(CHARSET_INFO *cs, const char *src, size_t srclen, char *dst, size_t dstlen) { my_wc_t wc; int srcres, dstres; - char *srcend= src + srclen, *dstend= dst + dstlen, *dst0= dst; + const char *srcend= src + srclen; + char *dstend= dst + dstlen, *dst0= dst; MY_UNICASE_INFO *uni_plane= cs->caseinfo; DBUG_ASSERT(src != dst || cs->caseup_multiply == 1); @@ -5218,12 +5219,13 @@ static size_t my_caseup_str_utf8(CHARSET_INFO *cs, char *src) } -static size_t my_casedn_utf8(CHARSET_INFO *cs, char *src, size_t srclen, +static size_t my_casedn_utf8(CHARSET_INFO *cs, const char *src, size_t srclen, char *dst, size_t dstlen) { my_wc_t wc; int srcres, dstres; - char *srcend= src + srclen, *dstend= dst + dstlen, *dst0= dst; + const char *srcend= src + srclen; + char *dstend= dst + dstlen, *dst0= dst; MY_UNICASE_INFO *uni_plane= cs->caseinfo; DBUG_ASSERT(src != dst || cs->casedn_multiply == 1); @@ -7567,12 +7569,13 @@ my_toupper_utf8mb4(MY_UNICASE_INFO *uni_plane, my_wc_t *wc) static size_t -my_caseup_utf8mb4(CHARSET_INFO *cs, char *src, size_t srclen, +my_caseup_utf8mb4(CHARSET_INFO *cs, const char *src, size_t srclen, char *dst, size_t dstlen) { my_wc_t wc; int srcres, dstres; - char *srcend= src + srclen, *dstend= dst + dstlen, *dst0= dst; + const char *srcend= src + srclen; + char *dstend= dst + dstlen, *dst0= dst; MY_UNICASE_INFO *uni_plane= cs->caseinfo; DBUG_ASSERT(src != dst || cs->caseup_multiply == 1); @@ -7662,12 +7665,13 @@ my_caseup_str_utf8mb4(CHARSET_INFO *cs, char *src) static size_t my_casedn_utf8mb4(CHARSET_INFO *cs, - char *src, size_t srclen, + const char *src, size_t srclen, char *dst, size_t dstlen) { my_wc_t wc; int srcres, dstres; - char *srcend= src + srclen, *dstend= dst + dstlen, *dst0= dst; + const char *srcend= src + srclen; + char *dstend= dst + dstlen, *dst0= dst; MY_UNICASE_INFO *uni_plane= cs->caseinfo; DBUG_ASSERT(src != dst || cs->casedn_multiply == 1); diff --git a/strings/json_lib.c b/strings/json_lib.c index 57ac3eb15b6..139bd98742f 100644 --- a/strings/json_lib.c +++ b/strings/json_lib.c @@ -1643,6 +1643,8 @@ int json_escape(CHARSET_INFO *str_cs, return -1; } } + else /* c_len == 0, an illegal symbol. */ + return -1; } return (int)(json - json_start); |