summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-07-02 09:41:44 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-07-02 09:41:44 +0300
commit1813d92d0c505a1c752f4a9d6e37db6bffe4efdd (patch)
treef570314890197949ae55cbbad3a94eb5893c4177
parent0fe97c20b341665058491fca4d665207406775c6 (diff)
parentf347b3e0e6592329b1447fa460aca0a4b1f680b1 (diff)
downloadmariadb-git-1813d92d0c505a1c752f4a9d6e37db6bffe4efdd.tar.gz
Merge 10.4 into 10.5
-rw-r--r--cmake/FindLZ4.cmake6
-rw-r--r--cmake/FindZSTD.cmake (renamed from cmake/Findzstd.cmake)6
-rw-r--r--cmake/configure.pl2
-rw-r--r--cmake/dtrace.cmake3
-rw-r--r--dbug/dbug.c4
-rwxr-xr-xdbug/dbug_add_tags.pl2
-rwxr-xr-xdbug/remove_function_from_trace.pl2
-rwxr-xr-xdebian/additions/mariadb-report2
-rw-r--r--extra/mariabackup/xtrabackup.cc4
-rw-r--r--include/scope.h66
-rwxr-xr-xmysql-test/lib/process-purecov-annotations.pl2
-rwxr-xr-xmysql-test/lib/t/SafeProcessStress.pl2
-rw-r--r--mysql-test/lib/t/copytree.t2
-rw-r--r--mysql-test/lib/t/dummyd.pl2
-rw-r--r--mysql-test/lib/t/rmtree.t2
-rwxr-xr-xmysql-test/lib/t/testMyConfig.t2
-rwxr-xr-xmysql-test/lib/t/testMyConfigFactory.t2
-rwxr-xr-xmysql-test/lib/t/test_child.pl2
-rwxr-xr-xmysql-test/lib/v1/mysql-test-run.pl2
-rw-r--r--mysql-test/main/func_json.result13
-rw-r--r--mysql-test/main/func_json.test13
-rw-r--r--mysql-test/main/information_schema.result10
-rw-r--r--mysql-test/main/information_schema.test12
-rw-r--r--mysql-test/main/join_outer.result31
-rw-r--r--mysql-test/main/join_outer.test35
-rw-r--r--mysql-test/main/join_outer_jcl6.result31
-rw-r--r--mysql-test/main/log_tables.result6
-rw-r--r--mysql-test/main/log_tables.test8
-rw-r--r--mysql-test/main/mysql_install_db_win.result2
-rw-r--r--mysql-test/main/mysql_install_db_win.test24
-rw-r--r--mysql-test/main/nested_profiling.result20
-rw-r--r--mysql-test/main/nested_profiling.test42
-rw-r--r--mysql-test/main/opt_trace.result123
-rw-r--r--mysql-test/main/opt_trace.test29
-rw-r--r--mysql-test/main/subselect4.result31
-rw-r--r--mysql-test/main/subselect4.test27
-rw-r--r--mysql-test/main/temp_table.result18
-rw-r--r--mysql-test/main/temp_table.test19
-rw-r--r--mysql-test/main/win.result10
-rw-r--r--mysql-test/main/win.test13
-rw-r--r--mysql-test/mtr.out-of-source2
-rwxr-xr-xmysql-test/mysql-stress-test.pl2
-rwxr-xr-xmysql-test/mysql-test-run.pl40
-rwxr-xr-xmysql-test/std_data/checkDBI_DBD-MariaDB.pl2
-rwxr-xr-xmysql-test/suite/engines/rr_trx/run_stress_tx_rr.pl2
-rw-r--r--mysql-test/suite/federated/federatedx_create_handlers.result93
-rw-r--r--mysql-test/suite/federated/federatedx_create_handlers.test34
-rwxr-xr-xmysql-test/suite/funcs_1/lib/DataGen_local.pl2
-rwxr-xr-xmysql-test/suite/funcs_1/lib/DataGen_modify.pl2
-rwxr-xr-xmysql-test/suite/funcs_2/lib/gen_charset_utf8.pl2
-rw-r--r--mysql-test/suite/galera/disabled.def2
-rw-r--r--mysql-test/suite/galera/galera_3nodes_as_slave.cnf3
-rw-r--r--mysql-test/suite/galera/r/galera_as_slave_gtid.result1
-rw-r--r--mysql-test/suite/galera/r/galera_as_slave_gtid_auto_engine.result1
-rw-r--r--mysql-test/suite/galera/r/galera_as_slave_gtid_myisam.result3
-rw-r--r--mysql-test/suite/galera/r/galera_var_innodb_disallow_writes.result18
-rw-r--r--mysql-test/suite/galera/r/mysql-wsrep-bugs-607.result31
-rw-r--r--mysql-test/suite/galera/suite.pm1
-rw-r--r--mysql-test/suite/galera/t/MW-388.test2
-rw-r--r--mysql-test/suite/galera/t/MW-86-wait1.test2
-rw-r--r--mysql-test/suite/galera/t/MW-86-wait8.test3
-rw-r--r--mysql-test/suite/galera/t/galera_as_slave_gtid.inc8
-rw-r--r--mysql-test/suite/galera/t/galera_as_slave_gtid_auto_engine.cnf2
-rw-r--r--mysql-test/suite/galera/t/galera_as_slave_gtid_auto_engine.test2
-rw-r--r--mysql-test/suite/galera/t/galera_as_slave_gtid_myisam.test7
-rw-r--r--mysql-test/suite/galera/t/galera_query_cache_sync_wait.test2
-rw-r--r--mysql-test/suite/galera/t/galera_var_cluster_conf_id.test4
-rw-r--r--mysql-test/suite/galera/t/galera_var_innodb_disallow_writes.test24
-rw-r--r--mysql-test/suite/galera/t/galera_var_retry_autocommit.test2
-rw-r--r--mysql-test/suite/galera/t/mysql-wsrep-bugs-607.test70
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_join_with_cc_A.result40
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_join_with_cc_B.result50
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_join_with_cc_C.result55
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_join_with_cc_A.test262
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_join_with_cc_B.test273
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_join_with_cc_C.test299
-rw-r--r--mysql-test/suite/innodb/r/information_schema_grants.result4
-rw-r--r--mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result7
-rw-r--r--mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test8
-rw-r--r--mysql-test/suite/mariabackup/options_check.result1
-rw-r--r--mysql-test/suite/mariabackup/options_check.test7
-rw-r--r--mysql-test/suite/rpl/disabled.def1
-rwxr-xr-xmysql-test/suite/rpl/extension/checksum.pl2
-rw-r--r--mysql-test/suite/rpl/r/rpl_binlog_dump_slave_gtid_state_info.result47
-rw-r--r--mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test121
-rw-r--r--mysql-test/suite/versioning/r/sysvars.result30
-rw-r--r--mysql-test/suite/versioning/t/sysvars.test26
-rw-r--r--plugin/auth_gssapi/CMakeLists.txt6
-rw-r--r--plugin/auth_gssapi/gssapi_server.cc2
-rwxr-xr-xplugin/handler_socket/client/hspool_test.pl2
-rwxr-xr-xplugin/handler_socket/client/hstest.pl2
-rwxr-xr-xplugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test01.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test02.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test03.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test04.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test05.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test06.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test07.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test08.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test09.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test10.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test11.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test12.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test13.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test14.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test15.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test16.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test17.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test18.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test19.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test20.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test21.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test22.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test23.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test24.pl2
-rwxr-xr-xscripts/convert-debug-for-diff.sh2
-rw-r--r--scripts/mytop.sh2
-rw-r--r--sql-bench/as3ap.sh2
-rw-r--r--sql-bench/bench-count-distinct.sh2
-rw-r--r--sql-bench/bench-init.pl.sh2
-rw-r--r--sql-bench/compare-results.sh2
-rw-r--r--sql-bench/copy-db.sh2
-rw-r--r--sql-bench/crash-me.sh2
-rwxr-xr-xsql-bench/graph-compare-results.sh2
-rw-r--r--sql-bench/innotest1.sh2
-rw-r--r--sql-bench/innotest1a.sh2
-rw-r--r--sql-bench/innotest1b.sh2
-rw-r--r--sql-bench/innotest2.sh2
-rw-r--r--sql-bench/innotest2a.sh2
-rw-r--r--sql-bench/innotest2b.sh2
-rw-r--r--sql-bench/run-all-tests.sh2
-rw-r--r--sql-bench/server-cfg.sh2
-rw-r--r--sql-bench/test-ATIS.sh2
-rw-r--r--sql-bench/test-alter-table.sh2
-rw-r--r--sql-bench/test-big-tables.sh2
-rw-r--r--sql-bench/test-connect.sh2
-rw-r--r--sql-bench/test-create.sh2
-rw-r--r--sql-bench/test-insert.sh2
-rw-r--r--sql-bench/test-select.sh2
-rwxr-xr-xsql-bench/test-table-elimination.sh2
-rw-r--r--sql-bench/test-transactions.sh2
-rw-r--r--sql-bench/test-wisconsin.sh2
-rw-r--r--sql/field.cc40
-rw-r--r--sql/field.h1
-rw-r--r--sql/filesort.cc9
-rw-r--r--sql/item_jsonfunc.cc35
-rw-r--r--sql/item_jsonfunc.h1
-rw-r--r--sql/item_subselect.cc2
-rw-r--r--sql/item_windowfunc.cc4
-rw-r--r--sql/mysql_install_db.cc22
-rw-r--r--sql/opt_range.cc129
-rw-r--r--sql/rpl_rli.cc6
-rw-r--r--sql/signal_handler.cc2
-rw-r--r--sql/sql_lex.h4
-rw-r--r--sql/sql_parse.cc8
-rw-r--r--sql/sql_prepare.cc5
-rw-r--r--sql/sql_repl.cc8
-rw-r--r--sql/sql_select.cc54
-rw-r--r--sql/sql_show.cc40
-rw-r--r--sql/sql_table.cc7
-rw-r--r--sql/table.cc2
-rw-r--r--sql/table.h6
-rw-r--r--sql/winservice.c39
-rw-r--r--sql/wsrep_server_service.cc14
-rw-r--r--storage/innobase/btr/btr0cur.cc27
-rw-r--r--storage/innobase/btr/btr0sea.cc1
-rw-r--r--storage/innobase/buf/buf0buddy.cc37
-rw-r--r--storage/innobase/buf/buf0buf.cc17
-rw-r--r--storage/innobase/buf/buf0flu.cc2
-rw-r--r--storage/innobase/buf/buf0lru.cc43
-rw-r--r--storage/innobase/buf/buf0rea.cc2
-rw-r--r--storage/innobase/data/data0data.cc48
-rw-r--r--storage/innobase/dict/dict0stats.cc59
-rw-r--r--storage/innobase/fil/fil0fil.cc35
-rw-r--r--storage/innobase/fsp/fsp0sysspace.cc14
-rw-r--r--storage/innobase/fts/fts0fts.cc46
-rw-r--r--storage/innobase/handler/ha_innodb.cc14
-rw-r--r--storage/innobase/handler/handler0alter.cc1
-rw-r--r--storage/innobase/handler/i_s.cc2
-rw-r--r--storage/innobase/include/buf0buf.h2
-rw-r--r--storage/innobase/include/buf0buf.ic4
-rw-r--r--storage/innobase/include/data0data.ic18
-rw-r--r--storage/innobase/include/dict0stats.ic35
-rw-r--r--storage/innobase/include/fts0fts.h11
-rw-r--r--storage/innobase/include/mem0mem.ic6
-rw-r--r--storage/innobase/include/page0zip.ic2
-rw-r--r--storage/innobase/include/read0types.h4
-rw-r--r--storage/innobase/include/rem0rec.h16
-rw-r--r--storage/innobase/include/rem0rec.ic2
-rw-r--r--storage/innobase/include/srv0mon.h10
-rw-r--r--storage/innobase/include/univ.i60
-rw-r--r--storage/innobase/include/ut0pool.h9
-rw-r--r--storage/innobase/log/log0recv.cc8
-rw-r--r--storage/innobase/mem/mem0mem.cc5
-rw-r--r--storage/innobase/mtr/mtr0mtr.cc6
-rw-r--r--storage/innobase/os/os0proc.cc2
-rw-r--r--storage/innobase/page/page0cur.cc22
-rw-r--r--storage/innobase/page/page0zip.cc124
-rw-r--r--storage/innobase/row/row0ext.cc2
-rw-r--r--storage/innobase/row/row0ftsort.cc10
-rw-r--r--storage/innobase/row/row0ins.cc6
-rw-r--r--storage/innobase/row/row0log.cc40
-rw-r--r--storage/innobase/row/row0merge.cc43
-rw-r--r--storage/innobase/row/row0mysql.cc4
-rw-r--r--storage/innobase/row/row0sel.cc38
-rw-r--r--storage/innobase/row/row0upd.cc4
-rw-r--r--storage/innobase/sync/sync0arr.cc4
-rw-r--r--storage/innobase/trx/trx0trx.cc10
-rw-r--r--storage/innobase/ut/ut0crc32.cc1
-rw-r--r--storage/innobase/ut/ut0ut.cc6
-rwxr-xr-xstorage/myisam/ftbench/Ecompare.pl2
-rwxr-xr-xstorage/myisam/ftbench/Ecreate.pl2
-rwxr-xr-xstorage/myisam/ftbench/Ereport.pl2
-rw-r--r--storage/rocksdb/CMakeLists.txt10
-rw-r--r--storage/rocksdb/build_rocksdb.cmake81
-rwxr-xr-xtests/big_record.pl2
-rwxr-xr-xtests/drop_test.pl2
-rwxr-xr-xtests/export.pl2
-rwxr-xr-xtests/fork2_test.pl2
-rwxr-xr-xtests/fork_big.pl2
-rw-r--r--tests/fork_big2.pl2
-rwxr-xr-xtests/grant.pl2
-rwxr-xr-xtests/index_corrupt.pl2
-rwxr-xr-xtests/insert_and_repair.pl2
-rwxr-xr-xtests/lock_test.pl2
-rwxr-xr-xtests/mail_to_db.pl2
-rw-r--r--tests/mysql_client_test.c56
-rwxr-xr-xtests/pmail.pl2
-rwxr-xr-xtests/rename_test.pl2
-rwxr-xr-xtests/table_types.pl2
-rwxr-xr-xtests/test_delayed_insert.pl2
-rwxr-xr-xtests/truncate.pl2
-rw-r--r--unittest/unit.pl2
234 files changed, 3048 insertions, 789 deletions
diff --git a/cmake/FindLZ4.cmake b/cmake/FindLZ4.cmake
index e97dd63e2b0..46c1fdc1b9f 100644
--- a/cmake/FindLZ4.cmake
+++ b/cmake/FindLZ4.cmake
@@ -1,9 +1,9 @@
find_path(LZ4_INCLUDE_DIR NAMES lz4.h)
-find_library(LZ4_LIBRARY NAMES lz4)
+find_library(LZ4_LIBRARIES NAMES lz4)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(
LZ4 DEFAULT_MSG
- LZ4_LIBRARY LZ4_INCLUDE_DIR)
+ LZ4_LIBRARIES LZ4_INCLUDE_DIR)
-mark_as_advanced(LZ4_INCLUDE_DIR LZ4_LIBRARY)
+mark_as_advanced(LZ4_INCLUDE_DIR LZ4_LIBRARIES)
diff --git a/cmake/Findzstd.cmake b/cmake/FindZSTD.cmake
index 8cd4c248145..ede59010742 100644
--- a/cmake/Findzstd.cmake
+++ b/cmake/FindZSTD.cmake
@@ -5,10 +5,6 @@
# ZSTD_LIBRARIES - List of libraries when using zstd.
# ZSTD_FOUND - True if zstd found.
-if (DEFINED ZSTD_LIBRARIES)
- return()
-endif()
-
find_path(ZSTD_INCLUDE_DIR
NAMES zstd.h
HINTS ${ZSTD_ROOT_DIR}/include)
@@ -18,7 +14,7 @@ find_library(ZSTD_LIBRARIES
HINTS ${ZSTD_ROOT_DIR}/lib)
include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(zstd DEFAULT_MSG ZSTD_LIBRARIES ZSTD_INCLUDE_DIR)
+find_package_handle_standard_args(ZSTD DEFAULT_MSG ZSTD_LIBRARIES ZSTD_INCLUDE_DIR)
mark_as_advanced(
ZSTD_LIBRARIES
diff --git a/cmake/configure.pl b/cmake/configure.pl
index a63ce5a483e..c296c5ba4b8 100644
--- a/cmake/configure.pl
+++ b/cmake/configure.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
#
diff --git a/cmake/dtrace.cmake b/cmake/dtrace.cmake
index 1e29ba685e0..dae3b56b584 100644
--- a/cmake/dtrace.cmake
+++ b/cmake/dtrace.cmake
@@ -43,7 +43,8 @@ MACRO(CHECK_DTRACE)
IF(DTRACE AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD"
AND NOT BUGGY_GCC_NO_DTRACE_MODULES
AND NOT BUGGY_LINUX_DTRACE
- AND NOT CMAKE_SYSTEM_NAME MATCHES "SunOS")
+ AND NOT CMAKE_SYSTEM_NAME MATCHES "SunOS"
+ AND NOT WIN32)
SET(ENABLE_DTRACE ON CACHE BOOL "Enable dtrace")
ENDIF()
# On GNU/Hurd, dtrace is not supported
diff --git a/dbug/dbug.c b/dbug/dbug.c
index 847a8cc2b5d..011b932a721 100644
--- a/dbug/dbug.c
+++ b/dbug/dbug.c
@@ -490,6 +490,7 @@ static int DbugParse(CODE_STATE *cs, const char *control)
rel= control[0] == '+' || control[0] == '-';
if ((!rel || (!stack->out_file && !stack->next)))
{
+ LockIfInitSettings(cs);
FreeState(cs, 0);
stack->flags= 0;
stack->delay= 0;
@@ -497,10 +498,9 @@ static int DbugParse(CODE_STATE *cs, const char *control)
stack->sub_level= 0;
stack->out_file= sstderr;
stack->functions= NULL;
- LockIfInitSettings(cs);
stack->keywords= NULL;
- UnlockIfInitSettings(cs);
stack->processes= NULL;
+ UnlockIfInitSettings(cs);
}
else if (!stack->out_file)
{
diff --git a/dbug/dbug_add_tags.pl b/dbug/dbug_add_tags.pl
index 7be8fb9b18d..f117bdcd65b 100755
--- a/dbug/dbug_add_tags.pl
+++ b/dbug/dbug_add_tags.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2002 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
diff --git a/dbug/remove_function_from_trace.pl b/dbug/remove_function_from_trace.pl
index 380df168caf..67d7fa54b6a 100755
--- a/dbug/remove_function_from_trace.pl
+++ b/dbug/remove_function_from_trace.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
die <<EEE unless @ARGV;
Usage: $0 func1 [func2 [ ...] ]
diff --git a/debian/additions/mariadb-report b/debian/additions/mariadb-report
index 870c13497e3..cf5f4ae2d6b 100755
--- a/debian/additions/mariadb-report
+++ b/debian/additions/mariadb-report
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl -w
# mariadb-report v4.0 Oct 23 2015
# renamed to from mysqlreport in 2020
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index faf2d6147a0..f4c793fc1d8 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -119,7 +119,7 @@ my_bool xtrabackup_move_back;
my_bool xtrabackup_decrypt_decompress;
my_bool xtrabackup_print_param;
my_bool xtrabackup_mysqld_args;
-my_bool help;
+my_bool xtrabackup_help;
my_bool xtrabackup_export;
@@ -1418,7 +1418,7 @@ struct my_option xb_server_options[] =
{"help", '?',
"Display this help and exit.",
- (G_PTR *) &help, (G_PTR *) &help, 0,
+ (G_PTR *) &xtrabackup_help, (G_PTR *) &xtrabackup_help, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
diff --git a/include/scope.h b/include/scope.h
new file mode 100644
index 00000000000..b9e2e96ae5c
--- /dev/null
+++ b/include/scope.h
@@ -0,0 +1,66 @@
+/*
+ Copyright (c) 2020, MariaDB
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by 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 St, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+#pragma once
+
+#include <type_traits>
+#include <utility>
+
+namespace detail
+{
+
+template <typename Callable> class scope_exit
+{
+public:
+ template <typename F>
+ explicit scope_exit(F &&f) : function_(std::forward<F>(f))
+ {
+ }
+
+ scope_exit(scope_exit &&rhs)
+ : function_(std::move(rhs.function_)), engaged_(rhs.engaged_)
+ {
+ rhs.release();
+ }
+
+ scope_exit(const scope_exit &)= delete;
+ scope_exit &operator=(scope_exit &&)= delete;
+ scope_exit &operator=(const scope_exit &)= delete;
+
+ void release() { engaged_= false; }
+
+ ~scope_exit()
+ {
+ if (engaged_)
+ function_();
+ }
+
+private:
+ Callable function_;
+ bool engaged_= true;
+};
+
+} // end namespace detail
+
+template <typename Callable>
+detail::scope_exit<typename std::decay<Callable>::type>
+make_scope_exit(Callable &&f)
+{
+ return detail::scope_exit<typename std::decay<Callable>::type>(
+ std::forward<Callable>(f));
+}
diff --git a/mysql-test/lib/process-purecov-annotations.pl b/mysql-test/lib/process-purecov-annotations.pl
index d533bd02fd6..4381aae4c64 100755
--- a/mysql-test/lib/process-purecov-annotations.pl
+++ b/mysql-test/lib/process-purecov-annotations.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# This script processes a .gcov coverage report to honor purecov
diff --git a/mysql-test/lib/t/SafeProcessStress.pl b/mysql-test/lib/t/SafeProcessStress.pl
index f591e9665dd..352b956d803 100755
--- a/mysql-test/lib/t/SafeProcessStress.pl
+++ b/mysql-test/lib/t/SafeProcessStress.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2007, 2008 MySQL AB
diff --git a/mysql-test/lib/t/copytree.t b/mysql-test/lib/t/copytree.t
index 15a41081b24..76a3d644751 100644
--- a/mysql-test/lib/t/copytree.t
+++ b/mysql-test/lib/t/copytree.t
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2007 MySQL AB
diff --git a/mysql-test/lib/t/dummyd.pl b/mysql-test/lib/t/dummyd.pl
index 15164428b95..e78648cfacf 100644
--- a/mysql-test/lib/t/dummyd.pl
+++ b/mysql-test/lib/t/dummyd.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2007 MySQL AB
diff --git a/mysql-test/lib/t/rmtree.t b/mysql-test/lib/t/rmtree.t
index 40c9e96eabd..033bc59ad21 100644
--- a/mysql-test/lib/t/rmtree.t
+++ b/mysql-test/lib/t/rmtree.t
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2007 MySQL AB
diff --git a/mysql-test/lib/t/testMyConfig.t b/mysql-test/lib/t/testMyConfig.t
index cd0a3a41b7a..99647c14ba1 100755
--- a/mysql-test/lib/t/testMyConfig.t
+++ b/mysql-test/lib/t/testMyConfig.t
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2007 MySQL AB
diff --git a/mysql-test/lib/t/testMyConfigFactory.t b/mysql-test/lib/t/testMyConfigFactory.t
index f38f660e85a..5ba63b3d823 100755
--- a/mysql-test/lib/t/testMyConfigFactory.t
+++ b/mysql-test/lib/t/testMyConfigFactory.t
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2007 MySQL AB, 2009 Sun Microsystems, Inc.
diff --git a/mysql-test/lib/t/test_child.pl b/mysql-test/lib/t/test_child.pl
index efbec4a9620..8a23c3d7541 100755
--- a/mysql-test/lib/t/test_child.pl
+++ b/mysql-test/lib/t/test_child.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2007 MySQL AB
diff --git a/mysql-test/lib/v1/mysql-test-run.pl b/mysql-test/lib/v1/mysql-test-run.pl
index f10a0378d88..6b419aff3bf 100755
--- a/mysql-test/lib/v1/mysql-test-run.pl
+++ b/mysql-test/lib/v1/mysql-test-run.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result
index cffaf9702be..523048ccb7a 100644
--- a/mysql-test/main/func_json.result
+++ b/mysql-test/main/func_json.result
@@ -916,6 +916,19 @@ NULL
Warnings:
Warning 4037 Unexpected end of JSON text in argument 2 to function 'json_merge_patch'
#
+# MDEV-22976 CAST(JSON_EXTRACT() AS DECIMAL) does not handle boolean values
+#
+SELECT
+CAST(JSON_EXTRACT('{"x":true}', '$.x') AS DOUBLE) AS cf,
+CAST(JSON_EXTRACT('{"x":true}', '$.x') AS DECIMAL) AS cd;
+cf cd
+1 1
+SELECT
+CAST(JSON_EXTRACT('{"x":false}', '$.x') AS DOUBLE) AS cf,
+CAST(JSON_EXTRACT('{"x":false}', '$.x') AS DECIMAL) AS cd;
+cf cd
+0 0
+#
# End of 10.2 tests
#
#
diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test
index 366a91e0cfd..68d381f5c07 100644
--- a/mysql-test/main/func_json.test
+++ b/mysql-test/main/func_json.test
@@ -538,6 +538,19 @@ SELECT JSON_MERGE_PATCH('{', '[1,2,3]');
SELECT JSON_MERGE_PATCH('{"a":"b"}', '[1,');
--echo #
+--echo # MDEV-22976 CAST(JSON_EXTRACT() AS DECIMAL) does not handle boolean values
+--echo #
+
+SELECT
+ CAST(JSON_EXTRACT('{"x":true}', '$.x') AS DOUBLE) AS cf,
+ CAST(JSON_EXTRACT('{"x":true}', '$.x') AS DECIMAL) AS cd;
+
+SELECT
+ CAST(JSON_EXTRACT('{"x":false}', '$.x') AS DOUBLE) AS cf,
+ CAST(JSON_EXTRACT('{"x":false}', '$.x') AS DECIMAL) AS cd;
+
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/main/information_schema.result b/mysql-test/main/information_schema.result
index b977af22209..1e1f66e377c 100644
--- a/mysql-test/main/information_schema.result
+++ b/mysql-test/main/information_schema.result
@@ -2209,3 +2209,13 @@ column_name
c1
c2
DROP TABLE tt1, tt2;
+#
+# MDEV-13242 Wrong results for queries with row constructors and information_schema
+#
+SELECT SCHEMA_NAME from information_schema.schemata where schema_name='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
+SCHEMA_NAME
+SELECT SCHEMA_NAME from information_schema.schemata where schema_name=REPEAT('a',193);
+SCHEMA_NAME
+#
+# End of 10.1 tests
+#
diff --git a/mysql-test/main/information_schema.test b/mysql-test/main/information_schema.test
index 9389c8bc43c..1df0d3f635f 100644
--- a/mysql-test/main/information_schema.test
+++ b/mysql-test/main/information_schema.test
@@ -1908,3 +1908,15 @@ SELECT count(*) FROM information_schema.columns WHERE table_schema='test' AND (t
SELECT count(*) FROM information_schema.columns WHERE table_schema='test' AND (table_name='tt1' AND column_name='c1') OR (table_name='tt2' AND column_name='c2');
SELECT column_name FROM information_schema.columns WHERE (table_name, column_name) IN (('tt1','c1'),('tt2', 'c2')) ORDER BY column_name;
DROP TABLE tt1, tt2;
+
+--echo #
+--echo # MDEV-13242 Wrong results for queries with row constructors and information_schema
+--echo #
+
+SELECT SCHEMA_NAME from information_schema.schemata where schema_name='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
+SELECT SCHEMA_NAME from information_schema.schemata where schema_name=REPEAT('a',193);
+
+
+--echo #
+--echo # End of 10.1 tests
+--echo #
diff --git a/mysql-test/main/join_outer.result b/mysql-test/main/join_outer.result
index 12f776d47c7..e882973043e 100644
--- a/mysql-test/main/join_outer.result
+++ b/mysql-test/main/join_outer.result
@@ -2755,3 +2755,34 @@ WHERE t3.pk IN (2);
drop view v4;
drop table t1,t2,t3,t4;
SET optimizer_switch=@org_optimizer_switch;
+#
+# MDEV-22866: Crash in join optimizer with constant outer join nest
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (c INT, KEY(c)) ENGINE=MyISAM;
+CREATE TABLE t4 (d INT, KEY(d)) ENGINE=MyISAM;
+INSERT INTO t4 VALUES (5),(6);
+CREATE TABLE t5 (e INT) ENGINE=MyISAM;
+INSERT INTO t5 VALUES (7),(8);
+CREATE TABLE t6 (f INT) ENGINE=MyISAM;
+INSERT INTO t6 VALUES (9),(10);
+SELECT *
+FROM
+t1
+LEFT JOIN (
+t2 LEFT JOIN (
+t3 JOIN
+t4 ON t3.c = t4.d and t3.c >2 and t3.c<0
+) ON t2.b >= t4.d
+) ON t1.a <= t2.b
+LEFT JOIN t5 ON t2.b = t5.e
+LEFT JOIN t6 ON t3.c = t6.f;
+a b c d e f
+1 3 NULL NULL NULL NULL
+2 3 NULL NULL NULL NULL
+1 4 NULL NULL NULL NULL
+2 4 NULL NULL NULL NULL
+drop table t1,t2,t3,t4,t5,t6;
diff --git a/mysql-test/main/join_outer.test b/mysql-test/main/join_outer.test
index 2e5fc65ebb6..f835d8af5a8 100644
--- a/mysql-test/main/join_outer.test
+++ b/mysql-test/main/join_outer.test
@@ -2252,3 +2252,38 @@ drop view v4;
drop table t1,t2,t3,t4;
SET optimizer_switch=@org_optimizer_switch;
+
+--echo #
+--echo # MDEV-22866: Crash in join optimizer with constant outer join nest
+--echo #
+
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (3),(4);
+
+CREATE TABLE t3 (c INT, KEY(c)) ENGINE=MyISAM;
+
+CREATE TABLE t4 (d INT, KEY(d)) ENGINE=MyISAM;
+INSERT INTO t4 VALUES (5),(6);
+
+CREATE TABLE t5 (e INT) ENGINE=MyISAM;
+INSERT INTO t5 VALUES (7),(8);
+
+CREATE TABLE t6 (f INT) ENGINE=MyISAM;
+INSERT INTO t6 VALUES (9),(10);
+
+SELECT *
+FROM
+ t1
+ LEFT JOIN (
+ t2 LEFT JOIN (
+ t3 JOIN
+ t4 ON t3.c = t4.d and t3.c >2 and t3.c<0
+ ) ON t2.b >= t4.d
+ ) ON t1.a <= t2.b
+ LEFT JOIN t5 ON t2.b = t5.e
+ LEFT JOIN t6 ON t3.c = t6.f;
+
+drop table t1,t2,t3,t4,t5,t6;
diff --git a/mysql-test/main/join_outer_jcl6.result b/mysql-test/main/join_outer_jcl6.result
index 6d4a0284e5a..9cbfa5d0fe5 100644
--- a/mysql-test/main/join_outer_jcl6.result
+++ b/mysql-test/main/join_outer_jcl6.result
@@ -2762,3 +2762,34 @@ WHERE t3.pk IN (2);
drop view v4;
drop table t1,t2,t3,t4;
SET optimizer_switch=@org_optimizer_switch;
+#
+# MDEV-22866: Crash in join optimizer with constant outer join nest
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (c INT, KEY(c)) ENGINE=MyISAM;
+CREATE TABLE t4 (d INT, KEY(d)) ENGINE=MyISAM;
+INSERT INTO t4 VALUES (5),(6);
+CREATE TABLE t5 (e INT) ENGINE=MyISAM;
+INSERT INTO t5 VALUES (7),(8);
+CREATE TABLE t6 (f INT) ENGINE=MyISAM;
+INSERT INTO t6 VALUES (9),(10);
+SELECT *
+FROM
+t1
+LEFT JOIN (
+t2 LEFT JOIN (
+t3 JOIN
+t4 ON t3.c = t4.d and t3.c >2 and t3.c<0
+) ON t2.b >= t4.d
+) ON t1.a <= t2.b
+LEFT JOIN t5 ON t2.b = t5.e
+LEFT JOIN t6 ON t3.c = t6.f;
+a b c d e f
+1 3 NULL NULL NULL NULL
+2 3 NULL NULL NULL NULL
+1 4 NULL NULL NULL NULL
+2 4 NULL NULL NULL NULL
+drop table t1,t2,t3,t4,t5,t6;
diff --git a/mysql-test/main/log_tables.result b/mysql-test/main/log_tables.result
index 43f44c90b06..90c97f629fb 100644
--- a/mysql-test/main/log_tables.result
+++ b/mysql-test/main/log_tables.result
@@ -259,6 +259,12 @@ Warning 1286 Unknown storage engine 'NonExistentEngine'
alter table mysql.slow_log engine=memory;
ERROR HY000: Storage engine MEMORY cannot be used for log tables
set default_storage_engine= @save_storage_engine;
+ALTER TABLE mysql.general_log ENGINE=Aria;
+ERROR HY000: Storage engine Aria cannot be used for log tables
+ALTER TABLE mysql.general_log ENGINE=Aria transactional = 0;
+ALTER TABLE mysql.slow_log ENGINE=Aria;
+ERROR HY000: Storage engine Aria cannot be used for log tables
+ALTER TABLE mysql.slow_log ENGINE=Aria transactional = 0;
drop table mysql.slow_log;
drop table mysql.general_log;
drop table mysql.general_log;
diff --git a/mysql-test/main/log_tables.test b/mysql-test/main/log_tables.test
index 4622b09079f..ff2a46b1917 100644
--- a/mysql-test/main/log_tables.test
+++ b/mysql-test/main/log_tables.test
@@ -269,6 +269,14 @@ alter table mysql.slow_log engine=memory;
#alter table mysql.slow_log engine=blackhole;
set default_storage_engine= @save_storage_engine;
+# Make sure only non-transactional Aria table can be used for logging
+--error ER_UNSUPORTED_LOG_ENGINE
+ALTER TABLE mysql.general_log ENGINE=Aria;
+ALTER TABLE mysql.general_log ENGINE=Aria transactional = 0;
+--error ER_UNSUPORTED_LOG_ENGINE
+ALTER TABLE mysql.slow_log ENGINE=Aria;
+ALTER TABLE mysql.slow_log ENGINE=Aria transactional = 0;
+
drop table mysql.slow_log;
drop table mysql.general_log;
diff --git a/mysql-test/main/mysql_install_db_win.result b/mysql-test/main/mysql_install_db_win.result
index 950ff868035..31336847a38 100644
--- a/mysql-test/main/mysql_install_db_win.result
+++ b/mysql-test/main/mysql_install_db_win.result
@@ -11,5 +11,7 @@ SELECT @@datadir;
@@datadir
DATADIR/
# Kill the server
+1
+FOUND 1 /is not empty. Only new or empty existing directories are accepted for --datadir/ in install.log
connection default;
# restart
diff --git a/mysql-test/main/mysql_install_db_win.test b/mysql-test/main/mysql_install_db_win.test
index 7bf62903219..3f0256e860e 100644
--- a/mysql-test/main/mysql_install_db_win.test
+++ b/mysql-test/main/mysql_install_db_win.test
@@ -18,6 +18,30 @@ SELECT @@datadir;
# restart in the original datadir again
--source include/kill_mysqld.inc
rmdir $ddir;
+
+# MDEV-23052
+# 1. mysql_install_db works on existing, empty directory
+mkdir $ddir;
+exec $MYSQL_INSTALL_DB_EXE --datadir=$ddir --password=foo -R > /dev/null;
+rmdir $ddir;
+
+# 2. mysql_install_db rejects existing, non-empty directory, and does not
+# remove it.
+mkdir $ddir;
+write_file $ddir/1;
+EOF
+
+error 1;
+exec $MYSQL_INSTALL_DB_EXE --datadir=$ddir --password=foo -R > $MYSQLTEST_VARDIR/tmp/install.log 2>&1;
+list_files $ddir;
+let $log=$MYSQLTEST_VARDIR/tmp/install.log;
+let SEARCH_FILE=$log;
+let SEARCH_PATTERN=is not empty. Only new or empty existing directories are accepted for --datadir;
+--source include/search_pattern_in_file.inc
+remove_file $log;
+
+rmdir $ddir;
+
let $restart_parameters=;
connection default;
--source include/start_mysqld.inc
diff --git a/mysql-test/main/nested_profiling.result b/mysql-test/main/nested_profiling.result
new file mode 100644
index 00000000000..b8bceba480a
--- /dev/null
+++ b/mysql-test/main/nested_profiling.result
@@ -0,0 +1,20 @@
+SET @saved_profiling=@@GLOBAL.profiling;
+SET @saved_init_connect=@@GLOBAL.init_connect;
+SET GLOBAL init_connect="set @a=2;set @b=3";
+SET GLOBAL profiling=on;
+create user mysqltest1@localhost;
+connect con1,localhost,mysqltest1,,;
+connection con1;
+SELECT @a, @b;
+@a @b
+2 3
+SHOW PROFILES;
+Query_ID Duration Query
+1 # set @a=2;set @b=3
+2 # set @b=3
+3 # SELECT @a, @b
+connection default;
+disconnect con1;
+DROP USER mysqltest1@localhost;
+SET GLOBAL profiling=@saved_profiling;
+SET GLOBAL init_connect=@saved_init_connect;
diff --git a/mysql-test/main/nested_profiling.test b/mysql-test/main/nested_profiling.test
new file mode 100644
index 00000000000..ba89aefc647
--- /dev/null
+++ b/mysql-test/main/nested_profiling.test
@@ -0,0 +1,42 @@
+# ==== Purpose ====
+#
+# Test verifies that "init_connect" and "init_slave" system variables work
+# fine when "profiling=on".
+#
+# ==== Implementation ====
+#
+# Steps:
+# 0 - Create regular user without super privilege so that "init_connect"
+# variable is effective.
+# 1 - Enable profiling.
+# 2 - Start a new connection which will try to execute the statements
+# specified in "init_connect". No assert should be reported.
+# 3 - Execute SHOW PROFILES to verify that statements specified in
+# "init_connect" are displayed as part of profiling.
+#
+# ==== References ====
+#
+# MDEV-22706: Assertion `!current' failed in PROFILING::start_new_query
+#
+--source include/not_embedded.inc
+--source include/have_profiling.inc
+
+SET @saved_profiling=@@GLOBAL.profiling;
+SET @saved_init_connect=@@GLOBAL.init_connect;
+SET GLOBAL init_connect="set @a=2;set @b=3";
+SET GLOBAL profiling=on;
+
+create user mysqltest1@localhost;
+connect (con1,localhost,mysqltest1,,);
+connection con1;
+SELECT @a, @b;
+--replace_column 2 #
+SHOW PROFILES;
+
+#========== Clean up ===========
+connection default;
+disconnect con1;
+DROP USER mysqltest1@localhost;
+
+SET GLOBAL profiling=@saved_profiling;
+SET GLOBAL init_connect=@saved_init_connect;
diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result
index 6af1c2afe9e..b0b6120e271 100644
--- a/mysql-test/main/opt_trace.result
+++ b/mysql-test/main/opt_trace.result
@@ -108,6 +108,7 @@ select * from v1 {
"selectivity_for_columns": [
{
"column_name": "a",
+ "ranges": ["1 <= a <= 1"],
"selectivity_from_histogram": 0.5
}
],
@@ -253,6 +254,7 @@ select * from (select * from t1 where t1.a=1)q {
"selectivity_for_columns": [
{
"column_name": "a",
+ "ranges": ["1 <= a <= 1"],
"selectivity_from_histogram": 0.5
}
],
@@ -403,6 +405,7 @@ select * from v2 {
"selectivity_for_columns": [
{
"column_name": "a",
+ "ranges": ["1 <= a <= 1"],
"selectivity_from_histogram": 0.5
}
],
@@ -2059,10 +2062,12 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 {
"selectivity_for_columns": [
{
"column_name": "a",
+ "ranges": ["1 <= a <= 1"],
"selectivity_from_histogram": 0.1796875
},
{
"column_name": "b",
+ "ranges": ["2 <= b <= 2"],
"selectivity_from_histogram": 0.015625
}
],
@@ -3277,10 +3282,12 @@ explain select * from t1 where pk = 2 and a=5 and b=1 {
"selectivity_for_columns": [
{
"column_name": "a",
+ "ranges": ["5 <= a <= 5"],
"selectivity_from_histogram": 0.1
},
{
"column_name": "b",
+ "ranges": ["1 <= b <= 1"],
"selectivity_from_histogram": 0.1
}
],
@@ -8431,6 +8438,122 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans'))
]
]
DROP TABLE t1,t2;
+#
+# MDEV-22665: Print ranges in the optimizer trace created for non-indexed columns when
+# optimizer_use_condition_selectivity >2
+#
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 SELECT seq, seq from seq_1_to_100;
+SET optimizer_trace=1;
+ANALYZE TABLE t1 PERSISTENT FOR ALL;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+EXPLAIN EXTENDED SELECT * from t1 WHERE a between 1 and 5 and b <= 5;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 100 0.22 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where `test`.`t1`.`a` between 1 and 5 and `test`.`t1`.`b` <= 5
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_columns')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_columns'))
+[
+
+ [
+
+ {
+ "column_name": "a",
+ "ranges":
+ [
+ "1 <= a <= 5"
+ ],
+ "selectivity_from_histogram": 0.046875
+ },
+
+ {
+ "column_name": "b",
+ "ranges":
+ [
+ "NULL < b <= 5"
+ ],
+ "selectivity_from_histogram": 0.046875
+ }
+ ]
+]
+EXPLAIN EXTENDED SELECT * from t1 WHERE a != 5;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 100 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where `test`.`t1`.`a` <> 5
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_columns')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_columns'))
+[
+
+ [
+
+ {
+ "column_name": "a",
+ "ranges":
+ [
+ "NULL < a < 5",
+ "5 < a"
+ ],
+ "selectivity_from_histogram": 1
+ }
+ ]
+]
+EXPLAIN EXTENDED SELECT * from t1 WHERE b >= 10 and b < 25;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 100 15.62 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where `test`.`t1`.`b` >= 10 and `test`.`t1`.`b` < 25
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_columns')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_columns'))
+[
+
+ [
+
+ {
+ "column_name": "b",
+ "ranges":
+ [
+ "10 <= b < 25"
+ ],
+ "selectivity_from_histogram": 0.15625
+ }
+ ]
+]
+drop table t1;
+#
+# MDEV-22910:SIGSEGV in Opt_trace_context::is_started & SIGSEGV in Json_writer::add_table_name
+# (on optimized builds)
+#
+CREATE TABLE t1( a INT, b INT, PRIMARY KEY( a ) );
+SELECT sum(b), row_number() OVER (order by b) FROM t1 WHERE a = 101;
+sum(b) row_number() OVER (order by b)
+NULL 1
+UPDATE t1 SET b=10 WHERE a=1;
+SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.range_scan_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+JSON_DETAILED(JSON_EXTRACT(trace, '$**.range_scan_alternatives'))
+[
+
+ [
+
+ {
+ "index": "PRIMARY",
+ "ranges":
+ [
+ "(1) <= (a) <= (1)"
+ ],
+ "rowid_ordered": true,
+ "using_mrr": false,
+ "index_only": false,
+ "rows": 0,
+ "cost": 0.145,
+ "chosen": true
+ }
+ ]
+]
+DROP TABLE t1;
# End of 10.4 tests
#
# Test many rows to see output of big cost numbers
diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test
index f7f19e38eac..d6030543313 100644
--- a/mysql-test/main/opt_trace.test
+++ b/mysql-test/main/opt_trace.test
@@ -594,8 +594,35 @@ EXPLAIN SELECT * FROM t1, t2 WHERE t1.a=t2.a ORDER BY t2.b;
select JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
DROP TABLE t1,t2;
---echo # End of 10.4 tests
+--echo #
+--echo # MDEV-22665: Print ranges in the optimizer trace created for non-indexed columns when
+--echo # optimizer_use_condition_selectivity >2
+--echo #
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 SELECT seq, seq from seq_1_to_100;
+SET optimizer_trace=1;
+ANALYZE TABLE t1 PERSISTENT FOR ALL;
+EXPLAIN EXTENDED SELECT * from t1 WHERE a between 1 and 5 and b <= 5;
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_columns')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+EXPLAIN EXTENDED SELECT * from t1 WHERE a != 5;
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_columns')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+EXPLAIN EXTENDED SELECT * from t1 WHERE b >= 10 and b < 25;
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_columns')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+drop table t1;
+
+--echo #
+--echo # MDEV-22910:SIGSEGV in Opt_trace_context::is_started & SIGSEGV in Json_writer::add_table_name
+--echo # (on optimized builds)
+--echo #
+
+CREATE TABLE t1( a INT, b INT, PRIMARY KEY( a ) );
+SELECT sum(b), row_number() OVER (order by b) FROM t1 WHERE a = 101;
+UPDATE t1 SET b=10 WHERE a=1;
+SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.range_scan_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+DROP TABLE t1;
+
+--echo # End of 10.4 tests
--echo #
--echo # Test many rows to see output of big cost numbers
diff --git a/mysql-test/main/subselect4.result b/mysql-test/main/subselect4.result
index 0240cbaf3f4..51194717676 100644
--- a/mysql-test/main/subselect4.result
+++ b/mysql-test/main/subselect4.result
@@ -2567,6 +2567,37 @@ sum(a) a b
6 1 1
DROP TABLE t1,t2;
#
+# MDEV-17606: Query returns wrong results (while using CHARACTER SET utf8)
+#
+CREATE TABLE t1(l1 varchar(10), i2 int);
+INSERT INTO t1 VALUES ('e',2),('o',6),('x',4);
+CREATE TABLE t2 (v1 varchar(10) CHARACTER SET utf8, KEY v1 (v1(3)));
+INSERT INTO t2 VALUES ('k'),('rid'),('f'),('x');
+EXPLAIN EXTENDED SELECT * FROM t1 where ( t1.l1 < ANY (SELECT MAX(t2.v1) FROM t2));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`l1` AS `l1`,`test`.`t1`.`i2` AS `i2` from `test`.`t1` where <nop>(<in_optimizer>(`test`.`t1`.`l1`,<max>(/* select#2 */ select max(`test`.`t2`.`v1`) from `test`.`t2`) > convert(<cache>(`test`.`t1`.`l1`) using utf8)))
+SELECT * FROM t1 where ( t1.l1 < ANY (SELECT MAX(t2.v1) FROM t2));
+l1 i2
+e 2
+o 6
+DROP TABLE t1, t2;
+#
+# MDEV-22852: SIGSEGV in sortlength (optimized builds)
+#
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='subquery_cache=off';
+CREATE TABLE t1 (a INT,b INT);
+INSERT INTO t1 VALUES (0,0),(0,0);
+SELECT (SELECT DISTINCT t1i.b FROM t1 t1i GROUP BY t1i.a ORDER BY MAX(t1o.b)) FROM t1 AS t1o;
+(SELECT DISTINCT t1i.b FROM t1 t1i GROUP BY t1i.a ORDER BY MAX(t1o.b))
+0
+SET @@optimizer_switch= @save_optimizer_switch;
+DROP TABLE t1;
+# End of 10.2 tests
+#
# MDEV-19134: EXISTS() slower if ORDER BY is defined
#
create table t0 (a int);
diff --git a/mysql-test/main/subselect4.test b/mysql-test/main/subselect4.test
index 6dc8736b64c..36490c340e1 100644
--- a/mysql-test/main/subselect4.test
+++ b/mysql-test/main/subselect4.test
@@ -2103,6 +2103,33 @@ eval $query;
DROP TABLE t1,t2;
--echo #
+--echo # MDEV-17606: Query returns wrong results (while using CHARACTER SET utf8)
+--echo #
+
+CREATE TABLE t1(l1 varchar(10), i2 int);
+INSERT INTO t1 VALUES ('e',2),('o',6),('x',4);
+CREATE TABLE t2 (v1 varchar(10) CHARACTER SET utf8, KEY v1 (v1(3)));
+INSERT INTO t2 VALUES ('k'),('rid'),('f'),('x');
+
+EXPLAIN EXTENDED SELECT * FROM t1 where ( t1.l1 < ANY (SELECT MAX(t2.v1) FROM t2));
+SELECT * FROM t1 where ( t1.l1 < ANY (SELECT MAX(t2.v1) FROM t2));
+DROP TABLE t1, t2;
+
+--echo #
+--echo # MDEV-22852: SIGSEGV in sortlength (optimized builds)
+--echo #
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='subquery_cache=off';
+CREATE TABLE t1 (a INT,b INT);
+INSERT INTO t1 VALUES (0,0),(0,0);
+SELECT (SELECT DISTINCT t1i.b FROM t1 t1i GROUP BY t1i.a ORDER BY MAX(t1o.b)) FROM t1 AS t1o;
+SET @@optimizer_switch= @save_optimizer_switch;
+DROP TABLE t1;
+
+--echo # End of 10.2 tests
+
+--echo #
--echo # MDEV-19134: EXISTS() slower if ORDER BY is defined
--echo #
create table t0 (a int);
diff --git a/mysql-test/main/temp_table.result b/mysql-test/main/temp_table.result
index 69f3b8e5155..293b6d5cd77 100644
--- a/mysql-test/main/temp_table.result
+++ b/mysql-test/main/temp_table.result
@@ -584,3 +584,21 @@ ALTER TABLE t1 CHANGE no_such_col1 col1 BIGINT NULL;
ERROR 42S22: Unknown column 'no_such_col1' in 't1'
TRUNCATE TABLE t1;
DROP TEMPORARY TABLE t1;
+#
+# MDEV-21695 Server crashes in TABLE::evaluate_update_default_function upon UPDATE on temporary table
+#
+SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30');
+CREATE TEMPORARY TABLE t1 (a DATETIME ON UPDATE CURRENT_TIMESTAMP);
+ALTER TABLE t1 ADD b INT;
+INSERT INTO t1 (b) VALUES (1),(2);
+ALTER TABLE t1 CHANGE COLUMN x xx INT;
+ERROR 42S22: Unknown column 'x' in 't1'
+UPDATE t1 SET b = 3;
+SELECT * FROM t1;
+a b
+2001-01-01 10:20:30 3
+2001-01-01 10:20:30 3
+DROP TEMPORARY TABLE t1;
+#
+# End of 10.2 tests
+#
diff --git a/mysql-test/main/temp_table.test b/mysql-test/main/temp_table.test
index bd3bba34f89..dc5fe7f3cd0 100644
--- a/mysql-test/main/temp_table.test
+++ b/mysql-test/main/temp_table.test
@@ -639,3 +639,22 @@ ALTER TABLE t1 CHANGE no_such_col1 col1 BIGINT NULL;
# was not dropped during the first TRUNCATE due to extra table handles.
TRUNCATE TABLE t1;
DROP TEMPORARY TABLE t1;
+
+--echo #
+--echo # MDEV-21695 Server crashes in TABLE::evaluate_update_default_function upon UPDATE on temporary table
+--echo #
+
+SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30');
+CREATE TEMPORARY TABLE t1 (a DATETIME ON UPDATE CURRENT_TIMESTAMP);
+ALTER TABLE t1 ADD b INT;
+INSERT INTO t1 (b) VALUES (1),(2);
+--error ER_BAD_FIELD_ERROR
+ALTER TABLE t1 CHANGE COLUMN x xx INT;
+UPDATE t1 SET b = 3;
+SELECT * FROM t1;
+DROP TEMPORARY TABLE t1;
+
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result
index 74322abd661..82e9399e653 100644
--- a/mysql-test/main/win.result
+++ b/mysql-test/main/win.result
@@ -3789,6 +3789,16 @@ row_number() OVER()
3
DROP TABLE t1;
#
+# MDEV-22984: Throw an error when arguments to window functions are window functions
+#
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1,1), (2,2), (3,3);
+SELECT NTILE(MAX(a) OVER (PARTITION BY a)) OVER (PARTITION BY a ORDER BY b) FROM t1;
+ERROR HY000: Window functions can not be used as arguments to group functions.
+SELECT FIRST_VALUE(MAX(a) OVER (PARTITION BY a)) OVER (ORDER BY a) AS x FROM t1 GROUP BY a;
+ERROR HY000: Window functions can not be used as arguments to group functions.
+DROP TABLE t1;
+#
# End of 10.2 tests
#
#
diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test
index b741461083f..6e628d3c0ba 100644
--- a/mysql-test/main/win.test
+++ b/mysql-test/main/win.test
@@ -2459,6 +2459,19 @@ SELECT row_number() OVER() FROM t1;
DROP TABLE t1;
--echo #
+--echo # MDEV-22984: Throw an error when arguments to window functions are window functions
+--echo #
+
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1,1), (2,2), (3,3);
+
+--error ER_SUM_FUNC_WITH_WINDOW_FUNC_AS_ARG
+SELECT NTILE(MAX(a) OVER (PARTITION BY a)) OVER (PARTITION BY a ORDER BY b) FROM t1;
+--error ER_SUM_FUNC_WITH_WINDOW_FUNC_AS_ARG
+SELECT FIRST_VALUE(MAX(a) OVER (PARTITION BY a)) OVER (ORDER BY a) AS x FROM t1 GROUP BY a;
+DROP TABLE t1;
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/mtr.out-of-source b/mysql-test/mtr.out-of-source
index 51713517ae1..30e2e65c569 100644
--- a/mysql-test/mtr.out-of-source
+++ b/mysql-test/mtr.out-of-source
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Call mtr in out-of-source build
$ENV{MTR_BINDIR} = '@CMAKE_BINARY_DIR@';
chdir('@CMAKE_SOURCE_DIR@/mysql-test');
diff --git a/mysql-test/mysql-stress-test.pl b/mysql-test/mysql-stress-test.pl
index ef7d97453a3..3ccf965024d 100755
--- a/mysql-test/mysql-stress-test.pl
+++ b/mysql-test/mysql-stress-test.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
#
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 5401c5478be..de07d018bdf 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2004, 2014, Oracle and/or its affiliates.
@@ -267,8 +267,12 @@ our %gprof_dirs;
our $glob_debugger= 0;
our $opt_gdb;
+my $opt_rr;
+my $opt_rr_dir;
+my @rr_record_args;
our $opt_client_gdb;
my $opt_boot_gdb;
+my $opt_boot_rr;
our $opt_dbx;
our $opt_client_dbx;
my $opt_boot_dbx;
@@ -1159,10 +1163,14 @@ sub command_line_setup {
'debug-common' => \$opt_debug_common,
'debug-server' => \$opt_debug_server,
'gdb=s' => \$opt_gdb,
+ 'rr' => \$opt_rr,
+ 'rr-arg=s' => \@rr_record_args,
+ 'rr-dir=s' => \$opt_rr_dir,
'client-gdb' => \$opt_client_gdb,
'manual-gdb' => \$opt_manual_gdb,
'manual-lldb' => \$opt_manual_lldb,
'boot-gdb' => \$opt_boot_gdb,
+ 'boot-rr' => \$opt_boot_rr,
'manual-debug' => \$opt_manual_debug,
'ddd' => \$opt_ddd,
'client-ddd' => \$opt_client_ddd,
@@ -1638,9 +1646,9 @@ sub command_line_setup {
$ENV{LSAN_OPTIONS}= "suppressions=${glob_mysql_test_dir}/lsan.supp:print_suppressions=0"
if -f "$glob_mysql_test_dir/lsan.supp" and not IS_WINDOWS;
- if ( $opt_gdb || $opt_client_gdb || $opt_ddd || $opt_client_ddd ||
- $opt_manual_gdb || $opt_manual_lldb || $opt_manual_ddd ||
- $opt_manual_debug || $opt_dbx || $opt_client_dbx || $opt_manual_dbx ||
+ if ( $opt_gdb || $opt_client_gdb || $opt_ddd || $opt_client_ddd || $opt_rr ||
+ $opt_manual_gdb || $opt_manual_lldb || $opt_manual_ddd ||
+ $opt_manual_debug || $opt_dbx || $opt_client_dbx || $opt_manual_dbx ||
$opt_debugger || $opt_client_debugger )
{
$ENV{ASAN_OPTIONS}= 'disable_coredump=0:'. $ENV{ASAN_OPTIONS};
@@ -3288,6 +3296,13 @@ sub mysql_install_db {
ddd_arguments(\$args, \$exe_mysqld_bootstrap, $mysqld->name(),
$bootstrap_sql_file);
}
+ if ($opt_boot_rr) {
+ $args= ["record", @rr_record_args, $exe_mysqld_bootstrap, @$args];
+ $exe_mysqld_bootstrap= "rr";
+ my $rr_dir= $opt_rr_dir ? $opt_rr_dir : "$opt_vardir/rr.boot";
+ $ENV{'_RR_TRACE_DIR'}= $rr_dir;
+ mkpath($rr_dir);
+ }
my $path_sql= my_find_file($install_basedir,
["mysql", "sql/share", "share/mariadb",
@@ -5286,6 +5301,14 @@ sub mysqld_start ($$) {
# Indicate the exe should not be started
$exe= undef;
}
+ elsif ( $opt_rr )
+ {
+ $args= ["record", @rr_record_args, "$exe", @$args];
+ $exe= "rr";
+ my $rr_dir= $opt_rr_dir ? $opt_rr_dir : "$opt_vardir/rr". $mysqld->after('mysqld');
+ $ENV{'_RR_TRACE_DIR'}= $rr_dir;
+ mkpath($rr_dir);
+ }
else
{
# Default to not wait until pid file has been created
@@ -6470,6 +6493,15 @@ Options for strace
stracer=<EXE> Specify name and path to the trace program to use.
Default is "strace". Example: $0 --stracer=ktrace.
+Options for rr (Record and Replay)
+ rr Run the "mysqld" executables using rr. Default run
+ option is "rr record mysqld mysqld_options"
+ boot-rr Start bootstrap server in rr
+ rr-arg=ARG Option to give rr record, can be specified more then once
+ rr-dir=DIR The directory where rr recordings are stored. Defaults
+ to 'vardir'/rr.0 (rr.boot for bootstrap instance and
+ rr.1, ..., rr.N for slave instances).
+
Misc options
user=USER User for connecting to mysqld(default: $opt_user)
comment=STR Write STR to the output
diff --git a/mysql-test/std_data/checkDBI_DBD-MariaDB.pl b/mysql-test/std_data/checkDBI_DBD-MariaDB.pl
index ed0f5b415d7..b078342c2a0 100755
--- a/mysql-test/std_data/checkDBI_DBD-MariaDB.pl
+++ b/mysql-test/std_data/checkDBI_DBD-MariaDB.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2011, Oracle and/or its affiliates
#
diff --git a/mysql-test/suite/engines/rr_trx/run_stress_tx_rr.pl b/mysql-test/suite/engines/rr_trx/run_stress_tx_rr.pl
index f277bce018e..e997f479466 100755
--- a/mysql-test/suite/engines/rr_trx/run_stress_tx_rr.pl
+++ b/mysql-test/suite/engines/rr_trx/run_stress_tx_rr.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
################################################################################
#
# This script runs the transactional stress test "stress_tx_rr" against the
diff --git a/mysql-test/suite/federated/federatedx_create_handlers.result b/mysql-test/suite/federated/federatedx_create_handlers.result
index 90a5234a02f..7a407d8aeef 100644
--- a/mysql-test/suite/federated/federatedx_create_handlers.result
+++ b/mysql-test/suite/federated/federatedx_create_handlers.result
@@ -209,7 +209,6 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 7
1 PRIMARY <derived2> ref key0 key0 18 federated.t3.name 2
2 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL
-3 MATERIALIZED t2 ALL NULL NULL NULL NULL 7 Using temporary
ANALYZE FORMAT=JSON
SELECT *
FROM federated.t3, (SELECT t1.name FROM federated.t1
@@ -253,25 +252,7 @@ ANALYZE
"select_id": 2,
"table": {
"message": "Pushed derived"
- },
- "subqueries": [
- {
- "query_block": {
- "select_id": 3,
- "temporary_table": {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "r_loops": 0,
- "rows": 7,
- "r_rows": null,
- "filtered": 100,
- "r_filtered": null
- }
- }
- }
- }
- ]
+ }
}
}
}
@@ -321,6 +302,78 @@ select @var;
@var
xxx
select name into outfile 'tmp.txt' from federated.t1;
+#
+# MDEV-22993: Crash on EXPLAIN with PUSHED DOWN SELECT and subquery
+#
+explain
+select * from federated.t1
+where name in (select name from federated.t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PUSHED SELECT NULL NULL NULL NULL NULL NULL NULL NULL
+explain format=json
+select * from federated.t1
+where name in (select name from federated.t2);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "message": "Pushed select"
+ }
+ }
+}
+#
+# MDEV-22993, testcase #2: EXPLAIN output doesn't make sense when
+# derived table pushdown is used.
+#
+create table t5 (a int) engine=myisam;
+insert into t5 values (1),(2);
+# Must not show lines with id=3
+explain
+select * from t5,
+(select id from federated.t1
+where name in (select name from federated.t2) or name like 'foo%') as TQ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t5 ALL NULL NULL NULL NULL 2
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join)
+2 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL
+# Must not show elements with select_id=3
+explain format=json
+select * from t5,
+(select id from federated.t1
+where name in (select name from federated.t2) or name like 'foo%') as TQ;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t5",
+ "access_type": "ALL",
+ "rows": 2,
+ "filtered": 100
+ },
+ "block-nl-join": {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100
+ },
+ "buffer_type": "flat",
+ "buffer_size": "65",
+ "join_type": "BNL",
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "table": {
+ "message": "Pushed derived"
+ }
+ }
+ }
+ }
+ }
+}
+drop table t5;
DROP TABLE federated.t1, federated.t2, federated.t3, federated.t4;
connection slave;
DROP TABLE federated.t1, federated.t2;
diff --git a/mysql-test/suite/federated/federatedx_create_handlers.test b/mysql-test/suite/federated/federatedx_create_handlers.test
index 42a03e60d67..d765588b79b 100644
--- a/mysql-test/suite/federated/federatedx_create_handlers.test
+++ b/mysql-test/suite/federated/federatedx_create_handlers.test
@@ -167,6 +167,40 @@ select name into outfile 'tmp.txt' from federated.t1;
let $path=`select concat(@@datadir, 'test/tmp.txt')`;
remove_file $path;
+--echo #
+--echo # MDEV-22993: Crash on EXPLAIN with PUSHED DOWN SELECT and subquery
+--echo #
+
+explain
+select * from federated.t1
+where name in (select name from federated.t2);
+
+explain format=json
+select * from federated.t1
+where name in (select name from federated.t2);
+
+--echo #
+--echo # MDEV-22993, testcase #2: EXPLAIN output doesn't make sense when
+--echo # derived table pushdown is used.
+--echo #
+
+create table t5 (a int) engine=myisam;
+insert into t5 values (1),(2);
+
+--echo # Must not show lines with id=3
+explain
+select * from t5,
+(select id from federated.t1
+ where name in (select name from federated.t2) or name like 'foo%') as TQ;
+
+--echo # Must not show elements with select_id=3
+explain format=json
+select * from t5,
+(select id from federated.t1
+ where name in (select name from federated.t2) or name like 'foo%') as TQ;
+
+drop table t5;
+
DROP TABLE federated.t1, federated.t2, federated.t3, federated.t4;
connection slave;
diff --git a/mysql-test/suite/funcs_1/lib/DataGen_local.pl b/mysql-test/suite/funcs_1/lib/DataGen_local.pl
index 738a73e0fd5..8ca74407141 100755
--- a/mysql-test/suite/funcs_1/lib/DataGen_local.pl
+++ b/mysql-test/suite/funcs_1/lib/DataGen_local.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
if ( (scalar(@ARGV) != 1 ) || ($ARGV[0] =~ /[^0-9]/i ) )
diff --git a/mysql-test/suite/funcs_1/lib/DataGen_modify.pl b/mysql-test/suite/funcs_1/lib/DataGen_modify.pl
index 4675049ff0d..8ad8e619a20 100755
--- a/mysql-test/suite/funcs_1/lib/DataGen_modify.pl
+++ b/mysql-test/suite/funcs_1/lib/DataGen_modify.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
if ( (scalar(@ARGV) != 2 ) || ($ARGV[0] =~ /[^0-9]/i ) )
diff --git a/mysql-test/suite/funcs_2/lib/gen_charset_utf8.pl b/mysql-test/suite/funcs_2/lib/gen_charset_utf8.pl
index 3b85ed02f5b..c0973a10950 100755
--- a/mysql-test/suite/funcs_2/lib/gen_charset_utf8.pl
+++ b/mysql-test/suite/funcs_2/lib/gen_charset_utf8.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
#################################################################################
# Author: Serge Kozlov #
diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def
index 81970cd22aa..e4244c63297 100644
--- a/mysql-test/suite/galera/disabled.def
+++ b/mysql-test/suite/galera/disabled.def
@@ -37,7 +37,7 @@ galera_split_brain : MDEV-18280 Galera test failure on galera_split_brain and ga
galera_ssl_upgrade : MDEV-19950 Galera test failure on galera_ssl_upgrade
galera_sst_mariabackup_encrypt_with_key : MDEV-21484 galera_sst_mariabackup_encrypt_with_key
galera_toi_ddl_nonconflicting : MDEV-21518 galera.galera_toi_ddl_nonconflicting
-galera_var_innodb_disallow_writes : MDEV-20928 galera.galera_var_innodb_disallow_writes
+galera_toi_truncate : MDEV-22996 Hang on galera_toi_truncate test case
galera_var_node_address : MDEV-20485 Galera test failure
galera_var_notify_cmd : MDEV-21905 Galera test galera_var_notify_cmd causes hang
galera_var_reject_queries : assertion in inline_mysql_socket_send
diff --git a/mysql-test/suite/galera/galera_3nodes_as_slave.cnf b/mysql-test/suite/galera/galera_3nodes_as_slave.cnf
index c84c4b25d2a..4181ee13ebc 100644
--- a/mysql-test/suite/galera/galera_3nodes_as_slave.cnf
+++ b/mysql-test/suite/galera/galera_3nodes_as_slave.cnf
@@ -19,6 +19,7 @@ innodb_lock_schedule_algorithm=FCFS
wsrep-on=1
log-slave-updates
+wsrep-on=1
innodb-autoinc-lock-mode=2
default-storage-engine=innodb
@@ -44,6 +45,7 @@ innodb_lock_schedule_algorithm=FCFS
wsrep-on=1
log-slave-updates
+wsrep-on=1
innodb-autoinc-lock-mode=2
default-storage-engine=innodb
@@ -69,6 +71,7 @@ innodb_lock_schedule_algorithm=FCFS
wsrep-on=1
log-slave-updates
+wsrep-on=1
innodb-autoinc-lock-mode=2
default-storage-engine=innodb
diff --git a/mysql-test/suite/galera/r/galera_as_slave_gtid.result b/mysql-test/suite/galera/r/galera_as_slave_gtid.result
index 3f4137a3b28..41d9085ccac 100644
--- a/mysql-test/suite/galera/r/galera_as_slave_gtid.result
+++ b/mysql-test/suite/galera/r/galera_as_slave_gtid.result
@@ -9,6 +9,7 @@ INSERT INTO t1 VALUES(1);
SELECT LENGTH(@@global.gtid_binlog_state) > 1;
LENGTH(@@global.gtid_binlog_state) > 1
1
+connection node_1;
connection node_2;
gtid_binlog_state_equal
1
diff --git a/mysql-test/suite/galera/r/galera_as_slave_gtid_auto_engine.result b/mysql-test/suite/galera/r/galera_as_slave_gtid_auto_engine.result
index 6c84c1ecd31..cff5bb0a5d0 100644
--- a/mysql-test/suite/galera/r/galera_as_slave_gtid_auto_engine.result
+++ b/mysql-test/suite/galera/r/galera_as_slave_gtid_auto_engine.result
@@ -9,6 +9,7 @@ INSERT INTO t1 VALUES(1);
SELECT LENGTH(@@global.gtid_binlog_state) > 1;
LENGTH(@@global.gtid_binlog_state) > 1
1
+connection node_1;
connection node_2;
gtid_binlog_state_equal
1
diff --git a/mysql-test/suite/galera/r/galera_as_slave_gtid_myisam.result b/mysql-test/suite/galera/r/galera_as_slave_gtid_myisam.result
index 7e8da675ad4..b498f334bf8 100644
--- a/mysql-test/suite/galera/r/galera_as_slave_gtid_myisam.result
+++ b/mysql-test/suite/galera/r/galera_as_slave_gtid_myisam.result
@@ -31,7 +31,6 @@ DROP TABLE t1;
connection node_1;
connection node_2;
connection node_3;
-connection node_3;
RESET MASTER;
connection node_1;
STOP SLAVE;
@@ -43,3 +42,5 @@ connection node_2;
SET GLOBAL WSREP_ON=OFF;
reset master;
SET GLOBAL WSREP_ON=ON;
+connection node_3;
+RESET MASTER;
diff --git a/mysql-test/suite/galera/r/galera_var_innodb_disallow_writes.result b/mysql-test/suite/galera/r/galera_var_innodb_disallow_writes.result
index f5ec473fea4..3eb56d1a48d 100644
--- a/mysql-test/suite/galera/r/galera_var_innodb_disallow_writes.result
+++ b/mysql-test/suite/galera/r/galera_var_innodb_disallow_writes.result
@@ -1,5 +1,6 @@
connection node_2;
connection node_1;
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
connection node_1a;
SET SESSION wsrep_sync_wait = 0;
connection node_1;
@@ -7,19 +8,20 @@ CREATE TABLE t1 (f1 INTEGER) Engine=InnoDB;
SET GLOBAL innodb_disallow_writes=ON;
INSERT INTO t1 VALUES (1);;
connection node_1a;
-SELECT COUNT(*) = 1 FROM t1;
-COUNT(*) = 1
+SELECT COUNT(*) AS EXPECT_0 FROM t1;
+EXPECT_0
0
-SELECT COUNT(*) = 1 FROM t1;
-COUNT(*) = 1
+SELECT COUNT(*) AS EXPECT_0 FROM t1;
+EXPECT_0
0
SET GLOBAL innodb_disallow_writes=OFF;
connection node_1;
-SELECT COUNT(*) = 1 FROM t1;
-COUNT(*) = 1
+SELECT COUNT(*) AS EXPECT_1 FROM t1;
+EXPECT_1
1
connection node_2;
-SELECT COUNT(*) = 1 FROM t1;
-COUNT(*) = 1
+SELECT COUNT(*) AS EXPECT_1 FROM t1;
+EXPECT_1
1
DROP TABLE t1;
+disconnect node_1a;
diff --git a/mysql-test/suite/galera/r/mysql-wsrep-bugs-607.result b/mysql-test/suite/galera/r/mysql-wsrep-bugs-607.result
new file mode 100644
index 00000000000..9d9614ffefe
--- /dev/null
+++ b/mysql-test/suite/galera/r/mysql-wsrep-bugs-607.result
@@ -0,0 +1,31 @@
+connection node_2;
+connection node_1;
+#
+# test the order of wsrep XID storage after certifiation failure
+#
+connection node_1;
+set session wsrep_sync_wait=0;
+create table t1 (i int primary key, j int);
+insert into t1 values (4, 0);
+connect node_2b, 127.0.0.1, root, , test, $NODE_MYPORT_2;
+connection node_2b;
+set session wsrep_sync_wait=0;
+SET GLOBAL debug_dbug = "d,sync.wsrep_apply_cb";
+connection node_1;
+UPDATE test.t1 set j=1 where i=4;
+connection node_2b;
+SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached";
+connection node_2;
+set session wsrep_sync_wait=0;
+set session wsrep_retry_autocommit=0;
+UPDATE test.t1 SET j=2 WHERE i=4;
+connection node_2b;
+SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb";
+SET GLOBAL debug_dbug = "";
+SET DEBUG_SYNC = "RESET";
+connection node_2;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+select * from t1;
+i j
+4 1
+DROP TABLE t1;
diff --git a/mysql-test/suite/galera/suite.pm b/mysql-test/suite/galera/suite.pm
index f17ef09fc88..671fd1688c9 100644
--- a/mysql-test/suite/galera/suite.pm
+++ b/mysql-test/suite/galera/suite.pm
@@ -63,6 +63,7 @@ push @::global_suppressions,
qr(WSREP: Failed to remove page file .*),
qr(WSREP: wsrep_sst_method is set to 'mysqldump' yet mysqld bind_address is set to .*),
qr|WSREP: Sending JOIN failed: -107 \(Transport endpoint is not connected\). Will retry in new primary component.|,
+ qr|WSREP: Trying to continue unpaused monitor|,
);
sub skip_combinations {
diff --git a/mysql-test/suite/galera/t/MW-388.test b/mysql-test/suite/galera/t/MW-388.test
index 09fc8a8bfc9..b88f53ca8d9 100644
--- a/mysql-test/suite/galera/t/MW-388.test
+++ b/mysql-test/suite/galera/t/MW-388.test
@@ -1,5 +1,7 @@
--source include/galera_cluster.inc
+--source include/have_debug.inc
--source include/have_debug_sync.inc
+--source include/galera_have_debug_sync.inc
--connection node_1
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(255)) Engine=InnoDB;
diff --git a/mysql-test/suite/galera/t/MW-86-wait1.test b/mysql-test/suite/galera/t/MW-86-wait1.test
index 4e99872bf4d..7ebd3ba95a0 100644
--- a/mysql-test/suite/galera/t/MW-86-wait1.test
+++ b/mysql-test/suite/galera/t/MW-86-wait1.test
@@ -7,6 +7,8 @@
--source include/have_binlog_format_row.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
+--source include/galera_have_debug_sync.inc
+
SET @orig_debug=@@debug_dbug;
--connection node_2
diff --git a/mysql-test/suite/galera/t/MW-86-wait8.test b/mysql-test/suite/galera/t/MW-86-wait8.test
index 7d9e54a16ba..1b3f355eb25 100644
--- a/mysql-test/suite/galera/t/MW-86-wait8.test
+++ b/mysql-test/suite/galera/t/MW-86-wait8.test
@@ -3,7 +3,10 @@
#
--source include/galera_cluster.inc
--source include/have_binlog_format_row.inc
+--source include/have_debug.inc
--source include/have_debug_sync.inc
+--source include/galera_have_debug_sync.inc
+
SET @orig_debug=@@debug_dbug;
--connection node_2
diff --git a/mysql-test/suite/galera/t/galera_as_slave_gtid.inc b/mysql-test/suite/galera/t/galera_as_slave_gtid.inc
index f5222b4322b..ca6cce52497 100644
--- a/mysql-test/suite/galera/t/galera_as_slave_gtid.inc
+++ b/mysql-test/suite/galera/t/galera_as_slave_gtid.inc
@@ -8,6 +8,7 @@
#
--source include/have_innodb.inc
+--source include/have_log_bin.inc
--source include/galera_cluster.inc
# As node #3 is not a Galera node, and galera_cluster.inc does not open connetion to it
@@ -27,6 +28,13 @@ INSERT INTO t1 VALUES(1);
SELECT LENGTH(@@global.gtid_binlog_state) > 1;
--let $gtid_binlog_state_node1 = `SELECT @@global.gtid_binlog_state;`
+--connection node_1
+--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
+--source include/wait_condition.inc
+
+--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
+--source include/wait_condition.inc
+
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc
diff --git a/mysql-test/suite/galera/t/galera_as_slave_gtid_auto_engine.cnf b/mysql-test/suite/galera/t/galera_as_slave_gtid_auto_engine.cnf
index adcba9b6069..efabe4161aa 100644
--- a/mysql-test/suite/galera/t/galera_as_slave_gtid_auto_engine.cnf
+++ b/mysql-test/suite/galera/t/galera_as_slave_gtid_auto_engine.cnf
@@ -5,4 +5,4 @@ log-bin=mysqld-bin
log-slave-updates
binlog-format=ROW
-gtid_pos_auto_engines=InnoDB \ No newline at end of file
+gtid_pos_auto_engines=InnoDB
diff --git a/mysql-test/suite/galera/t/galera_as_slave_gtid_auto_engine.test b/mysql-test/suite/galera/t/galera_as_slave_gtid_auto_engine.test
index 990dd35f40e..5ef98573660 100644
--- a/mysql-test/suite/galera/t/galera_as_slave_gtid_auto_engine.test
+++ b/mysql-test/suite/galera/t/galera_as_slave_gtid_auto_engine.test
@@ -11,4 +11,4 @@
--connection node_2
DROP TABLE mysql.gtid_slave_pos_InnoDB;
-CALL mtr.add_suppression("The automatically created table"); \ No newline at end of file
+CALL mtr.add_suppression("The automatically created table");
diff --git a/mysql-test/suite/galera/t/galera_as_slave_gtid_myisam.test b/mysql-test/suite/galera/t/galera_as_slave_gtid_myisam.test
index 004f5c825bb..8787f864a99 100644
--- a/mysql-test/suite/galera/t/galera_as_slave_gtid_myisam.test
+++ b/mysql-test/suite/galera/t/galera_as_slave_gtid_myisam.test
@@ -59,6 +59,8 @@ SELECT COUNT(*) AS EXPECT_0 FROM t1;
--connection node_3
DROP TABLE t1;
+--sleep 1
+
--connection node_1
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc
@@ -70,8 +72,6 @@ DROP TABLE t1;
--connection node_3
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc
-
---connection node_3
RESET MASTER;
--connection node_1
@@ -85,3 +85,6 @@ SET GLOBAL WSREP_ON=ON;
SET GLOBAL WSREP_ON=OFF;
reset master;
SET GLOBAL WSREP_ON=ON;
+
+--connection node_3
+RESET MASTER;
diff --git a/mysql-test/suite/galera/t/galera_query_cache_sync_wait.test b/mysql-test/suite/galera/t/galera_query_cache_sync_wait.test
index e13e7f1f748..6d1e21fd94d 100644
--- a/mysql-test/suite/galera/t/galera_query_cache_sync_wait.test
+++ b/mysql-test/suite/galera/t/galera_query_cache_sync_wait.test
@@ -1,6 +1,8 @@
--source include/galera_cluster.inc
+--source include/have_debug.inc
--source include/have_debug_sync.inc
--source include/have_query_cache.inc
+--source include/galera_have_debug_sync.inc
CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
diff --git a/mysql-test/suite/galera/t/galera_var_cluster_conf_id.test b/mysql-test/suite/galera/t/galera_var_cluster_conf_id.test
index c569634823f..dd4a630035d 100644
--- a/mysql-test/suite/galera/t/galera_var_cluster_conf_id.test
+++ b/mysql-test/suite/galera/t/galera_var_cluster_conf_id.test
@@ -1,9 +1,9 @@
--source include/galera_cluster.inc
--connection node_1
---replace_regex /18446744073709551/ERROR/ /[0-9]/#/
+--replace_regex /18446744073709551/ERROR/ /[0-9+]/#/
show status like 'wsrep_cluster_conf_id';
--connection node_2
---replace_regex /18446744073709551/ERROR/ /[0-9]/#/
+--replace_regex /18446744073709551/ERROR/ /[0-9+]/#/
show status like 'wsrep_cluster_conf_id';
diff --git a/mysql-test/suite/galera/t/galera_var_innodb_disallow_writes.test b/mysql-test/suite/galera/t/galera_var_innodb_disallow_writes.test
index 9ccecc5a61d..37469d8a5fb 100644
--- a/mysql-test/suite/galera/t/galera_var_innodb_disallow_writes.test
+++ b/mysql-test/suite/galera/t/galera_var_innodb_disallow_writes.test
@@ -11,13 +11,10 @@
#
--source include/galera_cluster.inc
---source include/have_innodb.inc
--source include/have_log_bin.inc
# Open a separate connection to be used to run SHOW PROCESSLIST
---let $galera_connection_name = node_1a
---let $galera_server_number = 1
---source include/galera_connect.inc
+--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
--connection node_1a
SET SESSION wsrep_sync_wait = 0;
@@ -27,18 +24,27 @@ SET GLOBAL innodb_disallow_writes=ON;
--send INSERT INTO t1 VALUES (1);
--connection node_1a
-SELECT COUNT(*) = 1 FROM t1;
-let $wait_condition = SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO = 'INSERT INTO t1 VALUES (1)' AND State = 'Commit';
+--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1';
--source include/wait_condition.inc
-SELECT COUNT(*) = 1 FROM t1;
+SELECT COUNT(*) AS EXPECT_0 FROM t1;
+let $wait_condition = SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO = 'INSERT INTO t1 VALUES (1)';
+--source include/wait_condition.inc
+SELECT COUNT(*) AS EXPECT_0 FROM t1;
SET GLOBAL innodb_disallow_writes=OFF;
--connection node_1
--reap
-SELECT COUNT(*) = 1 FROM t1;
+SELECT COUNT(*) AS EXPECT_1 FROM t1;
--connection node_2
-SELECT COUNT(*) = 1 FROM t1;
+--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1';
+--source include/wait_condition.inc
+--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
+--source include/wait_condition.inc
+SELECT COUNT(*) AS EXPECT_1 FROM t1;
DROP TABLE t1;
+
+--disconnect node_1a
+
diff --git a/mysql-test/suite/galera/t/galera_var_retry_autocommit.test b/mysql-test/suite/galera/t/galera_var_retry_autocommit.test
index df541b774a4..6bed1b0120f 100644
--- a/mysql-test/suite/galera/t/galera_var_retry_autocommit.test
+++ b/mysql-test/suite/galera/t/galera_var_retry_autocommit.test
@@ -4,7 +4,9 @@
--source include/galera_cluster.inc
--source include/have_innodb.inc
+--source include/have_debug.inc
--source include/have_debug_sync.inc
+--source include/galera_have_debug_sync.inc
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
diff --git a/mysql-test/suite/galera/t/mysql-wsrep-bugs-607.test b/mysql-test/suite/galera/t/mysql-wsrep-bugs-607.test
new file mode 100644
index 00000000000..c24ec7911e2
--- /dev/null
+++ b/mysql-test/suite/galera/t/mysql-wsrep-bugs-607.test
@@ -0,0 +1,70 @@
+--source include/galera_cluster.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+--source include/galera_have_debug_sync.inc
+--source include/have_log_bin.inc
+
+#
+# Test case to stress the order of wsrep XID checkpointing.
+#
+# In buggy version, the transaction which failed certification can
+# rush to record wsrep XID checkpoint before the offending applier,
+# causing assert in innodb sys header update routine
+#
+
+--echo #
+--echo # test the order of wsrep XID storage after certifiation failure
+--echo #
+
+--connection node_1
+set session wsrep_sync_wait=0;
+
+create table t1 (i int primary key, j int);
+
+insert into t1 values (4, 0);
+
+--connect node_2b, 127.0.0.1, root, , test, $NODE_MYPORT_2
+--connection node_2b
+set session wsrep_sync_wait=0;
+# wait for the last insert to be replicated from node 1
+--let $wait_condition = SELECT COUNT(*) = 1 FROM test.t1;
+--source include/wait_condition.inc
+
+# block applier before applying
+SET GLOBAL debug_dbug = "d,sync.wsrep_apply_cb";
+
+# send update from node 1, it will pause in the sync point
+--connection node_1
+UPDATE test.t1 set j=1 where i=4;
+
+--connection node_2b
+# wait until applier has reached the sync point
+SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached";
+
+# look number of cert failures so far, and expect one more to happen
+--let $expected_cert_failures = `SELECT VARIABLE_VALUE+1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_cert_failures'`
+
+# Inject a conflicting update in node 2, it should fail in certification
+--connection node_2
+set session wsrep_sync_wait=0;
+set session wsrep_retry_autocommit=0;
+--send UPDATE test.t1 SET j=2 WHERE i=4
+
+--connection node_2b
+# wait until the update has hit certification failure
+
+--let $wait_condition = SELECT VARIABLE_VALUE = $expected_cert_failures FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_cert_failures'
+--source include/wait_condition.inc
+
+# release the applier
+SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb";
+
+SET GLOBAL debug_dbug = "";
+SET DEBUG_SYNC = "RESET";
+
+--connection node_2
+--error ER_LOCK_DEADLOCK
+--reap
+select * from t1;
+
+DROP TABLE t1;
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
new file mode 100644
index 00000000000..0461f1f1feb
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_A.result
@@ -0,0 +1,40 @@
+CREATE TABLE t1 (pk INT PRIMARY KEY, node INT) ENGINE=innodb;
+INSERT INTO t1 VALUES (1, 1);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (2, 3);
+SET wsrep_sync_wait = 0;
+SET wsrep_on = OFF;
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_shift_to_joining';
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (3, 2);
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (4, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (5, 2);
+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='gmcast.isolate=1';
+INSERT INTO t1 VALUES (6, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (7, 2);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (8, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+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;
+INSERT INTO t1 VALUES (9, 2);
+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=';
+DROP TABLE t1;
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+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
new file mode 100644
index 00000000000..d878f60ca6b
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_B.result
@@ -0,0 +1,50 @@
+CREATE TABLE t1 (pk INT PRIMARY KEY, node INT) ENGINE=innodb;
+INSERT INTO t1 VALUES (1, 1);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (2, 3);
+SET wsrep_sync_wait = 0;
+SET wsrep_on = OFF;
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_shift_to_joining';
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (3, 2);
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (4, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (5, 2);
+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=';
+SET GLOBAL wsrep_provider_options = 'signal=before_send_state_request';
+SET SESSION wsrep_on = 0;
+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
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (6, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (7, 2);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (8, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+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;
+INSERT INTO t1 VALUES (9, 2);
+SET GLOBAL wsrep_provider_options = 'signal=process_primary_configuration';
+SET SESSION wsrep_on = 0;
+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 process_primary_configuration
+SET GLOBAL wsrep_provider_options = 'signal=process_primary_configuration';
+SET GLOBAL wsrep_provider_options = 'dbug=';
+DROP TABLE t1;
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+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
new file mode 100644
index 00000000000..df0a924029c
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_C.result
@@ -0,0 +1,55 @@
+CREATE TABLE t1 (pk INT PRIMARY KEY, node INT) ENGINE=innodb;
+INSERT INTO t1 VALUES (1, 1);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (2, 3);
+SET wsrep_sync_wait = 0;
+SET wsrep_on = OFF;
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_shift_to_joining';
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (3, 2);
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (4, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (5, 2);
+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=';
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+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
+INSERT INTO t1 VALUES (6, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (7, 2);
+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';
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (8, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+INSERT INTO t1 VALUES (9, 2);
+SET GLOBAL wsrep_provider_options = 'signal=process_primary_configuration';
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'signal=process_primary_configuration';
+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';
+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.");
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
diff --git a/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_A.test b/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_A.test
new file mode 100644
index 00000000000..2248ff5014a
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_A.test
@@ -0,0 +1,262 @@
+#
+# Tests handling of several configuration changes while a joiner gets
+# state transfer
+#
+# Variant A: sending of state transfer request delayed until two more
+# primary configuration changes happen
+#
+# Refs codersihp/galera-bugs#454
+#
+--source include/have_innodb.inc
+--source include/galera_cluster.inc
+--source include/galera_have_debug_sync.inc
+
+--let $galera_connection_name = node_3
+--let $galera_server_number = 3
+--source include/galera_connect.inc
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+CREATE TABLE t1 (pk INT PRIMARY KEY, node INT) ENGINE=innodb;
+INSERT INTO t1 VALUES (1, 1);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Isolate node_1 and update cluster state to force node 1 into joiner mode
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (2, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 2 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now reconnect node_1 but first make it block before sending state transfer
+# request
+#
+# THIS IS PC1
+#
+--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
+SET wsrep_sync_wait = 0;
+SET wsrep_on = OFF;
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_set_sync_point.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (3, 2);
+
+--connection node_1a
+--source include/galera_wait_sync_point.inc
+#
+# At this point every node thinks that node_1 is in a JOINER state
+#
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 3 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now that node_1 sent state request and became JOINER isolate node_1 again
+# and commit one more action, so that node_1 loses JOINER state
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (4, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 4 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Reconnect node_1 again
+#
+# THIS IS PC2
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# After this point node_1 is no longer JOINER and is required to start the
+# whole procedure over because it missed some actions (4th insert into t1)
+#
+
+INSERT INTO t1 VALUES (5, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 5 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now let node_1 continue with IST and finish processing PC1, but make it
+# block when processing PC2 just before sending state transfer request
+#
+--connection node_1a
+--let $galera_sync_point = before_send_state_request
+--source include/galera_set_sync_point.inc
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_signal_sync_point.inc
+--let $galera_sync_point = before_send_state_request
+--source include/galera_wait_sync_point.inc
+
+# since PC1 has been processed node_1 must have 3 rows in t1
+# 2 were there before PC1 and one was added while in PC1
+--let $wait_condition = SELECT COUNT(*) = 3 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now disconnect and reconnect node_1 again to get PC3
+# It still is blocked before sending state transfer request in PC2.
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (6, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 6 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# This is PC3
+#
+
+INSERT INTO t1 VALUES (7, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 7 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now disconnect and reconnect node_1 again to get PC4 and allow node_1
+# to send state transfer request to be delivered in PC4 (and thus get
+# updated to PC4 seqno in state transfer.
+# Note that node_1 still processes PC2.
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (8, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 8 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# This is PC4. node_1 is still processing PC2, waiting to send state trasfer
+# request
+#
+--connection node_1a
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_set_sync_point.inc
+--let $galera_sync_point = before_send_state_request
+--source include/galera_signal_sync_point.inc
+# sent STR from PC2 into PC4
+
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_wait_sync_point.inc
+#
+# Now node_1 is processing PC3, but should have completed state transfer from
+# PC4 and thus must have 8 rows in t1
+#
+--let $wait_condition = SELECT COUNT(*) = 8 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_2
+INSERT INTO t1 VALUES (9, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 9 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1a
+#--let $galera_sync_point = process_primary_configuration
+--source include/galera_signal_sync_point.inc
+--source include/galera_wait_sync_point.inc
+#
+# Now node_1 is processing PC4, still must have 8 rows in t1
+#
+--let $wait_condition = SELECT COUNT(*) = 8 FROM t1;
+--source include/wait_condition.inc
+
+#--let $galera_sync_point = process_primary_configuration
+--source include/galera_signal_sync_point.inc
+--source include/galera_clear_sync_point.inc
+
+--let $wait_condition = SELECT COUNT(*) = 9 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready';
+--source include/wait_condition.inc
+
+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/t/galera_join_with_cc_B.test b/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_B.test
new file mode 100644
index 00000000000..2fb0e78c759
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_B.test
@@ -0,0 +1,273 @@
+#
+# Tests handling of several configuration changes while a joiner gets
+# state transfer
+#
+# Variant B: sending of state transfer request is immediate but completion
+# of IST delayed until two more primary configuration changes happen
+#
+# Refs codersihp/galera-bugs#454
+#
+--source include/have_innodb.inc
+--source include/galera_cluster.inc
+--source include/galera_have_debug_sync.inc
+
+--let $galera_connection_name = node_3
+--let $galera_server_number = 3
+--source include/galera_connect.inc
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+CREATE TABLE t1 (pk INT PRIMARY KEY, node INT) ENGINE=innodb;
+INSERT INTO t1 VALUES (1, 1);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Isolate node_1 and update cluster state to force node 1 into joiner mode
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (2, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 2 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now reconnect node_1 but first make it block before sending state transfer
+# request
+#
+# THIS IS PC1
+#
+--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
+SET wsrep_sync_wait = 0;
+SET wsrep_on = OFF;
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_set_sync_point.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (3, 2);
+
+--connection node_1a
+--source include/galera_wait_sync_point.inc
+#
+# At this point every node thinks that node_1 is in a JOINER state
+#
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 3 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now that node_1 sent state request and became JOINER isolate node_1 again
+# and commit one more action, so that node_1 loses JOINER state
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (4, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 4 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Reconnect node_1 again
+#
+# THIS IS PC2
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# After this point node_1 is no longer JOINER and is required to start the
+# whole procedure over because it missed some actions (4th insert into t1)
+#
+
+INSERT INTO t1 VALUES (5, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 5 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now let node_1 continue with IST and finish processing PC1, but make it
+# block when processing PC2 right after progressing to JOINER state and
+# before IST happens.
+#
+--connection node_1a
+--let $galera_sync_point = before_send_state_request
+--source include/galera_set_sync_point.inc
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_signal_sync_point.inc
+--let $galera_sync_point = before_send_state_request
+--source include/galera_wait_sync_point.inc
+--source include/galera_clear_sync_point.inc
+# Here node_1 is processing PC2 just before sending state request
+
+# since PC1 has been processed node_1 must have 3 rows in t1
+# 2 were there before PC1 and one was added while in PC1
+--let $wait_condition = SELECT COUNT(*) = 3 FROM t1;
+--source include/wait_condition.inc
+
+# Proceed to sending state transfer request and block right after
+--source include/galera_signal_sync_point.inc # before_send_state_request
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_wait_sync_point.inc
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_debug_sync_waiters';
+
+#
+# Now disconnect and reconnect node_1 again to get PC3
+# It is blocked right after shifting to JOINING state.
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (6, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 6 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# This is PC3
+#
+
+INSERT INTO t1 VALUES (7, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 7 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now disconnect and reconnect node_1 again to get PC4 and allow node_1
+# to continue with IST.
+# Note that node_1 still processes PC2 and is joining.
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (8, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 8 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# This is PC4. node_1 is still processing PC2, waiting to send state trasfer
+# request
+#
+--connection node_1a
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_set_sync_point.inc
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_signal_sync_point.inc
+# continue with IST prepared for in PC2
+
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_wait_sync_point.inc
+#
+# Now node_1 is processing PC3, and should have finished state transfer
+# State tranfer request was dilivered before PC3, so node_1 should have
+# received IST up to 4 rows in t1 (what was there before PC2) plus one more
+# INSERT while in PC2.
+#
+--let $wait_condition = SELECT COUNT(*) = 5 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_2
+INSERT INTO t1 VALUES (9, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 9 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1a
+#--let $galera_sync_point = process_primary_configuration
+--source include/galera_signal_sync_point.inc
+--source include/galera_wait_sync_point.inc
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_debug_sync_waiters';
+#
+# Now node_1 is processing PC4, still must have 8 rows in t1
+#
+--let $wait_condition = SELECT COUNT(*) = 8 FROM t1;
+--source include/wait_condition.inc
+
+#--let $galera_sync_point = process_primary_configuration
+--source include/galera_signal_sync_point.inc
+--source include/galera_clear_sync_point.inc
+
+--let $wait_condition = SELECT COUNT(*) = 9 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready';
+--source include/wait_condition.inc
+
+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/t/galera_join_with_cc_C.test b/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_C.test
new file mode 100644
index 00000000000..133903d7cbf
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_C.test
@@ -0,0 +1,299 @@
+#
+# Tests handling of several configuration changes while a joiner gets
+# state transfer
+#
+# Variant C: sending of state transfer request is scheduled while in non-PRIM
+#
+# Refs codersihp/galera-bugs#454
+#
+--source include/have_innodb.inc
+--source include/galera_cluster.inc
+--source include/galera_have_debug_sync.inc
+
+--let $galera_connection_name = node_3
+--let $galera_server_number = 3
+--source include/galera_connect.inc
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+CREATE TABLE t1 (pk INT PRIMARY KEY, node INT) ENGINE=innodb;
+INSERT INTO t1 VALUES (1, 1);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Isolate node_1 and update cluster state to force node 1 into joiner mode
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (2, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 2 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now reconnect node_1 but first make it block before sending state transfer
+# request
+#
+# THIS IS PC1
+#
+--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
+SET wsrep_sync_wait = 0;
+SET wsrep_on = OFF;
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_set_sync_point.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (3, 2);
+
+--connection node_1a
+--source include/galera_wait_sync_point.inc
+#
+# At this point every node thinks that node_1 is in a JOINER state
+#
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 3 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now that node_1 sent state request and became JOINER isolate node_1 again
+# and commit one more action, so that node_1 loses JOINER state
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (4, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 4 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Reconnect node_1 again
+#
+# THIS IS PC2
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# After this point node_1 is no longer JOINER and is required to start the
+# whole procedure over because it missed some actions (4th insert into t1)
+#
+
+INSERT INTO t1 VALUES (5, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 5 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now let node_1 continue with IST and finish processing PC1, but make it
+# block when processing PC2 right after progressing to JOINER state and
+# before IST happens.
+#
+--connection node_1a
+--let $galera_sync_point = before_send_state_request
+--source include/galera_set_sync_point.inc
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_signal_sync_point.inc
+--let $galera_sync_point = before_send_state_request
+--source include/galera_wait_sync_point.inc
+--source include/galera_clear_sync_point.inc
+# Here we are processing PC2 just before sending state request
+
+# since PC1 has been processed node_1 must have 3 rows in t1
+# 2 were there before PC1 and one was added while in PC1
+--let $wait_condition = SELECT COUNT(*) = 3 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now disconnect and reconnect node_1 again to get PC3
+# It still is blocked before sending state transfer request in PC2.
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+# Proceed to sending state transfer request
+--connection node_1a
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_set_sync_point.inc
+--let $galera_sync_point = before_send_state_request
+--source include/galera_signal_sync_point.inc # before_send_state_request
+#
+# node_1 proceeds to sending state transfer request, it will be delivered only
+# in the next PC which is PC3. Only then the node will shift to JOINING
+#
+--echo 4
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_debug_sync_waiters';
+
+--connection node_3
+INSERT INTO t1 VALUES (6, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 6 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# This is PC3
+#
+
+INSERT INTO t1 VALUES (7, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 7 FROM t1;
+--source include/wait_condition.inc
+
+# node_1 is stiil processing PC2, it was let to send state transfer request
+# while in non-PRIM. Now it should be able to complete it and shift to
+# JOINING. Make it block on next PC(3) and continue to receive IST
+--connection node_1a
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_wait_sync_point.inc
+--source include/galera_clear_sync_point.inc # won't need it any more
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_set_sync_point.inc
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_signal_sync_point.inc
+# continue with IST while still processing PC2
+
+#
+# Now disconnect and reconnect node_1 again to generate PC4.
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (8, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 8 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# This is PC4. node_1 should complete IST, complete PC2, and continue
+# with the next item in queue
+#
+--connection node_1a
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_wait_sync_point.inc
+
+#
+# Now node_1 is blocked before processing PC3, and should have finished state
+# transfer started while in PC2.
+# State tranfer request was dilivered in PC3 to donor, so node_1 should have
+# received IST up to 6 rows in t1 (what was there before PC3).
+#
+--let $wait_condition = SELECT COUNT(*) = 6 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_2
+INSERT INTO t1 VALUES (9, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 9 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1a
+# continue with processing PC3
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_signal_sync_point.inc
+
+# wait for row that follows PC3
+--let $wait_condition = SELECT COUNT(*) = 7 FROM t1;
+--source include/wait_condition.inc
+
+# wait till PC4
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_wait_sync_point.inc
+#
+# Now node_1 is processing PC4, still must have 7 rows in t1
+#
+--let $wait_condition = SELECT COUNT(*) = 7 FROM t1;
+--source include/wait_condition.inc
+
+# Continue with PC4
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_clear_sync_point.inc
+--source include/galera_signal_sync_point.inc
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_wait_sync_point.inc
+--source include/galera_clear_sync_point.inc
+--source include/galera_signal_sync_point.inc
+
+--let $wait_condition = SELECT COUNT(*) = 9 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready';
+--source include/wait_condition.inc
+
+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/r/information_schema_grants.result b/mysql-test/suite/innodb/r/information_schema_grants.result
index 25eb1c632bd..622faa2920a 100644
--- a/mysql-test/suite/innodb/r/information_schema_grants.result
+++ b/mysql-test/suite/innodb/r/information_schema_grants.result
@@ -276,9 +276,9 @@ select count(*) > -1 from d_sys_virtual;
count(*) > -1
1
select count(*) > -1 from information_schema.innodb_tablespaces_encryption;
-ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
select count(*) > -1 from i_tablespaces_encryption;
-ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
select count(*) > -1 from d_tablespaces_encryption;
count(*) > -1
1
diff --git a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result
index 1382457debf..7d98aba7fc3 100644
--- a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result
+++ b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result
@@ -225,6 +225,13 @@ id title body
1 MySQL Tutorial DBMS stands for DataBase ...
3 Optimizing MySQL In this tutorial we will show ...
DROP TABLE articles;
+#
+# MDEV-22811 DDL fails to drop and re-create FTS index
+#
+CREATE TABLE t1 (FTS_DOC_ID BIGINT UNSIGNED PRIMARY KEY,
+f1 VARCHAR(200),FULLTEXT fidx(f1))engine=innodb;
+ALTER TABLE t1 DROP index fidx, ADD FULLTEXT INDEX(f1);
+DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR(3)) ENGINE=InnoDB;
ALTER TABLE t1 ADD FULLTEXT KEY(a), ADD COLUMN b VARCHAR(3), ADD FULLTEXT KEY(b);
DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test
index c81ec18a4e6..cca110f3550 100644
--- a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test
+++ b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test
@@ -270,6 +270,14 @@ SELECT * FROM articles WHERE MATCH (title, body)
DROP TABLE articles;
+--echo #
+--echo # MDEV-22811 DDL fails to drop and re-create FTS index
+--echo #
+CREATE TABLE t1 (FTS_DOC_ID BIGINT UNSIGNED PRIMARY KEY,
+ f1 VARCHAR(200),FULLTEXT fidx(f1))engine=innodb;
+ALTER TABLE t1 DROP index fidx, ADD FULLTEXT INDEX(f1);
+DROP TABLE t1;
+
# Add more than one FTS index
CREATE TABLE t1 (a VARCHAR(3)) ENGINE=InnoDB;
ALTER TABLE t1 ADD FULLTEXT KEY(a), ADD COLUMN b VARCHAR(3), ADD FULLTEXT KEY(b);
diff --git a/mysql-test/suite/mariabackup/options_check.result b/mysql-test/suite/mariabackup/options_check.result
index 6b9925a0a8e..59666754f04 100644
--- a/mysql-test/suite/mariabackup/options_check.result
+++ b/mysql-test/suite/mariabackup/options_check.result
@@ -5,3 +5,4 @@
# Check for options overwriting
# Check if uknown options that follow --mysqld-args are ingored
# Check if [mariadb-client] group is not loaded (MDEV-22894)
+# Check if --help presents
diff --git a/mysql-test/suite/mariabackup/options_check.test b/mysql-test/suite/mariabackup/options_check.test
index 7483453d19b..022bcbd5d10 100644
--- a/mysql-test/suite/mariabackup/options_check.test
+++ b/mysql-test/suite/mariabackup/options_check.test
@@ -7,7 +7,6 @@
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --unknown-option=xxx --target-dir=$targetdir;
--error 2
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --unknown-option --target-dir=$targetdir;
---enable_result_log
--echo # Check for unknown options in "mariabackup" group
--write_file $custom_cnf
@@ -62,3 +61,9 @@ EOF
exec $XTRABACKUP --defaults-file=$custom_cnf --backup --target-dir=$targetdir;
--remove_file $custom_cnf
--rmdir $targetdir
+
+--echo # Check if --help presents
+exec $XTRABACKUP --help;
+exec $XTRABACKUP -?;
+--enable_result_log
+
diff --git a/mysql-test/suite/rpl/disabled.def b/mysql-test/suite/rpl/disabled.def
index 67e710f2637..9e52c277726 100644
--- a/mysql-test/suite/rpl/disabled.def
+++ b/mysql-test/suite/rpl/disabled.def
@@ -15,7 +15,6 @@ rpl_spec_variables : BUG#11755836 2009-10-27 jasonh rpl_spec_variables fa
rpl_partition_archive : MDEV-5077 2013-09-27 svoj Cannot exchange partition with archive table
rpl_row_binlog_max_cache_size : MDEV-11092
rpl_row_index_choice : MDEV-11666
-rpl_parallel2 : fails after MDEV-16172
rpl_semi_sync_after_sync : fails after MDEV-16172
rpl_slave_grp_exec: MDEV-10514
rpl_auto_increment_update_failure : disabled for now
diff --git a/mysql-test/suite/rpl/extension/checksum.pl b/mysql-test/suite/rpl/extension/checksum.pl
index f94341446cd..8369d1bbdce 100755
--- a/mysql-test/suite/rpl/extension/checksum.pl
+++ b/mysql-test/suite/rpl/extension/checksum.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
#
diff --git a/mysql-test/suite/rpl/r/rpl_binlog_dump_slave_gtid_state_info.result b/mysql-test/suite/rpl/r/rpl_binlog_dump_slave_gtid_state_info.result
new file mode 100644
index 00000000000..98688df7273
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_binlog_dump_slave_gtid_state_info.result
@@ -0,0 +1,47 @@
+include/master-slave.inc
+[connection master]
+connection master;
+SET GLOBAL LOG_WARNINGS=2;
+connection slave;
+include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=current_pos;
+include/start_slave.inc
+connection master;
+"Test Case 1: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('')"
+FOUND 1 /using_gtid\(1\), gtid\(\'\'\).*/ in mysqld.1.err
+connection slave;
+include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=no;
+include/start_slave.inc
+connection master;
+"Test Case 2: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(0), gtid('')"
+FOUND 1 /using_gtid\(0\), gtid\(\'\'\).*/ in mysqld.1.err
+CREATE TABLE t (f INT) ENGINE=INNODB;
+INSERT INTO t VALUES(10);
+connection slave;
+connection slave;
+include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
+include/start_slave.inc
+connection master;
+"Test Case 3: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('0-1-2')"
+FOUND 1 /using_gtid\(1\), gtid\(\'0-1-2\'\).*/ in mysqld.1.err
+SET @@SESSION.gtid_domain_id=10;
+INSERT INTO t VALUES(20);
+connection slave;
+connection slave;
+include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
+include/start_slave.inc
+connection master;
+"Test Case 4: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('0-1-2,10-1-1')"
+FOUND 1 /using_gtid\(1\), gtid\(\'0-1-2,10-1-1\'\).*/ in mysqld.1.err
+"===== Clean up ====="
+connection slave;
+include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=no;
+include/start_slave.inc
+connection master;
+DROP TABLE t;
+SET GLOBAL LOG_WARNINGS=default;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test b/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test
new file mode 100644
index 00000000000..f26e9565671
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test
@@ -0,0 +1,121 @@
+# ==== Purpose ====
+#
+# Test verifies that Start binlog_dump message will report GTID position
+# requested by slave when log_warnings > 1.
+#
+# ==== Implementation ====
+#
+# Steps:
+# 0 - Have LOG_WARNINGS=2
+# 1 - On a fresh slave server which has not replicated any GTIDs execute
+# "CHANGE MASTER TO MASTER_USE_GTID=current_pos;" command. Start the
+# slave.
+# 2 - In Master error log verify that pattern "using_gtid(1), gtid('')" is
+# present.
+# 3 - On slave server do STOP SLAVE and execute "CHANGE MASTER TO
+# MASTER_USE_GTID=no;" command. Start the slave threads.
+# 4 - In Master error log verify that pattern "using_gtid(0), gtid('')" is
+# present.
+# 5- Execute a DDL and DML on master server. This will generated two GTIDs
+# on the master server ('0-1-2'). Sync the slave server with master.
+# 6 - On slave do STOP SLAVE and execute "CHANGE MASTER TO
+# MASTER_USE_GTID=slave_pos;" command. Start slave threads.
+# 7 - In Master error verify that pattern "using_gtid(1), gtid('0-1-2')" is
+# present.
+# 8 - On Master change domain ID to 10 and execute a DML operation. It will
+# generate a GTID 10-1-1.
+# 9 - On slave do STOP SLAVE and execute "CHANGE MASTER TO
+# MASTER_USE_GTID=slave_pos;" command. Start slave threads.
+# 10 -In Master error verify that pattern "using_gtid(1),
+# gtid('0-1-2,10-1-1')" is present.
+#
+# ==== References ====
+#
+# MDEV-20428: "Start binlog_dump" message doesn't indicate GTID position
+#
+
+--source include/have_binlog_format_mixed.inc
+--source include/have_innodb.inc
+--source include/master-slave.inc
+
+--connection master
+SET GLOBAL LOG_WARNINGS=2;
+
+--connection slave
+--source include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=current_pos;
+--source include/start_slave.inc
+
+--connection master
+# Check error log for correct messages.
+let $log_error_= `SELECT @@GLOBAL.log_error`;
+if(!$log_error_)
+{
+ # MySQL Server on windows is started with --console and thus
+ # does not know the location of its .err log, use default location
+ let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.1.err;
+}
+--echo "Test Case 1: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('')"
+--let SEARCH_FILE=$log_error_
+--let SEARCH_RANGE=-50000
+--let SEARCH_PATTERN=using_gtid\(1\), gtid\(\'\'\).*
+--source include/search_pattern_in_file.inc
+
+--connection slave
+--source include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=no;
+--source include/start_slave.inc
+
+--connection master
+--echo "Test Case 2: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(0), gtid('')"
+--let SEARCH_FILE=$log_error_
+--let SEARCH_RANGE=-50000
+--let SEARCH_PATTERN=using_gtid\(0\), gtid\(\'\'\).*
+--source include/search_pattern_in_file.inc
+CREATE TABLE t (f INT) ENGINE=INNODB;
+INSERT INTO t VALUES(10);
+save_master_pos;
+
+--connection slave
+sync_with_master;
+
+--connection slave
+--source include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
+--source include/start_slave.inc
+
+--connection master
+--echo "Test Case 3: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('0-1-2')"
+--let SEARCH_FILE=$log_error_
+--let SEARCH_RANGE=-50000
+--let SEARCH_PATTERN=using_gtid\(1\), gtid\(\'0-1-2\'\).*
+--source include/search_pattern_in_file.inc
+SET @@SESSION.gtid_domain_id=10;
+INSERT INTO t VALUES(20);
+save_master_pos;
+
+--connection slave
+sync_with_master;
+
+--connection slave
+--source include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
+--source include/start_slave.inc
+
+--connection master
+--echo "Test Case 4: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('0-1-2,10-1-1')"
+--let SEARCH_FILE=$log_error_
+--let SEARCH_RANGE=-50000
+--let SEARCH_PATTERN=using_gtid\(1\), gtid\(\'0-1-2,10-1-1\'\).*
+--source include/search_pattern_in_file.inc
+
+--echo "===== Clean up ====="
+--connection slave
+--source include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=no;
+--source include/start_slave.inc
+
+--connection master
+DROP TABLE t;
+SET GLOBAL LOG_WARNINGS=default;
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/versioning/r/sysvars.result b/mysql-test/suite/versioning/r/sysvars.result
index 93d99273a40..ac0a1237902 100644
--- a/mysql-test/suite/versioning/r/sysvars.result
+++ b/mysql-test/suite/versioning/r/sysvars.result
@@ -147,6 +147,35 @@ Variable_name Value
Feature_system_versioning 2
drop table t;
#
+# MDEV-22906 Disallow system_versioning_asof in DML
+#
+create or replace table t1 (x int) with system versioning;
+create or replace table t2 (y int);
+insert into t1 values (1);
+insert into t2 values (1);
+set system_versioning_asof= '1970-01-01 00:00:00';
+delete t1, t2 from t1 join t2 where t1.x = t2.y;
+select * from t1 for system_time as of timestamp now(6);
+x
+insert into t1 values (1);
+insert into t2 values (1);
+update t1, t2 set x= 2, y= 2 where x = y;
+select * from t1 for system_time as of timestamp now(6);
+x
+2
+replace t2 select x + 1 from t1;
+select * from t2;
+y
+2
+3
+insert t2 select x + 2 from t1;
+select * from t2;
+y
+2
+3
+4
+drop tables t1, t2;
+#
# MDEV-16991 Rounding vs truncation for TIME, DATETIME, TIMESTAMP
#
SET sql_mode=TIME_ROUND_FRACTIONAL;
@@ -157,3 +186,4 @@ SELECT @@global.system_versioning_asof;
@@global.system_versioning_asof
2002-01-01 00:00:00.000000
SET @@global.system_versioning_asof= DEFAULT;
+# End of 10.4 tests
diff --git a/mysql-test/suite/versioning/t/sysvars.test b/mysql-test/suite/versioning/t/sysvars.test
index ef5d97ad262..7c5e818ec81 100644
--- a/mysql-test/suite/versioning/t/sysvars.test
+++ b/mysql-test/suite/versioning/t/sysvars.test
@@ -104,6 +104,30 @@ show status like "Feature_system_versioning";
drop table t;
+--echo #
+--echo # MDEV-22906 Disallow system_versioning_asof in DML
+--echo #
+create or replace table t1 (x int) with system versioning;
+create or replace table t2 (y int);
+insert into t1 values (1);
+insert into t2 values (1);
+set system_versioning_asof= '1970-01-01 00:00:00';
+delete t1, t2 from t1 join t2 where t1.x = t2.y;
+select * from t1 for system_time as of timestamp now(6);
+
+insert into t1 values (1);
+insert into t2 values (1);
+update t1, t2 set x= 2, y= 2 where x = y;
+select * from t1 for system_time as of timestamp now(6);
+
+replace t2 select x + 1 from t1;
+select * from t2;
+
+insert t2 select x + 2 from t1;
+select * from t2;
+
+drop tables t1, t2;
+
--echo #
--echo # MDEV-16991 Rounding vs truncation for TIME, DATETIME, TIMESTAMP
@@ -113,3 +137,5 @@ SET sql_mode=TIME_ROUND_FRACTIONAL;
SET @@global.system_versioning_asof= timestamp'2001-12-31 23:59:59.9999999';
SELECT @@global.system_versioning_asof;
SET @@global.system_versioning_asof= DEFAULT;
+
+--echo # End of 10.4 tests
diff --git a/plugin/auth_gssapi/CMakeLists.txt b/plugin/auth_gssapi/CMakeLists.txt
index bdf29580683..3c43d169d07 100644
--- a/plugin/auth_gssapi/CMakeLists.txt
+++ b/plugin/auth_gssapi/CMakeLists.txt
@@ -22,9 +22,9 @@ ELSE()
SET(CMAKE_REQUIRED_LIBRARIES ${GSSAPI_LIBS})
SET(CMAKE_REQUIRED_FLAGS "-Werror -Wall")
INCLUDE(CheckCXXSymbolExists)
- CHECK_CXX_SYMBOL_EXISTS(krb5_free_unparsed_name "krb5.h" HAVE_KRB5_FREE_UNPARSED_NAME)
- IF(HAVE_KRB5_FREE_UNPARSED_NAME)
- ADD_DEFINITIONS(-DHAVE_KRB5_FREE_UNPARSED_NAME=1)
+ CHECK_CXX_SYMBOL_EXISTS(krb5_xfree "krb5.h" HAVE_KRB5_XFREE)
+ IF(HAVE_KRB5_XFREE)
+ ADD_DEFINITIONS(-DHAVE_KRB5_XFREE=1)
ENDIF()
ELSE()
diff --git a/plugin/auth_gssapi/gssapi_server.cc b/plugin/auth_gssapi/gssapi_server.cc
index c040300a8b2..db7bda9a6b4 100644
--- a/plugin/auth_gssapi/gssapi_server.cc
+++ b/plugin/auth_gssapi/gssapi_server.cc
@@ -30,7 +30,7 @@ static void log_error( OM_uint32 major, OM_uint32 minor, const char *msg)
Generate default principal service name formatted as principal name "mariadb/server.fqdn@REALM"
*/
#include <krb5.h>
-#ifndef HAVE_KRB5_FREE_UNPARSED_NAME
+#ifdef HAVE_KRB5_XFREE
#define krb5_free_unparsed_name(a,b) krb5_xfree(b)
#endif
static char* get_default_principal_name()
diff --git a/plugin/handler_socket/client/hspool_test.pl b/plugin/handler_socket/client/hspool_test.pl
index 091cb4967cb..03227e31b56 100755
--- a/plugin/handler_socket/client/hspool_test.pl
+++ b/plugin/handler_socket/client/hspool_test.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
use strict;
use warnings;
diff --git a/plugin/handler_socket/client/hstest.pl b/plugin/handler_socket/client/hstest.pl
index de39fcb6d6c..1363e153c44 100755
--- a/plugin/handler_socket/client/hstest.pl
+++ b/plugin/handler_socket/client/hstest.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=8:ai:ts=8
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm b/plugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm
index c51fe60d591..b6ea62651a3 100755
--- a/plugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
package Net::HandlerSocket::HSPool;
diff --git a/plugin/handler_socket/regtest/test_01_lib/test01.pl b/plugin/handler_socket/regtest/test_01_lib/test01.pl
index d3a072fb3cc..0a3ad9e9b25 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test01.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test01.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test02.pl b/plugin/handler_socket/regtest/test_01_lib/test02.pl
index c69515d76e9..f9bdc8b6738 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test02.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test02.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test03.pl b/plugin/handler_socket/regtest/test_01_lib/test03.pl
index a081786c132..a51aaf3b257 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test03.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test03.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test04.pl b/plugin/handler_socket/regtest/test_01_lib/test04.pl
index 52fe11364c8..d922b713271 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test04.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test04.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test05.pl b/plugin/handler_socket/regtest/test_01_lib/test05.pl
index 10b1a0805a0..2993e7a9680 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test05.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test05.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test06.pl b/plugin/handler_socket/regtest/test_01_lib/test06.pl
index fb0549f2295..69dd107e1ff 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test06.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test06.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test07.pl b/plugin/handler_socket/regtest/test_01_lib/test07.pl
index fa9802366d8..2286aeba9fe 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test07.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test07.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test08.pl b/plugin/handler_socket/regtest/test_01_lib/test08.pl
index c33bf190d29..da736ef34c3 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test08.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test08.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test09.pl b/plugin/handler_socket/regtest/test_01_lib/test09.pl
index 14fd9c26641..7d6165ece1e 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test09.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test09.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test10.pl b/plugin/handler_socket/regtest/test_01_lib/test10.pl
index fd294fe8b78..560976ba9b2 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test10.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test10.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test11.pl b/plugin/handler_socket/regtest/test_01_lib/test11.pl
index 5cfe3e83614..cfaa940572c 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test11.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test11.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test12.pl b/plugin/handler_socket/regtest/test_01_lib/test12.pl
index 100a779de4e..0cae3798372 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test12.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test12.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test13.pl b/plugin/handler_socket/regtest/test_01_lib/test13.pl
index 1e1104d2a07..2068c4bc9b6 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test13.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test13.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test14.pl b/plugin/handler_socket/regtest/test_01_lib/test14.pl
index ff4e433ae8f..ab89073370b 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test14.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test14.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test15.pl b/plugin/handler_socket/regtest/test_01_lib/test15.pl
index 4c56d355708..2205be5b363 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test15.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test15.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test16.pl b/plugin/handler_socket/regtest/test_01_lib/test16.pl
index 6db8c576d7a..c0c3fc556ff 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test16.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test16.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test17.pl b/plugin/handler_socket/regtest/test_01_lib/test17.pl
index 1ffd7fa1242..7c150dab746 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test17.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test17.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test18.pl b/plugin/handler_socket/regtest/test_01_lib/test18.pl
index 87047bc9cba..7854642af15 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test18.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test18.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test19.pl b/plugin/handler_socket/regtest/test_01_lib/test19.pl
index 9870199c1a7..2e5363c8137 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test19.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test19.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test20.pl b/plugin/handler_socket/regtest/test_01_lib/test20.pl
index 139bbf9aba1..96307e0a5f0 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test20.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test20.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test21.pl b/plugin/handler_socket/regtest/test_01_lib/test21.pl
index 413ea636400..34e9d43972b 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test21.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test21.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test22.pl b/plugin/handler_socket/regtest/test_01_lib/test22.pl
index cf029944292..370d16d6027 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test22.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test22.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test23.pl b/plugin/handler_socket/regtest/test_01_lib/test23.pl
index 83c2194bfa6..d9bd0381251 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test23.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test23.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test24.pl b/plugin/handler_socket/regtest/test_01_lib/test24.pl
index 6cd95a995e5..f4e3bb3f10c 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test24.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test24.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/scripts/convert-debug-for-diff.sh b/scripts/convert-debug-for-diff.sh
index 5b3ce05b815..60b328d946b 100755
--- a/scripts/convert-debug-for-diff.sh
+++ b/scripts/convert-debug-for-diff.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -i
+#!/usr/bin/env perl -i
#
# This script converts all numbers that look like addresses or memory sizes,
# in a debug files generated by --debug (like mysqld --debug-dbug), to #.
diff --git a/scripts/mytop.sh b/scripts/mytop.sh
index c8de6c56f3e..f4e6dffb3b5 100644
--- a/scripts/mytop.sh
+++ b/scripts/mytop.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
#
# $Id: mytop,v 1.99-maria6 2019/10/22 14:53:51 jweisbuch Exp $
diff --git a/sql-bench/as3ap.sh b/sql-bench/as3ap.sh
index fd2b6ba3b25..8e4b3167429 100644
--- a/sql-bench/as3ap.sh
+++ b/sql-bench/as3ap.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/bench-count-distinct.sh b/sql-bench/bench-count-distinct.sh
index 9ce9b2fb168..b6465d0635f 100644
--- a/sql-bench/bench-count-distinct.sh
+++ b/sql-bench/bench-count-distinct.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/bench-init.pl.sh b/sql-bench/bench-init.pl.sh
index a6a12603e6d..f23ef6f5949 100644
--- a/sql-bench/bench-init.pl.sh
+++ b/sql-bench/bench-init.pl.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000-2003, 2005-2007 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/compare-results.sh b/sql-bench/compare-results.sh
index f0658160db2..06e247bae8a 100644
--- a/sql-bench/compare-results.sh
+++ b/sql-bench/compare-results.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2001, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/copy-db.sh b/sql-bench/copy-db.sh
index 38a010e52ab..d70472feaff 100644
--- a/sql-bench/copy-db.sh
+++ b/sql-bench/copy-db.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/crash-me.sh b/sql-bench/crash-me.sh
index a7298c5f9a1..26f66f94735 100644
--- a/sql-bench/crash-me.sh
+++ b/sql-bench/crash-me.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- perl -*-
# Copyright (c) 2000-2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
diff --git a/sql-bench/graph-compare-results.sh b/sql-bench/graph-compare-results.sh
index ddc9080acd6..d43f722cb14 100755
--- a/sql-bench/graph-compare-results.sh
+++ b/sql-bench/graph-compare-results.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
####
#### Hello ... this is a heavily hacked script by Luuk
#### instead of printing the result it makes a nice gif
diff --git a/sql-bench/innotest1.sh b/sql-bench/innotest1.sh
index 9e1ed32c273..1b99f601f42 100644
--- a/sql-bench/innotest1.sh
+++ b/sql-bench/innotest1.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
############################################################################
# Stress test for MySQL/InnoDB combined database
# (c) 2002 Innobase Oy & MySQL AB
diff --git a/sql-bench/innotest1a.sh b/sql-bench/innotest1a.sh
index 1e428e33dcf..7183c901831 100644
--- a/sql-bench/innotest1a.sh
+++ b/sql-bench/innotest1a.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
############################################################################
# Stress test for MySQL/InnoDB combined database
# (c) 2002 Innobase Oy & MySQL AB
diff --git a/sql-bench/innotest1b.sh b/sql-bench/innotest1b.sh
index 524a6e0e145..0a909d1a8f6 100644
--- a/sql-bench/innotest1b.sh
+++ b/sql-bench/innotest1b.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
############################################################################
# Stress test for MySQL/InnoDB combined database
# (c) 2002 Innobase Oy & MySQL AB
diff --git a/sql-bench/innotest2.sh b/sql-bench/innotest2.sh
index fa0fd418968..941b0ac8b59 100644
--- a/sql-bench/innotest2.sh
+++ b/sql-bench/innotest2.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
############################################################################
# Stress test for MySQL/InnoDB combined database
# (c) 2002 Innobase Oy & MySQL AB
diff --git a/sql-bench/innotest2a.sh b/sql-bench/innotest2a.sh
index 4a6e4b20a9a..e873d2b458c 100644
--- a/sql-bench/innotest2a.sh
+++ b/sql-bench/innotest2a.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
############################################################################
# Stress test for MySQL/Innobase combined database
# (c) 2000 Innobase Oy & MySQL AB
diff --git a/sql-bench/innotest2b.sh b/sql-bench/innotest2b.sh
index b94325ff39e..56b44eda561 100644
--- a/sql-bench/innotest2b.sh
+++ b/sql-bench/innotest2b.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
############################################################################
# Stress test for MySQL/Innobase combined database
# (c) 2000 Innobase Oy & MySQL AB
diff --git a/sql-bench/run-all-tests.sh b/sql-bench/run-all-tests.sh
index 5d77c8c388d..ecab48e88fe 100644
--- a/sql-bench/run-all-tests.sh
+++ b/sql-bench/run-all-tests.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2001, 2003, 2006, 2007 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/server-cfg.sh b/sql-bench/server-cfg.sh
index 6ef39c4d91f..d862f367c1c 100644
--- a/sql-bench/server-cfg.sh
+++ b/sql-bench/server-cfg.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- perl -*-
# Copyright (c) 2000-2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
diff --git a/sql-bench/test-ATIS.sh b/sql-bench/test-ATIS.sh
index d7ef5dca476..c51688de0c2 100644
--- a/sql-bench/test-ATIS.sh
+++ b/sql-bench/test-ATIS.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/test-alter-table.sh b/sql-bench/test-alter-table.sh
index e092453b16a..350c6fae2c6 100644
--- a/sql-bench/test-alter-table.sh
+++ b/sql-bench/test-alter-table.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/test-big-tables.sh b/sql-bench/test-big-tables.sh
index e2cf983de1c..6be907d0ee6 100644
--- a/sql-bench/test-big-tables.sh
+++ b/sql-bench/test-big-tables.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/test-connect.sh b/sql-bench/test-connect.sh
index 1226301df9b..e3acb453a30 100644
--- a/sql-bench/test-connect.sh
+++ b/sql-bench/test-connect.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/test-create.sh b/sql-bench/test-create.sh
index 7af6fa13562..09961f0d698 100644
--- a/sql-bench/test-create.sh
+++ b/sql-bench/test-create.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000-2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/test-insert.sh b/sql-bench/test-insert.sh
index 3e35ac5ff5c..dbdc58fdcca 100644
--- a/sql-bench/test-insert.sh
+++ b/sql-bench/test-insert.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000-2003, 2006, 2007 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/test-select.sh b/sql-bench/test-select.sh
index 4c7147b57a4..e3020698cb8 100644
--- a/sql-bench/test-select.sh
+++ b/sql-bench/test-select.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/test-table-elimination.sh b/sql-bench/test-table-elimination.sh
index de440fc0633..c3a264492a4 100755
--- a/sql-bench/test-table-elimination.sh
+++ b/sql-bench/test-table-elimination.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Test of table elimination feature
use Cwd;
diff --git a/sql-bench/test-transactions.sh b/sql-bench/test-transactions.sh
index 4732658c529..334a6f0a385 100644
--- a/sql-bench/test-transactions.sh
+++ b/sql-bench/test-transactions.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/test-wisconsin.sh b/sql-bench/test-wisconsin.sh
index 47c9e050304..581db89712e 100644
--- a/sql-bench/test-wisconsin.sh
+++ b/sql-bench/test-wisconsin.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql/field.cc b/sql/field.cc
index 8e8ed7df0cb..9b6f117a82e 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -11107,6 +11107,46 @@ void Field_blob::print_key_value(String *out, uint32 length)
}
+/*
+ @brief Print value of the key part
+
+ @param
+ out Output string
+ key value of the key
+ length Length of field in bytes,
+ excluding NULL flag and length bytes
+*/
+
+
+void
+Field::print_key_part_value(String *out, const uchar* key, uint32 length)
+{
+ StringBuffer<128> tmp(system_charset_info);
+ uint null_byte= 0;
+ if (real_maybe_null())
+ {
+ /*
+ Byte 0 of key is the null-byte. If set, key is NULL.
+ Otherwise, print the key value starting immediately after the
+ null-byte
+ */
+ if (*key)
+ {
+ out->append(STRING_WITH_LEN("NULL"));
+ return;
+ }
+ null_byte++; // Skip null byte
+ }
+
+ set_key_image(key + null_byte, length);
+ print_key_value(&tmp, length);
+ if (charset() == &my_charset_bin)
+ out->append(tmp.ptr(), tmp.length(), tmp.charset());
+ else
+ tmp.print(out, system_charset_info);
+}
+
+
void Field::print_key_value_binary(String *out, const uchar* key, uint32 length)
{
out->append_semi_hex((const char*)key, length, charset());
diff --git a/sql/field.h b/sql/field.h
index e4c5ffcc0de..420ff6866bd 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1611,6 +1611,7 @@ public:
bool set_warning(Sql_condition::enum_warning_level, unsigned int code,
int cuted_increment, ulong current_row=0) const;
virtual void print_key_value(String *out, uint32 length);
+ void print_key_part_value(String *out, const uchar *key, uint32 length);
void print_key_value_binary(String *out, const uchar* key, uint32 length);
protected:
bool set_warning(unsigned int code, int cuted_increment) const
diff --git a/sql/filesort.cc b/sql/filesort.cc
index ac43c96b0e0..f5d57a36685 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -586,7 +586,14 @@ Filesort::make_sortorder(THD *thd, JOIN *join, table_map first_table_bit)
if (item->type() == Item::FIELD_ITEM)
pos->field= ((Item_field*) item)->field;
else if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item())
- pos->field= ((Item_sum*) item)->get_tmp_table_field();
+ {
+ // Aggregate, or Item_aggregate_ref
+ DBUG_ASSERT(first->type() == Item::SUM_FUNC_ITEM ||
+ (first->type() == Item::REF_ITEM &&
+ static_cast<Item_ref*>(first)->ref_type() ==
+ Item_ref::AGGREGATE_REF));
+ pos->field= first->get_tmp_table_field();
+ }
else if (item->type() == Item::COPY_STR_ITEM)
{ // Blob patch
pos->item= ((Item_copy*) item)->get_item();
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc
index fe3fae5840c..aec3e1edcd3 100644
--- a/sql/item_jsonfunc.cc
+++ b/sql/item_jsonfunc.cc
@@ -951,6 +951,41 @@ double Item_func_json_extract::val_real()
}
+my_decimal *Item_func_json_extract::val_decimal(my_decimal *to)
+{
+ json_value_types type;
+ char *value;
+ int value_len;
+
+ if (read_json(NULL, &type, &value, &value_len) != NULL)
+ {
+ switch (type)
+ {
+ case JSON_VALUE_STRING:
+ case JSON_VALUE_NUMBER:
+ {
+ my_decimal *res= decimal_from_string_with_check(to, collation.collation,
+ value,
+ value + value_len);
+ null_value= res == NULL;
+ return res;
+ }
+ case JSON_VALUE_TRUE:
+ int2my_decimal(E_DEC_FATAL_ERROR, 1, false/*unsigned_flag*/, to);
+ return to;
+ case JSON_VALUE_OBJECT:
+ case JSON_VALUE_ARRAY:
+ case JSON_VALUE_FALSE:
+ case JSON_VALUE_NULL:
+ break;
+ };
+ }
+ int2my_decimal(E_DEC_FATAL_ERROR, 0, false/*unsigned_flag*/, to);
+ return to;
+}
+
+
+
bool Item_func_json_contains::fix_length_and_dec()
{
a2_constant= args[1]->const_item();
diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h
index 69625831045..6bd2a81afc6 100644
--- a/sql/item_jsonfunc.h
+++ b/sql/item_jsonfunc.h
@@ -241,6 +241,7 @@ public:
String *val_str(String *);
longlong val_int();
double val_real();
+ my_decimal *val_decimal(my_decimal *);
uint get_n_paths() const { return arg_count - 1; }
Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_json_extract>(thd, this); }
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 23ff906e3cf..1690ec96e65 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -2104,7 +2104,7 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
The swap is needed for expressions of type 'f1 < ALL ( SELECT ....)'
where we want to evaluate the sub query even if f1 would be null.
*/
- subs= func->create_swap(thd, *(optimizer->get_cache()), subs);
+ subs= func->create_swap(thd, expr, subs);
thd->change_item_tree(place, subs);
if (subs->fix_fields(thd, &subs))
DBUG_RETURN(true);
diff --git a/sql/item_windowfunc.cc b/sql/item_windowfunc.cc
index acf2ee4fdda..25e86c5d777 100644
--- a/sql/item_windowfunc.cc
+++ b/sql/item_windowfunc.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2016,2017 MariaDB
+ Copyright (c) 2016, 2020, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -341,9 +341,9 @@ bool Item_sum_hybrid_simple::fix_fields(THD *thd, Item **ref)
for (uint i= 0; i < arg_count; i++)
{
- // 'item' can be changed during fix_fields
if (args[i]->fix_fields_if_needed_for_scalar(thd, &args[i]))
return TRUE;
+ with_window_func|= args[i]->with_window_func;
}
for (uint i= 0; i < arg_count && !m_with_subquery; i++)
diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc
index ed3f777b1de..651eea33304 100644
--- a/sql/mysql_install_db.cc
+++ b/sql/mysql_install_db.cc
@@ -426,8 +426,8 @@ static int register_service()
static void clean_directory(const char *dir)
{
- char dir2[MAX_PATH+2];
- *(strmake_buf(dir2, dir)+1)= 0;
+ char dir2[MAX_PATH + 4]= {};
+ snprintf(dir2, MAX_PATH+2, "%s\\*", dir);
SHFILEOPSTRUCT fileop;
fileop.hwnd= NULL; /* no status display */
@@ -556,7 +556,7 @@ static int create_db_instance()
DWORD cwd_len= MAX_PATH;
char cmdline[3*MAX_PATH];
FILE *in;
- bool cleanup_datadir= true;
+ bool created_datadir= false;
DWORD last_error;
verbose("Running bootstrap");
@@ -565,7 +565,11 @@ static int create_db_instance()
/* Create datadir and datadir/mysql, if they do not already exist. */
- if (!CreateDirectory(opt_datadir, NULL) && (GetLastError() != ERROR_ALREADY_EXISTS))
+ if (CreateDirectory(opt_datadir, NULL))
+ {
+ created_datadir= true;
+ }
+ else if (GetLastError() != ERROR_ALREADY_EXISTS)
{
last_error = GetLastError();
switch(last_error)
@@ -602,9 +606,11 @@ static int create_db_instance()
}
}
- if (PathIsDirectoryEmpty(opt_datadir))
+ if (!PathIsDirectoryEmpty(opt_datadir))
{
- cleanup_datadir= false;
+ fprintf(stderr,"ERROR : Data directory %s is not empty."
+ " Only new or empty existing directories are accepted for --datadir\n",opt_datadir);
+ exit(1);
}
if (!CreateDirectory("mysql",NULL))
@@ -732,10 +738,12 @@ static int create_db_instance()
}
end:
- if (ret && cleanup_datadir)
+ if (ret)
{
SetCurrentDirectory(cwd);
clean_directory(opt_datadir);
+ if (created_datadir)
+ RemoveDirectory(opt_datadir);
}
return ret;
}
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 80d67d884bf..1993dc265a0 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -442,6 +442,13 @@ static
void print_range(String *out, const KEY_PART_INFO *key_part,
KEY_MULTI_RANGE *range, uint n_key_parts);
+static
+void print_range_for_non_indexed_field(String *out, Field *field,
+ KEY_MULTI_RANGE *range);
+
+static void print_min_range_operator(String *out, const ha_rkey_function flag);
+static void print_max_range_operator(String *out, const ha_rkey_function flag);
+
/*
SEL_IMERGE is a list of possible ways to do index merge, i.e. it is
@@ -2691,10 +2698,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
DBUG_PRINT("info",("Time to scan table: %g", read_time));
Json_writer_object table_records(thd);
- if (head->reginfo.join_tab)
- table_records.add_table_name(head->reginfo.join_tab);
- else
- table_records.add_table_name(head);
+ table_records.add_table_name(head);
+
Json_writer_object trace_range(thd, "range_analysis");
{
Json_writer_object table_rec(thd, "table_scan");
@@ -3191,6 +3196,7 @@ static
double records_in_column_ranges(PARAM *param, uint idx,
SEL_ARG *tree)
{
+ THD *thd= param->thd;
SEL_ARG_RANGE_SEQ seq;
KEY_MULTI_RANGE range;
range_seq_t seq_it;
@@ -3217,6 +3223,8 @@ double records_in_column_ranges(PARAM *param, uint idx,
seq_it= seq_if.init((void *) &seq, 0, flags);
+ Json_writer_array range_trace(thd, "ranges");
+
while (!seq_if.next(seq_it, &range))
{
key_range *min_endp, *max_endp;
@@ -3233,6 +3241,13 @@ double records_in_column_ranges(PARAM *param, uint idx,
if (range.start_key.flag == HA_READ_BEFORE_KEY)
range_flag |= NEAR_MAX;
+ if (unlikely(thd->trace_started()))
+ {
+ StringBuffer<128> range_info(system_charset_info);
+ print_range_for_non_indexed_field(&range_info, field, &range);
+ range_trace.add(range_info.c_ptr_safe(), range_info.length());
+ }
+
rows= get_column_range_cardinality(field, min_endp, max_endp, range_flag);
if (DBL_MAX == rows)
{
@@ -15820,6 +15835,37 @@ void QUICK_GROUP_MIN_MAX_SELECT::dbug_dump(int indent, bool verbose)
#endif /* !DBUG_OFF */
+
+/*
+ @brief Print the comparison operator for the min range
+*/
+
+static void print_min_range_operator(String *out, const ha_rkey_function flag)
+{
+ if (flag == HA_READ_AFTER_KEY)
+ out->append(STRING_WITH_LEN(" < "));
+ else if (flag == HA_READ_KEY_EXACT || flag == HA_READ_KEY_OR_NEXT)
+ out->append(STRING_WITH_LEN(" <= "));
+ else
+ out->append(STRING_WITH_LEN(" ? "));
+}
+
+
+/*
+ @brief Print the comparison operator for the max range
+*/
+
+static void print_max_range_operator(String *out, const ha_rkey_function flag)
+{
+ if (flag == HA_READ_BEFORE_KEY)
+ out->append(STRING_WITH_LEN(" < "));
+ else if (flag == HA_READ_AFTER_KEY)
+ out->append(STRING_WITH_LEN(" <= "));
+ else
+ out->append(STRING_WITH_LEN(" ? "));
+}
+
+
static
void print_range(String *out, const KEY_PART_INFO *key_part,
KEY_MULTI_RANGE *range, uint n_key_parts)
@@ -15848,30 +15894,55 @@ void print_range(String *out, const KEY_PART_INFO *key_part,
{
print_key_value(out, key_part, range->start_key.key,
range->start_key.length);
- if (range->start_key.flag == HA_READ_AFTER_KEY)
- out->append(STRING_WITH_LEN(" < "));
- else if (range->start_key.flag == HA_READ_KEY_EXACT ||
- range->start_key.flag == HA_READ_KEY_OR_NEXT)
- out->append(STRING_WITH_LEN(" <= "));
- else
- out->append(STRING_WITH_LEN(" ? "));
+ print_min_range_operator(out, range->start_key.flag);
}
print_keyparts_name(out, key_part, n_key_parts, keypart_map);
if (range->end_key.length)
{
- if (range->end_key.flag == HA_READ_BEFORE_KEY)
- out->append(STRING_WITH_LEN(" < "));
- else if (range->end_key.flag == HA_READ_AFTER_KEY)
- out->append(STRING_WITH_LEN(" <= "));
- else
- out->append(STRING_WITH_LEN(" ? "));
+ print_max_range_operator(out, range->end_key.flag);
print_key_value(out, key_part, range->end_key.key,
range->end_key.length);
}
}
+
+/*
+ @brief Print range created for non-indexed columns
+
+ @param
+ out output string
+ field field for which the range is printed
+ range range for the field
+*/
+
+static
+void print_range_for_non_indexed_field(String *out, Field *field,
+ KEY_MULTI_RANGE *range)
+{
+ TABLE *table= field->table;
+ my_bitmap_map *old_sets[2];
+ dbug_tmp_use_all_columns(table, old_sets, table->read_set, table->write_set);
+
+ if (range->start_key.length)
+ {
+ field->print_key_part_value(out, range->start_key.key, field->key_length());
+ print_min_range_operator(out, range->start_key.flag);
+ }
+
+ out->append(field->field_name);
+
+ if (range->end_key.length)
+ {
+ print_max_range_operator(out, range->end_key.flag);
+ field->print_key_part_value(out, range->end_key.key, field->key_length());
+ }
+ dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets);
+}
+
+
+
/*
Add ranges to the trace
@@ -15943,30 +16014,8 @@ static void print_key_value(String *out, const KEY_PART_INFO *key_part,
field= key_part->field;
store_length= key_part->store_length;
- if (field->real_maybe_null())
- {
- /*
- Byte 0 of key is the null-byte. If set, key is NULL.
- Otherwise, print the key value starting immediately after the
- null-byte
- */
- if (*key)
- {
- out->append(STRING_WITH_LEN("NULL"));
- goto next;
- }
- key++; // Skip null byte
- store_length--;
- }
-
- field->set_key_image(key, key_part->length);
- field->print_key_value(&tmp, key_part->length);
- if (field->charset() == &my_charset_bin)
- out->append(tmp.ptr(), tmp.length(), tmp.charset());
- else
- tmp.print(out, system_charset_info);
+ field->print_key_part_value(out, key, key_part->length);
- next:
if (key + store_length < key_end)
out->append(STRING_WITH_LEN(","));
}
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index d8ef17e3494..11eccefdde9 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -1473,8 +1473,14 @@ bool Relay_log_info::stmt_done(my_off_t event_master_log_pos, THD *thd,
}
DBUG_EXECUTE_IF("inject_crash_before_flush_rli", DBUG_SUICIDE(););
if (mi->using_gtid == Master_info::USE_GTID_NO)
+ {
+ if (rgi->is_parallel_exec)
+ mysql_mutex_lock(&data_lock);
if (flush())
error= 1;
+ if (rgi->is_parallel_exec)
+ mysql_mutex_unlock(&data_lock);
+ }
DBUG_EXECUTE_IF("inject_crash_after_flush_rli", DBUG_SUICIDE(););
}
DBUG_RETURN(error);
diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc
index 147b2568981..5e3f32eae4e 100644
--- a/sql/signal_handler.cc
+++ b/sql/signal_handler.cc
@@ -279,7 +279,7 @@ extern "C" sig_handler handle_fatal_signal(int sig)
}
my_safe_printf_stderr("%s",
"The manual page at "
- "http://dev.mysql.com/doc/mysql/en/crashing.html contains\n"
+ "https://mariadb.com/kb/en/how-to-produce-a-full-stack-trace-for-mysqld/ contains\n"
"information that should help you find out what is causing the crash.\n");
#endif /* HAVE_STACKTRACE */
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index adfa0c08959..b6dcb49ed08 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates.
- Copyright (c) 2010, 2019, 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
@@ -1015,7 +1015,7 @@ public:
int save_union_explain_part2(Explain_query *output);
unit_common_op common_op();
- bool explainable()
+ bool explainable() const
{
/*
EXPLAIN/ANALYZE unit, when:
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index cd60472e81c..167aefee7a6 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -942,11 +942,6 @@ void execute_init_command(THD *thd, LEX_STRING *init_command,
char *buf= thd->strmake(init_command->str, len);
mysql_rwlock_unlock(var_lock);
-#if defined(ENABLED_PROFILING)
- thd->profiling.start_new_query();
- thd->profiling.set_query_source(buf, len);
-#endif
-
THD_STAGE_INFO(thd, stage_execution_of_init_command);
save_client_capabilities= thd->client_capabilities;
thd->client_capabilities|= CLIENT_MULTI_QUERIES;
@@ -961,9 +956,6 @@ void execute_init_command(THD *thd, LEX_STRING *init_command,
thd->client_capabilities= save_client_capabilities;
thd->net.vio= save_vio;
-#if defined(ENABLED_PROFILING)
- thd->profiling.finish_current_query();
-#endif
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 6dbdfe75767..93bef049d28 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -853,6 +853,8 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array,
if (param->convert_str_value(thd))
DBUG_RETURN(1); /* out of memory */
+
+ param->sync_clones();
}
if (acc.finalize())
DBUG_RETURN(1);
@@ -3130,7 +3132,10 @@ static void reset_stmt_params(Prepared_statement *stmt)
Item_param **item= stmt->param_array;
Item_param **end= item + stmt->param_count;
for (;item < end ; ++item)
+ {
(**item).reset();
+ (**item).sync_clones();
+ }
}
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 83ae25c962d..3ed0e288870 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -2121,9 +2121,13 @@ static int init_binlog_sender(binlog_send_info *info,
});
if (global_system_variables.log_warnings > 1)
+ {
sql_print_information(
- "Start binlog_dump to slave_server(%lu), pos(%s, %lu)",
- thd->variables.server_id, log_ident, (ulong)*pos);
+ "Start binlog_dump to slave_server(%lu), pos(%s, %lu), "
+ "using_gtid(%d), gtid('%s')", thd->variables.server_id,
+ log_ident, (ulong)*pos, info->using_gtid_state,
+ connect_gtid_state.c_ptr_quick());
+ }
#ifndef DBUG_OFF
if (opt_sporadic_binlog_dump_fail && (binlog_dump_count++ % 2))
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 52e6b905638..552363f80c0 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -982,9 +982,12 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
}
bool is_select= false;
+ bool use_sysvar= false;
switch (thd->lex->sql_command)
{
case SQLCOM_SELECT:
+ use_sysvar= true;
+ /* fall through */
case SQLCOM_INSERT_SELECT:
case SQLCOM_REPLACE_SELECT:
case SQLCOM_DELETE_MULTI:
@@ -1028,7 +1031,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
}
// propagate system_time from sysvar
- if (!vers_conditions.is_set() && is_select)
+ if (!vers_conditions.is_set() && use_sysvar)
{
if (vers_conditions.init_from_sysvar(thd))
DBUG_RETURN(-1);
@@ -6942,6 +6945,7 @@ void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
uint n_tables= my_count_bits(map);
if (n_tables == 1) // Only one table
{
+ DBUG_ASSERT(!(map & PSEUDO_TABLE_BITS)); // Must be a real table
Table_map_iterator it(map);
int tablenr= it.next_bit();
DBUG_ASSERT(tablenr != Table_map_iterator::BITMAP_END);
@@ -16610,10 +16614,15 @@ static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
/**
- Set NESTED_JOIN::counter=0 in all nested joins in passed list.
+ Set NESTED_JOIN::counter and n_tables in all nested joins in passed list.
- Recursively set NESTED_JOIN::counter=0 for all nested joins contained in
- the passed join_list.
+ For all nested joins contained in the passed join_list (including its
+ children), set:
+ - nested_join->counter=0
+ - nested_join->n_tables= {number of non-degenerate direct children}.
+
+ Non-degenerate means non-const base table or a join nest that has a
+ non-degenerate child.
@param join_list List of nested joins to process. It may also contain base
tables which will be ignored.
@@ -16636,8 +16645,11 @@ static uint reset_nj_counters(JOIN *join, List<TABLE_LIST> *join_list)
if (!nested_join->n_tables)
is_eliminated_nest= TRUE;
}
- if ((table->nested_join && !is_eliminated_nest) ||
- (!table->nested_join && (table->table->map & ~join->eliminated_tables)))
+ const table_map removed_tables= join->eliminated_tables |
+ join->const_table_map;
+
+ if ((table->nested_join && !is_eliminated_nest) ||
+ (!table->nested_join && (table->table->map & ~removed_tables)))
n++;
}
DBUG_RETURN(n);
@@ -27062,13 +27074,18 @@ int JOIN::save_explain_data_intern(Explain_query *output,
output->add_node(xpl_sel);
}
- for (SELECT_LEX_UNIT *tmp_unit= join->select_lex->first_inner_unit();
- tmp_unit;
- tmp_unit= tmp_unit->next_unit())
- {
- if (tmp_unit->explainable())
- explain->add_child(tmp_unit->first_select()->select_number);
- }
+ /*
+ Don't try to add query plans for child selects if this select was pushed
+ down into a Smart Storage Engine:
+ - the entire statement was pushed down ("PUSHED SELECT"), or
+ - this derived table was pushed down ("PUSHED DERIVED")
+ */
+ if (!select_lex->pushdown_select && select_lex->type != pushed_derived_text)
+ for (SELECT_LEX_UNIT *tmp_unit= join->select_lex->first_inner_unit();
+ tmp_unit;
+ tmp_unit= tmp_unit->next_unit())
+ if (tmp_unit->explainable())
+ explain->add_child(tmp_unit->first_select()->select_number);
if (select_lex->is_top_level_node())
output->query_plan_ready();
@@ -27099,7 +27116,16 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
THD *thd=join->thd;
select_result *result=join->result;
DBUG_ENTER("select_describe");
-
+
+ if (join->select_lex->pushdown_select)
+ {
+ /*
+ The whole statement was pushed down to a Smart Storage Engine. Do not
+ attempt to produce a query plan locally.
+ */
+ DBUG_VOID_RETURN;
+ }
+
/* Update the QPF with latest values of using_temporary, using_filesort */
for (SELECT_LEX_UNIT *unit= join->select_lex->first_inner_unit();
unit;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index f61c5677ced..5eb2d911926 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -5275,6 +5275,29 @@ bool store_schema_schemata(THD* thd, TABLE *table, LEX_CSTRING *db_name,
}
+/*
+ Check if the specified database exists on disk.
+
+ @param dbname - the database name
+ @retval true - on error, the database directory does not exists
+ @retval false - on success, the database directory exists
+*/
+static bool verify_database_directory_exists(const LEX_CSTRING &dbname)
+{
+ DBUG_ENTER("verify_database_directory_exists");
+ char path[FN_REFLEN + 16];
+ uint path_len;
+ MY_STAT stat_info;
+ if (!dbname.str[0])
+ DBUG_RETURN(true); // Empty database name: does not exist.
+ path_len= build_table_filename(path, sizeof(path) - 1, dbname.str, "", "", 0);
+ path[path_len - 1]= 0;
+ if (!mysql_file_stat(key_file_misc, path, &stat_info, MYF(0)))
+ DBUG_RETURN(true); // The database directory was not found: does not exist.
+ DBUG_RETURN(false); // The database directory was found.
+}
+
+
int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
{
/*
@@ -5303,19 +5326,10 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
If we have lookup db value we should check that the database exists
*/
if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value &&
- db_names.at(0) != &INFORMATION_SCHEMA_NAME)
- {
- char path[FN_REFLEN+16];
- uint path_len;
- MY_STAT stat_info;
- if (!lookup_field_vals.db_value.str[0])
- DBUG_RETURN(0);
- path_len= build_table_filename(path, sizeof(path) - 1,
- lookup_field_vals.db_value.str, "", "", 0);
- path[path_len-1]= 0;
- if (!mysql_file_stat(key_file_misc, path, &stat_info, MYF(0)))
- DBUG_RETURN(0);
- }
+ (!db_names.elements() /* The database name was too long */||
+ (db_names.at(0) != &INFORMATION_SCHEMA_NAME &&
+ verify_database_directory_exists(lookup_field_vals.db_value))))
+ DBUG_RETURN(0);
for (size_t i=0; i < db_names.elements(); i++)
{
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 5c491421511..f091fd29303 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -9844,11 +9844,16 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
(!create_info->db_type || /* unknown engine */
!(create_info->db_type->flags & HTON_SUPPORT_LOG_TABLES)))
{
+ unsupported:
my_error(ER_UNSUPORTED_LOG_ENGINE, MYF(0),
hton_name(create_info->db_type)->str);
DBUG_RETURN(true);
}
+ if (create_info->db_type == maria_hton &&
+ create_info->transactional != HA_CHOICE_NO)
+ goto unsupported;
+
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (alter_info->partition_flags & ALTER_PARTITION_INFO)
{
@@ -11130,6 +11135,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
sql_mode_t save_sql_mode= thd->variables.sql_mode;
ulonglong prev_insert_id, time_to_report_progress;
Field **dfield_ptr= to->default_field;
+ uint save_to_s_default_fields= to->s->default_fields;
bool make_versioned= !from->versioned() && to->versioned();
bool make_unversioned= from->versioned() && !to->versioned();
bool keep_versioned= from->versioned() && to->versioned();
@@ -11463,6 +11469,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
*copied= found_count;
*deleted=delete_count;
to->file->ha_release_auto_increment();
+ to->s->default_fields= save_to_s_default_fields;
if (!cleanup_done)
{
diff --git a/sql/table.cc b/sql/table.cc
index 73c3bd4b3ba..7b7313d3ea1 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -5374,6 +5374,8 @@ void TABLE::init(THD *thd, TABLE_LIST *tl)
fulltext_searched= 0;
file->ft_handler= 0;
reginfo.impossible_range= 0;
+ reginfo.join_tab= NULL;
+ reginfo.not_exists_optimize= FALSE;
created= TRUE;
cond_selectivity= 1.0;
cond_selectivity_sampling_explain= NULL;
diff --git a/sql/table.h b/sql/table.h
index f2fad6c19b2..43ef03e16df 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -2984,9 +2984,11 @@ typedef struct st_nested_join
Before each use the counters are zeroed by reset_nj_counters.
*/
uint counter;
+
/*
- Number of elements in join_list that were not (or contain table(s) that
- weren't) removed by table elimination.
+ Number of elements in join_list that participate in the join plan choice:
+ - Base tables that were not removed by table elimination
+ - Join nests that were not removed by mark_join_nest_as_const
*/
uint n_tables;
nested_join_map nj_map; /* Bit used to identify this nested join*/
diff --git a/sql/winservice.c b/sql/winservice.c
index 2f30cac9206..c275e6d99c8 100644
--- a/sql/winservice.c
+++ b/sql/winservice.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2011, 2012, Monty Program Ab
+ Copyright (c) 2011, 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
@@ -148,7 +148,7 @@ int get_mysql_service_properties(const wchar_t *bin_path,
{
/*
There are rare cases where service config does not have
- --defaults-file in the binary parth . There services were
+ --defaults-file in the binary path . There services were
registered with plain mysqld --install, the data directory is
next to "bin" in this case.
*/
@@ -209,7 +209,7 @@ int get_mysql_service_properties(const wchar_t *bin_path,
}
}
- if(!have_inifile)
+ if(!have_inifile || props->datadir[0] == 0)
{
/*
Hard, although a rare case, we're guessing datadir and defaults-file.
@@ -233,22 +233,25 @@ int get_mysql_service_properties(const wchar_t *bin_path,
*p= 0;
}
- /* Look for my.ini, my.cnf in the install root */
- sprintf_s(props->inifile, MAX_PATH, "%s\\my.ini", install_root);
- if (GetFileAttributes(props->inifile) == INVALID_FILE_ATTRIBUTES)
+ if (!have_inifile)
{
- sprintf_s(props->inifile, MAX_PATH, "%s\\my.cnf", install_root);
- }
- if (GetFileAttributes(props->inifile) != INVALID_FILE_ATTRIBUTES)
- {
- /* Ini file found, get datadir from there */
- GetPrivateProfileString("mysqld", "datadir", NULL, props->datadir,
- MAX_PATH, props->inifile);
- }
- else
- {
- /* No ini file */
- props->inifile[0]= 0;
+ /* Look for my.ini, my.cnf in the install root */
+ sprintf_s(props->inifile, MAX_PATH, "%s\\my.ini", install_root);
+ if (GetFileAttributes(props->inifile) == INVALID_FILE_ATTRIBUTES)
+ {
+ sprintf_s(props->inifile, MAX_PATH, "%s\\my.cnf", install_root);
+ }
+ if (GetFileAttributes(props->inifile) != INVALID_FILE_ATTRIBUTES)
+ {
+ /* Ini file found, get datadir from there */
+ GetPrivateProfileString("mysqld", "datadir", NULL, props->datadir,
+ MAX_PATH, props->inifile);
+ }
+ else
+ {
+ /* No ini file */
+ props->inifile[0]= 0;
+ }
}
/* Try datadir in install directory.*/
diff --git a/sql/wsrep_server_service.cc b/sql/wsrep_server_service.cc
index 50aea494255..7ba744b4d3c 100644
--- a/sql/wsrep_server_service.cc
+++ b/sql/wsrep_server_service.cc
@@ -303,9 +303,21 @@ wsrep::gtid Wsrep_server_service::get_position(wsrep::client_service&)
return wsrep_get_SE_checkpoint<wsrep::gtid>();
}
-void Wsrep_server_service::set_position(wsrep::client_service&,
+void Wsrep_server_service::set_position(wsrep::client_service& c WSREP_UNUSED,
const wsrep::gtid& gtid)
{
+ Wsrep_client_service& cs WSREP_UNUSED (static_cast<Wsrep_client_service&>(c));
+ DBUG_ASSERT(cs.m_client_state.transaction().state()
+ == wsrep::transaction::s_aborted);
+ // Wait until all prior committers have finished.
+ wsrep::gtid wait_for(gtid.id(),
+ wsrep::seqno(gtid.seqno().get() - 1));
+ if (auto err = Wsrep_server_state::instance().provider()
+ .wait_for_gtid(wait_for, std::numeric_limits<int>::max()))
+ {
+ WSREP_WARN("Wait for gtid returned error %d while waiting for "
+ "prior transactions to commit before setting position", err);
+ }
wsrep_set_SE_checkpoint(gtid, wsrep_gtid_server.gtid());
}
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 9da9b90d246..a282826b8de 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -1299,10 +1299,12 @@ btr_cur_search_to_nth_level_func(
ut_ad(!(index->type & DICT_FTS));
ut_ad(index->page != FIL_NULL);
- UNIV_MEM_INVALID(&cursor->up_match, sizeof cursor->up_match);
- UNIV_MEM_INVALID(&cursor->up_bytes, sizeof cursor->up_bytes);
- UNIV_MEM_INVALID(&cursor->low_match, sizeof cursor->low_match);
- UNIV_MEM_INVALID(&cursor->low_bytes, sizeof cursor->low_bytes);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(&cursor->up_match, sizeof cursor->up_match);
+ MEM_UNDEFINED(&cursor->up_bytes, sizeof cursor->up_bytes);
+ MEM_UNDEFINED(&cursor->low_match, sizeof cursor->low_match);
+ MEM_UNDEFINED(&cursor->low_bytes, sizeof cursor->low_bytes);
+#endif /* HAVE_valgrind_or_MSAN */
#ifdef UNIV_DEBUG
cursor->up_match = ULINT_UNDEFINED;
cursor->low_match = ULINT_UNDEFINED;
@@ -3365,13 +3367,12 @@ btr_cur_optimistic_insert(
|| (flags & BTR_CREATE_FLAG));
ut_ad(dtuple_check_typed(entry));
-#ifdef UNIV_DEBUG_VALGRIND
+#ifdef HAVE_valgrind_or_MSAN
if (block->page.zip.data) {
- UNIV_MEM_ASSERT_RW(page, srv_page_size);
- UNIV_MEM_ASSERT_RW(block->page.zip.data,
- block->zip_size());
+ MEM_CHECK_DEFINED(page, srv_page_size);
+ MEM_CHECK_DEFINED(block->page.zip.data, block->zip_size());
}
-#endif /* UNIV_DEBUG_VALGRIND */
+#endif /* HAVE_valgrind_or_MSAN */
leaf = page_is_leaf(page);
@@ -7263,9 +7264,7 @@ btr_store_big_rec_extern_fields(
BTR_EXTERN_FIELD_REF_SIZE));
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
extern_len = big_rec_vec->fields[i].len;
- UNIV_MEM_ASSERT_RW(big_rec_vec->fields[i].data,
- extern_len);
-
+ MEM_CHECK_DEFINED(big_rec_vec->fields[i].data, extern_len);
ut_a(extern_len > 0);
prev_page_no = FIL_NULL;
@@ -7878,7 +7877,7 @@ btr_copy_blob_prefix(
mtr_commit(&mtr);
if (page_no == FIL_NULL || copy_len != part_len) {
- UNIV_MEM_ASSERT_RW(buf, copied_len);
+ MEM_CHECK_DEFINED(buf, copied_len);
return(copied_len);
}
@@ -8034,7 +8033,7 @@ end_of_blob:
func_exit:
inflateEnd(&d_stream);
mem_heap_free(heap);
- UNIV_MEM_ASSERT_RW(buf, d_stream.total_out);
+ MEM_CHECK_DEFINED(buf, d_stream.total_out);
return(d_stream.total_out);
}
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index de2f58a23b4..92cb38d0a85 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -1656,7 +1656,6 @@ btr_search_build_page_hash_index(
for (ulint i = 0; i < n_cached; i++) {
ha_insert_for_fold(&part->table, part->heap,
folds[i], block, recs[i]);
- MONITOR_INC(MONITOR_ADAPTIVE_HASH_ROW_ADDED);
}
}
diff --git a/storage/innobase/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc
index db156ba036b..bedf00441ec 100644
--- a/storage/innobase/buf/buf0buddy.cc
+++ b/storage/innobase/buf/buf0buddy.cc
@@ -81,7 +81,6 @@ enum buf_buddy_state_t {
are in use */
};
-#ifdef UNIV_DEBUG_VALGRIND
/**********************************************************************//**
Invalidate memory area that we won't access while page is free */
UNIV_INLINE
@@ -91,15 +90,11 @@ buf_buddy_mem_invalid(
buf_buddy_free_t* buf, /*!< in: block to check */
ulint i) /*!< in: index of zip_free[] */
{
- const size_t size = BUF_BUDDY_LOW << i;
- ut_ad(i <= BUF_BUDDY_SIZES);
+ ut_ad(i <= BUF_BUDDY_SIZES);
- UNIV_MEM_ASSERT_W(buf, size);
- UNIV_MEM_INVALID(buf, size);
+ MEM_CHECK_ADDRESSABLE(buf, BUF_BUDDY_LOW << i);
+ MEM_UNDEFINED(buf, BUF_BUDDY_LOW << i);
}
-#else /* UNIV_DEBUG_VALGRIND */
-# define buf_buddy_mem_invalid(buf, i) ut_ad((i) <= BUF_BUDDY_SIZES)
-#endif /* UNIV_DEBUG_VALGRIND */
/**********************************************************************//**
Check if a buddy is stamped free.
@@ -333,11 +328,10 @@ static buf_buddy_free_t* buf_buddy_alloc_zip(ulint i)
if (buf) {
/* Trash the page other than the BUF_BUDDY_STAMP_NONFREE. */
- UNIV_MEM_TRASH((void*) buf, (int) ~i, BUF_BUDDY_STAMP_OFFSET);
- UNIV_MEM_TRASH(BUF_BUDDY_STAMP_OFFSET + 4
- + buf->stamp.bytes, (int) ~i,
- (BUF_BUDDY_LOW << i)
- - (BUF_BUDDY_STAMP_OFFSET + 4));
+ MEM_UNDEFINED(buf, BUF_BUDDY_STAMP_OFFSET);
+ MEM_UNDEFINED(BUF_BUDDY_STAMP_OFFSET + 4 + buf->stamp.bytes,
+ (BUF_BUDDY_LOW << i)
+ - (BUF_BUDDY_STAMP_OFFSET + 4));
ut_ad(mach_read_from_4(buf->stamp.bytes
+ BUF_BUDDY_STAMP_OFFSET)
== BUF_BUDDY_STAMP_NONFREE);
@@ -370,7 +364,9 @@ buf_buddy_block_free(void* buf)
HASH_DELETE(buf_page_t, hash, &buf_pool.zip_hash, fold, bpage);
ut_d(memset(buf, 0, srv_page_size));
- UNIV_MEM_INVALID(buf, srv_page_size);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(buf, srv_page_size);
+#endif /* HAVE_valgrind_or_MSAN */
block = (buf_block_t*) bpage;
buf_LRU_block_free_non_file_page(block);
@@ -493,17 +489,16 @@ static bool buf_buddy_relocate(void* src, void* dst, ulint i, bool force)
ut_ad(!ut_align_offset(src, size));
ut_ad(!ut_align_offset(dst, size));
ut_ad(i >= buf_buddy_get_slot(UNIV_ZIP_SIZE_MIN));
- UNIV_MEM_ASSERT_W(dst, size);
+ MEM_CHECK_ADDRESSABLE(dst, size);
space = mach_read_from_4((const byte*) src
+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
offset = mach_read_from_4((const byte*) src
+ FIL_PAGE_OFFSET);
- /* Suppress Valgrind warnings about conditional jump
- on uninitialized value. */
- UNIV_MEM_VALID(&space, sizeof space);
- UNIV_MEM_VALID(&offset, sizeof offset);
+ /* Suppress Valgrind or MSAN warnings. */
+ MEM_MAKE_DEFINED(&space, sizeof space);
+ MEM_MAKE_DEFINED(&offset, sizeof offset);
ut_ad(space != BUF_BUDDY_STAMP_FREE);
@@ -549,7 +544,7 @@ static bool buf_buddy_relocate(void* src, void* dst, ulint i, bool force)
/* The block must have been allocated, but it may
contain uninitialized data. */
- UNIV_MEM_ASSERT_W(src, size);
+ MEM_CHECK_ADDRESSABLE(src, size);
if (!bpage->can_relocate()) {
return false;
@@ -598,7 +593,7 @@ void buf_buddy_free_low(void* buf, ulint i)
buf_pool.buddy_stat[i].used--;
recombine:
- UNIV_MEM_ALLOC(buf, BUF_BUDDY_LOW << i);
+ MEM_UNDEFINED(buf, BUF_BUDDY_LOW << i);
if (i == BUF_BUDDY_SIZES) {
buf_buddy_block_free(buf);
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 4aaf374da95..1e2abc2e04d 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -1295,8 +1295,6 @@ static
void
buf_block_init(buf_block_t* block, byte* frame)
{
- UNIV_MEM_DESC(frame, srv_page_size);
-
/* This function should only be executed at database startup or by
buf_pool.resize(). Either way, adaptive hash index must not exist. */
assert_block_ahi_empty_on_init(block);
@@ -1412,7 +1410,7 @@ inline bool buf_pool_t::chunk_t::create(size_t bytes)
for (auto i= size; i--; ) {
buf_block_init(block, frame);
- UNIV_MEM_INVALID(block->frame, srv_page_size);
+ MEM_UNDEFINED(block->frame, srv_page_size);
/* Add the block to the free list */
UT_LIST_ADD_LAST(buf_pool.free, &block->page);
@@ -1704,8 +1702,6 @@ inline bool buf_pool_t::realloc(buf_block_t *block)
if (block->page.zip.data != NULL) {
ut_ad(block->in_unzip_LRU_list);
ut_d(new_block->in_unzip_LRU_list = true);
- UNIV_MEM_DESC(&new_block->page.zip.data,
- page_zip_get_size(&new_block->page.zip));
buf_block_t* prev_block = UT_LIST_GET_PREV(unzip_LRU, block);
UT_LIST_REMOVE(unzip_LRU, block);
@@ -1740,7 +1736,9 @@ inline bool buf_pool_t::realloc(buf_block_t *block)
"not perfect alignment");
memset_aligned<2>(block->frame
+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xff, 4);
- UNIV_MEM_INVALID(block->frame, srv_page_size);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(block->frame, srv_page_size);
+#endif /* HAVE_valgrind_or_MSAN */
block->page.set_state(BUF_BLOCK_REMOVE_HASH);
/* Relocate flush_list. */
@@ -3366,9 +3364,6 @@ evict_from_pool:
block->lock_hash_val = lock_rec_hash(page_id.space(),
page_id.page_no());
- UNIV_MEM_DESC(&block->page.zip.data,
- page_zip_get_size(&block->page.zip));
-
if (!block->page.oldest_modification()) {
ut_d(UT_LIST_REMOVE(buf_pool.zip_clean, &block->page));
} else {
@@ -3387,7 +3382,9 @@ evict_from_pool:
block->page.set_io_fix(BUF_IO_READ);
rw_lock_x_lock_inline(&block->lock, 0, file, line);
- UNIV_MEM_INVALID(bpage, sizeof *bpage);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(bpage, sizeof *bpage);
+#endif /* HAVE_valgrind_or_MSAN */
mutex_exit(&buf_pool.mutex);
hash_lock->write_unlock();
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index 1e4e5a2721c..af9302aa113 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -375,7 +375,7 @@ void buf_flush_insert_into_flush_list(buf_block_t* block, lsn_t lsn)
mutex_enter(&buf_pool.flush_list_mutex);
block->page.set_oldest_modification(lsn);
- UNIV_MEM_ASSERT_RW(block->page.zip.data
+ MEM_CHECK_DEFINED(block->page.zip.data
? block->page.zip.data : block->frame,
block->physical_size());
incr_flush_list_size_in_bytes(block);
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index f9189216ac0..41d1e40a730 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -626,7 +626,7 @@ buf_block_t* buf_LRU_get_free_only()
assert_block_ahi_empty(block);
block->page.set_state(BUF_BLOCK_MEMORY);
- UNIV_MEM_ALLOC(block->frame, srv_page_size);
+ MEM_UNDEFINED(block->frame, srv_page_size);
break;
}
@@ -1216,8 +1216,6 @@ func_exit:
ut_ad(!buf_pool.page_hash_get_low(id, fold));
ut_ad(b->zip_size());
- UNIV_MEM_DESC(b->zip.data, b->zip_size());
-
/* The field in_LRU_list of
the to-be-freed block descriptor should have
been cleared in
@@ -1306,13 +1304,16 @@ func_exit:
The page was declared uninitialized by
buf_LRU_block_remove_hashed(). We need to flag
the contents of the page valid (which it still is) in
- order to avoid bogus Valgrind warnings.*/
+ order to avoid bogus Valgrind or MSAN warnings.*/
+ buf_block_t* block = reinterpret_cast<buf_block_t*>(bpage);
- UNIV_MEM_VALID(((buf_block_t*) bpage)->frame,
- srv_page_size);
- btr_search_drop_page_hash_index((buf_block_t*) bpage);
- UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame,
- srv_page_size);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_MAKE_DEFINED(block->frame, srv_page_size);
+#endif /* HAVE_valgrind_or_MSAN */
+ btr_search_drop_page_hash_index(block);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(block->frame, srv_page_size);
+#endif /* HAVE_valgrind_or_MSAN */
if (UNIV_LIKELY_NULL(b)) {
ut_ad(b->zip_size());
@@ -1320,7 +1321,7 @@ func_exit:
}
mutex_enter(&buf_pool.mutex);
- buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
+ buf_LRU_block_free_hashed_page(block);
return(true);
}
@@ -1342,11 +1343,7 @@ buf_LRU_block_free_non_file_page(
block->page.set_state(BUF_BLOCK_NOT_USED);
- UNIV_MEM_ALLOC(block->frame, srv_page_size);
-#ifdef UNIV_DEBUG
- /* Wipe contents of page to reveal possible stale pointers to it */
- memset(block->frame, '\0', srv_page_size);
-#else
+ MEM_UNDEFINED(block->frame, srv_page_size);
/* Wipe page_no and space_id */
static_assert(FIL_PAGE_OFFSET % 4 == 0, "alignment");
memset_aligned<4>(block->frame + FIL_PAGE_OFFSET, 0xfe, 4);
@@ -1354,7 +1351,6 @@ buf_LRU_block_free_non_file_page(
"not perfect alignment");
memset_aligned<2>(block->frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
0xfe, 4);
-#endif /* UNIV_DEBUG */
data = block->page.zip.data;
if (data != NULL) {
@@ -1382,7 +1378,7 @@ buf_LRU_block_free_non_file_page(
ut_d(block->page.in_free_list = true);
}
- UNIV_MEM_FREE(block->frame, srv_page_size);
+ MEM_NOACCESS(block->frame, srv_page_size);
}
/** Remove bpage from buf_pool.LRU and buf_pool.page_hash.
@@ -1415,9 +1411,9 @@ static bool buf_LRU_block_remove_hashed(buf_page_t *bpage, const page_id_t id,
switch (bpage->state()) {
case BUF_BLOCK_FILE_PAGE:
- UNIV_MEM_ASSERT_W(bpage, sizeof(buf_block_t));
- UNIV_MEM_ASSERT_W(((buf_block_t*) bpage)->frame,
- srv_page_size);
+ MEM_CHECK_ADDRESSABLE(bpage, sizeof(buf_block_t));
+ MEM_CHECK_ADDRESSABLE(((buf_block_t*) bpage)->frame,
+ srv_page_size);
buf_block_modify_clock_inc((buf_block_t*) bpage);
if (bpage->zip.data) {
const page_t* page = ((buf_block_t*) bpage)->frame;
@@ -1474,7 +1470,7 @@ static bool buf_LRU_block_remove_hashed(buf_page_t *bpage, const page_id_t id,
/* fall through */
case BUF_BLOCK_ZIP_PAGE:
ut_a(!bpage->oldest_modification());
- UNIV_MEM_ASSERT_W(bpage->zip.data, bpage->zip_size());
+ MEM_CHECK_ADDRESSABLE(bpage->zip.data, bpage->zip_size());
break;
case BUF_BLOCK_NOT_USED:
case BUF_BLOCK_MEMORY:
@@ -1515,8 +1511,9 @@ static bool buf_LRU_block_remove_hashed(buf_page_t *bpage, const page_id_t id,
"not perfect alignment");
memset_aligned<2>(reinterpret_cast<buf_block_t*>(bpage)->frame
+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xff, 4);
- UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame,
- srv_page_size);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(((buf_block_t*) bpage)->frame, srv_page_size);
+#endif /* HAVE_valgrind_or_MSAN */
bpage->set_state(BUF_BLOCK_REMOVE_HASH);
/* Question: If we release hash_lock here
diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc
index 8eaf0089495..0f6e0e84e84 100644
--- a/storage/innobase/buf/buf0rea.cc
+++ b/storage/innobase/buf/buf0rea.cc
@@ -217,8 +217,6 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id,
page_zip_set_size(&bpage->zip, zip_size);
bpage->zip.data = (page_zip_t*) data;
- UNIV_MEM_DESC(bpage->zip.data, zip_size);
-
bpage->init(BUF_BLOCK_ZIP_PAGE, page_id);
if (hash_page)
diff --git a/storage/innobase/data/data0data.cc b/storage/innobase/data/data0data.cc
index af2ea0fd198..0fb9f5e66af 100644
--- a/storage/innobase/data/data0data.cc
+++ b/storage/innobase/data/data0data.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 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
@@ -233,41 +233,20 @@ dtuple_validate(
/*============*/
const dtuple_t* tuple) /*!< in: tuple */
{
- const dfield_t* field;
- ulint n_fields;
- ulint len;
- ulint i;
-
ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
+#ifdef HAVE_valgrind_or_MSAN
+ const ulint n_fields = dtuple_get_n_fields(tuple);
- n_fields = dtuple_get_n_fields(tuple);
-
- /* We dereference all the data of each field to test
- for memory traps */
-
- for (i = 0; i < n_fields; i++) {
-
- field = dtuple_get_nth_field(tuple, i);
- len = dfield_get_len(field);
+ for (ulint i = 0; i < n_fields; i++) {
+ const dfield_t* field = dtuple_get_nth_field(tuple, i);
if (!dfield_is_null(field)) {
-
- const byte* data;
-
- data = static_cast<const byte*>(dfield_get_data(field));
-#ifndef UNIV_DEBUG_VALGRIND
- ulint j;
-
- for (j = 0; j < len; j++) {
- data++;
- }
-#endif /* !UNIV_DEBUG_VALGRIND */
-
- UNIV_MEM_ASSERT_RW(data, len);
+ MEM_CHECK_DEFINED(dfield_get_data(field),
+ dfield_get_len(field));
}
}
-
- ut_a(dtuple_check_typed(tuple));
+#endif /* HAVE_valgrind_or_MSAN */
+ ut_ad(dtuple_check_typed(tuple));
return(TRUE);
}
@@ -748,14 +727,7 @@ ext_write:
memcpy(data, dfield_get_data(dfield), local_prefix_len);
/* Clear the extern field reference (BLOB pointer). */
memset(data + local_prefix_len, 0, BTR_EXTERN_FIELD_REF_SIZE);
-#if 0
- /* The following would fail the Valgrind checks in
- page_cur_insert_rec_low() and page_cur_insert_rec_zip().
- The BLOB pointers in the record will be initialized after
- the record and the BLOBs have been written. */
- UNIV_MEM_ALLOC(data + local_prefix_len,
- BTR_EXTERN_FIELD_REF_SIZE);
-#endif
+
dfield_set_data(dfield, data, local_len);
dfield_set_ext(dfield);
diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc
index fc5c7fc5eb1..797f76862fa 100644
--- a/storage/innobase/dict/dict0stats.cc
+++ b/storage/innobase/dict/dict0stats.cc
@@ -409,7 +409,7 @@ dict_stats_table_clone_create(
t = (dict_table_t*) mem_heap_alloc(heap, sizeof(*t));
- UNIV_MEM_ASSERT_RW_ABORT(&table->id, sizeof(table->id));
+ MEM_CHECK_DEFINED(&table->id, sizeof(table->id));
t->id = table->id;
t->heap = heap;
@@ -437,7 +437,7 @@ dict_stats_table_clone_create(
idx = (dict_index_t*) mem_heap_alloc(heap, sizeof(*idx));
- UNIV_MEM_ASSERT_RW_ABORT(&index->id, sizeof(index->id));
+ MEM_CHECK_DEFINED(&index->id, sizeof(index->id));
idx->id = index->id;
idx->name = mem_heap_strdup(heap, index->name);
@@ -583,23 +583,23 @@ dict_stats_assert_initialized_index(
/*================================*/
const dict_index_t* index) /*!< in: index */
{
- UNIV_MEM_ASSERT_RW_ABORT(
+ MEM_CHECK_DEFINED(
index->stat_n_diff_key_vals,
index->n_uniq * sizeof(index->stat_n_diff_key_vals[0]));
- UNIV_MEM_ASSERT_RW_ABORT(
+ MEM_CHECK_DEFINED(
index->stat_n_sample_sizes,
index->n_uniq * sizeof(index->stat_n_sample_sizes[0]));
- UNIV_MEM_ASSERT_RW_ABORT(
+ MEM_CHECK_DEFINED(
index->stat_n_non_null_key_vals,
index->n_uniq * sizeof(index->stat_n_non_null_key_vals[0]));
- UNIV_MEM_ASSERT_RW_ABORT(
+ MEM_CHECK_DEFINED(
&index->stat_index_size,
sizeof(index->stat_index_size));
- UNIV_MEM_ASSERT_RW_ABORT(
+ MEM_CHECK_DEFINED(
&index->stat_n_leaf_pages,
sizeof(index->stat_n_leaf_pages));
}
@@ -614,32 +614,32 @@ dict_stats_assert_initialized(
{
ut_a(table->stat_initialized);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stats_last_recalc,
- sizeof(table->stats_last_recalc));
+ MEM_CHECK_DEFINED(&table->stats_last_recalc,
+ sizeof table->stats_last_recalc);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stat_persistent,
- sizeof(table->stat_persistent));
+ MEM_CHECK_DEFINED(&table->stat_persistent,
+ sizeof table->stat_persistent);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stats_auto_recalc,
- sizeof(table->stats_auto_recalc));
+ MEM_CHECK_DEFINED(&table->stats_auto_recalc,
+ sizeof table->stats_auto_recalc);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stats_sample_pages,
- sizeof(table->stats_sample_pages));
+ MEM_CHECK_DEFINED(&table->stats_sample_pages,
+ sizeof table->stats_sample_pages);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stat_n_rows,
- sizeof(table->stat_n_rows));
+ MEM_CHECK_DEFINED(&table->stat_n_rows,
+ sizeof table->stat_n_rows);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stat_clustered_index_size,
- sizeof(table->stat_clustered_index_size));
+ MEM_CHECK_DEFINED(&table->stat_clustered_index_size,
+ sizeof table->stat_clustered_index_size);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stat_sum_of_other_index_sizes,
- sizeof(table->stat_sum_of_other_index_sizes));
+ MEM_CHECK_DEFINED(&table->stat_sum_of_other_index_sizes,
+ sizeof table->stat_sum_of_other_index_sizes);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stat_modified_counter,
- sizeof(table->stat_modified_counter));
+ MEM_CHECK_DEFINED(&table->stat_modified_counter,
+ sizeof table->stat_modified_counter);
- UNIV_MEM_ASSERT_RW_ABORT(&table->stats_bg_flag,
- sizeof(table->stats_bg_flag));
+ MEM_CHECK_DEFINED(&table->stats_bg_flag,
+ sizeof table->stats_bg_flag);
for (dict_index_t* index = dict_table_get_first_index(table);
index != NULL;
@@ -2304,20 +2304,19 @@ dict_stats_save_index_stat(
pars_info_add_str_literal(pinfo, "database_name", db_utf8);
pars_info_add_str_literal(pinfo, "table_name", table_utf8);
pars_info_add_str_literal(pinfo, "index_name", index->name);
- UNIV_MEM_ASSERT_RW_ABORT(&last_update, 4);
+ MEM_CHECK_DEFINED(&last_update, 4);
pars_info_add_int4_literal(pinfo, "last_update", uint32(last_update));
- UNIV_MEM_ASSERT_RW_ABORT(stat_name, strlen(stat_name));
+ MEM_CHECK_DEFINED(stat_name, strlen(stat_name));
pars_info_add_str_literal(pinfo, "stat_name", stat_name);
- UNIV_MEM_ASSERT_RW_ABORT(&stat_value, 8);
+ MEM_CHECK_DEFINED(&stat_value, 8);
pars_info_add_ull_literal(pinfo, "stat_value", stat_value);
if (sample_size != NULL) {
- UNIV_MEM_ASSERT_RW_ABORT(sample_size, 8);
+ MEM_CHECK_DEFINED(sample_size, 8);
pars_info_add_ull_literal(pinfo, "sample_size", *sample_size);
} else {
pars_info_add_literal(pinfo, "sample_size", NULL,
UNIV_SQL_NULL, DATA_FIXBINARY, 0);
}
- UNIV_MEM_ASSERT_RW_ABORT(stat_description, strlen(stat_description));
pars_info_add_str_literal(pinfo, "stat_description",
stat_description);
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 2045df354b3..34afe458687 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -4161,10 +4161,20 @@ struct Check {
Check check;
ut_list_validate(space->chain, check);
ut_a(space->size == check.size);
- ut_ad(space->id != TRX_SYS_SPACE
- || space == fil_system.sys_space);
- ut_ad(space->id != SRV_TMP_SPACE_ID
- || space == fil_system.temp_space);
+
+ switch (space->id) {
+ case TRX_SYS_SPACE:
+ ut_ad(fil_system.sys_space == NULL
+ || fil_system.sys_space == space);
+ break;
+ case SRV_TMP_SPACE_ID:
+ ut_ad(fil_system.temp_space == NULL
+ || fil_system.temp_space == space);
+ break;
+ default:
+ break;
+ }
+
return(check.n_open);
}
};
@@ -4174,24 +4184,15 @@ Checks the consistency of the tablespace cache.
@return true if ok */
bool fil_validate()
{
- fil_space_t* space;
fil_node_t* fil_node;
ulint n_open = 0;
mutex_enter(&fil_system.mutex);
- /* Look for spaces in the hash table */
-
- for (ulint i = 0; i < fil_system.spaces.n_cells; i++) {
-
- for (space = static_cast<fil_space_t*>(
- HASH_GET_FIRST(&fil_system.spaces, i));
- space != 0;
- space = static_cast<fil_space_t*>(
- HASH_GET_NEXT(hash, space))) {
-
- n_open += Check::validate(space);
- }
+ for (fil_space_t *space = UT_LIST_GET_FIRST(fil_system.space_list);
+ space != NULL;
+ space = UT_LIST_GET_NEXT(space_list, space)) {
+ n_open += Check::validate(space);
}
ut_a(fil_system.n_open == n_open);
diff --git a/storage/innobase/fsp/fsp0sysspace.cc b/storage/innobase/fsp/fsp0sysspace.cc
index f0dea8ebde2..5d381fca033 100644
--- a/storage/innobase/fsp/fsp0sysspace.cc
+++ b/storage/innobase/fsp/fsp0sysspace.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2020, MariaDB Corporation.
+Copyright (c) 2016, 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
@@ -906,9 +906,13 @@ SysTablespace::open_or_create(
} else if (is_temp) {
ut_ad(!fil_system.temp_space);
ut_ad(space_id() == SRV_TMP_SPACE_ID);
- space = fil_system.temp_space = fil_space_create(
+ space = fil_space_create(
name(), SRV_TMP_SPACE_ID, flags(),
FIL_TYPE_TEMPORARY, NULL);
+
+ mutex_enter(&fil_system.mutex);
+ fil_system.temp_space = space;
+ mutex_exit(&fil_system.mutex);
if (!space) {
return DB_ERROR;
}
@@ -917,9 +921,13 @@ SysTablespace::open_or_create(
} else {
ut_ad(!fil_system.sys_space);
ut_ad(space_id() == TRX_SYS_SPACE);
- space = fil_system.sys_space = fil_space_create(
+ space = fil_space_create(
name(), TRX_SYS_SPACE, it->flags(),
FIL_TYPE_TABLESPACE, NULL);
+
+ mutex_enter(&fil_system.mutex);
+ fil_system.sys_space = space;
+ mutex_exit(&fil_system.mutex);
if (!space) {
return DB_ERROR;
}
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 7f89a0b6f42..145f5c27e5f 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -804,6 +804,29 @@ fts_check_cached_index(
return(TRUE);
}
+/** Clear all fts resources when there is no internal DOC_ID
+and there are no new fts index to add.
+@param[in,out] table table where fts is to be freed
+@param[in] trx transaction to drop all fts tables */
+void fts_clear_all(dict_table_t *table, trx_t *trx)
+{
+ if (DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID) ||
+ !table->fts ||
+ !ib_vector_is_empty(table->fts->indexes))
+ return;
+
+ for (const dict_index_t *index= dict_table_get_first_index(table);
+ index; index= dict_table_get_next_index(index))
+ if (index->type & DICT_FTS)
+ return;
+
+ fts_optimize_remove_table(table);
+
+ fts_drop_tables(trx, table);
+ fts_free(table);
+ DICT_TF2_FLAG_UNSET(table, DICT_TF2_FTS);
+}
+
/*******************************************************************//**
Drop auxiliary tables related to an FTS index
@return DB_SUCCESS or error number */
@@ -820,30 +843,15 @@ fts_drop_index(
ut_a(indexes);
if ((ib_vector_size(indexes) == 1
- && (index == static_cast<dict_index_t*>(
- ib_vector_getp(table->fts->indexes, 0))))
- || ib_vector_is_empty(indexes)) {
+ && (index == static_cast<dict_index_t*>(
+ ib_vector_getp(table->fts->indexes, 0)))
+ && DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID))
+ || ib_vector_is_empty(indexes)) {
doc_id_t current_doc_id;
doc_id_t first_doc_id;
DICT_TF2_FLAG_UNSET(table, DICT_TF2_FTS);
- /* If Doc ID column is not added internally by FTS index,
- we can drop all FTS auxiliary tables. Otherwise, we will
- need to keep some common table such as CONFIG table, so
- as to keep track of incrementing Doc IDs */
- if (!DICT_TF2_FLAG_IS_SET(
- table, DICT_TF2_FTS_HAS_DOC_ID)) {
-
- err = fts_drop_tables(trx, table);
-
- err = fts_drop_index_tables(trx, index);
-
- fts_free(table);
-
- return(err);
- }
-
current_doc_id = table->fts->cache->next_doc_id;
first_doc_id = table->fts->cache->first_doc_id;
fts_cache_clear(table->fts->cache);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index df9f52adb51..9344ec660b9 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -55,6 +55,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include <mysql/service_thd_alloc.h>
#include <mysql/service_thd_wait.h>
#include "field.h"
+#include "scope.h"
#include "srv0srv.h"
// MYSQL_PLUGIN_IMPORT extern my_bool lower_case_file_system;
@@ -7032,7 +7033,9 @@ build_template_field(
ut_ad(clust_index->table == index->table);
templ = prebuilt->mysql_template + prebuilt->n_template++;
- UNIV_MEM_INVALID(templ, sizeof *templ);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(templ, sizeof *templ);
+#endif /* HAVE_valgrind_or_MSAN */
templ->is_virtual = !field->stored_in_db();
if (!templ->is_virtual) {
@@ -8143,7 +8146,9 @@ calc_row_difference(
/* The field has changed */
ufield = uvect->fields + n_changed;
- UNIV_MEM_INVALID(ufield, sizeof *ufield);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(ufield, sizeof *ufield);
+#endif /* HAVE_valgrind_or_MSAN */
/* Let us use a dummy dfield to make the conversion
from the MySQL column format to the InnoDB format */
@@ -10566,6 +10571,7 @@ create_table_info_t::create_table_def()
}
heap = mem_heap_create(1000);
+ auto _ = make_scope_exit([heap]() { mem_heap_free(heap); });
ut_d(bool have_vers_start = false);
ut_d(bool have_vers_end = false);
@@ -10602,7 +10608,6 @@ create_table_info_t::create_table_def()
table->name.m_name, field->field_name.str);
err_col:
dict_mem_table_free(table);
- mem_heap_free(heap);
ut_ad(trx_state_eq(m_trx, TRX_STATE_NOT_STARTED));
DBUG_RETURN(HA_ERR_GENERIC);
}
@@ -10630,7 +10635,6 @@ err_col:
" must be below 256."
" Unsupported code " ULINTPF ".",
charset_no);
- mem_heap_free(heap);
dict_mem_table_free(table);
DBUG_RETURN(ER_CANT_CREATE_TABLE);
@@ -10785,8 +10789,6 @@ err_col:
DBUG_SUICIDE(););
}
- mem_heap_free(heap);
-
DBUG_EXECUTE_IF("ib_create_err_tablespace_exist",
err = DB_TABLESPACE_EXISTS;);
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 97f56796e69..f878a483019 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -10383,6 +10383,7 @@ commit_cache_norebuild(
dict_index_remove_from_cache(index->table, index);
}
+ fts_clear_all(ctx->old_table, trx);
trx_commit_for_mysql(trx);
}
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index d2d9a546969..0f1fe0bf814 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -7036,7 +7036,7 @@ i_s_tablespaces_encryption_fill_table(
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
/* deny access to user without PROCESS_ACL privilege */
- if (check_global_access(thd, SUPER_ACL)) {
+ if (check_global_access(thd, PROCESS_ACL)) {
DBUG_RETURN(0);
}
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index 4e0b25c52dd..e316e1b7dab 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -1156,7 +1156,7 @@ struct buf_block_t{
# define assert_block_ahi_empty(block) \
ut_a((block)->n_pointers == 0)
# define assert_block_ahi_empty_on_init(block) do { \
- UNIV_MEM_VALID(&(block)->n_pointers, sizeof (block)->n_pointers); \
+ MEM_MAKE_DEFINED(&(block)->n_pointers, sizeof (block)->n_pointers); \
assert_block_ahi_empty(block); \
} while (0)
# define assert_block_ahi_valid(block) \
diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic
index c264ae07ff8..242c9cbb65d 100644
--- a/storage/innobase/include/buf0buf.ic
+++ b/storage/innobase/include/buf0buf.ic
@@ -185,7 +185,9 @@ buf_page_alloc_descriptor(void)
bpage = (buf_page_t*) ut_zalloc_nokey(sizeof *bpage);
ut_ad(bpage);
- UNIV_MEM_ALLOC(bpage, sizeof *bpage);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(bpage, sizeof *bpage);
+#endif /* HAVE_valgrind_or_MSAN */
return(bpage);
}
diff --git a/storage/innobase/include/data0data.ic b/storage/innobase/include/data0data.ic
index 857ffc15d76..2d1bf5a2d50 100644
--- a/storage/innobase/include/data0data.ic
+++ b/storage/innobase/include/data0data.ic
@@ -51,10 +51,6 @@ dfield_set_len(
ulint len) /*!< in: length or UNIV_SQL_NULL */
{
ut_ad(len != UNIV_SQL_DEFAULT);
-#ifdef UNIV_VALGRIND_DEBUG
- if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(field->data, len);
-#endif /* UNIV_VALGRIND_DEBUG */
-
field->ext = 0;
field->len = static_cast<unsigned int>(len);
}
@@ -94,9 +90,6 @@ dfield_set_data(
const void* data, /*!< in: data */
ulint len) /*!< in: length or UNIV_SQL_NULL */
{
-#ifdef UNIV_VALGRIND_DEBUG
- if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(data, len);
-#endif /* UNIV_VALGRIND_DEBUG */
field->data = (void*) data;
field->ext = 0;
field->len = static_cast<unsigned int>(len);
@@ -111,9 +104,7 @@ dfield_write_mbr(
dfield_t* field, /*!< in: field */
const double* mbr) /*!< in: data */
{
-#ifdef UNIV_VALGRIND_DEBUG
- if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(data, len);
-#endif /* UNIV_VALGRIND_DEBUG */
+ MEM_CHECK_DEFINED(mbr, sizeof *mbr);
field->ext = 0;
for (unsigned i = 0; i < SPDIMS * 2; i++) {
@@ -175,7 +166,7 @@ dfield_dup(
mem_heap_t* heap) /*!< in: memory heap where allocated */
{
if (!dfield_is_null(field)) {
- UNIV_MEM_ASSERT_RW(field->data, field->len);
+ MEM_CHECK_DEFINED(field->data, field->len);
field->data = mem_heap_dup(heap, field->data, field->len);
}
}
@@ -333,8 +324,9 @@ dtuple_create_from_mem(
}
}
#endif
- UNIV_MEM_ASSERT_W(tuple->fields, n_t_fields * sizeof *tuple->fields);
- UNIV_MEM_INVALID(tuple->fields, n_t_fields * sizeof *tuple->fields);
+ MEM_CHECK_ADDRESSABLE(tuple->fields, n_t_fields
+ * sizeof *tuple->fields);
+ MEM_UNDEFINED(tuple->fields, n_t_fields * sizeof *tuple->fields);
return(tuple);
}
diff --git a/storage/innobase/include/dict0stats.ic b/storage/innobase/include/dict0stats.ic
index 3c24e7a8fc3..dbdbceab9ba 100644
--- a/storage/innobase/include/dict0stats.ic
+++ b/storage/innobase/include/dict0stats.ic
@@ -187,41 +187,40 @@ dict_stats_deinit(
table->stat_initialized = FALSE;
-#ifdef UNIV_DEBUG_VALGRIND
- UNIV_MEM_INVALID(&table->stat_n_rows,
- sizeof(table->stat_n_rows));
- UNIV_MEM_INVALID(&table->stat_clustered_index_size,
- sizeof(table->stat_clustered_index_size));
- UNIV_MEM_INVALID(&table->stat_sum_of_other_index_sizes,
- sizeof(table->stat_sum_of_other_index_sizes));
- UNIV_MEM_INVALID(&table->stat_modified_counter,
- sizeof(table->stat_modified_counter));
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(&table->stat_n_rows, sizeof table->stat_n_rows);
+ MEM_UNDEFINED(&table->stat_clustered_index_size,
+ sizeof table->stat_clustered_index_size);
+ MEM_UNDEFINED(&table->stat_sum_of_other_index_sizes,
+ sizeof table->stat_sum_of_other_index_sizes);
+ MEM_UNDEFINED(&table->stat_modified_counter,
+ sizeof table->stat_modified_counter);
dict_index_t* index;
for (index = dict_table_get_first_index(table);
index != NULL;
index = dict_table_get_next_index(index)) {
- UNIV_MEM_INVALID(
+ MEM_UNDEFINED(
index->stat_n_diff_key_vals,
index->n_uniq
- * sizeof(index->stat_n_diff_key_vals[0]));
- UNIV_MEM_INVALID(
+ * sizeof index->stat_n_diff_key_vals[0]);
+ MEM_UNDEFINED(
index->stat_n_sample_sizes,
index->n_uniq
- * sizeof(index->stat_n_sample_sizes[0]));
- UNIV_MEM_INVALID(
+ * sizeof index->stat_n_sample_sizes[0]);
+ MEM_UNDEFINED(
index->stat_n_non_null_key_vals,
index->n_uniq
- * sizeof(index->stat_n_non_null_key_vals[0]));
- UNIV_MEM_INVALID(
+ * sizeof index->stat_n_non_null_key_vals[0]);
+ MEM_UNDEFINED(
&index->stat_index_size,
sizeof(index->stat_index_size));
- UNIV_MEM_INVALID(
+ MEM_UNDEFINED(
&index->stat_n_leaf_pages,
sizeof(index->stat_n_leaf_pages));
}
-#endif /* UNIV_DEBUG_VALGRIND */
+#endif /* HAVE_valgrind_or_MSAN */
rw_lock_x_unlock(&table->stats_latch);
}
diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h
index 0f3a568a048..9e0cab12373 100644
--- a/storage/innobase/include/fts0fts.h
+++ b/storage/innobase/include/fts0fts.h
@@ -24,8 +24,7 @@ Full text search header file
Created 2011/09/02 Sunny Bains
***********************************************************************/
-#ifndef fts0fts_h
-#define fts0fts_h
+#pragma once
#include "data0type.h"
#include "data0types.h"
@@ -986,8 +985,12 @@ fts_trx_t*
fts_trx_create(
trx_t* trx);
+/** Clear all fts resources when there is no internal DOC_ID
+and there are no new fts index to add.
+@param[in,out] table table where fts is to be freed
+@param[in] trx transaction to drop all fts tables */
+void fts_clear_all(dict_table_t *table, trx_t *trx);
+
/** Sync the table during commit phase
@param[in] table table to be synced */
void fts_sync_during_ddl(dict_table_t* table);
-
-#endif /*!< fts0fts.h */
diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic
index 2a88c0f1065..c1e7348a548 100644
--- a/storage/innobase/include/mem0mem.ic
+++ b/storage/innobase/include/mem0mem.ic
@@ -203,7 +203,7 @@ mem_heap_alloc(
mem_block_set_free(block, free + MEM_SPACE_NEEDED(n));
buf = buf + REDZONE_SIZE;
- UNIV_MEM_ALLOC(buf, n - REDZONE_SIZE);
+ MEM_UNDEFINED(buf, n - REDZONE_SIZE);
return(buf);
}
@@ -268,7 +268,7 @@ mem_heap_free_heap_top(
ulint(old_top - reinterpret_cast<byte*>(block)));
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
- UNIV_MEM_FREE(old_top, (byte*) block + block->len - old_top);
+ MEM_NOACCESS(old_top, (byte*) block + block->len - old_top);
/* If free == start, we may free the block if it is not the first
one */
@@ -342,7 +342,7 @@ mem_heap_free_top(
== mem_block_get_start(block))) {
mem_heap_block_free(heap, block);
} else {
- UNIV_MEM_FREE((byte*) block + mem_block_get_free(block), n);
+ MEM_NOACCESS((byte*) block + mem_block_get_free(block), n);
}
}
diff --git a/storage/innobase/include/page0zip.ic b/storage/innobase/include/page0zip.ic
index a59d880284a..ede61283f33 100644
--- a/storage/innobase/include/page0zip.ic
+++ b/storage/innobase/include/page0zip.ic
@@ -218,7 +218,7 @@ page_zip_get_trailer_len(
ulint uncompressed_size;
ut_ad(page_zip_simple_validate(page_zip));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
if (!page_is_leaf(page_zip->data)) {
uncompressed_size = PAGE_ZIP_DIR_SLOT_SIZE
diff --git a/storage/innobase/include/read0types.h b/storage/innobase/include/read0types.h
index ff282aa1f3f..dc0ffffda1f 100644
--- a/storage/innobase/include/read0types.h
+++ b/storage/innobase/include/read0types.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-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
@@ -290,7 +290,7 @@ public:
MEM_UNDEFINED(&m_mutex, sizeof m_mutex);
#endif
#ifdef HAVE_valgrind
- UNIV_MEM_VALID(&m_mutex, sizeof m_mutex);
+ MEM_MAKE_VALID(&m_mutex, sizeof m_mutex);
#endif
}
};
diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h
index 197375b6301..c51e831fb0e 100644
--- a/storage/innobase/include/rem0rec.h
+++ b/storage/innobase/include/rem0rec.h
@@ -601,19 +601,17 @@ rec_offs_make_nth_extern(
rec_offs* offsets,
const ulint n);
+MY_ATTRIBUTE((nonnull))
/** Determine the number of allocated elements for an array of offsets.
@param[in] offsets offsets after rec_offs_set_n_alloc()
@return number of elements */
-inline
-ulint
-rec_offs_get_n_alloc(const rec_offs* offsets)
+inline ulint rec_offs_get_n_alloc(const rec_offs *offsets)
{
- ulint n_alloc;
- ut_ad(offsets);
- n_alloc = offsets[0];
- ut_ad(n_alloc > REC_OFFS_HEADER_SIZE);
- UNIV_MEM_ASSERT_W(offsets, n_alloc * sizeof *offsets);
- return(n_alloc);
+ ut_ad(offsets);
+ ulint n_alloc= offsets[0];
+ ut_ad(n_alloc > REC_OFFS_HEADER_SIZE);
+ MEM_CHECK_ADDRESSABLE(offsets, n_alloc * sizeof *offsets);
+ return n_alloc;
}
/** Determine the number of fields for which offsets have been initialized.
diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic
index 6d0a1771f6d..30c72a7415a 100644
--- a/storage/innobase/include/rem0rec.ic
+++ b/storage/innobase/include/rem0rec.ic
@@ -703,7 +703,7 @@ rec_offs_set_n_alloc(
ulint n_alloc) /*!< in: number of elements */
{
ut_ad(n_alloc > REC_OFFS_HEADER_SIZE);
- UNIV_MEM_ALLOC(offsets, n_alloc * sizeof *offsets);
+ MEM_UNDEFINED(offsets, n_alloc * sizeof *offsets);
offsets[0] = static_cast<rec_offs>(n_alloc);
}
diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h
index 8f497fa9f44..8e833642ee0 100644
--- a/storage/innobase/include/srv0mon.h
+++ b/storage/innobase/include/srv0mon.h
@@ -2,7 +2,7 @@
Copyright (c) 2010, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 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
@@ -651,14 +651,14 @@ Use MONITOR_DEC if appropriate mutex protection exists.
} \
}
-#ifdef UNIV_DEBUG_VALGRIND
+#ifdef HAVE_valgrind_or_MSAN
# define MONITOR_CHECK_DEFINED(value) do { \
mon_type_t m = value; \
- UNIV_MEM_ASSERT_RW(&m, sizeof m); \
+ MEM_CHECK_DEFINED(&m, sizeof m); \
} while (0)
-#else /* UNIV_DEBUG_VALGRIND */
+#else /* HAVE_valgrind_or_MSAN */
# define MONITOR_CHECK_DEFINED(value) (void) 0
-#endif /* UNIV_DEBUG_VALGRIND */
+#endif /* HAVE_valgrind_or_MSAN */
#define MONITOR_INC_VALUE(monitor, value) \
MONITOR_CHECK_DEFINED(value); \
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 147a6285e5c..18c228e56c3 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -170,14 +170,6 @@ using the call command. */
#define UNIV_ENABLE_UNIT_TEST_ROW_RAW_FORMAT_INT
*/
-#include <my_valgrind.h>
-
-#if defined HAVE_valgrind && defined HAVE_VALGRIND_MEMCHECK_H
-# define UNIV_DEBUG_VALGRIND
-#elif __has_feature(memory_sanitizer)
-# define UNIV_DEBUG_VALGRIND
-#endif
-
#ifdef DBUG_OFF
# undef UNIV_DEBUG
#elif !defined UNIV_DEBUG
@@ -185,8 +177,6 @@ using the call command. */
#endif
#if 0
-#define UNIV_DEBUG_VALGRIND /* Enable extra
- Valgrind instrumentation */
#define UNIV_DEBUG_PRINT /* Enable the compilation of
some debug print functions */
#define UNIV_AHI_DEBUG /* Enable adaptive hash index
@@ -575,56 +565,6 @@ typedef void* os_thread_ret_t;
#include "ut0ut.h"
#include "sync0types.h"
-/* define UNIV macros in terms of my_valgrind.h */
-#define UNIV_MEM_INVALID(addr, size) MEM_UNDEFINED(addr, size)
-#define UNIV_MEM_FREE(addr, size) MEM_NOACCESS(addr, size)
-#define UNIV_MEM_ALLOC(addr, size) UNIV_MEM_INVALID(addr, size)
-#ifdef UNIV_DEBUG_VALGRIND
-# include <valgrind/memcheck.h>
-# define UNIV_MEM_VALID(addr, size) MEM_MAKE_DEFINED(addr, size)
-# define UNIV_MEM_DESC(addr, size) VALGRIND_CREATE_BLOCK(addr, size, #addr)
-# define UNIV_MEM_UNDESC(b) VALGRIND_DISCARD(b)
-# define UNIV_MEM_ASSERT_RW_LOW(addr, size, should_abort) do { \
- const void* _p = (const void*) (ulint) \
- VALGRIND_CHECK_MEM_IS_DEFINED(addr, size); \
- if (UNIV_LIKELY_NULL(_p)) { \
- fprintf(stderr, "%s:%d: %p[%u] undefined at %ld\n", \
- __FILE__, __LINE__, \
- (const void*) (addr), (unsigned) (size), (long) \
- (((const char*) _p) - ((const char*) (addr)))); \
- if (should_abort) { \
- ut_error; \
- } \
- } \
-} while (0)
-# define UNIV_MEM_ASSERT_RW(addr, size) \
- UNIV_MEM_ASSERT_RW_LOW(addr, size, false)
-# define UNIV_MEM_ASSERT_RW_ABORT(addr, size) \
- UNIV_MEM_ASSERT_RW_LOW(addr, size, true)
-# define UNIV_MEM_ASSERT_W(addr, size) do { \
- const void* _p = (const void*) (ulint) \
- VALGRIND_CHECK_MEM_IS_ADDRESSABLE(addr, size); \
- if (UNIV_LIKELY_NULL(_p)) \
- fprintf(stderr, "%s:%d: %p[%u] unwritable at %ld\n", \
- __FILE__, __LINE__, \
- (const void*) (addr), (unsigned) (size), (long) \
- (((const char*) _p) - ((const char*) (addr)))); \
- } while (0)
-# define UNIV_MEM_TRASH(addr, c, size) do { \
- ut_d(memset(addr, c, size)); \
- UNIV_MEM_INVALID(addr, size); \
- } while (0)
-#else
-# define UNIV_MEM_VALID(addr, size) do {} while(0)
-# define UNIV_MEM_DESC(addr, size) do {} while(0)
-# define UNIV_MEM_UNDESC(b) do {} while(0)
-# define UNIV_MEM_ASSERT_RW_LOW(addr, size, should_abort) do {} while(0)
-# define UNIV_MEM_ASSERT_RW(addr, size) do {} while(0)
-# define UNIV_MEM_ASSERT_RW_ABORT(addr, size) do {} while(0)
-# define UNIV_MEM_ASSERT_W(addr, size) do {} while(0)
-# define UNIV_MEM_TRASH(addr, c, size) do {} while(0)
-#endif
-
extern ulong srv_page_size_shift;
extern ulong srv_page_size;
diff --git a/storage/innobase/include/ut0pool.h b/storage/innobase/include/ut0pool.h
index f6006144dc4..703a07a23f2 100644
--- a/storage/innobase/include/ut0pool.h
+++ b/storage/innobase/include/ut0pool.h
@@ -94,7 +94,7 @@ struct Pool {
#ifdef HAVE_valgrind
/* Declare the contents as initialized for Valgrind;
we checked this in mem_free(). */
- UNIV_MEM_VALID(&elem->m_type, sizeof elem->m_type);
+ MEM_MAKE_DEFINED(&elem->m_type, sizeof elem->m_type);
#endif
Factory::destroy(&elem->m_type);
}
@@ -137,13 +137,12 @@ struct Pool {
MEM_UNDEFINED(&elem->m_type, sizeof elem->m_type);
# endif
# ifdef HAVE_valgrind
-
/* Declare the memory initialized for Valgrind.
The trx_t that are released to the pool are
actually initialized; we checked that by
- UNIV_MEM_ASSERT_RW() in mem_free() below. */
- UNIV_MEM_VALID(&elem->m_type, sizeof elem->m_type);
+ MEM_CHECK_DEFINED() in mem_free() below. */
# endif
+ MEM_MAKE_DEFINED(&elem->m_type, sizeof elem->m_type);
}
#endif
@@ -159,7 +158,7 @@ struct Pool {
byte* p = reinterpret_cast<byte*>(ptr + 1);
elem = reinterpret_cast<Element*>(p - sizeof(*elem));
- UNIV_MEM_ASSERT_RW(&elem->m_type, sizeof elem->m_type);
+ MEM_CHECK_DEFINED(&elem->m_type, sizeof elem->m_type);
elem->m_pool->m_lock_strategy.enter();
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index aa70d67c28a..2a4891f2716 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -1093,8 +1093,8 @@ create_block:
ut_calc_align<uint16_t>(static_cast<uint16_t>(len), ALIGNMENT);
static_assert(ut_is_2pow(ALIGNMENT), "ALIGNMENT must be a power of 2");
UT_LIST_ADD_FIRST(blocks, block);
- UNIV_MEM_INVALID(block->frame, len);
- UNIV_MEM_FREE(block->frame + len, srv_page_size - len);
+ MEM_UNDEFINED(block->frame, len);
+ MEM_NOACCESS(block->frame + len, srv_page_size - len);
return my_assume_aligned<ALIGNMENT>(block->frame);
}
@@ -1113,7 +1113,7 @@ create_block:
block->page.access_time= ((block->page.access_time >> 16) + 1) << 16 |
ut_calc_align<uint16_t>(static_cast<uint16_t>(free_offset), ALIGNMENT);
- UNIV_MEM_ALLOC(block->frame + free_offset - len, len);
+ MEM_UNDEFINED(block->frame + free_offset - len, len);
return my_assume_aligned<ALIGNMENT>(block->frame + free_offset - len);
}
@@ -1758,7 +1758,7 @@ inline void recv_sys_t::add(const page_id_t page_id,
{
/* Use already allocated 'padding' bytes */
append:
- UNIV_MEM_ALLOC(end + 1, len);
+ MEM_UNDEFINED(end + 1, len);
/* Append to the preceding record for the page */
tail->append(l, len);
return;
diff --git a/storage/innobase/mem/mem0mem.cc b/storage/innobase/mem/mem0mem.cc
index 261d8062bd6..6d4593e0ab4 100644
--- a/storage/innobase/mem/mem0mem.cc
+++ b/storage/innobase/mem/mem0mem.cc
@@ -322,8 +322,7 @@ mem_heap_create_block_func(
/* Not the first allocation for the heap. This block's
total_length field should be set to undefined. */
ut_d(block->total_size = ULINT_UNDEFINED);
- UNIV_MEM_INVALID(&block->total_size,
- sizeof block->total_size);
+ MEM_UNDEFINED(&block->total_size, sizeof block->total_size);
heap->total_size += len;
}
@@ -331,7 +330,7 @@ mem_heap_create_block_func(
/* Poison all available memory. Individual chunks will be unpoisoned on
every mem_heap_alloc() call. */
compile_time_assert(MEM_BLOCK_HEADER_SIZE >= sizeof *block);
- UNIV_MEM_FREE(block + 1, len - sizeof *block);
+ MEM_NOACCESS(block + 1, len - sizeof *block);
ut_ad((ulint)MEM_BLOCK_HEADER_SIZE < len);
diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc
index 2a2f61641fe..16a0ecc051c 100644
--- a/storage/innobase/mtr/mtr0mtr.cc
+++ b/storage/innobase/mtr/mtr0mtr.cc
@@ -354,8 +354,10 @@ struct mtr_write_log_t {
/** Start a mini-transaction. */
void mtr_t::start()
{
- UNIV_MEM_INVALID(this, sizeof *this);
- UNIV_MEM_VALID(&m_freed_pages, sizeof(m_freed_pages));
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(this, sizeof *this);
+ MEM_MAKE_DEFINED(&m_freed_pages, sizeof(m_freed_pages));
+#endif /* HAVE_valgrind_or_MSAN */
ut_d(m_start= true);
ut_d(m_commit= false);
diff --git a/storage/innobase/os/os0proc.cc b/storage/innobase/os/os0proc.cc
index 32747aae3ab..819e16f2302 100644
--- a/storage/innobase/os/os0proc.cc
+++ b/storage/innobase/os/os0proc.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2019, MariaDB Corporation.
+Copyright (c) 2019, 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
diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc
index 666f7c8d788..92e7ce5e60d 100644
--- a/storage/innobase/page/page0cur.cc
+++ b/storage/innobase/page/page0cur.cc
@@ -1302,7 +1302,7 @@ page_cur_insert_rec_low(
/* 1. Get the size of the physical record in the page */
const ulint rec_size= rec_offs_size(offsets);
-#ifdef UNIV_DEBUG_VALGRIND
+#ifdef HAVE_valgrind_or_MSAN
{
const void *rec_start= rec - rec_offs_extra_size(offsets);
ulint extra_size= rec_offs_extra_size(offsets) -
@@ -1310,11 +1310,11 @@ page_cur_insert_rec_low(
? REC_N_NEW_EXTRA_BYTES
: REC_N_OLD_EXTRA_BYTES);
/* All data bytes of the record must be valid. */
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
/* The variable-length header must be valid. */
- UNIV_MEM_ASSERT_RW(rec_start, extra_size);
+ MEM_CHECK_DEFINED(rec_start, extra_size);
}
-#endif /* UNIV_DEBUG_VALGRIND */
+#endif /* HAVE_valgrind_or_MSAN */
/* 2. Try to find suitable space from page memory management */
bool reuse= false;
@@ -1613,7 +1613,7 @@ static inline void page_zip_dir_add_slot(buf_block_t *block,
page_zip_des_t *page_zip= &block->page.zip;
ut_ad(page_is_comp(page_zip->data));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
/* Read the old n_dense (n_heap has already been incremented). */
ulint n_dense= page_dir_get_n_heap(page_zip->data) - (PAGE_HEAP_NO_USER_LOW +
@@ -1702,16 +1702,16 @@ page_cur_insert_rec_zip(
/* 1. Get the size of the physical record in the page */
const ulint rec_size= rec_offs_size(offsets);
-#ifdef UNIV_DEBUG_VALGRIND
+#ifdef HAVE_valgrind_or_MSAN
{
const void *rec_start= rec - rec_offs_extra_size(offsets);
ulint extra_size= rec_offs_extra_size(offsets) - REC_N_NEW_EXTRA_BYTES;
/* All data bytes of the record must be valid. */
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
/* The variable-length header must be valid. */
- UNIV_MEM_ASSERT_RW(rec_start, extra_size);
+ MEM_CHECK_DEFINED(rec_start, extra_size);
}
-#endif /* UNIV_DEBUG_VALGRIND */
+#endif /* HAVE_valgrind_or_MSAN */
const bool reorg_before_insert= page_has_garbage(cursor->block->frame) &&
rec_size > page_get_max_insert_size(cursor->block->frame, 1) &&
rec_size <= page_get_max_insert_size_after_reorganize(cursor->block->frame,
@@ -1954,8 +1954,8 @@ use_heap:
rec_set_bit_field_2(insert_rec, heap_no, REC_NEW_HEAP_NO,
REC_HEAP_NO_MASK, REC_HEAP_NO_SHIFT);
- UNIV_MEM_ASSERT_RW(rec_get_start(insert_rec, offsets),
- rec_offs_size(offsets));
+ MEM_CHECK_DEFINED(rec_get_start(insert_rec, offsets),
+ rec_offs_size(offsets));
/* 6. Update the last insertion info in page header */
byte *last_insert= my_assume_aligned<4>(PAGE_LAST_INSERT + PAGE_HEADER +
diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc
index 21f2e9da75a..a89ae5b3a64 100644
--- a/storage/innobase/page/page0zip.cc
+++ b/storage/innobase/page/page0zip.cc
@@ -908,9 +908,9 @@ page_zip_compress_node_ptrs(
/* Only leaf nodes may contain externally stored columns. */
ut_ad(!rec_offs_any_extern(offsets));
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
/* Compress the extra bytes. */
c_stream->avail_in = static_cast<uInt>(
@@ -973,8 +973,8 @@ page_zip_compress_sec(
- c_stream->next_in);
if (UNIV_LIKELY(c_stream->avail_in != 0)) {
- UNIV_MEM_ASSERT_RW(c_stream->next_in,
- c_stream->avail_in);
+ MEM_CHECK_DEFINED(c_stream->next_in,
+ c_stream->avail_in);
err = deflate(c_stream, Z_NO_FLUSH);
if (UNIV_UNLIKELY(err != Z_OK)) {
break;
@@ -1016,9 +1016,9 @@ page_zip_compress_clust_ext(
int err;
ulint i;
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
for (i = 0; i < rec_offs_n_fields(offsets); i++) {
ulint len;
@@ -1156,9 +1156,9 @@ page_zip_compress_clust(
ULINT_UNDEFINED, &heap);
ut_ad(rec_offs_n_fields(offsets)
== dict_index_get_n_fields(index));
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
/* Compress the extra bytes. */
c_stream->avail_in = static_cast<uInt>(
@@ -1205,9 +1205,9 @@ page_zip_compress_clust(
== rec_get_nth_field(rec, offsets,
trx_id_col + 1, &len));
ut_ad(len == DATA_ROLL_PTR_LEN);
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
/* Compress any preceding bytes. */
c_stream->avail_in = static_cast<uInt>(
@@ -1300,7 +1300,7 @@ page_zip_compress(
ut_ad(dict_table_is_comp(index->table));
ut_ad(!dict_index_is_ibuf(index));
- UNIV_MEM_ASSERT_RW(page, srv_page_size);
+ MEM_CHECK_DEFINED(page, srv_page_size);
/* Check the data that will be omitted. */
ut_a(!memcmp(page + (PAGE_NEW_INFIMUM - REC_N_NEW_EXTRA_BYTES),
@@ -1463,7 +1463,7 @@ page_zip_compress(
trx_id_col = ULINT_UNDEFINED;
}
- UNIV_MEM_ASSERT_RW(c_stream.next_in, c_stream.avail_in);
+ MEM_CHECK_DEFINED(c_stream.next_in, c_stream.avail_in);
err = deflate(&c_stream, Z_FULL_FLUSH);
if (err != Z_OK) {
goto zlib_error;
@@ -1517,7 +1517,7 @@ page_zip_compress(
- (c_stream.next_in - page));
ut_a(c_stream.avail_in <= srv_page_size - PAGE_ZIP_START - PAGE_DIR);
- UNIV_MEM_ASSERT_RW(c_stream.next_in, c_stream.avail_in);
+ MEM_CHECK_DEFINED(c_stream.next_in, c_stream.avail_in);
err = deflate(&c_stream, Z_FINISH);
if (UNIV_UNLIKELY(err != Z_STREAM_END)) {
@@ -1552,9 +1552,11 @@ err_exit:
ut_ad(buf + c_stream.total_out == c_stream.next_out);
ut_ad((ulint) (storage - c_stream.next_out) >= c_stream.avail_out);
+#ifdef HAVE_valgrind
/* Valgrind believes that zlib does not initialize some bits
in the last 7 or 8 bytes of the stream. Make Valgrind happy. */
- UNIV_MEM_VALID(buf, c_stream.total_out);
+ MEM_MAKE_DEFINED(buf, c_stream.total_out);
+#endif /* HAVE_valgrind */
/* Zero out the area reserved for the modification log.
Space for the end marker of the modification log is not
@@ -1585,7 +1587,7 @@ err_exit:
page_zip_compress_write_log(block, index, mtr);
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
#ifdef PAGE_ZIP_COMPRESS_DBG
if (logfile) {
@@ -3026,8 +3028,8 @@ page_zip_decompress_low(
rec_offs* offsets;
ut_ad(page_zip_simple_validate(page_zip));
- UNIV_MEM_ASSERT_W(page, srv_page_size);
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_ADDRESSABLE(page, srv_page_size);
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
/* The dense directory excludes the infimum and supremum records. */
n_dense = page_dir_get_n_heap(page_zip->data) - PAGE_HEAP_NO_USER_LOW;
@@ -3074,7 +3076,9 @@ page_zip_decompress_low(
/* Clear the uncompressed page, except the header. */
memset(PAGE_DATA + page, 0x55, srv_page_size - PAGE_DATA);
#endif /* UNIV_ZIP_DEBUG */
- UNIV_MEM_INVALID(PAGE_DATA + page, srv_page_size - PAGE_DATA);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(PAGE_DATA + page, srv_page_size - PAGE_DATA);
+#endif /* HAVE_valgrind_or_MSAN */
/* Copy the page directory. */
if (UNIV_UNLIKELY(!page_zip_dir_decode(page_zip, page, recs,
@@ -3205,7 +3209,7 @@ err_exit:
}
ut_a(page_is_comp(page));
- UNIV_MEM_ASSERT_RW(page, srv_page_size);
+ MEM_CHECK_DEFINED(page, srv_page_size);
page_zip_fields_free(index);
mem_heap_free(heap);
@@ -3346,8 +3350,8 @@ page_zip_validate_low(
page_t* temp_page = static_cast<byte*>(aligned_malloc(srv_page_size,
srv_page_size));
- UNIV_MEM_ASSERT_RW(page, srv_page_size);
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page, srv_page_size);
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
temp_page_zip = *page_zip;
valid = page_zip_decompress_low(&temp_page_zip, temp_page, TRUE);
@@ -3570,9 +3574,9 @@ page_zip_write_rec_ext(
page_zip_des_t* const page_zip = &block->page.zip;
ut_ad(rec_offs_validate(rec, index, offsets));
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
externs -= (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN)
* (page_dir_get_n_heap(page) - PAGE_HEAP_NO_USER_LOW);
@@ -3702,10 +3706,10 @@ void page_zip_write_rec(buf_block_t *block, const byte *rec,
ut_ad(page_zip_header_cmp(page_zip, page));
ut_ad(page_simple_validate_new((page_t*) page));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
slot = page_zip_dir_find(page_zip, page_offset(rec));
ut_a(slot);
@@ -3891,10 +3895,10 @@ page_zip_write_blob_ptr(
ut_ad(page_is_leaf(page));
ut_ad(dict_index_is_clust(index));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
blob_no = page_zip_get_n_prev_extern(page_zip, rec, index)
+ rec_get_n_extern_new(rec, index, n);
@@ -3944,8 +3948,8 @@ page_zip_write_node_ptr(
ut_ad(!page_is_leaf(page));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
- UNIV_MEM_ASSERT_RW(rec, size);
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(rec, size);
storage = page_zip_dir_start(page_zip)
- (rec_get_heap_no_new(rec) - 1) * REC_NODE_PTR_SIZE;
@@ -3993,7 +3997,7 @@ page_zip_write_trx_id_and_roll_ptr(
ut_ad(page_is_leaf(page));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
constexpr ulint sys_len = DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN;
const ulint heap_no = rec_get_heap_no_new(rec);
@@ -4056,10 +4060,10 @@ write:
ut_a(!memcmp(storage - len, field - len, sys_len));
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
}
/**********************************************************************//**
@@ -4093,10 +4097,10 @@ page_zip_clear_rec(
heap_no = rec_get_heap_no_new(rec);
ut_ad(heap_no >= PAGE_HEAP_NO_USER_LOW);
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
if (!page_is_leaf(block->frame)) {
/* Clear node_ptr. On the compressed page,
@@ -4191,7 +4195,7 @@ page_zip_rec_set_owned(
ut_ad(page_align(rec) == block->frame);
page_zip_des_t *const page_zip= &block->page.zip;
byte *slot= page_zip_dir_find(page_zip, page_offset(rec));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
byte b= *slot;
if (flag)
b|= (PAGE_ZIP_DIR_SLOT_OWNED >> 8);
@@ -4223,7 +4227,7 @@ page_zip_dir_insert(
ut_ad(page_rec_get_next_const(cursor->rec) == rec);
ut_ad(page_zip_simple_validate(page_zip));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
if (page_rec_is_infimum(cursor->rec)) {
/* Use the first slot. */
@@ -4306,10 +4310,10 @@ void page_zip_dir_delete(buf_block_t *block, byte *rec,
ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(rec_offs_comp(offsets));
- UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
- UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
- UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
- rec_offs_extra_size(offsets));
+ MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
+ MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
+ rec_offs_extra_size(offsets));
mach_write_to_2(rec - REC_NEXT,
free ? static_cast<uint16_t>(free - rec) : 0);
@@ -4429,9 +4433,9 @@ page_zip_reorganize(
ut_ad(!dict_index_is_ibuf(index));
ut_ad(!index->table->is_temporary());
/* Note that page_zip_validate(page_zip, page, index) may fail here. */
- UNIV_MEM_ASSERT_RW(page, srv_page_size);
- UNIV_MEM_ASSERT_RW(buf_block_get_page_zip(block)->data,
- page_zip_get_size(buf_block_get_page_zip(block)));
+ MEM_CHECK_DEFINED(page, srv_page_size);
+ MEM_CHECK_DEFINED(buf_block_get_page_zip(block)->data,
+ page_zip_get_size(buf_block_get_page_zip(block)));
/* Disable logging */
mtr_log_t log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
@@ -4547,10 +4551,10 @@ page_zip_copy_recs(
ut_a(dict_index_is_clust(index));
}
- UNIV_MEM_ASSERT_W(page, srv_page_size);
- UNIV_MEM_ASSERT_W(page_zip->data, page_zip_get_size(page_zip));
- UNIV_MEM_ASSERT_RW(src, srv_page_size);
- UNIV_MEM_ASSERT_RW(src_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_ADDRESSABLE(page, srv_page_size);
+ MEM_CHECK_ADDRESSABLE(page_zip->data, page_zip_get_size(page_zip));
+ MEM_CHECK_DEFINED(src, srv_page_size);
+ MEM_CHECK_DEFINED(src_zip->data, page_zip_get_size(page_zip));
/* Copy those B-tree page header fields that are related to
the records stored in the page. Also copy the field
diff --git a/storage/innobase/row/row0ext.cc b/storage/innobase/row/row0ext.cc
index 9b07727d058..b7a627603d9 100644
--- a/storage/innobase/row/row0ext.cc
+++ b/storage/innobase/row/row0ext.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2019, MariaDB Corporation.
+Copyright (c) 2019, 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
diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc
index 42188fb98b5..4698f25428c 100644
--- a/storage/innobase/row/row0ftsort.cc
+++ b/storage/innobase/row/row0ftsort.cc
@@ -888,7 +888,7 @@ loop:
goto func_exit;
}
- UNIV_MEM_INVALID(block[t_ctx.buf_used], srv_sort_buf_size);
+ MEM_UNDEFINED(block[t_ctx.buf_used], srv_sort_buf_size);
buf[t_ctx.buf_used] = row_merge_buf_empty(buf[t_ctx.buf_used]);
mycount[t_ctx.buf_used] += t_ctx.rows_added[t_ctx.buf_used];
t_ctx.rows_added[t_ctx.buf_used] = 0;
@@ -982,12 +982,14 @@ exit:
goto func_exit;
}
- UNIV_MEM_INVALID(block[i], srv_sort_buf_size);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(block[i], srv_sort_buf_size);
if (crypt_block[i]) {
- UNIV_MEM_INVALID(crypt_block[i],
- srv_sort_buf_size);
+ MEM_UNDEFINED(crypt_block[i],
+ srv_sort_buf_size);
}
+#endif /* HAVE_valgrind_or_MSAN */
}
buf[i] = row_merge_buf_empty(buf[i]);
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 91c401cd4ba..5f3cdb4356e 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1240,8 +1240,10 @@ row_ins_foreign_check_on_constraint(
update->info_bits = 0;
update->n_fields = foreign->n_fields;
- UNIV_MEM_INVALID(update->fields,
- update->n_fields * sizeof *update->fields);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(update->fields,
+ update->n_fields * sizeof *update->fields);
+#endif /* HAVE_valgrind_or_MSAN */
bool affects_fulltext = false;
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index 1e5362180ba..78f605c373d 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -375,7 +375,9 @@ row_log_online_op(
goto err_exit;
}
- UNIV_MEM_INVALID(log->tail.buf, sizeof log->tail.buf);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(log->tail.buf, sizeof log->tail.buf);
+#endif /* HAVE_valgrind_or_MSAN */
ut_ad(log->tail.bytes < srv_sort_buf_size);
avail_size = srv_sort_buf_size - log->tail.bytes;
@@ -425,7 +427,7 @@ row_log_online_op(
log->tail.buf, avail_size);
}
- UNIV_MEM_ASSERT_RW(buf, srv_sort_buf_size);
+ MEM_CHECK_DEFINED(buf, srv_sort_buf_size);
if (row_log_tmpfile(log) == OS_FILE_CLOSED) {
log->error = DB_OUT_OF_MEMORY;
@@ -460,8 +462,10 @@ write_failed:
index->type |= DICT_CORRUPT;
}
- UNIV_MEM_INVALID(log->tail.block, srv_sort_buf_size);
- UNIV_MEM_INVALID(buf, srv_sort_buf_size);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(log->tail.block, srv_sort_buf_size);
+ MEM_UNDEFINED(buf, srv_sort_buf_size);
+#endif /* HAVE_valgrind_or_MSAN */
memcpy(log->tail.block, log->tail.buf + avail_size,
mrec_size - avail_size);
@@ -471,7 +475,9 @@ write_failed:
ut_ad(b == log->tail.block + log->tail.bytes);
}
- UNIV_MEM_INVALID(log->tail.buf, sizeof log->tail.buf);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(log->tail.buf, sizeof log->tail.buf);
+#endif /* HAVE_valgrind_or_MSAN */
err_exit:
mutex_exit(&log->mutex);
}
@@ -503,7 +509,9 @@ row_log_table_open(
{
mutex_enter(&log->mutex);
- UNIV_MEM_INVALID(log->tail.buf, sizeof log->tail.buf);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(log->tail.buf, sizeof log->tail.buf);
+#endif /* HAVE_valgrind_or_MSAN */
if (log->error != DB_SUCCESS) {
err_exit:
@@ -563,7 +571,7 @@ row_log_table_close_func(
memcpy(buf + log->tail.bytes, log->tail.buf, avail);
}
- UNIV_MEM_ASSERT_RW(buf, srv_sort_buf_size);
+ MEM_CHECK_DEFINED(buf, srv_sort_buf_size);
if (row_log_tmpfile(log) == OS_FILE_CLOSED) {
log->error = DB_OUT_OF_MEMORY;
@@ -595,8 +603,10 @@ row_log_table_close_func(
write_failed:
log->error = DB_ONLINE_LOG_TOO_BIG;
}
- UNIV_MEM_INVALID(log->tail.block, srv_sort_buf_size);
- UNIV_MEM_INVALID(buf, srv_sort_buf_size);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(log->tail.block, srv_sort_buf_size);
+ MEM_UNDEFINED(buf, srv_sort_buf_size);
+#endif /* HAVE_valgrind_or_MSAN */
memcpy(log->tail.block, log->tail.buf + avail, size - avail);
log->tail.bytes = size - avail;
} else {
@@ -605,7 +615,9 @@ write_failed:
}
log->tail.total += size;
- UNIV_MEM_INVALID(log->tail.buf, sizeof log->tail.buf);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(log->tail.buf, sizeof log->tail.buf);
+#endif /* HAVE_valgrind_or_MSAN */
err_exit:
mutex_exit(&log->mutex);
@@ -2777,7 +2789,9 @@ row_log_table_apply_ops(
ut_ad(new_trx_id_col > 0);
ut_ad(new_trx_id_col != ULINT_UNDEFINED);
- UNIV_MEM_INVALID(&mrec_end, sizeof mrec_end);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(&mrec_end, sizeof mrec_end);
+#endif /* HAVE_valgrind_or_MSAN */
offsets = static_cast<rec_offs*>(ut_malloc_nokey(i * sizeof *offsets));
rec_offs_set_n_alloc(offsets, i);
@@ -3689,7 +3703,9 @@ row_log_apply_ops(
ut_ad(!index->is_committed());
ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_X));
ut_ad(index->online_log);
- UNIV_MEM_INVALID(&mrec_end, sizeof mrec_end);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(&mrec_end, sizeof mrec_end);
+#endif /* HAVE_valgrind_or_MSAN */
offsets = static_cast<rec_offs*>(ut_malloc_nokey(i * sizeof *offsets));
rec_offs_set_n_alloc(offsets, i);
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index ac17f098292..d1074f74725 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -1021,11 +1021,11 @@ row_merge_buf_write(
ut_a(b < &block[srv_sort_buf_size]);
ut_a(b == &block[0] + buf->total_size);
*b++ = 0;
-#ifdef UNIV_DEBUG_VALGRIND
+#ifdef HAVE_valgrind_or_MSAN
/* The rest of the block is uninitialized. Initialize it
to avoid bogus warnings. */
memset(b, 0xff, &block[srv_sort_buf_size] - b);
-#endif /* UNIV_DEBUG_VALGRIND */
+#endif /* HAVE_valgrind_or_MSAN */
DBUG_LOG("ib_merge_sort",
"write " << reinterpret_cast<const void*>(b) << ','
<< of->fd << ',' << of->offset << " EOF");
@@ -1418,7 +1418,9 @@ row_merge_write_rec(
return(NULL);
}
- UNIV_MEM_INVALID(&block[0], srv_sort_buf_size);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(&block[0], srv_sort_buf_size);
+#endif /* HAVE_valgrind_or_MSAN */
/* Copy the rest. */
b = &block[0];
@@ -1459,20 +1461,19 @@ row_merge_write_eof(
",fd=" << fd << ',' << *foffs);
*b++ = 0;
- UNIV_MEM_ASSERT_RW(&block[0], b - &block[0]);
- UNIV_MEM_ASSERT_W(&block[0], srv_sort_buf_size);
+ MEM_CHECK_DEFINED(&block[0], b - &block[0]);
+ MEM_CHECK_ADDRESSABLE(&block[0], srv_sort_buf_size);
-#ifdef UNIV_DEBUG_VALGRIND
- /* The rest of the block is uninitialized. Initialize it
- to avoid bogus warnings. */
- memset(b, 0xff, ulint(&block[srv_sort_buf_size] - b));
-#endif /* UNIV_DEBUG_VALGRIND */
+ /* The rest of the block is uninitialized. Silence warnings. */
+ MEM_MAKE_DEFINED(b, &block[srv_sort_buf_size] - b);
if (!row_merge_write(fd, (*foffs)++, block, crypt_block, space)) {
DBUG_RETURN(NULL);
}
- UNIV_MEM_INVALID(&block[0], srv_sort_buf_size);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(&block[0], srv_sort_buf_size);
+#endif
DBUG_RETURN(&block[0]);
}
@@ -2660,8 +2661,10 @@ write_buffers:
break;
}
- UNIV_MEM_INVALID(
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(
&block[0], srv_sort_buf_size);
+#endif /* HAVE_valgrind_or_MSAN */
}
}
merge_buf[i] = row_merge_buf_empty(buf);
@@ -3137,10 +3140,10 @@ row_merge(
ulint n_run = 0;
/*!< num of runs generated from this merge */
- UNIV_MEM_ASSERT_W(&block[0], 3 * srv_sort_buf_size);
+ MEM_CHECK_ADDRESSABLE(&block[0], 3 * srv_sort_buf_size);
if (crypt_block) {
- UNIV_MEM_ASSERT_W(&crypt_block[0], 3 * srv_sort_buf_size);
+ MEM_CHECK_ADDRESSABLE(&crypt_block[0], 3 * srv_sort_buf_size);
}
ut_ad(ihalf < file->offset);
@@ -3161,7 +3164,9 @@ row_merge(
foffs0 = 0;
foffs1 = ihalf;
- UNIV_MEM_INVALID(run_offset, *num_run * sizeof *run_offset);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(run_offset, *num_run * sizeof *run_offset);
+#endif /* HAVE_valgrind_or_MSAN */
for (; foffs0 < ihalf && foffs1 < file->offset; foffs0++, foffs1++) {
@@ -3242,7 +3247,9 @@ row_merge(
*tmpfd = file->fd;
*file = of;
- UNIV_MEM_INVALID(&block[0], 3 * srv_sort_buf_size);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(&block[0], 3 * srv_sort_buf_size);
+#endif /* HAVE_valgrind_or_MSAN */
return(DB_SUCCESS);
}
@@ -3356,7 +3363,7 @@ row_merge_sort(
break;
}
- UNIV_MEM_ASSERT_RW(run_offset, num_runs * sizeof *run_offset);
+ MEM_CHECK_DEFINED(run_offset, num_runs * sizeof *run_offset);
} while (num_runs > 1);
ut_free(run_offset);
@@ -3916,6 +3923,7 @@ row_merge_drop_indexes(
ut_error;
}
+ fts_clear_all(table, trx);
return;
}
@@ -3968,6 +3976,7 @@ row_merge_drop_indexes(
}
}
+ fts_clear_all(table, trx);
table->drop_aborted = FALSE;
ut_d(dict_table_check_for_dup_indexes(table, CHECK_ALL_COMPLETE));
}
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 298c2a3c879..20f06fc5444 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -294,9 +294,7 @@ row_mysql_store_geometry(
{
/* MySQL might assume the field is set to zero except the length and
the pointer fields */
- UNIV_MEM_ASSERT_RW(src, src_len);
- UNIV_MEM_ASSERT_W(dest, dest_len);
- UNIV_MEM_INVALID(dest, dest_len);
+ MEM_CHECK_DEFINED(src, src_len);
memset(dest, '\0', dest_len);
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 77a043acccc..8b46364c744 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -974,9 +974,11 @@ row_sel_get_clust_rec(
switch (err) {
case DB_SUCCESS:
case DB_SUCCESS_LOCKED_REC:
- /* Declare the variable uninitialized in Valgrind.
+#ifdef HAVE_valgrind_or_MSAN
+ /* Declare the variable uninitialized.
It should be set to DB_SUCCESS at func_exit. */
- UNIV_MEM_INVALID(&err, sizeof err);
+ MEM_UNDEFINED(&err, sizeof err);
+#endif /* HAVE_valgrind_or_MSAN */
break;
default:
goto err_exit;
@@ -2682,9 +2684,11 @@ row_sel_field_store_in_mysql_format_func(
#endif /* UNIV_DEBUG */
ut_ad(len != UNIV_SQL_NULL);
- UNIV_MEM_ASSERT_RW(data, len);
- UNIV_MEM_ASSERT_W(dest, templ->mysql_col_len);
- UNIV_MEM_INVALID(dest, templ->mysql_col_len);
+ MEM_CHECK_DEFINED(data, len);
+ MEM_CHECK_ADDRESSABLE(dest, templ->mysql_col_len);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(dest, templ->mysql_col_len);
+#endif /* HAVE_valgrind_or_MSAN */
byte* pad = dest + len;
@@ -2932,9 +2936,9 @@ row_sel_store_mysql_field(
NULL value is set to the default value. */
ut_ad(templ->mysql_null_bit_mask);
- UNIV_MEM_ASSERT_RW(prebuilt->default_rec
- + templ->mysql_col_offset,
- templ->mysql_col_len);
+ MEM_CHECK_DEFINED(prebuilt->default_rec
+ + templ->mysql_col_offset,
+ templ->mysql_col_len);
#if defined __GNUC__ && !defined __clang__ && __GNUC__ < 6
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wconversion" /* GCC 5 may need this here */
@@ -3601,7 +3605,7 @@ row_sel_copy_cached_field_for_mysql(
buf += templ->mysql_col_offset;
cache += templ->mysql_col_offset;
- UNIV_MEM_ASSERT_W(buf, templ->mysql_col_len);
+ MEM_CHECK_ADDRESSABLE(buf, templ->mysql_col_len);
if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR
&& (templ->type != DATA_INT)) {
@@ -3611,7 +3615,9 @@ row_sel_copy_cached_field_for_mysql(
row_mysql_read_true_varchar(
&len, cache, templ->mysql_length_bytes);
len += templ->mysql_length_bytes;
- UNIV_MEM_INVALID(buf, templ->mysql_col_len);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(buf, templ->mysql_col_len);
+#endif /* HAVE_valgrind_or_MSAN */
} else {
len = templ->mysql_col_len;
}
@@ -3677,7 +3683,7 @@ row_sel_dequeue_cached_row_for_mysql(
ut_ad(prebuilt->n_fetch_cached > 0);
ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len);
- UNIV_MEM_ASSERT_W(buf, prebuilt->mysql_row_len);
+ MEM_CHECK_ADDRESSABLE(buf, prebuilt->mysql_row_len);
cached_rec = prebuilt->fetch_cache[prebuilt->fetch_cache_first];
@@ -3687,7 +3693,9 @@ row_sel_dequeue_cached_row_for_mysql(
/* The record is long. Copy it field by field, in case
there are some long VARCHAR column of which only a
small length is being used. */
- UNIV_MEM_INVALID(buf, prebuilt->mysql_prefix_len);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(buf, prebuilt->mysql_prefix_len);
+#endif /* HAVE_valgrind_or_MSAN */
/* First copy the NULL bits. */
memcpy(buf, cached_rec, prebuilt->null_bitmap_len);
@@ -3771,8 +3779,10 @@ row_sel_fetch_last_buf(
}
ut_ad(prebuilt->fetch_cache_first == 0);
- UNIV_MEM_INVALID(prebuilt->fetch_cache[prebuilt->n_fetch_cached],
- prebuilt->mysql_row_len);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(prebuilt->fetch_cache[prebuilt->n_fetch_cached],
+ prebuilt->mysql_row_len);
+#endif /* HAVE_valgrind_or_MSAN */
return(prebuilt->fetch_cache[prebuilt->n_fetch_cached]);
}
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index 894ee3e1e0c..969d0017eeb 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -1542,7 +1542,9 @@ row_upd_changes_ord_field_binary_func(
/* Silence a compiler warning without
silencing a Valgrind error. */
dfield_len = 0;
- UNIV_MEM_INVALID(&dfield_len, sizeof dfield_len);
+#ifdef HAVE_valgrind_or_MSAN
+ MEM_UNDEFINED(&dfield_len, sizeof dfield_len);
+#endif /* HAVE_valgrind_or_MSAN */
/* See if the column is stored externally. */
buf = row_ext_lookup(ext, col_no, &dfield_len);
diff --git a/storage/innobase/sync/sync0arr.cc b/storage/innobase/sync/sync0arr.cc
index a599ab2f644..a0203ca6bde 100644
--- a/storage/innobase/sync/sync0arr.cc
+++ b/storage/innobase/sync/sync0arr.cc
@@ -891,9 +891,9 @@ sync_array_print_long_waits_low(
return(false);
}
-#ifdef UNIV_DEBUG_VALGRIND
+#ifdef HAVE_valgrind
/* Increase the timeouts if running under valgrind because it executes
- extremely slowly. UNIV_DEBUG_VALGRIND does not necessary mean that
+ extremely slowly. HAVE_valgrind does not necessary mean that
we are running under valgrind but we have no better way to tell.
See Bug#58432 innodb.innodb_bug56143 fails under valgrind
for an example */
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index e44b4e497d1..eaf127b5a43 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -462,18 +462,18 @@ void trx_free(trx_t*& trx)
MEM_UNDEFINED(&trx->state, sizeof trx->state);
MEM_UNDEFINED(&trx->mysql_thd, sizeof trx->mysql_thd);
#endif
-#ifdef HAVE_valgrind
+#ifdef HAVE_valgrind_or_MSAN
/* Unpoison the memory for innodb_monitor_set_option;
it is operating also on the freed transaction objects.
We checked that these were initialized in
trx_pools->mem_free(trx). */
- UNIV_MEM_VALID(&trx->mutex, sizeof trx->mutex);
+ MEM_MAKE_DEFINED(&trx->mutex, sizeof trx->mutex);
/* For innobase_kill_connection() */
# ifdef WITH_WSREP
- UNIV_MEM_VALID(&trx->wsrep, sizeof trx->wsrep);
+ MEM_MAKE_DEFINED(&trx->wsrep, sizeof trx->wsrep);
# endif
- UNIV_MEM_VALID(&trx->state, sizeof trx->state);
- UNIV_MEM_VALID(&trx->mysql_thd, sizeof trx->mysql_thd);
+ MEM_MAKE_DEFINED(&trx->state, sizeof trx->state);
+ MEM_MAKE_DEFINED(&trx->mysql_thd, sizeof trx->mysql_thd);
#endif
trx = NULL;
diff --git a/storage/innobase/ut/ut0crc32.cc b/storage/innobase/ut/ut0crc32.cc
index 3c40a2aac7d..dabf92e875b 100644
--- a/storage/innobase/ut/ut0crc32.cc
+++ b/storage/innobase/ut/ut0crc32.cc
@@ -84,6 +84,7 @@ mysys/my_perf.c, contributed by Facebook under the following license.
#include <string.h>
#include "ut0crc32.h"
+#include "my_valgrind.h"
#ifdef _MSC_VER
# include <intrin.h>
diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc
index dfc1d62c60c..bf35e7857c5 100644
--- a/storage/innobase/ut/ut0ut.cc
+++ b/storage/innobase/ut/ut0ut.cc
@@ -148,8 +148,6 @@ ut_print_buf(
const byte* data;
ulint i;
- UNIV_MEM_ASSERT_RW(buf, len);
-
fprintf(file, " len " ULINTPF "; hex ", len);
for (data = (const byte*) buf, i = 0; i < len; i++) {
@@ -184,8 +182,6 @@ ut_print_buf_hex(
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
};
- UNIV_MEM_ASSERT_RW(buf, len);
-
o << "(0x";
for (data = static_cast<const byte*>(buf), i = 0; i < len; i++) {
@@ -208,8 +204,6 @@ ut_print_buf(
const byte* data;
ulint i;
- UNIV_MEM_ASSERT_RW(buf, len);
-
for (data = static_cast<const byte*>(buf), i = 0; i < len; i++) {
int c = static_cast<int>(*data++);
o << (isprint(c) ? static_cast<char>(c) : ' ');
diff --git a/storage/myisam/ftbench/Ecompare.pl b/storage/myisam/ftbench/Ecompare.pl
index 07132ef9001..a97f126e64e 100755
--- a/storage/myisam/ftbench/Ecompare.pl
+++ b/storage/myisam/ftbench/Ecompare.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2003, 2005 MySQL AB
# Use is subject to license terms
diff --git a/storage/myisam/ftbench/Ecreate.pl b/storage/myisam/ftbench/Ecreate.pl
index 86af9f9c0a5..78962466c80 100755
--- a/storage/myisam/ftbench/Ecreate.pl
+++ b/storage/myisam/ftbench/Ecreate.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2003, 2005 MySQL AB
# Use is subject to license terms
diff --git a/storage/myisam/ftbench/Ereport.pl b/storage/myisam/ftbench/Ereport.pl
index d3f8961ec85..a8c7c57e1be 100755
--- a/storage/myisam/ftbench/Ereport.pl
+++ b/storage/myisam/ftbench/Ereport.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2003, 2005 MySQL AB
# Use is subject to license terms
diff --git a/storage/rocksdb/CMakeLists.txt b/storage/rocksdb/CMakeLists.txt
index 1b4f9aa6a17..090ababf238 100644
--- a/storage/rocksdb/CMakeLists.txt
+++ b/storage/rocksdb/CMakeLists.txt
@@ -188,9 +188,6 @@ endif()
TARGET_LINK_LIBRARIES(rocksdb rocksdb_aux_lib)
- FIND_LIBRARY(LZ4_LIBRARY
- NAMES liblz4${PIC_EXT}.a lz4
- HINTS ${WITH_LZ4}/lib)
CHECK_FUNCTION_EXISTS(sched_getcpu HAVE_SCHED_GETCPU)
IF(HAVE_SCHED_GETCPU)
@@ -252,13 +249,6 @@ ELSEIF(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Cla
SET_TARGET_PROPERTIES(rocksdb_tools sst_dump mariadb-ldb PROPERTIES COMPILE_FLAGS "-Wno-error")
ENDIF()
-# Enable ZSTD if available. Upstream rocksdb cmake will use WITH_ZSTD and set
-# defines within their code.
-FIND_PACKAGE(zstd)
-IF (ZSTD_FOUND)
- SET(WITH_ZSTD ON)
-ENDIF()
-
IF(GIT_EXECUTABLE AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/.git)
EXECUTE_PROCESS(
COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
diff --git a/storage/rocksdb/build_rocksdb.cmake b/storage/rocksdb/build_rocksdb.cmake
index 2e939587811..f7b2170978d 100644
--- a/storage/rocksdb/build_rocksdb.cmake
+++ b/storage/rocksdb/build_rocksdb.cmake
@@ -35,52 +35,47 @@ endif()
# Optional compression libraries.
-foreach(compression_lib LZ4 BZip2 ZSTD snappy)
- FIND_PACKAGE(${compression_lib} QUIET)
-
- SET(WITH_ROCKSDB_${compression_lib} AUTO CACHE STRING
- "Build RocksDB with ${compression_lib} compression. Possible values are 'ON', 'OFF', 'AUTO' and default is 'AUTO'")
-
- if(${WITH_ROCKSDB_${compression_lib}} STREQUAL "ON" AND NOT ${${compression_lib}_FOUND})
- MESSAGE(FATAL_ERROR
- "${compression_lib} library was not found, but WITH_ROCKSDB${compression_lib} option is ON.\
- Either set WITH_ROCKSDB${compression_lib} to OFF, or make sure ${compression_lib} is installed")
- endif()
-endforeach()
-
-if(LZ4_FOUND AND (NOT WITH_ROCKSDB_LZ4 STREQUAL "OFF"))
- add_definitions(-DLZ4)
- include_directories(${LZ4_INCLUDE_DIR})
- list(APPEND THIRDPARTY_LIBS ${LZ4_LIBRARY})
-endif()
-
-if(BZIP2_FOUND AND (NOT WITH_ROCKSDB_BZip2 STREQUAL "OFF"))
- add_definitions(-DBZIP2)
- include_directories(${BZIP2_INCLUDE_DIR})
- list(APPEND THIRDPARTY_LIBS ${BZIP2_LIBRARIES})
-endif()
-
-if(SNAPPY_FOUND AND (NOT WITH_ROCKSDB_snappy STREQUAL "OFF"))
- add_definitions(-DSNAPPY)
- include_directories(${snappy_INCLUDE_DIR})
- list(APPEND THIRDPARTY_LIBS ${snappy_LIBRARIES})
-endif()
-
include(CheckFunctionExists)
-if(ZSTD_FOUND AND (NOT WITH_ROCKSDB_ZSTD STREQUAL "OFF"))
- SET(CMAKE_REQUIRED_LIBRARIES zstd)
- CHECK_FUNCTION_EXISTS(ZDICT_trainFromBuffer ZSTD_VALID)
- UNSET(CMAKE_REQUIRED_LIBRARIES)
- if (WITH_ROCKSDB_ZSTD STREQUAL "ON" AND NOT ZSTD_VALID)
+macro(check_lib package var)
+ STRING(TOUPPER ${package} PACKAGE_NAME)
+ SET(WITH_ROCKSDB_${package} AUTO CACHE STRING
+ "Build RocksDB with ${package} compression. Possible values are 'ON', 'OFF', 'AUTO' and default is 'AUTO'")
+
+ IF (NOT ${WITH_ROCKSDB_${package}} STREQUAL "OFF")
+ FIND_PACKAGE(${package} QUIET)
+ IF (${${PACKAGE_NAME}_FOUND})
+ IF(${ARGC} GREATER 2)
+ SET(CMAKE_REQUIRED_LIBRARIES ${${var}_LIBRARIES})
+ CHECK_FUNCTION_EXISTS(${ARGV2} ${var}_VALID)
+ UNSET(CMAKE_REQUIRED_LIBRARIES)
+ ELSE()
+ SET(${var}_VALID TRUE)
+ ENDIF()
+ ENDIF()
+ ENDIF()
+
+ IF(${${var}_VALID})
+ MESSAGE_ONCE(rocksdb_${var} "Found ${package}: ${${var}_LIBRARIES}")
+ add_definitions(-D${PACKAGE_NAME})
+ include_directories(${${var}_INCLUDE_DIR})
+ list(APPEND THIRDPARTY_LIBS ${${var}_LIBRARIES})
+ ELSEIF(${${PACKAGE_NAME}_FOUND})
+ MESSAGE_ONCE(rocksdb_${var} "Found unusable ${package}: ${${var}_LIBRARIES} [${ARGV2}]")
+ ELSE()
+ MESSAGE_ONCE(rocksdb_${var} "Could NOT find ${package}")
+ ENDIF()
+
+ IF (${WITH_ROCKSDB_${package}} STREQUAL "ON" AND NOT ${${PACKAGE_NAME}_FOUND})
MESSAGE(FATAL_ERROR
- "WITH_ROCKSDB_ZSTD is ON and ZSTD library was found, but the version needs to be >= 1.1.3")
+ "${package} library was not found, but WITH_ROCKSDB_${package} option is ON.\
+ Either set WITH_ROCKSDB_${package} to OFF, or make sure ${package} is installed")
endif()
- if (ZSTD_VALID)
- add_definitions(-DZSTD)
- include_directories(${ZSTD_INCLUDE_DIR})
- list(APPEND THIRDPARTY_LIBS ${ZSTD_LIBRARIES})
- endif()
-endif()
+endmacro()
+
+check_lib(LZ4 LZ4)
+check_lib(BZip2 BZIP2)
+check_lib(snappy snappy) # rocksdb/cmake/modules/Findsnappy.cmake violates the convention
+check_lib(ZSTD ZSTD ZDICT_trainFromBuffer)
add_definitions(-DZLIB)
list(APPEND THIRDPARTY_LIBS ${ZLIB_LIBRARY})
diff --git a/tests/big_record.pl b/tests/big_record.pl
index b2aeee27658..639e305b2e8 100755
--- a/tests/big_record.pl
+++ b/tests/big_record.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
#
diff --git a/tests/drop_test.pl b/tests/drop_test.pl
index 15a75f4908c..c132c207811 100755
--- a/tests/drop_test.pl
+++ b/tests/drop_test.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl -w
# Copyright (C) 2000 MySQL AB
# Use is subject to license terms
diff --git a/tests/export.pl b/tests/export.pl
index f99798ecac8..dace79feb30 100755
--- a/tests/export.pl
+++ b/tests/export.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (C) 2000, 2001 MySQL AB
# Use is subject to license terms
diff --git a/tests/fork2_test.pl b/tests/fork2_test.pl
index 356055733fa..a05a9b96679 100755
--- a/tests/fork2_test.pl
+++ b/tests/fork2_test.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl -w
# Copyright (C) 2000, 2001 MySQL AB
# Use is subject to license terms
diff --git a/tests/fork_big.pl b/tests/fork_big.pl
index 2f803b7fdd3..a08044efbd8 100755
--- a/tests/fork_big.pl
+++ b/tests/fork_big.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl -w
use strict;
# Copyright (c) 2001, 2006 MySQL AB
diff --git a/tests/fork_big2.pl b/tests/fork_big2.pl
index a2b465734dc..a90af381376 100644
--- a/tests/fork_big2.pl
+++ b/tests/fork_big2.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl -w
# Copyright (c) 2002, 2003, 2005, 2006 MySQL AB
# Use is subject to license terms
diff --git a/tests/grant.pl b/tests/grant.pl
index f8cdc1af4d5..6da22286d1c 100755
--- a/tests/grant.pl
+++ b/tests/grant.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2005 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
diff --git a/tests/index_corrupt.pl b/tests/index_corrupt.pl
index 6f31b85bd61..dad288d71de 100755
--- a/tests/index_corrupt.pl
+++ b/tests/index_corrupt.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl -w
# Copyright (C) 2005 MySQL AB
# Use is subject to license terms
diff --git a/tests/insert_and_repair.pl b/tests/insert_and_repair.pl
index dfa490456cb..f70bc75fb9a 100755
--- a/tests/insert_and_repair.pl
+++ b/tests/insert_and_repair.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl -w
# Copyright (C) 2000, 2001 MySQL AB
# Use is subject to license terms
diff --git a/tests/lock_test.pl b/tests/lock_test.pl
index 98c4ad6377d..8a8a0322467 100755
--- a/tests/lock_test.pl
+++ b/tests/lock_test.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (C) 2000 MySQL AB
# Use is subject to license terms
diff --git a/tests/mail_to_db.pl b/tests/mail_to_db.pl
index 94f3955b2c3..0dd0fe751aa 100755
--- a/tests/mail_to_db.pl
+++ b/tests/mail_to_db.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl -w
# Copyright Abandoned 1998 TCX DataKonsult AB & Monty Program KB & Detron HB
# This file is public domain and comes with NO WARRANTY of any kind
#
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 22c3955d524..6a6f626ae8c 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2002, 2014, Oracle and/or its affiliates.
- Copyright (c) 2008, 2019, MariaDB
+ Copyright (c) 2008, 2020, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20548,6 +20548,59 @@ static void test_bulk_replace()
}
#endif
+
+static void test_ps_params_in_ctes()
+{
+ int rc;
+ const char *query;
+ MYSQL_BIND ps_params[1];
+ int int_data[1];
+ MYSQL_STMT *stmt;
+
+ rc= mysql_query(mysql, "create table t1(a int, b int, key(a))");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "insert into t1 (a) values "
+ "(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)");
+ myquery(rc);
+
+ query=
+ "explain "
+ "with T as "
+ "( "
+ " select * from t1 where t1.a=? limit 2 "
+ ") "
+ "select * from T as TA, T as TB;";
+
+ stmt= mysql_stmt_init(mysql);
+ check_stmt(stmt);
+
+ rc= mysql_stmt_prepare(stmt, query, (uint) strlen(query));
+ check_execute(stmt, rc);
+
+ int_data[0]=2;
+
+ ps_params[0].buffer_type= MYSQL_TYPE_LONG;
+ ps_params[0].buffer= (char *) &int_data[0];
+ ps_params[0].length= 0;
+ ps_params[0].is_null= 0;
+
+ rc= mysql_stmt_bind_param(stmt, ps_params);
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_store_result(stmt);
+ check_execute(stmt, rc);
+
+ mysql_stmt_close(stmt);
+
+ rc= mysql_query(mysql, "drop table t1");
+ myquery(rc);
+}
+
+
static void print_metadata(MYSQL_RES *rs_metadata, int num_fields)
{
int i;
@@ -21224,6 +21277,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bulk_delete", test_bulk_delete },
{ "test_bulk_replace", test_bulk_replace },
#endif
+ { "test_ps_params_in_ctes", test_ps_params_in_ctes },
{ "test_explain_meta", test_explain_meta },
{ "test_mdev18408", test_mdev18408 },
{ "test_mdev20261", test_mdev20261 },
diff --git a/tests/pmail.pl b/tests/pmail.pl
index de469923c7d..ef654d99770 100755
--- a/tests/pmail.pl
+++ b/tests/pmail.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl -w
# Copyright (C) 2000, 2005 MySQL AB
# Use is subject to license terms
diff --git a/tests/rename_test.pl b/tests/rename_test.pl
index ff1b73434e5..eef8af642ab 100755
--- a/tests/rename_test.pl
+++ b/tests/rename_test.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl -w
# Copyright (C) 2000, 2001 MySQL AB
# Use is subject to license terms
diff --git a/tests/table_types.pl b/tests/table_types.pl
index c633a153098..782b8f254bf 100755
--- a/tests/table_types.pl
+++ b/tests/table_types.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (C) 2000, 2003 MySQL AB
# Use is subject to license terms
diff --git a/tests/test_delayed_insert.pl b/tests/test_delayed_insert.pl
index 2ebb42e08d1..8a8028be7ef 100755
--- a/tests/test_delayed_insert.pl
+++ b/tests/test_delayed_insert.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl -w
# Copyright (C) 2000, 2001 MySQL AB
# Use is subject to license terms
diff --git a/tests/truncate.pl b/tests/truncate.pl
index 85a7888bc4a..84381187aa7 100755
--- a/tests/truncate.pl
+++ b/tests/truncate.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl -w
# Copyright (C) 2002 MySQL AB
# Use is subject to license terms
diff --git a/unittest/unit.pl b/unittest/unit.pl
index fb9a16fbe49..dc72a57d20c 100644
--- a/unittest/unit.pl
+++ b/unittest/unit.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2006 MySQL AB, 2009, 2010 Sun Microsystems, Inc.
# Use is subject to license terms.
#