summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt6
-rw-r--r--client/mysqlbinlog.cc2
-rw-r--r--cmake/dtrace.cmake4
-rw-r--r--cmake/install_macros.cmake9
-rw-r--r--cmake/mysql_add_executable.cmake3
-rw-r--r--cmake/package_name.cmake3
-rw-r--r--extra/mariabackup/backup_copy.cc30
-rw-r--r--include/m_ctype.h28
-rw-r--r--include/sql_common.h4
-rw-r--r--mysql-test/include/ctype_mdev13118.inc15
-rw-r--r--mysql-test/r/ctype_binary.result23
-rw-r--r--mysql-test/r/ctype_eucjpms.result23
-rw-r--r--mysql-test/r/ctype_euckr.result29
-rw-r--r--mysql-test/r/ctype_gbk.result23
-rw-r--r--mysql-test/r/ctype_latin1.result23
-rw-r--r--mysql-test/r/ctype_ucs.result23
-rw-r--r--mysql-test/r/ctype_ujis.result23
-rw-r--r--mysql-test/r/ctype_utf16.result23
-rw-r--r--mysql-test/r/ctype_utf16le.result29
-rw-r--r--mysql-test/r/ctype_utf32.result23
-rw-r--r--mysql-test/r/ctype_utf8.result23
-rw-r--r--mysql-test/r/ctype_utf8mb4.result23
-rw-r--r--mysql-test/r/derived.result33
-rw-r--r--mysql-test/r/grant.result4
-rw-r--r--mysql-test/r/join.result40
-rw-r--r--mysql-test/r/join_cache.result33
-rw-r--r--mysql-test/r/join_outer.result50
-rw-r--r--mysql-test/r/join_outer_jcl6.result50
-rw-r--r--mysql-test/r/rename.result4
-rw-r--r--mysql-test/r/sp_notembedded.result2
-rw-r--r--mysql-test/r/stat_tables.result129
-rw-r--r--mysql-test/r/stat_tables_innodb.result129
-rw-r--r--mysql-test/r/subselect_mat.result93
-rw-r--r--mysql-test/r/subselect_mat_cost_bugs.result2
-rw-r--r--mysql-test/r/subselect_sj2_mat.result51
-rw-r--r--mysql-test/r/subselect_sj_mat.result93
-rw-r--r--mysql-test/r/union.result16
-rw-r--r--mysql-test/suite/binlog/include/check_binlog_size.inc31
-rw-r--r--mysql-test/suite/binlog/r/binlog_tmp_table_row.result7
-rw-r--r--mysql-test/suite/binlog/t/binlog_tmp_table_row.test30
-rw-r--r--mysql-test/suite/galera/r/galera_bf_background_statistics.result33
-rw-r--r--mysql-test/suite/galera/r/galera_sst_mysqldump_with_key.result90
-rw-r--r--mysql-test/suite/galera/t/galera_bf_background_statistics.opt1
-rw-r--r--mysql-test/suite/galera/t/galera_bf_background_statistics.test49
-rw-r--r--mysql-test/suite/galera/t/galera_sst_mysqldump_with_key.test7
-rw-r--r--mysql-test/suite/innodb/r/default_row_format_compatibility.result2
-rw-r--r--mysql-test/suite/innodb/r/innodb-wl5522.result264
-rw-r--r--mysql-test/suite/innodb/r/row_format_redundant.result2
-rw-r--r--mysql-test/suite/innodb/t/innodb-wl5522.test254
-rw-r--r--mysql-test/suite/innodb_fts/r/fts_kill_query.result9
-rw-r--r--mysql-test/suite/innodb_fts/r/sync_ddl.result117
-rw-r--r--mysql-test/suite/innodb_fts/t/fts_kill_query.test30
-rw-r--r--mysql-test/suite/innodb_fts/t/sync_ddl.test177
-rw-r--r--mysql-test/suite/parts/r/truncate_locked.result7
-rw-r--r--mysql-test/suite/parts/t/truncate_locked.test10
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff-disabled2
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff-disabled6
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_embedded.result14
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result14
-rw-r--r--mysql-test/t/bootstrap.test9
-rw-r--r--mysql-test/t/ctype_binary.test3
-rw-r--r--mysql-test/t/ctype_eucjpms.test2
-rw-r--r--mysql-test/t/ctype_euckr.test10
-rw-r--r--mysql-test/t/ctype_gbk.test3
-rw-r--r--mysql-test/t/ctype_latin1.test3
-rw-r--r--mysql-test/t/ctype_ucs.test4
-rw-r--r--mysql-test/t/ctype_ujis.test4
-rw-r--r--mysql-test/t/ctype_utf16.test5
-rw-r--r--mysql-test/t/ctype_utf16le.test13
-rw-r--r--mysql-test/t/ctype_utf32.test8
-rw-r--r--mysql-test/t/ctype_utf8.test7
-rw-r--r--mysql-test/t/ctype_utf8mb4.test8
-rw-r--r--mysql-test/t/derived.test21
-rw-r--r--mysql-test/t/grant.test3
-rw-r--r--mysql-test/t/join.test53
-rw-r--r--mysql-test/t/join_cache.test32
-rw-r--r--mysql-test/t/join_outer.test48
-rw-r--r--mysql-test/t/rename.test7
-rw-r--r--mysql-test/t/stat_tables.test112
-rw-r--r--mysql-test/t/subselect_sj2_mat.test49
-rw-r--r--mysql-test/t/subselect_sj_mat.test79
-rw-r--r--mysql-test/t/union.test15
-rw-r--r--mysql-test/valgrind.supp13
-rw-r--r--mysys/my_rename.c5
-rw-r--r--scripts/CMakeLists.txt2
-rw-r--r--scripts/mysql_install_db.pl.in2
-rw-r--r--scripts/mysql_install_db.sh7
-rw-r--r--scripts/mysql_system_tables_fix.sql50
-rw-r--r--scripts/mysqld_multi.sh2
-rw-r--r--scripts/wsrep_sst_mariabackup.sh32
-rw-r--r--scripts/wsrep_sst_rsync.sh2
-rw-r--r--scripts/wsrep_sst_xtrabackup-v2.sh23
-rw-r--r--sql-common/client.c4
-rw-r--r--sql/field.cc8
-rw-r--r--sql/item.cc3
-rw-r--r--sql/item_strfunc.cc112
-rw-r--r--sql/log.cc11
-rw-r--r--sql/mysqld.cc10
-rw-r--r--sql/mysqld.h3
-rw-r--r--sql/opt_subselect.cc69
-rw-r--r--sql/share/CMakeLists.txt12
-rw-r--r--sql/sql_acl.cc13
-rw-r--r--sql/sql_base.cc12
-rw-r--r--sql/sql_parse.cc26
-rw-r--r--sql/sql_select.cc17
-rw-r--r--sql/sql_statistics.cc33
-rw-r--r--sql/sql_statistics.h1
-rw-r--r--sql/sql_table.cc6
-rw-r--r--sql/sql_truncate.cc3
-rw-r--r--sql/sys_vars.cc6
-rw-r--r--sql/table.cc19
-rw-r--r--sql/table_cache.cc2
-rw-r--r--sql/tztime.cc2
-rw-r--r--sql/wsrep_binlog.cc52
-rw-r--r--sql/wsrep_mysqld.cc26
-rw-r--r--sql/wsrep_sst.cc26
-rw-r--r--storage/connect/filamvct.cpp5
-rw-r--r--storage/innobase/buf/buf0buddy.cc2
-rw-r--r--storage/innobase/buf/buf0dump.cc2
-rw-r--r--storage/innobase/dict/dict0stats_bg.cc26
-rw-r--r--storage/innobase/fts/fts0ast.cc9
-rw-r--r--storage/innobase/fts/fts0fts.cc76
-rw-r--r--storage/innobase/fts/fts0opt.cc169
-rw-r--r--storage/innobase/fts/fts0pars.cc16
-rw-r--r--storage/innobase/fts/fts0pars.y16
-rw-r--r--storage/innobase/fts/fts0que.cc17
-rw-r--r--storage/innobase/handler/ha_innodb.cc37
-rw-r--r--storage/innobase/handler/handler0alter.cc65
-rw-r--r--storage/innobase/handler/i_s.cc8
-rw-r--r--storage/innobase/include/dict0stats.h13
-rw-r--r--storage/innobase/include/fts0ast.h5
-rw-r--r--storage/innobase/include/fts0fts.h8
-rw-r--r--storage/innobase/include/fts0priv.h11
-rw-r--r--storage/innobase/row/row0import.cc85
-rw-r--r--storage/innobase/row/row0mysql.cc14
-rw-r--r--storage/innobase/row/row0purge.cc14
-rw-r--r--storage/innobase/row/row0trunc.cc14
-rw-r--r--storage/innobase/row/row0uins.cc3
-rw-r--r--storage/innobase/row/row0umod.cc3
-rw-r--r--storage/mroonga/vendor/groonga/config.h.cmake1
-rw-r--r--storage/mroonga/vendor/groonga/lib/ts/ts_expr_node.c2
-rw-r--r--storage/myisam/ha_myisam.cc6
-rw-r--r--storage/myisam/mi_check.c6
-rw-r--r--storage/myisam/mi_locking.c6
-rw-r--r--storage/xtradb/buf/buf0buddy.cc2
-rw-r--r--storage/xtradb/buf/buf0dump.cc2
-rw-r--r--storage/xtradb/fts/fts0ast.cc9
-rw-r--r--storage/xtradb/fts/fts0fts.cc76
-rw-r--r--storage/xtradb/fts/fts0opt.cc175
-rw-r--r--storage/xtradb/fts/fts0pars.cc16
-rw-r--r--storage/xtradb/fts/fts0pars.y16
-rw-r--r--storage/xtradb/fts/fts0que.cc17
-rw-r--r--storage/xtradb/handler/ha_innodb.cc40
-rw-r--r--storage/xtradb/handler/handler0alter.cc119
-rw-r--r--storage/xtradb/handler/i_s.cc19
-rw-r--r--storage/xtradb/include/fts0ast.h6
-rw-r--r--storage/xtradb/include/fts0fts.h8
-rw-r--r--storage/xtradb/include/fts0priv.h18
-rw-r--r--storage/xtradb/os/os0file.cc41
-rw-r--r--storage/xtradb/row/row0import.cc78
-rw-r--r--storage/xtradb/row/row0log.cc12
-rw-r--r--storage/xtradb/row/row0mysql.cc12
-rw-r--r--storage/xtradb/trx/trx0trx.cc4
-rw-r--r--storage/xtradb/trx/trx0undo.cc3
-rw-r--r--strings/ctype-bin.c8
-rw-r--r--strings/ctype-euc_kr.c4
-rw-r--r--strings/ctype-mb.c100
-rw-r--r--strings/ctype-simple.c22
-rw-r--r--strings/ctype-ucs2.c78
-rw-r--r--strings/ctype-ujis.c8
-rw-r--r--strings/ctype-utf8.c20
-rw-r--r--support-files/CMakeLists.txt2
172 files changed, 3934 insertions, 1009 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 48f573b772e..990cc5f7097 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -176,6 +176,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 9a3a4aaa9eb..4c271b73b96 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -79,7 +79,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 16a4042d66e..b583624c366 100644
--- a/extra/mariabackup/backup_copy.cc
+++ b/extra/mariabackup/backup_copy.cc
@@ -631,11 +631,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--);
@@ -644,19 +647,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);
}
@@ -666,17 +673,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/include/m_ctype.h b/include/m_ctype.h
index 04a82953f0a..d27bc068ff6 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -371,7 +371,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,
@@ -726,9 +726,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 *);
@@ -822,17 +824,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/r/ctype_binary.result b/mysql-test/r/ctype_binary.result
index 976c3df6e0e..228949904ec 100644
--- a/mysql-test/r/ctype_binary.result
+++ b/mysql-test/r/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/r/ctype_eucjpms.result b/mysql-test/r/ctype_eucjpms.result
index bc7b4b9ef9d..507d0021a1f 100644
--- a/mysql-test/r/ctype_eucjpms.result
+++ b/mysql-test/r/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/r/ctype_euckr.result b/mysql-test/r/ctype_euckr.result
index 3fb6f98b2eb..cc50ddd20be 100644
--- a/mysql-test/r/ctype_euckr.result
+++ b/mysql-test/r/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/r/ctype_gbk.result b/mysql-test/r/ctype_gbk.result
index 5244d6eb333..4e5c9695415 100644
--- a/mysql-test/r/ctype_gbk.result
+++ b/mysql-test/r/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/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result
index cbf5f145d22..9899342bdcd 100644
--- a/mysql-test/r/ctype_latin1.result
+++ b/mysql-test/r/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/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index f6d3d86e2cd..3caac471a7c 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -5685,6 +5685,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/r/ctype_ujis.result b/mysql-test/r/ctype_ujis.result
index cb9de83fedc..0b1cf606f0b 100644
--- a/mysql-test/r/ctype_ujis.result
+++ b/mysql-test/r/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/r/ctype_utf16.result b/mysql-test/r/ctype_utf16.result
index 8de21a14bd9..a105017b726 100644
--- a/mysql-test/r/ctype_utf16.result
+++ b/mysql-test/r/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/r/ctype_utf16le.result b/mysql-test/r/ctype_utf16le.result
index 0fedff7d3bf..6d8d7ddca2a 100644
--- a/mysql-test/r/ctype_utf16le.result
+++ b/mysql-test/r/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/r/ctype_utf32.result b/mysql-test/r/ctype_utf32.result
index 59ce4c2f445..28b9caf6ffe 100644
--- a/mysql-test/r/ctype_utf32.result
+++ b/mysql-test/r/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/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 46b7386d993..de524055d51 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/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/r/ctype_utf8mb4.result b/mysql-test/r/ctype_utf8mb4.result
index 7e5e99354ea..27ffd5552fa 100644
--- a/mysql-test/r/ctype_utf8mb4.result
+++ b/mysql-test/r/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/r/derived.result b/mysql-test/r/derived.result
index dd04cc798e6..b5a9485d9db 100644
--- a/mysql-test/r/derived.result
+++ b/mysql-test/r/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/r/grant.result b/mysql-test/r/grant.result
index 81b41a083a3..44eb59fbf9e 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -1753,6 +1753,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;
@@ -1846,8 +1847,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
@@ -1858,6 +1857,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/r/join.result b/mysql-test/r/join.result
index 596cecfa8b2..69511c820cf 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -1505,6 +1505,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/r/join_cache.result b/mysql-test/r/join_cache.result
index eea397402ad..fde6e0fec6b 100644
--- a/mysql-test/r/join_cache.result
+++ b/mysql-test/r/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/r/join_outer.result b/mysql-test/r/join_outer.result
index 3905ec8a7d4..cf9e17ce9d1 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/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(`test`.`tb2`.`v1`, 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(`test`.`tb2`.`v1`, 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/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result
index 6e2bbc25aa0..b3ba3c35c08 100644
--- a/mysql-test/r/join_outer_jcl6.result
+++ b/mysql-test/r/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(`test`.`tb2`.`v1`, 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(`test`.`tb2`.`v1`, 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/r/rename.result b/mysql-test/r/rename.result
index ecb394e9e29..60c17d59320 100644
--- a/mysql-test/r/rename.result
+++ b/mysql-test/r/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/r/sp_notembedded.result b/mysql-test/r/sp_notembedded.result
index 190f8f78d23..8edb9e79b70 100644
--- a/mysql-test/r/sp_notembedded.result
+++ b/mysql-test/r/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/r/stat_tables.result b/mysql-test/r/stat_tables.result
index fcced761283..ceadb61feea 100644
--- a/mysql-test/r/stat_tables.result
+++ b/mysql-test/r/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/r/stat_tables_innodb.result b/mysql-test/r/stat_tables_innodb.result
index 42443bfcb72..7b98ca4259f 100644
--- a/mysql-test/r/stat_tables_innodb.result
+++ b/mysql-test/r/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/r/subselect_mat.result b/mysql-test/r/subselect_mat.result
index 919b31055d6..369d175a8c9 100644
--- a/mysql-test/r/subselect_mat.result
+++ b/mysql-test/r/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/r/subselect_mat_cost_bugs.result b/mysql-test/r/subselect_mat_cost_bugs.result
index f19cf0d4095..fd768b1efd4 100644
--- a/mysql-test/r/subselect_mat_cost_bugs.result
+++ b/mysql-test/r/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/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result
index 88ff82e72d6..281a4a44e91 100644
--- a/mysql-test/r/subselect_sj2_mat.result
+++ b/mysql-test/r/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/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result
index 8109c36441e..84198885ed3 100644
--- a/mysql-test/r/subselect_sj_mat.result
+++ b/mysql-test/r/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/r/union.result b/mysql-test/r/union.result
index a7863506951..aba81fe9d3a 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -2112,6 +2112,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/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/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..0329e105a63 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
@@ -60,7 +60,95 @@ 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');
+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;
+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;
+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;
+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
+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;
+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 ...
+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');
+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');
+Performing --wsrep-recover ...
+Starting server ...
+Using --wsrep-start-position when starting mysqld ...
SET AUTOCOMMIT=OFF;
START TRANSACTION;
INSERT INTO t1 VALUES ('node2_committed_after');
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 d63a3955d0d..e9c82d225b4 100644
--- a/mysql-test/suite/innodb/r/default_row_format_compatibility.result
+++ b/mysql-test/suite/innodb/r/default_row_format_compatibility.result
@@ -30,7 +30,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 4ef92cdfed9..4ef8a2ee131 100644
--- a/mysql-test/suite/innodb/r/innodb-wl5522.result
+++ b/mysql-test/suite/innodb/r/innodb-wl5522.result
@@ -109,7 +109,7 @@ ALTER TABLE t2 DISCARD TABLESPACE;
# List after t2 DISCARD
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;
@@ -589,7 +589,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;
@@ -601,7 +601,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;
@@ -775,7 +787,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;
@@ -787,7 +799,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;
@@ -964,7 +988,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;
@@ -976,7 +1000,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;
@@ -1035,6 +1071,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 a2d5bbef8df..07b7a29675e 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=255\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=255\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 fc328cfd71f..0f5910245ed 100644
--- a/mysql-test/suite/innodb/t/innodb-wl5522.test
+++ b/mysql-test/suite/innodb/t/innodb-wl5522.test
@@ -486,7 +486,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,
@@ -588,6 +588,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,
@@ -616,7 +639,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,
@@ -718,6 +741,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,
@@ -747,7 +793,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,
@@ -849,6 +895,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,
@@ -877,6 +946,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..1e98594b28e
--- /dev/null
+++ b/mysql-test/suite/innodb_fts/r/sync_ddl.result
@@ -0,0 +1,117 @@
+CREATE TABLE t1 (
+id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
+value VARCHAR(1024)
+) ENGINE=InnoDB;
+CREATE FULLTEXT INDEX idx1 ON t1(value);
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+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);
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+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);
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+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);
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+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);
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+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);
+Warnings:
+Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID
+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/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/sysvars_innodb,32bit,xtradb.rdiff-disabled b/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff-disabled
index 65439e3ae5a..b1c041a5444 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff-disabled
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff-disabled
@@ -1210,7 +1210,7 @@
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME INNODB_VERSION
SESSION_VALUE NULL
--GLOBAL_VALUE 5.6.40
+-GLOBAL_VALUE 5.6.41
+GLOBAL_VALUE 5.6.39-83.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE NULL
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff-disabled b/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff-disabled
index dafdde75e12..e7af5f851bd 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff-disabled
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff-disabled
@@ -1,5 +1,5 @@
---- suite/sys_vars/r/sysvars_innodb.result
-+++ suite/sys_vars/r/sysvars_innodb,xtradb.reject
+--- mysql-test/suite/sys_vars/r/sysvars_innodb.result 2018-07-30 23:41:05.030930072 +0200
++++ mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.reject 2018-07-31 09:45:20.330811949 +0200
@@ -47,6 +47,20 @@
ENUM_VALUE_LIST OFF,ON
READ_ONLY NO
@@ -684,7 +684,7 @@
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME INNODB_VERSION
SESSION_VALUE NULL
--GLOBAL_VALUE 5.6.40
+-GLOBAL_VALUE 5.6.41
+GLOBAL_VALUE 5.6.39-83.1
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE NULL
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 f7a5cf591c2..a7a7547d73b 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
@@ -485,6 +485,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 034195efbd1..a8f20769e30 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
@@ -485,6 +485,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/t/bootstrap.test b/mysql-test/t/bootstrap.test
index e8589fa9242..add9e0286db 100644
--- a/mysql-test/t/bootstrap.test
+++ b/mysql-test/t/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/t/ctype_binary.test b/mysql-test/t/ctype_binary.test
index 8da4eaff572..155d8548f77 100644
--- a/mysql-test/t/ctype_binary.test
+++ b/mysql-test/t/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/t/ctype_eucjpms.test b/mysql-test/t/ctype_eucjpms.test
index c69abc32a03..867ca809dbf 100644
--- a/mysql-test/t/ctype_eucjpms.test
+++ b/mysql-test/t/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/t/ctype_euckr.test b/mysql-test/t/ctype_euckr.test
index 950c60c47e5..46955360217 100644
--- a/mysql-test/t/ctype_euckr.test
+++ b/mysql-test/t/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/t/ctype_gbk.test b/mysql-test/t/ctype_gbk.test
index a3dc7f4af44..d9d0a4d0ee4 100644
--- a/mysql-test/t/ctype_gbk.test
+++ b/mysql-test/t/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/t/ctype_latin1.test b/mysql-test/t/ctype_latin1.test
index 38f147708b8..61df80e2186 100644
--- a/mysql-test/t/ctype_latin1.test
+++ b/mysql-test/t/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/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index 17a07cd4bf9..061130e429f 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -991,6 +991,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/t/ctype_ujis.test b/mysql-test/t/ctype_ujis.test
index ff9c61c05ba..cf247763b46 100644
--- a/mysql-test/t/ctype_ujis.test
+++ b/mysql-test/t/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/t/ctype_utf16.test b/mysql-test/t/ctype_utf16.test
index 526f5251055..504e62e3e89 100644
--- a/mysql-test/t/ctype_utf16.test
+++ b/mysql-test/t/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/t/ctype_utf16le.test b/mysql-test/t/ctype_utf16le.test
index 79cf875852a..b8728b52db2 100644
--- a/mysql-test/t/ctype_utf16le.test
+++ b/mysql-test/t/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/t/ctype_utf32.test b/mysql-test/t/ctype_utf32.test
index 6f036898d15..2e739ebfdbc 100644
--- a/mysql-test/t/ctype_utf32.test
+++ b/mysql-test/t/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/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index e293cae930a..be342f80a75 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/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/t/ctype_utf8mb4.test b/mysql-test/t/ctype_utf8mb4.test
index 545347fcd26..9cf87d12340 100644
--- a/mysql-test/t/ctype_utf8mb4.test
+++ b/mysql-test/t/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/t/derived.test b/mysql-test/t/derived.test
index 466d79af409..6c51f23c51e 100644
--- a/mysql-test/t/derived.test
+++ b/mysql-test/t/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/t/grant.test b/mysql-test/t/grant.test
index cb4254fe8c6..c3bb987acc8 100644
--- a/mysql-test/t/grant.test
+++ b/mysql-test/t/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/t/join.test b/mysql-test/t/join.test
index e07a3665920..8a088de91cc 100644
--- a/mysql-test/t/join.test
+++ b/mysql-test/t/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/t/join_cache.test b/mysql-test/t/join_cache.test
index b775725903c..df89fc30dee 100644
--- a/mysql-test/t/join_cache.test
+++ b/mysql-test/t/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/t/join_outer.test b/mysql-test/t/join_outer.test
index 34b0551a32e..6d20c089bd9 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/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/t/rename.test b/mysql-test/t/rename.test
index 67732d5b5b9..215ecbcbb18 100644
--- a/mysql-test/t/rename.test
+++ b/mysql-test/t/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/t/stat_tables.test b/mysql-test/t/stat_tables.test
index 4cbaa9e27c8..2c9c1eca7d3 100644
--- a/mysql-test/t/stat_tables.test
+++ b/mysql-test/t/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/t/subselect_sj2_mat.test b/mysql-test/t/subselect_sj2_mat.test
index 68a888012f2..f54771856e7 100644
--- a/mysql-test/t/subselect_sj2_mat.test
+++ b/mysql-test/t/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/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test
index bfd3b28a5b2..7853b528e8f 100644
--- a/mysql-test/t/subselect_sj_mat.test
+++ b/mysql-test/t/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/t/union.test b/mysql-test/t/union.test
index 0d3fd7bc8e2..ac3114827fb 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -1454,6 +1454,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/valgrind.supp b/mysql-test/valgrind.supp
index 96a6e2ea1c2..49e863d506c 100644
--- a/mysql-test/valgrind.supp
+++ b/mysql-test/valgrind.supp
@@ -627,6 +627,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 e68284a7d58..7aa89c68822 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
@@ -103,6 +104,7 @@ INSTALL(FILES
${FIX_PRIVILEGES_SQL}
DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT Server
)
+ENDIF()
# TCMalloc hacks
IF(MALLOC_LIB)
diff --git a/scripts/mysql_install_db.pl.in b/scripts/mysql_install_db.pl.in
index 9d2c1f6874a..68d47fed2ea 100644
--- a/scripts/mysql_install_db.pl.in
+++ b/scripts/mysql_install_db.pl.in
@@ -329,7 +329,7 @@ else
$opt->{basedir} = '@prefix@';
$bindir = '@bindir@';
$extra_bindir = $bindir;
- $mysqld = '@libexecdir@/mysqld';
+ $mysqld = '@sbindir@/mysqld';
$srcpkgdatadir = '@pkgdatadir@';
$buildpkgdatadir = '@pkgdatadir@';
$scriptdir = '@scriptdir@';
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index ec87acbc95d..9e0c66cc55b 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 --srcddir"
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_fix.sql b/scripts/mysql_system_tables_fix.sql
index 2a826bb2df0..e724c3e2d23 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,
@@ -460,7 +469,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
@@ -524,19 +533,18 @@ ALTER TABLE proc MODIFY comment
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.
@@ -576,8 +584,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';
@@ -639,12 +647,14 @@ ALTER TABLE user MODIFY Create_tablespace_priv enum('N','Y') COLLATE utf8_genera
UPDATE user SET Create_tablespace_priv = Super_priv WHERE @hadCreateTablespacePriv = 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;
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 20a4a63c204..41c0a6d178d 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=""
@@ -225,7 +224,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"
@@ -248,7 +247,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
@@ -518,10 +517,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
@@ -644,6 +639,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
+}
+
if [[ ! -x `which $INNOBACKUPEX_BIN` ]];then
wsrep_log_error "${INNOBACKUPEX_BIN} not in path: $PATH"
exit 2
@@ -932,7 +948,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 05c99880d75..88b1352db2e 100644
--- a/scripts/wsrep_sst_rsync.sh
+++ b/scripts/wsrep_sst_rsync.sh
@@ -374,6 +374,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 00efdaeebcf..99bbabbe9be 100644
--- a/scripts/wsrep_sst_xtrabackup-v2.sh
+++ b/scripts/wsrep_sst_xtrabackup-v2.sh
@@ -801,6 +801,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
+}
+
if [[ ! -x `which $INNOBACKUPEX_BIN` ]];then
wsrep_log_error "innobackupex not in path: $PATH"
@@ -1102,7 +1123,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 81244de7a74..3cc4b918772 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1465,6 +1465,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))))
{
@@ -2583,6 +2584,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 e84658bb64d..9ca9663f066 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -7978,7 +7978,13 @@ int Field_blob::store(const char *from,uint 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/item.cc b/sql/item.cc
index a501ff6fdc6..58d2b7dbfc0 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
@@ -10408,6 +10408,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
if (Field::result_merge_type(real_field_type()) == DECIMAL_RESULT)
{
+ collation.set_numeric();
decimals= MY_MIN(MY_MAX(decimals, item->decimals), DECIMAL_MAX_SCALE);
int item_int_part= item->decimal_int_part();
int item_prec = MY_MAX(prev_decimal_int_part, item_int_part) + decimals;
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 87c766340c7..e332f034fb3 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1518,32 +1518,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)
- {
- uint 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
- {
- uint 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;
+ uint 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;
}
@@ -1746,7 +1732,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;
@@ -1795,20 +1781,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;
}
}
}
@@ -1820,13 +1817,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
@@ -1841,30 +1841,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 f74e73f47ba..fa1fe3d808c 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -2708,14 +2708,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);
}
}
@@ -2900,7 +2900,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;
@@ -3086,7 +3086,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
if (! write_error)
{
write_error= 1;
- sql_print_error(ER_THD(thd, ER_ERROR_ON_WRITE), name, tmp_errno);
+ sql_print_error(ER_DEFAULT(ER_ERROR_ON_WRITE), name, tmp_errno);
}
}
}
@@ -8425,8 +8425,7 @@ void MYSQL_BIN_LOG::close(uint exiting)
if (mysql_file_close(index_file.file, MYF(0)) < 0 && ! 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 8dd178108b9..8e2884e2048 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -489,7 +489,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;
@@ -516,6 +516,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;
@@ -5648,6 +5649,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.
@@ -6045,7 +6051,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 5a2dc6dce8d..2604121a9f1 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -166,7 +166,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/opt_subselect.cc b/sql/opt_subselect.cc
index 36d0116696a..d0be72b8d51 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);
@@ -819,6 +820,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
@@ -1456,6 +1460,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
@@ -1719,6 +1784,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)
{
@@ -3543,7 +3609,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 792fe700473..f5c422cc5ea 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
@@ -10937,17 +10937,12 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
if (!(combo=(LEX_USER*) thd->alloc(sizeof(st_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 0ac7a112161..36bf39ea8f3 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -6587,6 +6587,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);
@@ -6594,7 +6595,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. */
@@ -6603,7 +6604,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;
}
@@ -6624,7 +6625,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 (;;)
@@ -6657,7 +6658,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;
@@ -6889,7 +6891,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. */
@@ -6934,6 +6935,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 3ec7b54e0a9..dd16200539d 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -724,6 +724,9 @@ void init_update_queries(void)
sql_command_flags[SQLCOM_TRUNCATE]|= CF_FORCE_ORIGINAL_BINLOG_FORMAT;
/* We don't want to replicate DROP for temp tables in row format */
sql_command_flags[SQLCOM_DROP_TABLE]|= 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;
@@ -1577,10 +1580,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;
@@ -7826,36 +7829,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
@@ -7891,6 +7904,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 47ca733468b..643ddfeba39 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -4137,8 +4137,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;
/*
@@ -4305,7 +4305,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,
@@ -8548,8 +8548,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;
}
@@ -9154,7 +9159,6 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
if (first_keyuse)
{
key_parts++;
- first_keyuse= FALSE;
}
else
{
@@ -9164,7 +9168,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;
}
@@ -9172,6 +9176,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 0743e886eb1..ae72b828ae3 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -3066,6 +3066,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
diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h
index f46583839d1..0611c021e88 100644
--- a/sql/sql_statistics.h
+++ b/sql/sql_statistics.h
@@ -92,6 +92,7 @@ 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_STRING *db, LEX_STRING *tab);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 73f62f2f2c8..dbcab9bb870 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4795,6 +4795,10 @@ int create_table_impl(THD *thd,
{
if (options.or_replace())
{
+ LEX_STRING db_name= {(char *) db, strlen(db)};
+ LEX_STRING tab_name= {(char *) table_name, strlen(table_name)};
+ (void) delete_statistics_for_table(thd, &db_name, &tab_name);
+
TABLE_LIST table_list;
table_list.init_one_table(db, strlen(db), table_name,
strlen(table_name), table_name,
@@ -5326,6 +5330,8 @@ mysql_rename_table(handlerton *base, const char *old_db,
delete file;
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);
else if (error)
my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error);
else if (!(flags & FN_IS_TMP))
diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc
index 8a70e6f6bdb..9a54b4f947f 100644
--- a/sql/sql_truncate.cc
+++ b/sql/sql_truncate.cc
@@ -349,7 +349,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 e6aec472b9e..841e57fa3e2 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -442,6 +442,12 @@ bool check_has_super(sys_var *self, THD *thd, set_var *var)
#endif
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)
{
if (check_has_super(self, thd, var))
diff --git a/sql/table.cc b/sql/table.cc
index 7cb84bcc5ea..6a19b1ebdbc 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -6073,7 +6073,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);
/*
@@ -6122,7 +6122,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 *
@@ -6138,7 +6138,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;
}
@@ -6949,6 +6949,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
*/
@@ -6964,11 +6972,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 be990543757..7dfd1c2ac8e 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. */
@@ -972,6 +973,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 ccd5ed4a86b..82160231b03 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -1661,7 +1661,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 483da2296ad..672e1d77f47 100644
--- a/sql/wsrep_binlog.cc
+++ b/sql/wsrep_binlog.cc
@@ -318,13 +318,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;
}
@@ -343,6 +358,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);
}
/*
@@ -448,19 +464,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);
Format_description_log_event *ev=NULL;
- 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;
}
@@ -501,6 +532,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 eeb1be72ebb..326b5928366 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -1477,6 +1477,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
@@ -1499,7 +1518,8 @@ static int wsrep_TOI_begin(THD *thd, char *db_, 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:
@@ -1573,8 +1593,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 a504d2eafd3..f4fe6af8d9f 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -193,8 +193,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();
@@ -203,14 +202,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);
}
}
@@ -1366,19 +1369,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/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/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc
index a1457956767..440d64322a4 100644
--- a/storage/innobase/buf/buf0buddy.cc
+++ b/storage/innobase/buf/buf0buddy.cc
@@ -127,7 +127,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/buf0dump.cc b/storage/innobase/buf/buf0dump.cc
index f27c2524782..d733ecdad17 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/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc
index 6c9a17c8a7c..b203c60bd3c 100644
--- a/storage/innobase/dict/dict0stats_bg.cc
+++ b/storage/innobase/dict/dict0stats_bg.cc
@@ -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>
@@ -146,11 +152,18 @@ dict_stats_recalc_pool_add(
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));
@@ -162,6 +175,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;
}
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 b5c4a44514d..81ec3a3c80e 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
@@ -861,37 +861,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;
@@ -901,18 +892,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);
}
@@ -4070,6 +4057,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);
@@ -4354,7 +4344,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
@@ -4420,15 +4410,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;
}
}
@@ -4463,8 +4451,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 cb1df7082f7..9adfb16c438 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 @@ 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 @@ 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 @@ 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 @@ 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 b9977bd31e5..9956be93cb1 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
@@ -4057,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);
@@ -4070,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 */
@@ -4096,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 != NULL) {
+ fts_query_free_result(*result);
+ }
+ goto func_exit;
+ }
+
ut_free(lc_query_str);
if (fts_enable_diag_print && (*result)) {
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index a8594fd37b3..d8e805862f7 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -13534,6 +13534,7 @@ inline MY_ATTRIBUTE((warn_unused_result))
dberr_t
innobase_rename_table(
/*==================*/
+ THD* thd, /*!< Connection thread handle */
trx_t* trx, /*!< in: transaction */
const char* from, /*!< in: old name of the table */
const char* to) /*!< in: new name of the table */
@@ -13559,6 +13560,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(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);
+ }
+
/* Transaction must be flagged as a locking transaction or it hasn't
been started yet. */
@@ -13649,7 +13680,7 @@ ha_innobase::rename_table(
++trx->will_lock;
trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
- dberr_t error = innobase_rename_table(trx, from, to);
+ dberr_t error = innobase_rename_table(thd, trx, from, to);
DEBUG_SYNC(thd, "after_innobase_rename_table");
@@ -13693,6 +13724,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 e38dc1951ca..6e318a040ca 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -8532,24 +8532,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);
}
}
@@ -8596,41 +8596,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);
}
@@ -8910,6 +8908,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);
@@ -8994,8 +8997,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
@@ -9010,14 +9011,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 2f0bdac3f07..064e0e88113 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -1380,12 +1380,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/dict0stats.h b/storage/innobase/include/dict0stats.h
index 5dd53c46d1b..03f0c0c6377 100644
--- a/storage/innobase/include/dict0stats.h
+++ b/storage/innobase/include/dict0stats.h
@@ -110,12 +110,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 362bdcb7fe6..cad9ef37560 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
@@ -711,6 +711,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 f9d5d07a44c..fca22bdc7d6 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
@@ -513,13 +513,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/row/row0import.cc b/storage/innobase/row/row0import.cc
index 3689c21588d..4ca878253ea 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;
@@ -1229,17 +1229,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);
@@ -1700,7 +1746,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
@@ -3800,8 +3845,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/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 8af20e27b41..5ba8d038671 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -71,6 +71,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;
@@ -1520,7 +1527,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) {
@@ -1892,7 +1899,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++;
@@ -2145,7 +2152,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 7e7dd794f1b..83f4a313e5f 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -1072,9 +1072,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 */
{
@@ -1095,7 +1095,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);
}
@@ -1124,13 +1126,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 f6be8bdfbc5..79870ceaf5f 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
@@ -1232,6 +1232,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");
@@ -1562,6 +1567,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);
@@ -1806,6 +1814,10 @@ row_truncate_table_for_mysql(
/* Step-2: Start transaction (only for non-temp table as temp-table
don't modify any data on disk doesn't need transaction object). */
if (!dict_table_is_temporary(table)) {
+ if (table->fts) {
+ fts_optimize_remove_table(table);
+ }
+
/* Avoid transaction overhead for temporary table DDL. */
trx_start_for_ddl(trx, TRX_DICT_OP_TABLE);
}
diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc
index f4cd07dc53a..b3e53cab028 100644
--- a/storage/innobase/row/row0uins.cc
+++ b/storage/innobase/row/row0uins.cc
@@ -526,7 +526,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 b5c8d7c4ce2..8955eab639c 100644
--- a/storage/innobase/row/row0umod.cc
+++ b/storage/innobase/row/row0umod.cc
@@ -1299,7 +1299,8 @@ row_undo_mod(
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/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 622e5c66d4f..dedf232523b 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
@@ -1328,10 +1328,14 @@ int ha_myisam::repair(THD *thd, HA_CHECK &param, bool do_optimize)
if (file->s->base.auto_key)
update_auto_increment_key(&param, file, 1);
if (optimize_done)
+ {
+ mysql_mutex_lock(&share->intern_lock);
error = update_state_info(&param, 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 c5995d74ca3..f7fd2033083 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 4fd287c6038..85b06c81312 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/xtradb/buf/buf0buddy.cc b/storage/xtradb/buf/buf0buddy.cc
index 1c50e71e687..ee687efc9ec 100644
--- a/storage/xtradb/buf/buf0buddy.cc
+++ b/storage/xtradb/buf/buf0buddy.cc
@@ -132,7 +132,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/xtradb/buf/buf0dump.cc b/storage/xtradb/buf/buf0dump.cc
index ce21a308960..90358d34b04 100644
--- a/storage/xtradb/buf/buf0dump.cc
+++ b/storage/xtradb/buf/buf0dump.cc
@@ -201,7 +201,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/xtradb/fts/fts0ast.cc b/storage/xtradb/fts/fts0ast.cc
index 030b972440f..4b36152cf62 100644
--- a/storage/xtradb/fts/fts0ast.cc
+++ b/storage/xtradb/fts/fts0ast.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
-Copyright (c) 2007, 2014, 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
@@ -27,6 +28,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 {
@@ -498,6 +500,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;
@@ -596,6 +599,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/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc
index 42cb2056dfc..5981c24c470 100644
--- a/storage/xtradb/fts/fts0fts.cc
+++ b/storage/xtradb/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
@@ -268,7 +268,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
@@ -869,37 +869,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;
@@ -909,18 +900,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);
}
@@ -3974,6 +3961,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);
@@ -4538,7 +4528,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
@@ -4600,15 +4590,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;
}
}
@@ -4643,8 +4631,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/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc
index d9f96948000..77293bc867a 100644
--- a/storage/xtradb/fts/fts0opt.cc
+++ b/storage/xtradb/fts/fts0opt.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) 2016, MariaDB Corporation. All Rights reserved.
This program is free software; you can redistribute it and/or modify it under
@@ -58,12 +58,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,
@@ -75,17 +69,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 */
@@ -235,7 +223,7 @@ struct fts_msg_t {
/** The number of words to read and optimize in a single pass. */
UNIV_INTERN ulong fts_num_word_optimize;
-// FIXME
+/** Whether to enable additional FTS diagnostic printout. */
UNIV_INTERN char fts_enable_diag_print;
/** ZLib compressed block size.*/
@@ -2560,13 +2548,9 @@ fts_optimize_create_msg(
return(msg);
}
-/**********************************************************************//**
-Add the table to add to the OPTIMIZER's list. */
-UNIV_INTERN
-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 */
+UNIV_INTERN void fts_optimize_add_table(dict_table_t* table)
{
fts_msg_t* msg;
@@ -2585,26 +2569,6 @@ fts_optimize_add_table(
}
/**********************************************************************//**
-Optimize a table. */
-UNIV_INTERN
-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);
-}
-
-/**********************************************************************//**
Remove the table from the OPTIMIZER's list. We do wait for
acknowledgement from the consumer of the message. */
UNIV_INTERN
@@ -2618,7 +2582,7 @@ fts_optimize_remove_table(
fts_msg_del_t* remove;
/* if the optimize system not yet initialized, return */
- if (!fts_optimize_wq) {
+ if (!fts_optimize_is_init()) {
return;
}
@@ -2660,7 +2624,7 @@ fts_optimize_request_sync_table(
table_id_t* table_id;
/* if the optimize system not yet initialized, return */
- if (!fts_optimize_wq) {
+ if (!fts_optimize_is_init()) {
return;
}
@@ -2683,54 +2647,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->id == table->id) {
- 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) {
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Error: table %s not registered "
- "with the optimize thread.\n", table->name);
- } else {
- slot->last_run = 0;
- slot->completed = 0;
- }
-}
-
-/**********************************************************************//**
Add the table to the vector if it doesn't already exist. */
static
ibool
@@ -2912,57 +2828,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
@@ -2975,7 +2840,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);
@@ -3047,8 +2912,7 @@ 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) {
@@ -3060,12 +2924,6 @@ fts_optimize_thread(
}
switch (msg->type) {
- case FTS_MSG_START:
- break;
-
- case FTS_MSG_PAUSE:
- break;
-
case FTS_MSG_STOP:
done = TRUE;
exit_event = (os_event_t) msg->ptr;
@@ -3081,15 +2939,6 @@ fts_optimize_thread(
}
break;
- case FTS_MSG_OPTIMIZE_TABLE:
- if (!done) {
- fts_optimize_start_table(
- tables,
- static_cast<dict_table_t*>(
- msg->ptr));
- }
- break;
-
case FTS_MSG_DEL_TABLE:
if (fts_optimize_del_table(
tables, static_cast<fts_msg_del_t*>(
@@ -3104,6 +2953,10 @@ 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;
@@ -3163,7 +3016,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_is_init());
fts_optimize_wq = ib_wqueue_create();
ut_a(fts_optimize_wq != NULL);
diff --git a/storage/xtradb/fts/fts0pars.cc b/storage/xtradb/fts/fts0pars.cc
index 7f0ba4e0c1b..19917ccd26a 100644
--- a/storage/xtradb/fts/fts0pars.cc
+++ b/storage/xtradb/fts/fts0pars.cc
@@ -87,7 +87,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);
@@ -102,8 +102,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;
@@ -1950,7 +1950,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 {
@@ -1959,7 +1959,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);
@@ -1973,7 +1973,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);
@@ -1991,9 +1991,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/xtradb/fts/fts0pars.y b/storage/xtradb/fts/fts0pars.y
index e48036e82fe..65c4189eece 100644
--- a/storage/xtradb/fts/fts0pars.y
+++ b/storage/xtradb/fts/fts0pars.y
@@ -35,7 +35,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);
@@ -48,8 +48,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, 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, 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);
@@ -276,9 +276,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/xtradb/fts/fts0que.cc b/storage/xtradb/fts/fts0que.cc
index 100dbcd70ca..50f198401f9 100644
--- a/storage/xtradb/fts/fts0que.cc
+++ b/storage/xtradb/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, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -3989,6 +3989,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);
@@ -4002,6 +4003,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 */
@@ -4029,6 +4035,15 @@ fts_query(
memset(*result, 0, sizeof(**result));
}
+ if (trx_is_interrupted(trx)) {
+ error = DB_INTERRUPTED;
+ ut_free(lc_query_str);
+ if (result != NULL) {
+ fts_query_free_result(*result);
+ }
+ goto func_exit;
+ }
+
ut_free(lc_query_str);
if (fts_enable_diag_print && (*result)) {
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 30fabbdb089..988b10522a4 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-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) 2013, 2018, MariaDB Corporation.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
@@ -13395,6 +13395,7 @@ static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
innobase_rename_table(
/*==================*/
+ THD* thd, /*!< Connection thread handle */
trx_t* trx, /*!< in: transaction */
const char* from, /*!< in: old name of the table */
const char* to) /*!< in: new name of the table */
@@ -13420,6 +13421,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(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);
+ }
+
/* Transaction must be flagged as a locking transaction or it hasn't
been started yet. */
@@ -13534,7 +13565,7 @@ ha_innobase::rename_table(
++trx->will_lock;
trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
- error = innobase_rename_table(trx, from, to);
+ error = innobase_rename_table(thd, trx, from, to);
DEBUG_SYNC(thd, "after_innobase_rename_table");
@@ -13578,6 +13609,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));
@@ -15401,6 +15436,7 @@ ha_innobase::start_stmt(
case SQLCOM_INSERT:
case SQLCOM_UPDATE:
case SQLCOM_DELETE:
+ case SQLCOM_REPLACE:
init_table_handle_for_HANDLER();
prebuilt->select_lock_type = LOCK_X;
prebuilt->stored_select_lock_type = LOCK_X;
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index dfc1c23144d..136d7ae7527 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2018, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2005, 2018, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 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
@@ -4901,13 +4901,15 @@ processed_field:
}
/** Get the auto-increment value of the table on commit.
-@param ha_alter_info Data used during in-place alter
-@param ctx In-place ALTER TABLE context
-@param altered_table MySQL table that is being altered
-@param old_table MySQL table as it is before the ALTER operation
-@return the next auto-increment value (0 if not present) */
+@param[in] ha_alter_info Data used during in-place alter
+@param[in,out] ctx In-place ALTER TABLE context
+ return autoinc value in ctx->max_autoinc
+@param altered_table[in] MySQL table that is being altered
+@param old_table[in] MySQL table as it is before the ALTER operation
+retval true Failure
+@retval false Success*/
static MY_ATTRIBUTE((nonnull, warn_unused_result))
-ulonglong
+bool
commit_get_autoinc(
/*===============*/
Alter_inplace_info* ha_alter_info,
@@ -4915,23 +4917,28 @@ commit_get_autoinc(
const TABLE* altered_table,
const TABLE* old_table)
{
- ulonglong max_autoinc;
DBUG_ENTER("commit_get_autoinc");
if (!altered_table->found_next_number_field) {
/* There is no AUTO_INCREMENT column in the table
after the ALTER operation. */
- max_autoinc = 0;
+ ctx->max_autoinc = 0;
} else if (ctx->add_autoinc != ULINT_UNDEFINED) {
/* An AUTO_INCREMENT column was added. Get the last
value from the sequence, which may be based on a
supplied AUTO_INCREMENT value. */
- max_autoinc = ctx->sequence.last();
+ ctx->max_autoinc = ctx->sequence.last();
} else if ((ha_alter_info->handler_flags
& Alter_inplace_info::CHANGE_CREATE_OPTION)
&& (ha_alter_info->create_info->used_fields
& HA_CREATE_USED_AUTO)) {
+
+ /* Check if the table is discarded */
+ if(dict_table_is_discarded(ctx->old_table)) {
+ DBUG_RETURN(true);
+ }
+
/* An AUTO_INCREMENT value was supplied, but the table was not
rebuilt. Get the user-supplied value or the last value from the
sequence. */
@@ -4946,7 +4953,8 @@ commit_get_autoinc(
dict_index_t* index = dict_table_get_index_on_name(
ctx->old_table, autoinc_key->name);
- max_autoinc = ha_alter_info->create_info->auto_increment_value;
+ ctx->max_autoinc =
+ ha_alter_info->create_info->auto_increment_value;
dict_table_autoinc_lock(ctx->old_table);
@@ -4955,8 +4963,8 @@ commit_get_autoinc(
if (err != DB_SUCCESS) {
ut_ad(0);
- max_autoinc = 0;
- } else if (max_autoinc <= max_value_table) {
+ ctx->max_autoinc = 0;
+ } else if (ctx->max_autoinc <= max_value_table) {
ulonglong col_max_value;
ulonglong offset;
@@ -4964,7 +4972,7 @@ commit_get_autoinc(
old_table->found_next_number_field);
offset = ctx->prebuilt->autoinc_offset;
- max_autoinc = innobase_next_autoinc(
+ ctx->max_autoinc = innobase_next_autoinc(
max_value_table, 1, 1, offset,
col_max_value);
}
@@ -4974,11 +4982,11 @@ commit_get_autoinc(
Read the old counter value from the table. */
ut_ad(old_table->found_next_number_field);
dict_table_autoinc_lock(ctx->old_table);
- max_autoinc = ctx->old_table->autoinc;
+ ctx->max_autoinc = ctx->old_table->autoinc;
dict_table_autoinc_unlock(ctx->old_table);
}
- DBUG_RETURN(max_autoinc);
+ DBUG_RETURN(false);
}
/** Add or drop foreign key constraints to the data dictionary tables,
@@ -5850,24 +5858,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);
}
}
@@ -5912,41 +5920,40 @@ 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_logf(IB_LOG_LEVEL_INFO,
+ "Drop index waiting for background sync"
+ " to finish");
+ retry_count = 0;
+ }
+
DICT_BG_YIELD(trx);
}
@@ -5960,8 +5967,13 @@ ha_innobase::commit_inplace_alter_table(
DBUG_ASSERT(new_clustered == ctx->need_rebuild());
- ctx->max_autoinc = commit_get_autoinc(
- ha_alter_info, ctx, altered_table, table);
+ if (commit_get_autoinc(ha_alter_info, ctx, altered_table,
+ table)) {
+ fail = true;
+ my_error(ER_TABLESPACE_DISCARDED, MYF(0),
+ table->s->table_name.str);
+ goto rollback_trx;
+ }
if (ctx->need_rebuild()) {
ctx->tmp_name = dict_mem_create_temporary_tablename(
@@ -5993,6 +6005,8 @@ ha_innobase::commit_inplace_alter_table(
#endif
}
+rollback_trx:
+
/* Commit or roll back the changes to the data dictionary. */
if (fail) {
@@ -6203,6 +6217,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);
@@ -6251,8 +6270,6 @@ foreign_fail:
dict_table_autoinc_unlock(t);
}
- 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
@@ -6267,14 +6284,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/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index dc4fa99fc56..201d2ad13a5 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -1433,19 +1433,16 @@ i_s_cmp_fill_low(
clear it. We could introduce mutex protection, but it
could cause a measureable performance hit in
page0zip.cc. */
- table->field[1]->store(
- static_cast<double>(zip_stat->compressed));
- table->field[2]->store(
- static_cast<double>(zip_stat->compressed_ok));
- table->field[3]->store(
- static_cast<double>(zip_stat->compressed_usec / 1000000));
- table->field[4]->store(
- static_cast<double>(zip_stat->decompressed));
- table->field[5]->store(
- static_cast<double>(zip_stat->decompressed_usec / 1000000));
+ 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[4]->store(zip_stat->decompressed, 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/xtradb/include/fts0ast.h b/storage/xtradb/include/fts0ast.h
index 6229869e8d0..983a3579773 100644
--- a/storage/xtradb/include/fts0ast.h
+++ b/storage/xtradb/include/fts0ast.h
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, MariaDB Corporation.
+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
@@ -317,6 +317,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;
};
/* To track state during parsing */
diff --git a/storage/xtradb/include/fts0fts.h b/storage/xtradb/include/fts0fts.h
index cd94956dc55..4c2d247e0a6 100644
--- a/storage/xtradb/include/fts0fts.h
+++ b/storage/xtradb/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
@@ -705,6 +705,12 @@ fts_drop_index_tables(
dict_index_t* index) /*!< in: Index to drop */
MY_ATTRIBUTE((nonnull, 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/xtradb/include/fts0priv.h b/storage/xtradb/include/fts0priv.h
index 2d4e9d88fd1..a3936f54a48 100644
--- a/storage/xtradb/include/fts0priv.h
+++ b/storage/xtradb/include/fts0priv.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.
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
@@ -598,22 +598,6 @@ fts_get_table_id(
long */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//**
-Add the table to add to the OPTIMIZER's list. */
-UNIV_INTERN
-void
-fts_optimize_add_table(
-/*===================*/
- dict_table_t* table) /*!< in: table to add */
- MY_ATTRIBUTE((nonnull));
-/******************************************************************//**
-Optimize a table. */
-UNIV_INTERN
-void
-fts_optimize_do_table(
-/*==================*/
- dict_table_t* table) /*!< in: table to optimize */
- MY_ATTRIBUTE((nonnull));
-/******************************************************************//**
Construct the prefix name of an FTS table.
@return own: table name, must be freed with mem_free() */
UNIV_INTERN
diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc
index 2e172a7524c..468a54768be 100644
--- a/storage/xtradb/os/os0file.cc
+++ b/storage/xtradb/os/os0file.cc
@@ -1875,6 +1875,33 @@ os_file_set_atomic_writes(
#endif
}
+#ifdef _WIN32
+/** Check that IO of specific size is possible for the file
+opened with FILE_FLAG_NO_BUFFERING.
+
+The requirement is that IO is multiple of the disk sector size.
+
+@param[in] file file handle
+@param[in] io_size expected io size
+@return true - unbuffered io of requested size is possible, false otherwise.
+
+@note: this function only works correctly with Windows 8 or later,
+(GetFileInformationByHandleEx with FileStorageInfo is only supported there).
+It will return true on earlier Windows version.
+*/
+static bool unbuffered_io_possible(HANDLE file, size_t io_size)
+{
+ FILE_STORAGE_INFO info;
+ if (GetFileInformationByHandleEx(
+ file, FileStorageInfo, &info, sizeof(info))) {
+ ULONG sector_size = info.LogicalBytesPerSector;
+ if (sector_size)
+ return io_size % sector_size == 0;
+ }
+ return true;
+}
+#endif
+
/****************************************************************//**
NOTE! Use the corresponding macro os_file_create(), not directly
this function!
@@ -2041,7 +2068,19 @@ os_file_create_func(
(LPCTSTR) name, access, share_mode, NULL,
create_flag, attributes, NULL);
- if (file == INVALID_HANDLE_VALUE) {
+ /* If FILE_FLAG_NO_BUFFERING was set, check if this can work at all,
+ for expected IO sizes. Reopen without the unbuffered flag, if it is won't work*/
+ if ((file.m_file != INVALID_HANDLE_VALUE)
+ && (attributes & FILE_FLAG_NO_BUFFERING)
+ && (type == OS_LOG_FILE)
+ && !unbuffered_io_possible(file.m_file, OS_FILE_LOG_BLOCK_SIZE)) {
+ ut_a(CloseHandle(file.m_file));
+ attributes &= ~FILE_FLAG_NO_BUFFERING;
+ create_flag = OPEN_ALWAYS;
+ continue;
+ }
+
+ if (file.m_file == INVALID_HANDLE_VALUE) {
const char* operation;
operation = (create_mode == OS_FILE_CREATE
diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc
index b281df670e8..83f5aca5d4c 100644
--- a/storage/xtradb/row/row0import.cc
+++ b/storage/xtradb/row/row0import.cc
@@ -111,18 +111,18 @@ struct row_index_t {
struct row_import {
row_import() UNIV_NOTHROW
:
- m_table(),
- m_version(),
- m_hostname(),
- m_table_name(),
- m_autoinc(),
- m_page_size(),
- m_flags(),
- m_n_cols(),
- m_cols(),
- m_col_names(),
- m_n_indexes(),
- m_indexes(),
+ m_table(NULL),
+ m_version(0),
+ m_hostname(NULL),
+ m_table_name(NULL),
+ m_autoinc(0),
+ m_page_size(0),
+ 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;
@@ -1298,11 +1298,57 @@ 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%lx",
- m_table->flags, ulong(m_flags));
+ " and the meta-data file has 0x%lx;"
+ " .cfg file uses %s",
+ m_table->flags, ulong(m_flags), msg);
return(DB_ERROR);
} else if (m_table->n_cols != m_n_cols) {
@@ -3898,8 +3944,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/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc
index 21f1a1c5974..d86dcb077e5 100644
--- a/storage/xtradb/row/row0log.cc
+++ b/storage/xtradb/row/row0log.cc
@@ -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) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -2703,7 +2703,15 @@ all_done:
while (!trx_is_interrupted(trx)) {
mrec = next_mrec;
- ut_ad(mrec < mrec_end);
+ ut_ad(mrec <= mrec_end);
+
+ if (mrec == mrec_end) {
+ /* We are at the end of the log.
+ Mark the replay all_done. */
+ if (has_index_lock) {
+ goto all_done;
+ }
+ }
if (!has_index_lock) {
/* We are applying operations from a different
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 1347cbdedf8..c9684d49167 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -3404,6 +3404,10 @@ row_truncate_table_for_mysql(
return (row_mysql_get_table_status(table, trx, true));
}
+ if (table->fts) {
+ fts_optimize_remove_table(table);
+ }
+
trx_start_for_ddl(trx, TRX_DICT_OP_TABLE);
trx->op_info = "truncating table";
@@ -3833,6 +3837,9 @@ next_rec:
/* Reset the Doc ID in cache to 0 */
if (has_internal_doc_id && table->fts->cache) {
+ 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);
@@ -3856,6 +3863,11 @@ funct_exit:
table->memcached_sync_count = 0;
}
+ /* Add the table back to FTS optimize background thread. */
+ if (table->fts) {
+ fts_optimize_add_table(table);
+ }
+
row_mysql_unlock_data_dictionary(trx);
dict_stats_update(table, DICT_STATS_EMPTY_TABLE);
diff --git a/storage/xtradb/trx/trx0trx.cc b/storage/xtradb/trx/trx0trx.cc
index b3d709ccf8a..a61198c54ae 100644
--- a/storage/xtradb/trx/trx0trx.cc
+++ b/storage/xtradb/trx/trx0trx.cc
@@ -2573,6 +2573,7 @@ trx_get_trx_by_xid_low(
if (trx->is_recovered
&& trx_state_eq(trx, TRX_STATE_PREPARED)
+ && !trx->xid.is_null()
&& xid->gtrid_length == trx->xid.gtrid_length
&& xid->bqual_length == trx->xid.bqual_length
&& memcmp(xid->data, trx->xid.data,
@@ -2580,8 +2581,7 @@ trx_get_trx_by_xid_low(
/* Invalidate the XID, so that subsequent calls
will not find it. */
- memset(&trx->xid, 0, sizeof(trx->xid));
- trx->xid.formatID = -1;
+ trx->xid.null();
break;
}
}
diff --git a/storage/xtradb/trx/trx0undo.cc b/storage/xtradb/trx/trx0undo.cc
index 594416ba34d..e55361ed827 100644
--- a/storage/xtradb/trx/trx0undo.cc
+++ b/storage/xtradb/trx/trx0undo.cc
@@ -1314,8 +1314,7 @@ trx_undo_mem_create_at_db_start(
/* Read X/Open XA transaction identification if it exists, or
set it to NULL. */
- memset(&xid, 0, sizeof(xid));
- xid.formatID = -1;
+ xid.null();
if (xid_exists == TRUE) {
trx_undo_read_xid(undo_header, &xid);
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 19caa22edb4..cb2b8b8ac76 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 d6e5f02d463..400ec1fbfa0 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 80bb6745b19..687796bdcbb 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 a73de37bbd7..c095cc7d74d 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/support-files/CMakeLists.txt b/support-files/CMakeLists.txt
index dff4610d490..4ad3810e082 100644
--- a/support-files/CMakeLists.txt
+++ b/support-files/CMakeLists.txt
@@ -41,12 +41,14 @@ ELSE()
SET(inst_location ${INSTALL_SUPPORTFILESDIR})
ENDIF()
+IF (NOT WITHOUT_SERVER)
FOREACH(inifile my-huge my-innodb-heavy-4G my-large my-medium my-small)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${inifile}.cnf.sh
${CMAKE_CURRENT_BINARY_DIR}/${inifile}.${ini_file_extension} @ONLY)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${inifile}.${ini_file_extension}
DESTINATION ${inst_location} COMPONENT IniFiles)
ENDFOREACH()
+ENDIF()
IF(WITH_WSREP)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/wsrep.cnf.sh