summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2020-09-02 14:36:14 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2020-09-02 14:36:14 +0200
commit5edf3e03887142f83044ee9fcc8fcf65386c43c7 (patch)
tree179e1f56be501aeb8ed2a975ee49efad5e5144dd
parent32a29afea777d8bbfcea7a2b5e6e5ee674013cb5 (diff)
parentc58e184b14ccdf0b0eaeeeb7947e23b8b5fff7a7 (diff)
downloadmariadb-git-5edf3e03887142f83044ee9fcc8fcf65386c43c7.tar.gz
Merge branch '10.5' into 10.6
-rw-r--r--.github/CODEOWNERS2
-rwxr-xr-xBUILD/SETUP.sh5
-rw-r--r--CMakeLists.txt7
-rw-r--r--client/mysqltest.cc10
-rw-r--r--extra/mariabackup/backup_copy.cc2
-rw-r--r--include/ilist.h11
-rw-r--r--include/my_dbug.h5
-rw-r--r--include/my_stacktrace.h15
-rw-r--r--include/my_sys.h4
-rw-r--r--libmysqld/emb_qcache.cc4
-rw-r--r--libmysqld/emb_qcache.h1
-rw-r--r--libmysqld/lib_sql.cc11
-rw-r--r--libmysqld/libmysql.c5
-rw-r--r--mysql-test/include/restart_mysqld.inc2
-rw-r--r--mysql-test/include/rpl_stop_server.inc4
-rw-r--r--mysql-test/include/search_pattern_in_file.inc2
-rw-r--r--mysql-test/include/shutdown_mysqld.inc2
-rw-r--r--mysql-test/main/empty_server_name-8224.test2
-rw-r--r--mysql-test/main/host_cache_size_functionality.test4
-rw-r--r--mysql-test/main/init_file_set_password-7656.test2
-rw-r--r--mysql-test/main/log_errchk.test2
-rw-r--r--mysql-test/main/mysql_tzinfo_to_sql_symlink.result6
-rw-r--r--mysql-test/main/type_datetime.result4
-rw-r--r--mysql-test/main/type_datetime.test5
-rw-r--r--mysql-test/main/type_time.result122
-rw-r--r--mysql-test/main/type_time.test60
-rw-r--r--mysql-test/suite/binlog/t/binlog_max_extension.test4
-rw-r--r--mysql-test/suite/binlog_encryption/restart_server.inc2
-rw-r--r--mysql-test/suite/galera/r/galera_ist_progress.result17
-rw-r--r--mysql-test/suite/galera/r/mdev-22543.result19
-rw-r--r--mysql-test/suite/galera/t/galera_ist_progress.test13
-rw-r--r--mysql-test/suite/galera/t/mdev-22543.test58
-rw-r--r--mysql-test/suite/galera_3nodes/r/GCF-354.result3
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_join_with_cc_A.result41
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_join_with_cc_B.result41
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_join_with_cc_C.result44
-rw-r--r--mysql-test/suite/innodb/include/alter_table_pk_no_sort.inc7
-rw-r--r--mysql-test/suite/innodb/r/alter_table.result7
-rw-r--r--mysql-test/suite/innodb/r/foreign_key.result31
-rw-r--r--mysql-test/suite/innodb/r/innodb-64k.result7
-rw-r--r--mysql-test/suite/innodb/r/innodb-index-debug.result5
-rw-r--r--mysql-test/suite/innodb/r/innodb-index.result5
-rw-r--r--mysql-test/suite/innodb/r/innodb.result2
-rw-r--r--mysql-test/suite/innodb/r/instant_alter_bugs.result6
-rw-r--r--mysql-test/suite/innodb/t/alter_table.test9
-rw-r--r--mysql-test/suite/innodb/t/foreign_key.test29
-rw-r--r--mysql-test/suite/innodb/t/innodb-64k.test9
-rw-r--r--mysql-test/suite/innodb/t/innodb-corrupted-table.test2
-rw-r--r--mysql-test/suite/innodb/t/innodb.test2
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug60196.test4
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_bugs.test7
-rw-r--r--mysql-test/suite/maria/maria-connect.result2
-rw-r--r--mysql-test/suite/multi_source/info_logs.test2
-rw-r--r--mysql-test/suite/roles/acl_load_mutex-5170.test2
-rw-r--r--mysql-test/suite/rpl/include/rpl_shutdown_wait_slaves.inc2
-rw-r--r--mysql-test/suite/rpl/t/rpl_gtid_crash.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_gtid_stop_start.test18
-rw-r--r--mysql-test/suite/rpl/t/rpl_mdev12179.test10
-rw-r--r--mysql-test/suite/rpl/t/rpl_mdev382.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_parallel_partition.test2
-rw-r--r--mysql-test/suite/storage_engine/alter_tablespace.test2
-rw-r--r--mysql-test/suite/storage_engine/trx/xa_recovery.test2
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb.result2
-rw-r--r--mysql-test/suite/wsrep/r/MDEV-22443.result3
-rw-r--r--mysql-test/suite/wsrep/r/MDEV-23092.result13
-rw-r--r--mysql-test/suite/wsrep/r/MDEV-23466.result3
-rw-r--r--mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result4
-rw-r--r--mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result4
-rw-r--r--mysql-test/suite/wsrep/t/MDEV-22443.cnf8
-rw-r--r--mysql-test/suite/wsrep/t/MDEV-22443.test12
-rw-r--r--mysql-test/suite/wsrep/t/MDEV-23092.cnf8
-rw-r--r--mysql-test/suite/wsrep/t/MDEV-23092.test22
-rw-r--r--mysql-test/suite/wsrep/t/MDEV-23466.cnf8
-rw-r--r--mysql-test/suite/wsrep/t/MDEV-23466.test10
-rw-r--r--mysys/crc32/crc32_arm64.c428
-rw-r--r--mysys/stacktrace.c152
-rw-r--r--mysys/thr_mutex.c4
-rw-r--r--plugin/handler_socket/CMakeLists.txt5
-rw-r--r--plugin/server_audit/server_audit.c60
-rw-r--r--scripts/mysqld_multi.sh14
-rw-r--r--scripts/wsrep_sst_mariabackup.sh25
-rw-r--r--scripts/wsrep_sst_rsync.sh8
-rw-r--r--sql-common/client.c6
-rw-r--r--sql/CMakeLists.txt2
-rw-r--r--sql/backup.cc5
-rw-r--r--sql/field.cc197
-rw-r--r--sql/field.h65
-rw-r--r--sql/filesort.cc4
-rw-r--r--sql/ha_partition.cc8
-rw-r--r--sql/item.cc31
-rw-r--r--sql/item.h18
-rw-r--r--sql/item_func.h14
-rw-r--r--sql/item_geofunc.cc17
-rw-r--r--sql/item_strfunc.cc6
-rw-r--r--sql/item_timefunc.h4
-rw-r--r--sql/mdl.cc27
-rw-r--r--sql/mysqld.cc3
-rw-r--r--sql/mysqld.h6
-rw-r--r--sql/protocol.cc110
-rw-r--r--sql/protocol.h97
-rw-r--r--sql/share/errmsg-utf8.txt2
-rw-r--r--sql/slave.cc2
-rw-r--r--sql/sql_audit.h29
-rw-r--r--sql/sql_class.cc55
-rw-r--r--sql/sql_class.h7
-rw-r--r--sql/sql_connect.cc2
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_prepare.cc904
-rw-r--r--sql/sql_prepare.h5
-rw-r--r--sql/sql_profile.cc6
-rw-r--r--sql/sql_repl.cc6
-rw-r--r--sql/sql_select.cc5
-rw-r--r--sql/sql_show.cc4
-rw-r--r--sql/sql_type.cc104
-rw-r--r--sql/sql_type.h19
-rw-r--r--sql/sql_yacc.yy12
-rw-r--r--sql/threadpool_generic.cc11
-rw-r--r--sql/tztime.cc3
-rw-r--r--sql/wsrep_mysqld.cc2
-rw-r--r--sql/wsrep_sst.cc14
-rw-r--r--sql/wsrep_sst.h2
-rw-r--r--sql/wsrep_var.cc11
-rw-r--r--storage/innobase/btr/btr0btr.cc1
-rw-r--r--storage/innobase/btr/btr0cur.cc21
-rw-r--r--storage/innobase/buf/buf0buf.cc4
-rw-r--r--storage/innobase/dict/dict0crea.cc6
-rw-r--r--storage/innobase/dict/dict0dict.cc4
-rw-r--r--storage/innobase/dict/dict0load.cc4
-rw-r--r--storage/innobase/dict/dict0mem.cc2
-rw-r--r--storage/innobase/dict/dict0stats.cc6
-rw-r--r--storage/innobase/fil/fil0crypt.cc33
-rw-r--r--storage/innobase/fil/fil0fil.cc34
-rw-r--r--storage/innobase/fil/fil0pagecompress.cc32
-rw-r--r--storage/innobase/fts/fts0fts.cc38
-rw-r--r--storage/innobase/fts/fts0opt.cc5
-rw-r--r--storage/innobase/fts/fts0que.cc4
-rw-r--r--storage/innobase/handler/ha_innodb.cc61
-rw-r--r--storage/innobase/handler/handler0alter.cc38
-rw-r--r--storage/innobase/handler/i_s.cc6
-rw-r--r--storage/innobase/include/dict0mem.h2
-rw-r--r--storage/innobase/include/fil0fil.h5
-rw-r--r--storage/innobase/include/fts0ast.h8
-rw-r--r--storage/innobase/include/log0log.h5
-rw-r--r--storage/innobase/include/log0recv.h2
-rw-r--r--storage/innobase/include/read0types.h21
-rw-r--r--storage/innobase/include/trx0sys.h2
-rw-r--r--storage/innobase/include/trx0trx.h23
-rw-r--r--storage/innobase/include/ut0pool.h36
-rw-r--r--storage/innobase/log/log0log.cc11
-rw-r--r--storage/innobase/log/log0recv.cc76
-rw-r--r--storage/innobase/page/page0cur.cc9
-rw-r--r--storage/innobase/page/page0page.cc57
-rw-r--r--storage/innobase/row/row0ftsort.cc2
-rw-r--r--storage/innobase/row/row0import.cc2
-rw-r--r--storage/innobase/row/row0merge.cc2
-rw-r--r--storage/innobase/row/row0mysql.cc18
-rw-r--r--storage/innobase/row/row0uins.cc7
-rw-r--r--storage/innobase/row/row0umod.cc57
-rw-r--r--storage/innobase/row/row0undo.cc18
-rw-r--r--storage/innobase/srv/srv0srv.cc12
-rw-r--r--storage/innobase/trx/trx0purge.cc2
-rw-r--r--storage/innobase/trx/trx0roll.cc2
-rw-r--r--storage/innobase/trx/trx0trx.cc230
-rw-r--r--storage/innobase/ut/ut0crc32.cc6
-rw-r--r--storage/maria/aria_chk.c2
-rw-r--r--storage/maria/ma_create.c10
-rw-r--r--storage/maria/ma_loghandler.c3
-rw-r--r--storage/myisam/mi_create.c1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/include/restart_mysqld_with_option.inc2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/mysqldump2.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/optimize_table.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/persistent_cache.test4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/shutdown.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test8
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/mdev12179.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_rate_limiter_bytes_per_sec_basic.test4
-rw-r--r--strings/ctype-ucs2.c2
-rw-r--r--support-files/mariadb@.service.in2
-rw-r--r--support-files/policy/apparmor/usr.sbin.mysqld4
-rw-r--r--unittest/mysys/CMakeLists.txt2
-rw-r--r--unittest/mysys/stacktrace-t.c67
-rw-r--r--win/packaging/CMakeLists.txt2
-rw-r--r--win/upgrade_wizard/CMakeLists.txt15
185 files changed, 2859 insertions, 1536 deletions
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 00000000000..538007ed62d
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,2 @@
+/debian @ottok
+
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index 94e21df15a1..0fd3ee7597a 100755
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -313,10 +313,11 @@ gcov_configs="--with-gcov"
# gprof
-gprof_compile_flags="-O2 -pg -g"
+gprof_compile_flags="-O2"
+# Rest of the flags are set in CmakeFile.txt
gprof_link_flags="--disable-shared $static_link"
-disable_gprof_plugins="--with-zlib-dir=bundled --without-plugin-oqgraph --without-plugin-mroonga"
+disable_gprof_plugins="--with-zlib-dir=bundled --without-plugin-oqgraph --without-plugin-mroonga --with-gprof"
disable_asan_plugins="--without-plugin-rocksdb"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 80fac4b2ccc..36922e04368 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -242,13 +242,18 @@ IF (WITH_MSAN)
MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=memory -fsanitize-memory-track-origins -U_FORTIFY_SOURCE" DEBUG RELWITHDEBINFO)
ENDIF()
+OPTION(WITH_GPROF "Enable profilingg with gprof" OFF)
+IF (WITH_GPROF)
+ MY_CHECK_AND_SET_COMPILER_FLAG("-pg -g -no-pie -fPIC")
+ENDIF()
+
# Be nice to profilers etc
MY_CHECK_AND_SET_COMPILER_FLAG("-fno-omit-frame-pointer" RELWITHDEBINFO)
# enable security hardening features, like most distributions do
# in our benchmarks that costs about ~1% of performance, depending on the load
OPTION(SECURITY_HARDENED "Use security-enhancing compiler features (stack protector, relro, etc)" ON)
-IF(SECURITY_HARDENED AND NOT WITH_ASAN AND NOT WITH_UBSAN AND NOT WITH_TSAN)
+IF(SECURITY_HARDENED AND NOT WITH_ASAN AND NOT WITH_UBSAN AND NOT WITH_TSAN AND NOT WITH_GPROF)
# security-enhancing flags
MY_CHECK_AND_SET_COMPILER_FLAG("-pie -fPIC")
MY_CHECK_AND_SET_LINKER_FLAG("-Wl,-z,relro,-z,now")
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 6b829ccb8be..f8238cbb26d 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -184,7 +184,7 @@ static uint opt_tail_lines= 0;
static uint opt_connect_timeout= 0;
static uint opt_wait_for_pos_timeout= 0;
-
+static const uint default_wait_for_pos_timeout= 300;
static char delimiter[MAX_DELIMITER_LENGTH]= ";";
static size_t delimiter_length= 1;
@@ -5079,6 +5079,8 @@ void do_shutdown_server(struct st_command *command)
};
DBUG_ENTER("do_shutdown_server");
+ /* the wait-for-pos' default based value of 'timeout' must fit to MDEV-23511 */
+ compile_time_assert(default_wait_for_pos_timeout / 5 >= 60);
check_command_args(command, command->first_argument, shutdown_args,
sizeof(shutdown_args)/sizeof(struct command_arg),
' ');
@@ -7058,7 +7060,7 @@ static struct my_option my_long_options[] =
{"wait_for_pos_timeout", 0,
"Number of seconds to wait for master_pos_wait",
&opt_wait_for_pos_timeout, &opt_wait_for_pos_timeout, 0, GET_UINT,
- REQUIRED_ARG, 300, 0, 3600 * 12, 0, 0, 0},
+ REQUIRED_ARG, default_wait_for_pos_timeout, 0, 3600 * 12, 0, 0, 0},
{"plugin_dir", 0, "Directory for client-side plugins.",
&opt_plugin_dir, &opt_plugin_dir, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -9085,10 +9087,6 @@ static void init_signal_handling(void)
struct sigaction sa;
DBUG_ENTER("init_signal_handling");
-#ifdef HAVE_STACKTRACE
- my_init_stacktrace(0);
-#endif
-
sa.sa_flags = SA_RESETHAND | SA_NODEFER;
sigemptyset(&sa.sa_mask);
sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL);
diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc
index 9cba5600849..c4dee56edd1 100644
--- a/extra/mariabackup/backup_copy.cc
+++ b/extra/mariabackup/backup_copy.cc
@@ -1721,7 +1721,7 @@ apply_log_finish()
bool
copy_back()
{
- bool ret;
+ bool ret = false;
datadir_iter_t *it = NULL;
datadir_node_t node;
char *dst_dir;
diff --git a/include/ilist.h b/include/ilist.h
index 822f0334022..92812ba8f5d 100644
--- a/include/ilist.h
+++ b/include/ilist.h
@@ -19,6 +19,8 @@
#ifndef ILIST_H
#define ILIST_H
+#include "my_dbug.h"
+
#include <cstddef>
#include <iterator>
@@ -73,11 +75,13 @@ public:
typedef T *pointer;
typedef T &reference;
- Iterator(ListNode *node) noexcept : node_(node) {}
+ Iterator(ListNode *node) noexcept : node_(node)
+ { DBUG_ASSERT(node_ != nullptr); }
Iterator &operator++() noexcept
{
node_= node_->next;
+ DBUG_ASSERT(node_ != nullptr);
return *this;
}
Iterator operator++(int) noexcept
@@ -90,6 +94,7 @@ public:
Iterator &operator--() noexcept
{
node_= node_->prev;
+ DBUG_ASSERT(node_ != nullptr);
return *this;
}
Iterator operator--(int) noexcept
@@ -184,8 +189,8 @@ public:
#ifndef DBUG_OFF
ListNode *curr= pos.node_;
- curr->prev= NULL;
- curr->next= NULL;
+ curr->prev= nullptr;
+ curr->next= nullptr;
#endif
return next;
diff --git a/include/my_dbug.h b/include/my_dbug.h
index f0c74ab485c..fa5b4c126d1 100644
--- a/include/my_dbug.h
+++ b/include/my_dbug.h
@@ -106,6 +106,9 @@ extern int (*dbug_sanity)(void);
(_db_keyword_(0,(keyword), 1) ? (a1) : (a2))
#define DBUG_PRINT(keyword,arglist) \
do if (_db_pargs_(__LINE__,keyword)) _db_doprnt_ arglist; while(0)
+
+#define DBUG_PUSH_EMPTY if (_dbug_on_) { DBUG_PUSH(""); }
+#define DBUG_POP_EMPTY if (_dbug_on_) { DBUG_POP(); }
#define DBUG_PUSH(a1) _db_push_ (a1)
#define DBUG_POP() _db_pop_ ()
#define DBUG_SET(a1) _db_set_ (a1)
@@ -172,6 +175,8 @@ extern void _db_suicide_(void);
#define DBUG_EVALUATE(keyword,a1,a2) (a2)
#define DBUG_EVALUATE_IF(keyword,a1,a2) (a2)
#define DBUG_PRINT(keyword,arglist) do { } while(0)
+#define DBUG_PUSH_EMPTY do { } while(0)
+#define DBUG_POP_EMPTY do { } while(0)
#define DBUG_PUSH(a1) do { } while(0)
#define DBUG_SET(a1) do { } while(0)
#define DBUG_SET_INITIAL(a1) do { } while(0)
diff --git a/include/my_stacktrace.h b/include/my_stacktrace.h
index 63e97dbc4f2..20b86f45232 100644
--- a/include/my_stacktrace.h
+++ b/include/my_stacktrace.h
@@ -1,5 +1,6 @@
/*
Copyright (c) 2001, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2020, 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
@@ -41,19 +42,21 @@
C_MODE_START
#if defined(HAVE_STACKTRACE) || defined(HAVE_BACKTRACE)
-void my_init_stacktrace(int setup_handlers);
void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack,
my_bool silent);
int my_safe_print_str(const char* val, size_t max_len);
void my_write_core(int sig);
-#if BACKTRACE_DEMANGLE
+# if BACKTRACE_DEMANGLE
char *my_demangle(const char *mangled_name, int *status);
-#endif /* BACKTRACE_DEMANGLE */
-#ifdef __WIN__
+# endif /* BACKTRACE_DEMANGLE */
+# ifdef __WIN__
+# define my_setup_stacktrace()
void my_set_exception_pointers(EXCEPTION_POINTERS *ep);
-#endif /* __WIN__ */
+# else
+void my_setup_stacktrace(void);
+# endif /* __WIN__ */
#else
-#define my_init_stacktrace(A) do { } while(0)
+# define my_setup_stacktrace()
#endif /* ! (defined(HAVE_STACKTRACE) || defined(HAVE_BACKTRACE)) */
#ifndef _WIN32
diff --git a/include/my_sys.h b/include/my_sys.h
index 9e26aa4f8f4..68e52d13fff 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -915,9 +915,7 @@ extern MYSQL_PLUGIN_IMPORT my_crc32_t my_checksum;
#if defined(__GNUC__) && defined(HAVE_ARMV8_CRC)
int crc32_aarch64_available(void);
-#if defined(HAVE_ARMV8_CRYPTO)
-int crc32c_aarch64_available(void);
-#endif
+const char *crc32c_aarch64_available(void);
#endif
#ifdef DBUG_ASSERT_EXISTS
diff --git a/libmysqld/emb_qcache.cc b/libmysqld/emb_qcache.cc
index 33de60e92ac..31f4cf111ee 100644
--- a/libmysqld/emb_qcache.cc
+++ b/libmysqld/emb_qcache.cc
@@ -491,8 +491,8 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src)
*prev_row= NULL;
data->embedded_info->prev_ptr= prev_row;
return_ok:
- net_send_eof(thd, thd->server_status,
- thd->get_stmt_da()->current_statement_warn_count());
+ thd->protocol->net_send_eof(thd, thd->server_status,
+ thd->get_stmt_da()->current_statement_warn_count());
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
diff --git a/libmysqld/emb_qcache.h b/libmysqld/emb_qcache.h
index c4268752f9a..e3b6339ba3a 100644
--- a/libmysqld/emb_qcache.h
+++ b/libmysqld/emb_qcache.h
@@ -81,4 +81,3 @@ public:
uint emb_count_querycache_size(THD *thd);
int emb_load_querycache_result(THD *thd, Querycache_stream *src);
void emb_store_querycache_result(Querycache_stream *dst, THD* thd);
-bool net_send_eof(THD *thd, uint server_status, uint total_warn_count);
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index eb3cf9cd8e3..21227e78a39 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -1138,7 +1138,7 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags)
for (uint pos= 0 ; (item= it++); pos++)
{
- if (prot.store_field_metadata(thd, item, pos))
+ if (prot.store_item_metadata(thd, item, pos))
goto err;
}
@@ -1253,8 +1253,7 @@ bool Protocol_binary::write()
@retval FALSE Success
*/
-bool
-net_send_ok(THD *thd,
+bool Protocol::net_send_ok(THD *thd,
uint server_status, uint statement_warn_count,
ulonglong affected_rows, ulonglong id, const char *message,
bool)
@@ -1289,7 +1288,7 @@ net_send_ok(THD *thd,
*/
bool
-net_send_eof(THD *thd, uint server_status, uint statement_warn_count)
+Protocol::net_send_eof(THD *thd, uint server_status, uint statement_warn_count)
{
bool error= write_eof_packet(thd, server_status, statement_warn_count);
thd->cur_data= 0;
@@ -1297,8 +1296,8 @@ net_send_eof(THD *thd, uint server_status, uint statement_warn_count)
}
-bool net_send_error_packet(THD *thd, uint sql_errno, const char *err,
- const char *sqlstate)
+bool Protocol::net_send_error_packet(THD *thd, uint sql_errno, const char *err,
+ const char *sqlstate)
{
uint error;
char converted_err[MYSQL_ERRMSG_SIZE];
diff --git a/libmysqld/libmysql.c b/libmysqld/libmysql.c
index e269840d674..9a17b9b4f09 100644
--- a/libmysqld/libmysql.c
+++ b/libmysqld/libmysql.c
@@ -1087,11 +1087,6 @@ unsigned int STDCALL mysql_field_count(MYSQL *mysql)
return mysql->field_count;
}
-my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql)
-{
- return mysql->affected_rows;
-}
-
my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql)
{
return mysql->insert_id;
diff --git a/mysql-test/include/restart_mysqld.inc b/mysql-test/include/restart_mysqld.inc
index 3d3e55db4ac..689f3b8cc1f 100644
--- a/mysql-test/include/restart_mysqld.inc
+++ b/mysql-test/include/restart_mysqld.inc
@@ -1,6 +1,6 @@
# ==== Usage ====
#
-# [--let $shutdown_timeout= 30]
+# [--let $shutdown_timeout= 60]
# [--let $allow_rpl_inited= 1]
# --source include/restart_mysqld.inc
diff --git a/mysql-test/include/rpl_stop_server.inc b/mysql-test/include/rpl_stop_server.inc
index 978cfec1885..049c3d5bbd2 100644
--- a/mysql-test/include/rpl_stop_server.inc
+++ b/mysql-test/include/rpl_stop_server.inc
@@ -47,8 +47,8 @@ if ($rpl_debug)
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect
# Send shutdown to the connected server and give
-# it 60 seconds to die before zapping it
-shutdown_server 60;
+# it 60 seconds (of mysqltest's default) to die before zapping it
+shutdown_server;
--source include/wait_until_disconnected.inc
diff --git a/mysql-test/include/search_pattern_in_file.inc b/mysql-test/include/search_pattern_in_file.inc
index 6cd725c3698..a899a9294cc 100644
--- a/mysql-test/include/search_pattern_in_file.inc
+++ b/mysql-test/include/search_pattern_in_file.inc
@@ -39,7 +39,7 @@
# # Stop the server
# let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
# --exec echo "wait" > $restart_file
-# --shutdown_server 10
+# --shutdown_server
# --source include/wait_until_disconnected.inc
#
# --error 1
diff --git a/mysql-test/include/shutdown_mysqld.inc b/mysql-test/include/shutdown_mysqld.inc
index c787c2b8c3f..db0cfb82c68 100644
--- a/mysql-test/include/shutdown_mysqld.inc
+++ b/mysql-test/include/shutdown_mysqld.inc
@@ -1,6 +1,6 @@
# ==== Usage ====
#
-# [--let $shutdown_timeout= 30]
+# [--let $shutdown_timeout= 60]
# [--let $allow_rpl_inited= 1]
# --source include/shutdown_mysqld.inc
diff --git a/mysql-test/main/empty_server_name-8224.test b/mysql-test/main/empty_server_name-8224.test
index b15e9d82eb8..5c5140be2e0 100644
--- a/mysql-test/main/empty_server_name-8224.test
+++ b/mysql-test/main/empty_server_name-8224.test
@@ -4,7 +4,7 @@
--source include/not_embedded.inc
create server '' foreign data wrapper w2 options (host '127.0.0.1');
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
---shutdown_server 10
+--shutdown_server
--source include/wait_until_disconnected.inc
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
diff --git a/mysql-test/main/host_cache_size_functionality.test b/mysql-test/main/host_cache_size_functionality.test
index db4f64fd493..9ec26010ab6 100644
--- a/mysql-test/main/host_cache_size_functionality.test
+++ b/mysql-test/main/host_cache_size_functionality.test
@@ -44,7 +44,7 @@ select @@global.Host_Cache_Size > 0;
let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
--exec echo "wait" > $restart_file
---shutdown_server 10
+--shutdown_server
--source include/wait_until_disconnected.inc
-- exec echo "restart:--host_cache_size=1 " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- enable_reconnect
@@ -143,7 +143,7 @@ SELECT Host_Cache_Size = @@SESSION.Host_Cache_Size;
#let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
#--exec echo "wait" > $restart_file
-#--shutdown_server 10
+#--shutdown_server
#--source include/wait_until_disconnected.inc
#-- exec echo "restart:--bind-address=$bind_ip " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
#-- enable_reconnect
diff --git a/mysql-test/main/init_file_set_password-7656.test b/mysql-test/main/init_file_set_password-7656.test
index c695d01b675..5e7a24fcf7f 100644
--- a/mysql-test/main/init_file_set_password-7656.test
+++ b/mysql-test/main/init_file_set_password-7656.test
@@ -15,7 +15,7 @@ EOF
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
---shutdown_server 10
+--shutdown_server
--source include/wait_until_disconnected.inc
--exec echo "restart:--init-file=$MYSQLTEST_VARDIR/init.file " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
diff --git a/mysql-test/main/log_errchk.test b/mysql-test/main/log_errchk.test
index 2808458e9f1..1afc0e29f3a 100644
--- a/mysql-test/main/log_errchk.test
+++ b/mysql-test/main/log_errchk.test
@@ -31,7 +31,7 @@
--echo # and slow query log file.
# Restart server with fifo file as general log file.
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
---shutdown_server 60
+--shutdown_server
--source include/wait_until_disconnected.inc
--enable_reconnect
# Write file to make mysql-test-run.pl start up the server again
diff --git a/mysql-test/main/mysql_tzinfo_to_sql_symlink.result b/mysql-test/main/mysql_tzinfo_to_sql_symlink.result
index 9de067b0e3f..a7426327ecf 100644
--- a/mysql-test/main/mysql_tzinfo_to_sql_symlink.result
+++ b/mysql-test/main/mysql_tzinfo_to_sql_symlink.result
@@ -15,6 +15,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -32,6 +33,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/ignored.tab' as time zone. Skipping it.
Warning: Skipping directory 'MYSQLTEST_VARDIR/zoneinfo/posix/posix': to avoid infinite symlink recursion.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
\d |
@@ -57,6 +59,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -71,6 +74,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
(@time_zone_id, 0, 0, 0, 'GMT')
;
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
\d |
@@ -160,6 +164,8 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
\d |
diff --git a/mysql-test/main/type_datetime.result b/mysql-test/main/type_datetime.result
index 5b27d02d28f..3c1baf82167 100644
--- a/mysql-test/main/type_datetime.result
+++ b/mysql-test/main/type_datetime.result
@@ -57,6 +57,7 @@ select * from t1;
t
0000-00-00 00:00:00
drop table t1;
+SET TIMESTAMP=UNIX_TIMESTAMP('2020-08-11 00:00:01');
CREATE TABLE t1 (a timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, b date, c time, d datetime);
insert into t1 (b,c,d) values(now(),curtime(),now());
Warnings:
@@ -65,6 +66,7 @@ select date_format(a,"%Y-%m-%d")=b,right(a+0,6)=c+0,a=d+0 from t1;
date_format(a,"%Y-%m-%d")=b right(a+0,6)=c+0 a=d+0
1 1 1
drop table t1;
+SET TIMESTAMP=DEFAULT;
CREATE TABLE t1 (a datetime not null);
insert into t1 values (0);
select * from t1 where a is null;
@@ -298,8 +300,10 @@ f2 f3
select f2 from t1 where DATE(f2) between "2001-4-15" AND "01-4-15";
f2
2001-04-15 00:00:00
+SET timestamp=UNIX_TIMESTAMP('2001-01-01 00:00:01');
SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
1
+SET timestamp=DEFAULT;
drop table t1;
create table t1 (f1 date);
insert into t1 values('01-01-01'),('01-01-02'),('01-01-03');
diff --git a/mysql-test/main/type_datetime.test b/mysql-test/main/type_datetime.test
index c8ad240d817..4fddf1c1a74 100644
--- a/mysql-test/main/type_datetime.test
+++ b/mysql-test/main/type_datetime.test
@@ -32,10 +32,12 @@ drop table t1;
# Test insert of now() and curtime()
#
+SET TIMESTAMP=UNIX_TIMESTAMP('2020-08-11 00:00:01');
CREATE TABLE t1 (a timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, b date, c time, d datetime);
insert into t1 (b,c,d) values(now(),curtime(),now());
select date_format(a,"%Y-%m-%d")=b,right(a+0,6)=c+0,a=d+0 from t1;
drop table t1;
+SET TIMESTAMP=DEFAULT;
#
# Test of datetime and not null
@@ -201,6 +203,7 @@ drop table t1;
#
# Bug#16377: Wrong DATE/DATETIME comparison in BETWEEN function.
#
+
create table t1 (f1 date, f2 datetime, f3 timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
insert into t1 values('2001-01-01','2001-01-01 01:01:01','2001-01-01 01:01:01');
insert into t1 values('2001-02-05','2001-02-05 00:00:00','2001-02-05 01:01:01');
@@ -214,7 +217,9 @@ select f1, f2, f3 from t1 where cast(f1 as datetime) between f2 and
select f2 from t1 where '2001-04-10 12:34:56' between f2 and '01-05-01';
select f2, f3 from t1 where '01-03-10' between f2 and f3;
select f2 from t1 where DATE(f2) between "2001-4-15" AND "01-4-15";
+SET timestamp=UNIX_TIMESTAMP('2001-01-01 00:00:01');
SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
+SET timestamp=DEFAULT;
drop table t1;
#
diff --git a/mysql-test/main/type_time.result b/mysql-test/main/type_time.result
index 8ef8e981f57..ead494e3ace 100644
--- a/mysql-test/main/type_time.result
+++ b/mysql-test/main/type_time.result
@@ -2286,5 +2286,127 @@ SELECT '1972-11-06 16:58:58' < TIME'20:31:05';
'1972-11-06 16:58:58' < TIME'20:31:05'
1
#
+# MDEV-23525 Wrong result of MIN(time_expr) and MAX(time_expr) with GROUP BY
+#
+SET timestamp=UNIX_TIMESTAMP('2020-08-21 18:19:20');
+CREATE PROCEDURE p1()
+BEGIN
+SELECT MIN(t), MAX(t) FROM t1;
+SELECT i, MIN(t), MAX(t) FROM t1 GROUP BY i;
+SELECT i, MIN(COALESCE(t)), MAX(COALESCE(t)) FROM t1 GROUP BY i;
+SELECT i, MIN(t+INTERVAL 1 SECOND), MAX(t+INTERVAL 1 SECOND) FROM t1 GROUP BY i;
+SELECT i, MIN(TIME'10:20:30'+INTERVAL 1 SECOND) FROM t1 GROUP BY i;
+SELECT i, MIN(CURRENT_TIME), MAX(CURRENT_TIME) FROM t1 GROUP BY i;
+SELECT
+i,
+MIN((SELECT MAX(CURRENT_TIME) FROM t1)),
+MAX((SELECT MAX(CURRENT_TIME) FROM t1))
+FROM t1 GROUP BY i;
+SELECT
+i,
+MIN(NAME_CONST('name',TIME'10:20:30')),
+MAX(NAME_CONST('name',TIME'10:20:30'))
+FROM t1 GROUP BY i;
+EXECUTE IMMEDIATE "SELECT i, MIN(?),MAX(?) FROM t1 GROUP BY i"
+ USING TIME'10:20:30', TIME'10:20:30';
+END;
+$$
+CREATE TABLE t1 (i INT, t TIME);
+INSERT INTO t1 VALUES (1,'10:20:30');
+INSERT INTO t1 VALUES (1,'100:20:20');
+CALL p1;
+MIN(t) MAX(t)
+10:20:30 100:20:20
+i MIN(t) MAX(t)
+1 10:20:30 100:20:20
+i MIN(COALESCE(t)) MAX(COALESCE(t))
+1 10:20:30 100:20:20
+i MIN(t+INTERVAL 1 SECOND) MAX(t+INTERVAL 1 SECOND)
+1 10:20:31 100:20:21
+i MIN(TIME'10:20:30'+INTERVAL 1 SECOND)
+1 10:20:31
+i MIN(CURRENT_TIME) MAX(CURRENT_TIME)
+1 18:19:20 18:19:20
+i MIN((SELECT MAX(CURRENT_TIME) FROM t1)) MAX((SELECT MAX(CURRENT_TIME) FROM t1))
+1 18:19:20 18:19:20
+i MIN(NAME_CONST('name',TIME'10:20:30')) MAX(NAME_CONST('name',TIME'10:20:30'))
+1 10:20:30 10:20:30
+i MIN(?) MAX(?)
+1 10:20:30 10:20:30
+DROP TABLE t1;
+CREATE TABLE t1 (i INT, t TIME(3));
+INSERT INTO t1 VALUES (1,'10:20:30.123');
+INSERT INTO t1 VALUES (1,'100:20:20.123');
+CALL p1;
+MIN(t) MAX(t)
+10:20:30.123 100:20:20.123
+i MIN(t) MAX(t)
+1 10:20:30.123 100:20:20.123
+i MIN(COALESCE(t)) MAX(COALESCE(t))
+1 10:20:30.123 100:20:20.123
+i MIN(t+INTERVAL 1 SECOND) MAX(t+INTERVAL 1 SECOND)
+1 10:20:31.123 100:20:21.123
+i MIN(TIME'10:20:30'+INTERVAL 1 SECOND)
+1 10:20:31
+i MIN(CURRENT_TIME) MAX(CURRENT_TIME)
+1 18:19:20 18:19:20
+i MIN((SELECT MAX(CURRENT_TIME) FROM t1)) MAX((SELECT MAX(CURRENT_TIME) FROM t1))
+1 18:19:20 18:19:20
+i MIN(NAME_CONST('name',TIME'10:20:30')) MAX(NAME_CONST('name',TIME'10:20:30'))
+1 10:20:30 10:20:30
+i MIN(?) MAX(?)
+1 10:20:30 10:20:30
+DROP TABLE t1;
+CREATE TABLE t1 (i INT, t TIME(6));
+INSERT INTO t1 VALUES (1,'10:20:30.123456');
+INSERT INTO t1 VALUES (1,'100:20:20.123456');
+CALL p1;
+MIN(t) MAX(t)
+10:20:30.123456 100:20:20.123456
+i MIN(t) MAX(t)
+1 10:20:30.123456 100:20:20.123456
+i MIN(COALESCE(t)) MAX(COALESCE(t))
+1 10:20:30.123456 100:20:20.123456
+i MIN(t+INTERVAL 1 SECOND) MAX(t+INTERVAL 1 SECOND)
+1 10:20:31.123456 100:20:21.123456
+i MIN(TIME'10:20:30'+INTERVAL 1 SECOND)
+1 10:20:31
+i MIN(CURRENT_TIME) MAX(CURRENT_TIME)
+1 18:19:20 18:19:20
+i MIN((SELECT MAX(CURRENT_TIME) FROM t1)) MAX((SELECT MAX(CURRENT_TIME) FROM t1))
+1 18:19:20 18:19:20
+i MIN(NAME_CONST('name',TIME'10:20:30')) MAX(NAME_CONST('name',TIME'10:20:30'))
+1 10:20:30 10:20:30
+i MIN(?) MAX(?)
+1 10:20:30 10:20:30
+DROP TABLE t1;
+SET @@global.mysql56_temporal_format=false;
+CREATE TABLE t1 (i INT, t TIME(6));
+INSERT INTO t1 VALUES (1,'10:20:30.123456');
+INSERT INTO t1 VALUES (1,'100:20:20.123456');
+CALL p1;
+MIN(t) MAX(t)
+10:20:30.123456 100:20:20.123456
+i MIN(t) MAX(t)
+1 10:20:30.123456 100:20:20.123456
+i MIN(COALESCE(t)) MAX(COALESCE(t))
+1 10:20:30.123456 100:20:20.123456
+i MIN(t+INTERVAL 1 SECOND) MAX(t+INTERVAL 1 SECOND)
+1 10:20:31.123456 100:20:21.123456
+i MIN(TIME'10:20:30'+INTERVAL 1 SECOND)
+1 10:20:31
+i MIN(CURRENT_TIME) MAX(CURRENT_TIME)
+1 18:19:20 18:19:20
+i MIN((SELECT MAX(CURRENT_TIME) FROM t1)) MAX((SELECT MAX(CURRENT_TIME) FROM t1))
+1 18:19:20 18:19:20
+i MIN(NAME_CONST('name',TIME'10:20:30')) MAX(NAME_CONST('name',TIME'10:20:30'))
+1 10:20:30 10:20:30
+i MIN(?) MAX(?)
+1 10:20:30 10:20:30
+DROP TABLE t1;
+SET @@global.mysql56_temporal_format=default;
+DROP PROCEDURE p1;
+SET timestamp=DEFAULT;
+#
# End of 10.4 tests
#
diff --git a/mysql-test/main/type_time.test b/mysql-test/main/type_time.test
index 521953a5078..1d4d157b976 100644
--- a/mysql-test/main/type_time.test
+++ b/mysql-test/main/type_time.test
@@ -1491,5 +1491,65 @@ DROP TABLE t1;
SELECT '1972-11-06 16:58:58' < TIME'20:31:05';
--echo #
+--echo # MDEV-23525 Wrong result of MIN(time_expr) and MAX(time_expr) with GROUP BY
+--echo #
+
+SET timestamp=UNIX_TIMESTAMP('2020-08-21 18:19:20');
+
+DELIMITER $$;
+CREATE PROCEDURE p1()
+BEGIN
+ SELECT MIN(t), MAX(t) FROM t1;
+ SELECT i, MIN(t), MAX(t) FROM t1 GROUP BY i;
+ SELECT i, MIN(COALESCE(t)), MAX(COALESCE(t)) FROM t1 GROUP BY i;
+ SELECT i, MIN(t+INTERVAL 1 SECOND), MAX(t+INTERVAL 1 SECOND) FROM t1 GROUP BY i;
+ SELECT i, MIN(TIME'10:20:30'+INTERVAL 1 SECOND) FROM t1 GROUP BY i;
+ SELECT i, MIN(CURRENT_TIME), MAX(CURRENT_TIME) FROM t1 GROUP BY i;
+ SELECT
+ i,
+ MIN((SELECT MAX(CURRENT_TIME) FROM t1)),
+ MAX((SELECT MAX(CURRENT_TIME) FROM t1))
+ FROM t1 GROUP BY i;
+ SELECT
+ i,
+ MIN(NAME_CONST('name',TIME'10:20:30')),
+ MAX(NAME_CONST('name',TIME'10:20:30'))
+ FROM t1 GROUP BY i;
+ EXECUTE IMMEDIATE "SELECT i, MIN(?),MAX(?) FROM t1 GROUP BY i"
+ USING TIME'10:20:30', TIME'10:20:30';
+END;
+$$
+DELIMITER ;$$
+
+CREATE TABLE t1 (i INT, t TIME);
+INSERT INTO t1 VALUES (1,'10:20:30');
+INSERT INTO t1 VALUES (1,'100:20:20');
+CALL p1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (i INT, t TIME(3));
+INSERT INTO t1 VALUES (1,'10:20:30.123');
+INSERT INTO t1 VALUES (1,'100:20:20.123');
+CALL p1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (i INT, t TIME(6));
+INSERT INTO t1 VALUES (1,'10:20:30.123456');
+INSERT INTO t1 VALUES (1,'100:20:20.123456');
+CALL p1;
+DROP TABLE t1;
+
+SET @@global.mysql56_temporal_format=false;
+CREATE TABLE t1 (i INT, t TIME(6));
+INSERT INTO t1 VALUES (1,'10:20:30.123456');
+INSERT INTO t1 VALUES (1,'100:20:20.123456');
+CALL p1;
+DROP TABLE t1;
+SET @@global.mysql56_temporal_format=default;
+
+DROP PROCEDURE p1;
+SET timestamp=DEFAULT;
+
+--echo #
--echo # End of 10.4 tests
--echo #
diff --git a/mysql-test/suite/binlog/t/binlog_max_extension.test b/mysql-test/suite/binlog/t/binlog_max_extension.test
index 199a31ea05c..81e357448f6 100644
--- a/mysql-test/suite/binlog/t/binlog_max_extension.test
+++ b/mysql-test/suite/binlog/t/binlog_max_extension.test
@@ -41,7 +41,7 @@ RESET MASTER;
# 1. Stop master server
-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--- shutdown_server 10
+-- shutdown_server
-- source include/wait_until_disconnected.inc
# 2. Prepare log and index file
@@ -70,7 +70,7 @@ FLUSH LOGS;
# 1. Stop the server
-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--- shutdown_server 10
+-- shutdown_server
-- source include/wait_until_disconnected.inc
# 2. Undo changes to index and log files
diff --git a/mysql-test/suite/binlog_encryption/restart_server.inc b/mysql-test/suite/binlog_encryption/restart_server.inc
index 6cd0788cf43..8f0fe7d8970 100644
--- a/mysql-test/suite/binlog_encryption/restart_server.inc
+++ b/mysql-test/suite/binlog_encryption/restart_server.inc
@@ -22,7 +22,7 @@
--enable_reconnect
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect
-shutdown_server 10;
+shutdown_server;
--source include/wait_until_disconnected.inc
diff --git a/mysql-test/suite/galera/r/galera_ist_progress.result b/mysql-test/suite/galera/r/galera_ist_progress.result
index 9fc7febbea5..9233d95b970 100644
--- a/mysql-test/suite/galera/r/galera_ist_progress.result
+++ b/mysql-test/suite/galera/r/galera_ist_progress.result
@@ -1,6 +1,12 @@
+connection node_2;
+connection node_1;
+connection node_2;
SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1';
+connection node_1;
+connection node_2;
SET SESSION wsrep_on = OFF;
SET SESSION wsrep_on = ON;
+connection node_1;
CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
INSERT INTO t1 VALUES (2);
@@ -12,8 +18,13 @@ INSERT INTO t1 VALUES (7);
INSERT INTO t1 VALUES (8);
INSERT INTO t1 VALUES (9);
INSERT INTO t1 VALUES (10);
+connection node_2;
SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 0';
-include/assert_grep.inc [Receiving IST: 11 writesets, seqnos]
-include/assert_grep.inc [Receiving IST\.\.\. 0\.0% \( 0/11 events\) complete]
-include/assert_grep.inc [Receiving IST\.\.\.100\.0% \(11/11 events\) complete]
+connection node_1;
+connection node_2;
+connection node_1;
+include/assert_grep.inc [Receiving IST: 13 writesets, seqnos 3-15]
+include/assert_grep.inc [Receiving IST\.\.\. 0\.0% \( 0/13 events\) complete]
+include/assert_grep.inc [Receiving IST\.\.\.100\.0% \(13/13 events\) complete]
+connection node_1;
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/r/mdev-22543.result b/mysql-test/suite/galera/r/mdev-22543.result
new file mode 100644
index 00000000000..9386b7405d4
--- /dev/null
+++ b/mysql-test/suite/galera/r/mdev-22543.result
@@ -0,0 +1,19 @@
+connection node_2;
+connection node_1;
+connection node_1;
+connection node_2;
+connection node_1;
+CREATE TABLE t1 (f1 INT PRIMARY KEY, f2 INT);
+INSERT INTO t1 VALUES (1, 1);
+SET DEBUG_SYNC = "before_lock_tables_takes_lock SIGNAL sync_point_reached WAIT_FOR sync_point_continue";
+UPDATE t1 SET f2 = 2 WHERE f1 = 1;
+connection node_1_ctrl;
+SET DEBUG_SYNC = "now WAIT_FOR sync_point_reached";
+connection node_2;
+connection node_1_ctrl;
+SET DEBUG_SYNC = "now SIGNAL sync_point_continue";
+connection node_1;
+SET DEBUG_SYNC = "RESET";
+connection node_2;
+connection node_1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/galera/t/galera_ist_progress.test b/mysql-test/suite/galera/t/galera_ist_progress.test
index dd93161eab8..3d7c53bd1eb 100644
--- a/mysql-test/suite/galera/t/galera_ist_progress.test
+++ b/mysql-test/suite/galera/t/galera_ist_progress.test
@@ -5,6 +5,7 @@
--source include/galera_cluster.inc
# This could cause out of storage if run /dev/shm
--source include/big_test.inc
+--source include/force_restart.inc
# Isolate node #2
--connection node_2
@@ -58,16 +59,16 @@ SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 0';
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.2.err
--let $assert_only_after = Need state transfer
---let $assert_text = Receiving IST: 1[13] writesets
---let $assert_select = Receiving IST: 1[13] writesets
+--let $assert_text = Receiving IST: 13 writesets, seqnos 3-15
+--let $assert_select = Receiving IST: 13 writesets, seqnos 3-15
--source include/assert_grep.inc
---let $assert_text = Receiving IST\.\.\. 0\.0% \( 0/11 events\) complete
---let $assert_select = Receiving IST\.\.\. 0\.0% \( 0/11 events\) complete
+--let $assert_text = Receiving IST\.\.\. 0\.0% \( 0/13 events\) complete
+--let $assert_select = Receiving IST\.\.\. 0\.0% \( 0/13 events\) complete
--source include/assert_grep.inc
---let $assert_text = Receiving IST\.\.\.100\.0% \(11/11 events\) complete
---let $assert_select = Receiving IST\.\.\.100\.0% \(11/11 events\) complete
+--let $assert_text = Receiving IST\.\.\.100\.0% \(13/13 events\) complete
+--let $assert_select = Receiving IST\.\.\.100\.0% \(13/13 events\) complete
--source include/assert_grep.inc
# Cleanup
diff --git a/mysql-test/suite/galera/t/mdev-22543.test b/mysql-test/suite/galera/t/mdev-22543.test
new file mode 100644
index 00000000000..53662e36942
--- /dev/null
+++ b/mysql-test/suite/galera/t/mdev-22543.test
@@ -0,0 +1,58 @@
+# The test verifies that the FLUSH TABLES WITH READ LOCK does not
+# time out if it needs to wait for another MDL lock for short duration
+# during SST donation.
+
+--source include/galera_cluster.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+--let $node_1 = node_1
+--let $node_2 = node_2
+--source include/auto_increment_offset_save.inc
+
+--let $galera_connection_name = node_1_ctrl
+--let $galera_server_number = 1
+--source include/galera_connect.inc
+
+#
+# Run UPDATE on node_1 and make it block before table locks are taken.
+# This should block FTWRL.
+#
+--connection node_1
+CREATE TABLE t1 (f1 INT PRIMARY KEY, f2 INT);
+INSERT INTO t1 VALUES (1, 1);
+SET DEBUG_SYNC = "before_lock_tables_takes_lock SIGNAL sync_point_reached WAIT_FOR sync_point_continue";
+--send UPDATE t1 SET f2 = 2 WHERE f1 = 1
+
+--connection node_1_ctrl
+SET DEBUG_SYNC = "now WAIT_FOR sync_point_reached";
+
+#
+# Restart node_2, force SST.
+#
+--connection node_2
+--source include/shutdown_mysqld.inc
+--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat
+# Restart without waiting. The UPDATE should block FTWRL on node_1,
+# so the SST cannot be completed and node_2 cannot join before
+# UPDATE connection is signalled to continue.
+--exec echo "restart:$start_mysqld_params" > $_expect_file_name
+# If the bug is present, FTWRL times out on node_1 in couple of
+# seconds and node_2 fails to join.
+--sleep 10
+
+--connection node_1_ctrl
+SET DEBUG_SYNC = "now SIGNAL sync_point_continue";
+
+--connection node_1
+--reap
+SET DEBUG_SYNC = "RESET";
+
+--connection node_2
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+
+--connection node_1
+DROP TABLE t1;
+
+--source include/auto_increment_offset_restore.inc
diff --git a/mysql-test/suite/galera_3nodes/r/GCF-354.result b/mysql-test/suite/galera_3nodes/r/GCF-354.result
index b7ab3014ff5..dad57fe15ec 100644
--- a/mysql-test/suite/galera_3nodes/r/GCF-354.result
+++ b/mysql-test/suite/galera_3nodes/r/GCF-354.result
@@ -5,6 +5,9 @@ SET wsrep_on=OFF;
DROP SCHEMA test;
connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3;
connection node_3;
+connection node_1;
+connection node_2;
+connection node_3;
SET wsrep_on=OFF;
CREATE TABLE test.t1 (f1 INTEGER);
connection node_1;
diff --git a/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_A.result b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_A.result
index 0461f1f1feb..a60e2bbb6cc 100644
--- a/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_A.result
+++ b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_A.result
@@ -1,40 +1,81 @@
+connection node_2;
+connection node_1;
+connection node_1;
CREATE TABLE t1 (pk INT PRIMARY KEY, node INT) ENGINE=innodb;
INSERT INTO t1 VALUES (1, 1);
+connection node_2;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+connection node_2;
+connection node_3;
INSERT INTO t1 VALUES (2, 3);
+connection node_2;
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
SET wsrep_sync_wait = 0;
SET wsrep_on = OFF;
SET GLOBAL wsrep_provider_options = 'dbug=d,after_shift_to_joining';
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+connection node_2;
INSERT INTO t1 VALUES (3, 2);
+connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 0;
+connection node_3;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+connection node_2;
+connection node_3;
INSERT INTO t1 VALUES (4, 3);
+connection node_2;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+connection node_2;
INSERT INTO t1 VALUES (5, 2);
+connection node_3;
+connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,before_send_state_request';
SET GLOBAL wsrep_provider_options = 'signal=after_shift_to_joining';
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 0;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+connection node_2;
+connection node_3;
INSERT INTO t1 VALUES (6, 3);
+connection node_2;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+connection node_2;
INSERT INTO t1 VALUES (7, 2);
+connection node_3;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+connection node_2;
+connection node_3;
INSERT INTO t1 VALUES (8, 3);
+connection node_2;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+connection node_2;
+connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,process_primary_configuration';
SET GLOBAL wsrep_provider_options = 'signal=before_send_state_request';
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 0;
+connection node_2;
INSERT INTO t1 VALUES (9, 2);
+connection node_3;
+connection node_1a;
SET GLOBAL wsrep_provider_options = 'signal=process_primary_configuration';
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 0;
SET GLOBAL wsrep_provider_options = 'signal=process_primary_configuration';
SET GLOBAL wsrep_provider_options = 'dbug=';
+connection node_1;
DROP TABLE t1;
call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+connection node_2;
call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+connection node_3;
call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
diff --git a/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_B.result b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_B.result
index d878f60ca6b..7e75bc4b08a 100644
--- a/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_B.result
+++ b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_B.result
@@ -1,18 +1,39 @@
+connection node_2;
+connection node_1;
+connection node_1;
CREATE TABLE t1 (pk INT PRIMARY KEY, node INT) ENGINE=innodb;
INSERT INTO t1 VALUES (1, 1);
+connection node_2;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+connection node_2;
+connection node_3;
INSERT INTO t1 VALUES (2, 3);
+connection node_2;
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
SET wsrep_sync_wait = 0;
SET wsrep_on = OFF;
SET GLOBAL wsrep_provider_options = 'dbug=d,after_shift_to_joining';
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+connection node_2;
INSERT INTO t1 VALUES (3, 2);
+connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 0;
+connection node_3;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+connection node_2;
+connection node_3;
INSERT INTO t1 VALUES (4, 3);
+connection node_2;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+connection node_2;
INSERT INTO t1 VALUES (5, 2);
+connection node_3;
+connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,before_send_state_request';
SET GLOBAL wsrep_provider_options = 'signal=after_shift_to_joining';
SET SESSION wsrep_on = 0;
@@ -24,18 +45,35 @@ SET SESSION wsrep_on = 0;
SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_debug_sync_waiters';
VARIABLE_NAME VARIABLE_VALUE
WSREP_DEBUG_SYNC_WAITERS after_shift_to_joining
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+connection node_2;
+connection node_3;
INSERT INTO t1 VALUES (6, 3);
+connection node_2;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+connection node_2;
INSERT INTO t1 VALUES (7, 2);
+connection node_3;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+connection node_2;
+connection node_3;
INSERT INTO t1 VALUES (8, 3);
+connection node_2;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+connection node_2;
+connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,process_primary_configuration';
SET GLOBAL wsrep_provider_options = 'signal=after_shift_to_joining';
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 0;
+connection node_2;
INSERT INTO t1 VALUES (9, 2);
+connection node_3;
+connection node_1a;
SET GLOBAL wsrep_provider_options = 'signal=process_primary_configuration';
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 0;
@@ -44,7 +82,10 @@ VARIABLE_NAME VARIABLE_VALUE
WSREP_DEBUG_SYNC_WAITERS process_primary_configuration
SET GLOBAL wsrep_provider_options = 'signal=process_primary_configuration';
SET GLOBAL wsrep_provider_options = 'dbug=';
+connection node_1;
DROP TABLE t1;
call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+connection node_2;
call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+connection node_3;
call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
diff --git a/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_C.result b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_C.result
index df0a924029c..ea10edfc62c 100644
--- a/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_C.result
+++ b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_C.result
@@ -1,44 +1,85 @@
+connection node_2;
+connection node_1;
+connection node_1;
CREATE TABLE t1 (pk INT PRIMARY KEY, node INT) ENGINE=innodb;
INSERT INTO t1 VALUES (1, 1);
+connection node_2;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+connection node_2;
+connection node_3;
INSERT INTO t1 VALUES (2, 3);
+connection node_2;
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
SET wsrep_sync_wait = 0;
SET wsrep_on = OFF;
SET GLOBAL wsrep_provider_options = 'dbug=d,after_shift_to_joining';
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+connection node_2;
INSERT INTO t1 VALUES (3, 2);
+connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 0;
+connection node_3;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+connection node_2;
+connection node_3;
INSERT INTO t1 VALUES (4, 3);
+connection node_2;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+connection node_2;
INSERT INTO t1 VALUES (5, 2);
+connection node_3;
+connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,before_send_state_request';
SET GLOBAL wsrep_provider_options = 'signal=after_shift_to_joining';
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 0;
SET GLOBAL wsrep_provider_options = 'dbug=';
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+connection node_2;
+connection node_3;
+connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,after_shift_to_joining';
SET GLOBAL wsrep_provider_options = 'signal=before_send_state_request';
4
SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_debug_sync_waiters';
VARIABLE_NAME VARIABLE_VALUE
WSREP_DEBUG_SYNC_WAITERS
+connection node_3;
INSERT INTO t1 VALUES (6, 3);
+connection node_2;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+connection node_2;
INSERT INTO t1 VALUES (7, 2);
+connection node_3;
+connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 0;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'dbug=d,process_primary_configuration';
SET GLOBAL wsrep_provider_options = 'signal=after_shift_to_joining';
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+connection node_2;
+connection node_3;
INSERT INTO t1 VALUES (8, 3);
+connection node_2;
+connection node_1;
SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+connection node_2;
+connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 0;
+connection node_2;
INSERT INTO t1 VALUES (9, 2);
+connection node_3;
+connection node_1a;
SET GLOBAL wsrep_provider_options = 'signal=process_primary_configuration';
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 0;
@@ -48,8 +89,11 @@ SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 0;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'signal=after_shift_to_joining';
+connection node_1;
DROP TABLE t1;
call mtr.add_suppression("WSREP: Send action {\(.*\), STATE_REQUEST} returned -107 \\(Transport endpoint is not connected\\)");
call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+connection node_2;
call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+connection node_3;
call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
diff --git a/mysql-test/suite/innodb/include/alter_table_pk_no_sort.inc b/mysql-test/suite/innodb/include/alter_table_pk_no_sort.inc
index 6a2fcd15be0..61e304a7626 100644
--- a/mysql-test/suite/innodb/include/alter_table_pk_no_sort.inc
+++ b/mysql-test/suite/innodb/include/alter_table_pk_no_sort.inc
@@ -263,3 +263,10 @@ create table t1(o1 int, o2 int, o3 int, primary key(o1,o2,o3)) engine = innodb;
insert into t1 values(1,1,2),(2,2,1);
alter table t1 drop primary key, add primary key(o1), lock=none;
drop table t1;
+
+# pk(o1,o2) to pk(o1,o2,autoinc) must not sort
+create table t1(o1 int, o2 int, primary key(o1,o2)) engine = innodb;
+insert into t1 values(1,1),(2,1);
+alter table t1 drop primary key, add column a int unique auto_increment,
+add primary key(o1,o2,a), algorithm=inplace;
+drop table t1;
diff --git a/mysql-test/suite/innodb/r/alter_table.result b/mysql-test/suite/innodb/r/alter_table.result
index 6e8f4d721ae..b1de6be804a 100644
--- a/mysql-test/suite/innodb/r/alter_table.result
+++ b/mysql-test/suite/innodb/r/alter_table.result
@@ -53,6 +53,13 @@ ALTER TABLE t1 DROP a;
ERROR HY000: Cannot drop index 'a': needed in a foreign key constraint
ALTER TABLE t1 ADD c INT;
DROP TABLE t1, tx;
+#
+# MDEV-14119 Assertion cmp_rec_rec() on ALTER TABLE
+#
+CREATE TABLE t1(a INT NOT NULL UNIQUE) ENGINE=InnoDB;
+INSERT INTO t1 SELECT * FROM seq_1_to_128;
+ALTER TABLE t1 ADD b TINYINT AUTO_INCREMENT PRIMARY KEY, DROP KEY a;
+DROP TABLE t1;
create table t1 (a int) transactional=1 engine=aria;
create table t2 (a int) transactional=1 engine=innodb;
show create table t1;
diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result
index 00563d397f3..854b53b3083 100644
--- a/mysql-test/suite/innodb/r/foreign_key.result
+++ b/mysql-test/suite/innodb/r/foreign_key.result
@@ -655,6 +655,7 @@ SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
# MDEV-17187 table doesn't exist in engine after ALTER other tables
# with CONSTRAINTs
#
+call mtr.add_suppression("\\[Warning\\] InnoDB: In ALTER TABLE `test`\\.`t2` has or is referenced in foreign key constraints which are not compatible with the new table definition.");
set foreign_key_checks=on;
create table t1 (id int not null primary key) engine=innodb;
create table t2 (id int not null primary key, fid int not null,
@@ -710,6 +711,32 @@ drop table t1,t2;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
drop table t1,t2;
ERROR 42S02: Unknown table 'test.t2'
+#
+# MDEV-22934 Table disappear after two alter table command
+#
+CREATE TABLE t1(f1 INT NOT NULL AUTO_INCREMENT,
+f2 INT NOT NULL,
+PRIMARY KEY (f1), INDEX (f2))ENGINE=InnoDB;
+CREATE TABLE t2(f1 INT NOT NULL,
+f2 INT NOT NULL, f3 INT NOT NULL,
+PRIMARY KEY(f1, f2), UNIQUE KEY(f2),
+CONSTRAINT `t2_ibfk_1` FOREIGN KEY (f2) REFERENCES t1(f2) ON DELETE CASCADE,
+CONSTRAINT `t2_ibfk_2` FOREIGN KEY (f1) REFERENCES t1(f1) ON DELETE CASCADE
+) ENGINE=InnoDB;
+SET FOREIGN_KEY_CHECKS=0;
+ALTER TABLE t2 DROP PRIMARY KEY, ADD PRIMARY KEY(f3), ALGORITHM=INPLACE;
+ALTER TABLE t2 DROP INDEX `f2`, ALGORITHM=COPY;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `f1` int(11) NOT NULL,
+ `f2` int(11) NOT NULL,
+ `f3` int(11) NOT NULL,
+ PRIMARY KEY (`f3`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+CREATE TABLE t2 (f1 INT NOT NULL)ENGINE=InnoDB;
+ERROR 42S01: Table 't2' already exists
+DROP TABLE t2, t1;
# End of 10.2 tests
CREATE TABLE t1 (a GEOMETRY, INDEX(a(8)),
FOREIGN KEY (a) REFERENCES x (xx)) ENGINE=InnoDB;
@@ -761,11 +788,12 @@ set default_storage_engine= default;
#
# MDEV-21690 LeakSanitizer: detected memory leaks in mem_heap_create_block_func
#
+SET FOREIGN_KEY_CHECKS=1;
CREATE TABLE t1 (a TEXT, b TEXT) ENGINE=InnoDB;
ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES t1 (b);
ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed")
+SET FOREIGN_KEY_CHECKS=DEFAULT;
DROP TABLE t1;
-# End of 10.5 tests
#
# MDEV-22602 Disable UPDATE CASCADE for SQL constraints
#
@@ -784,3 +812,4 @@ create or replace table t1 (a varchar(4096) unique) engine=innodb;
create or replace table t2 (pk int primary key, a varchar(4096) unique, foreign key(a) references t1(a) on update cascade) engine=innodb;
ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
drop table t1;
+# End of 10.5 tests
diff --git a/mysql-test/suite/innodb/r/innodb-64k.result b/mysql-test/suite/innodb/r/innodb-64k.result
index 8f8e031bce2..f8dad893d0e 100644
--- a/mysql-test/suite/innodb/r/innodb-64k.result
+++ b/mysql-test/suite/innodb/r/innodb-64k.result
@@ -1081,3 +1081,10 @@ update t2 set col145=@b;
COMMIT;
drop table t2;
DROP TABLE t1;
+#
+# MDEV-19526 heap number overflow
+#
+CREATE TABLE t1(a SMALLINT NOT NULL UNIQUE AUTO_INCREMENT, KEY(a))
+ENGINE=InnoDB;
+INSERT INTO t1 (a) SELECT seq FROM seq_1_to_8191;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/innodb-index-debug.result b/mysql-test/suite/innodb/r/innodb-index-debug.result
index 5d161e5e6ca..daef31d2caa 100644
--- a/mysql-test/suite/innodb/r/innodb-index-debug.result
+++ b/mysql-test/suite/innodb/r/innodb-index-debug.result
@@ -323,4 +323,9 @@ create table t1(o1 int, o2 int, o3 int, primary key(o1,o2,o3)) engine = innodb;
insert into t1 values(1,1,2),(2,2,1);
alter table t1 drop primary key, add primary key(o1), lock=none;
drop table t1;
+create table t1(o1 int, o2 int, primary key(o1,o2)) engine = innodb;
+insert into t1 values(1,1),(2,1);
+alter table t1 drop primary key, add column a int unique auto_increment,
+add primary key(o1,o2,a), algorithm=inplace;
+drop table t1;
SET DEBUG_DBUG = @saved_debug_dbug;
diff --git a/mysql-test/suite/innodb/r/innodb-index.result b/mysql-test/suite/innodb/r/innodb-index.result
index 4eba99950c7..7e58bfe38e5 100644
--- a/mysql-test/suite/innodb/r/innodb-index.result
+++ b/mysql-test/suite/innodb/r/innodb-index.result
@@ -1907,6 +1907,11 @@ create table t1(o1 int, o2 int, o3 int, primary key(o1,o2,o3)) engine = innodb;
insert into t1 values(1,1,2),(2,2,1);
alter table t1 drop primary key, add primary key(o1), lock=none;
drop table t1;
+create table t1(o1 int, o2 int, primary key(o1,o2)) engine = innodb;
+insert into t1 values(1,1),(2,1);
+alter table t1 drop primary key, add column a int unique auto_increment,
+add primary key(o1,o2,a), algorithm=inplace;
+drop table t1;
#
# MDEV-15325 Incomplete validation of missing tablespace during recovery
#
diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result
index 1cd62911e81..2313c415496 100644
--- a/mysql-test/suite/innodb/r/innodb.result
+++ b/mysql-test/suite/innodb/r/innodb.result
@@ -2544,7 +2544,6 @@ set foreign_key_checks=0;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb;
create table t1(a varchar(10) primary key) engine = innodb;
alter table t1 modify column a int;
-Got one of the listed errors
set foreign_key_checks=1;
drop table t2,t1;
set foreign_key_checks=0;
@@ -2553,6 +2552,7 @@ create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin
alter table t1 convert to character set utf8;
set foreign_key_checks=1;
drop table t2,t1;
+call mtr.add_suppression("\\[Warning\\] InnoDB: In ALTER TABLE `test`.`t1` has or is referenced in foreign key constraints which are not compatible with the new table definition.");
set foreign_key_checks=0;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
diff --git a/mysql-test/suite/innodb/r/instant_alter_bugs.result b/mysql-test/suite/innodb/r/instant_alter_bugs.result
index d5acc872b49..1dfc709a775 100644
--- a/mysql-test/suite/innodb/r/instant_alter_bugs.result
+++ b/mysql-test/suite/innodb/r/instant_alter_bugs.result
@@ -410,4 +410,10 @@ CREATE TABLE t (i INT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t SET i=1;
ALTER TABLE t ADD e CHAR(255) CHARACTER SET UTF32 FIRST, ALGORITHM=INSTANT;
DROP TABLE t;
+#
+# MDEV-23499 Assertion c.same_type(*o) failed
+#
+CREATE TABLE t (pk SERIAL, b TEXT CHARACTER SET utf8) ENGINE=InnoDB;
+ALTER TABLE t MODIFY b TEXT CHARACTER SET utf8mb4 FIRST;
+DROP TABLE t;
SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency;
diff --git a/mysql-test/suite/innodb/t/alter_table.test b/mysql-test/suite/innodb/t/alter_table.test
index 6d6b1d9ab11..26f3a9f013f 100644
--- a/mysql-test/suite/innodb/t/alter_table.test
+++ b/mysql-test/suite/innodb/t/alter_table.test
@@ -1,4 +1,5 @@
--source include/have_innodb.inc
+--source include/have_sequence.inc
#
# MDEV-11995 ALTER TABLE proceeds despite reporting ER_TOO_LONG_KEY error
#
@@ -60,6 +61,14 @@ ALTER TABLE t1 DROP a;
ALTER TABLE t1 ADD c INT;
DROP TABLE t1, tx;
+--echo #
+--echo # MDEV-14119 Assertion cmp_rec_rec() on ALTER TABLE
+--echo #
+CREATE TABLE t1(a INT NOT NULL UNIQUE) ENGINE=InnoDB;
+INSERT INTO t1 SELECT * FROM seq_1_to_128;
+ALTER TABLE t1 ADD b TINYINT AUTO_INCREMENT PRIMARY KEY, DROP KEY a;
+DROP TABLE t1;
+
#
# Check that innodb supports transactional=1
#
diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test
index 4719384cd65..c595cf92690 100644
--- a/mysql-test/suite/innodb/t/foreign_key.test
+++ b/mysql-test/suite/innodb/t/foreign_key.test
@@ -657,6 +657,8 @@ SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
--echo # with CONSTRAINTs
--echo #
+call mtr.add_suppression("\\[Warning\\] InnoDB: In ALTER TABLE `test`\\.`t2` has or is referenced in foreign key constraints which are not compatible with the new table definition.");
+
set foreign_key_checks=on;
create table t1 (id int not null primary key) engine=innodb;
create table t2 (id int not null primary key, fid int not null,
@@ -698,6 +700,27 @@ drop table t1,t2;
--error ER_BAD_TABLE_ERROR
drop table t1,t2;
+--echo #
+--echo # MDEV-22934 Table disappear after two alter table command
+--echo #
+CREATE TABLE t1(f1 INT NOT NULL AUTO_INCREMENT,
+ f2 INT NOT NULL,
+ PRIMARY KEY (f1), INDEX (f2))ENGINE=InnoDB;
+CREATE TABLE t2(f1 INT NOT NULL,
+ f2 INT NOT NULL, f3 INT NOT NULL,
+ PRIMARY KEY(f1, f2), UNIQUE KEY(f2),
+CONSTRAINT `t2_ibfk_1` FOREIGN KEY (f2) REFERENCES t1(f2) ON DELETE CASCADE,
+CONSTRAINT `t2_ibfk_2` FOREIGN KEY (f1) REFERENCES t1(f1) ON DELETE CASCADE
+) ENGINE=InnoDB;
+
+SET FOREIGN_KEY_CHECKS=0;
+ALTER TABLE t2 DROP PRIMARY KEY, ADD PRIMARY KEY(f3), ALGORITHM=INPLACE;
+ALTER TABLE t2 DROP INDEX `f2`, ALGORITHM=COPY;
+SHOW CREATE TABLE t2;
+--error ER_TABLE_EXISTS_ERROR
+CREATE TABLE t2 (f1 INT NOT NULL)ENGINE=InnoDB;
+DROP TABLE t2, t1;
+
--echo # End of 10.2 tests
# MDEV-21792 Server aborts upon attempt to create foreign key on spatial field
@@ -732,15 +755,15 @@ set default_storage_engine= default;
--echo #
--echo # MDEV-21690 LeakSanitizer: detected memory leaks in mem_heap_create_block_func
--echo #
+SET FOREIGN_KEY_CHECKS=1;
CREATE TABLE t1 (a TEXT, b TEXT) ENGINE=InnoDB;
--error ER_CANT_CREATE_TABLE
ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES t1 (b);
+SET FOREIGN_KEY_CHECKS=DEFAULT;
# Cleanup
DROP TABLE t1;
---echo # End of 10.5 tests
-
--echo #
--echo # MDEV-22602 Disable UPDATE CASCADE for SQL constraints
--echo #
@@ -764,4 +787,6 @@ create or replace table t2 (pk int primary key, a varchar(4096) unique, foreign
drop table t1;
+--echo # End of 10.5 tests
+
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/innodb/t/innodb-64k.test b/mysql-test/suite/innodb/t/innodb-64k.test
index b091eee6d57..62d7b929ba1 100644
--- a/mysql-test/suite/innodb/t/innodb-64k.test
+++ b/mysql-test/suite/innodb/t/innodb-64k.test
@@ -2,6 +2,7 @@
# Tests for setting innodb-page-size=64k;
--source include/have_innodb.inc
--source include/have_innodb_64k.inc
+--source include/have_sequence.inc
call mtr.add_suppression('InnoDB: Cannot add field.*because after adding it, the row size is');
@@ -638,3 +639,11 @@ COMMIT;
drop table t2;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-19526 heap number overflow
+--echo #
+CREATE TABLE t1(a SMALLINT NOT NULL UNIQUE AUTO_INCREMENT, KEY(a))
+ENGINE=InnoDB;
+INSERT INTO t1 (a) SELECT seq FROM seq_1_to_8191;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/innodb-corrupted-table.test b/mysql-test/suite/innodb/t/innodb-corrupted-table.test
index d1384d20c7b..a064f08d677 100644
--- a/mysql-test/suite/innodb/t/innodb-corrupted-table.test
+++ b/mysql-test/suite/innodb/t/innodb-corrupted-table.test
@@ -24,7 +24,7 @@ alter table t1 add primary key (pk);
--echo # Stop the server, replace the frm with the old one and restart the server
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
---shutdown_server 10
+--shutdown_server
--source include/wait_until_disconnected.inc
--remove_file $datadir/test/t1.frm
diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test
index dfb4da3a63d..5a718265624 100644
--- a/mysql-test/suite/innodb/t/innodb.test
+++ b/mysql-test/suite/innodb/t/innodb.test
@@ -1622,7 +1622,6 @@ drop table t1;
set foreign_key_checks=0;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb;
create table t1(a varchar(10) primary key) engine = innodb;
--- error 1025,1025
alter table t1 modify column a int;
set foreign_key_checks=1;
drop table t2,t1;
@@ -1638,6 +1637,7 @@ drop table t2,t1;
# test that RENAME does not allow invalid charsets when f_k_c is 0
+call mtr.add_suppression("\\[Warning\\] InnoDB: In ALTER TABLE `test`.`t1` has or is referenced in foreign key constraints which are not compatible with the new table definition.");
set foreign_key_checks=0;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
diff --git a/mysql-test/suite/innodb/t/innodb_bug60196.test b/mysql-test/suite/innodb/t/innodb_bug60196.test
index e479b8d6b82..7f1f5c40585 100644
--- a/mysql-test/suite/innodb/t/innodb_bug60196.test
+++ b/mysql-test/suite/innodb/t/innodb_bug60196.test
@@ -50,7 +50,7 @@ SELECT * FROM bug_60196;
-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
# Send a shutdown request to the server
--- shutdown_server 10
+-- shutdown_server
# Call script that will poll the server waiting for it to disapear
-- source include/wait_until_disconnected.inc
@@ -124,7 +124,7 @@ SELECT * FROM Bug_60309;
-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
# Send a shutdown request to the server
--- shutdown_server 10
+-- shutdown_server
# Call script that will poll the server waiting for it to disapear
-- source include/wait_until_disconnected.inc
diff --git a/mysql-test/suite/innodb/t/instant_alter_bugs.test b/mysql-test/suite/innodb/t/instant_alter_bugs.test
index 3dd0bedbbb6..4548e978f86 100644
--- a/mysql-test/suite/innodb/t/instant_alter_bugs.test
+++ b/mysql-test/suite/innodb/t/instant_alter_bugs.test
@@ -430,4 +430,11 @@ INSERT INTO t SET i=1;
ALTER TABLE t ADD e CHAR(255) CHARACTER SET UTF32 FIRST, ALGORITHM=INSTANT;
DROP TABLE t;
+--echo #
+--echo # MDEV-23499 Assertion c.same_type(*o) failed
+--echo #
+CREATE TABLE t (pk SERIAL, b TEXT CHARACTER SET utf8) ENGINE=InnoDB;
+ALTER TABLE t MODIFY b TEXT CHARACTER SET utf8mb4 FIRST;
+DROP TABLE t;
+
SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency;
diff --git a/mysql-test/suite/maria/maria-connect.result b/mysql-test/suite/maria/maria-connect.result
index 5c8b5524d69..84195780cf8 100644
--- a/mysql-test/suite/maria/maria-connect.result
+++ b/mysql-test/suite/maria/maria-connect.result
@@ -11,7 +11,7 @@ ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
show warnings;
Level Code Message
Error 1062 Duplicate entry '2' for key 'PRIMARY'
-Note 4173 Engine Aria does not support rollback. Changes where committed during rollback call
+Note 4173 Engine Aria does not support rollback. Changes were committed during rollback call
Warning 1196 Some non-transactional changed tables couldn't be rolled back
select * from t1;
a
diff --git a/mysql-test/suite/multi_source/info_logs.test b/mysql-test/suite/multi_source/info_logs.test
index ef504e06a2f..234e317e5ce 100644
--- a/mysql-test/suite/multi_source/info_logs.test
+++ b/mysql-test/suite/multi_source/info_logs.test
@@ -150,7 +150,7 @@ show all slaves status;
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.3.expect
restart
EOF
---shutdown_server 60
+--shutdown_server
--source include/wait_until_connected_again.inc
--source include/wait_for_slave_to_start.inc
set default_master_connection = 'MASTER 2.2';
diff --git a/mysql-test/suite/roles/acl_load_mutex-5170.test b/mysql-test/suite/roles/acl_load_mutex-5170.test
index 22b9dffb5fd..76d817be055 100644
--- a/mysql-test/suite/roles/acl_load_mutex-5170.test
+++ b/mysql-test/suite/roles/acl_load_mutex-5170.test
@@ -10,7 +10,7 @@ flush tables;
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
wait
EOF
---shutdown_server 60
+--shutdown_server
--source include/wait_until_disconnected.inc
--enable_reconnect
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
diff --git a/mysql-test/suite/rpl/include/rpl_shutdown_wait_slaves.inc b/mysql-test/suite/rpl/include/rpl_shutdown_wait_slaves.inc
index 17720e94dc8..4726bbe1889 100644
--- a/mysql-test/suite/rpl/include/rpl_shutdown_wait_slaves.inc
+++ b/mysql-test/suite/rpl/include/rpl_shutdown_wait_slaves.inc
@@ -40,7 +40,7 @@ SET @@GLOBAL.debug_dbug="+d,simulate_delay_at_shutdown";
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
wait
EOF
-# --shutdown_server 60
+# --shutdown_server
--send SHUTDOWN WAIT FOR ALL SLAVES
--reap
--source include/wait_until_disconnected.inc
diff --git a/mysql-test/suite/rpl/t/rpl_gtid_crash.test b/mysql-test/suite/rpl/t/rpl_gtid_crash.test
index 3c5542f4b2f..e72d1c3ef47 100644
--- a/mysql-test/suite/rpl/t/rpl_gtid_crash.test
+++ b/mysql-test/suite/rpl/t/rpl_gtid_crash.test
@@ -626,7 +626,7 @@ SELECT * FROM t1 WHERE a >= 30 ORDER BY a;
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
wait
EOF
-shutdown_server 10;
+shutdown_server;
--source include/wait_until_disconnected.inc
--remove_file $datadir/master-bin.state
diff --git a/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test
index 53d62805c58..fd4cdf71f6f 100644
--- a/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test
+++ b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test
@@ -29,7 +29,7 @@ CHANGE MASTER TO master_use_gtid=current_pos;
wait
EOF
FLUSH LOGS;
---shutdown_server 30
+--shutdown_server
--source include/wait_until_disconnected.inc
--connection server_1
@@ -70,7 +70,7 @@ SHOW BINLOG EVENTS IN 'master-bin.000004' LIMIT 1,1;
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
wait
EOF
---shutdown_server 30
+--shutdown_server
--source include/wait_until_disconnected.inc
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
@@ -103,7 +103,7 @@ SELECT * FROM t1 ORDER BY a;
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
---shutdown_server 30
+--shutdown_server
--source include/wait_until_disconnected.inc
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
@@ -148,7 +148,7 @@ SELECT * FROM t1 ORDER BY a;
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
---shutdown_server 30
+--shutdown_server
--source include/wait_until_disconnected.inc
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
@@ -191,7 +191,7 @@ SET sql_log_bin= 1;
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
---shutdown_server 30
+--shutdown_server
--source include/wait_until_disconnected.inc
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
@@ -221,7 +221,7 @@ SELECT * FROM t1 ORDER BY a;
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
---shutdown_server 30
+--shutdown_server
--source include/wait_until_disconnected.inc
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
@@ -237,7 +237,7 @@ SET sql_log_bin= 1;
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
---shutdown_server 30
+--shutdown_server
--source include/wait_until_disconnected.inc
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
@@ -273,7 +273,7 @@ SELECT domain_id, COUNT(*) FROM mysql.gtid_slave_pos GROUP BY domain_id;
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
---shutdown_server 30
+--shutdown_server
--source include/wait_until_disconnected.inc
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
@@ -305,7 +305,7 @@ SET sql_log_bin=1;
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
---shutdown_server 30
+--shutdown_server
--source include/wait_until_disconnected.inc
# Let the slave mysqld server start again.
diff --git a/mysql-test/suite/rpl/t/rpl_mdev12179.test b/mysql-test/suite/rpl/t/rpl_mdev12179.test
index db1ec3d4d22..e3caccde6b4 100644
--- a/mysql-test/suite/rpl/t/rpl_mdev12179.test
+++ b/mysql-test/suite/rpl/t/rpl_mdev12179.test
@@ -57,7 +57,7 @@ SET sql_log_bin=1;
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
---shutdown_server 30
+--shutdown_server
--source include/wait_until_disconnected.inc
--connection server_1
@@ -96,7 +96,7 @@ SET sql_log_bin=1;
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
---shutdown_server 30
+--shutdown_server
--source include/wait_until_disconnected.inc
--connection server_1
@@ -134,7 +134,7 @@ SET sql_log_bin=1;
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
---shutdown_server 30
+--shutdown_server
--source include/wait_until_disconnected.inc
--connection server_1
@@ -178,7 +178,7 @@ SET sql_log_bin=1;
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
---shutdown_server 30
+--shutdown_server
--source include/wait_until_disconnected.inc
--connection server_1
@@ -275,7 +275,7 @@ while (!$done)
wait
EOF
--connection server_2
---shutdown_server 30
+--shutdown_server
--source include/wait_until_disconnected.inc
--echo *** Restart the slave server to prove 'gtid_slave_pos_innodb' autodiscovery ***
diff --git a/mysql-test/suite/rpl/t/rpl_mdev382.test b/mysql-test/suite/rpl/t/rpl_mdev382.test
index 1d951cc7456..093b7b92413 100644
--- a/mysql-test/suite/rpl/t/rpl_mdev382.test
+++ b/mysql-test/suite/rpl/t/rpl_mdev382.test
@@ -208,7 +208,7 @@ SELECT * FROM `db1``; select 'oops!'`.`t``1` ORDER BY 1;
wait-rpl_mdev382.test
EOF
---shutdown_server 30
+--shutdown_server
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
restart-rpl_mdev382.test
diff --git a/mysql-test/suite/rpl/t/rpl_parallel_partition.test b/mysql-test/suite/rpl/t/rpl_parallel_partition.test
index 37dce9fef80..ea6c5dca6be 100644
--- a/mysql-test/suite/rpl/t/rpl_parallel_partition.test
+++ b/mysql-test/suite/rpl/t/rpl_parallel_partition.test
@@ -42,7 +42,7 @@ ALTER TABLE `E` REMOVE PARTITIONING;
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
wait
EOF
---shutdown_server 30
+--shutdown_server
--source include/wait_until_disconnected.inc
--connection default
--source include/wait_until_disconnected.inc
diff --git a/mysql-test/suite/storage_engine/alter_tablespace.test b/mysql-test/suite/storage_engine/alter_tablespace.test
index 3c4910069a0..1899da28320 100644
--- a/mysql-test/suite/storage_engine/alter_tablespace.test
+++ b/mysql-test/suite/storage_engine/alter_tablespace.test
@@ -46,7 +46,7 @@ wait
EOF
--enable_reconnect
- --shutdown_server 60
+ --shutdown_server
--source include/wait_until_disconnected.inc
diff --git a/mysql-test/suite/storage_engine/trx/xa_recovery.test b/mysql-test/suite/storage_engine/trx/xa_recovery.test
index e17bb9d2ea4..f53640578cd 100644
--- a/mysql-test/suite/storage_engine/trx/xa_recovery.test
+++ b/mysql-test/suite/storage_engine/trx/xa_recovery.test
@@ -12,7 +12,7 @@
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
restart
EOF
---shutdown_server 60
+--shutdown_server
--source include/wait_until_connected_again.inc
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
index b8a566a27cb..2ef79a39b7a 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
@@ -314,7 +314,7 @@ SESSION_VALUE NULL
DEFAULT_VALUE zlib
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE ENUM
-VARIABLE_COMMENT Compression algorithm used on page compression. One of: none, zlib, lz4, lzo, lzma, or bzip2
+VARIABLE_COMMENT Compression algorithm used on page compression. One of: none, zlib, lz4, lzo, lzma, bzip2, or snappy
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
diff --git a/mysql-test/suite/wsrep/r/MDEV-22443.result b/mysql-test/suite/wsrep/r/MDEV-22443.result
new file mode 100644
index 00000000000..ea07cbec5a0
--- /dev/null
+++ b/mysql-test/suite/wsrep/r/MDEV-22443.result
@@ -0,0 +1,3 @@
+SET SESSION wsrep_sync_wait=15;
+SET SESSION wsrep_on=1;
+START TRANSACTION READ WRITE;
diff --git a/mysql-test/suite/wsrep/r/MDEV-23092.result b/mysql-test/suite/wsrep/r/MDEV-23092.result
new file mode 100644
index 00000000000..d88aacf7d5c
--- /dev/null
+++ b/mysql-test/suite/wsrep/r/MDEV-23092.result
@@ -0,0 +1,13 @@
+SET COLLATION_CONNECTION='utf16le_bin';
+SET GLOBAL wsrep_provider='/invalid/path/libgalera_smm.so';
+ERROR 42000: Variable 'wsrep_provider' can't be set to the value of '/'
+SET GLOBAL wsrep_cluster_address='OFF';
+SET GLOBAL wsrep_slave_threads=10;
+SELECT 1;
+1
+1
+SET GLOBAL wsrep_cluster_address='gcomm://';
+SET GLOBAL wsrep_slave_threads=DEFAULT;
+CALL mtr.add_suppression("wsrep_load()");
+CALL mtr.add_suppression("Failed to create a new provider");
+CALL mtr.add_suppression("Failed to load provider");
diff --git a/mysql-test/suite/wsrep/r/MDEV-23466.result b/mysql-test/suite/wsrep/r/MDEV-23466.result
new file mode 100644
index 00000000000..a019704d7d3
--- /dev/null
+++ b/mysql-test/suite/wsrep/r/MDEV-23466.result
@@ -0,0 +1,3 @@
+SELECT WSREP_LAST_SEEN_GTID();
+WSREP_LAST_SEEN_GTID()
+0-0-0
diff --git a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result
index f219625b490..d5bbecfa7c2 100644
--- a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result
+++ b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result
@@ -15,6 +15,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -32,6 +33,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/ignored.tab' as time zone. Skipping it.
Warning: Skipping directory 'MYSQLTEST_VARDIR/zoneinfo/posix/posix': to avoid infinite symlink recursion.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
\d |
@@ -57,6 +59,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -71,6 +74,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
(@time_zone_id, 0, 0, 0, 'GMT')
;
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
\d |
diff --git a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result
index 85c4d858be2..aff02cb413e 100644
--- a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result
+++ b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result
@@ -9,6 +9,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -26,6 +27,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/ignored.tab' as time zone. Skipping it.
Warning: Skipping directory 'MYSQLTEST_VARDIR/zoneinfo/posix/posix': to avoid infinite symlink recursion.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
# Silent run
@@ -36,6 +38,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -50,6 +53,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
(@time_zone_id, 0, 0, 0, 'GMT')
;
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
#
diff --git a/mysql-test/suite/wsrep/t/MDEV-22443.cnf b/mysql-test/suite/wsrep/t/MDEV-22443.cnf
new file mode 100644
index 00000000000..851f2999a83
--- /dev/null
+++ b/mysql-test/suite/wsrep/t/MDEV-22443.cnf
@@ -0,0 +1,8 @@
+!include ../my.cnf
+
+[mysqld.1]
+wsrep-on=OFF
+binlog-format=ROW
+wsrep-provider=none
+wsrep-cluster-address='gcomm://'
+innodb_autoinc_lock_mode=2
diff --git a/mysql-test/suite/wsrep/t/MDEV-22443.test b/mysql-test/suite/wsrep/t/MDEV-22443.test
new file mode 100644
index 00000000000..674cb5ae2d8
--- /dev/null
+++ b/mysql-test/suite/wsrep/t/MDEV-22443.test
@@ -0,0 +1,12 @@
+#
+# MDEV-22443: terminate called after throwing an instance of
+# 'wsrep::runtime_error' in std::terminate on START TRANSACTION
+#
+
+--source include/have_innodb.inc
+--source include/have_wsrep.inc
+--source include/have_binlog_format_row.inc
+
+SET SESSION wsrep_sync_wait=15;
+SET SESSION wsrep_on=1;
+START TRANSACTION READ WRITE;
diff --git a/mysql-test/suite/wsrep/t/MDEV-23092.cnf b/mysql-test/suite/wsrep/t/MDEV-23092.cnf
new file mode 100644
index 00000000000..851f2999a83
--- /dev/null
+++ b/mysql-test/suite/wsrep/t/MDEV-23092.cnf
@@ -0,0 +1,8 @@
+!include ../my.cnf
+
+[mysqld.1]
+wsrep-on=OFF
+binlog-format=ROW
+wsrep-provider=none
+wsrep-cluster-address='gcomm://'
+innodb_autoinc_lock_mode=2
diff --git a/mysql-test/suite/wsrep/t/MDEV-23092.test b/mysql-test/suite/wsrep/t/MDEV-23092.test
new file mode 100644
index 00000000000..92a6e392013
--- /dev/null
+++ b/mysql-test/suite/wsrep/t/MDEV-23092.test
@@ -0,0 +1,22 @@
+#
+# MDEV-23092: SIGABRT in wsrep::server_state::provider when setting
+# invalid wsrep_provider (on optimized builds)
+#
+
+--source include/have_innodb.inc
+--source include/have_wsrep.inc
+--source include/have_binlog_format_row.inc
+
+SET COLLATION_CONNECTION='utf16le_bin';
+--error 1231
+SET GLOBAL wsrep_provider='/invalid/path/libgalera_smm.so';
+SET GLOBAL wsrep_cluster_address='OFF';
+SET GLOBAL wsrep_slave_threads=10;
+SELECT 1;
+
+SET GLOBAL wsrep_cluster_address='gcomm://';
+SET GLOBAL wsrep_slave_threads=DEFAULT;
+
+CALL mtr.add_suppression("wsrep_load()");
+CALL mtr.add_suppression("Failed to create a new provider");
+CALL mtr.add_suppression("Failed to load provider");
diff --git a/mysql-test/suite/wsrep/t/MDEV-23466.cnf b/mysql-test/suite/wsrep/t/MDEV-23466.cnf
new file mode 100644
index 00000000000..851f2999a83
--- /dev/null
+++ b/mysql-test/suite/wsrep/t/MDEV-23466.cnf
@@ -0,0 +1,8 @@
+!include ../my.cnf
+
+[mysqld.1]
+wsrep-on=OFF
+binlog-format=ROW
+wsrep-provider=none
+wsrep-cluster-address='gcomm://'
+innodb_autoinc_lock_mode=2
diff --git a/mysql-test/suite/wsrep/t/MDEV-23466.test b/mysql-test/suite/wsrep/t/MDEV-23466.test
new file mode 100644
index 00000000000..2615298226e
--- /dev/null
+++ b/mysql-test/suite/wsrep/t/MDEV-23466.test
@@ -0,0 +1,10 @@
+#
+# MDEV-23466: SIGABRT in wsrep::server_state::provider on
+# SELECT WSREP_LAST_SEEN_GTID() on optimized builds
+#
+
+--source include/have_innodb.inc
+--source include/have_wsrep.inc
+--source include/have_binlog_format_row.inc
+
+SELECT WSREP_LAST_SEEN_GTID();
diff --git a/mysys/crc32/crc32_arm64.c b/mysys/crc32/crc32_arm64.c
index aae6f769002..a7eb2a47442 100644
--- a/mysys/crc32/crc32_arm64.c
+++ b/mysys/crc32/crc32_arm64.c
@@ -8,40 +8,49 @@
#include <asm/hwcap.h>
#ifndef HWCAP_CRC32
-#define HWCAP_CRC32 (1 << 7)
+# define HWCAP_CRC32 (1 << 7)
#endif
+#ifndef HWCAP_PMULL
+# define HWCAP_PMULL (1 << 4)
+#endif
+
+static int pmull_supported;
+
/* ARM made crc32 default from ARMv8.1 but optional in ARMv8A
-so the runtime check. */
+ * Runtime check API.
+ */
int crc32_aarch64_available(void)
{
unsigned long auxv= getauxval(AT_HWCAP);
return (auxv & HWCAP_CRC32) != 0;
}
-#if defined(HAVE_ARMV8_CRYPTO)
+const char *crc32c_aarch64_available(void)
+{
+ unsigned long auxv= getauxval(AT_HWCAP);
-#ifndef HWCAP_PMULL
-#define HWCAP_PMULL (1 << 4)
-#endif
+ if (!(auxv & HWCAP_CRC32))
+ return NULL;
-/* Check if target ARM machine support crc32 + pmull for computing crc32c */
-int crc32c_aarch64_available(void)
-{
- return !(~getauxval(AT_HWCAP) & (HWCAP_CRC32 | HWCAP_PMULL));
+ pmull_supported= (auxv & HWCAP_PMULL) != 0;
+ if (pmull_supported)
+ return "Using ARMv8 crc32 + pmull instructions";
+ else
+ return "Using ARMv8 crc32 instructions";
}
-#endif /* HAVE_ARMV8_CRYPTO */
-#endif /* HAVE_ARMV8_CRC */
+
+#endif /* __GNUC__ && HAVE_ARMV8_CRC */
#ifndef HAVE_ARMV8_CRC_CRYPTO_INTRINSICS
/* Request crc extension capabilities from the assembler */
asm(".arch_extension crc");
-#ifdef HAVE_ARMV8_CRYPTO
+# ifdef HAVE_ARMV8_CRYPTO
/* crypto extension */
asm(".arch_extension crypto");
-#endif
+# endif
#define CRC32CX(crc, value) __asm__("crc32cx %w[c], %w[c], %x[v]":[c]"+r"(crc):[v]"r"(value))
#define CRC32CW(crc, value) __asm__("crc32cw %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value))
@@ -49,12 +58,9 @@ asm(".arch_extension crypto");
#define CRC32CB(crc, value) __asm__("crc32cb %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value))
#define CRC32C3X8(buffer, ITR) \
- __asm__("crc32cx %w[c1], %w[c1], %x[v]":[c1]"+r"(crc1):[v]"r"(*((const uint64_t *)buffer + 42*1 + (ITR))));\
- __asm__("crc32cx %w[c2], %w[c2], %x[v]":[c2]"+r"(crc2):[v]"r"(*((const uint64_t *)buffer + 42*2 + (ITR))));\
- __asm__("crc32cx %w[c0], %w[c0], %x[v]":[c0]"+r"(crc0):[v]"r"(*((const uint64_t *)buffer + 42*0 + (ITR))));
-
-#define CRC32C3X8_ZERO \
- __asm__("crc32cx %w[c0], %w[c0], xzr":[c0]"+r"(crc0));
+ __asm__("crc32cx %w[c1], %w[c1], %x[v]":[c1]"+r"(crc1):[v]"r"(*((const uint64_t *)buffer + 42*1 + (ITR))));\
+ __asm__("crc32cx %w[c2], %w[c2], %x[v]":[c2]"+r"(crc2):[v]"r"(*((const uint64_t *)buffer + 42*2 + (ITR))));\
+ __asm__("crc32cx %w[c0], %w[c0], %x[v]":[c0]"+r"(crc0):[v]"r"(*((const uint64_t *)buffer + 42*0 + (ITR))));
#else /* HAVE_ARMV8_CRC_CRYPTO_INTRINSICS */
@@ -68,250 +74,194 @@ asm(".arch_extension crypto");
#define CRC32CB(crc, value) (crc) = __crc32cb((crc), (value))
#define CRC32C3X8(buffer, ITR) \
- crc1 = __crc32cd(crc1, *((const uint64_t *)buffer + 42*1 + (ITR)));\
- crc2 = __crc32cd(crc2, *((const uint64_t *)buffer + 42*2 + (ITR)));\
- crc0 = __crc32cd(crc0, *((const uint64_t *)buffer + 42*0 + (ITR)));
-
-#define CRC32C3X8_ZERO \
- crc0 = __crc32cd(crc0, (const uint64_t)0);
+ crc1 = __crc32cd(crc1, *((const uint64_t *)buffer + 42*1 + (ITR)));\
+ crc2 = __crc32cd(crc2, *((const uint64_t *)buffer + 42*2 + (ITR)));\
+ crc0 = __crc32cd(crc0, *((const uint64_t *)buffer + 42*0 + (ITR)));
#endif /* HAVE_ARMV8_CRC_CRYPTO_INTRINSICS */
#define CRC32C7X3X8(buffer, ITR) do {\
- CRC32C3X8(buffer, ((ITR) * 7 + 0)) \
- CRC32C3X8(buffer, ((ITR) * 7 + 1)) \
- CRC32C3X8(buffer, ((ITR) * 7 + 2)) \
- CRC32C3X8(buffer, ((ITR) * 7 + 3)) \
- CRC32C3X8(buffer, ((ITR) * 7 + 4)) \
- CRC32C3X8(buffer, ((ITR) * 7 + 5)) \
- CRC32C3X8(buffer, ((ITR) * 7 + 6)) \
- } while(0)
-
-#define CRC32C7X3X8_ZERO do {\
- CRC32C3X8_ZERO \
- CRC32C3X8_ZERO \
- CRC32C3X8_ZERO \
- CRC32C3X8_ZERO \
- CRC32C3X8_ZERO \
- CRC32C3X8_ZERO \
- CRC32C3X8_ZERO \
- } while(0)
+ CRC32C3X8(buffer, ((ITR) * 7 + 0)) \
+ CRC32C3X8(buffer, ((ITR) * 7 + 1)) \
+ CRC32C3X8(buffer, ((ITR) * 7 + 2)) \
+ CRC32C3X8(buffer, ((ITR) * 7 + 3)) \
+ CRC32C3X8(buffer, ((ITR) * 7 + 4)) \
+ CRC32C3X8(buffer, ((ITR) * 7 + 5)) \
+ CRC32C3X8(buffer, ((ITR) * 7 + 6)) \
+} while(0)
#define PREF4X64L1(buffer, PREF_OFFSET, ITR) \
- __asm__("PRFM PLDL1KEEP, [%x[v],%[c]]"::[v]"r"(buffer), [c]"I"((PREF_OFFSET) + ((ITR) + 0)*64));\
- __asm__("PRFM PLDL1KEEP, [%x[v],%[c]]"::[v]"r"(buffer), [c]"I"((PREF_OFFSET) + ((ITR) + 1)*64));\
- __asm__("PRFM PLDL1KEEP, [%x[v],%[c]]"::[v]"r"(buffer), [c]"I"((PREF_OFFSET) + ((ITR) + 2)*64));\
- __asm__("PRFM PLDL1KEEP, [%x[v],%[c]]"::[v]"r"(buffer), [c]"I"((PREF_OFFSET) + ((ITR) + 3)*64));
+ __asm__("PRFM PLDL1KEEP, [%x[v],%[c]]"::[v]"r"(buffer), [c]"I"((PREF_OFFSET) + ((ITR) + 0)*64));\
+ __asm__("PRFM PLDL1KEEP, [%x[v],%[c]]"::[v]"r"(buffer), [c]"I"((PREF_OFFSET) + ((ITR) + 1)*64));\
+ __asm__("PRFM PLDL1KEEP, [%x[v],%[c]]"::[v]"r"(buffer), [c]"I"((PREF_OFFSET) + ((ITR) + 2)*64));\
+ __asm__("PRFM PLDL1KEEP, [%x[v],%[c]]"::[v]"r"(buffer), [c]"I"((PREF_OFFSET) + ((ITR) + 3)*64));
#define PREF1KL1(buffer, PREF_OFFSET) \
- PREF4X64L1(buffer,(PREF_OFFSET), 0) \
- PREF4X64L1(buffer,(PREF_OFFSET), 4) \
- PREF4X64L1(buffer,(PREF_OFFSET), 8) \
- PREF4X64L1(buffer,(PREF_OFFSET), 12)
+ PREF4X64L1(buffer,(PREF_OFFSET), 0) \
+ PREF4X64L1(buffer,(PREF_OFFSET), 4) \
+ PREF4X64L1(buffer,(PREF_OFFSET), 8) \
+ PREF4X64L1(buffer,(PREF_OFFSET), 12)
#define PREF4X64L2(buffer, PREF_OFFSET, ITR) \
- __asm__("PRFM PLDL2KEEP, [%x[v],%[c]]"::[v]"r"(buffer), [c]"I"((PREF_OFFSET) + ((ITR) + 0)*64));\
- __asm__("PRFM PLDL2KEEP, [%x[v],%[c]]"::[v]"r"(buffer), [c]"I"((PREF_OFFSET) + ((ITR) + 1)*64));\
- __asm__("PRFM PLDL2KEEP, [%x[v],%[c]]"::[v]"r"(buffer), [c]"I"((PREF_OFFSET) + ((ITR) + 2)*64));\
- __asm__("PRFM PLDL2KEEP, [%x[v],%[c]]"::[v]"r"(buffer), [c]"I"((PREF_OFFSET) + ((ITR) + 3)*64));
+ __asm__("PRFM PLDL2KEEP, [%x[v],%[c]]"::[v]"r"(buffer), [c]"I"((PREF_OFFSET) + ((ITR) + 0)*64));\
+ __asm__("PRFM PLDL2KEEP, [%x[v],%[c]]"::[v]"r"(buffer), [c]"I"((PREF_OFFSET) + ((ITR) + 1)*64));\
+ __asm__("PRFM PLDL2KEEP, [%x[v],%[c]]"::[v]"r"(buffer), [c]"I"((PREF_OFFSET) + ((ITR) + 2)*64));\
+ __asm__("PRFM PLDL2KEEP, [%x[v],%[c]]"::[v]"r"(buffer), [c]"I"((PREF_OFFSET) + ((ITR) + 3)*64));
#define PREF1KL2(buffer, PREF_OFFSET) \
- PREF4X64L2(buffer,(PREF_OFFSET), 0) \
- PREF4X64L2(buffer,(PREF_OFFSET), 4) \
- PREF4X64L2(buffer,(PREF_OFFSET), 8) \
- PREF4X64L2(buffer,(PREF_OFFSET), 12)
-
+ PREF4X64L2(buffer,(PREF_OFFSET), 0) \
+ PREF4X64L2(buffer,(PREF_OFFSET), 4) \
+ PREF4X64L2(buffer,(PREF_OFFSET), 8) \
+ PREF4X64L2(buffer,(PREF_OFFSET), 12)
uint32_t crc32c_aarch64(uint32_t crc, const unsigned char *buffer, uint64_t len)
{
- uint32_t crc0, crc1, crc2;
- int64_t length = (int64_t)len;
-
- crc = 0xFFFFFFFFU;
-
- if (buffer) {
+ uint32_t crc0, crc1, crc2;
+ int64_t length= (int64_t)len;
+
+ crc= 0xFFFFFFFFU;
+
+ /* Pmull runtime check here.
+ * Raspberry Pi 4 supports crc32 but doesn't support pmull (MDEV-23030).
+ *
+ * Consider the condition that the target platform does support hardware crc32
+ * but not support PMULL. In this condition, it should leverage the aarch64
+ * crc32 instruction (__crc32c) and just only skip parallel computation (pmull/vmull)
+ * rather than skip all hardware crc32 instruction of computation.
+ */
+ if (pmull_supported)
+ {
+/* The following Macro (HAVE_ARMV8_CRYPTO) is used for compiling check */
+#ifdef HAVE_ARMV8_CRYPTO
/* Crypto extension Support
- * Process 1024 Bytes (per block)
+ * Parallel computation with 1024 Bytes (per block)
+ * Intrinsics Support
*/
-#ifdef HAVE_ARMV8_CRYPTO
-
-/* Intrinsics Support */
-#ifdef HAVE_ARMV8_CRC_CRYPTO_INTRINSICS
- const poly64_t k1 = 0xe417f38a, k2 = 0x8f158014;
- uint64_t t0, t1;
-
- /* Process per block size of 1024 Bytes
- * A block size = 8 + 42*3*sizeof(uint64_t) + 8
- */
- while ((length -= 1024) >= 0) {
- /* Prefetch 3*1024 data for avoiding L2 cache miss */
- PREF1KL2(buffer, 1024*3);
- /* Do first 8 bytes here for better pipelining */
- crc0 = __crc32cd(crc, *(const uint64_t *)buffer);
- crc1 = 0;
- crc2 = 0;
- buffer += sizeof(uint64_t);
-
- /* Process block inline
- * Process crc0 last to avoid dependency with above
- */
- CRC32C7X3X8(buffer, 0);
- CRC32C7X3X8(buffer, 1);
- CRC32C7X3X8(buffer, 2);
- CRC32C7X3X8(buffer, 3);
- CRC32C7X3X8(buffer, 4);
- CRC32C7X3X8(buffer, 5);
-
- buffer += 42*3*sizeof(uint64_t);
- /* Prefetch data for following block to avoid L1 cache miss */
- PREF1KL1(buffer, 1024);
-
- /* Last 8 bytes
- * Merge crc0 and crc1 into crc2
- * crc1 multiply by K2
- * crc0 multiply by K1
- */
- t1 = (uint64_t)vmull_p64(crc1, k2);
- t0 = (uint64_t)vmull_p64(crc0, k1);
- crc = __crc32cd(crc2, *(const uint64_t *)buffer);
- crc1 = __crc32cd(0, t1);
- crc ^= crc1;
- crc0 = __crc32cd(0, t0);
- crc ^= crc0;
-
- buffer += sizeof(uint64_t);
- }
-
-#else /* HAVE_ARMV8_CRC_CRYPTO_INTRINSICS */
-
- /*No intrinsics*/
- __asm__("mov x16, #0xf38a \n\t"
- "movk x16, #0xe417, lsl 16 \n\t"
- "mov v1.2d[0], x16 \n\t"
- "mov x16, #0x8014 \n\t"
- "movk x16, #0x8f15, lsl 16 \n\t"
- "mov v0.2d[0], x16 \n\t"
- :::"x16");
-
- while ((length -= 1024) >= 0) {
- PREF1KL2(buffer, 1024*3);
- __asm__("crc32cx %w[c0], %w[c], %x[v]\n\t"
- :[c0]"=r"(crc0):[c]"r"(crc), [v]"r"(*(const uint64_t *)buffer):);
- crc1 = 0;
- crc2 = 0;
- buffer += sizeof(uint64_t);
-
- CRC32C7X3X8(buffer, 0);
- CRC32C7X3X8(buffer, 1);
- CRC32C7X3X8(buffer, 2);
- CRC32C7X3X8(buffer, 3);
- CRC32C7X3X8(buffer, 4);
- CRC32C7X3X8(buffer, 5);
-
- buffer += 42*3*sizeof(uint64_t);
- PREF1KL1(buffer, 1024);
- __asm__("mov v2.2d[0], %x[c1] \n\t"
- "pmull v2.1q, v2.1d, v0.1d \n\t"
- "mov v3.2d[0], %x[c0] \n\t"
- "pmull v3.1q, v3.1d, v1.1d \n\t"
- "crc32cx %w[c], %w[c2], %x[v] \n\t"
- "mov %x[c1], v2.2d[0] \n\t"
- "crc32cx %w[c1], wzr, %x[c1] \n\t"
- "eor %w[c], %w[c], %w[c1] \n\t"
- "mov %x[c0], v3.2d[0] \n\t"
- "crc32cx %w[c0], wzr, %x[c0] \n\t"
- "eor %w[c], %w[c], %w[c0] \n\t"
- :[c1]"+r"(crc1), [c0]"+r"(crc0), [c2]"+r"(crc2), [c]"+r"(crc)
- :[v]"r"(*((const uint64_t *)buffer)));
- buffer += sizeof(uint64_t);
- }
-#endif /* HAVE_ARMV8_CRC_CRYPTO_INTRINSICS */
-
- /* Done if Input data size is aligned with 1024 */
- if(!(length += 1024))
- return (~crc);
+# ifdef HAVE_ARMV8_CRC_CRYPTO_INTRINSICS
+ const poly64_t k1= 0xe417f38a, k2= 0x8f158014;
+ uint64_t t0, t1;
+
+ /* Process per block size of 1024 Bytes
+ * A block size = 8 + 42*3*sizeof(uint64_t) + 8
+ */
+ while ((length-= 1024) >= 0)
+ {
+ /* Prefetch 3*1024 data for avoiding L2 cache miss */
+ PREF1KL2(buffer, 1024*3);
+ /* Do first 8 bytes here for better pipelining */
+ crc0= __crc32cd(crc, *(const uint64_t *)buffer);
+ crc1= 0;
+ crc2= 0;
+ buffer+= sizeof(uint64_t);
+
+ /* Process block inline
+ * Process crc0 last to avoid dependency with above
+ */
+ CRC32C7X3X8(buffer, 0);
+ CRC32C7X3X8(buffer, 1);
+ CRC32C7X3X8(buffer, 2);
+ CRC32C7X3X8(buffer, 3);
+ CRC32C7X3X8(buffer, 4);
+ CRC32C7X3X8(buffer, 5);
+
+ buffer+= 42*3*sizeof(uint64_t);
+ /* Prefetch data for following block to avoid L1 cache miss */
+ PREF1KL1(buffer, 1024);
+
+ /* Last 8 bytes
+ * Merge crc0 and crc1 into crc2
+ * crc1 multiply by K2
+ * crc0 multiply by K1
+ */
+ t1= (uint64_t)vmull_p64(crc1, k2);
+ t0= (uint64_t)vmull_p64(crc0, k1);
+ crc= __crc32cd(crc2, *(const uint64_t *)buffer);
+ crc1= __crc32cd(0, t1);
+ crc^= crc1;
+ crc0= __crc32cd(0, t0);
+ crc^= crc0;
+
+ buffer+= sizeof(uint64_t);
+ }
+
+# else /* HAVE_ARMV8_CRC_CRYPTO_INTRINSICS */
+
+ /*No intrinsics*/
+ __asm__("mov x16, #0xf38a \n\t"
+ "movk x16, #0xe417, lsl 16 \n\t"
+ "mov v1.2d[0], x16 \n\t"
+ "mov x16, #0x8014 \n\t"
+ "movk x16, #0x8f15, lsl 16 \n\t"
+ "mov v0.2d[0], x16 \n\t"
+ :::"x16");
+
+ while ((length-= 1024) >= 0)
+ {
+ PREF1KL2(buffer, 1024*3);
+ __asm__("crc32cx %w[c0], %w[c], %x[v]\n\t"
+ :[c0]"=r"(crc0):[c]"r"(crc), [v]"r"(*(const uint64_t *)buffer):);
+ crc1= 0;
+ crc2= 0;
+ buffer+= sizeof(uint64_t);
+
+ CRC32C7X3X8(buffer, 0);
+ CRC32C7X3X8(buffer, 1);
+ CRC32C7X3X8(buffer, 2);
+ CRC32C7X3X8(buffer, 3);
+ CRC32C7X3X8(buffer, 4);
+ CRC32C7X3X8(buffer, 5);
+
+ buffer+= 42*3*sizeof(uint64_t);
+ PREF1KL1(buffer, 1024);
+ __asm__("mov v2.2d[0], %x[c1] \n\t"
+ "pmull v2.1q, v2.1d, v0.1d \n\t"
+ "mov v3.2d[0], %x[c0] \n\t"
+ "pmull v3.1q, v3.1d, v1.1d \n\t"
+ "crc32cx %w[c], %w[c2], %x[v] \n\t"
+ "mov %x[c1], v2.2d[0] \n\t"
+ "crc32cx %w[c1], wzr, %x[c1] \n\t"
+ "eor %w[c], %w[c], %w[c1] \n\t"
+ "mov %x[c0], v3.2d[0] \n\t"
+ "crc32cx %w[c0], wzr, %x[c0] \n\t"
+ "eor %w[c], %w[c], %w[c0] \n\t"
+ :[c1]"+r"(crc1), [c0]"+r"(crc0), [c2]"+r"(crc2), [c]"+r"(crc)
+ :[v]"r"(*((const uint64_t *)buffer)));
+ buffer+= sizeof(uint64_t);
+ }
+# endif /* HAVE_ARMV8_CRC_CRYPTO_INTRINSICS */
+
+ /* Done if Input data size is aligned with 1024 */
+ if (!(length+= 1024))
+ return ~crc;
#endif /* HAVE_ARMV8_CRYPTO */
- while ((length -= sizeof(uint64_t)) >= 0) {
- CRC32CX(crc, *(uint64_t *)buffer);
- buffer += sizeof(uint64_t);
- }
- /* The following is more efficient than the straight loop */
- if (length & sizeof(uint32_t)) {
- CRC32CW(crc, *(uint32_t *)buffer);
- buffer += sizeof(uint32_t);
- }
- if (length & sizeof(uint16_t)) {
- CRC32CH(crc, *(uint16_t *)buffer);
- buffer += sizeof(uint16_t);
- }
- if (length & sizeof(uint8_t))
- CRC32CB(crc, *buffer);
-
- } else {
-#ifdef HAVE_ARMV8_CRYPTO
-#ifdef HAVE_ARMV8_CRC_CRYPTO_INTRINSICS
- const poly64_t k1 = 0xe417f38a;
- uint64_t t0;
- while ((length -= 1024) >= 0) {
- crc0 = __crc32cd(crc, 0);
-
- CRC32C7X3X8_ZERO;
- CRC32C7X3X8_ZERO;
- CRC32C7X3X8_ZERO;
- CRC32C7X3X8_ZERO;
- CRC32C7X3X8_ZERO;
- CRC32C7X3X8_ZERO;
-
- /* Merge crc0 into crc: crc0 multiply by K1 */
- t0 = (uint64_t)vmull_p64(crc0, k1);
- crc = __crc32cd(0, t0);
- }
-#else /* !HAVE_ARMV8_CRC_CRYPTO_INTRINSICS */
- __asm__("mov x16, #0xf38a \n\t"
- "movk x16, #0xe417, lsl 16 \n\t"
- "mov v1.2d[0], x16 \n\t"
- :::"x16");
-
- while ((length -= 1024) >= 0) {
- __asm__("crc32cx %w[c0], %w[c], xzr\n\t"
- :[c0]"=r"(crc0):[c]"r"(crc));
-
- CRC32C7X3X8_ZERO;
- CRC32C7X3X8_ZERO;
- CRC32C7X3X8_ZERO;
- CRC32C7X3X8_ZERO;
- CRC32C7X3X8_ZERO;
- CRC32C7X3X8_ZERO;
-
- __asm__("mov v3.2d[0], %x[c0] \n\t"
- "pmull v3.1q, v3.1d, v1.1d \n\t"
- "mov %x[c0], v3.2d[0] \n\t"
- "crc32cx %w[c], wzr, %x[c0] \n\t"
- :[c]"=r"(crc)
- :[c0]"r"(crc0));
- }
-#endif /* HAVE_ARMV8_CRC_CRYPTO_INTRINSICS */
- if(!(length += 1024))
- return (~crc);
-#endif /* HAVE_ARMV8_CRYPTO */
- while ((length -= sizeof(uint64_t)) >= 0)
- CRC32CX(crc, 0);
+ } // end if pmull_supported
- /* The following is more efficient than the straight loop */
- if (length & sizeof(uint32_t))
- CRC32CW(crc, 0);
+ while ((length-= sizeof(uint64_t)) >= 0)
+ {
+ CRC32CX(crc, *(uint64_t *)buffer);
+ buffer+= sizeof(uint64_t);
+ }
- if (length & sizeof(uint16_t))
- CRC32CH(crc, 0);
+ /* The following is more efficient than the straight loop */
+ if (length & sizeof(uint32_t))
+ {
+ CRC32CW(crc, *(uint32_t *)buffer);
+ buffer+= sizeof(uint32_t);
+ }
- if (length & sizeof(uint8_t))
- CRC32CB(crc, 0);
- }
+ if (length & sizeof(uint16_t))
+ {
+ CRC32CH(crc, *(uint16_t *)buffer);
+ buffer+= sizeof(uint16_t);
+ }
- return (~crc);
+ if (length & sizeof(uint8_t))
+ CRC32CB(crc, *buffer);
+
+ return ~crc;
}
/* There are multiple approaches to calculate crc.
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c
index 36731e14a58..5718b2e762d 100644
--- a/mysys/stacktrace.c
+++ b/mysys/stacktrace.c
@@ -1,5 +1,6 @@
/*
Copyright (c) 2001, 2011, Oracle and/or its affiliates
+ Copyright (c) 2020, 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
@@ -33,15 +34,6 @@
#include <execinfo.h>
#endif
-#ifdef __linux__
-#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
-static char *heap_start;
-char *__bss_start;
-#else
-#define PTR_SANE(p) (p)
-#endif /* __linux */
-
-
/**
Default handler for printing stacktrace
*/
@@ -61,111 +53,23 @@ static sig_handler default_handle_fatal_signal(int sig)
/**
Initialize priting off stacktrace at signal
-
- @param setup_handlers 0 only initialize variables
- 1 setup signal handlers for stacktrace printing
*/
-void my_init_stacktrace(int setup_handlers)
+void my_setup_stacktrace(void)
{
-#ifdef __linux__
- heap_start = (char*) &__bss_start;
-#endif /* __linux */
- if (setup_handlers)
- {
- struct sigaction sa;
- sa.sa_flags = SA_RESETHAND | SA_NODEFER;
- sigemptyset(&sa.sa_mask);
- sa.sa_handler= default_handle_fatal_signal;
- sigaction(SIGSEGV, &sa, NULL);
- sigaction(SIGABRT, &sa, NULL);
+ struct sigaction sa;
+ sa.sa_flags = SA_RESETHAND | SA_NODEFER;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler= default_handle_fatal_signal;
+ sigaction(SIGSEGV, &sa, NULL);
+ sigaction(SIGABRT, &sa, NULL);
#ifdef SIGBUS
- sigaction(SIGBUS, &sa, NULL);
+ sigaction(SIGBUS, &sa, NULL);
#endif
- sigaction(SIGILL, &sa, NULL);
- sigaction(SIGFPE, &sa, NULL);
- }
-}
-
-#ifdef __linux__
-
-static void print_buffer(char *buffer, size_t count)
-{
- const char s[]= " ";
- for (; count && *buffer; --count)
- {
- my_write_stderr(isprint(*buffer) ? buffer : s, 1);
- ++buffer;
- }
-}
-
-/**
- Access the pages of this process through /proc/self/task/<tid>/mem
- in order to safely print the contents of a memory address range.
-
- @param addr The address at the start of the memory region.
- @param max_len The length of the memory region.
-
- @return Zero on success.
-*/
-static int safe_print_str(const char *addr, size_t max_len)
-{
- int fd;
- pid_t tid;
- off_t offset;
- ssize_t nbytes= 0;
- size_t total, count;
- char buf[256];
-
- tid= (pid_t) syscall(SYS_gettid);
-
- sprintf(buf, "/proc/self/task/%d/mem", tid);
-
- if ((fd= open(buf, O_RDONLY)) < 0)
- return -1;
-
- /* Ensure that off_t can hold a pointer. */
- compile_time_assert(sizeof(off_t) >= sizeof(intptr));
-
- total= max_len;
- offset= (intptr) addr;
-
- /* Read up to the maximum number of bytes. */
- while (total)
- {
- count= MY_MIN(sizeof(buf), total);
-
- if ((nbytes= pread(fd, buf, count, offset)) < 0)
- {
- /* Just in case... */
- if (errno == EINTR)
- continue;
- else
- break;
- }
-
- /* Advance offset into memory. */
- total-= nbytes;
- offset+= nbytes;
- addr+= nbytes;
-
- /* Output the printable characters. */
- print_buffer(buf, nbytes);
-
- /* Break if less than requested... */
- if ((count - nbytes))
- break;
- }
-
- if (nbytes == -1)
- my_safe_printf_stderr("Can't read from address %p", addr);
-
- close(fd);
-
- return 0;
+ sigaction(SIGILL, &sa, NULL);
+ sigaction(SIGFPE, &sa, NULL);
}
-#endif
/*
Attempt to print a char * pointer as a string.
@@ -187,24 +91,25 @@ static int safe_print_str(const char *addr, size_t max_len)
int my_safe_print_str(const char* val, size_t max_len)
{
-#ifdef __linux__
- char *heap_end;
-
- // Try and make use of /proc filesystem to safely print memory contents.
- if (!safe_print_str(val, max_len))
- return 0;
-
- heap_end= (char*) sbrk(0);
-#endif
-
- if (!PTR_SANE(val))
+ const char *orig_val= val;
+ if (!val)
{
- my_safe_printf_stderr("%s", "is an invalid pointer");
+ my_safe_printf_stderr("%s", "(null)");
return 1;
}
- for (; max_len && PTR_SANE(val) && *val; --max_len)
- my_write_stderr((val++), 1);
+ for (; max_len; --max_len)
+ {
+ if (my_write_stderr((val++), 1) != 1)
+ {
+ if ((errno == EFAULT) &&(val == orig_val + 1))
+ {
+ // We can not read the address from very beginning
+ my_safe_printf_stderr("Can't access address %p", orig_val);
+ }
+ break;
+ }
+ }
my_safe_printf_stderr("%s", "\n");
return 0;
@@ -548,11 +453,6 @@ static EXCEPTION_POINTERS *exception_ptrs;
#define MODULE64_SIZE_WINXP 576
#define STACKWALK_MAX_FRAMES 64
-void my_init_stacktrace(int setup_handlers __attribute__((unused)))
-{
-}
-
-
void my_set_exception_pointers(EXCEPTION_POINTERS *ep)
{
exception_ptrs = ep;
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index 9db1e0efabf..2a8e54621c0 100644
--- a/mysys/thr_mutex.c
+++ b/mysys/thr_mutex.c
@@ -233,7 +233,7 @@ int safe_mutex_lock(safe_mutex_t *mp, myf my_flags, const char *file,
int error;
DBUG_PRINT("mutex", ("%s (0x%lx) locking", mp->name ? mp->name : "Null",
(ulong) mp));
- DBUG_PUSH("");
+ DBUG_PUSH_EMPTY;
pthread_mutex_lock(&mp->global);
if (!mp->file)
@@ -395,7 +395,7 @@ int safe_mutex_lock(safe_mutex_t *mp, myf my_flags, const char *file,
}
end:
- DBUG_POP();
+ DBUG_POP_EMPTY;
if (!error)
DBUG_PRINT("mutex", ("%s (0x%lx) locked", mp->name, (ulong) mp));
return error;
diff --git a/plugin/handler_socket/CMakeLists.txt b/plugin/handler_socket/CMakeLists.txt
index 329ff58d7f2..5a1925b40e0 100644
--- a/plugin/handler_socket/CMakeLists.txt
+++ b/plugin/handler_socket/CMakeLists.txt
@@ -1,7 +1,8 @@
-IF(WIN32)
+IF(WIN32 OR WITHOUT_SERVER)
# Handlersocket does not compile on Windows, compiles but does
- # not start on FreeBSD.
+ # not start on FreeBSD.
+ # It is a server plugin and disable it explicitly here.
RETURN()
ENDIF()
diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c
index 113a26804bf..33e4d067766 100644
--- a/plugin/server_audit/server_audit.c
+++ b/plugin/server_audit/server_audit.c
@@ -1431,7 +1431,6 @@ static size_t escape_string_hide_passwords(const char *str, unsigned int len,
const char *res_start= result;
const char *res_end= result + result_len - 2;
size_t d_len;
- char b_char;
while (len)
{
@@ -1469,27 +1468,28 @@ static size_t escape_string_hide_passwords(const char *str, unsigned int len,
if (*next_s)
{
- memmove(result + d_len, "*****", 5);
+ const char b_char= *next_s++;
+ memset(result + d_len, '*', 5);
result+= d_len + 5;
- b_char= *(next_s++);
- }
- else
- result+= d_len;
- while (*next_s)
- {
- if (*next_s == b_char)
- {
- ++next_s;
- break;
- }
- if (*next_s == '\\')
+ while (*next_s)
{
- if (next_s[1])
- next_s++;
+ if (*next_s == b_char)
+ {
+ ++next_s;
+ break;
+ }
+ if (*next_s == '\\')
+ {
+ if (next_s[1])
+ next_s++;
+ }
+ next_s++;
}
- next_s++;
}
+ else
+ result+= d_len;
+
len-= (uint)(next_s - str);
str= next_s;
continue;
@@ -1497,19 +1497,23 @@ static size_t escape_string_hide_passwords(const char *str, unsigned int len,
no_password:
if (result >= res_end)
break;
- if ((b_char= escaped_char(*str)))
+ else
{
- if (result+1 >= res_end)
- break;
- *(result++)= '\\';
- *(result++)= b_char;
+ const char b_char= escaped_char(*str);
+ if (b_char)
+ {
+ if (result+1 >= res_end)
+ break;
+ *(result++)= '\\';
+ *(result++)= b_char;
+ }
+ else if (is_space(*str))
+ *(result++)= ' ';
+ else
+ *(result++)= *str;
+ str++;
+ len--;
}
- else if (is_space(*str))
- *(result++)= ' ';
- else
- *(result++)= *str;
- str++;
- len--;
}
*result= 0;
return result - res_start;
diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh
index 2c3578834eb..0b33f61710e 100644
--- a/scripts/mysqld_multi.sh
+++ b/scripts/mysqld_multi.sh
@@ -308,9 +308,7 @@ sub report_mysqlds
sub start_mysqlds()
{
- my (@groups, $com, $tmp, $i, @options, $j, $mysqld_found, $suffix_found, $info_sent);
-
- $suffix_found= 0;
+ my (@groups, $com, $tmp, $i, @options, $j, $mysqld_found, $info_sent);
if (!$opt_no_log)
{
@@ -349,10 +347,6 @@ sub start_mysqlds()
$options[$j]= quote_shell_word($options[$j]);
$tmp.= " $options[$j]";
}
- elsif ("--defaults-group-suffix=" eq substr($options[$j], 0, 24))
- {
- $suffix_found= 1;
- }
else
{
$options[$j]= quote_shell_word($options[$j]);
@@ -369,12 +363,6 @@ sub start_mysqlds()
$info_sent= 1;
}
- if (!$suffix_found)
- {
- $com.= " --defaults-group-suffix=";
- $com.= substr($groups[$i],6);
- }
-
$com.= $tmp;
if ($opt_wsrep_new_cluster) {
diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh
index 1991fe4dd8d..63ff5646535 100644
--- a/scripts/wsrep_sst_mariabackup.sh
+++ b/scripts/wsrep_sst_mariabackup.sh
@@ -712,7 +712,8 @@ INNODB_DATA_HOME_DIR=${INNODB_DATA_HOME_DIR:-""}
if [ ! -z "$INNODB_DATA_HOME_DIR_ARG" ]; then
INNODB_DATA_HOME_DIR=$INNODB_DATA_HOME_DIR_ARG
fi
-# if INNODB_DATA_HOME_DIR env. variable is not set, try to get it from my.cnf
+# if no command line arg and INNODB_DATA_HOME_DIR environment variable
+# is not set, try to get it from my.cnf:
if [ -z "$INNODB_DATA_HOME_DIR" ]; then
INNODB_DATA_HOME_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-data-home-dir '')
fi
@@ -951,17 +952,25 @@ then
ib_home_dir=$INNODB_DATA_HOME_DIR
- # Try to set ib_log_dir from the command line:
- ib_log_dir=$INNODB_LOG_GROUP_HOME_ARG
- if [ -z "$ib_log_dir" ]; then
- ib_log_dir=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-log-group-home-dir "")
+ WSREP_LOG_DIR=${WSREP_LOG_DIR:-""}
+ # Try to set WSREP_LOG_DIR from the command line:
+ if [ ! -z "$INNODB_LOG_GROUP_HOME_ARG" ]; then
+ WSREP_LOG_DIR=$INNODB_LOG_GROUP_HOME_ARG
fi
- if [ -z "$ib_log_dir" ]; then
- ib_log_dir=$(parse_cnf --mysqld innodb-log-group-home-dir "")
+ # if no command line arg and WSREP_LOG_DIR is not set,
+ # try to get it from my.cnf:
+ if [ -z "$WSREP_LOG_DIR" ]; then
+ WSREP_LOG_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-log-group-home-dir '')
fi
+ if [ -z "$WSREP_LOG_DIR" ]; then
+ WSREP_LOG_DIR=$(parse_cnf --mysqld innodb-log-group-home-dir '')
+ fi
+
+ ib_log_dir=$WSREP_LOG_DIR
# Try to set ib_undo_dir from the command line:
- ib_undo_dir=$INNODB_UNDO_DIR_ARG
+ ib_undo_dir=${INNODB_UNDO_DIR_ARG:-""}
+ # if no command line arg then try to get it from my.cnf:
if [ -z "$ib_undo_dir" ]; then
ib_undo_dir=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-undo-directory "")
fi
diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh
index 96e542ce844..d42cf014009 100644
--- a/scripts/wsrep_sst_rsync.sh
+++ b/scripts/wsrep_sst_rsync.sh
@@ -152,10 +152,11 @@ fi
WSREP_LOG_DIR=${WSREP_LOG_DIR:-""}
# Try to set WSREP_LOG_DIR from the command line:
-if [ -z "$WSREP_LOG_DIR" ]; then
+if [ ! -z "$INNODB_LOG_GROUP_HOME_ARG" ]; then
WSREP_LOG_DIR=$INNODB_LOG_GROUP_HOME_ARG
fi
-# if WSREP_LOG_DIR env. variable is not set, try to get it from my.cnf
+# if no command line arg and WSREP_LOG_DIR is not set,
+# try to get it from my.cnf:
if [ -z "$WSREP_LOG_DIR" ]; then
WSREP_LOG_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-log-group-home-dir '')
fi
@@ -176,7 +177,8 @@ INNODB_DATA_HOME_DIR=${INNODB_DATA_HOME_DIR:-""}
if [ ! -z "$INNODB_DATA_HOME_DIR_ARG" ]; then
INNODB_DATA_HOME_DIR=$INNODB_DATA_HOME_DIR_ARG
fi
-# if INNODB_DATA_HOME_DIR env. variable is not set, try to get it from my.cnf
+# if no command line arg and INNODB_DATA_HOME_DIR environment variable
+# is not set, try to get it from my.cnf:
if [ -z "$INNODB_DATA_HOME_DIR" ]; then
INNODB_DATA_HOME_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-data-home-dir '')
fi
diff --git a/sql-common/client.c b/sql-common/client.c
index 5e072a8b538..42ef5e24a75 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -3665,6 +3665,12 @@ static MYSQL_RES * cli_use_result(MYSQL *mysql)
}
+my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql)
+{
+ return mysql->affected_rows;
+}
+
+
/**************************************************************************
Return next row of the query results
**************************************************************************/
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 8a3677d7cf6..4be129ac9d0 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -1,5 +1,5 @@
# Copyright (c) 2006, 2014, Oracle and/or its affiliates.
-# Copyright (c) 2010, 2018, MariaDB Corporation
+# Copyright (c) 2010, 2020, 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
diff --git a/sql/backup.cc b/sql/backup.cc
index 40791e27416..02570dfd30d 100644
--- a/sql/backup.cc
+++ b/sql/backup.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2018, MariaDB Corporation
+/* Copyright (c) 2018, 2020, 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 Foundation; version 2 of the License.
@@ -96,7 +96,7 @@ bool run_backup_stage(THD *thd, backup_stages stage)
do
{
- bool res;
+ bool res= false;
backup_stages previous_stage= thd->current_backup_stage;
thd->current_backup_stage= next_stage;
switch (next_stage) {
@@ -120,7 +120,6 @@ bool run_backup_stage(THD *thd, backup_stages stage)
break;
case BACKUP_FINISHED:
DBUG_ASSERT(0);
- res= 0;
}
if (res)
{
diff --git a/sql/field.cc b/sql/field.cc
index f50ddec1c80..491cd1b5079 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1888,7 +1888,7 @@ void Field::copy_from_tmp(int row_offset)
}
-bool Field::send_binary(Protocol *protocol)
+bool Field::send(Protocol *protocol)
{
char buff[MAX_FIELD_WIDTH];
String tmp(buff,sizeof(buff),charset());
@@ -1897,6 +1897,18 @@ bool Field::send_binary(Protocol *protocol)
}
+bool Field_num::send_numeric_zerofill_str(Protocol_text *protocol,
+ protocol_send_type_t send_type)
+{
+ DBUG_ASSERT(marked_for_read());
+ StringBuffer<MAX_FIELD_WIDTH> tmp(&my_charset_latin1);
+ val_str(&tmp);
+ return protocol->store_numeric_zerofill_str(tmp.ptr(),
+ tmp.length(),
+ send_type);
+}
+
+
/**
Check to see if field size is compatible with destination.
@@ -2407,6 +2419,33 @@ bool Field::get_date(MYSQL_TIME *to, date_mode_t mode)
return !t->is_valid_temporal();
}
+
+longlong Field::val_datetime_packed(THD *thd)
+{
+ MYSQL_TIME ltime, tmp;
+ if (get_date(&ltime, Datetime::Options_cmp(thd)))
+ return 0;
+ if (ltime.time_type != MYSQL_TIMESTAMP_TIME)
+ return pack_time(&ltime);
+ if (time_to_datetime_with_warn(thd, &ltime, &tmp, TIME_CONV_NONE))
+ return 0;
+ return pack_time(&tmp);
+}
+
+
+longlong Field::val_time_packed(THD *thd)
+{
+ MYSQL_TIME ltime;
+ Time::Options_cmp opt(thd);
+ if (get_date(&ltime, opt))
+ return 0;
+ if (ltime.time_type == MYSQL_TIMESTAMP_TIME)
+ return pack_time(&ltime);
+ // Conversion from DATETIME or DATE to TIME is needed
+ return Time(thd, &ltime, opt).to_packed();
+}
+
+
/**
This is called when storing a date in a string.
@@ -3855,11 +3894,16 @@ String *Field_tiny::val_str(String *val_buffer,
return val_str_from_long(val_buffer, 5, -10, nr);
}
-bool Field_tiny::send_binary(Protocol *protocol)
+bool Field_tiny::send(Protocol *protocol)
{
- return protocol->store_tiny((longlong) (int8) ptr[0]);
+ DBUG_ASSERT(marked_for_read());
+ Protocol_text *txt;
+ if (unlikely(zerofill) && (txt= dynamic_cast<Protocol_text*>(protocol)))
+ return send_numeric_zerofill_str(txt, PROTOCOL_SEND_TINY);
+ return protocol->store_tiny(Field_tiny::val_int());
}
+
int Field_tiny::cmp(const uchar *a_ptr, const uchar *b_ptr) const
{
signed char a,b;
@@ -4015,8 +4059,12 @@ String *Field_short::val_str(String *val_buffer,
}
-bool Field_short::send_binary(Protocol *protocol)
+bool Field_short::send(Protocol *protocol)
{
+ DBUG_ASSERT(marked_for_read());
+ Protocol_text *txt;
+ if (unlikely(zerofill) && (txt= dynamic_cast<Protocol_text*>(protocol)))
+ return send_numeric_zerofill_str(txt, PROTOCOL_SEND_SHORT);
return protocol->store_short(Field_short::val_int());
}
@@ -4198,9 +4246,12 @@ String *Field_int::val_str_from_long(String *val_buffer,
}
-bool Field_medium::send_binary(Protocol *protocol)
+bool Field_medium::send(Protocol *protocol)
{
DBUG_ASSERT(marked_for_read());
+ Protocol_text *txt;
+ if (unlikely(zerofill) && (txt= dynamic_cast<Protocol_text*>(protocol)))
+ return send_numeric_zerofill_str(txt, PROTOCOL_SEND_LONG);
return protocol->store_long(Field_medium::val_int());
}
@@ -4369,12 +4420,16 @@ String *Field_long::val_str(String *val_buffer,
}
-bool Field_long::send_binary(Protocol *protocol)
+bool Field_long::send(Protocol *protocol)
{
DBUG_ASSERT(marked_for_read());
+ Protocol_text *txt;
+ if (unlikely(zerofill) && (txt= dynamic_cast<Protocol_text*>(protocol)))
+ return send_numeric_zerofill_str(txt, PROTOCOL_SEND_LONG);
return protocol->store_long(Field_long::val_int());
}
+
int Field_long::cmp(const uchar *a_ptr, const uchar *b_ptr) const
{
int32 a,b;
@@ -4506,9 +4561,12 @@ String *Field_longlong::val_str(String *val_buffer,
}
-bool Field_longlong::send_binary(Protocol *protocol)
+bool Field_longlong::send(Protocol *protocol)
{
DBUG_ASSERT(marked_for_read());
+ Protocol_text *txt;
+ if (unlikely(zerofill) && (txt= dynamic_cast<Protocol_text*>(protocol)))
+ return send_numeric_zerofill_str(txt, PROTOCOL_SEND_LONGLONG);
return protocol->store_longlong(Field_longlong::val_int(), unsigned_flag);
}
@@ -4686,10 +4744,13 @@ void Field_float::sort_string(uchar *to,uint length __attribute__((unused)))
}
-bool Field_float::send_binary(Protocol *protocol)
+bool Field_float::send(Protocol *protocol)
{
DBUG_ASSERT(marked_for_read());
- return protocol->store((float) Field_float::val_real(), dec, (String*) 0);
+ Protocol_text *txt;
+ if (unlikely(zerofill) && (txt= dynamic_cast<Protocol_text*>(protocol)))
+ return send_numeric_zerofill_str(txt, PROTOCOL_SEND_FLOAT);
+ return protocol->store_float((float) Field_float::val_real(), dec);
}
@@ -4980,9 +5041,13 @@ String *Field_double::val_str(String *val_buffer,
return val_buffer;
}
-bool Field_double::send_binary(Protocol *protocol)
+bool Field_double::send(Protocol *protocol)
{
- return protocol->store((double) Field_double::val_real(), dec, (String*) 0);
+ DBUG_ASSERT(marked_for_read());
+ Protocol_text *txt;
+ if (unlikely(zerofill) && (txt= dynamic_cast<Protocol_text*>(protocol)))
+ return send_numeric_zerofill_str(txt, PROTOCOL_SEND_DOUBLE);
+ return protocol->store_double(Field_double::val_real(), dec);
}
@@ -5378,7 +5443,7 @@ bool Field_timestamp::get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate)
}
-bool Field_timestamp0::send_binary(Protocol *protocol)
+bool Field_timestamp0::send(Protocol *protocol)
{
MYSQL_TIME ltime;
Field_timestamp0::get_date(&ltime, date_mode_t(0));
@@ -5538,7 +5603,7 @@ int Field_timestamp_with_dec::set_time()
return 0;
}
-bool Field_timestamp_with_dec::send_binary(Protocol *protocol)
+bool Field_timestamp_with_dec::send(Protocol *protocol)
{
MYSQL_TIME ltime;
Field_timestamp::get_date(&ltime, date_mode_t(0));
@@ -6047,7 +6112,25 @@ bool Field_time0::get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate)
}
-bool Field_time::send_binary(Protocol *protocol)
+int Field_time::store_native(const Native &value)
+{
+ Time t(value);
+ DBUG_ASSERT(t.is_valid_time());
+ store_TIME(t);
+ return 0;
+}
+
+
+bool Field_time::val_native(Native *to)
+{
+ MYSQL_TIME ltime;
+ get_date(&ltime, date_mode_t(0));
+ int warn;
+ return Time(&warn, &ltime, 0).to_native(to, decimals());
+}
+
+
+bool Field_time::send(Protocol *protocol)
{
MYSQL_TIME ltime;
get_date(&ltime, Time::Options(TIME_TIME_ONLY, get_thd()));
@@ -6283,6 +6366,33 @@ Binlog_type_info Field_timef::binlog_type_info() const
return Binlog_type_info(Field_timef::binlog_type(), decimals(), 1);
}
+
+longlong Field_timef::val_time_packed(THD *thd)
+{
+ DBUG_ASSERT(marked_for_read());
+ longlong tmp= my_time_packed_from_binary(ptr, dec);
+ MYSQL_TIME ltime;
+ TIME_from_longlong_time_packed(&ltime, tmp);
+ return pack_time(&ltime);
+}
+
+
+int Field_timef::store_native(const Native &value)
+{
+ DBUG_ASSERT(value.length() == my_time_binary_length(dec));
+ DBUG_ASSERT(Time(value).is_valid_time());
+ memcpy(ptr, value.ptr(), value.length());
+ return 0;
+}
+
+
+bool Field_timef::val_native(Native *to)
+{
+ uint32 binlen= my_time_binary_length(dec);
+ return to->copy((const char*) ptr, binlen);
+}
+
+
/****************************************************************************
** year type
** Save in a byte the year 0, 1901->2155
@@ -6369,9 +6479,12 @@ int Field_year::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg)
return 0;
}
-bool Field_year::send_binary(Protocol *protocol)
+bool Field_year::send(Protocol *protocol)
{
DBUG_ASSERT(marked_for_read());
+ Protocol_text *txt;
+ if ((txt= dynamic_cast<Protocol_text*>(protocol)))
+ return send_numeric_zerofill_str(txt, PROTOCOL_SEND_SHORT);
ulonglong tmp= Field_year::val_int();
return protocol->store_short(tmp);
}
@@ -6506,7 +6619,7 @@ void Field_date::store_TIME(const MYSQL_TIME *ltime)
int4store(ptr,tmp);
}
-bool Field_date::send_binary(Protocol *protocol)
+bool Field_date::send(Protocol *protocol)
{
longlong tmp= Field_date::val_int();
MYSQL_TIME tm;
@@ -6600,7 +6713,7 @@ void Field_newdate::store_TIME(const MYSQL_TIME *ltime)
}
-bool Field_newdate::send_binary(Protocol *protocol)
+bool Field_newdate::send(Protocol *protocol)
{
MYSQL_TIME tm;
Field_newdate::get_date(&tm, date_mode_t(0));
@@ -6668,6 +6781,14 @@ bool Field_newdate::get_TIME(MYSQL_TIME *ltime, const uchar *pos,
}
+longlong Field_newdate::val_datetime_packed(THD *thd)
+{
+ MYSQL_TIME ltime;
+ Field_newdate::get_date(&ltime, date_mode_t(0));
+ return pack_time(&ltime);
+}
+
+
int Field_newdate::cmp(const uchar *a_ptr, const uchar *b_ptr) const
{
uint32 a,b;
@@ -6772,7 +6893,7 @@ Field_datetime::conversion_depends_on_sql_mode(THD *thd, Item *expr) const
}
-bool Field_datetime0::send_binary(Protocol *protocol)
+bool Field_datetime0::send(Protocol *protocol)
{
MYSQL_TIME tm;
Field_datetime0::get_date(&tm, date_mode_t(0));
@@ -6900,7 +7021,7 @@ void Field_datetime_hires::store_TIME(const MYSQL_TIME *ltime)
store_bigendian(packed, ptr, Field_datetime_hires::pack_length());
}
-bool Field_datetime_with_dec::send_binary(Protocol *protocol)
+bool Field_datetime_with_dec::send(Protocol *protocol)
{
MYSQL_TIME ltime;
get_date(&ltime, date_mode_t(0));
@@ -6989,6 +7110,16 @@ Binlog_type_info Field_datetimef::binlog_type_info() const
return Binlog_type_info(Field_datetimef::binlog_type(), decimals(), 1);
}
+longlong Field_datetimef::val_datetime_packed(THD *thd)
+{
+ DBUG_ASSERT(marked_for_read());
+ longlong tmp= my_datetime_packed_from_binary(ptr, dec);
+ MYSQL_TIME ltime;
+ TIME_from_longlong_datetime_packed(&ltime, tmp);
+ return pack_time(&ltime);
+}
+
+
/****************************************************************************
** string type
** A string may be varchar or binary
@@ -7109,6 +7240,23 @@ void Field_longstr::make_send_field(Send_field *field)
}
}
+
+/*
+ An optimized version that uses less stack than Field::send().
+*/
+bool Field_longstr::send(Protocol *protocol)
+{
+ String tmp;
+ val_str(&tmp, &tmp);
+ /*
+ Ensure this function is only used with classes that do not allocate
+ memory in val_str()
+ */
+ DBUG_ASSERT(tmp.alloced_length() == 0);
+ return protocol->store(tmp.ptr(), tmp.length(), tmp.charset());
+}
+
+
/* Copy a string and fill with space */
int Field_string::store(const char *from, size_t length,CHARSET_INFO *cs)
@@ -7698,6 +7846,17 @@ my_decimal *Field_varstring::val_decimal(my_decimal *decimal_value)
}
+/*
+ An optimized version that uses less stack and less temporary
+ variable initialization than Field_longstr::send()
+*/
+bool Field_varstring::send(Protocol *protocol)
+{
+ return protocol->store((const char *) get_data(), get_length(),
+ field_charset());
+}
+
+
#ifdef HAVE_valgrind
void Field_varstring::mark_unused_memory_as_defined()
{
diff --git a/sql/field.h b/sql/field.h
index 0f531564116..be4d279ce61 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -37,6 +37,7 @@
class Send_field;
class Copy_field;
class Protocol;
+class Protocol_text;
class Create_field;
class Relay_log_info;
class Field;
@@ -1576,7 +1577,7 @@ public:
ptr= old_ptr;
return str;
}
- virtual bool send_binary(Protocol *protocol);
+ virtual bool send(Protocol *protocol);
virtual uchar *pack(uchar *to, const uchar *from, uint max_length);
/**
@@ -1605,6 +1606,8 @@ public:
void copy_from_tmp(int offset);
uint fill_cache_field(struct st_cache_field *copy);
virtual bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate);
+ virtual longlong val_datetime_packed(THD *thd);
+ virtual longlong val_time_packed(THD *thd);
virtual const TYPELIB *get_typelib() const { return NULL; }
virtual CHARSET_INFO *charset() const= 0;
virtual const DTCollation &dtcollation() const= 0;
@@ -2005,6 +2008,9 @@ protected:
return (flags & UNSIGNED_FLAG) ? Binlog_type_info::SIGN_UNSIGNED :
Binlog_type_info::SIGN_SIGNED;
}
+ bool send_numeric_zerofill_str(Protocol_text *protocol,
+ protocol_send_type_t send_type);
+
public:
const uint8 dec;
bool zerofill,unsigned_flag; // Purify cannot handle bit fields
@@ -2194,6 +2200,7 @@ public:
int store_decimal(const my_decimal *d) override;
uint32 max_data_length() const override;
void make_send_field(Send_field *) override;
+ bool send(Protocol *protocol) override;
bool is_varchar_and_in_write_set() const override
{
@@ -2520,7 +2527,7 @@ public:
double val_real() override;
longlong val_int() override;
String *val_str(String *, String *) override;
- bool send_binary(Protocol *protocol) override;
+ bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override;
uint32 pack_length() const override { return 1; }
@@ -2583,7 +2590,7 @@ public:
double val_real() override;
longlong val_int() override;
String *val_str(String *, String *) override;
- bool send_binary(Protocol *protocol) override;
+ bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override;
uint32 pack_length() const override { return 2; }
@@ -2630,7 +2637,7 @@ public:
double val_real() override;
longlong val_int() override;
String *val_str(String *, String *) override;
- bool send_binary(Protocol *protocol) override;
+ bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override;
uint32 pack_length() const override { return 3; }
@@ -2681,7 +2688,7 @@ public:
int reset() override { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; }
double val_real() override;
longlong val_int() override;
- bool send_binary(Protocol *protocol) override;
+ bool send(Protocol *protocol) override;
String *val_str(String *, String *) override;
int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override;
@@ -2743,7 +2750,7 @@ public:
double val_real() override;
longlong val_int() override;
String *val_str(String *, String *) override;
- bool send_binary(Protocol *protocol) override;
+ bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override;
uint32 pack_length() const override { return 8; }
@@ -2843,7 +2850,7 @@ public:
double val_real() override;
longlong val_int() override;
String *val_str(String *, String *) override;
- bool send_binary(Protocol *protocol) override;
+ bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff, uint length) override;
uint32 pack_length() const override { return sizeof(float); }
@@ -2907,7 +2914,7 @@ public:
longlong val_int() override final { return val_int_from_real(false); }
ulonglong val_uint() override final { return (ulonglong) val_int_from_real(true); }
String *val_str(String *, String *) override final;
- bool send_binary(Protocol *protocol) override final;
+ bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override final;
void sort_string(uchar *buff, uint length) override final;
uint32 pack_length() const override final { return sizeof(double); }
@@ -3210,7 +3217,7 @@ public:
{
return (double) Field_timestamp0::val_int();
}
- bool send_binary(Protocol *protocol) override;
+ bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override;
uint32 pack_length() const override { return 4; }
@@ -3265,7 +3272,7 @@ public:
DBUG_ASSERT(length == pack_length());
memcpy(to, ptr, length);
}
- bool send_binary(Protocol *protocol) override;
+ bool send(Protocol *protocol) override;
double val_real() override;
my_decimal* val_decimal(my_decimal*) override;
int set_time() override;
@@ -3403,7 +3410,7 @@ public:
longlong val_int() override;
String *val_str(String *, String *) override;
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate) override;
- bool send_binary(Protocol *protocol) override;
+ bool send(Protocol *protocol) override;
Information_schema_numeric_attributes
information_schema_numeric_attributes() const override
{
@@ -3462,7 +3469,7 @@ public:
double val_real() override;
longlong val_int() override;
String *val_str(String *, String *) override;
- bool send_binary(Protocol *protocol) override;
+ bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override;
uint32 pack_length() const override { return 4; }
@@ -3501,13 +3508,14 @@ public:
double val_real() override;
longlong val_int() override;
String *val_str(String *, String *) override;
- bool send_binary(Protocol *protocol) override;
+ bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override;
uint32 pack_length() const override { return 3; }
void sql_type(String &str) const override;
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate) override
{ return Field_newdate::get_TIME(ltime, ptr, fuzzydate); }
+ longlong val_datetime_packed(THD *thd) override;
uint size_of() const override { return sizeof *this; }
Item *get_equal_const_item(THD *thd, const Context &ctx, Item *const_item)
override;
@@ -3555,13 +3563,15 @@ public:
decimals() == from->decimals();
}
sql_mode_t conversion_depends_on_sql_mode(THD *, Item *) const override;
+ int store_native(const Native &value) override;
+ bool val_native(Native *to) override;
int store_time_dec(const MYSQL_TIME *ltime, uint dec) override;
int store(const char *to,size_t length,CHARSET_INFO *charset) override;
int store(double nr) override;
int store(longlong nr, bool unsigned_val) override;
int store_decimal(const my_decimal *) override;
String *val_str(String *, String *) override;
- bool send_binary(Protocol *protocol) override;
+ bool send(Protocol *protocol) override;
void set_curdays(THD *thd);
Field *new_key_field(MEM_ROOT *root, TABLE *new_table,
uchar *new_ptr, uint32 length,
@@ -3706,6 +3716,9 @@ public:
}
int reset() override;
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate) override;
+ longlong val_time_packed(THD *thd) override;
+ int store_native(const Native &value) override;
+ bool val_native(Native *to) override;
uint size_of() const override { return sizeof *this; }
Binlog_type_info binlog_type_info() const override;
};
@@ -3775,7 +3788,7 @@ public:
}
longlong val_int() override;
String *val_str(String *, String *) override;
- bool send_binary(Protocol *protocol) override;
+ bool send(Protocol *protocol) override;
int cmp(const uchar *,const uchar *) const override;
void sort_string(uchar *buff,uint length) override;
uint32 pack_length() const override { return 8; }
@@ -3815,7 +3828,7 @@ public:
uint decimals() const override final { return dec; }
enum ha_base_keytype key_type() const override final { return HA_KEYTYPE_BINARY; }
void make_send_field(Send_field *field) override final;
- bool send_binary(Protocol *protocol) override final;
+ bool send(Protocol *protocol) override final;
uchar *pack(uchar *to, const uchar *from, uint max_length) override final
{ return Field::pack(to, from, max_length); }
const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end,
@@ -3907,6 +3920,7 @@ public:
int reset() override;
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate) override
{ return Field_datetimef::get_TIME(ltime, ptr, fuzzydate); }
+ longlong val_datetime_packed(THD *thd) override;
uint size_of() const override { return sizeof *this; }
Binlog_type_info binlog_type_info() const override;
};
@@ -4153,6 +4167,7 @@ public:
longlong val_int() override;
String *val_str(String *, String *) override;
my_decimal *val_decimal(my_decimal *) override;
+ bool send(Protocol *protocol) override;
int cmp(const uchar *a,const uchar *b) const override;
int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_len) const
override;
@@ -4217,6 +4232,15 @@ private:
double val_real() override;
longlong val_int() override;
uint size_of() const override { return sizeof *this; }
+ /*
+ We use the default Field::send() implementation,
+ because the derived optimized version (from Field_longstr)
+ is not suitable for compressed fields.
+ */
+ bool send(Protocol *protocol) override
+ {
+ return Field::send(protocol);
+ }
enum_field_types binlog_type() const override
{ return MYSQL_TYPE_VARCHAR_COMPRESSED; }
void sql_type(String &str) const override
@@ -4614,6 +4638,15 @@ private:
String *val_str(String *, String *) override;
double val_real() override;
longlong val_int() override;
+ /*
+ We use the default Field::send() implementation,
+ because the derived optimized version (from Field_longstr)
+ is not suitable for compressed fields.
+ */
+ bool send(Protocol *protocol) override
+ {
+ return Field::send(protocol);
+ }
uint size_of() const override { return sizeof *this; }
enum_field_types binlog_type() const override
{ return MYSQL_TYPE_BLOB_COMPRESSED; }
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 8469e7b0fa8..2a713ecf97b 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -215,7 +215,7 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
DBUG_EXECUTE("info",TEST_filesort(filesort->sortorder, s_length););
#ifdef SKIP_DBUG_IN_FILESORT
- DBUG_PUSH(""); /* No DBUG here */
+ DBUG_PUSH_EMPTY; /* No DBUG here */
#endif
SORT_INFO *sort;
TABLE_LIST *tab= table->pos_in_table_list;
@@ -496,7 +496,7 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
sort->examined_rows= param.examined_rows;
sort->return_rows= num_rows;
#ifdef SKIP_DBUG_IN_FILESORT
- DBUG_POP(); /* Ok to DBUG */
+ DBUG_POP_EMPTY; /* Ok to DBUG */
#endif
DBUG_PRINT("exit",
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 0a378bde0bd..921b461f15e 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -9683,7 +9683,6 @@ double ha_partition::read_time(uint index, uint ranges, ha_rows rows)
ha_rows ha_partition::records()
{
- int error;
ha_rows tot_rows= 0;
uint i;
DBUG_ENTER("ha_partition::records");
@@ -9692,9 +9691,10 @@ ha_rows ha_partition::records()
i < m_tot_parts;
i= bitmap_get_next_set(&m_part_info->read_partitions, i))
{
- ha_rows rows;
- if (unlikely((error= m_file[i]->pre_records()) ||
- (rows= m_file[i]->records()) == HA_POS_ERROR))
+ if (unlikely(m_file[i]->pre_records()))
+ DBUG_RETURN(HA_POS_ERROR);
+ const ha_rows rows= m_file[i]->records();
+ if (unlikely(rows == HA_POS_ERROR))
DBUG_RETURN(HA_POS_ERROR);
tot_rows+= rows;
}
diff --git a/sql/item.cc b/sql/item.cc
index dbf20f31d7a..733b5d56b1b 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2064,6 +2064,11 @@ bool Item_name_const::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydat
return rc;
}
+bool Item_name_const::val_native(THD *thd, Native *to)
+{
+ return val_native_from_item(thd, value_item, to);
+}
+
bool Item_name_const::is_null()
{
return value_item->is_null();
@@ -3193,6 +3198,12 @@ void Item_ident::print(String *str, enum_query_type query_type)
use_db_name= use_table_name= false;
}
+ if ((query_type & QT_ITEM_IDENT_DISABLE_DB_TABLE_NAMES))
+ {
+ // Don't print db or table name irrespective of any other settings.
+ use_db_name= use_table_name= false;
+ }
+
if (!field_name.str || !field_name.str[0])
{
append_identifier(thd, str, STRING_WITH_LEN("tmp_field"));
@@ -3309,6 +3320,24 @@ bool Item_field::val_native_result(THD *thd, Native *to)
}
+longlong Item_field::val_datetime_packed(THD *thd)
+{
+ DBUG_ASSERT(fixed == 1);
+ if ((null_value= field->is_null()))
+ return 0;
+ return field->val_datetime_packed(thd);
+}
+
+
+longlong Item_field::val_time_packed(THD *thd)
+{
+ DBUG_ASSERT(fixed == 1);
+ if ((null_value= field->is_null()))
+ return 0;
+ return field->val_time_packed(thd);
+}
+
+
void Item_field::save_result(Field *to)
{
save_field_in_field(result_field, &null_value, to, TRUE);
@@ -7537,7 +7566,6 @@ Item *find_producing_item(Item *item, st_select_lex *sel)
DBUG_ASSERT(item->type() == Item::FIELD_ITEM ||
(item->type() == Item::REF_ITEM &&
((Item_ref *) item)->ref_type() == Item_ref::VIEW_REF));
- Item *producing_item;
Item_field *field_item= NULL;
Item_equal *item_equal= item->get_item_equal();
table_map tab_map= sel->master_unit()->derived->table->map;
@@ -7559,6 +7587,7 @@ Item *find_producing_item(Item *item, st_select_lex *sel)
List_iterator_fast<Item> li(sel->item_list);
if (field_item)
{
+ Item *producing_item= NULL;
uint field_no= field_item->field->field_index;
for (uint i= 0; i <= field_no; i++)
producing_item= li++;
diff --git a/sql/item.h b/sql/item.h
index c4fbf8f9c0a..e872335bb77 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1333,16 +1333,13 @@ public:
{
/*
The default implementation for the Items that do not need native format:
- - Item_basic_value
+ - Item_basic_value (default implementation)
- Item_copy
- Item_exists_subselect
- Item_sum_field
- Item_sum_or_func (default implementation)
- Item_proc
- Item_type_holder (as val_xxx() are never called for it);
- - TODO: Item_name_const will need val_native() in the future,
- when we add this syntax:
- TIMESTAMP WITH LOCAL TIMEZONE'2001-01-01 00:00:00'
These hybrid Item types override val_native():
- Item_field
@@ -1353,6 +1350,8 @@ public:
- Item_direct_ref
- Item_direct_view_ref
- Item_ref_null_helper
+ - Item_name_const
+ - Item_time_literal
- Item_sum_or_func
Note, these hybrid type Item_sum_or_func descendants
override the default implementation:
@@ -3173,6 +3172,7 @@ public:
String *val_str(String *sp);
my_decimal *val_decimal(my_decimal *);
bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
+ bool val_native(THD *thd, Native *to);
bool is_null();
virtual void print(String *str, enum_query_type query_type);
@@ -3474,6 +3474,8 @@ public:
longlong val_int_endpoint(bool left_endp, bool *incl_endp);
bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
bool get_date_result(THD *thd, MYSQL_TIME *ltime,date_mode_t fuzzydate);
+ longlong val_datetime_packed(THD *thd);
+ longlong val_time_packed(THD *thd);
bool is_null() { return field->is_null(); }
void update_null_value();
void update_table_bitmaps()
@@ -4897,6 +4899,10 @@ public:
String *val_str(String *to) { return Time(this).to_string(to, decimals); }
my_decimal *val_decimal(my_decimal *to) { return Time(this).to_decimal(to); }
bool get_date(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate);
+ bool val_native(THD *thd, Native *to)
+ {
+ return Time(thd, this).to_native(to, decimals);
+ }
Item *get_copy(THD *thd)
{ return get_item_copy<Item_time_literal>(thd, this); }
};
@@ -6874,6 +6880,10 @@ public:
{
return has_value() ? Time(this).to_decimal(to) : NULL;
}
+ bool val_native(THD *thd, Native *to)
+ {
+ return has_value() ? Time(thd, this).to_native(to, decimals) : true;
+ }
};
diff --git a/sql/item_func.h b/sql/item_func.h
index 5b4acdce1c6..6a4a9fa5dae 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -485,6 +485,12 @@ public:
virtual longlong val_int(Item_handled_func *) const= 0;
virtual my_decimal *val_decimal(Item_handled_func *, my_decimal *) const= 0;
virtual bool get_date(THD *thd, Item_handled_func *, MYSQL_TIME *, date_mode_t fuzzydate) const= 0;
+ virtual bool val_native(THD *thd, Item_handled_func *, Native *to) const
+ {
+ DBUG_ASSERT(0);
+ to->length(0);
+ return true;
+ }
virtual const Type_handler *
return_type_handler(const Item_handled_func *item) const= 0;
virtual const Type_handler *
@@ -631,6 +637,10 @@ public:
{
return Time(item).to_string(to, item->decimals);
}
+ bool val_native(THD *thd, Item_handled_func *item, Native *to) const
+ {
+ return Time(thd, item).to_native(to, item->decimals);
+ }
};
@@ -788,6 +798,10 @@ public:
{
return m_func_handler->get_date(thd, this, to, fuzzydate);
}
+ bool val_native(THD *thd, Native *to)
+ {
+ return m_func_handler->val_native(thd, this, to);
+ }
};
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index c107c93d584..4acf1c6525b 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -2372,12 +2372,15 @@ double Item_func_distance::val_real()
MBR mbr1, mbr2;
const char *c_end;
-
- if ((null_value= (args[0]->null_value || args[1]->null_value ||
- !(g1= Geometry::construct(&buffer1, res1->ptr(), res1->length())) ||
- !(g2= Geometry::construct(&buffer2, res2->ptr(), res2->length())) ||
- g1->get_mbr(&mbr1, &c_end) ||
- g2->get_mbr(&mbr2, &c_end))))
+ if (args[0]->null_value || args[1]->null_value)
+ goto mem_error;
+ g1= Geometry::construct(&buffer1, res1->ptr(), res1->length());
+ if (!g1)
+ goto mem_error;
+ g2= Geometry::construct(&buffer2, res2->ptr(), res2->length());
+ if (!g2)
+ goto mem_error;
+ if (g1->get_mbr(&mbr1, &c_end) || g2->get_mbr(&mbr2, &c_end))
goto mem_error;
mbr1.add_mbr(&mbr2);
@@ -2526,7 +2529,7 @@ String *Item_func_pointonsurface::val_str(String *str)
Geometry *g;
MBR mbr;
const char *c_end;
- double UNINIT_VAR(px), UNINIT_VAR(py), x0, y0;
+ double UNINIT_VAR(px), UNINIT_VAR(py), x0, UNINIT_VAR(y0);
String *result= 0;
const Gcalc_scan_iterator::point *pprev= NULL;
uint32 srid;
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 58f41ecfbbc..c2de296a109 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2017, Oracle and/or its affiliates.
- Copyright (c) 2009, 2020, MariaDB Corporation
+ Copyright (c) 2009, 2020, 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
@@ -641,7 +641,7 @@ String *Item_func_concat_operator_oracle::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
THD *thd= current_thd;
- String *res;
+ String *res= NULL;
uint i;
null_value=0;
@@ -651,7 +651,7 @@ String *Item_func_concat_operator_oracle::val_str(String *str)
if ((res= args[i]->val_str(str)))
break;
}
- if (i == arg_count)
+ if (!res)
goto null;
if (res != str)
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index c9a493f8efc..35c9df533c4 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -598,6 +598,10 @@ public:
double val_real() { return Time(this).to_double(); }
String *val_str(String *to) { return Time(this).to_string(to, decimals); }
my_decimal *val_decimal(my_decimal *to) { return Time(this).to_decimal(to); }
+ bool val_native(THD *thd, Native *to)
+ {
+ return Time(thd, this).to_native(to, decimals);
+ }
};
diff --git a/sql/mdl.cc b/sql/mdl.cc
index 4772dc017f9..240ef97b1c4 100644
--- a/sql/mdl.cc
+++ b/sql/mdl.cc
@@ -25,6 +25,9 @@
#include <mysql/plugin.h>
#include <mysql/service_thd_wait.h>
#include <mysql/psi/mysql_stage.h>
+#ifdef WITH_WSREP
+#include "wsrep_sst.h"
+#endif
#include <tpool.h>
#include <pfs_metadata_provider.h>
#include <mysql/psi/mysql_mdl.h>
@@ -2332,18 +2335,26 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout)
wait_status= m_wait.timed_wait(m_owner, &abs_shortwait, FALSE,
mdl_request->key.get_wait_state_name());
+ THD* thd= m_owner->get_thd();
+
if (wait_status != MDL_wait::EMPTY)
break;
/* Check if the client is gone while we were waiting. */
- if (! thd_is_connected(m_owner->get_thd()))
+ if (! thd_is_connected(thd))
{
- /*
- * The client is disconnected. Don't wait forever:
- * assume it's the same as a wait timeout, this
- * ensures all error handling is correct.
- */
- wait_status= MDL_wait::TIMEOUT;
- break;
+#if defined(WITH_WSREP) && !defined(EMBEDDED_LIBRARY)
+ // During SST client might not be connected
+ if (!wsrep_is_sst_progress())
+#endif
+ {
+ /*
+ * The client is disconnected. Don't wait forever:
+ * assume it's the same as a wait timeout, this
+ * ensures all error handling is correct.
+ */
+ wait_status= MDL_wait::TIMEOUT;
+ break;
+ }
}
mysql_prlock_wrlock(&lock->m_rwlock);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 4d0b6af8ec9..520ffa8fa0c 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2553,7 +2553,7 @@ void close_connection(THD *thd, uint sql_errno)
if (sql_errno)
{
- net_send_error(thd, sql_errno, ER_DEFAULT(sql_errno), NULL);
+ thd->protocol->net_send_error(thd, sql_errno, ER_DEFAULT(sql_errno), NULL);
thd->print_aborted_warning(lvl, ER_DEFAULT(sql_errno));
}
else
@@ -2873,7 +2873,6 @@ void init_signals(void)
sigemptyset(&sa.sa_mask);
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
- my_init_stacktrace(0);
#if defined(__amiga__)
sa.sa_handler=(void(*)())handle_fatal_signal;
#else
diff --git a/sql/mysqld.h b/sql/mysqld.h
index fda3a7d2ef9..cd05a66fff3 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -872,6 +872,12 @@ enum enum_query_type
QT_ITEM_SUBSELECT_ID_ONLY,
QT_SHOW_SELECT_NUMBER= (1<<10),
+
+ /// Do not print database name or table name in the identifiers (even if
+ /// this means the printout will be ambigous). It is assumed that the caller
+ /// passing this flag knows what they are doing.
+ QT_ITEM_IDENT_DISABLE_DB_TABLE_NAMES= (1 <<11),
+
/// This is used for EXPLAIN EXTENDED extra warnings / Be more detailed
/// Be more detailed than QT_EXPLAIN.
/// Perhaps we should eventually include QT_ITEM_IDENT_SKIP_CURRENT_DATABASE
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 303c33b8fc1..d5e6a7b92bf 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -32,13 +32,6 @@
#include <stdarg.h>
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
-/* Declared non-static only because of the embedded library. */
-bool net_send_error_packet(THD *, uint, const char *, const char *);
-/* Declared non-static only because of the embedded library. */
-bool net_send_ok(THD *, uint, uint, ulonglong, ulonglong, const char *,
- bool);
-/* Declared non-static only because of the embedded library. */
-bool net_send_eof(THD *thd, uint server_status, uint statement_warn_count);
#ifndef EMBEDDED_LIBRARY
static bool write_eof_packet(THD *, NET *, uint, uint);
#endif
@@ -152,11 +145,11 @@ bool Protocol_binary::net_store_data_cs(const uchar *from, size_t length,
@retval TRUE An error occurred and the message wasn't sent properly
*/
-bool net_send_error(THD *thd, uint sql_errno, const char *err,
- const char* sqlstate)
+bool Protocol::net_send_error(THD *thd, uint sql_errno, const char *err,
+ const char* sqlstate)
{
bool error;
- DBUG_ENTER("net_send_error");
+ DBUG_ENTER("Protocol::net_send_error");
DBUG_ASSERT(!thd->spcont);
DBUG_ASSERT(sql_errno);
@@ -214,10 +207,10 @@ bool net_send_error(THD *thd, uint sql_errno, const char *err,
#ifndef EMBEDDED_LIBRARY
bool
-net_send_ok(THD *thd,
- uint server_status, uint statement_warn_count,
- ulonglong affected_rows, ulonglong id, const char *message,
- bool is_eof)
+Protocol::net_send_ok(THD *thd,
+ uint server_status, uint statement_warn_count,
+ ulonglong affected_rows, ulonglong id,
+ const char *message, bool is_eof)
{
NET *net= &thd->net;
StringBuffer<MYSQL_ERRMSG_SIZE + 10> store;
@@ -225,7 +218,7 @@ net_send_ok(THD *thd,
bool state_changed= false;
bool error= FALSE;
- DBUG_ENTER("net_send_ok");
+ DBUG_ENTER("Protocol::net_send_ok");
if (! net->vio) // hack for re-parsing queries
{
@@ -328,11 +321,11 @@ static uchar eof_buff[1]= { (uchar) 254 }; /* Marker for end of fields */
*/
bool
-net_send_eof(THD *thd, uint server_status, uint statement_warn_count)
+Protocol::net_send_eof(THD *thd, uint server_status, uint statement_warn_count)
{
NET *net= &thd->net;
bool error= FALSE;
- DBUG_ENTER("net_send_eof");
+ DBUG_ENTER("Protocol::net_send_eof");
/*
Check if client understand new format packets (OK instead of EOF)
@@ -419,8 +412,8 @@ static bool write_eof_packet(THD *thd, NET *net,
@retval TRUE An error occurred and the messages wasn't sent properly
*/
-bool net_send_error_packet(THD *thd, uint sql_errno, const char *err,
- const char* sqlstate)
+bool Protocol::net_send_error_packet(THD *thd, uint sql_errno, const char *err,
+ const char* sqlstate)
{
NET *net= &thd->net;
@@ -433,7 +426,7 @@ bool net_send_error_packet(THD *thd, uint sql_errno, const char *err,
char buff[2+1+SQLSTATE_LENGTH+MYSQL_ERRMSG_SIZE], *pos;
my_bool ret;
uint8 save_compress;
- DBUG_ENTER("send_error_packet");
+ DBUG_ENTER("Protocol::send_error_packet");
if (net->vio == 0)
{
@@ -845,13 +838,12 @@ bool Protocol_text::store_field_metadata(const THD * thd,
{
CHARSET_INFO *thd_charset= thd->variables.character_set_results;
char *pos;
- CHARSET_INFO *cs= system_charset_info;
DBUG_ASSERT(field.is_sane());
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{
const LEX_CSTRING def= {STRING_WITH_LEN("def")};
- if (store_ident(def, MY_REPERTOIRE_ASCII) ||
+ if (store_ident(def) ||
store_ident(field.db_name) ||
store_ident(field.table_name) ||
store_ident(field.org_table_name) ||
@@ -867,8 +859,7 @@ bool Protocol_text::store_field_metadata(const THD * thd,
Don't apply character set conversion:
extended metadata is a binary encoded data.
*/
- if (store_binary_string(&metadata, cs,
- MY_REPERTOIRE_UNICODE30))
+ if (store_binary_string(metadata.ptr(), metadata.length()))
return true;
}
if (packet->realloc(packet->length() + 12))
@@ -962,7 +953,7 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags)
for (uint pos= 0; (item=it++); pos++)
{
prot.prepare_for_resend();
- if (prot.store_field_metadata(thd, item, pos))
+ if (prot.store_item_metadata(thd, item, pos))
goto err;
if (prot.write())
DBUG_RETURN(1);
@@ -1042,7 +1033,7 @@ bool Protocol::write()
#endif /* EMBEDDED_LIBRARY */
-bool Protocol_text::store_field_metadata(THD *thd, Item *item, uint pos)
+bool Protocol_text::store_item_metadata(THD *thd, Item *item, uint pos)
{
Send_field field(thd, item);
return store_field_metadata(thd, field, item->charset_for_protocol(), pos);
@@ -1182,12 +1173,10 @@ bool Protocol_text::store_null()
*/
bool Protocol::store_string_aux(const char *from, size_t length,
- CHARSET_INFO *fromcs,
- my_repertoire_t from_repertoire,
- CHARSET_INFO *tocs)
+ CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
{
/* 'tocs' is set 0 when client issues SET character_set_results=NULL */
- if (needs_conversion(fromcs, from_repertoire, tocs))
+ if (needs_conversion(fromcs, tocs))
{
/* Store with conversion */
return net_store_data_cs((uchar*) from, length, fromcs, tocs);
@@ -1220,9 +1209,7 @@ bool Protocol::store_warning(const char *from, size_t length)
bool Protocol_text::store_str(const char *from, size_t length,
- CHARSET_INFO *fromcs,
- my_repertoire_t from_repertoire,
- CHARSET_INFO *tocs)
+ CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
{
#ifndef DBUG_OFF
DBUG_PRINT("info", ("Protocol_text::store field %u : %.*b", field_pos,
@@ -1231,7 +1218,23 @@ bool Protocol_text::store_str(const char *from, size_t length,
DBUG_ASSERT(valid_handler(field_pos, PROTOCOL_SEND_STRING));
field_pos++;
#endif
- return store_string_aux(from, length, fromcs, from_repertoire, tocs);
+ return store_string_aux(from, length, fromcs, tocs);
+}
+
+
+bool Protocol_text::store_numeric_zerofill_str(const char *from,
+ size_t length,
+ protocol_send_type_t send_type)
+{
+#ifndef DBUG_OFF
+ DBUG_PRINT("info",
+ ("Protocol_text::store_numeric_zerofill_str field %u : %.*b",
+ field_pos, (int) length, (length == 0 ? "" : from)));
+ DBUG_ASSERT(field_handlers == 0 || field_pos < field_count);
+ DBUG_ASSERT(valid_handler(field_pos, send_type));
+ field_pos++;
+#endif
+ return store_numeric_string_aux(from, length);
}
@@ -1298,25 +1301,25 @@ bool Protocol_text::store_decimal(const my_decimal *d)
}
-bool Protocol_text::store(float from, uint32 decimals, String *buffer)
+bool Protocol_text::store_float(float from, uint32 decimals)
{
#ifndef DBUG_OFF
DBUG_ASSERT(valid_handler(field_pos, PROTOCOL_SEND_FLOAT));
field_pos++;
#endif
- Float(from).to_string(buffer, decimals);
- return store_numeric_string_aux(buffer->ptr(), buffer->length());
+ Float(from).to_string(&buffer, decimals);
+ return store_numeric_string_aux(buffer.ptr(), buffer.length());
}
-bool Protocol_text::store(double from, uint32 decimals, String *buffer)
+bool Protocol_text::store_double(double from, uint32 decimals)
{
#ifndef DBUG_OFF
DBUG_ASSERT(valid_handler(field_pos, PROTOCOL_SEND_DOUBLE));
field_pos++;
#endif
- buffer->set_real(from, decimals, thd->charset());
- return store_numeric_string_aux(buffer->ptr(), buffer->length());
+ buffer.set_real(from, decimals, thd->charset());
+ return store_numeric_string_aux(buffer.ptr(), buffer.length());
}
@@ -1324,12 +1327,6 @@ bool Protocol_text::store(Field *field)
{
if (field->is_null())
return store_null();
-#ifndef DBUG_OFF
- field_pos++;
-#endif
- char buff[MAX_FIELD_WIDTH];
- String str(buff,sizeof(buff), &my_charset_bin);
- CHARSET_INFO *tocs= this->thd->variables.character_set_results;
#ifdef DBUG_ASSERT_EXISTS
TABLE *table= field->table;
my_bitmap_map *old_map= 0;
@@ -1337,14 +1334,14 @@ bool Protocol_text::store(Field *field)
old_map= dbug_tmp_use_all_columns(table, table->read_set);
#endif
- field->val_str(&str);
+ bool rc= field->send(this);
+
#ifdef DBUG_ASSERT_EXISTS
if (old_map)
dbug_tmp_restore_column_map(table->read_set, old_map);
#endif
- return store_string_aux(str.ptr(), str.length(), str.charset(),
- field->dtcollation().repertoire, tocs);
+ return rc;
}
@@ -1463,12 +1460,10 @@ void Protocol_binary::prepare_for_resend()
bool Protocol_binary::store_str(const char *from, size_t length,
- CHARSET_INFO *fromcs,
- my_repertoire_t from_repertoire,
- CHARSET_INFO *tocs)
+ CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
{
field_pos++;
- return store_string_aux(from, length, fromcs, from_repertoire, tocs);
+ return store_string_aux(from, length, fromcs, tocs);
}
bool Protocol_binary::store_null()
@@ -1531,11 +1526,10 @@ bool Protocol_binary::store_decimal(const my_decimal *d)
StringBuffer<DECIMAL_MAX_STR_LENGTH> str;
(void) d->to_string(&str);
return store_str(str.ptr(), str.length(), str.charset(),
- MY_REPERTOIRE_ASCII,
thd->variables.character_set_results);
}
-bool Protocol_binary::store(float from, uint32 decimals, String *buffer)
+bool Protocol_binary::store_float(float from, uint32 decimals)
{
field_pos++;
char *to= packet->prep_append(4, PACKET_BUFFER_EXTRA_ALLOC);
@@ -1546,7 +1540,7 @@ bool Protocol_binary::store(float from, uint32 decimals, String *buffer)
}
-bool Protocol_binary::store(double from, uint32 decimals, String *buffer)
+bool Protocol_binary::store_double(double from, uint32 decimals)
{
field_pos++;
char *to= packet->prep_append(8, PACKET_BUFFER_EXTRA_ALLOC);
@@ -1560,12 +1554,12 @@ bool Protocol_binary::store(double from, uint32 decimals, String *buffer)
bool Protocol_binary::store(Field *field)
{
/*
- We should not increment field_pos here as send_binary() will call another
+ We should not increment field_pos here as send() will call another
protocol function to do this for us
*/
if (field->is_null())
return store_null();
- return field->send_binary(this);
+ return field->send(this);
}
diff --git a/sql/protocol.h b/sql/protocol.h
index 243f3ce417f..19899885599 100644
--- a/sql/protocol.h
+++ b/sql/protocol.h
@@ -50,38 +50,31 @@ protected:
}
#endif
uint field_count;
-#ifndef EMBEDDED_LIBRARY
- bool net_store_data(const uchar *from, size_t length);
- bool net_store_data_cs(const uchar *from, size_t length,
- CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
-#else
virtual bool net_store_data(const uchar *from, size_t length);
virtual bool net_store_data_cs(const uchar *from, size_t length,
CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
+ virtual bool net_send_ok(THD *, uint, uint, ulonglong, ulonglong, const char *,
+ bool);
+ virtual bool net_send_error_packet(THD *, uint, const char *, const char *);
+#ifdef EMBEDDED_LIBRARY
char **next_field;
MYSQL_FIELD *next_mysql_field;
MEM_ROOT *alloc;
#endif
bool needs_conversion(CHARSET_INFO *fromcs,
- my_repertoire_t from_repertoire,
CHARSET_INFO *tocs) const
{
// 'tocs' is set 0 when client issues SET character_set_results=NULL
return tocs && !my_charset_same(fromcs, tocs) &&
fromcs != &my_charset_bin &&
- tocs != &my_charset_bin &&
- (from_repertoire != MY_REPERTOIRE_ASCII ||
- (fromcs->state & MY_CS_NONASCII) ||
- (tocs->state & MY_CS_NONASCII));
+ tocs != &my_charset_bin;
}
/*
The following two are low-level functions that are invoked from
higher-level store_xxx() funcs. The data is stored into this->packet.
*/
bool store_string_aux(const char *from, size_t length,
- CHARSET_INFO *fromcs,
- my_repertoire_t from_repertoire,
- CHARSET_INFO *tocs);
+ CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
virtual bool send_ok(uint server_status, uint statement_warn_count,
ulonglong affected_rows, ulonglong last_insert_id,
@@ -138,11 +131,9 @@ public:
virtual bool store_longlong(longlong from, bool unsigned_flag)=0;
virtual bool store_decimal(const my_decimal *)=0;
virtual bool store_str(const char *from, size_t length,
- CHARSET_INFO *fromcs,
- my_repertoire_t from_repertoire,
- CHARSET_INFO *tocs)=0;
- virtual bool store(float from, uint32 decimals, String *buffer)=0;
- virtual bool store(double from, uint32 decimals, String *buffer)=0;
+ CHARSET_INFO *fromcs, CHARSET_INFO *tocs)=0;
+ virtual bool store_float(float from, uint32 decimals)=0;
+ virtual bool store_double(double from, uint32 decimals)=0;
virtual bool store(MYSQL_TIME *time, int decimals)=0;
virtual bool store_date(MYSQL_TIME *time)=0;
virtual bool store_time(MYSQL_TIME *time, int decimals)=0;
@@ -150,30 +141,23 @@ public:
// Various useful wrappers for the virtual store*() methods.
// Backward wrapper for store_str()
- inline bool store(const char *from, size_t length, CHARSET_INFO *cs,
- my_repertoire_t repertoire= MY_REPERTOIRE_UNICODE30)
+ bool store(const char *from, size_t length, CHARSET_INFO *cs)
{
- return store_str(from, length, cs, repertoire, character_set_results());
+ return store_str(from, length, cs, character_set_results());
}
- inline bool store_lex_cstring(const LEX_CSTRING &s,
- CHARSET_INFO *fromcs,
- my_repertoire_t from_repertoire,
- CHARSET_INFO *tocs)
+ bool store_lex_cstring(const LEX_CSTRING &s,
+ CHARSET_INFO *fromcs,
+ CHARSET_INFO *tocs)
{
- return store_str(s.str, (uint) s.length, fromcs, from_repertoire, tocs);
+ return store_str(s.str, (uint) s.length, fromcs, tocs);
}
- inline bool store_binary_string(Binary_string *str,
- CHARSET_INFO *fromcs,
- my_repertoire_t from_repertoire)
+ bool store_binary_string(const char *str, size_t length)
{
- return store_str(str->ptr(), (uint) str->length(), fromcs, from_repertoire,
- &my_charset_bin);
+ return store_str(str, (uint) length, &my_charset_bin, &my_charset_bin);
}
- bool store_ident(const LEX_CSTRING &s,
- my_repertoire_t repertoire= MY_REPERTOIRE_UNICODE30)
+ bool store_ident(const LEX_CSTRING &s)
{
- return store_lex_cstring(s, system_charset_info, repertoire,
- character_set_results());
+ return store_lex_cstring(s, system_charset_info, character_set_results());
}
// End of wrappers
@@ -196,6 +180,9 @@ public:
};
virtual enum enum_protocol_type type()= 0;
+ virtual bool net_send_eof(THD *thd, uint server_status, uint statement_warn_count);
+ bool net_send_error(THD *thd, uint sql_errno, const char *err,
+ const char* sqlstate);
void end_statement();
friend int send_answer_1(Protocol *protocol, String *s1, String *s2,
@@ -206,8 +193,9 @@ public:
/** Class used for the old (MySQL 4.0 protocol). */
-class Protocol_text final :public Protocol
+class Protocol_text :public Protocol
{
+ StringBuffer<FLOATING_POINT_BUFFER> buffer;
bool store_numeric_string_aux(const char *from, size_t length);
public:
Protocol_text(THD *thd_arg, ulong prealloc= 0)
@@ -224,24 +212,26 @@ public:
bool store_longlong(longlong from, bool unsigned_flag) override;
bool store_decimal(const my_decimal *) override;
bool store_str(const char *from, size_t length,
- CHARSET_INFO *fromcs,
- my_repertoire_t from_repertoire,
- CHARSET_INFO *tocs) override;
+ CHARSET_INFO *fromcs, CHARSET_INFO *tocs) override;
bool store(MYSQL_TIME *time, int decimals) override;
bool store_date(MYSQL_TIME *time) override;
bool store_time(MYSQL_TIME *time, int decimals) override;
- bool store(float nr, uint32 decimals, String *buffer) override;
- bool store(double from, uint32 decimals, String *buffer) override;
+ bool store_float(float nr, uint32 decimals) override;
+ bool store_double(double from, uint32 decimals) override;
bool store(Field *field) override;
bool send_out_parameters(List<Item_param> *sp_params) override;
+
+ bool store_numeric_zerofill_str(const char *from, size_t length,
+ protocol_send_type_t send_type);
+
#ifdef EMBEDDED_LIBRARY
void remove_last_row() override;
#endif
- bool store_field_metadata(const THD *thd, const Send_field &field,
- CHARSET_INFO *charset_for_protocol,
- uint pos);
- bool store_field_metadata(THD *thd, Item *item, uint pos);
+ virtual bool store_field_metadata(const THD *thd, const Send_field &field,
+ CHARSET_INFO *charset_for_protocol,
+ uint pos);
+ bool store_item_metadata(THD *thd, Item *item, uint pos);
bool store_field_metadata_for_list_fields(const THD *thd, Field *field,
const TABLE_LIST *table_list,
uint pos);
@@ -270,14 +260,12 @@ public:
bool store_longlong(longlong from, bool unsigned_flag) override;
bool store_decimal(const my_decimal *) override;
bool store_str(const char *from, size_t length,
- CHARSET_INFO *fromcs,
- my_repertoire_t from_repertoire,
- CHARSET_INFO *tocs) override;
+ CHARSET_INFO *fromcs, CHARSET_INFO *tocs) override;
bool store(MYSQL_TIME *time, int decimals) override;
bool store_date(MYSQL_TIME *time) override;
bool store_time(MYSQL_TIME *time, int decimals) override;
- bool store(float nr, uint32 decimals, String *buffer) override;
- bool store(double from, uint32 decimals, String *buffer) override;
+ bool store_float(float nr, uint32 decimals) override;
+ bool store_double(double from, uint32 decimals) override;
bool store(Field *field) override;
bool send_out_parameters(List<Item_param> *sp_params) override;
@@ -320,24 +308,21 @@ public:
bool store_long(longlong) override { return false; }
bool store_longlong(longlong, bool) override { return false; }
bool store_decimal(const my_decimal *) override { return false; }
- bool store_str(const char *, size_t, CHARSET_INFO *, my_repertoire_t,
- CHARSET_INFO *) override
+ bool store_str(const char *, size_t, CHARSET_INFO *, CHARSET_INFO *) override
{
return false;
}
bool store(MYSQL_TIME *, int) override { return false; }
bool store_date(MYSQL_TIME *) override { return false; }
bool store_time(MYSQL_TIME *, int) override { return false; }
- bool store(float, uint32, String *) override { return false; }
- bool store(double, uint32, String *) override { return false; }
+ bool store_float(float, uint32) override { return false; }
+ bool store_double(double, uint32) override { return false; }
bool store(Field *) override { return false; }
enum enum_protocol_type type() override { return PROTOCOL_DISCARD; };
};
void send_warning(THD *thd, uint sql_errno, const char *err=0);
-bool net_send_error(THD *thd, uint sql_errno, const char *err,
- const char* sqlstate);
void net_send_progress_packet(THD *thd);
uchar *net_store_data(uchar *to,const uchar *from, size_t length);
uchar *net_store_data(uchar *to,int32 from);
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index b2b253d0d7b..63c3ee30444 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -7961,4 +7961,4 @@ ER_KEY_CANT_HAVE_WITHOUT_OVERLAPS
ER_NOT_ALLOWED_IN_THIS_CONTEXT
eng "'%-.128s' is not allowed in this context"
ER_DATA_WAS_COMMITED_UNDER_ROLLBACK
- eng "Engine %s does not support rollback. Changes where committed during rollback call"
+ eng "Engine %s does not support rollback. Changes were committed during rollback call"
diff --git a/sql/slave.cc b/sql/slave.cc
index fba3992a820..cc50638ae5b 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -3477,7 +3477,7 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full,
protocol->store((ulonglong) mi->rli.max_relay_log_size);
protocol->store(mi->rli.executed_entries);
protocol->store((uint32) mi->received_heartbeats);
- protocol->store((double) mi->heartbeat_period, 3, &tmp);
+ protocol->store_double(mi->heartbeat_period, 3);
protocol->store(gtid_pos->ptr(), gtid_pos->length(), &my_charset_bin);
}
diff --git a/sql/sql_audit.h b/sql/sql_audit.h
index 97317203e34..40276c86a78 100644
--- a/sql/sql_audit.h
+++ b/sql/sql_audit.h
@@ -254,35 +254,36 @@ void mysql_audit_notify_connection_disconnect(THD *thd, int errcode)
}
static inline
-void mysql_audit_notify_connection_change_user(THD *thd)
+void mysql_audit_notify_connection_change_user(THD *thd,
+ const Security_context *old_ctx)
{
if (mysql_audit_connection_enabled())
{
- const Security_context *sctx= thd->security_ctx;
mysql_event_connection event;
event.event_subclass= MYSQL_AUDIT_CONNECTION_CHANGE_USER;
event.status= thd->get_stmt_da()->is_error() ?
thd->get_stmt_da()->sql_errno() : 0;
event.thread_id= (unsigned long)thd->thread_id;
- event.user= sctx->user;
- event.user_length= safe_strlen_uint(sctx->user);
- event.priv_user= sctx->priv_user;
- event.priv_user_length= strlen_uint(sctx->priv_user);
- event.external_user= sctx->external_user;
- event.external_user_length= safe_strlen_uint(sctx->external_user);
- event.proxy_user= sctx->proxy_user;
- event.proxy_user_length= strlen_uint(sctx->proxy_user);
- event.host= sctx->host;
- event.host_length= safe_strlen_uint(sctx->host);
- event.ip= sctx->ip;
- event.ip_length= safe_strlen_uint(sctx->ip);
+ event.user= old_ctx->user;
+ event.user_length= safe_strlen_uint(old_ctx->user);
+ event.priv_user= old_ctx->priv_user;
+ event.priv_user_length= strlen_uint(old_ctx->priv_user);
+ event.external_user= old_ctx->external_user;
+ event.external_user_length= safe_strlen_uint(old_ctx->external_user);
+ event.proxy_user= old_ctx->proxy_user;
+ event.proxy_user_length= strlen_uint(old_ctx->proxy_user);
+ event.host= old_ctx->host;
+ event.host_length= safe_strlen_uint(old_ctx->host);
+ event.ip= old_ctx->ip;
+ event.ip_length= safe_strlen_uint(old_ctx->ip);
event.database= thd->db;
mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS, &event);
}
}
+
static inline
void mysql_audit_external_lock_ex(THD *thd, my_thread_id thread_id,
const char *user, const char *host, const char *ip, query_id_t query_id,
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index a01b5e400ba..ac952fffae8 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -348,6 +348,12 @@ void thd_clear_errors(THD *thd)
}
+extern "C" unsigned long long thd_query_id(const MYSQL_THD thd)
+{
+ return((unsigned long long)thd->query_id);
+}
+
+
/**
Get thread attributes for connection threads
@@ -4983,6 +4989,55 @@ extern "C" size_t thd_query_safe(MYSQL_THD thd, char *buf, size_t buflen)
}
+extern "C" const char *thd_user_name(MYSQL_THD thd)
+{
+ if (!thd->security_ctx)
+ return 0;
+
+ return thd->security_ctx->user;
+}
+
+
+extern "C" const char *thd_client_host(MYSQL_THD thd)
+{
+ if (!thd->security_ctx)
+ return 0;
+
+ return thd->security_ctx->host;
+}
+
+
+extern "C" const char *thd_client_ip(MYSQL_THD thd)
+{
+ if (!thd->security_ctx)
+ return 0;
+
+ return thd->security_ctx->ip;
+}
+
+
+extern "C" LEX_CSTRING *thd_current_db(MYSQL_THD thd)
+{
+ return &thd->db;
+}
+
+
+extern "C" int thd_current_status(MYSQL_THD thd)
+{
+ Diagnostics_area *da= thd->get_stmt_da();
+ if (!da)
+ return 0;
+
+ return da->is_error() ? da->sql_errno() : 0;
+}
+
+
+extern "C" enum enum_server_command thd_current_command(MYSQL_THD thd)
+{
+ return thd->get_command();
+}
+
+
extern "C" int thd_slave_thread(const MYSQL_THD thd)
{
return(thd->slave_thread);
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 7088131f12a..b0f68aa8fab 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -195,7 +195,14 @@ extern char empty_c_string[1];
extern MYSQL_PLUGIN_IMPORT const char **errmesg;
extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd);
+extern "C" unsigned long long thd_query_id(const MYSQL_THD thd);
extern "C" size_t thd_query_safe(MYSQL_THD thd, char *buf, size_t buflen);
+extern "C" const char *thd_user_name(MYSQL_THD thd);
+extern "C" const char *thd_client_host(MYSQL_THD thd);
+extern "C" const char *thd_client_ip(MYSQL_THD thd);
+extern "C" LEX_CSTRING *thd_current_db(MYSQL_THD thd);
+extern "C" int thd_current_status(MYSQL_THD thd);
+extern "C" enum enum_server_command thd_current_command(MYSQL_THD thd);
/**
@class CSET_STRING
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 83f4de1b5df..479a310542b 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -1494,7 +1494,7 @@ void CONNECT::close_with_error(uint sql_errno,
if (thd)
{
if (sql_errno)
- net_send_error(thd, sql_errno, message, NULL);
+ thd->protocol->net_send_error(thd, sql_errno, message, NULL);
close_connection(thd, close_error);
delete thd;
set_current_thd(0);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 144b86e8fc9..8c95aa0a760 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1693,7 +1693,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
else
auth_rc= acl_authenticate(thd, packet_length);
- mysql_audit_notify_connection_change_user(thd);
+ mysql_audit_notify_connection_change_user(thd, &save_security_ctx);
if (auth_rc)
{
/* Free user if allocated by acl_authenticate */
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index f6920e7420f..6753b857b54 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -243,65 +243,6 @@ private:
class Ed_connection;
-/**
- Protocol_local: a helper class to intercept the result
- of the data written to the network.
-*/
-
-class Protocol_local :public Protocol
-{
-public:
- Protocol_local(THD *thd, Ed_connection *ed_connection);
- ~Protocol_local() { free_root(&m_rset_root, MYF(0)); }
-protected:
- virtual void prepare_for_resend();
- virtual bool write();
- virtual bool store_null();
- virtual bool store_tiny(longlong from);
- virtual bool store_short(longlong from);
- virtual bool store_long(longlong from);
- virtual bool store_longlong(longlong from, bool unsigned_flag);
- virtual bool store_decimal(const my_decimal *);
- virtual bool store_str(const char *from, size_t length,
- CHARSET_INFO *fromcs,
- my_repertoire_t from_repertoire,
- CHARSET_INFO *tocs);
- virtual bool store(MYSQL_TIME *time, int decimals);
- virtual bool store_date(MYSQL_TIME *time);
- virtual bool store_time(MYSQL_TIME *time, int decimals);
- virtual bool store(float value, uint32 decimals, String *buffer);
- virtual bool store(double value, uint32 decimals, String *buffer);
- virtual bool store(Field *field);
-
- virtual bool send_result_set_metadata(List<Item> *list, uint flags);
- virtual bool send_out_parameters(List<Item_param> *sp_params);
-#ifdef EMBEDDED_LIBRARY
- void remove_last_row();
-#endif
- virtual enum enum_protocol_type type() { return PROTOCOL_LOCAL; };
-
- virtual bool send_ok(uint server_status, uint statement_warn_count,
- ulonglong affected_rows, ulonglong last_insert_id,
- const char *message);
-
- virtual bool send_eof(uint server_status, uint statement_warn_count);
- virtual bool send_error(uint sql_errno, const char *err_msg, const char* sqlstate);
-private:
- bool store_string(const char *str, size_t length,
- CHARSET_INFO *src_cs,
- my_repertoire_t src_repertoire,
- CHARSET_INFO *dst_cs);
-
- bool store_column(const void *data, size_t length);
- void opt_add_row_to_rset();
-private:
- Ed_connection *m_connection;
- MEM_ROOT m_rset_root;
- List<Ed_row> *m_rset;
- size_t m_column_count;
- Ed_column *m_current_row;
- Ed_column *m_current_column;
-};
/******************************************************************************
Implementation
@@ -3796,6 +3737,7 @@ Execute_sql_statement::execute_server_code(THD *thd)
end:
thd->lex->restore_set_statement_var();
+ delete_explain_query(thd->lex);
lex_end(thd->lex);
return error;
@@ -5039,12 +4981,12 @@ Ed_connection::free_old_result()
*/
bool
-Ed_connection::execute_direct(LEX_STRING sql_text)
+Ed_connection::execute_direct(Protocol *p, LEX_STRING sql_text)
{
Execute_sql_statement execute_sql_statement(sql_text);
DBUG_PRINT("ed_query", ("%s", sql_text.str));
- return execute_direct(&execute_sql_statement);
+ return execute_direct(p, &execute_sql_statement);
}
@@ -5061,10 +5003,9 @@ Ed_connection::execute_direct(LEX_STRING sql_text)
@param server_runnable A code fragment to execute.
*/
-bool Ed_connection::execute_direct(Server_runnable *server_runnable)
+bool Ed_connection::execute_direct(Protocol *p, Server_runnable *server_runnable)
{
bool rc= FALSE;
- Protocol_local protocol_local(m_thd, this);
Prepared_statement stmt(m_thd);
Protocol *save_protocol= m_thd->protocol;
Diagnostics_area *save_diagnostics_area= m_thd->get_stmt_da();
@@ -5073,7 +5014,7 @@ bool Ed_connection::execute_direct(Server_runnable *server_runnable)
free_old_result(); /* Delete all data from previous execution, if any */
- m_thd->protocol= &protocol_local;
+ m_thd->protocol= p;
m_thd->set_stmt_da(&m_diagnostics_area);
rc= stmt.execute_server_runnable(server_runnable);
@@ -5160,344 +5101,741 @@ Ed_connection::store_result_set()
return ed_result_set;
}
-/*************************************************************************
-* Protocol_local
-**************************************************************************/
-
-Protocol_local::Protocol_local(THD *thd, Ed_connection *ed_connection)
- :Protocol(thd),
- m_connection(ed_connection),
- m_rset(NULL),
- m_column_count(0),
- m_current_row(NULL),
- m_current_column(NULL)
-{
- clear_alloc_root(&m_rset_root);
-}
+/*
+ MENT-56
+ Protocol_local and service_sql for plugins to enable 'local' SQL query execution.
+*/
-/**
- Called between two result set rows.
+#ifndef EMBEDDED_LIBRARY
+// This part is mostly copied from libmysqld/lib_sql.cc
+// TODO: get rid of code duplications
- Prepare structures to fill result set rows.
- Unfortunately, we can't return an error here. If memory allocation
- fails, we'll have to return an error later. And so is done
- in methods such as @sa store_column().
-*/
+#include <mysql.h>
+#include "../libmysqld/embedded_priv.h"
-void Protocol_local::prepare_for_resend()
+class Protocol_local : public Protocol_text
{
- DBUG_ASSERT(alloc_root_inited(&m_rset_root));
+public:
+ struct st_mysql_data *cur_data;
+ struct st_mysql_data *first_data;
+ struct st_mysql_data **data_tail;
+ void clear_data_list();
+ struct st_mysql_data *alloc_new_dataset();
+ char **next_field;
+ MYSQL_FIELD *next_mysql_field;
+ MEM_ROOT *alloc;
+
+ Protocol_local(THD *thd_arg, ulong prealloc= 0) :
+ Protocol_text(thd_arg, prealloc),
+ cur_data(0), first_data(0), data_tail(&first_data)
+ {}
+
+protected:
+ bool net_store_data(const uchar *from, size_t length);
+ bool net_store_data_cs(const uchar *from, size_t length,
+ CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
+ bool net_send_eof(THD *thd, uint server_status, uint statement_warn_count);
+ bool net_send_ok(THD *, uint, uint, ulonglong, ulonglong, const char *,
+ bool);
+ bool net_send_error_packet(THD *, uint, const char *, const char *);
+ bool begin_dataset();
+ bool begin_dataset(THD *thd, uint numfields);
+
+ bool write();
+ bool flush();
+
+ bool store_field_metadata(const THD *thd, const Send_field &field,
+ CHARSET_INFO *charset_for_protocol,
+ uint pos);
+ bool send_result_set_metadata(List<Item> *list, uint flags);
+ void remove_last_row();
+ bool store_null();
+ void prepare_for_resend();
+ bool send_list_fields(List<Field> *list, const TABLE_LIST *table_list);
+
+ enum enum_protocol_type type() { return PROTOCOL_LOCAL; };
+};
- opt_add_row_to_rset();
- /* Start a new row. */
- m_current_row= (Ed_column *) alloc_root(&m_rset_root,
- sizeof(Ed_column) * m_column_count);
- m_current_column= m_current_row;
+static
+bool
+write_eof_packet_local(THD *thd,
+ Protocol_local *p, uint server_status, uint statement_warn_count)
+{
+// if (!thd->mysql) // bootstrap file handling
+// return FALSE;
+ /*
+ The following test should never be true, but it's better to do it
+ because if 'is_fatal_error' is set the server is not going to execute
+ other queries (see the if test in dispatch_command / COM_QUERY)
+ */
+ if (thd->is_fatal_error)
+ thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
+ p->cur_data->embedded_info->server_status= server_status;
+ /*
+ Don't send warn count during SP execution, as the warn_list
+ is cleared between substatements, and mysqltest gets confused
+ */
+ p->cur_data->embedded_info->warning_count=
+ (thd->spcont ? 0 : MY_MIN(statement_warn_count, 65535));
+ return FALSE;
}
-/**
- In "real" protocols this is called to finish a result set row.
- Unused in the local implementation.
-*/
-
-bool Protocol_local::write()
+MYSQL_DATA *Protocol_local::alloc_new_dataset()
{
- return FALSE;
+ MYSQL_DATA *data;
+ struct embedded_query_result *emb_data;
+ if (!my_multi_malloc(PSI_INSTRUMENT_ME, MYF(MY_WME | MY_ZEROFILL),
+ &data, sizeof(*data),
+ &emb_data, sizeof(*emb_data),
+ NULL))
+ return NULL;
+
+ emb_data->prev_ptr= &data->data;
+ cur_data= data;
+ *data_tail= data;
+ data_tail= &emb_data->next;
+ data->embedded_info= emb_data;
+ return data;
}
-/**
- A helper function to add the current row to the current result
- set. Called in @sa prepare_for_resend(), when a new row is started,
- and in send_eof(), when the result set is finished.
-*/
-void Protocol_local::opt_add_row_to_rset()
+static char *dup_str_aux(MEM_ROOT *root, const char *from, uint length,
+ CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
{
- if (m_current_row)
+ uint32 dummy32;
+ uint dummy_err;
+ char *result;
+
+ /* 'tocs' is set 0 when client issues SET character_set_results=NULL */
+ if (tocs && String::needs_conversion(0, fromcs, tocs, &dummy32))
{
- /* Add the old row to the result set */
- Ed_row *ed_row= new (&m_rset_root) Ed_row(m_current_row, m_column_count);
- if (ed_row)
- m_rset->push_back(ed_row, &m_rset_root);
+ uint new_len= (tocs->mbmaxlen * length) / fromcs->mbminlen + 1;
+ result= (char *)alloc_root(root, new_len);
+ length= copy_and_convert(result, new_len,
+ tocs, from, length, fromcs, &dummy_err);
}
+ else
+ {
+ result= (char *)alloc_root(root, length + 1);
+ memcpy(result, from, length);
+ }
+
+ result[length]= 0;
+ return result;
}
-/**
- Add a NULL column to the current row.
-*/
+static char *dup_str_aux(MEM_ROOT *root, const LEX_CSTRING &from,
+ CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
+{
+ return dup_str_aux(root, from.str, (uint) from.length, fromcs, tocs);
+}
-bool Protocol_local::store_null()
+
+bool Protocol_local::net_store_data(const uchar *from, size_t length)
{
- if (m_current_column == NULL)
- return TRUE; /* prepare_for_resend() failed to allocate memory. */
+ char *field_buf;
+// if (!thd->mysql) // bootstrap file handling
+// return FALSE;
- bzero(m_current_column, sizeof(*m_current_column));
- ++m_current_column;
+ if (!(field_buf= (char*) alloc_root(alloc, length + sizeof(uint) + 1)))
+ return TRUE;
+ *(uint *)field_buf= (uint) length;
+ *next_field= field_buf + sizeof(uint);
+ memcpy((uchar*) *next_field, from, length);
+ (*next_field)[length]= 0;
+ if (next_mysql_field->max_length < length)
+ next_mysql_field->max_length= (unsigned long) length;
+ ++next_field;
+ ++next_mysql_field;
return FALSE;
}
+bool Protocol_local::net_store_data_cs(const uchar *from, size_t length,
+ CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
+{
+ uint conv_length= (uint) (to_cs->mbmaxlen * length / from_cs->mbminlen);
+ uint dummy_error;
+ char *field_buf;
+// if (!thd->mysql) // bootstrap file handling
+// return false;
+
+ if (!(field_buf= (char*) alloc_root(alloc, conv_length + sizeof(uint) + 1)))
+ return true;
+ *next_field= field_buf + sizeof(uint);
+ length= copy_and_convert(*next_field, conv_length, to_cs,
+ (const char*) from, length, from_cs, &dummy_error);
+ *(uint *) field_buf= (uint) length;
+ (*next_field)[length]= 0;
+ if (next_mysql_field->max_length < length)
+ next_mysql_field->max_length= (unsigned long) length;
+ ++next_field;
+ ++next_mysql_field;
+ return false;
+}
+
+
/**
- A helper method to add any column to the current row
- in its binary form.
+ Embedded library implementation of OK response.
+
+ This function is used by the server to write 'OK' packet to
+ the "network" when the server is compiled as an embedded library.
+ Since there is no network in the embedded configuration,
+ a different implementation is necessary.
+ Instead of marshalling response parameters to a network representation
+ and then writing it to the socket, here we simply copy the data to the
+ corresponding client-side connection structures.
+
+ @sa Server implementation of net_send_ok in protocol.cc for
+ description of the arguments.
- Allocates memory for the data in the result set memory root.
+ @return
+ @retval TRUE An error occurred
+ @retval FALSE Success
*/
-bool Protocol_local::store_column(const void *data, size_t length)
+bool
+Protocol_local::net_send_ok(THD *thd,
+ uint server_status, uint statement_warn_count,
+ ulonglong affected_rows, ulonglong id, const char *message, bool)
{
- if (m_current_column == NULL)
- return TRUE; /* prepare_for_resend() failed to allocate memory. */
- /*
- alloc_root() automatically aligns memory, so we don't need to
- do any extra alignment if we're pointing to, say, an integer.
- */
- m_current_column->str= (char*) memdup_root(&m_rset_root,
- data,
- length + 1 /* Safety */);
- if (! m_current_column->str)
- return TRUE;
- m_current_column->str[length]= '\0'; /* Safety */
- m_current_column->length= length;
- ++m_current_column;
- return FALSE;
+ DBUG_ENTER("emb_net_send_ok");
+ MYSQL_DATA *data;
+// MYSQL *mysql= thd->mysql;
+
+// if (!mysql) // bootstrap file handling
+// DBUG_RETURN(FALSE);
+ if (!(data= alloc_new_dataset()))
+ DBUG_RETURN(TRUE);
+ data->embedded_info->affected_rows= affected_rows;
+ data->embedded_info->insert_id= id;
+ if (message)
+ strmake_buf(data->embedded_info->info, message);
+
+ bool error= write_eof_packet_local(thd, this,
+ server_status, statement_warn_count);
+ cur_data= 0;
+ DBUG_RETURN(error);
}
/**
- Store a string value in a result set column, optionally
- having converted it to character_set_results.
+ Embedded library implementation of EOF response.
+
+ @sa net_send_ok
+
+ @return
+ @retval TRUE An error occurred
+ @retval FALSE Success
*/
bool
-Protocol_local::store_string(const char *str, size_t length,
- CHARSET_INFO *src_cs,
- my_repertoire_t src_repertoire,
- CHARSET_INFO *dst_cs)
+Protocol_local::net_send_eof(THD *thd, uint server_status,
+ uint statement_warn_count)
{
- /* Store with conversion */
- uint error_unused;
-
- if (needs_conversion(src_cs, src_repertoire, dst_cs))
- {
- if (unlikely(convert->copy(str, length, src_cs, dst_cs, &error_unused)))
- return TRUE;
- str= convert->ptr();
- length= convert->length();
- }
- return store_column(str, length);
+ bool error= write_eof_packet_local(thd, this, server_status,
+ statement_warn_count);
+ cur_data= 0;
+ return error;
}
-/** Store a tiny int as is (1 byte) in a result set column. */
+bool Protocol_local::net_send_error_packet(THD *thd, uint sql_errno,
+ const char *err, const char *sqlstate)
+{
+ uint error;
+ char converted_err[MYSQL_ERRMSG_SIZE];
+ MYSQL_DATA *data= cur_data;
+ struct embedded_query_result *ei;
+
+// if (!thd->mysql) // bootstrap file handling
+// {
+// fprintf(stderr, "ERROR: %d %s\n", sql_errno, err);
+// return TRUE;
+// }
+ if (!data)
+ data= alloc_new_dataset();
+
+ ei= data->embedded_info;
+ ei->last_errno= sql_errno;
+ convert_error_message(converted_err, sizeof(converted_err),
+ thd->variables.character_set_results,
+ err, strlen(err),
+ system_charset_info, &error);
+ /* Converted error message is always null-terminated. */
+ strmake_buf(ei->info, converted_err);
+ strmov(ei->sqlstate, sqlstate);
+ ei->server_status= thd->server_status;
+ cur_data= 0;
+ return FALSE;
+}
+
-bool Protocol_local::store_tiny(longlong value)
+bool Protocol_local::begin_dataset()
{
- char v= (char) value;
- return store_column(&v, 1);
+ MYSQL_DATA *data= alloc_new_dataset();
+ if (!data)
+ return 1;
+ alloc= &data->alloc;
+ /* Assume rowlength < 8192 */
+ init_alloc_root(PSI_INSTRUMENT_ME, alloc, 8192, 0, MYF(0));
+ alloc->min_malloc= sizeof(MYSQL_ROWS);
+ return 0;
}
-/** Store a short as is (2 bytes, host order) in a result set column. */
-
-bool Protocol_local::store_short(longlong value)
+bool Protocol_local::begin_dataset(THD *thd, uint numfields)
{
- int16 v= (int16) value;
- return store_column(&v, 2);
+ if (begin_dataset())
+ return true;
+ MYSQL_DATA *data= cur_data;
+ data->fields= field_count= numfields;
+ if (!(data->embedded_info->fields_list=
+ (MYSQL_FIELD*)alloc_root(&data->alloc, sizeof(MYSQL_FIELD)*field_count)))
+ return true;
+ return false;
}
-/** Store a "long" as is (4 bytes, host order) in a result set column. */
-
-bool Protocol_local::store_long(longlong value)
+bool Protocol_local::write()
{
- int32 v= (int32) value;
- return store_column(&v, 4);
-}
+// if (!thd->mysql) // bootstrap file handling
+// return false;
+ *next_field= 0;
+ return false;
+}
-/** Store a "longlong" as is (8 bytes, host order) in a result set column. */
-bool Protocol_local::store_longlong(longlong value, bool unsigned_flag)
+bool Protocol_local::flush()
{
- int64 v= (int64) value;
- return store_column(&v, 8);
+ return 0;
}
-/** Store a decimal in string format in a result set column */
+bool Protocol_local::store_field_metadata(const THD * thd,
+ const Send_field &server_field,
+ CHARSET_INFO *charset_for_protocol,
+ uint pos)
+{
+ CHARSET_INFO *cs= system_charset_info;
+ CHARSET_INFO *thd_cs= thd->variables.character_set_results;
+ MYSQL_DATA *data= cur_data;
+ MEM_ROOT *field_alloc= &data->alloc;
+ MYSQL_FIELD *client_field= &cur_data->embedded_info->fields_list[pos];
+ DBUG_ASSERT(server_field.is_sane());
+
+ client_field->db= dup_str_aux(field_alloc, server_field.db_name,
+ cs, thd_cs);
+ client_field->table= dup_str_aux(field_alloc, server_field.table_name,
+ cs, thd_cs);
+ client_field->name= dup_str_aux(field_alloc, server_field.col_name,
+ cs, thd_cs);
+ client_field->org_table= dup_str_aux(field_alloc, server_field.org_table_name,
+ cs, thd_cs);
+ client_field->org_name= dup_str_aux(field_alloc, server_field.org_col_name,
+ cs, thd_cs);
+ if (charset_for_protocol == &my_charset_bin || thd_cs == NULL)
+ {
+ /* No conversion */
+ client_field->charsetnr= charset_for_protocol->number;
+ client_field->length= server_field.length;
+ }
+ else
+ {
+ /* With conversion */
+ client_field->charsetnr= thd_cs->number;
+ client_field->length= server_field.max_octet_length(charset_for_protocol,
+ thd_cs);
+ }
+ client_field->type= server_field.type_handler()->type_code_for_protocol();
+ client_field->flags= (uint16) server_field.flags;
+ client_field->decimals= server_field.decimals;
-bool Protocol_local::store_decimal(const my_decimal *value)
-{
- DBUG_ASSERT(0); // This method is not used yet
- StringBuffer<DECIMAL_MAX_STR_LENGTH> str;
- return value->to_string(&str) ? store_column(str.ptr(), str.length()) : true;
-}
+ client_field->db_length= (unsigned int) strlen(client_field->db);
+ client_field->table_length= (unsigned int) strlen(client_field->table);
+ client_field->name_length= (unsigned int) strlen(client_field->name);
+ client_field->org_name_length= (unsigned int) strlen(client_field->org_name);
+ client_field->org_table_length= (unsigned int) strlen(client_field->org_table);
+ client_field->catalog= dup_str_aux(field_alloc, "def", 3, cs, thd_cs);
+ client_field->catalog_length= 3;
-/** Store a string. */
+ if (IS_NUM(client_field->type))
+ client_field->flags|= NUM_FLAG;
-bool Protocol_local::store_str(const char *str, size_t length,
- CHARSET_INFO *src_cs,
- my_repertoire_t from_repertoire,
- CHARSET_INFO *dst_cs)
-{
- return store_string(str, length, src_cs, from_repertoire, dst_cs);
+ client_field->max_length= 0;
+ client_field->def= 0;
+ return false;
}
-/* Store MYSQL_TIME (in binary format) */
-
-bool Protocol_local::store(MYSQL_TIME *time, int decimals)
+void Protocol_local::remove_last_row()
{
- if (decimals != AUTO_SEC_PART_DIGITS)
- my_datetime_trunc(time, decimals);
- return store_column(time, sizeof(MYSQL_TIME));
-}
+ MYSQL_DATA *data= cur_data;
+ MYSQL_ROWS **last_row_hook= &data->data;
+ my_ulonglong count= data->rows;
+ DBUG_ENTER("Protocol_text::remove_last_row");
+ while (--count)
+ last_row_hook= &(*last_row_hook)->next;
+
+ *last_row_hook= 0;
+ data->embedded_info->prev_ptr= last_row_hook;
+ data->rows--;
+ DBUG_VOID_RETURN;
+}
-/** Store MYSQL_TIME (in binary format) */
-bool Protocol_local::store_date(MYSQL_TIME *time)
+bool Protocol_local::send_result_set_metadata(List<Item> *list, uint flags)
{
- return store_column(time, sizeof(MYSQL_TIME));
-}
+ List_iterator_fast<Item> it(*list);
+ Item *item;
+// Protocol_local prot(thd);
+ DBUG_ENTER("send_result_set_metadata");
+
+// if (!thd->mysql) // bootstrap file handling
+// DBUG_RETURN(0);
+ if (begin_dataset(thd, list->elements))
+ goto err;
+
+ for (uint pos= 0 ; (item= it++); pos++)
+ {
+ if (/*prot.*/store_item_metadata(thd, item, pos))
+ goto err;
+ }
-/** Store MYSQL_TIME (in binary format) */
+ if (flags & SEND_EOF)
+ write_eof_packet_local(thd, this, thd->server_status,
+ thd->get_stmt_da()->current_statement_warn_count());
-bool Protocol_local::store_time(MYSQL_TIME *time, int decimals)
-{
- if (decimals != AUTO_SEC_PART_DIGITS)
- my_time_trunc(time, decimals);
- return store_column(time, sizeof(MYSQL_TIME));
+ DBUG_RETURN(prepare_for_send(list->elements));
+ err:
+ my_error(ER_OUT_OF_RESOURCES, MYF(0)); /* purecov: inspected */
+ DBUG_RETURN(1); /* purecov: inspected */
}
+static void
+list_fields_send_default(THD *thd, Protocol_local *p, Field *fld, uint pos)
+{
+ char buff[80];
+ String tmp(buff, sizeof(buff), default_charset_info), *res;
+ MYSQL_FIELD *client_field= &p->cur_data->embedded_info->fields_list[pos];
+
+ if (fld->is_null() || !(res= fld->val_str(&tmp)))
+ {
+ client_field->def_length= 0;
+ client_field->def= strmake_root(&p->cur_data->alloc, "", 0);
+ }
+ else
+ {
+ client_field->def_length= res->length();
+ client_field->def= strmake_root(&p->cur_data->alloc, res->ptr(),
+ client_field->def_length);
+ }
+}
-/* Store a floating point number, as is. */
-bool Protocol_local::store(float value, uint32 decimals, String *buffer)
+bool Protocol_local::send_list_fields(List<Field> *list, const TABLE_LIST *table_list)
{
- return store_column(&value, sizeof(float));
+ DBUG_ENTER("send_result_set_metadata");
+ Protocol_text prot(thd);
+ List_iterator_fast<Field> it(*list);
+ Field *fld;
+
+// if (!thd->mysql) // bootstrap file handling
+// DBUG_RETURN(0);
+
+ if (begin_dataset(thd, list->elements))
+ goto err;
+
+ for (uint pos= 0 ; (fld= it++); pos++)
+ {
+ if (prot.store_field_metadata_for_list_fields(thd, fld, table_list, pos))
+ goto err;
+ list_fields_send_default(thd, this, fld, pos);
+ }
+
+ DBUG_RETURN(prepare_for_send(list->elements));
+err:
+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
+ DBUG_RETURN(1);
}
-/* Store a double precision number, as is. */
+void Protocol_local::prepare_for_resend()
+{
+ MYSQL_ROWS *cur;
+ MYSQL_DATA *data= cur_data;
+ DBUG_ENTER("send_data");
+
+// if (!thd->mysql) // bootstrap file handling
+// DBUG_VOID_RETURN;
+
+ data->rows++;
+ if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS)+(field_count + 1) * sizeof(char *))))
+ {
+ my_error(ER_OUT_OF_RESOURCES,MYF(0));
+ DBUG_VOID_RETURN;
+ }
+ cur->data= (MYSQL_ROW)(((char *)cur) + sizeof(MYSQL_ROWS));
+
+ *data->embedded_info->prev_ptr= cur;
+ data->embedded_info->prev_ptr= &cur->next;
+ next_field=cur->data;
+ next_mysql_field= data->embedded_info->fields_list;
+#ifndef DBUG_OFF
+ field_pos= 0;
+#endif
-bool Protocol_local::store(double value, uint32 decimals, String *buffer)
+ DBUG_VOID_RETURN;
+}
+
+bool Protocol_local::store_null()
{
- return store_column(&value, sizeof (double));
+ *(next_field++)= NULL;
+ ++next_mysql_field;
+ return false;
}
-/* Store a Field. */
+#include <sql_common.h>
+#include <errmsg.h>
-bool Protocol_local::store(Field *field)
+struct local_results
{
- if (field->is_null())
- return store_null();
- return field->send_binary(this);
-}
+ struct st_mysql_data *cur_data;
+ struct st_mysql_data *first_data;
+ struct st_mysql_data **data_tail;
+ void clear_data_list();
+ struct st_mysql_data *alloc_new_dataset();
+ char **next_field;
+ MYSQL_FIELD *next_mysql_field;
+ MEM_ROOT *alloc;
+};
-/** Called to start a new result set. */
+static void embedded_get_error(MYSQL *mysql, MYSQL_DATA *data)
+{
+ NET *net= &mysql->net;
+ struct embedded_query_result *ei= data->embedded_info;
+ net->last_errno= ei->last_errno;
+ strmake_buf(net->last_error, ei->info);
+ memcpy(net->sqlstate, ei->sqlstate, sizeof(net->sqlstate));
+ mysql->server_status= ei->server_status;
+ my_free(data);
+}
+
-bool Protocol_local::send_result_set_metadata(List<Item> *columns, uint)
+static my_bool loc_read_query_result(MYSQL *mysql)
{
- DBUG_ASSERT(m_rset == 0 && !alloc_root_inited(&m_rset_root));
+ local_results *thd= (local_results *) mysql->thd;
- init_sql_alloc(PSI_INSTRUMENT_ME, &m_rset_root, MEM_ROOT_BLOCK_SIZE, 0,
- MYF(MY_THREAD_SPECIFIC));
+ MYSQL_DATA *res= thd->first_data;
+ DBUG_ASSERT(!thd->cur_data);
+ thd->first_data= res->embedded_info->next;
+ if (res->embedded_info->last_errno &&
+ !res->embedded_info->fields_list)
+ {
+ embedded_get_error(mysql, res);
+ return 1;
+ }
- if (! (m_rset= new (&m_rset_root) List<Ed_row>))
- return TRUE;
+ mysql->warning_count= res->embedded_info->warning_count;
+ mysql->server_status= res->embedded_info->server_status;
+ mysql->field_count= res->fields;
+ if (!(mysql->fields= res->embedded_info->fields_list))
+ {
+ mysql->affected_rows= res->embedded_info->affected_rows;
+ mysql->insert_id= res->embedded_info->insert_id;
+ }
+ net_clear_error(&mysql->net);
+ mysql->info= 0;
+
+ if (res->embedded_info->info[0])
+ {
+ strmake(mysql->info_buffer, res->embedded_info->info, MYSQL_ERRMSG_SIZE-1);
+ mysql->info= mysql->info_buffer;
+ }
- m_column_count= columns->elements;
+ if (res->embedded_info->fields_list)
+ {
+ mysql->status=MYSQL_STATUS_GET_RESULT;
+ thd->cur_data= res;
+ }
+ else
+ my_free(res);
- return FALSE;
+ return 0;
}
-/**
- Normally this is a separate result set with OUT parameters
- of stored procedures. Currently unsupported for the local
- version.
-*/
+static MYSQL_METHODS local_methods=
+{
+ loc_read_query_result, /* read_query_result */
+ NULL/*loc_advanced_command*/, /* advanced_command */
+ NULL/*loc_read_rows*/, /* read_rows */
+ NULL/*loc_use_result*/, /* use_result */
+ NULL/*loc_fetch_lengths*/, /* fetch_lengths */
+ NULL/*loc_flush_use_result*/, /* flush_use_result */
+ NULL/*loc_read_change_user_result*/ /* read_change_user_result */
+};
+
-bool Protocol_local::send_out_parameters(List<Item_param> *sp_params)
+extern "C" MYSQL *mysql_real_connect_local(MYSQL *mysql,
+ const char *host, const char *user, const char *passwd, const char *db)
{
- return FALSE;
-}
+ //char name_buff[USERNAME_LENGTH];
+ DBUG_ENTER("mysql_real_connect_local");
-/** Called for statements that don't have a result set, at statement end. */
+ /* Test whether we're already connected */
+ if (mysql->server_version)
+ {
+ set_mysql_error(mysql, CR_ALREADY_CONNECTED, unknown_sqlstate);
+ DBUG_RETURN(0);
+ }
-bool
-Protocol_local::send_ok(uint server_status, uint statement_warn_count,
- ulonglong affected_rows, ulonglong last_insert_id,
- const char *message)
-{
- /*
- Just make sure nothing is sent to the client, we have grabbed
- the status information in the connection diagnostics area.
- */
- return FALSE;
-}
+ if (!host || !host[0])
+ host= mysql->options.host;
+ mysql->methods= &local_methods;
-/**
- Called at the end of a result set. Append a complete
- result set to the list in Ed_connection.
+ if (!db || !db[0])
+ db=mysql->options.db;
- Don't send anything to the client, but instead finish
- building of the result set at hand.
-*/
+ if (!user || !user[0])
+ user=mysql->options.user;
-bool Protocol_local::send_eof(uint server_status, uint statement_warn_count)
-{
- Ed_result_set *ed_result_set;
+ mysql->user= my_strdup(PSI_INSTRUMENT_ME, user, MYF(0));
- DBUG_ASSERT(m_rset);
- opt_add_row_to_rset();
- m_current_row= 0;
+ mysql->info_buffer= (char *) my_malloc(PSI_INSTRUMENT_ME,
+ MYSQL_ERRMSG_SIZE, MYF(0));
+ //mysql->thd= create_embedded_thd(client_flag);
- ed_result_set= new (&m_rset_root) Ed_result_set(m_rset, m_column_count,
- &m_rset_root);
+ //init_embedded_mysql(mysql, client_flag);
- m_rset= NULL;
+ //if (mysql_init_character_set(mysql))
+ // goto error;
- if (! ed_result_set)
- return TRUE;
+ //if (check_embedded_connection(mysql, db))
+ // goto error;
- /* In case of successful allocation memory ownership was transferred. */
- DBUG_ASSERT(!alloc_root_inited(&m_rset_root));
+ mysql->server_status= SERVER_STATUS_AUTOCOMMIT;
- /*
- Link the created Ed_result_set instance into the list of connection
- result sets. Never fails.
- */
- m_connection->add_result_set(ed_result_set);
- return FALSE;
-}
+ //if (mysql->options.init_commands)
+ //{
+ // DYNAMIC_ARRAY *init_commands= mysql->options.init_commands;
+ // char **ptr= (char**)init_commands->buffer;
+ // char **end= ptr + init_commands->elements;
+//
+ // for (; ptr<end; ptr++)
+ // {
+ // MYSQL_RES *res;
+ // if (mysql_query(mysql,*ptr))
+ // goto error;
+ // if (mysql->fields)
+ // {
+ // if (!(res= (*mysql->methods->use_result)(mysql)))
+ // goto error;
+ // mysql_free_result(res);
+ // }
+ // }
+ //}
+ DBUG_PRINT("exit",("Mysql handler: %p", mysql));
+ DBUG_RETURN(mysql);
-/** Called to send an error to the client at the end of a statement. */
+//error:
+ DBUG_PRINT("error",("message: %u (%s)",
+ mysql->net.last_errno,
+ mysql->net.last_error));
+ {
+ /* Free alloced memory */
+ my_bool free_me=mysql->free_me;
+ free_old_query(mysql);
+ mysql->free_me=0;
+ mysql_close(mysql);
+ mysql->free_me=free_me;
+ }
+ DBUG_RETURN(0);
+}
-bool
-Protocol_local::send_error(uint sql_errno, const char *err_msg, const char*)
+
+extern "C" int execute_sql_command(const char *command,
+ char *hosts, char *names, char *filters)
{
- /*
- Just make sure that nothing is sent to the client (default
- implementation).
- */
- return FALSE;
+ MYSQL_LEX_STRING sql_text;
+ THD *thd= current_thd;
+ THD *new_thd= 0;
+ int result;
+ my_bool qc_save= 0;
+
+ if (!thd)
+ {
+ new_thd= new THD(0);
+ new_thd->thread_stack= (char*) &sql_text;
+ new_thd->store_globals();
+ new_thd->security_ctx->skip_grants();
+ new_thd->query_cache_is_applicable= 0;
+ bzero((char*) &new_thd->net, sizeof(new_thd->net));
+ thd= new_thd;
+ }
+ else
+ {
+ if (thd->lock)
+ /* Doesn't work if the thread opened/locked tables already. */
+ return 2;
+
+ qc_save= thd->query_cache_is_applicable;
+ thd->query_cache_is_applicable= 0;
+ }
+ sql_text.str= (char *) command;
+ sql_text.length= strlen(command);
+ {
+ Protocol_local p(thd);
+ Ed_connection con(thd);
+ result= con.execute_direct(&p, sql_text);
+ if (!result && p.first_data)
+ {
+ int nr= (int) p.first_data->rows;
+ MYSQL_ROWS *rows= p.first_data->data;
+
+ while (nr--)
+ {
+ strcpy(hosts, rows->data[0]);
+ hosts+= strlen(hosts) + 1;
+ strcpy(names, rows->data[1]);
+ names+= strlen(names) + 1;
+ if (filters)
+ {
+ strcpy(filters, rows->data[2]);
+ filters+= strlen(filters) + 1;
+ }
+ rows= rows->next;
+ }
+ }
+ if (p.first_data)
+ {
+ if (p.alloc)
+ free_root(p.alloc, MYF(0));
+ my_free(p.first_data);
+ }
+ }
+
+ if (new_thd)
+ delete new_thd;
+ else
+ thd->query_cache_is_applicable= qc_save;
+
+ *hosts= 0;
+ return result;
}
+#endif /*!EMBEDDED_LIBRARY*/
+
-#ifdef EMBEDDED_LIBRARY
-void Protocol_local::remove_last_row()
-{ }
-#endif
diff --git a/sql/sql_prepare.h b/sql/sql_prepare.h
index f1c4e5e4be9..166be95eb89 100644
--- a/sql/sql_prepare.h
+++ b/sql/sql_prepare.h
@@ -200,7 +200,7 @@ public:
@retval TRUE error, use get_last_error()
to see the error number.
*/
- bool execute_direct(LEX_STRING sql_text);
+ bool execute_direct(Protocol *p, LEX_STRING sql_text);
/**
Same as the previous, but takes an instance of Server_runnable
@@ -213,7 +213,7 @@ public:
return a result set
@retval TRUE failure
*/
- bool execute_direct(Server_runnable *server_runnable);
+ bool execute_direct(Protocol *p, Server_runnable *server_runnable);
/**
Get the number of affected (deleted, updated)
@@ -309,7 +309,6 @@ private:
THD *m_thd;
Ed_result_set *m_rsets;
Ed_result_set *m_current_rset;
- friend class Protocol_local;
private:
void free_old_result();
void add_result_set(Ed_result_set *ed_result_set);
diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc
index 2a47aa846eb..d8ecd2abee7 100644
--- a/sql/sql_profile.cc
+++ b/sql/sql_profile.cc
@@ -433,8 +433,6 @@ bool PROFILING::show_profiles()
{
prof= history.iterator_value(iterator);
- String elapsed;
-
double query_time_usecs= prof->m_end_time_usecs - prof->m_start_time_usecs;
if (unit->lim.check_offset(idx))
@@ -444,8 +442,8 @@ bool PROFILING::show_profiles()
protocol->prepare_for_resend();
protocol->store((uint32)(prof->profiling_query_id));
- protocol->store((double)(query_time_usecs/(1000.0*1000)),
- (uint32) TIME_FLOAT_DIGITS-1, &elapsed);
+ protocol->store_double(query_time_usecs/(1000.0*1000),
+ (uint32) TIME_FLOAT_DIGITS-1);
if (prof->query_source != NULL)
protocol->store(prof->query_source, strlen(prof->query_source),
system_charset_info);
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 3ed0e288870..4a1484df2c2 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -374,11 +374,15 @@ static int send_file(THD *thd)
We need net_flush here because the client will not know it needs to send
us the file name until it has processed the load event entry
*/
- if (unlikely(net_flush(net) || (packet_len = my_net_read(net)) == packet_error))
+ if (unlikely(net_flush(net)))
{
+ read_error:
errmsg = "while reading file name";
goto err;
}
+ packet_len= my_net_read(net);
+ if (unlikely(packet_len == packet_error))
+ goto read_error;
// terminate with \0 for fn_format
*((char*)net->read_pos + packet_len) = 0;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 22bf2eb37b5..b0869e15289 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -11597,11 +11597,16 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
HA_CAN_TABLE_CONDITION_PUSHDOWN) &&
!first_inner_tab)
{
+ Json_writer_object wrap(thd);
+ Json_writer_object trace_cp(thd, "table_condition_pushdown");
+ trace_cp.add_table_name(tab->table);
+
COND *push_cond=
make_cond_for_table(thd, tmp_cond, current_map, current_map,
-1, FALSE, FALSE);
if (push_cond)
{
+ trace_cp.add("push_cond", push_cond);
/* Push condition to handler */
if (!tab->table->file->cond_push(push_cond))
tab->table->file->pushed_cond= push_cond;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 0d41857aaf5..452690f3237 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2891,8 +2891,6 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
server_threads.iterate(list_callback, &arg);
ulonglong now= microsecond_interval_timer();
- char buff[20]; // For progress
- String store_buffer(buff, sizeof(buff), system_charset_info);
while (auto thd_info= arg.thread_infos.get())
{
@@ -2918,7 +2916,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
protocol->store_null();
if (!thd->variables.old_mode &&
!(thd->variables.old_behavior & OLD_MODE_NO_PROGRESS_INFO))
- protocol->store(thd_info->progress, 3, &store_buffer);
+ protocol->store_double(thd_info->progress, 3);
if (protocol->write())
break; /* purecov: inspected */
}
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index 9e0f9b013c0..fdd92d3d7bb 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -734,6 +734,23 @@ uint Interval_DDhhmmssff::fsp(THD *thd, Item *item)
}
+bool Time::to_native(Native *to, uint decimals) const
+{
+ if (!is_valid_time())
+ {
+ to->length(0);
+ return true;
+ }
+ uint len= my_time_binary_length(decimals);
+ if (to->reserve(len))
+ return true;
+ longlong tmp= TIME_to_longlong_time_packed(get_mysql_time());
+ my_time_packed_to_binary(tmp, (uchar*) to->ptr(), decimals);
+ to->length(len);
+ return false;
+}
+
+
void Time::make_from_item(THD *thd, int *warn, Item *item, const Options opt)
{
*warn= 0;
@@ -918,6 +935,28 @@ void Time::make_from_time(int *warn, const MYSQL_TIME *from)
}
+uint Time::binary_length_to_precision(uint length)
+{
+ switch (length) {
+ case 3: return 0;
+ case 4: return 2;
+ case 5: return 4;
+ case 6: return 6;
+ }
+ DBUG_ASSERT(0);
+ return 0;
+}
+
+
+Time::Time(const Native &native)
+{
+ uint dec= binary_length_to_precision(native.length());
+ longlong tmp= my_time_packed_from_binary((const uchar *) native.ptr(), dec);
+ TIME_from_longlong_time_packed(this, tmp);
+ DBUG_ASSERT(is_valid_time());
+}
+
+
Time::Time(int *warn, const MYSQL_TIME *from, long curdays)
{
switch (from->time_type) {
@@ -1685,6 +1724,13 @@ Type_handler_timestamp_common::type_handler_for_native_format() const
}
+const Type_handler *
+Type_handler_time_common::type_handler_for_native_format() const
+{
+ return &type_handler_time2;
+}
+
+
/***************************************************************************/
const Type_handler *Type_handler_typelib::type_handler_for_item_field() const
@@ -7348,7 +7394,7 @@ bool Type_handler::
{
float nr= (float) item->val_real();
if (!item->null_value)
- return protocol->store(nr, item->decimals, &buf->m_string);
+ return protocol->store_float(nr, item->decimals);
return protocol->store_null();
}
@@ -7358,7 +7404,7 @@ bool Type_handler::
{
double nr= item->val_real();
if (!item->null_value)
- return protocol->store(nr, item->decimals, &buf->m_string);
+ return protocol->store_double(nr, item->decimals);
return protocol->store_null();
}
@@ -8820,6 +8866,51 @@ Type_handler_time_common::create_literal_item(THD *thd,
}
+bool
+Type_handler_time_common::Item_val_native_with_conversion(THD *thd,
+ Item *item,
+ Native *to) const
+{
+ if (item->type_handler()->type_handler_for_native_format() ==
+ &type_handler_time2)
+ return item->val_native(thd, to);
+ return Time(thd, item).to_native(to, item->time_precision(thd));
+}
+
+
+bool
+Type_handler_time_common::Item_val_native_with_conversion_result(THD *thd,
+ Item *item,
+ Native *to)
+ const
+{
+ if (item->type_handler()->type_handler_for_native_format() ==
+ &type_handler_time2)
+ return item->val_native_result(thd, to);
+ MYSQL_TIME ltime;
+ if (item->get_date_result(thd, &ltime, Time::Options(thd)))
+ return true;
+ int warn;
+ return Time(&warn, &ltime, 0).to_native(to, item->time_precision(thd));
+}
+
+
+int Type_handler_time_common::cmp_native(const Native &a,
+ const Native &b) const
+{
+ // Optimize a simple case: equal fractional precision:
+ if (a.length() == b.length())
+ return memcmp(a.ptr(), b.ptr(), a.length());
+ longlong lla= Time(a).to_packed();
+ longlong llb= Time(b).to_packed();
+ if (lla < llb)
+ return -1;
+ if (lla> llb)
+ return 1;
+ return 0;
+}
+
+
bool Type_handler_timestamp_common::TIME_to_native(THD *thd,
const MYSQL_TIME *ltime,
Native *to,
@@ -8930,6 +9021,15 @@ Type_handler_timestamp_common::Item_param_val_native(THD *thd,
}
+bool
+Type_handler_time_common::Item_param_val_native(THD *thd,
+ Item_param *item,
+ Native *to) const
+{
+ return Time(thd, item).to_native(to, item->decimals);
+}
+
+
/***************************************************************************/
bool Type_handler::validate_implicit_default_value(THD *thd,
diff --git a/sql/sql_type.h b/sql/sql_type.h
index a6d85b5bb47..f94d17541a4 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -1453,6 +1453,7 @@ class Schema;
*/
class Time: public Temporal
{
+ static uint binary_length_to_precision(uint length);
public:
enum datetime_to_time_mode_t
{
@@ -1685,6 +1686,14 @@ public:
*/
Time(int *warn, bool neg, ulonglong hour, uint minute, const Sec6 &second);
Time() { time_type= MYSQL_TIMESTAMP_NONE; }
+ Time(const Native &native);
+ Time(THD *thd, const MYSQL_TIME *ltime, const Options opt)
+ {
+ *(static_cast<MYSQL_TIME*>(this))= *ltime;
+ DBUG_ASSERT(is_valid_temporal());
+ int warn= 0;
+ valid_MYSQL_TIME_to_valid_value(thd, &warn, opt);
+ }
Time(Item *item)
:Time(current_thd, item)
{ }
@@ -1840,6 +1849,7 @@ public:
return !is_valid_time() ? 0 :
Temporal::to_double(neg, TIME_to_ulonglong_time(this), second_part);
}
+ bool to_native(Native *to, uint decimals) const;
String *to_string(String *str, uint dec) const
{
if (!is_valid_time())
@@ -5897,6 +5907,15 @@ public:
{
return MYSQL_TIMESTAMP_TIME;
}
+ bool is_val_native_ready() const override { return true; }
+ const Type_handler *type_handler_for_native_format() const override;
+ int cmp_native(const Native &a, const Native &b) const override;
+ bool Item_val_native_with_conversion(THD *thd, Item *, Native *to)
+ const override;
+ bool Item_val_native_with_conversion_result(THD *thd, Item *, Native *to)
+ const override;
+ bool Item_param_val_native(THD *thd, Item_param *item, Native *to)
+ const override;
bool partition_field_check(const LEX_CSTRING &field_name,
Item *item_expr) const override
{
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index b472dfd4939..3fa54a3bf54 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -3877,9 +3877,11 @@ sp_fetch_list:
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_pcontext *spc= lex->spcont;
- sp_variable *spv;
+ sp_variable *spv= likely(spc != NULL)
+ ? spc->find_variable(&$1, false)
+ : NULL;
- if (unlikely(!spc || !(spv = spc->find_variable(&$1, false))))
+ if (unlikely(!spv))
my_yyabort_error((ER_SP_UNDECLARED_VAR, MYF(0), $1.str));
/* An SP local variable */
@@ -3891,9 +3893,11 @@ sp_fetch_list:
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_pcontext *spc= lex->spcont;
- sp_variable *spv;
+ sp_variable *spv= likely(spc != NULL)
+ ? spc->find_variable(&$3, false)
+ : NULL;
- if (unlikely(!spc || !(spv = spc->find_variable(&$3, false))))
+ if (unlikely(!spv))
my_yyabort_error((ER_SP_UNDECLARED_VAR, MYF(0), $3.str));
/* An SP local variable */
diff --git a/sql/threadpool_generic.cc b/sql/threadpool_generic.cc
index 7895431bc13..709bb95eb98 100644
--- a/sql/threadpool_generic.cc
+++ b/sql/threadpool_generic.cc
@@ -1009,7 +1009,10 @@ void thread_group_destroy(thread_group_t *thread_group)
#endif
if (!--shutdown_group_count)
+ {
my_free(all_groups);
+ all_groups= 0;
+ }
}
/**
@@ -1614,6 +1617,14 @@ TP_pool_generic::~TP_pool_generic()
{
thread_group_close(&all_groups[i]);
}
+
+ /*
+ Wait until memory occupied by all_groups is freed.
+ */
+ int timeout_ms=5000;
+ while(all_groups && timeout_ms--)
+ my_sleep(1000);
+
threadpool_started= false;
DBUG_VOID_RETURN;
}
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 4546f2291cd..8e08a201e88 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -2753,9 +2753,11 @@ main(int argc, char **argv)
printf("TRUNCATE TABLE time_zone_name;\n");
printf("TRUNCATE TABLE time_zone_transition;\n");
printf("TRUNCATE TABLE time_zone_transition_type;\n");
+ printf("START TRANSACTION;\n");
if (scan_tz_dir(root_name_end, 0, opt_verbose))
{
+ printf("ROLLBACK;\n");
fflush(stdout);
fprintf(stderr,
"There were fatal errors during processing "
@@ -2763,6 +2765,7 @@ main(int argc, char **argv)
return 1;
}
+ printf("COMMIT;\n");
printf("ALTER TABLE time_zone_transition "
"ORDER BY Time_zone_id, Transition_time;\n");
printf("ALTER TABLE time_zone_transition_type "
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index 9a2d5e635a5..d0155f27d6d 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -1171,7 +1171,7 @@ bool wsrep_must_sync_wait (THD* thd, uint mask)
mysql_mutex_lock(&thd->LOCK_thd_data);
ret= (thd->variables.wsrep_sync_wait & mask) &&
thd->wsrep_client_thread &&
- thd->variables.wsrep_on &&
+ WSREP_ON &&
!(thd->variables.wsrep_dirty_reads &&
!is_update_query(thd->lex->sql_command)) &&
!thd->in_active_multi_stmt_transaction() &&
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index 54bb9aa9889..610e864593e 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -54,6 +54,7 @@ my_bool wsrep_sst_donor_rejects_queries= FALSE;
bool sst_joiner_completed = false;
bool sst_donor_completed = false;
+bool sst_needed = false;
struct sst_thread_arg
{
@@ -307,6 +308,7 @@ bool wsrep_before_SE()
&& strcmp (wsrep_sst_method, WSREP_SST_MYSQLDUMP));
}
+static bool sst_in_progress = false;
// Signal end of SST
static void wsrep_sst_complete (THD* thd,
int const rcode)
@@ -1625,7 +1627,10 @@ static void* sst_donor_thread (void* a)
char out_buf[out_len];
wsrep_uuid_t ret_uuid= WSREP_UUID_UNDEFINED;
- wsrep_seqno_t ret_seqno= WSREP_SEQNO_UNDEFINED; // seqno of complete SST
+ // seqno of complete SST
+ wsrep_seqno_t ret_seqno= WSREP_SEQNO_UNDEFINED;
+ // SST is now in progress
+ sst_in_progress= true;
wsp::thd thd(FALSE); // we turn off wsrep_on for this THD so that it can
// operate with wsrep_ready == OFF
@@ -1731,6 +1736,8 @@ wait_signal:
proc.wait();
wsrep_donor_monitor_end();
+ sst_in_progress= false;
+
return NULL;
}
@@ -1884,3 +1891,8 @@ int wsrep_sst_donate(const std::string& msg,
return (ret >= 0 ? 0 : 1);
}
+
+bool wsrep_is_sst_progress()
+{
+ return (sst_in_progress);
+}
diff --git a/sql/wsrep_sst.h b/sql/wsrep_sst.h
index 2389db4abe7..50f2d362c5a 100644
--- a/sql/wsrep_sst.h
+++ b/sql/wsrep_sst.h
@@ -77,6 +77,7 @@ extern void wsrep_SE_init_grab(); /*! grab init critical section */
extern void wsrep_SE_init_wait(); /*! wait for SE init to complete */
extern void wsrep_SE_init_done(); /*! signal that SE init is complte */
extern void wsrep_SE_initialized(); /*! mark SE initialization complete */
+extern bool wsrep_is_sst_progress();
/**
Return a string containing the state transfer request string.
@@ -102,5 +103,6 @@ int wsrep_sst_donate(const std::string& request,
#define wsrep_SE_init_grab() do { } while(0)
#define wsrep_SE_init_done() do { } while(0)
#define wsrep_sst_continue() (0)
+#define wsrep_is_sst_progress() (0)
#endif /* WSREP_SST_H */
diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc
index 4fffc3ddc8a..40689b7cf88 100644
--- a/sql/wsrep_var.cc
+++ b/sql/wsrep_var.cc
@@ -360,6 +360,12 @@ static int wsrep_provider_verify (const char* provider_str)
{
return 1;
}
+
+ if (MY_S_ISDIR(f_stat.st_mode))
+ {
+ return 1;
+ }
+
return 0;
}
@@ -942,6 +948,11 @@ int wsrep_show_status (THD *thd, SHOW_VAR *var, char *buff)
var->type= SHOW_ARRAY;
var->value= (char *) &mysql_status_vars;
}
+ else
+ {
+ var->type= SHOW_CHAR;
+ var->value= (char*) "0";
+ }
return 0;
}
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index 126f873569f..40684e95615 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -5072,7 +5072,6 @@ btr_validate_index(
if (!btr_validate_level(index, trx, n - i, lockout)) {
err = DB_CORRUPTION;
- break;
}
}
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index daa1901181e..9c627ecd145 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -3442,7 +3442,7 @@ fail:
/* prefetch siblings of the leaf for the pessimistic
operation, if the page is leaf. */
- if (page_is_leaf(page)) {
+ if (page_is_leaf(page) && !index->is_ibuf()) {
btr_cur_prefetch_siblings(block);
}
fail_err:
@@ -3455,17 +3455,23 @@ fail_err:
}
ulint max_size = page_get_max_insert_size_after_reorganize(page, 1);
+ if (max_size < rec_size) {
+ goto fail;
+ }
+
+ const ulint n_recs = page_get_n_recs(page);
+ if (UNIV_UNLIKELY(n_recs >= 8189)) {
+ ut_ad(srv_page_size == 65536);
+ goto fail;
+ }
if (page_has_garbage(page)) {
- if ((max_size < rec_size
- || max_size < BTR_CUR_PAGE_REORGANIZE_LIMIT)
- && page_get_n_recs(page) > 1
+ if (max_size < BTR_CUR_PAGE_REORGANIZE_LIMIT
+ && n_recs > 1
&& page_get_max_insert_size(page, 1) < rec_size) {
goto fail;
}
- } else if (max_size < rec_size) {
- goto fail;
}
/* If there have been many consecutive inserts to the
@@ -4569,6 +4575,7 @@ btr_cur_optimistic_update(
if (rec_offs_any_extern(*offsets)) {
any_extern:
+ ut_ad(!index->is_ibuf());
/* Externally stored fields are treated in pessimistic
update */
@@ -4765,7 +4772,7 @@ func_exit:
}
}
- if (err != DB_SUCCESS) {
+ if (err != DB_SUCCESS && !index->is_ibuf()) {
/* prefetch siblings of the leaf for the pessimistic
operation. */
btr_cur_prefetch_siblings(block);
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 6a8c4869659..5977271dc20 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -3840,7 +3840,7 @@ buf_page_create(fil_space_t *space, uint32_t offset,
const bool drop_hash_entry= block->page.state() == BUF_BLOCK_FILE_PAGE &&
UNIV_LIKELY_NULL(block->index);
if (UNIV_UNLIKELY(drop_hash_entry))
- block->page.set_io_fix(BUF_IO_PIN);
+ rw_lock_x_lock(&block->lock);
#endif /* BTR_CUR_HASH_ADAPT */
/* Page can be found in buf_pool */
@@ -3851,7 +3851,7 @@ buf_page_create(fil_space_t *space, uint32_t offset,
if (UNIV_UNLIKELY(drop_hash_entry))
{
btr_search_drop_page_hash_index(block);
- block->page.io_unfix();
+ rw_lock_x_unlock(&block->lock);
}
#endif /* BTR_CUR_HASH_ADAPT */
diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc
index e00e59f79c4..7a27160ccd5 100644
--- a/storage/innobase/dict/dict0crea.cc
+++ b/storage/innobase/dict/dict0crea.cc
@@ -1511,7 +1511,7 @@ dict_create_or_check_foreign_constraint_tables(void)
row_mysql_unlock_data_dictionary(trx);
- trx_free(trx);
+ trx->free();
srv_file_per_table = srv_file_per_table_backup;
@@ -1612,7 +1612,7 @@ dict_create_or_check_sys_virtual()
row_mysql_unlock_data_dictionary(trx);
- trx_free(trx);
+ trx->free();
srv_file_per_table = srv_file_per_table_backup;
@@ -2146,7 +2146,7 @@ dict_create_or_check_sys_tablespace(void)
row_mysql_unlock_data_dictionary(trx);
- trx_free(trx);
+ trx->free();
srv_file_per_table = srv_file_per_table_backup;
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 0f1b3b461a8..097c907a826 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -262,7 +262,7 @@ dict_table_try_drop_aborted(
}
row_mysql_unlock_data_dictionary(trx);
- trx_free(trx);
+ trx->free();
}
/**********************************************************************//**
@@ -1975,7 +1975,7 @@ void dict_sys_t::remove(dict_table_t* table, bool lru, bool keep)
row_merge_drop_indexes_dict(trx, table->id);
trx_commit_for_mysql(trx);
trx->dict_operation_lock_mode = 0;
- trx_free(trx);
+ trx->free();
}
/* Free virtual column template if any */
diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc
index b8fdff89545..b135e042dc7 100644
--- a/storage/innobase/dict/dict0load.cc
+++ b/storage/innobase/dict/dict0load.cc
@@ -897,7 +897,7 @@ dict_update_filepath(
trx_commit_for_mysql(trx);
trx->dict_operation_lock_mode = 0;
- trx_free(trx);
+ trx->free();
if (UNIV_LIKELY(err == DB_SUCCESS)) {
/* We just updated SYS_DATAFILES due to the contents in
@@ -958,7 +958,7 @@ dict_replace_tablespace_and_filepath(
trx_commit_for_mysql(trx);
trx->dict_operation_lock_mode = 0;
- trx_free(trx);
+ trx->free();
return(err);
}
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index 1e8c9ec2131..5b79406fb18 100644
--- a/storage/innobase/dict/dict0mem.cc
+++ b/storage/innobase/dict/dict0mem.cc
@@ -120,7 +120,7 @@ bool dict_col_t::same_encoding(uint16_t a, uint16_t b)
{
if (const CHARSET_INFO *acs= get_charset(a, MYF(MY_WME)))
if (const CHARSET_INFO *bcs= get_charset(b, MYF(MY_WME)))
- return Charset(acs).same_encoding(bcs);
+ return Charset(bcs).encoding_allows_reinterpret_as(acs);
return false;
}
diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc
index 797f76862fa..03330664264 100644
--- a/storage/innobase/dict/dict0stats.cc
+++ b/storage/innobase/dict/dict0stats.cc
@@ -326,7 +326,7 @@ dict_stats_exec_sql(
}
if (trx_started) {
- trx_free(trx);
+ trx->free();
}
return(err);
@@ -2569,7 +2569,7 @@ func_exit:
trx_commit_for_mysql(trx);
end:
- trx_free(trx);
+ trx->free();
goto func_exit;
}
@@ -3039,7 +3039,7 @@ dict_stats_fetch_from_ps(
trx_commit_for_mysql(trx);
- trx_free(trx);
+ trx->free();
if (!index_fetch_arg.stats_were_modified) {
return(DB_STATS_DO_NOT_EXIST);
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index 6f9f1c2c17c..9fdd5f6b457 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -1462,28 +1462,31 @@ inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space,
ut_ad(mutex_own(&mutex));
sized_ilist<fil_space_t, rotation_list_tag_t>::iterator it=
- space ? space : rotation_list.begin();
+ space && space->is_in_rotation_list ? space : rotation_list.begin();
const sized_ilist<fil_space_t, rotation_list_tag_t>::iterator end=
rotation_list.end();
if (space)
{
- while (++it != end && (!UT_LIST_GET_LEN(it->chain) || it->is_stopping()));
+ const bool released= !space->release();
- /* If one of the encryption threads already started the encryption
- of the table then don't remove the unencrypted spaces from rotation list
-
- If there is a change in innodb_encrypt_tables variables value then
- don't remove the last processed tablespace from the rotation list. */
- space->release();
-
- if (!space->referenced() &&
- (!recheck || space->crypt_data) && !encrypt == !srv_encrypt_tables &&
- space->is_in_rotation_list)
+ if (space->is_in_rotation_list)
{
- ut_a(!rotation_list.empty());
- rotation_list.remove(*space);
- space->is_in_rotation_list= false;
+ while (++it != end &&
+ (!UT_LIST_GET_LEN(it->chain) || it->is_stopping()));
+
+ /* If one of the encryption threads already started the encryption
+ of the table then don't remove the unencrypted spaces from rotation list
+
+ If there is a change in innodb_encrypt_tables variables value then
+ don't remove the last processed tablespace from the rotation list. */
+ if (released && (!recheck || space->crypt_data) &&
+ !encrypt == !srv_encrypt_tables)
+ {
+ ut_a(!rotation_list.empty());
+ rotation_list.remove(*space);
+ space->is_in_rotation_list= false;
+ }
}
}
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 5e6bd9575b1..3874616e230 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -1496,21 +1496,27 @@ void fil_system_t::create(ulint hash_size)
void fil_system_t::close()
{
- ut_ad(this == &fil_system);
- ut_a(!UT_LIST_GET_LEN(LRU));
- ut_a(unflushed_spaces.empty());
- ut_a(!UT_LIST_GET_LEN(space_list));
- ut_ad(!sys_space);
- ut_ad(!temp_space);
+ ut_ad(this == &fil_system);
+ ut_a(!UT_LIST_GET_LEN(LRU));
+ ut_a(unflushed_spaces.empty());
+ ut_a(!UT_LIST_GET_LEN(space_list));
+ ut_ad(!sys_space);
+ ut_ad(!temp_space);
+
+ if (is_initialised())
+ {
+ m_initialised= false;
+ spaces.free();
+ mutex_free(&mutex);
+ fil_space_crypt_cleanup();
+ }
- if (is_initialised()) {
- m_initialised = false;
- spaces.free();
- mutex_free(&mutex);
- fil_space_crypt_cleanup();
- }
+ ut_ad(!spaces.array);
- ut_ad(!spaces.array);
+#ifdef UNIV_LINUX
+ ssd.clear();
+ ssd.shrink_to_fit();
+#endif /* UNIV_LINUX */
}
/** Opens all system tablespace data files. They stay open until the
@@ -1995,7 +2001,7 @@ fil_check_pending_io(
/* Give a warning every 10 second, starting after 1 second */
if ((count % 500) == 50) {
- ib::warn() << "Trying to delete"
+ ib::info() << "Trying to delete"
" tablespace '" << space->name
<< "' but there are "
<< space->n_pending_flushes
diff --git a/storage/innobase/fil/fil0pagecompress.cc b/storage/innobase/fil/fil0pagecompress.cc
index d3f6a9af72f..909e8092f99 100644
--- a/storage/innobase/fil/fil0pagecompress.cc
+++ b/storage/innobase/fil/fil0pagecompress.cc
@@ -253,15 +253,6 @@ fail:
memset(out_buf + tmp, 0, write_size - tmp);
}
-#ifdef UNIV_DEBUG
- /* Verify that page can be decompressed */
- {
- page_t tmp_buf[UNIV_PAGE_SIZE_MAX];
- page_t page[UNIV_PAGE_SIZE_MAX];
- memcpy(page, out_buf, write_size);
- ut_ad(fil_page_decompress(tmp_buf, page, flags));
- }
-#endif
srv_stats.page_compression_saved.add(srv_page_size - write_size);
srv_stats.pages_page_compressed.inc();
@@ -332,23 +323,13 @@ static ulint fil_page_compress_for_non_full_crc32(
mach_write_to_2(out_buf + FIL_PAGE_DATA + FIL_PAGE_COMP_SIZE,
write_size);
-#ifdef UNIV_DEBUG
- /* Verify */
- switch (fil_page_get_type(out_buf)) {
- case FIL_PAGE_PAGE_COMPRESSED:
- case FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED:
- break;
- default:
- ut_ad("wrong page type" == 0);
- break;
- }
-
ut_ad(mach_read_from_4(out_buf + FIL_PAGE_SPACE_OR_CHKSUM)
== BUF_NO_CHECKSUM_MAGIC);
ut_ad(mach_read_from_2(out_buf + FIL_PAGE_DATA + FIL_PAGE_COMP_SIZE)
== write_size);
+#ifdef UNIV_DEBUG
bool is_compressed = (mach_read_from_8(out_buf + FIL_PAGE_COMP_ALGO)
== (ulint) comp_algo);
@@ -356,19 +337,10 @@ static ulint fil_page_compress_for_non_full_crc32(
(mach_read_from_2(out_buf + FIL_PAGE_DATA
+ FIL_PAGE_ENCRYPT_COMP_ALGO)
== (ulint) comp_algo);
+#endif /* UNIV_DEBUG */
ut_ad(is_compressed || is_encrypted_compressed);
- /* Verify that page can be decompressed */
- {
- page_t tmp_buf[UNIV_PAGE_SIZE_MAX];
- page_t page[UNIV_PAGE_SIZE_MAX];
- memcpy(page, out_buf, srv_page_size);
- ut_ad(fil_page_decompress(tmp_buf, page, flags));
- ut_ad(!buf_page_is_corrupted(false, page, flags));
- }
-#endif /* UNIV_DEBUG */
-
write_size+=header_len;
if (block_size <= 0) {
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index b5083b51061..cc69863f54b 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -532,7 +532,7 @@ cleanup:
}
que_graph_free(graph);
- trx_free(trx);
+ trx->free();
ret = true;
goto cleanup;
}
@@ -2711,7 +2711,7 @@ func_exit:
}
}
- trx_free(trx);
+ trx->free();
return(error);
}
@@ -2786,7 +2786,7 @@ fts_update_sync_doc_id(
fts_sql_rollback(trx);
}
- trx_free(trx);
+ trx->free();
}
return(error);
@@ -3016,7 +3016,7 @@ fts_commit_table(
fts_sql_commit(trx);
- trx_free(trx);
+ trx->free();
return(error);
}
@@ -3781,7 +3781,7 @@ fts_doc_fetch_by_doc_id(
error = fts_eval_sql(trx, graph);
fts_sql_commit(trx);
- trx_free(trx);
+ trx->free();
if (!get_doc) {
fts_que_graph_free(graph);
@@ -4175,9 +4175,9 @@ fts_sync_commit(
<< " ins/sec";
}
- /* Avoid assertion in trx_free(). */
+ /* Avoid assertion in trx_t::free(). */
trx->dict_operation_lock_mode = 0;
- trx_free(trx);
+ trx->free();
return(error);
}
@@ -4229,9 +4229,9 @@ fts_sync_rollback(
fts_sql_rollback(trx);
- /* Avoid assertion in trx_free(). */
+ /* Avoid assertion in trx_t::free(). */
trx->dict_operation_lock_mode = 0;
- trx_free(trx);
+ trx->free();
}
/** Run SYNC on the table, i.e., write out data from the cache to the
@@ -4934,7 +4934,7 @@ fts_get_rows_count(
fts_que_graph_free(graph);
- trx_free(trx);
+ trx->free();
return(count);
}
@@ -4960,7 +4960,7 @@ fts_update_max_cache_size(
fts_sql_commit(trx);
- trx_free(trx);
+ trx->free();
}
#endif /* FTS_CACHE_SIZE_DEBUG */
@@ -6150,14 +6150,12 @@ fts_rename_aux_tables_to_hex_format_low(
<< table->name << ". Please revert"
" manually.";
fts_sql_rollback(trx_bg);
- trx_free(trx_bg);
/* Continue to clear aux tables' flags2 */
not_rename = true;
- continue;
+ } else {
+ fts_sql_commit(trx_bg);
}
-
- fts_sql_commit(trx_bg);
- trx_free(trx_bg);
+ trx_bg->free();
}
DICT_TF2_FLAG_UNSET(parent_table, DICT_TF2_FTS_AUX_HEX_NAME);
@@ -6400,7 +6398,7 @@ fts_rename_aux_tables_to_hex_format(
}
fts_sql_commit(trx_rename);
- trx_free(trx_rename);
+ trx_rename->free();
ib_vector_reset(aux_tables);
}
@@ -6479,7 +6477,7 @@ fts_drop_obsolete_aux_table_from_vector(
fts_sql_commit(trx_drop);
}
- trx_free(trx_drop);
+ trx_drop->free();
}
}
@@ -6973,7 +6971,7 @@ fts_drop_orphaned_tables(void)
row_mysql_unlock_data_dictionary(trx);
- trx_free(trx);
+ trx->free();
if (heap != NULL) {
mem_heap_free(heap);
@@ -7146,7 +7144,7 @@ cleanup:
fts_sql_rollback(trx);
}
- trx_free(trx);
+ trx->free();
}
if (!cache->stopword_info.cached_stopword) {
diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc
index 490cbcd4546..419fc6e0011 100644
--- a/storage/innobase/fts/fts0opt.cc
+++ b/storage/innobase/fts/fts0opt.cc
@@ -1014,7 +1014,7 @@ fts_table_fetch_doc_ids(
}
if (alloc_bk_trx) {
- trx_free(trx);
+ trx->free();
}
return(error);
@@ -1716,7 +1716,8 @@ fts_optimize_free(
mem_heap_t* heap = static_cast<mem_heap_t*>(optim->self_heap->arg);
trx_commit_for_mysql(optim->trx);
- trx_free(optim->trx);
+ optim->trx->free();
+ optim->trx = NULL;
fts_doc_ids_free(optim->to_delete);
fts_optimize_graph_free(&optim->graph);
diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc
index db972b5dbff..4baba419ff7 100644
--- a/storage/innobase/fts/fts0que.cc
+++ b/storage/innobase/fts/fts0que.cc
@@ -2743,7 +2743,7 @@ fts_query_phrase_search(
/* Ignore empty strings. */
if (num_token > 0) {
- fts_string_t* token;
+ fts_string_t* token = NULL;
fts_fetch_t fetch;
trx_t* trx = query->trx;
fts_ast_oper_t oper = query->oper;
@@ -4123,7 +4123,7 @@ fts_query(
func_exit:
fts_query_free(&query);
- trx_free(query_trx);
+ query_trx->free();
return(error);
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 0471923fe60..6c40a7690f3 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -2373,18 +2373,6 @@ trx_is_registered_for_2pc(
}
/*********************************************************************//**
-Note that innobase_commit_ordered() was run. */
-static inline
-void
-trx_set_active_commit_ordered(
-/*==========================*/
- trx_t* trx) /* in: transaction */
-{
- ut_a(trx_is_registered_for_2pc(trx));
- trx->active_commit_ordered = 1;
-}
-
-/*********************************************************************//**
Note that a transaction has been registered with MySQL 2PC coordinator. */
static inline
void
@@ -2393,7 +2381,7 @@ trx_register_for_2pc(
trx_t* trx) /* in: transaction */
{
trx->is_registered = 1;
- ut_ad(trx->active_commit_ordered == 0);
+ ut_ad(!trx->active_commit_ordered);
}
/*********************************************************************//**
@@ -2404,19 +2392,8 @@ trx_deregister_from_2pc(
/*====================*/
trx_t* trx) /* in: transaction */
{
- trx->is_registered = 0;
- trx->active_commit_ordered = 0;
-}
-
-/*********************************************************************//**
-Check whether a transaction has active_commit_ordered set */
-static inline
-bool
-trx_is_active_commit_ordered(
-/*=========================*/
- const trx_t* trx) /* in: transaction */
-{
- return(trx->active_commit_ordered == 1);
+ trx->is_registered= false;
+ trx->active_commit_ordered= false;
}
/*********************************************************************//**
@@ -3787,9 +3764,8 @@ innobase_end(handlerton*, ha_panic_function)
if (srv_was_started) {
THD *thd= current_thd;
if (thd) { // may be UNINSTALL PLUGIN statement
- trx_t* trx = thd_to_trx(thd);
- if (trx) {
- trx_free(trx);
+ if (trx_t* trx = thd_to_trx(thd)) {
+ trx->free();
}
}
@@ -3975,8 +3951,7 @@ innobase_commit_ordered(
(!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)));
innobase_commit_ordered_2(trx, thd);
-
- trx_set_active_commit_ordered(trx);
+ trx->active_commit_ordered = true;
DBUG_VOID_RETURN;
}
@@ -4029,7 +4004,7 @@ innobase_commit(
DBUG_SUICIDE(););
/* Run the fast part of commit if we did not already. */
- if (!trx_is_active_commit_ordered(trx)) {
+ if (!trx->active_commit_ordered) {
innobase_commit_ordered_2(trx, thd);
}
@@ -4458,7 +4433,7 @@ static int innobase_close_connection(handlerton *hton, THD *thd)
return 0;
}
innobase_rollback_trx(trx);
- trx_free(trx);
+ trx->free();
}
return 0;
}
@@ -12624,7 +12599,7 @@ create_table_info_t::create_table_update_dict()
if (m_flags2 & DICT_TF2_FTS) {
if (!innobase_fts_load_stopword(innobase_table, NULL, m_thd)) {
dict_table_close(innobase_table, FALSE, FALSE);
- trx_free(m_trx);
+ m_trx->free();
DBUG_RETURN(-1);
}
@@ -12755,7 +12730,7 @@ ha_innobase::create(
trx_rollback_for_mysql(trx);
row_mysql_unlock_data_dictionary(trx);
if (own_trx) {
- trx_free(trx);
+ trx->free();
}
DBUG_RETURN(error);
}
@@ -12764,7 +12739,7 @@ ha_innobase::create(
row_mysql_unlock_data_dictionary(trx);
if (own_trx) {
- trx_free(trx);
+ trx->free();
}
/* Flush the log to reduce probability that the .frm files and
@@ -13117,7 +13092,7 @@ inline int ha_innobase::delete_table(const char* name, enum_sql_command sqlcom)
innobase_commit_low(trx);
- trx_free(trx);
+ trx->free();
DBUG_RETURN(convert_error_code_to_mysql(err, 0, NULL));
}
@@ -13217,7 +13192,7 @@ innobase_drop_database(
innobase_commit_low(trx);
- trx_free(trx);
+ trx->free();
}
/** Rename an InnoDB table.
@@ -13394,7 +13369,7 @@ int ha_innobase::truncate()
|| dict_table_is_file_per_table(ib_table), trx);
}
- trx_free(trx);
+ trx->free();
if (!err) {
/* Reopen the newly created table, and drop the
@@ -13457,7 +13432,7 @@ ha_innobase::rename_table(
innobase_commit_low(trx);
- trx_free(trx);
+ trx->free();
if (error == DB_SUCCESS) {
char norm_from[MAX_FULL_NAME_LEN];
@@ -16876,7 +16851,7 @@ innobase_commit_by_xid(
ut_ad(trx->mysql_thd == NULL);
trx_deregister_from_2pc(trx);
ut_ad(!trx->will_lock); /* trx cache requirement */
- trx_free(trx);
+ trx->free();
return(XA_OK);
} else {
@@ -16913,7 +16888,7 @@ int innobase_rollback_by_xid(handlerton* hton, XID* xid)
#endif /* WITH_WSREP */
int ret = innobase_rollback_trx(trx);
ut_ad(!trx->will_lock);
- trx_free(trx);
+ trx->free();
return(ret);
} else {
@@ -19542,7 +19517,7 @@ static TYPELIB page_compression_algorithms_typelib=
};
static MYSQL_SYSVAR_ENUM(compression_algorithm, innodb_compression_algorithm,
PLUGIN_VAR_OPCMDARG,
- "Compression algorithm used on page compression. One of: none, zlib, lz4, lzo, lzma, or bzip2",
+ "Compression algorithm used on page compression. One of: none, zlib, lz4, lzo, lzma, bzip2, or snappy",
innodb_compression_algorithm_validate, NULL,
/* We use here the largest number of supported compression method to
enable all those methods that are available. Availability of compression
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 95f3b52d41e..ceda6187374 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -4054,7 +4054,7 @@ online_retry_drop_indexes(
online_retry_drop_indexes_low(table, trx);
trx_commit_for_mysql(trx);
row_mysql_unlock_data_dictionary(trx);
- trx_free(trx);
+ trx->free();
}
ut_d(mutex_enter(&dict_sys.mutex));
@@ -4693,7 +4693,11 @@ innobase_pk_order_preserved(
if (old_pk_column) {
new_field_order = lint(old_field);
} else if (innobase_pk_col_is_existing(new_col_no, col_map,
- old_n_cols)) {
+ old_n_cols)
+ || new_clust_index->table->persistent_autoinc
+ == new_field + 1) {
+ /* Adding an existing column or an AUTO_INCREMENT
+ column may change the existing ordering. */
new_field_order = lint(old_n_uniq
+ existing_field_count++);
} else {
@@ -6828,12 +6832,6 @@ error_handling_drop_uncached_1:
user_table);
dict_index_t* new_clust_index = dict_table_get_first_index(
ctx->new_table);
- ctx->skip_pk_sort = innobase_pk_order_preserved(
- ctx->col_map, clust_index, new_clust_index);
-
- DBUG_EXECUTE_IF("innodb_alter_table_pk_assert_no_sort",
- DBUG_ASSERT(ctx->skip_pk_sort););
-
ut_ad(!new_clust_index->is_instant());
/* row_merge_build_index() depends on the correct value */
ut_ad(new_clust_index->n_core_null_bytes
@@ -6857,6 +6855,12 @@ error_handling_drop_uncached_1:
}
}
+ ctx->skip_pk_sort = innobase_pk_order_preserved(
+ ctx->col_map, clust_index, new_clust_index);
+
+ DBUG_EXECUTE_IF("innodb_alter_table_pk_assert_no_sort",
+ DBUG_ASSERT(ctx->skip_pk_sort););
+
if (ctx->online) {
/* Allocate a log for online table rebuild. */
rw_lock_x_lock(&clust_index->lock);
@@ -7159,7 +7163,7 @@ err_exit:
if (ctx->trx) {
row_mysql_unlock_data_dictionary(ctx->trx);
- trx_free(ctx->trx);
+ ctx->trx->free();
}
trx_commit_for_mysql(ctx->prebuilt->trx);
@@ -8726,7 +8730,8 @@ rollback_inplace_alter_table(
trx_commit_for_mysql(ctx->trx);
row_mysql_unlock_data_dictionary(ctx->trx);
- trx_free(ctx->trx);
+ ctx->trx->free();
+ ctx->trx = NULL;
func_exit:
#ifndef DBUG_OFF
@@ -10792,11 +10797,11 @@ ha_innobase::commit_inplace_alter_table(
/* Exclusively lock the table, to ensure that no other
transaction is holding locks on the table while we
- change the table definition. The MySQL meta-data lock
+ change the table definition. The meta-data lock (MDL)
should normally guarantee that no conflicting locks
exist. However, FOREIGN KEY constraints checks and any
transactions collected during crash recovery could be
- holding InnoDB locks only, not MySQL locks. */
+ holding InnoDB locks only, not MDL. */
dberr_t error = row_merge_lock_table(
m_prebuilt->trx, ctx->old_table, LOCK_X);
@@ -11097,7 +11102,7 @@ foreign_fail:
row_mysql_unlock_data_dictionary(trx);
if (trx != ctx0->trx) {
- trx_free(trx);
+ trx->free();
}
DBUG_RETURN(true);
}
@@ -11116,7 +11121,8 @@ foreign_fail:
= static_cast<ha_innobase_inplace_ctx*>(*pctx);
if (ctx->trx) {
- trx_free(ctx->trx);
+ ctx->trx->free();
+ ctx->trx = NULL;
}
}
@@ -11164,7 +11170,7 @@ foreign_fail:
}
row_mysql_unlock_data_dictionary(trx);
- trx_free(trx);
+ trx->free();
MONITOR_ATOMIC_DEC(MONITOR_PENDING_ALTER_TABLE);
DBUG_RETURN(false);
}
@@ -11285,7 +11291,7 @@ foreign_fail:
}
row_mysql_unlock_data_dictionary(trx);
- trx_free(trx);
+ trx->free();
/* TODO: The following code could be executed
while allowing concurrent access to the table
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 897bda85d9b..125456c1ad4 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -2446,7 +2446,7 @@ i_s_fts_deleted_generic_fill(
rw_lock_s_unlock(&dict_sys.latch);
- trx_free(trx);
+ trx->free();
fields = table->field;
@@ -2992,7 +2992,7 @@ i_s_fts_index_table_fill_selected(
que_graph_free(graph);
mutex_exit(&dict_sys.mutex);
- trx_free(trx);
+ trx->free();
if (fetch.total_memory >= fts_result_cache_limit) {
error = DB_FTS_EXCEED_RESULT_CACHE_LIMIT;
@@ -3470,7 +3470,7 @@ no_fts:
rw_lock_s_unlock(&dict_sys.latch);
- trx_free(trx);
+ trx->free();
DBUG_RETURN(ret);
}
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 81a76ac8bab..0c42c5ffe6f 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -728,7 +728,7 @@ public:
bool same_format(const dict_col_t &other) const
{
return same_type(other) && len >= other.len &&
- mbminlen == other.mbminlen && mbmaxlen == other.mbmaxlen &&
+ mbminlen == other.mbminlen && mbmaxlen >= other.mbmaxlen &&
!((prtype ^ other.prtype) & ~(DATA_NOT_NULL | DATA_VERSIONED |
CHAR_COLL_MASK << 16 |
DATA_LONG_TRUE_VARCHAR));
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 9ea5de0a125..3a2f78fa25f 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -504,8 +504,9 @@ struct fil_space_t
/** Acquire a tablespace reference. */
void acquire() { n_pending_ops++; }
- /** Release a tablespace reference. */
- void release() { ut_ad(referenced()); n_pending_ops--; }
+ /** Release a tablespace reference.
+ @return whether this was the last reference */
+ bool release() { auto n= n_pending_ops--; ut_ad(n); return n == 1; }
/** @return whether references are being held */
bool referenced() const { return n_pending_ops; }
diff --git a/storage/innobase/include/fts0ast.h b/storage/innobase/include/fts0ast.h
index bad040fdcda..3dca92235c7 100644
--- a/storage/innobase/include/fts0ast.h
+++ b/storage/innobase/include/fts0ast.h
@@ -29,14 +29,6 @@ Created 2007/03/16/03 Sunny Bains
#include "mem0mem.h"
-#ifdef UNIV_PFS_MEMORY
-
-#define malloc(A) ut_malloc_nokey(A)
-#define free(A) ut_free(A)
-#define realloc(P, A) ut_realloc(P, A)
-
-#endif /* UNIV_PFS_MEMORY */
-
/* The type of AST Node */
enum fts_ast_type_t {
FTS_AST_OPER, /*!< Operator */
diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h
index 8a4953d7533..9eae5369d48 100644
--- a/storage/innobase/include/log0log.h
+++ b/storage/innobase/include/log0log.h
@@ -480,6 +480,11 @@ public:
bool writes_are_durable() const noexcept;
dberr_t write(os_offset_t offset, span<const byte> buf) noexcept;
dberr_t flush() noexcept;
+ void free()
+ {
+ m_path.clear();
+ m_path.shrink_to_fit();
+ }
private:
std::unique_ptr<file_io> m_file;
diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h
index fe36b3a5c83..b8d7e40246c 100644
--- a/storage/innobase/include/log0recv.h
+++ b/storage/innobase/include/log0recv.h
@@ -302,7 +302,7 @@ public:
void read(os_offset_t offset, span<byte> buf);
inline size_t files_size();
- void close_files() { files.clear(); }
+ void close_files() { files.clear(); files.shrink_to_fit(); }
private:
/** Attempt to initialize a page based on redo log records.
diff --git a/storage/innobase/include/read0types.h b/storage/innobase/include/read0types.h
index de3ff927520..21143ab609d 100644
--- a/storage/innobase/include/read0types.h
+++ b/storage/innobase/include/read0types.h
@@ -279,22 +279,15 @@ public:
/**
- Make the memory accessible by innodb_monitor_set_option;
- It is operating also on freed transaction objects.
+ Declare the object mostly unaccessible.
+ innodb_monitor_set_option is operating also on freed transaction objects.
*/
- void mem_valid() const
+ void mem_noaccess() const
{
- /* Cancel the effect of MEM_NOACCESS(). */
-#ifdef __SANITIZE_ADDRESS__
- MEM_MAKE_ADDRESSABLE(&m_mutex, sizeof m_mutex);
-#endif
-#if defined HAVE_valgrind && !__has_feature(memory_sanitizer)
- /* In Valgrind, we cannot cancel MEM_NOACCESS() without changing
- the state of the V bits (indicating which bits are initialized).
- We will declare the contents as initialized.
- We did invoke MEM_CHECK_DEFINED() in trx_pools->mem_free(). */
- MEM_MAKE_DEFINED(&m_mutex, sizeof m_mutex);
-#endif
+ MEM_NOACCESS(&m_open, sizeof m_open);
+ /* m_mutex is accessed by innodb_show_mutex_status()
+ and innodb_monitor_update() even after trx_t::free() */
+ MEM_NOACCESS(&m_creator_trx_id, sizeof m_creator_trx_id);
}
};
#endif
diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
index d91e77f9a52..acb10428108 100644
--- a/storage/innobase/include/trx0sys.h
+++ b/storage/innobase/include/trx0sys.h
@@ -572,7 +572,7 @@ public:
Releases LF_HASH pins.
Must be called by thread that owns trx_t object when the latter is being
- "detached" from thread (e.g. released to the pool by trx_free()). Can be
+ "detached" from thread (e.g. released to the pool by trx_t::free()). Can be
called earlier if thread is expected not to use rw_trx_hash.
Since pins are not allowed to be transferred to another thread,
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 20043a6c4a4..2294025a1aa 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -68,27 +68,18 @@ trx_get_error_info(
/*===============*/
const trx_t* trx); /*!< in: trx object */
-/** @return a trx_t instance from trx_pools. */
+/** @return an allocated transaction */
trx_t *trx_create();
-/**
- Release a trx_t instance back to the pool.
- @param trx the instance to release.
-*/
-void trx_free(trx_t*& trx);
-
/** At shutdown, frees a transaction object. */
-void
-trx_free_at_shutdown(trx_t *trx);
+void trx_free_at_shutdown(trx_t *trx);
/** Disconnect a prepared transaction from MySQL.
@param[in,out] trx transaction */
-void
-trx_disconnect_prepared(trx_t* trx);
+void trx_disconnect_prepared(trx_t *trx);
/** Initialize (resurrect) transactions at startup. */
-void
-trx_lists_init_at_db_start();
+void trx_lists_init_at_db_start();
/*************************************************************//**
Starts the transaction if it is not yet started. */
@@ -840,7 +831,8 @@ public:
the coordinator using the XA API, and
is set to false after commit or
rollback. */
- unsigned active_commit_ordered:1;/* 1 if owns prepare mutex */
+ /** whether this is holding the prepare mutex */
+ bool active_commit_ordered;
/*------------------------------*/
bool check_unique_secondary;
/*!< normally TRUE, but if the user
@@ -1095,6 +1087,9 @@ public:
ut_ad(old_n_ref > 0);
}
+ /** Free the memory to trx_pools */
+ void free();
+
void assert_freed() const
{
diff --git a/storage/innobase/include/ut0pool.h b/storage/innobase/include/ut0pool.h
index c31633e7f4c..e0a1f7c04ca 100644
--- a/storage/innobase/include/ut0pool.h
+++ b/storage/innobase/include/ut0pool.h
@@ -87,19 +87,6 @@ struct Pool {
for (Element* elem = m_start; elem != m_last; ++elem) {
ut_ad(elem->m_pool == this);
-#ifdef __SANITIZE_ADDRESS__
- /* Unpoison the memory for AddressSanitizer */
- MEM_MAKE_ADDRESSABLE(&elem->m_type,
- sizeof elem->m_type);
-#endif
-#if defined HAVE_valgrind && !__has_feature(memory_sanitizer)
- /* In Valgrind, we cannot cancel MEM_NOACCESS() without
- changing the state of the V bits (which indicate
- which bits are initialized).
- We will declare the contents as initialized.
- We did invoke MEM_CHECK_DEFINED() in mem_free(). */
- MEM_MAKE_DEFINED(&elem->m_type, sizeof elem->m_type);
-#endif
Factory::destroy(&elem->m_type);
}
@@ -134,24 +121,6 @@ struct Pool {
elem = NULL;
}
-#if defined HAVE_valgrind || defined __SANITIZE_ADDRESS__
- if (elem) {
-# ifdef __SANITIZE_ADDRESS__
- /* Unpoison the memory for AddressSanitizer */
- MEM_MAKE_ADDRESSABLE(&elem->m_type,
- sizeof elem->m_type);
-# endif
-# if defined HAVE_valgrind && !__has_feature(memory_sanitizer)
- /* In Valgrind, we cannot cancel MEM_NOACCESS() without
- changing the state of the V bits (which indicate
- which bits are initialized).
- We will declare the contents as initialized.
- We did invoke MEM_CHECK_DEFINED() in mem_free(). */
- MEM_MAKE_DEFINED(&elem->m_type, sizeof elem->m_type);
-# endif
- }
-#endif
-
m_lock_strategy.exit();
return elem ? &elem->m_type : NULL;
}
@@ -164,12 +133,10 @@ struct Pool {
byte* p = reinterpret_cast<byte*>(ptr + 1);
elem = reinterpret_cast<Element*>(p - sizeof(*elem));
- MEM_CHECK_DEFINED(&elem->m_type, sizeof elem->m_type);
elem->m_pool->m_lock_strategy.enter();
elem->m_pool->putl(elem);
- MEM_NOACCESS(&elem->m_type, sizeof elem->m_type);
elem->m_pool->m_lock_strategy.exit();
}
@@ -192,9 +159,6 @@ private:
void putl(Element* elem)
{
ut_ad(elem >= m_start && elem < m_last);
-
- ut_ad(Factory::debug(&elem->m_type));
-
m_pqueue.push(elem);
}
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 1cf8d5fb5ad..e8a7a5aa88c 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -821,11 +821,12 @@ void log_t::file::flush()
void log_t::file::close_file()
{
- if (!fd.is_opened())
- return;
-
- if (const dberr_t err= fd.close())
- ib::fatal() << "close(" << fd.get_path() << ") returned " << err;
+ if (fd.is_opened())
+ {
+ if (const dberr_t err= fd.close())
+ ib::fatal() << "close(" << fd.get_path() << ") returned " << err;
+ }
+ fd.free(); // Free path
}
/** Initialize the redo log. */
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 791e13e014e..46830db1323 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -907,37 +907,34 @@ fil_name_process(char* name, ulint len, ulint space_id, bool deleted)
/** Clean up after recv_sys_t::create() */
void recv_sys_t::close()
{
- ut_ad(this == &recv_sys);
- ut_ad(!recv_writer_thread_active);
-
- if (is_initialised()) {
- dblwr.pages.clear();
- ut_d(mutex_enter(&mutex));
- clear();
- ut_d(mutex_exit(&mutex));
+ ut_ad(this == &recv_sys);
+ ut_ad(!recv_writer_thread_active);
- if (flush_start) {
- os_event_destroy(flush_start);
- }
+ if (is_initialised())
+ {
+ dblwr.pages.clear();
+ ut_d(mutex_enter(&mutex));
+ clear();
+ ut_d(mutex_exit(&mutex));
- if (flush_end) {
- os_event_destroy(flush_end);
- }
+ os_event_destroy(flush_start);
+ os_event_destroy(flush_end);
- if (buf) {
- ut_free_dodump(buf, RECV_PARSING_BUF_SIZE);
- buf = NULL;
- }
+ if (buf)
+ {
+ ut_free_dodump(buf, RECV_PARSING_BUF_SIZE);
+ buf= nullptr;
+ }
- last_stored_lsn = 0;
- mutex_free(&writer_mutex);
- mutex_free(&mutex);
- }
+ last_stored_lsn= 0;
+ mutex_free(&writer_mutex);
+ mutex_free(&mutex);
+ }
- recv_spaces.clear();
- mlog_init.clear();
+ recv_spaces.clear();
+ mlog_init.clear();
- files.clear();
+ close_files();
}
/******************************************************************//**
@@ -1060,24 +1057,25 @@ inline void recv_sys_t::clear()
/** Free most recovery data structures. */
void recv_sys_t::debug_free()
{
- ut_ad(this == &recv_sys);
- ut_ad(is_initialised());
- mutex_enter(&mutex);
+ ut_ad(this == &recv_sys);
+ ut_ad(is_initialised());
+ mutex_enter(&mutex);
- pages.clear();
- ut_free_dodump(buf, RECV_PARSING_BUF_SIZE);
+ pages.clear();
+ ut_free_dodump(buf, RECV_PARSING_BUF_SIZE);
- buf = NULL;
+ buf= nullptr;
- /* wake page cleaner up to progress */
- if (!srv_read_only_mode) {
- ut_ad(!recv_recovery_is_on());
- ut_ad(!recv_writer_thread_active);
- os_event_reset(buf_flush_event);
- os_event_set(flush_start);
- }
+ /* wake page cleaner up to progress */
+ if (!srv_read_only_mode)
+ {
+ ut_ad(!recv_recovery_is_on());
+ ut_ad(!recv_writer_thread_active);
+ os_event_reset(buf_flush_event);
+ os_event_set(flush_start);
+ }
- mutex_exit(&mutex);
+ mutex_exit(&mutex);
}
inline void *recv_sys_t::alloc(size_t len)
diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc
index 5f42deaaf8e..5ca0d120a10 100644
--- a/storage/innobase/page/page0cur.cc
+++ b/storage/innobase/page/page0cur.cc
@@ -1053,6 +1053,15 @@ static byte* page_mem_alloc_heap(buf_block_t *block, ulint need,
byte *n_heap= my_assume_aligned<2>(PAGE_N_HEAP + PAGE_HEADER + block->frame);
const uint16_t h= mach_read_from_2(n_heap);
+ if (UNIV_UNLIKELY((h + 1) & 0x6000))
+ {
+ /* At the minimum record size of 5+2 bytes, we can only reach this
+ condition when using innodb_page_size=64k. */
+ ut_ad((h & 0x7fff) == 8191);
+ ut_ad(srv_page_size == 65536);
+ return NULL;
+ }
+
*heap_no= h & 0x7fff;
ut_ad(*heap_no < srv_page_size / REC_N_NEW_EXTRA_BYTES);
compile_time_assert(UNIV_PAGE_SIZE_MAX / REC_N_NEW_EXTRA_BYTES < 0x3fff);
diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc
index a04537ea6c3..5fe029d5b4d 100644
--- a/storage/innobase/page/page0page.cc
+++ b/storage/innobase/page/page0page.cc
@@ -2098,6 +2098,7 @@ wrong_page_type:
/* Validate the record list in a loop checking also that
it is consistent with the directory. */
ulint count = 0, data_size = 0, own_count = 1, slot_no = 0;
+ ulint info_bits;
slot_no = 0;
slot = page_dir_get_nth_slot(page, slot_no);
@@ -2121,9 +2122,16 @@ wrong_page_type:
goto next_rec;
}
+ info_bits = rec_get_info_bits(rec, page_is_comp(page));
+ if (info_bits
+ & ~(REC_INFO_MIN_REC_FLAG | REC_INFO_DELETED_FLAG)) {
+ ib::error() << "info_bits has an incorrect value "
+ << info_bits;
+ ret = false;
+ }
+
if (rec == first_rec) {
- if ((rec_get_info_bits(rec, page_is_comp(page))
- & REC_INFO_MIN_REC_FLAG)) {
+ if (info_bits & REC_INFO_MIN_REC_FLAG) {
if (page_has_prev(page)) {
ib::error() << "REC_INFO_MIN_REC_FLAG "
"is set on non-left page";
@@ -2134,8 +2142,7 @@ wrong_page_type:
ib::error() << "REC_INFO_MIN_REC_FLAG "
"is set in a leaf-page record";
ret = false;
- } else if (!rec_get_deleted_flag(
- rec, page_is_comp(page))
+ } else if (!(info_bits & REC_INFO_DELETED_FLAG)
!= !index->table->instant) {
ib::error() << (index->table->instant
? "Metadata record "
@@ -2149,13 +2156,51 @@ wrong_page_type:
ib::error() << "Metadata record is missing";
ret = false;
}
- } else if (rec_get_info_bits(rec, page_is_comp(page))
- & REC_INFO_MIN_REC_FLAG) {
+ } else if (info_bits & REC_INFO_MIN_REC_FLAG) {
ib::error() << "REC_INFO_MIN_REC_FLAG record is not "
"first in page";
ret = false;
}
+ if (page_is_comp(page)) {
+ const rec_comp_status_t status = rec_get_status(rec);
+ if (status != REC_STATUS_ORDINARY
+ && status != REC_STATUS_NODE_PTR
+ && status != REC_STATUS_INFIMUM
+ && status != REC_STATUS_SUPREMUM
+ && status != REC_STATUS_INSTANT) {
+ ib::error() << "impossible record status "
+ << status;
+ ret = false;
+ } else if (page_rec_is_infimum(rec)) {
+ if (status != REC_STATUS_INFIMUM) {
+ ib::error()
+ << "infimum record has status "
+ << status;
+ ret = false;
+ }
+ } else if (page_rec_is_supremum(rec)) {
+ if (status != REC_STATUS_SUPREMUM) {
+ ib::error() << "supremum record has "
+ "status "
+ << status;
+ ret = false;
+ }
+ } else if (!page_is_leaf(page)) {
+ if (status != REC_STATUS_NODE_PTR) {
+ ib::error() << "node ptr record has "
+ "status "
+ << status;
+ ret = false;
+ }
+ } else if (!index->is_instant()
+ && status == REC_STATUS_INSTANT) {
+ ib::error() << "instantly added record in a "
+ "non-instant index";
+ ret = false;
+ }
+ }
+
/* Check that the records are in the ascending order */
if (count >= PAGE_HEAP_NO_USER_LOW
&& !page_rec_is_supremum(rec)) {
diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc
index 29197fde46b..baf63650347 100644
--- a/storage/innobase/row/row0ftsort.cc
+++ b/storage/innobase/row/row0ftsort.cc
@@ -1769,7 +1769,7 @@ exit:
error = ins_ctx.btr_bulk->finish(error);
UT_DELETE(ins_ctx.btr_bulk);
- trx_free(trx);
+ trx->free();
mem_heap_free(heap);
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 9fc7425957a..2ec0a06709e 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -2200,7 +2200,7 @@ row_import_cleanup(
row_mysql_unlock_data_dictionary(trx);
- trx_free(trx);
+ trx->free();
prebuilt->trx->op_info = "";
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 3e0ffcf28b9..4f4329082fe 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -4030,7 +4030,7 @@ row_merge_drop_temp_indexes(void)
trx_commit_for_mysql(trx);
row_mysql_unlock_data_dictionary(trx);
- trx_free(trx);
+ trx->free();
}
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index f7868135a94..42ed2aaf415 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -2568,7 +2568,7 @@ row_drop_table_for_mysql_in_background(
trx_commit_for_mysql(trx);
- trx_free(trx);
+ trx->free();
return(error);
}
@@ -2752,7 +2752,7 @@ row_mysql_drop_garbage_tables()
btr_pcur_close(&pcur);
mtr.commit();
row_mysql_unlock_data_dictionary(trx);
- trx_free(trx);
+ trx->free();
mem_heap_free(heap);
}
@@ -3807,8 +3807,6 @@ funct_exit_all_freed:
trx->op_info = "";
- srv_inc_activity_count();
-
DBUG_RETURN(err);
}
@@ -4521,12 +4519,20 @@ end:
if (err != DB_SUCCESS) {
if (old_is_tmp) {
- ib::error() << "In ALTER TABLE "
+ /* In case of copy alter, ignore the
+ loading of foreign key constraint
+ when foreign_key_check is disabled */
+ ib::error_or_warn(trx->check_foreigns)
+ << "In ALTER TABLE "
<< ut_get_name(trx, new_name)
<< " has or is referenced in foreign"
" key constraints which are not"
" compatible with the new table"
" definition.";
+ if (!trx->check_foreigns) {
+ err = DB_SUCCESS;
+ goto funct_exit;
+ }
} else {
ib::error() << "In RENAME TABLE table "
<< ut_get_name(trx, new_name)
@@ -4596,7 +4602,7 @@ funct_exit:
trx_bg->dict_operation_lock_mode = 0;
trx_commit_for_mysql(trx_bg);
- trx_free(trx_bg);
+ trx_bg->free();
}
if (table != NULL) {
diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc
index 63edbd9b86d..68856d47b5e 100644
--- a/storage/innobase/row/row0uins.cc
+++ b/storage/innobase/row/row0uins.cc
@@ -84,11 +84,11 @@ row_undo_ins_remove_clust_rec(
online = false;
} else {
index->set_modified(mtr);
+ ut_ad(lock_table_has_locks(index->table));
online = dict_index_is_online_ddl(index);
if (online) {
ut_ad(node->rec_type == TRX_UNDO_INSERT_REC);
- ut_ad(node->trx->dict_operation_lock_mode
- != RW_X_LATCH);
+ ut_ad(!node->trx->dict_operation_lock_mode);
ut_ad(node->table->id != DICT_INDEXES_ID);
ut_ad(node->table->id != DICT_COLUMNS_ID);
mtr_s_lock_index(index, &mtr);
@@ -529,6 +529,9 @@ row_undo_ins(
return DB_SUCCESS;
}
+ ut_ad(node->table->is_temporary()
+ || lock_table_has_locks(node->table));
+
/* Iterate over all the indexes and undo the insert.*/
node->index = dict_table_get_first_index(node->table);
diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc
index 39f7ddbd79a..d32c6cd2510 100644
--- a/storage/innobase/row/row0umod.cc
+++ b/storage/innobase/row/row0umod.cc
@@ -244,10 +244,7 @@ row_undo_mod_clust(
bool online;
ut_ad(thr_get_trx(thr) == node->trx);
- ut_ad(node->trx->dict_operation_lock_mode);
ut_ad(node->trx->in_rollback);
- ut_ad(rw_lock_own_flagged(&dict_sys.latch,
- RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
log_free_check();
pcur = &node->pcur;
@@ -259,11 +256,12 @@ row_undo_mod_clust(
mtr.set_log_mode(MTR_LOG_NO_REDO);
} else {
index->set_modified(mtr);
+ ut_ad(lock_table_has_locks(index->table));
}
online = dict_index_is_online_ddl(index);
if (online) {
- ut_ad(node->trx->dict_operation_lock_mode != RW_X_LATCH);
+ ut_ad(!node->trx->dict_operation_lock_mode);
mtr_s_lock_index(index, &mtr);
}
@@ -302,17 +300,7 @@ row_undo_mod_clust(
ut_ad(err == DB_SUCCESS || err == DB_OUT_OF_FILE_SPACE);
}
- /* Online rebuild cannot be initiated while we are holding
- dict_sys.latch and index->lock. (It can be aborted.) */
- ut_ad(online || !dict_index_is_online_ddl(index));
-
- if (err == DB_SUCCESS && online) {
-
- ut_ad(rw_lock_own_flagged(
- &index->lock,
- RW_LOCK_FLAG_S | RW_LOCK_FLAG_X
- | RW_LOCK_FLAG_SX));
-
+ if (err == DB_SUCCESS && online && dict_index_is_online_ddl(index)) {
switch (node->rec_type) {
case TRX_UNDO_DEL_MARK_REC:
row_log_table_insert(
@@ -887,37 +875,6 @@ func_exit_no_pcur:
}
/***********************************************************//**
-Flags a secondary index corrupted. */
-static MY_ATTRIBUTE((nonnull))
-void
-row_undo_mod_sec_flag_corrupted(
-/*============================*/
- trx_t* trx, /*!< in/out: transaction */
- dict_index_t* index) /*!< in: secondary index */
-{
- ut_ad(!dict_index_is_clust(index));
-
- switch (trx->dict_operation_lock_mode) {
- case RW_S_LATCH:
- /* Because row_undo() is holding an S-latch
- on the data dictionary during normal rollback,
- we can only mark the index corrupted in the
- data dictionary cache. TODO: fix this somehow.*/
- mutex_enter(&dict_sys.mutex);
- dict_set_corrupted_index_cache_only(index);
- mutex_exit(&dict_sys.mutex);
- break;
- default:
- ut_ad(0);
- /* fall through */
- case RW_X_LATCH:
- /* This should be the rollback of a data dictionary
- transaction. */
- dict_set_corrupted(index, trx, "rollback");
- }
-}
-
-/***********************************************************//**
Undoes a modify in secondary indexes when undo record type is UPD_DEL.
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
@@ -1030,8 +987,7 @@ row_undo_mod_del_mark_sec(
}
if (err == DB_DUPLICATE_KEY) {
- row_undo_mod_sec_flag_corrupted(
- thr_get_trx(thr), index);
+ index->type |= DICT_CORRUPT;
err = DB_SUCCESS;
/* Do not return any error to the caller. The
duplicate will be reported by ALTER TABLE or
@@ -1176,8 +1132,7 @@ row_undo_mod_upd_exist_sec(
}
if (err == DB_DUPLICATE_KEY) {
- row_undo_mod_sec_flag_corrupted(
- thr_get_trx(thr), index);
+ index->type |= DICT_CORRUPT;
err = DB_SUCCESS;
} else if (err != DB_SUCCESS) {
break;
@@ -1340,6 +1295,8 @@ row_undo_mod(
return DB_SUCCESS;
}
+ ut_ad(node->table->is_temporary()
+ || lock_table_has_locks(node->table));
node->index = dict_table_get_first_index(node->table);
ut_ad(dict_index_is_clust(node->index));
diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc
index 20bf53e3f91..2fe1135b894 100644
--- a/storage/innobase/row/row0undo.cc
+++ b/storage/innobase/row/row0undo.cc
@@ -411,15 +411,17 @@ row_undo(
return DB_SUCCESS;
}
- /* Prevent DROP TABLE etc. while we are rolling back this row.
- If we are doing a TABLE CREATE or some other dictionary operation,
- then we already have dict_sys.latch locked in x-mode. Do not
- try to lock again, because that would cause a hang. */
-
+ /* Prevent prepare_inplace_alter_table_dict() from adding
+ dict_table_t::indexes while we are processing the record.
+ Recovered transactions are not protected by MDL, and the
+ secondary index creation is not protected by table locks
+ for online operation. (A table lock would only be acquired
+ when committing the ALTER TABLE operation.) */
trx_t* trx = node->trx;
- const bool locked_data_dict = (trx->dict_operation_lock_mode == 0);
+ const bool locked_data_dict = UNIV_UNLIKELY(trx->is_recovered)
+ && !trx->dict_operation_lock_mode;
- if (locked_data_dict) {
+ if (UNIV_UNLIKELY(locked_data_dict)) {
row_mysql_freeze_data_dictionary(trx);
}
@@ -439,7 +441,7 @@ row_undo(
err = DB_CORRUPTION;
}
- if (locked_data_dict) {
+ if (UNIV_UNLIKELY(locked_data_dict)) {
row_mysql_unfreeze_data_dictionary(trx);
}
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index aa8a5ea2d14..ceb9245f659 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -73,7 +73,7 @@ Created 10/8/1995 Heikki Tuuri
#include "fil0crypt.h"
#include "fil0pagecompress.h"
#include "trx0types.h"
-
+#include <list>
#include <my_service_manager.h>
/* The following is the maximum allowed duration of a lock wait. */
@@ -2110,7 +2110,7 @@ static uint32_t srv_do_purge(ulint* n_total_purged)
}
-static std::queue<THD*> purge_thds;
+static std::list<THD*> purge_thds;
static std::mutex purge_thd_mutex;
extern void* thd_attach_thd(THD*);
extern void thd_detach_thd(void *);
@@ -2120,11 +2120,11 @@ THD* acquire_thd(void **ctx)
std::unique_lock<std::mutex> lk(purge_thd_mutex);
if (purge_thds.empty()) {
THD* thd = current_thd;
- purge_thds.push(innobase_create_background_thd("InnoDB purge worker"));
+ purge_thds.push_back(innobase_create_background_thd("InnoDB purge worker"));
set_current_thd(thd);
}
THD* thd = purge_thds.front();
- purge_thds.pop();
+ purge_thds.pop_front();
lk.unlock();
/* Set current thd, and thd->mysys_var as well,
@@ -2137,7 +2137,7 @@ void release_thd(THD *thd, void *ctx)
{
thd_detach_thd(ctx);
std::unique_lock<std::mutex> lk(purge_thd_mutex);
- purge_thds.push(thd);
+ purge_thds.push_back(thd);
lk.unlock();
set_current_thd(0);
}
@@ -2236,7 +2236,7 @@ static void srv_shutdown_purge_tasks()
while (!purge_thds.empty())
{
innobase_destroy_background_thd(purge_thds.front());
- purge_thds.pop();
+ purge_thds.pop_front();
}
}
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index 6747ada6de4..3f1d4258484 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -192,7 +192,7 @@ void purge_sys_t::close()
ut_ad(!trx->id);
ut_ad(trx->state == TRX_STATE_ACTIVE);
trx->state= TRX_STATE_NOT_STARTED;
- trx_free(trx);
+ trx->free();
rw_lock_free(&latch);
mutex_free(&pq_mutex);
mem_heap_free(heap);
diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc
index a16ee95dc83..dc3dd51bb89 100644
--- a/storage/innobase/trx/trx0roll.cc
+++ b/storage/innobase/trx/trx0roll.cc
@@ -807,7 +807,7 @@ discard:
trx_free_at_shutdown(trx);
}
else
- trx_free(trx);
+ trx->free();
}
}
}
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index a9ba8cd7786..d1f6a66f09b 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -110,7 +110,7 @@ trx_init(
trx->op_info = "";
- trx->active_commit_ordered = 0;
+ trx->active_commit_ordered = false;
trx->isolation_level = TRX_ISO_REPEATABLE_READ;
@@ -210,6 +210,18 @@ struct TrxFactory {
@param trx the transaction for which to release resources */
static void destroy(trx_t* trx)
{
+#ifdef __SANITIZE_ADDRESS__
+ /* Unpoison the memory for AddressSanitizer */
+ MEM_MAKE_ADDRESSABLE(trx, sizeof *trx);
+#elif !__has_feature(memory_sanitizer)
+ /* In Valgrind, we cannot cancel MEM_NOACCESS() without
+ changing the state of the V bits (which indicate
+ which bits are initialized).
+ We will declare the contents as initialized.
+ We did invoke MEM_CHECK_DEFINED() in trx_t::free(). */
+ MEM_MAKE_DEFINED(trx, sizeof *trx);
+#endif
+
ut_a(trx->magic_n == TRX_MAGIC_N);
ut_ad(!trx->mysql_thd);
@@ -238,36 +250,6 @@ struct TrxFactory {
trx->read_view.~ReadView();
}
-
- /** Enforce any invariants here, this is called before the transaction
- is added to the pool.
- @return true if all OK */
- static bool debug(const trx_t* trx)
- {
- ut_a(trx->error_state == DB_SUCCESS);
-
- ut_a(trx->magic_n == TRX_MAGIC_N);
-
- ut_ad(!trx->read_only);
-
- ut_ad(trx->state == TRX_STATE_NOT_STARTED);
-
- ut_ad(trx->dict_operation == TRX_DICT_OP_NONE);
-
- ut_ad(trx->mysql_thd == 0);
-
- ut_a(trx->lock.wait_thr == NULL);
- ut_a(trx->lock.wait_lock == NULL);
- ut_a(trx->dict_operation_lock_mode == 0);
-
- ut_a(UT_LIST_GET_LEN(trx->lock.trx_locks) == 0);
-
- ut_ad(trx->autoinc_locks == NULL);
-
- ut_ad(trx->lock.table_locks.empty());
-
- return(true);
- }
};
/** The lock strategy for TrxPool */
@@ -344,11 +326,24 @@ trx_pool_close()
trx_pools = 0;
}
-/** @return a trx_t instance from trx_pools. */
+/** @return an allocated transaction */
trx_t *trx_create()
{
trx_t* trx = trx_pools->get();
+#ifdef __SANITIZE_ADDRESS__
+ /* Unpoison the memory for AddressSanitizer.
+ It may have been poisoned in trx_t::free().*/
+ MEM_MAKE_ADDRESSABLE(trx, sizeof *trx);
+#elif !__has_feature(memory_sanitizer)
+ /* In Valgrind, we cannot cancel MEM_NOACCESS() without
+ changing the state of the V bits (which indicate
+ which bits are initialized).
+ We will declare the contents as initialized.
+ We did invoke MEM_CHECK_DEFINED() in trx_t::free(). */
+ MEM_MAKE_DEFINED(trx, sizeof *trx);
+#endif
+
trx->assert_freed();
mem_heap_t* heap;
@@ -364,14 +359,9 @@ trx_t *trx_create()
alloc = ib_heap_allocator_create(heap);
- /* Remember to free the vector explicitly in trx_free(). */
trx->autoinc_locks = ib_vector_create(alloc, sizeof(void**), 4);
- /* Should have been either just initialized or .clear()ed by
- trx_free(). */
ut_ad(trx->mod_tables.empty());
- ut_ad(trx->lock.table_locks.empty());
- ut_ad(UT_LIST_GET_LEN(trx->lock.trx_locks) == 0);
ut_ad(trx->lock.n_rec_locks == 0);
ut_ad(trx->lock.table_cached == 0);
ut_ad(trx->lock.rec_cached == 0);
@@ -382,83 +372,101 @@ trx_t *trx_create()
return(trx);
}
-/**
- Release a trx_t instance back to the pool.
- @param trx the instance to release.
-*/
-void trx_free(trx_t*& trx)
+/** Free the memory to trx_pools */
+void trx_t::free()
{
- ut_ad(!trx->n_mysql_tables_in_use);
- ut_ad(!trx->mysql_n_tables_locked);
- ut_ad(!trx->internal);
- ut_ad(!trx->mysql_log_file_name);
-
- if (trx->n_mysql_tables_in_use != 0
- || trx->mysql_n_tables_locked != 0) {
-
- ib::error() << "MySQL is freeing a thd though"
- " trx->n_mysql_tables_in_use is "
- << trx->n_mysql_tables_in_use
- << " and trx->mysql_n_tables_locked is "
- << trx->mysql_n_tables_locked << ".";
-
- trx_print(stderr, trx, 600);
- ut_print_buf(stderr, trx, sizeof(trx_t));
- putc('\n', stderr);
- }
-
- trx->dict_operation = TRX_DICT_OP_NONE;
- ut_ad(!trx->dict_operation_lock_mode);
-
- trx_sys.deregister_trx(trx);
-
- trx->assert_freed();
+ MEM_CHECK_DEFINED(this, sizeof *this);
+
+ ut_ad(!n_mysql_tables_in_use);
+ ut_ad(!mysql_log_file_name);
+ ut_ad(!mysql_n_tables_locked);
+ ut_ad(!internal);
+ ut_ad(!will_lock);
+ ut_ad(error_state == DB_SUCCESS);
+ ut_ad(magic_n == TRX_MAGIC_N);
+ ut_ad(!read_only);
+ ut_ad(!lock.wait_lock);
- trx_sys.rw_trx_hash.put_pins(trx);
- trx->mysql_thd = 0;
-
- // FIXME: We need to avoid this heap free/alloc for each commit.
- if (trx->autoinc_locks != NULL) {
- ut_ad(ib_vector_is_empty(trx->autoinc_locks));
- /* We allocated a dedicated heap for the vector. */
- ib_vector_free(trx->autoinc_locks);
- trx->autoinc_locks = NULL;
- }
+ dict_operation= TRX_DICT_OP_NONE;
+ trx_sys.deregister_trx(this);
+ assert_freed();
+ trx_sys.rw_trx_hash.put_pins(this);
- trx->mod_tables.clear();
+ mysql_thd= nullptr;
- /* trx locking state should have been reset before returning trx
- to pool */
- ut_ad(trx->will_lock == 0);
-
- trx_pools->mem_free(trx);
- trx->read_view.mem_valid();
-#ifdef __SANITIZE_ADDRESS__
- /* Unpoison the memory for innodb_monitor_set_option;
- it is operating also on the freed transaction objects. */
- MEM_MAKE_ADDRESSABLE(&trx->mutex, sizeof trx->mutex);
-# ifdef WITH_WSREP
- MEM_MAKE_ADDRESSABLE(&trx->wsrep, sizeof trx->wsrep);
-# endif
- /* For innobase_kill_connection() */
- MEM_MAKE_ADDRESSABLE(&trx->state, sizeof trx->state);
- MEM_MAKE_ADDRESSABLE(&trx->mysql_thd, sizeof trx->mysql_thd);
-#endif
-#if defined HAVE_valgrind && !__has_feature(memory_sanitizer)
- /* In Valgrind, we cannot cancel the effect of MEM_NOACCESS()
- without changing the state of the V bits (indicating which
- bits are initialized). We did invoke MEM_CHECK_DEFINED() in
- trx_pools->mem_free(). */
- MEM_MAKE_DEFINED(&trx->mutex, sizeof trx->mutex);
- /* For innobase_kill_connection() */
-# ifdef WITH_WSREP
- MEM_MAKE_DEFINED(&trx->wsrep, sizeof trx->wsrep);
-# endif
- MEM_MAKE_DEFINED(&trx->state, sizeof trx->state);
- MEM_MAKE_DEFINED(&trx->mysql_thd, sizeof trx->mysql_thd);
-#endif
+ // FIXME: We need to avoid this heap free/alloc for each commit.
+ if (autoinc_locks)
+ {
+ ut_ad(ib_vector_is_empty(autoinc_locks));
+ /* We allocated a dedicated heap for the vector. */
+ ib_vector_free(autoinc_locks);
+ autoinc_locks= NULL;
+ }
- trx = NULL;
+ mod_tables.clear();
+
+ MEM_NOACCESS(&n_ref, sizeof n_ref);
+ /* do not poison mutex */
+ MEM_NOACCESS(&id, sizeof id);
+ /* state is accessed by innobase_kill_connection() */
+ MEM_NOACCESS(&is_recovered, sizeof is_recovered);
+ /* wsrep is accessed by innobase_kill_connection() */
+ read_view.mem_noaccess();
+ MEM_NOACCESS(&lock, sizeof lock);
+ MEM_NOACCESS(&op_info, sizeof op_info);
+ MEM_NOACCESS(&isolation_level, sizeof isolation_level);
+ MEM_NOACCESS(&check_foreigns, sizeof check_foreigns);
+ MEM_NOACCESS(&is_registered, sizeof is_registered);
+ MEM_NOACCESS(&active_commit_ordered, sizeof active_commit_ordered);
+ MEM_NOACCESS(&check_unique_secondary, sizeof check_unique_secondary);
+ MEM_NOACCESS(&flush_log_later, sizeof flush_log_later);
+ MEM_NOACCESS(&must_flush_log_later, sizeof must_flush_log_later);
+ MEM_NOACCESS(&duplicates, sizeof duplicates);
+ MEM_NOACCESS(&dict_operation, sizeof dict_operation);
+ MEM_NOACCESS(&dict_operation_lock_mode, sizeof dict_operation_lock_mode);
+ MEM_NOACCESS(&start_time, sizeof start_time);
+ MEM_NOACCESS(&start_time_micro, sizeof start_time_micro);
+ MEM_NOACCESS(&commit_lsn, sizeof commit_lsn);
+ MEM_NOACCESS(&table_id, sizeof table_id);
+ /* mysql_thd is accessed by innobase_kill_connection() */
+ MEM_NOACCESS(&mysql_log_file_name, sizeof mysql_log_file_name);
+ MEM_NOACCESS(&mysql_log_offset, sizeof mysql_log_offset);
+ MEM_NOACCESS(&n_mysql_tables_in_use, sizeof n_mysql_tables_in_use);
+ MEM_NOACCESS(&mysql_n_tables_locked, sizeof mysql_n_tables_locked);
+ MEM_NOACCESS(&error_state, sizeof error_state);
+ MEM_NOACCESS(&error_info, sizeof error_info);
+ MEM_NOACCESS(&error_key_num, sizeof error_key_num);
+ MEM_NOACCESS(&graph, sizeof graph);
+ MEM_NOACCESS(&trx_savepoints, sizeof trx_savepoints);
+ MEM_NOACCESS(&undo_no, sizeof undo_no);
+ MEM_NOACCESS(&last_sql_stat_start, sizeof last_sql_stat_start);
+ MEM_NOACCESS(&rsegs, sizeof rsegs);
+ MEM_NOACCESS(&roll_limit, sizeof roll_limit);
+ MEM_NOACCESS(&in_rollback, sizeof in_rollback);
+ MEM_NOACCESS(&pages_undone, sizeof pages_undone);
+ MEM_NOACCESS(&n_autoinc_rows, sizeof n_autoinc_rows);
+ MEM_NOACCESS(&autoinc_locks, sizeof autoinc_locks);
+ MEM_NOACCESS(&read_only, sizeof read_only);
+ MEM_NOACCESS(&auto_commit, sizeof auto_commit);
+ MEM_NOACCESS(&will_lock, sizeof will_lock);
+ MEM_NOACCESS(&fts_trx, sizeof fts_trx);
+ MEM_NOACCESS(&fts_next_doc_id, sizeof fts_next_doc_id);
+ MEM_NOACCESS(&flush_tables, sizeof flush_tables);
+ MEM_NOACCESS(&ddl, sizeof ddl);
+ MEM_NOACCESS(&internal, sizeof internal);
+#ifdef UNIV_DEBUG
+ MEM_NOACCESS(&start_line, sizeof start_line);
+ MEM_NOACCESS(&start_file, sizeof start_file);
+#endif /* UNIV_DEBUG */
+ MEM_NOACCESS(&xid, sizeof xid);
+ MEM_NOACCESS(&mod_tables, sizeof mod_tables);
+ MEM_NOACCESS(&detailed_error, sizeof detailed_error);
+ MEM_NOACCESS(&n_rec_lock_waits, sizeof n_rec_lock_waits);
+ MEM_NOACCESS(&n_table_lock_waits, sizeof n_table_lock_waits);
+ MEM_NOACCESS(&total_rec_lock_wait_time, sizeof total_rec_lock_wait_time);
+ MEM_NOACCESS(&total_table_lock_wait_time, sizeof total_table_lock_wait_time);
+ MEM_NOACCESS(&magic_n, sizeof magic_n);
+ trx_pools->mem_free(this);
}
/** Transition to committed state, to release implicit locks. */
@@ -530,8 +538,7 @@ trx_free_at_shutdown(trx_t *trx)
trx->state = TRX_STATE_NOT_STARTED;
ut_ad(!UT_LIST_GET_LEN(trx->lock.trx_locks));
trx->id = 0;
-
- trx_free(trx);
+ trx->free();
}
@@ -1188,6 +1195,7 @@ trx_flush_log_if_needed_low(
case 1:
/* Write the log and optionally flush it to disk */
log_write_up_to(lsn, flush);
+ srv_inc_activity_count();
return;
case 0:
/* Do nothing */
diff --git a/storage/innobase/ut/ut0crc32.cc b/storage/innobase/ut/ut0crc32.cc
index 9de0ca81fe3..1ddac168d95 100644
--- a/storage/innobase/ut/ut0crc32.cc
+++ b/storage/innobase/ut/ut0crc32.cc
@@ -342,11 +342,11 @@ allocations, would not hurt if called twice, but would be pointless. */
void ut_crc32_init()
{
#ifndef HAVE_CRC32_VPMSUM
-# if defined(__GNUC__) && defined(HAVE_ARMV8_CRC) && defined(HAVE_ARMV8_CRYPTO)
- if (crc32c_aarch64_available())
+# if defined(__GNUC__) && defined(HAVE_ARMV8_CRC)
+ if (const char *crc32c_implementation= crc32c_aarch64_available())
{
ut_crc32_low= crc32c_aarch64;
- ut_crc32_implementation= "Using ARMv8 crc32 + pmull instructions";
+ ut_crc32_implementation= crc32c_implementation;
return;
}
# elif defined(TRY_SSE4_2)
diff --git a/storage/maria/aria_chk.c b/storage/maria/aria_chk.c
index f46fe7490d8..4f8438fb9d0 100644
--- a/storage/maria/aria_chk.c
+++ b/storage/maria/aria_chk.c
@@ -127,7 +127,7 @@ int main(int argc, char **argv)
int error;
MY_INIT(argv[0]);
- my_init_stacktrace(1);
+ my_setup_stacktrace();
default_log_dir= opt_log_dir= maria_data_root= (char *)".";
maria_chk_init(&check_param);
check_param.opt_lock_memory= 1; /* Lock memory if possible */
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index a13190b0220..25c44f7c90e 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -897,7 +897,6 @@ int maria_create(const char *name, enum data_file_type datafile_type,
fn_format(kfilename, name, "", MARIA_NAME_IEXT,
MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
- klinkname_ptr= NullS;
/*
Replace the current file.
Don't sync dir now if the data file has the same path.
@@ -1174,7 +1173,14 @@ int maria_create(const char *name, enum data_file_type datafile_type,
FALSE, TRUE))
goto err;
my_free(log_data);
+
+ /*
+ We don't need to sync directory as we can use the log to recreate
+ the index and data files if needed.
+ */
+ sync_dir= 0;
}
+ DBUG_ASSERT(!internal_table || sync_dir == 0);
if (!(flags & HA_DONT_TOUCH_DATA))
{
@@ -1212,7 +1218,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
if ((dfile=
mysql_file_create_with_symlink(key_file_dfile, dlinkname_ptr,
dfilename, 0, create_mode,
- MYF(MY_WME | create_flag | sync_dir))) < 0)
+ MYF(MY_WME | create_flag))) < 0)
goto err;
errpos=3;
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index 0ec0e58f8a8..1413b708bbc 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -3618,7 +3618,8 @@ my_bool translog_init_with_table(const char *directory,
int old_log_was_recovered= 0, logs_found= 0;
uint old_flags= flags;
uint32 start_file_num= 1;
- TRANSLOG_ADDRESS sure_page, last_page, last_valid_page, checkpoint_lsn;
+ TRANSLOG_ADDRESS UNINIT_VAR(sure_page), last_page, last_valid_page,
+ checkpoint_lsn;
my_bool version_changed= 0;
DBUG_ENTER("translog_init_with_table");
diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c
index fcdb4569f4c..6f2825a3319 100644
--- a/storage/myisam/mi_create.c
+++ b/storage/myisam/mi_create.c
@@ -623,7 +623,6 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
fn_format(kfilename, name, "", MI_NAME_IEXT,
MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
- klinkname_ptr= 0;
/* Replace the current file */
create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD;
}
diff --git a/storage/rocksdb/mysql-test/rocksdb/include/restart_mysqld_with_option.inc b/storage/rocksdb/mysql-test/rocksdb/include/restart_mysqld_with_option.inc
index 4250b368b1a..81cd2200ae0 100644
--- a/storage/rocksdb/mysql-test/rocksdb/include/restart_mysqld_with_option.inc
+++ b/storage/rocksdb/mysql-test/rocksdb/include/restart_mysqld_with_option.inc
@@ -15,7 +15,7 @@ if ($rpl_inited)
# Send shutdown to the connected server and give
# it 10 seconds to die before zapping it
-shutdown_server 10;
+shutdown_server;
# Write file to make mysql-test-run.pl start up the server again
--exec echo "restart:$_mysqld_option" > $_expect_file_name
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test b/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test
index c8c12626139..15a7d319c04 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test
@@ -41,7 +41,7 @@ perl;
EOF
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
---shutdown_server 10
+--shutdown_server
--error 1
--exec $MYSQLD_CMD --plugin_load=$HA_ROCKSDB_SO --rocksdb_ignore_unknown_options=0 --log-error=$error_log
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test b/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test
index 46ea7f0eb0a..a24851d9d8c 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test
@@ -8,7 +8,7 @@ DROP TABLE IF EXISTS t1;
# reload with load optimized config
let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
--exec echo "wait" > $restart_file
---shutdown_server 10
+--shutdown_server
--source include/wait_until_disconnected.inc
-- exec echo "restart:--rocksdb_write_disable_wal=1 --rocksdb_flush_log_at_trx_commit=0 --rocksdb_default_cf_options=write_buffer_size=16k;target_file_size_base=16k;level0_file_num_compaction_trigger=4;level0_slowdown_writes_trigger=256;level0_stop_writes_trigger=256;max_write_buffer_number=16;compression_per_level=kNoCompression;memtable=vector:1024 --rocksdb_override_cf_options=__system__={memtable=skip_list:16} --rocksdb_compaction_sequential_deletes=0 --rocksdb_compaction_sequential_deletes_window=0 --rocksdb_allow_concurrent_memtable_write=0" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- enable_reconnect
@@ -39,7 +39,7 @@ select count(*), sum(id), sum(i1), sum(i2) from t1;
# reload without load optimized config
let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
--exec echo "wait" > $restart_file
---shutdown_server 10
+--shutdown_server
--source include/wait_until_disconnected.inc
-- exec echo "restart:--rocksdb_write_disable_wal=0 --rocksdb_default_cf_options=write_buffer_size=64k;target_file_size_base=64k;max_bytes_for_level_base=1m;compression_per_level=kNoCompression;" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- enable_reconnect
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/mysqldump2.test b/storage/rocksdb/mysql-test/rocksdb/t/mysqldump2.test
index ca9eb5d2ecf..4f4f5ed092b 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/mysqldump2.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/mysqldump2.test
@@ -21,7 +21,7 @@ optimize table t1;
#wiping block cache
let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
--exec echo "wait" > $restart_file
---shutdown_server 10
+--shutdown_server
--source include/wait_until_disconnected.inc
-- exec echo "restart:--rocksdb_default_cf_options=write_buffer_size=64k;target_file_size_base=64k;max_bytes_for_level_base=1m;compression_per_level=kNoCompression;disable_auto_compactions=true;level0_stop_writes_trigger=1000 " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- enable_reconnect
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.test b/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.test
index 7a8f4fc7085..50df3f9c102 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.test
@@ -32,7 +32,7 @@ while ($t <= 6) {
# Disable auto compaction so that effects of optimize table are stable
let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
--exec echo "wait" > $restart_file
---shutdown_server 10
+--shutdown_server
--source include/wait_until_disconnected.inc
-- exec echo "restart:--rocksdb_default_cf_options=write_buffer_size=64k;target_file_size_base=64k;max_bytes_for_level_base=1m;compression_per_level=kNoCompression;disable_auto_compactions=true;level0_stop_writes_trigger=1000 " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- enable_reconnect
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/persistent_cache.test b/storage/rocksdb/mysql-test/rocksdb/t/persistent_cache.test
index 03d1d0a60bc..49e5e5c1172 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/persistent_cache.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/persistent_cache.test
@@ -10,7 +10,7 @@ DROP TABLE IF EXISTS t1;
--exec echo "wait" >$_expect_file_name
# restart server with correct parameters
-shutdown_server 10;
+shutdown_server;
--exec echo "restart:--rocksdb_persistent_cache_path=$_cache_file_name --rocksdb_persistent_cache_size_mb=100" >$_expect_file_name
--sleep 5
--enable_reconnect
@@ -28,7 +28,7 @@ select * from t1 where a = 1;
# restart server to re-read cache
--exec echo "wait" >$_expect_file_name
-shutdown_server 10;
+shutdown_server;
--exec echo "restart:--rocksdb_persistent_cache_path=$_cache_file_name --rocksdb_persistent_cache_size_mb=100" >$_expect_file_name
--sleep 5
--enable_reconnect
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/shutdown.test b/storage/rocksdb/mysql-test/rocksdb/t/shutdown.test
index ba625deb514..f76bc9f6153 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/shutdown.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/shutdown.test
@@ -23,7 +23,7 @@ while ($i <= $max) {
# Restart the server
let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
--exec echo "wait" > $restart_file
---shutdown_server 10
+--shutdown_server
--source include/wait_until_disconnected.inc
-- exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- enable_reconnect
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test b/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test
index ec48dc03ec8..e7ab37d2658 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test
@@ -25,7 +25,7 @@ CREATE TABLE t2 (pk int primary key) ENGINE=ROCKSDB PARTITION BY KEY(pk) PARTITI
# Send shutdown to the connected server and give it 10 seconds to die before
# zapping it
-shutdown_server 10;
+shutdown_server;
# Write file to make mysql-test-run.pl start up the server again
--exec echo "restart" >$_expect_file_name
@@ -42,7 +42,7 @@ shutdown_server 10;
# Now shut down again and rename one of the .frm files
--exec echo "wait" >$_expect_file_name
-shutdown_server 10;
+shutdown_server;
# Rename the file
--move_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm.tmp
@@ -70,7 +70,7 @@ shutdown_server 10;
# Now shut down again and rename one the .frm file back and make a copy of it
--exec echo "wait" >$_expect_file_name
-shutdown_server 10;
+shutdown_server;
--remove_file $LOG
# Rename the file
--move_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm.tmp $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm
@@ -92,7 +92,7 @@ shutdown_server 10;
# Shut down an clean up
--exec echo "wait" >$_expect_file_name
-shutdown_server 10;
+shutdown_server;
--remove_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t1_dummy.frm
--exec echo "restart" >$_expect_file_name
--enable_reconnect
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/mdev12179.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/mdev12179.test
index 631d9ca533f..845f155877a 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/mdev12179.test
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/mdev12179.test
@@ -237,7 +237,7 @@ SHOW STATUS LIKE "%transactions%engine";
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
---shutdown_server 30
+--shutdown_server
--source include/wait_until_disconnected.inc
# Restart without binary log.
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_rate_limiter_bytes_per_sec_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_rate_limiter_bytes_per_sec_basic.test
index 8277011831a..743f942af9c 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_rate_limiter_bytes_per_sec_basic.test
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_rate_limiter_bytes_per_sec_basic.test
@@ -13,7 +13,7 @@ SET @@global.rocksdb_rate_limiter_bytes_per_sec = 10000;
# Send shutdown to the connected server and give it 10 seconds to die before
# zapping it
-shutdown_server 10;
+shutdown_server;
# Attempt to restart the server with the rate limiter on
--exec echo "restart:--rocksdb_rate_limiter_bytes_per_sec=10000" >$_expect_file_name
@@ -53,7 +53,7 @@ SET @@global.rocksdb_rate_limiter_bytes_per_sec = -1;
# Restart the server without the rate limiter
--exec echo "wait" >$_expect_file_name
-shutdown_server 10;
+shutdown_server;
--exec echo "restart" >$_expect_file_name
--sleep 5
diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c
index c72fc9b6d00..9b7cea54d00 100644
--- a/strings/ctype-ucs2.c
+++ b/strings/ctype-ucs2.c
@@ -828,7 +828,7 @@ my_strtoll10_mb2(CHARSET_INFO *cs __attribute__((unused)),
const char *nptr, char **endptr, int *error)
{
const uchar *s, *end, *start, *n_end, *true_end;
- uchar c;
+ uchar UNINIT_VAR(c);
unsigned long i, j, k;
ulonglong li;
int negative;
diff --git a/support-files/mariadb@.service.in b/support-files/mariadb@.service.in
index 79f347ec271..14749092103 100644
--- a/support-files/mariadb@.service.in
+++ b/support-files/mariadb@.service.in
@@ -100,7 +100,7 @@
# in configuration between instances.
#
# [Service]
-# Environment=MYSQLD_MULTI_INSTANCE="--socket=/var/run/mysqld/%I.sock \
+# Environment=MYSQLD_MULTI_INSTANCE="--socket=/run/mysqld/%I.sock \
# --datadir=/var/lib/mysqld-multi/%I \
# --skip-networking"
#
diff --git a/support-files/policy/apparmor/usr.sbin.mysqld b/support-files/policy/apparmor/usr.sbin.mysqld
index 18a9c357ff2..c60ecd28531 100644
--- a/support-files/policy/apparmor/usr.sbin.mysqld
+++ b/support-files/policy/apparmor/usr.sbin.mysqld
@@ -54,8 +54,8 @@
/var/log/mysql.log rw,
/var/log/mysql/ r,
/var/log/mysql/* rw,
- /var/run/mysqld/mysqld.pid w,
- /var/run/mysqld/mysqld.sock w,
+ /run/mysqld/mysqld.pid w,
+ /run/mysqld/mysqld.sock w,
profile /bin/dash flags=(complain) {
diff --git a/unittest/mysys/CMakeLists.txt b/unittest/mysys/CMakeLists.txt
index ec4e0b91626..984b033e7aa 100644
--- a/unittest/mysys/CMakeLists.txt
+++ b/unittest/mysys/CMakeLists.txt
@@ -15,7 +15,7 @@
MY_ADD_TESTS(bitmap base64 my_atomic my_rdtsc lf my_malloc my_getopt dynstring
byte_order
- queues LINK_LIBRARIES mysys)
+ queues stacktrace LINK_LIBRARIES mysys)
MY_ADD_TESTS(my_vsnprintf LINK_LIBRARIES strings mysys)
MY_ADD_TESTS(aes LINK_LIBRARIES mysys mysys_ssl)
ADD_DEFINITIONS(${SSL_DEFINES})
diff --git a/unittest/mysys/stacktrace-t.c b/unittest/mysys/stacktrace-t.c
new file mode 100644
index 00000000000..8fa0db15b36
--- /dev/null
+++ b/unittest/mysys/stacktrace-t.c
@@ -0,0 +1,67 @@
+
+/* Copyright (c) 2020, 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 Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#include <my_global.h>
+#include <my_sys.h>
+#include <stdio.h>
+#include <my_stacktrace.h>
+#include <tap.h>
+
+char b_bss[10];
+
+void test_my_safe_print_str()
+{
+ char b_stack[10];
+ char *b_heap= strdup("LEGAL");
+ memcpy(b_stack, "LEGAL", 6);
+ memcpy(b_bss, "LEGAL", 6);
+
+#ifndef __SANITIZE_ADDRESS__
+ fprintf(stderr, "\n===== stack =====\n");
+ my_safe_print_str(b_stack, 65535);
+ fprintf(stderr, "\n===== heap =====\n");
+ my_safe_print_str(b_heap, 65535);
+ fprintf(stderr, "\n===== BSS =====\n");
+ my_safe_print_str(b_bss, 65535);
+ fprintf(stderr, "\n===== data =====\n");
+ my_safe_print_str("LEGAL", 65535);
+ fprintf(stderr, "\n===== Above is a junk, but it is expected. =====\n");
+#endif /*__SANITIZE_ADDRESS__*/
+ fprintf(stderr, "\n===== Nornal length test =====\n");
+ my_safe_print_str("LEGAL", 5);
+ fprintf(stderr, "\n===== NULL =====\n");
+ my_safe_print_str(0, 5);
+#ifndef __SANITIZE_ADDRESS__
+ fprintf(stderr, "\n===== (const char*) 1 =====\n");
+ my_safe_print_str((const char*)1, 5);
+#endif /*__SANITIZE_ADDRESS__*/
+
+ free(b_heap);
+
+ ok(1, "test_my_safe_print_str");
+}
+
+
+int main(int argc __attribute__((unused)), char **argv)
+{
+ MY_INIT(argv[0]);
+ plan(1);
+
+ test_my_safe_print_str();
+
+ my_end(0);
+ return exit_status();
+}
diff --git a/win/packaging/CMakeLists.txt b/win/packaging/CMakeLists.txt
index 2138c9233ad..d11053fa1dd 100644
--- a/win/packaging/CMakeLists.txt
+++ b/win/packaging/CMakeLists.txt
@@ -123,7 +123,7 @@ ELSE()
ENDIF()
SET(CPACK_WIX_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/CPackWixConfig.cmake)
-IF(NOT TARGET mysql_upgrade_wizard)
+IF(NOT TARGET mariadb-upgrade-wizard)
SET(EXTRA_WIX_PREPROCESSOR_FLAGS "-dHaveUpgradeWizard=0")
ENDIF()
IF(WITH_INNOBASE_STORAGE_ENGINE)
diff --git a/win/upgrade_wizard/CMakeLists.txt b/win/upgrade_wizard/CMakeLists.txt
index 5a98ab15d0f..20a06a41215 100644
--- a/win/upgrade_wizard/CMakeLists.txt
+++ b/win/upgrade_wizard/CMakeLists.txt
@@ -35,17 +35,12 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql)
MYSQL_ADD_EXECUTABLE(mariadb-upgrade-wizard
upgrade.cpp upgradeDlg.cpp upgrade.rc ${UPGRADE_WIZARD_SOURCES}
COMPONENT Server)
+
+
TARGET_LINK_LIBRARIES(mariadb-upgrade-wizard ${UPGRADE_WIZARD_LINK_LIBRARIES})
# upgrade_wizard is Windows executable, set WIN32_EXECUTABLE so it does not
# create a console.
-SET_TARGET_PROPERTIES(mariadb-upgrade-wizard PROPERTIES WIN32_EXECUTABLE 1)
-
-# Embed Vista "admin" manifest, since upgrade_wizard needs admin privileges
-# to change service configuration. Due to a CMake bug http://www.vtk.org/Bug/view.php?id=11171
-# it is not possible currenly to do it with linker flags. Work around is to use
-# manifest tool mt.exe and embed the manifest post-build.
-ADD_CUSTOM_COMMAND(
- TARGET mariadb-upgrade-wizard POST_BUILD
- COMMAND mt.exe -manifest ${CMAKE_CURRENT_SOURCE_DIR}/upgrade_wizard.exe.manifest
- "-outputresource:$<TARGET_FILE:mariadb-upgrade-wizard>;#1"
+SET_TARGET_PROPERTIES(mariadb-upgrade-wizard PROPERTIES
+ WIN32_EXECUTABLE 1
+ LINK_FLAGS "/MANIFESTUAC:level='requireAdministrator'"
)