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