summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt9
-rw-r--r--VERSION4
-rw-r--r--client/mysqladmin.cc63
-rw-r--r--client/mysqldump.c39
-rw-r--r--cmake/dtrace.cmake43
-rw-r--r--cmake/install_macros.cmake4
-rw-r--r--cmake/os/Windows.cmake29
-rw-r--r--extra/yassl/CMakeLists.txt3
-rw-r--r--extra/yassl/src/ssl.cpp7
-rw-r--r--extra/yassl/taocrypt/CMakeLists.txt3
-rw-r--r--extra/yassl/taocrypt/include/asn.hpp8
-rw-r--r--include/thread_pool_priv.h2
-rw-r--r--libmysql/CMakeLists.txt1
-rw-r--r--man/CMakeLists.txt1
-rw-r--r--man/aria_pack.12
-rw-r--r--man/mysqlbinlog.17
-rw-r--r--man/mysqldump.12
-rw-r--r--mysql-test/include/have_semisync_plugin.inc15
-rw-r--r--mysql-test/include/install_semisync.inc4
-rw-r--r--mysql-test/include/stop_dump_threads.inc32
-rw-r--r--mysql-test/include/uninstall_semisync.inc5
-rw-r--r--mysql-test/r/ctype_ucs.result33
-rw-r--r--mysql-test/r/ctype_utf32.result33
-rw-r--r--mysql-test/r/func_str.result3
-rw-r--r--mysql-test/r/func_time.result79
-rw-r--r--mysql-test/r/group_min_max.result56
-rw-r--r--mysql-test/r/group_min_max_innodb.result168
-rw-r--r--mysql-test/r/innodb_load_xa.result21
-rw-r--r--mysql-test/r/mysqld--help.result4
-rw-r--r--mysql-test/r/order_by_innodb.result13
-rw-r--r--mysql-test/r/partition.result44
-rw-r--r--mysql-test/r/partition_innodb.result28
-rw-r--r--mysql-test/r/partition_pruning.result114
-rw-r--r--mysql-test/r/plugin_loaderr.result3
-rw-r--r--mysql-test/r/subselect_mat.result37
-rw-r--r--mysql-test/r/subselect_sj_mat.result37
-rw-r--r--mysql-test/r/type_decimal.result4
-rw-r--r--mysql-test/r/type_newdecimal.result6
-rw-r--r--mysql-test/r/union.result34
-rw-r--r--mysql-test/r/variables.result4
-rw-r--r--mysql-test/r/view.result94
-rwxr-xr-x[-rw-r--r--]mysql-test/std_data/checkDBI_DBD-mysql.pl0
-rw-r--r--mysql-test/suite/archive/partition_archive.result26
-rw-r--r--mysql-test/suite/archive/partition_archive.test18
-rw-r--r--mysql-test/suite/binlog/t/binlog_killed.test4
-rw-r--r--mysql-test/suite/engines/iuds/r/insert_time.result4
-rw-r--r--mysql-test/suite/engines/iuds/suite.opt2
-rw-r--r--mysql-test/suite/innodb/r/blob_unique2pk.result15
-rw-r--r--mysql-test/suite/innodb/r/innodb-fk.result35
-rw-r--r--mysql-test/suite/innodb/t/blob_unique2pk.test20
-rw-r--r--mysql-test/suite/innodb/t/innodb-fk.test86
-rw-r--r--mysql-test/suite/maria/maria_partition.result15
-rw-r--r--mysql-test/suite/maria/maria_partition.test22
-rw-r--r--mysql-test/suite/rpl/r/failed_create_view-6409.result15
-rw-r--r--mysql-test/suite/rpl/r/kill_hard-6290.result4
-rw-r--r--mysql-test/suite/rpl/r/rpl_heartbeat_debug.result25
-rw-r--r--mysql-test/suite/rpl/r/rpl_semi_sync_uninstall_plugin.result61
-rw-r--r--mysql-test/suite/rpl/r/rpl_stop_slave.result7
-rw-r--r--mysql-test/suite/rpl/t/failed_create_view-6409.test24
-rw-r--r--mysql-test/suite/rpl/t/kill_hard-6290.test11
-rw-r--r--mysql-test/suite/rpl/t/rpl_heartbeat_debug.test52
-rw-r--r--mysql-test/suite/rpl/t/rpl_semi_sync_uninstall_plugin.test130
-rw-r--r--mysql-test/suite/rpl/t/rpl_stop_slave.test27
-rw-r--r--mysql-test/suite/sys_vars/r/timed_mutexes_basic.result20
-rw-r--r--mysql-test/t/ctype_ucs.test17
-rw-r--r--mysql-test/t/ctype_utf32.test16
-rw-r--r--mysql-test/t/func_str.test5
-rw-r--r--mysql-test/t/func_time.test46
-rw-r--r--mysql-test/t/group_min_max.test25
-rw-r--r--mysql-test/t/group_min_max_innodb.test93
-rw-r--r--mysql-test/t/innodb_load_xa.opt1
-rw-r--r--mysql-test/t/innodb_load_xa.test18
-rwxr-xr-x[-rw-r--r--]mysql-test/t/long_tmpdir-master.sh0
-rwxr-xr-x[-rw-r--r--]mysql-test/t/lowercase_mixed_tmpdir-master.sh0
-rw-r--r--mysql-test/t/order_by_innodb.test23
-rw-r--r--mysql-test/t/partition.test41
-rw-r--r--mysql-test/t/partition_innodb.test28
-rw-r--r--mysql-test/t/partition_pruning.test48
-rw-r--r--mysql-test/t/plugin_loaderr.test16
-rw-r--r--mysql-test/t/subselect_sj_mat.test33
-rw-r--r--mysql-test/t/union.test30
-rw-r--r--mysql-test/t/view.test104
-rw-r--r--mysys/CMakeLists.txt3
-rw-r--r--mysys/mf_iocache2.c9
-rwxr-xr-xpackaging/rpm-oel/filter-requires.sh2
-rw-r--r--packaging/rpm-oel/mysql.spec.in51
-rw-r--r--packaging/rpm-uln/CMakeLists.txt38
-rw-r--r--packaging/rpm-uln/README-ULN15
-rw-r--r--packaging/rpm-uln/README.mysql-docs4
-rwxr-xr-xpackaging/rpm-uln/filter-requires-mysql.sh3
-rwxr-xr-xpackaging/rpm-uln/generate-tarball.sh15
-rw-r--r--packaging/rpm-uln/my.cnf10
-rw-r--r--packaging/rpm-uln/my_config.h29
-rw-r--r--packaging/rpm-uln/mysql-5.5-errno.patch21
-rw-r--r--packaging/rpm-uln/mysql-5.5-fix-tests.patch34
-rw-r--r--packaging/rpm-uln/mysql-5.5-libdir.patch28
-rw-r--r--packaging/rpm-uln/mysql-5.5-mtr1.patch25
-rw-r--r--packaging/rpm-uln/mysql-5.5-stack-guard.patch140
-rw-r--r--packaging/rpm-uln/mysql-5.5-testing.patch23
-rw-r--r--packaging/rpm-uln/mysql-chain-certs.patch45
-rw-r--r--packaging/rpm-uln/mysql-embedded-check.c26
-rw-r--r--packaging/rpm-uln/mysql-expired-certs.patch555
-rw-r--r--packaging/rpm-uln/mysql-install-test.patch33
-rw-r--r--packaging/rpm-uln/mysql-strmov.patch32
-rw-r--r--packaging/rpm-uln/mysql.init209
-rw-r--r--packaging/rpm-uln/mysql.spec.sh1991
-rw-r--r--packaging/rpm-uln/scriptstub.c32
-rw-r--r--plugin/win_auth_client/CMakeLists.txt1
-rw-r--r--scripts/CMakeLists.txt1
-rw-r--r--scripts/mysql_config.sh7
-rw-r--r--[-rwxr-xr-x]scripts/mysqlaccess.conf0
-rw-r--r--scripts/mysqld_safe.sh29
-rwxr-xr-x[-rw-r--r--]sql-bench/graph-compare-results.sh0
-rw-r--r--sql/field.h23
-rw-r--r--sql/filesort.cc3
-rw-r--r--sql/handler.cc12
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item.h38
-rw-r--r--sql/item_func.cc93
-rw-r--r--sql/item_func.h17
-rw-r--r--sql/item_strfunc.cc104
-rw-r--r--sql/item_strfunc.h15
-rw-r--r--sql/item_subselect.cc5
-rw-r--r--sql/item_timefunc.h10
-rw-r--r--sql/log.cc9
-rw-r--r--sql/log.h9
-rw-r--r--sql/log_event.cc6
-rw-r--r--sql/mysqld.cc7
-rw-r--r--sql/opt_range.cc279
-rw-r--r--sql/opt_range.h15
-rw-r--r--sql/replication.h14
-rw-r--r--sql/rpl_handler.cc79
-rw-r--r--sql/rpl_handler.h5
-rw-r--r--sql/scheduler.cc4
-rw-r--r--sql/slave.cc39
-rw-r--r--sql/sql_cache.cc4
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_delete.cc3
-rw-r--r--sql/sql_derived.cc6
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_lex.cc21
-rw-r--r--sql/sql_lex.h6
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_partition.cc43
-rw-r--r--sql/sql_plugin.cc2
-rw-r--r--sql/sql_repl.cc2
-rw-r--r--sql/sql_select.cc61
-rw-r--r--sql/sql_select.h4
-rw-r--r--sql/sql_show.cc5
-rw-r--r--sql/sql_table.cc64
-rw-r--r--sql/sql_table.h3
-rw-r--r--sql/sql_union.cc3
-rw-r--r--sql/sql_view.cc7
-rw-r--r--sql/sql_yacc.yy5
-rw-r--r--sql/sys_vars.cc9
-rw-r--r--sql/table.cc27
-rw-r--r--storage/heap/hp_block.c6
-rw-r--r--storage/heap/hp_create.c3
-rw-r--r--storage/innobase/handler/ha_innodb.cc8
-rw-r--r--storage/innobase/row/row0sel.cc35
-rw-r--r--storage/maria/ha_maria.cc56
-rw-r--r--storage/maria/ma_close.c6
-rw-r--r--storage/maria/ma_open.c5
-rw-r--r--storage/maria/ma_state.c3
-rw-r--r--storage/maria/maria_def.h2
-rw-r--r--storage/myisam/ha_myisam.cc1
-rw-r--r--storage/tokudb/CMakeLists.in29
-rw-r--r--storage/tokudb/CMakeLists.txt3
-rw-r--r--storage/tokudb/README.md8
-rw-r--r--storage/tokudb/ft-index/CMakeLists.txt25
-rw-r--r--storage/tokudb/ft-index/cmake_modules/TokuThirdParty.cmake53
-rw-r--r--storage/tokudb/ft-index/ft/checkpoint.cc8
-rw-r--r--storage/tokudb/ft-index/ft/ft-cachetable-wrappers.cc22
-rw-r--r--storage/tokudb/ft-index/ft/ft-cachetable-wrappers.h3
-rw-r--r--storage/tokudb/ft-index/ft/ft-flusher.cc25
-rw-r--r--storage/tokudb/ft-index/ft/ft-internal.h25
-rw-r--r--storage/tokudb/ft-index/ft/ft-ops.cc408
-rw-r--r--storage/tokudb/ft-index/ft/ft-ops.h3
-rw-r--r--storage/tokudb/ft-index/ft/ft-serialize.cc1
-rw-r--r--storage/tokudb/ft-index/ft/ft-verify.cc26
-rw-r--r--storage/tokudb/ft-index/ft/ft_layout_version.h1
-rw-r--r--storage/tokudb/ft-index/ft/ft_node-serialize.cc132
-rw-r--r--storage/tokudb/ft-index/ft/ftloader-internal.h4
-rw-r--r--storage/tokudb/ft-index/ft/ftloader.cc165
-rw-r--r--storage/tokudb/ft-index/ft/ftloader.h3
-rw-r--r--storage/tokudb/ft-index/ft/log_upgrade.cc4
-rw-r--r--storage/tokudb/ft-index/ft/logger.cc2
-rw-r--r--storage/tokudb/ft-index/ft/tests/ftloader-test-bad-generate.cc2
-rw-r--r--storage/tokudb/ft-index/ft/tests/ftloader-test-extractor-errors.cc2
-rw-r--r--storage/tokudb/ft-index/ft/tests/ftloader-test-extractor.cc2
-rw-r--r--storage/tokudb/ft-index/ft/tests/ftloader-test-merge-files-dbufio.cc7
-rw-r--r--storage/tokudb/ft-index/ft/tests/ftloader-test-open.cc2
-rw-r--r--storage/tokudb/ft-index/ft/tests/test_rightmost_leaf_seqinsert_heuristic.cc183
-rw-r--r--storage/tokudb/ft-index/ft/tests/test_rightmost_leaf_split_merge.cc212
-rw-r--r--storage/tokudb/ft-index/ft/tokuftdump.cc415
-rwxr-xr-xstorage/tokudb/ft-index/scripts/run.stress-tests.py5
-rw-r--r--storage/tokudb/ft-index/src/loader.cc52
-rw-r--r--storage/tokudb/ft-index/src/tests/dbremove-nofile-limit.cc177
-rw-r--r--storage/tokudb/ft-index/src/tests/loader-close-nproc-limit.cc198
-rw-r--r--storage/tokudb/ft-index/src/tests/loader-create-close.cc14
-rw-r--r--storage/tokudb/ft-index/src/tests/loader-create-commit-nproc-limit.cc211
-rw-r--r--storage/tokudb/ft-index/src/tests/loader-create-nproc-limit.cc199
-rw-r--r--storage/tokudb/ft-index/src/tests/test_insert_unique.cc202
-rw-r--r--storage/tokudb/ft-index/src/ydb.cc10
-rw-r--r--storage/tokudb/ft-index/src/ydb_db.cc26
-rw-r--r--storage/tokudb/ft-index/src/ydb_write.cc82
-rw-r--r--storage/tokudb/ft-index/util/omt.cc3
-rw-r--r--storage/tokudb/ft-index/util/tests/threadpool-nproc-limit.cc171
-rw-r--r--storage/tokudb/ft-index/util/threadpool.cc25
-rw-r--r--storage/tokudb/ha_tokudb.cc229
-rw-r--r--storage/tokudb/ha_tokudb.h12
-rw-r--r--storage/tokudb/ha_tokudb_admin.cc44
-rw-r--r--storage/tokudb/ha_tokudb_alter_56.cc15
-rw-r--r--storage/tokudb/ha_tokudb_alter_common.cc2
-rw-r--r--storage/tokudb/hatoku_defines.h14
-rw-r--r--storage/tokudb/hatoku_hton.cc40
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_released.result3
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_timeout.result1
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks_released.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/mvcc-26.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/type_datetime.result1
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/type_decimal.result4
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result6
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test2
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_timeout.test1
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks.test2
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test5
-rw-r--r--storage/tokudb/mysql-test/tokudb_bugs/r/lock_uniq_key_empty.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb_bugs/r/optimize_temp_table_tokudb.result1
-rw-r--r--storage/tokudb/mysql-test/tokudb_bugs/t/lock_uniq_key_empty.test2
-rw-r--r--storage/tokudb/mysql-test/tokudb_mariadb/r/optimize.result1
-rwxr-xr-xstorage/tokudb/scripts/setup.mysql.bash83
-rw-r--r--storage/xtradb/handler/ha_innodb.cc8
-rw-r--r--storage/xtradb/os/os0stacktrace.cc2
-rw-r--r--storage/xtradb/row/row0sel.cc35
-rw-r--r--strings/CMakeLists.txt3
-rw-r--r--strings/ctype-bin.c3
-rw-r--r--strings/ctype-eucjpms.c5
-rw-r--r--strings/ctype-ucs2.c12
-rw-r--r--strings/ctype-ujis.c6
-rw-r--r--support-files/CMakeLists.txt8
-rw-r--r--support-files/mysql.server.sh5
-rw-r--r--support-files/mysql.spec.sh7
-rw-r--r--vio/CMakeLists.txt3
-rw-r--r--zlib/CMakeLists.txt3
246 files changed, 5932 insertions, 4666 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3426320c533..c5752d3e931 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,6 +26,14 @@ IF(POLICY CMP0022)
CMAKE_POLICY(SET CMP0022 OLD)
ENDIF()
+# We use the LOCATION target property (CMP0026)
+# and get_target_property() for non-existent targets (CMP0045)
+IF(CMAKE_VERSION VERSION_EQUAL "3.0.0" OR
+ CMAKE_VERSION VERSION_GREATER "3.0.0")
+ CMAKE_POLICY(SET CMP0026 OLD)
+ CMAKE_POLICY(SET CMP0045 OLD)
+ENDIF()
+
MESSAGE(STATUS "Running cmake version ${CMAKE_VERSION}")
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
@@ -441,7 +449,6 @@ IF(NOT WITHOUT_SERVER)
IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt)
ADD_SUBDIRECTORY(internal)
ENDIF()
- ADD_SUBDIRECTORY(packaging/rpm-uln)
ADD_SUBDIRECTORY(packaging/rpm-oel)
ENDIF()
diff --git a/VERSION b/VERSION
index 41932e2084d..1575b8cb514 100644
--- a/VERSION
+++ b/VERSION
@@ -1,7 +1,3 @@
-# Version number for MariaDB is maintained here.
-# The version string is created from:
-# MYSQL_VERSION_MAJOR.MYSQL_VERSION_MINOR.MYSQL_VERSION_PATCH-MYSQL_VERSION_EXTRA
-#
MYSQL_VERSION_MAJOR=10
MYSQL_VERSION_MINOR=0
MYSQL_VERSION_PATCH=13
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index bd5d2eac4e5..88016d9563d 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -1,6 +1,6 @@
/*
- Copyright (c) 2000, 2012, Oracle and/or its affiliates.
- Copyright (c) 2010, 2012, Monty Program Ab.
+ Copyright (c) 2000, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2014, Monty Program Ab.
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
@@ -71,6 +71,7 @@ extern "C" my_bool get_one_option(int optid, const struct my_option *opt,
char *argument);
static my_bool sql_connect(MYSQL *mysql, uint wait);
static int execute_commands(MYSQL *mysql,int argc, char **argv);
+static char **mask_password(int argc, char ***argv);
static int drop_db(MYSQL *mysql,const char *db);
extern "C" sig_handler endprog(int signal_number);
static void nice_time(ulong sec,char *buff);
@@ -306,9 +307,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
int main(int argc,char *argv[])
{
- int error= 0;
+ int error= 0, temp_argc;
MYSQL mysql;
- char **commands, **save_argv;
+ char **commands, **save_argv, **temp_argv;
MY_INIT(argv[0]);
mysql_init(&mysql);
@@ -316,8 +317,12 @@ int main(int argc,char *argv[])
if ((error= load_defaults("my",load_default_groups,&argc,&argv)))
goto err1;
save_argv = argv; /* Save for free_defaults */
+
if ((error=handle_options(&argc, &argv, my_long_options, get_one_option)))
goto err2;
+ temp_argv= mask_password(argc, &argv);
+ temp_argc= argc;
+
if (debug_info_flag)
my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
if (debug_check_flag)
@@ -328,7 +333,7 @@ int main(int argc,char *argv[])
usage();
exit(1);
}
- commands = argv;
+ commands = temp_argv;
if (tty_password)
opt_password = get_tty_password(NullS);
@@ -475,6 +480,13 @@ int main(int argc,char *argv[])
} /* got connection */
mysql_close(&mysql);
+ temp_argc--;
+ while(temp_argc >= 0)
+ {
+ my_free(temp_argv[temp_argc]);
+ temp_argc--;
+ }
+ my_free(temp_argv);
err2:
mysql_library_end();
my_free(opt_password);
@@ -1216,6 +1228,47 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
return 0;
}
+/**
+ @brief Masking the password if it is passed as command line argument.
+
+ @details It works in Linux and changes cmdline in ps and /proc/pid/cmdline,
+ but it won't work for history file of shell.
+ The command line arguments are copied to another array and the
+ password in the argv is masked. This function is called just after
+ "handle_options" because in "handle_options", the agrv pointers
+ are altered which makes freeing of dynamically allocated memory
+ difficult. The password masking is done before all other operations
+ in order to minimise the time frame of password visibility via cmdline.
+
+ @param argc command line options (count)
+ @param argv command line options (values)
+
+ @return temp_argv copy of argv
+*/
+
+static char **mask_password(int argc, char ***argv)
+{
+ char **temp_argv;
+ temp_argv= (char **)(my_malloc(sizeof(char *) * argc, MYF(MY_WME)));
+ argc--;
+ while (argc > 0)
+ {
+ temp_argv[argc]= my_strdup((*argv)[argc], MYF(MY_FAE));
+ if (find_type((*argv)[argc - 1],&command_typelib, FIND_TYPE_BASIC) == ADMIN_PASSWORD ||
+ find_type((*argv)[argc - 1],&command_typelib, FIND_TYPE_BASIC) == ADMIN_OLD_PASSWORD)
+ {
+ char *start= (*argv)[argc];
+ while (*start)
+ *start++= 'x';
+ start= (*argv)[argc];
+ if (*start)
+ start[1]= 0; /* Cut length of argument */
+ }
+ argc--;
+ }
+ temp_argv[argc]= my_strdup((*argv)[argc], MYF(MY_FAE));
+ return(temp_argv);
+}
static void print_version(void)
{
diff --git a/client/mysqldump.c b/client/mysqldump.c
index decde7dabb0..5bb20f2e814 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -5910,19 +5910,36 @@ int main(int argc, char **argv)
dump_all_tablespaces();
dump_all_databases();
}
- else if (argc > 1 && !opt_databases)
- {
- /* Only one database and selected table(s) */
- if (!opt_alltspcs && !opt_notspcs)
- dump_tablespaces_for_tables(*argv, (argv + 1), (argc -1));
- dump_selected_tables(*argv, (argv + 1), (argc - 1));
- }
else
{
- /* One or more databases, all tables */
- if (!opt_alltspcs && !opt_notspcs)
- dump_tablespaces_for_databases(argv);
- dump_databases(argv);
+ // Check all arguments meet length condition. Currently database and table
+ // names are limited to NAME_LEN bytes and stack-based buffers assumes
+ // that escaped name will be not longer than NAME_LEN*2 + 2 bytes long.
+ int argument;
+ for (argument= 0; argument < argc; argument++)
+ {
+ size_t argument_length= strlen(argv[argument]);
+ if (argument_length > NAME_LEN)
+ {
+ die(EX_CONSCHECK, "[ERROR] Argument '%s' is too long, it cannot be "
+ "name for any table or database.\n", argv[argument]);
+ }
+ }
+
+ if (argc > 1 && !opt_databases)
+ {
+ /* Only one database and selected table(s) */
+ if (!opt_alltspcs && !opt_notspcs)
+ dump_tablespaces_for_tables(*argv, (argv + 1), (argc - 1));
+ dump_selected_tables(*argv, (argv + 1), (argc - 1));
+ }
+ else
+ {
+ /* One or more databases, all tables */
+ if (!opt_alltspcs && !opt_notspcs)
+ dump_tablespaces_for_databases(argv);
+ dump_databases(argv);
+ }
}
/* add 'START SLAVE' to end of dump */
diff --git a/cmake/dtrace.cmake b/cmake/dtrace.cmake
index 1fc87cfcbef..5d0bb7ff8c9 100644
--- a/cmake/dtrace.cmake
+++ b/cmake/dtrace.cmake
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -80,13 +80,6 @@ IF(ENABLE_DTRACE)
${CMAKE_BINARY_DIR}/include/probes_mysql_dtrace.h
${CMAKE_BINARY_DIR}/include/probes_mysql_nodtrace.h
)
- IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
- # Systemtap object
- EXECUTE_PROCESS(
- COMMAND ${DTRACE} -G -s ${CMAKE_SOURCE_DIR}/include/probes_mysql.d.base
- -o ${CMAKE_BINARY_DIR}/probes_mysql.o
- )
- ENDIF()
ADD_CUSTOM_TARGET(gen_dtrace_header
DEPENDS
${CMAKE_BINARY_DIR}/include/probes_mysql.d
@@ -105,12 +98,7 @@ FUNCTION(DTRACE_INSTRUMENT target)
IF(ENABLE_DTRACE)
ADD_DEPENDENCIES(${target} gen_dtrace_header)
- IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
- TARGET_LINK_LIBRARIES(${target} ${CMAKE_BINARY_DIR}/probes_mysql.o)
- ENDIF()
-
- # On Solaris, invoke dtrace -G to generate object file and
- # link it together with target.
+ # Invoke dtrace to generate object file and link it together with target.
IF(CMAKE_SYSTEM_NAME MATCHES "SunOS")
SET(objdir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${target}.dir)
SET(outfile ${objdir}/${target}_dtrace.o)
@@ -127,6 +115,21 @@ FUNCTION(DTRACE_INSTRUMENT target)
-P ${CMAKE_SOURCE_DIR}/cmake/dtrace_prelink.cmake
WORKING_DIRECTORY ${objdir}
)
+ ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
+ # dtrace on Linux runs gcc and uses flags from environment
+ SET(CFLAGS_SAVED $ENV{CFLAGS})
+ SET(ENV{CFLAGS} ${CMAKE_C_FLAGS})
+ SET(outfile "${CMAKE_BINARY_DIR}/probes_mysql.o")
+ # Systemtap object
+ EXECUTE_PROCESS(
+ COMMAND ${DTRACE} -G -s ${CMAKE_SOURCE_DIR}/include/probes_mysql.d.base
+ -o ${outfile}
+ )
+ SET(ENV{CFLAGS} ${CFLAGS_SAVED})
+ ENDIF()
+
+ # Do not try to extend the library if we have not built the .o file
+ IF(outfile)
# Add full object path to linker flags
GET_TARGET_PROPERTY(target_type ${target} TYPE)
IF(NOT target_type MATCHES "STATIC")
@@ -138,12 +141,12 @@ FUNCTION(DTRACE_INSTRUMENT target)
# but maybe one day this will be fixed.
GET_TARGET_PROPERTY(target_location ${target} LOCATION)
ADD_CUSTOM_COMMAND(
- TARGET ${target} POST_BUILD
- COMMAND ${CMAKE_AR} r ${target_location} ${outfile}
- COMMAND ${CMAKE_RANLIB} ${target_location}
- )
- # Used in DTRACE_INSTRUMENT_WITH_STATIC_LIBS
- SET(TARGET_OBJECT_DIRECTORY_${target} ${objdir} CACHE INTERNAL "")
+ TARGET ${target} POST_BUILD
+ COMMAND ${CMAKE_AR} r ${target_location} ${outfile}
+ COMMAND ${CMAKE_RANLIB} ${target_location}
+ )
+ # Used in DTRACE_INSTRUMENT_WITH_STATIC_LIBS
+ SET(TARGET_OBJECT_DIRECTORY_${target} ${objdir} CACHE INTERNAL "")
ENDIF()
ENDIF()
ENDIF()
diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake
index ee345b177bd..15e2dc4930b 100644
--- a/cmake/install_macros.cmake
+++ b/cmake/install_macros.cmake
@@ -38,7 +38,9 @@ FUNCTION (INSTALL_DEBUG_SYMBOLS)
STRING(REPLACE ".dll" ".pdb" pdb_location ${pdb_location})
STRING(REPLACE ".lib" ".pdb" pdb_location ${pdb_location})
IF(CMAKE_GENERATOR MATCHES "Visual Studio")
- STRING(REPLACE "${CMAKE_CFG_INTDIR}" "\${CMAKE_INSTALL_CONFIG_NAME}" pdb_location ${pdb_location})
+ STRING(REPLACE
+ "${CMAKE_CFG_INTDIR}" "\${CMAKE_INSTALL_CONFIG_NAME}"
+ pdb_location ${pdb_location})
ENDIF()
set(comp "")
diff --git a/cmake/os/Windows.cmake b/cmake/os/Windows.cmake
index 254d9f6d946..d52e36193ca 100644
--- a/cmake/os/Windows.cmake
+++ b/cmake/os/Windows.cmake
@@ -1,4 +1,4 @@
-# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -62,22 +62,30 @@ IF(MINGW AND CMAKE_SIZEOF_VOID_P EQUAL 4)
ENDIF()
IF(MSVC)
- # Enable debug info also in Release build, and create PDB to be able to analyze
- # crashes
- FOREACH(lang C CXX)
- SET(CMAKE_${lang}_FLAGS_RELEASE "${CMAKE_${lang}_FLAGS_RELEASE} /Zi")
- ENDFOREACH()
+ # Enable debug info also in Release build,
+ # and create PDB to be able to analyze crashes.
FOREACH(type EXE SHARED MODULE)
- SET(CMAKE_{type}_LINKER_FLAGS_RELEASE "${CMAKE_${type}_LINKER_FLAGS_RELEASE} /debug")
+ SET(CMAKE_{type}_LINKER_FLAGS_RELEASE
+ "${CMAKE_${type}_LINKER_FLAGS_RELEASE} /debug")
ENDFOREACH()
# Force static runtime libraries
+ # - Choose debugging information:
+ # /Z7
+ # Produces an .obj file containing full symbolic debugging
+ # information for use with the debugger. The symbolic debugging
+ # information includes the names and types of variables, as well as
+ # functions and line numbers. No .pdb file is produced by the compiler.
+ FOREACH(lang C CXX)
+ SET(CMAKE_${lang}_FLAGS_RELEASE "${CMAKE_${lang}_FLAGS_RELEASE} /Z7")
+ ENDFOREACH()
FOREACH(flag
- CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO
- CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG_INIT
+ CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO
+ CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG_INIT
CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO
- CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG_INIT)
+ CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG_INIT)
STRING(REPLACE "/MD" "/MT" "${flag}" "${${flag}}")
+ STRING(REPLACE "/Zi" "/Z7" "${flag}" "${${flag}}")
ENDFOREACH()
@@ -105,7 +113,6 @@ IF(MSVC)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4800 /wd4805 /wd4996")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4800 /wd4805 /wd4996 /we4099")
-
IF(CMAKE_SIZEOF_VOID_P MATCHES 8)
# _WIN64 is defined by the compiler itself.
# Yet, we define it here again to work around a bug with Intellisense
diff --git a/extra/yassl/CMakeLists.txt b/extra/yassl/CMakeLists.txt
index 08e0f49d8a2..23404a661d6 100644
--- a/extra/yassl/CMakeLists.txt
+++ b/extra/yassl/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -33,7 +33,6 @@ SET(YASSL_SOURCES src/buffer.cpp src/cert_wrapper.cpp src/crypto_wrapper.cpp sr
ADD_CONVENIENCE_LIBRARY(yassl ${YASSL_SOURCES})
RESTRICT_SYMBOL_EXPORTS(yassl)
-INSTALL_DEBUG_SYMBOLS(yassl)
IF(MSVC)
INSTALL_DEBUG_TARGET(yassl DESTINATION ${INSTALL_LIBDIR}/debug)
ENDIF()
diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp
index 9352423de2a..356b310037e 100644
--- a/extra/yassl/src/ssl.cpp
+++ b/extra/yassl/src/ssl.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2012, Oracle and/or its affiliates.
+ Copyright (c) 2005, 2014, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -791,7 +791,10 @@ int SSL_CTX_load_verify_locations(SSL_CTX* ctx, const char* file,
strncpy(name, path, MAX_PATH - 1 - HALF_PATH);
strncat(name, "/", 1);
strncat(name, entry->d_name, HALF_PATH);
- if (stat(name, &buf) < 0) return SSL_BAD_STAT;
+ if (stat(name, &buf) < 0) {
+ closedir(dir);
+ return SSL_BAD_STAT;
+ }
if (S_ISREG(buf.st_mode))
ret = read_file(ctx, name, SSL_FILETYPE_PEM, CA);
diff --git a/extra/yassl/taocrypt/CMakeLists.txt b/extra/yassl/taocrypt/CMakeLists.txt
index 84f1fc186e4..eeed35fd6f4 100644
--- a/extra/yassl/taocrypt/CMakeLists.txt
+++ b/extra/yassl/taocrypt/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -32,7 +32,6 @@ SET(TAOCRYPT_SOURCES src/aes.cpp src/aestables.cpp src/algebra.cpp src/arc4.cpp
ADD_CONVENIENCE_LIBRARY(taocrypt ${TAOCRYPT_SOURCES})
RESTRICT_SYMBOL_EXPORTS(taocrypt)
-INSTALL_DEBUG_SYMBOLS(taocrypt)
IF(MSVC)
INSTALL_DEBUG_TARGET(taocrypt DESTINATION ${INSTALL_LIBDIR}/debug)
ENDIF()
diff --git a/extra/yassl/taocrypt/include/asn.hpp b/extra/yassl/taocrypt/include/asn.hpp
index c58c7579ccf..b826bf54f8d 100644
--- a/extra/yassl/taocrypt/include/asn.hpp
+++ b/extra/yassl/taocrypt/include/asn.hpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -296,11 +296,11 @@ private:
byte* signature_;
char issuer_[ASN_NAME_MAX]; // Names
char subject_[ASN_NAME_MAX]; // Names
- char beforeDate_[MAX_DATE_SZ]; // valid before date
+ char beforeDate_[MAX_DATE_SZ+1]; // valid before date, +null term
byte beforeDateType_; // beforeDate time type
- char afterDate_[MAX_DATE_SZ]; // valid after date
+ char afterDate_[MAX_DATE_SZ+1]; // valid after date, +null term
byte afterDateType_; // afterDate time type
- bool verify_; // Default to yes, but could be off
+ bool verify_; // Default to yes, but could be off
void ReadHeader();
void Decode(SignerList*, CertType);
diff --git a/include/thread_pool_priv.h b/include/thread_pool_priv.h
index 449c8ded66b..4270c32c826 100644
--- a/include/thread_pool_priv.h
+++ b/include/thread_pool_priv.h
@@ -1,6 +1,6 @@
#error don't use
/*
- Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
index 3637c2f7eee..f6b23d047d1 100644
--- a/libmysql/CMakeLists.txt
+++ b/libmysql/CMakeLists.txt
@@ -406,7 +406,6 @@ SET(LIBS clientlib dbug strings vio mysys mysys_ssl ${ZLIB_LIBRARY} ${SSL_LIBRAR
MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
# Visual Studio users need debug static library for debug projects
-INSTALL_DEBUG_SYMBOLS(clientlib)
IF(MSVC)
INSTALL_DEBUG_TARGET(mysqlclient DESTINATION ${INSTALL_LIBDIR}/debug)
INSTALL_DEBUG_TARGET(clientlib DESTINATION ${INSTALL_LIBDIR}/debug)
diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt
index f2842959c3f..c4383b31a17 100644
--- a/man/CMakeLists.txt
+++ b/man/CMakeLists.txt
@@ -14,6 +14,7 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
SET(MAN1_SERVER innochecksum.1 my_print_defaults.1 myisam_ftdump.1 myisamchk.1
+ aria_chk.1 aria_dump_log.1 aria_ftdump.1 aria_pack.1 aria_read_log.1
myisamlog.1 myisampack.1 mysql.server.1
mysql_convert_table_format.1 mysql_fix_extensions.1
mysql_install_db.1
diff --git a/man/aria_pack.1 b/man/aria_pack.1
index 9cec33a3818..ee47f5ff3bb 100644
--- a/man/aria_pack.1
+++ b/man/aria_pack.1
@@ -1,6 +1,6 @@
.TH ARIA_PACK "1" "May 2014" "aria_pack Ver 1.0" "User Commands"
.SH NAME
-aria_pack \- manual page for aria_pack Ver 1.0
+aria_pack \- generate compressed, read\-only Aria tables
.SH SYNOPSIS
.B aria_pack
[\fIOPTIONS\fR] \fIfilename\fR...
diff --git a/man/mysqlbinlog.1 b/man/mysqlbinlog.1
index cc0f62485b5..5e9bc6c2f43 100644
--- a/man/mysqlbinlog.1
+++ b/man/mysqlbinlog.1
@@ -1255,7 +1255,7 @@ indicates a
FORMAT_DESCRIPTION_EVENT\&. The following table lists the possible type codes\&.
.TS
allbox tab(:);
-l l l.
+l l lx.
T{
Type
T}:T{
@@ -1389,6 +1389,7 @@ T}
T{
0f
T}:T{
+.nf
FORMAT_DESCRIPTION_EVENT
T}:T{
This indicates the start of a log file written by MySQL 5 or later\&.
@@ -1526,7 +1527,7 @@ Master Pos: The position of the next event in the original master log file\&.
Flags: 16 flags\&. Currently, the following flags are used\&. The others are reserved for future use\&.
.TS
allbox tab(:);
-l l l.
+l l lx.
T{
Flag
T}:T{
@@ -1537,6 +1538,7 @@ T}
T{
01
T}:T{
+.nf
LOG_EVENT_BINLOG_IN_USE_F
T}:T{
Log file correctly closed\&. (Used only in
@@ -1558,6 +1560,7 @@ T}
T{
04
T}:T{
+.nf
LOG_EVENT_THREAD_SPECIFIC_F
T}:T{
Set if the event is dependent on the connection it was executed in (for
diff --git a/man/mysqldump.1 b/man/mysqldump.1
index 59d2416b25e..fdca51f091a 100644
--- a/man/mysqldump.1
+++ b/man/mysqldump.1
@@ -2027,7 +2027,7 @@ value, an empty string, and the string value
are distinguished from one another in the output generated by this option as follows\&.
.TS
allbox tab(:);
-l l.
+l lx.
T{
\fBValue\fR:
T}:T{
diff --git a/mysql-test/include/have_semisync_plugin.inc b/mysql-test/include/have_semisync_plugin.inc
new file mode 100644
index 00000000000..8a1679de636
--- /dev/null
+++ b/mysql-test/include/have_semisync_plugin.inc
@@ -0,0 +1,15 @@
+#
+# Check if server has support for loading plugins
+#
+if (`SELECT @@have_dynamic_loading != 'YES'`) {
+ --skip Requires dynamic loading
+}
+
+#
+# Check if the variable SEMISYNC_MASTER_SO is set
+#
+if (!$SEMISYNC_MASTER_SO)
+{
+ skip Need semisync plugins;
+}
+
diff --git a/mysql-test/include/install_semisync.inc b/mysql-test/include/install_semisync.inc
index 368b7b7cb4a..9cc6df2072a 100644
--- a/mysql-test/include/install_semisync.inc
+++ b/mysql-test/include/install_semisync.inc
@@ -14,7 +14,7 @@
if ($value == No such row)
{
SET sql_log_bin = 0;
- eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_PLUGIN';
+ install plugin rpl_semi_sync_master soname 'semisync_master';
SET GLOBAL rpl_semi_sync_master_enabled = 1;
SET sql_log_bin = 1;
}
@@ -28,7 +28,7 @@ if ($value == No such row)
if ($value == No such row)
{
SET sql_log_bin = 0;
- eval INSTALL PLUGIN rpl_semi_sync_slave SONAME '$SEMISYNC_SLAVE_PLUGIN';
+ install plugin rpl_semi_sync_slave soname 'semisync_slave';
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
SET sql_log_bin = 1;
}
diff --git a/mysql-test/include/stop_dump_threads.inc b/mysql-test/include/stop_dump_threads.inc
new file mode 100644
index 00000000000..ae33c963d9a
--- /dev/null
+++ b/mysql-test/include/stop_dump_threads.inc
@@ -0,0 +1,32 @@
+# ==== Purpose ====
+#
+# Stop all dump threads on the server of the current connection.
+#
+# ==== Usage ====
+#
+# --source include/stop_dump_threads.inc
+
+--let $include_filename= stop_dump_threads.inc
+--source include/begin_include_file.inc
+
+
+--let $_sdt_show_rpl_debug_info_old= $show_rpl_debug_info
+--let $show_rpl_debug_info= 1
+--disable_query_log
+--disable_result_log
+
+--let $_sdt_dump_thread_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND = 'Binlog dump'`
+
+while ($_sdt_dump_thread_id != '')
+{
+ eval KILL $_sdt_dump_thread_id;
+ --let $wait_condition= SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = $_sdt_dump_thread_id
+ --source include/wait_condition.inc
+
+ --let $_sdt_dump_thread_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND = 'Binlog dump'`
+}
+
+--let $show_rpl_debug_info= $_sdt_show_rpl_debug_info_old
+
+--let $include_filename= stop_dump_threads.inc
+--source include/end_include_file.inc
diff --git a/mysql-test/include/uninstall_semisync.inc b/mysql-test/include/uninstall_semisync.inc
index 11668d1db97..0a4c55fa4f2 100644
--- a/mysql-test/include/uninstall_semisync.inc
+++ b/mysql-test/include/uninstall_semisync.inc
@@ -13,6 +13,11 @@
UNINSTALL PLUGIN rpl_semi_sync_slave;
--connection master
+# After BUG#17638477 fix, uninstallation of rpl_semi_sync_master
+# is not allowed when there are semi sync slaves. Hence kill
+# all dump threads before uninstalling it.
+SET GLOBAL rpl_semi_sync_master_enabled = OFF;
+--source include/stop_dump_threads.inc
UNINSTALL PLUGIN rpl_semi_sync_master;
--enable_warnings
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index 492c9877917..c4236af1697 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -4508,6 +4508,39 @@ COALESCE(c1)
DROP TABLE t1;
#
+# MDEV-5745 analyze MySQL fix for bug#12368495
+#
+SELECT CHAR_LENGTH(TRIM(LEADING 0x000000 FROM _ucs2 0x0061));
+CHAR_LENGTH(TRIM(LEADING 0x000000 FROM _ucs2 0x0061))
+2
+SELECT CHAR_LENGTH(TRIM(LEADING 0x0001 FROM _ucs2 0x0061));
+CHAR_LENGTH(TRIM(LEADING 0x0001 FROM _ucs2 0x0061))
+2
+SELECT CHAR_LENGTH(TRIM(LEADING 0x00 FROM _ucs2 0x0061));
+CHAR_LENGTH(TRIM(LEADING 0x00 FROM _ucs2 0x0061))
+1
+SELECT CHAR_LENGTH(TRIM(TRAILING 0x000000 FROM _ucs2 0x0061));
+CHAR_LENGTH(TRIM(TRAILING 0x000000 FROM _ucs2 0x0061))
+2
+SELECT CHAR_LENGTH(TRIM(TRAILING 0x0001 FROM _ucs2 0x0061));
+CHAR_LENGTH(TRIM(TRAILING 0x0001 FROM _ucs2 0x0061))
+2
+SELECT CHAR_LENGTH(TRIM(TRAILING 0x61 FROM _ucs2 0x0061));
+CHAR_LENGTH(TRIM(TRAILING 0x61 FROM _ucs2 0x0061))
+1
+SELECT CHAR_LENGTH(TRIM(BOTH 0x000000 FROM _ucs2 0x0061));
+CHAR_LENGTH(TRIM(BOTH 0x000000 FROM _ucs2 0x0061))
+2
+SELECT CHAR_LENGTH(TRIM(BOTH 0x0001 FROM _ucs2 0x0061));
+CHAR_LENGTH(TRIM(BOTH 0x0001 FROM _ucs2 0x0061))
+2
+SELECT CHAR_LENGTH(TRIM(BOTH 0x61 FROM _ucs2 0x0061));
+CHAR_LENGTH(TRIM(BOTH 0x61 FROM _ucs2 0x0061))
+1
+SELECT CHAR_LENGTH(TRIM(BOTH 0x00 FROM _ucs2 0x0061));
+CHAR_LENGTH(TRIM(BOTH 0x00 FROM _ucs2 0x0061))
+1
+#
# End of 5.5 tests
#
#
diff --git a/mysql-test/r/ctype_utf32.result b/mysql-test/r/ctype_utf32.result
index 214ec9f9b1d..01edaac88d7 100644
--- a/mysql-test/r/ctype_utf32.result
+++ b/mysql-test/r/ctype_utf32.result
@@ -1626,6 +1626,39 @@ SELECT '2010-10-10 10:10:10' + INTERVAL GeometryType(GeomFromText('POINT(1 1)'))
'2010-10-10 10:10:10' + INTERVAL GeometryType(GeomFromText('POINT(1 1)')) hour_second
2010-10-10 10:10:10
#
+# MDEV-5745 analyze MySQL fix for bug#12368495
+#
+SELECT CHAR_LENGTH(TRIM(LEADING 0x0000000000 FROM _utf32 0x00000061));
+CHAR_LENGTH(TRIM(LEADING 0x0000000000 FROM _utf32 0x00000061))
+4
+SELECT CHAR_LENGTH(TRIM(LEADING 0x0001 FROM _utf32 0x00000061));
+CHAR_LENGTH(TRIM(LEADING 0x0001 FROM _utf32 0x00000061))
+4
+SELECT CHAR_LENGTH(TRIM(LEADING 0x00 FROM _utf32 0x00000061));
+CHAR_LENGTH(TRIM(LEADING 0x00 FROM _utf32 0x00000061))
+1
+SELECT CHAR_LENGTH(TRIM(TRAILING 0x0000000000 FROM _utf32 0x00000061));
+CHAR_LENGTH(TRIM(TRAILING 0x0000000000 FROM _utf32 0x00000061))
+4
+SELECT CHAR_LENGTH(TRIM(TRAILING 0x0001 FROM _utf32 0x00000061));
+CHAR_LENGTH(TRIM(TRAILING 0x0001 FROM _utf32 0x00000061))
+4
+SELECT CHAR_LENGTH(TRIM(TRAILING 0x61 FROM _utf32 0x00000061));
+CHAR_LENGTH(TRIM(TRAILING 0x61 FROM _utf32 0x00000061))
+3
+SELECT CHAR_LENGTH(TRIM(BOTH 0x0000000000 FROM _utf32 0x00000061));
+CHAR_LENGTH(TRIM(BOTH 0x0000000000 FROM _utf32 0x00000061))
+4
+SELECT CHAR_LENGTH(TRIM(BOTH 0x0001 FROM _utf32 0x00000061));
+CHAR_LENGTH(TRIM(BOTH 0x0001 FROM _utf32 0x00000061))
+4
+SELECT CHAR_LENGTH(TRIM(BOTH 0x61 FROM _utf32 0x00000061));
+CHAR_LENGTH(TRIM(BOTH 0x61 FROM _utf32 0x00000061))
+3
+SELECT CHAR_LENGTH(TRIM(BOTH 0x00 FROM _utf32 0x00000061));
+CHAR_LENGTH(TRIM(BOTH 0x00 FROM _utf32 0x00000061))
+1
+#
# End of 5.5 tests
#
#
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index e5edabb0130..44a67fe6b27 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -2961,6 +2961,9 @@ replace(var, '00000000', table_name)
(( t2 ++ t2 ))
drop procedure foo;
drop table t1,t2;
+select md5(_filename "a"), sha(_filename "a");
+md5(_filename "a") sha(_filename "a")
+0cc175b9c0f1b6a831c399e269772661 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8
#
# End of 5.5 tests
#
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index db68f08cbba..bf07595bc3a 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -2023,10 +2023,72 @@ SEC_TO_TIME(1.12)+0.1 decimal(14,2) YES NULL
SEC_TO_TIME(1.123456)+0.1 decimal(18,6) YES NULL
SEC_TO_TIME(1.1234567)+0.1 decimal(18,6) YES NULL
DROP TABLE t1;
+CREATE TABLE t1 (a DATE) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('2005-05-04'),('2000-02-23');
+SELECT * FROM t1 GROUP BY FROM_UNIXTIME(concat(a,'10'))*1;
+a
+2000-02-23
+2005-05-04
+SELECT * FROM t1 GROUP BY (-FROM_UNIXTIME(concat(a,'10')))*1;
+a
+2005-05-04
+2000-02-23
+SELECT * FROM t1 GROUP BY (-FROM_UNIXTIME(concat(a,'10')));
+a
+2005-05-04
+2000-02-23
+SELECT * FROM t1 GROUP BY ABS(FROM_UNIXTIME(concat(a,'10')));
+a
+2000-02-23
+2005-05-04
+SELECT * FROM t1 GROUP BY @a:=(FROM_UNIXTIME(concat(a,'10'))*1);
+a
+2000-02-23
+2005-05-04
+DROP TABLE t1;
+SET TIME_ZONE='+02:00';
+#
+# MDEV-6302 Wrong result set when using GROUP BY FROM_UNIXTIME(...)+0
+#
+CREATE TABLE t1 (a DATE);
+INSERT INTO t1 VALUES ('2005-05-04'),('2000-02-23');
+SELECT a, FROM_UNIXTIME(CONCAT(a,'10')) AS f1, FROM_UNIXTIME(CONCAT(a,'10'))+0 AS f2 FROM t1;
+a f1 f2
+2005-05-04 1970-01-01 02:33:25 19700101023325.000000
+2000-02-23 1970-01-01 02:33:20 19700101023320.000000
+SELECT * FROM t1 GROUP BY FROM_UNIXTIME(CONCAT(a,'10'))+0;
+a
+2000-02-23
+2005-05-04
+DROP TABLE t1;
+CREATE TABLE t1 (a DATE) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('2005-05-04'),('2000-02-23');
+SELECT * FROM t1 GROUP BY FROM_UNIXTIME(concat(a,'10'))/1;
+a
+2000-02-23
+2005-05-04
+DROP TABLE t1;
+CREATE TABLE t1 (a DATE);
+INSERT INTO t1 VALUES ('2005-05-04');
+SELECT CONCAT(FROM_UNIXTIME(CONCAT(a,'10')) MOD FROM_UNIXTIME(CONCAT(a,'10'))) AS f2 FROM t1;
+f2
+0.000000
+SELECT CHAR_LENGTH(CONCAT(FROM_UNIXTIME(CONCAT(a,'10')) MOD FROM_UNIXTIME(CONCAT(a,'10')))) AS f2 FROM t1;
+f2
+8
+CREATE TABLE t2 AS SELECT CONCAT(FROM_UNIXTIME(CONCAT(a,'10')) MOD FROM_UNIXTIME(CONCAT(a,'10'))) AS f2 FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `f2` varchar(26) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t2;
+f2
+0.000000
+DROP TABLE t1,t2;
#
# MDEV-4635 Crash in UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y'))
#
-SET TIME_ZONE='+02:00';
SELECT UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y'));
UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y'))
NULL
@@ -2600,3 +2662,18 @@ SELECT COALESCE(TIME'10:20:30',DATE'2001-01-01');
COALESCE(TIME'10:20:30',DATE'2001-01-01')
2014-04-15 10:20:30
SET timestamp=DEFAULT;
+#
+# MDEV-5750 Assertion `ltime->year == 0' fails on a query with EXTRACT DAY_MINUTE and TIME column
+#
+CREATE TABLE t1 ( d DATE, t TIME );
+INSERT INTO t1 VALUES ('2008-12-05','22:34:09'),('2005-03-27','14:26:02');
+SELECT EXTRACT(DAY_MINUTE FROM GREATEST(t,d)), GREATEST(t,d) FROM t1;
+EXTRACT(DAY_MINUTE FROM GREATEST(t,d)) GREATEST(t,d)
+342259 838:59:59
+342259 838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '9336:00:00'
+Warning 1292 Truncated incorrect time value: '9336:00:00'
+Warning 1292 Truncated incorrect time value: '2952:00:00'
+Warning 1292 Truncated incorrect time value: '2952:00:00'
+DROP TABLE t1;
diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
index 81cdad8c523..06a8a8a06b8 100644
--- a/mysql-test/r/group_min_max.result
+++ b/mysql-test/r/group_min_max.result
@@ -3536,7 +3536,7 @@ COUNT(DISTINCT a, b) SUM(DISTINCT a)
0 NULL
EXPLAIN SELECT SUM(DISTINCT a), MAX(b) FROM t2 GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range NULL a 5 NULL 9 Using index for group-by
+1 SIMPLE t2 index NULL a 15 NULL 16 Using index
SELECT SUM(DISTINCT a), MAX(b) FROM t2 GROUP BY a;
SUM(DISTINCT a) MAX(b)
1 8
@@ -3564,7 +3564,7 @@ SELECT 42 * (a + c + COUNT(DISTINCT c, a, b)) FROM t2 GROUP BY a, b, c;
168
EXPLAIN SELECT (SUM(DISTINCT a) + MAX(b)) FROM t2 GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range NULL a 5 NULL 9 Using index for group-by
+1 SIMPLE t2 index NULL a 15 NULL 16 Using index
SELECT (SUM(DISTINCT a) + MAX(b)) FROM t2 GROUP BY a;
(SUM(DISTINCT a) + MAX(b))
9
@@ -3593,6 +3593,58 @@ id select_type table type possible_keys key key_len ref rows Extra
drop table t1;
# End of test#50539.
#
+# Bug#17217128 - BAD INTERACTION BETWEEN MIN/MAX AND
+# "HAVING SUM(DISTINCT)": WRONG RESULTS.
+#
+CREATE TABLE t (a INT, b INT, KEY(a,b));
+INSERT INTO t VALUES (1,1), (2,2), (3,3), (4,4), (1,0), (3,2), (4,5);
+ANALYZE TABLE t;
+Table Op Msg_type Msg_text
+test.t analyze status OK
+SELECT a, SUM(DISTINCT a), MIN(b) FROM t GROUP BY a;
+a SUM(DISTINCT a) MIN(b)
+1 1 0
+2 2 2
+3 3 2
+4 4 4
+EXPLAIN SELECT a, SUM(DISTINCT a), MIN(b) FROM t GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t index NULL a 10 NULL 7 Using index
+SELECT a, SUM(DISTINCT a), MAX(b) FROM t GROUP BY a;
+a SUM(DISTINCT a) MAX(b)
+1 1 1
+2 2 2
+3 3 3
+4 4 5
+EXPLAIN SELECT a, SUM(DISTINCT a), MAX(b) FROM t GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t index NULL a 10 NULL 7 Using index
+SELECT a, MAX(b) FROM t GROUP BY a HAVING SUM(DISTINCT a);
+a MAX(b)
+1 1
+2 2
+3 3
+4 5
+EXPLAIN SELECT a, MAX(b) FROM t GROUP BY a HAVING SUM(DISTINCT a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t index NULL a 10 NULL 7 Using index
+SELECT SUM(DISTINCT a), MIN(b), MAX(b) FROM t;
+SUM(DISTINCT a) MIN(b) MAX(b)
+10 0 5
+EXPLAIN SELECT SUM(DISTINCT a), MIN(b), MAX(b) FROM t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t index NULL a 10 NULL 7 Using index
+SELECT a, SUM(DISTINCT a), MIN(b), MAX(b) FROM t GROUP BY a;
+a SUM(DISTINCT a) MIN(b) MAX(b)
+1 1 0 1
+2 2 2 2
+3 3 2 3
+4 4 4 5
+EXPLAIN SELECT a, SUM(DISTINCT a), MIN(b), MAX(b) FROM t GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t index NULL a 10 NULL 7 Using index
+DROP TABLE t;
+#
# MDEV-4219 A simple select query returns random data (upstream bug#68473)
#
drop table if exists faulty;
diff --git a/mysql-test/r/group_min_max_innodb.result b/mysql-test/r/group_min_max_innodb.result
index 320c4b2b750..f3511b0ad4a 100644
--- a/mysql-test/r/group_min_max_innodb.result
+++ b/mysql-test/r/group_min_max_innodb.result
@@ -118,3 +118,171 @@ COUNT(DISTINCT a)
1
DROP TABLE t1;
End of 5.5 tests
+#
+# Bug#17909656 - WRONG RESULTS FOR A SIMPLE QUERY WITH GROUP BY
+#
+CREATE TABLE t0 (
+i1 INTEGER NOT NULL
+);
+INSERT INTO t0 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),
+(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),
+(21),(22),(23),(24),(25),(26),(27),(28),(29),(30);
+CREATE TABLE t1 (
+c1 CHAR(1) NOT NULL,
+i1 INTEGER NOT NULL,
+i2 INTEGER NOT NULL,
+UNIQUE KEY k1 (c1,i2)
+) ENGINE=InnoDB;
+INSERT INTO t1 SELECT 'A',i1,i1 FROM t0;
+INSERT INTO t1 SELECT 'B',i1,i1 FROM t0;
+INSERT INTO t1 SELECT 'C',i1,i1 FROM t0;
+INSERT INTO t1 SELECT 'D',i1,i1 FROM t0;
+INSERT INTO t1 SELECT 'E',i1,i1 FROM t0;
+INSERT INTO t1 SELECT 'F',i1,i1 FROM t0;
+CREATE TABLE t2 (
+c1 CHAR(1) NOT NULL,
+i1 INTEGER NOT NULL,
+i2 INTEGER NOT NULL,
+UNIQUE KEY k2 (c1,i1,i2)
+) ENGINE=InnoDB;
+INSERT INTO t2 SELECT 'A',i1,i1 FROM t0;
+INSERT INTO t2 SELECT 'B',i1,i1 FROM t0;
+INSERT INTO t2 SELECT 'C',i1,i1 FROM t0;
+INSERT INTO t2 SELECT 'D',i1,i1 FROM t0;
+INSERT INTO t2 SELECT 'E',i1,i1 FROM t0;
+INSERT INTO t2 SELECT 'F',i1,i1 FROM t0;
+ANALYZE TABLE t1;
+ANALYZE TABLE t2;
+EXPLAIN SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' AND i2 = 17) OR ( c1 = 'F')
+GROUP BY c1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range k1 k1 5 NULL 31 Using where; Using index
+SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' AND i2 = 17) OR ( c1 = 'F')
+GROUP BY c1;
+c1 max(i2)
+C 17
+F 30
+EXPLAIN SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' OR ( c1 = 'F' AND i2 = 17))
+GROUP BY c1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range k1 k1 5 NULL 31 Using where; Using index
+SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' OR ( c1 = 'F' AND i2 = 17))
+GROUP BY c1;
+c1 max(i2)
+C 30
+F 17
+EXPLAIN SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' OR c1 = 'F' ) AND ( i2 = 17 )
+GROUP BY c1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range k1 k1 5 NULL 2 Using where; Using index
+SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' OR c1 = 'F' ) AND ( i2 = 17 )
+GROUP BY c1;
+c1 max(i2)
+C 17
+F 17
+EXPLAIN SELECT c1, max(i2) FROM t1
+WHERE ((c1 = 'C' AND (i2 = 40 OR i2 = 30)) OR ( c1 = 'F' AND (i2 = 40 )))
+GROUP BY c1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range k1 k1 5 NULL 3 Using where; Using index
+SELECT c1, max(i2) FROM t1
+WHERE ((c1 = 'C' AND (i2 = 40 OR i2 = 30)) OR ( c1 = 'F' AND (i2 = 40 )))
+GROUP BY c1;
+c1 max(i2)
+C 30
+EXPLAIN SELECT c1, i1, max(i2) FROM t2
+WHERE (c1 = 'C' OR ( c1 = 'F' AND i1 < 35)) AND ( i2 = 17 )
+GROUP BY c1,i1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range k2 k2 5 NULL 59 Using where; Using index
+SELECT c1, i1, max(i2) FROM t2
+WHERE (c1 = 'C' OR ( c1 = 'F' AND i1 < 35)) AND ( i2 = 17 )
+GROUP BY c1,i1;
+c1 i1 max(i2)
+C 17 17
+F 17 17
+EXPLAIN SELECT c1, i1, max(i2) FROM t2
+WHERE (((c1 = 'C' AND i1 < 40) OR ( c1 = 'F' AND i1 < 35)) AND ( i2 = 17 ))
+GROUP BY c1,i1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range k2 k2 5 NULL 58 Using where; Using index
+SELECT c1, i1, max(i2) FROM t2
+WHERE (((c1 = 'C' AND i1 < 40) OR ( c1 = 'F' AND i1 < 35)) AND ( i2 = 17 ))
+GROUP BY c1,i1;
+c1 i1 max(i2)
+C 17 17
+F 17 17
+EXPLAIN SELECT c1, i1, max(i2) FROM t2
+WHERE ((c1 = 'C' AND i1 < 40) OR ( c1 = 'F' AND i1 < 35) OR ( i2 = 17 ))
+GROUP BY c1,i1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index k2 k2 9 NULL 180 Using where; Using index
+SELECT c1, i1, max(i2) FROM t2
+WHERE ((c1 = 'C' AND i1 < 40) OR ( c1 = 'F' AND i1 < 35) OR ( i2 = 17 ))
+GROUP BY c1,i1;
+c1 i1 max(i2)
+A 17 17
+B 17 17
+C 1 1
+C 2 2
+C 3 3
+C 4 4
+C 5 5
+C 6 6
+C 7 7
+C 8 8
+C 9 9
+C 10 10
+C 11 11
+C 12 12
+C 13 13
+C 14 14
+C 15 15
+C 16 16
+C 17 17
+C 18 18
+C 19 19
+C 20 20
+C 21 21
+C 22 22
+C 23 23
+C 24 24
+C 25 25
+C 26 26
+C 27 27
+C 28 28
+C 29 29
+C 30 30
+D 17 17
+E 17 17
+F 1 1
+F 2 2
+F 3 3
+F 4 4
+F 5 5
+F 6 6
+F 7 7
+F 8 8
+F 9 9
+F 10 10
+F 11 11
+F 12 12
+F 13 13
+F 14 14
+F 15 15
+F 16 16
+F 17 17
+F 18 18
+F 19 19
+F 20 20
+F 21 21
+F 22 22
+F 23 23
+F 24 24
+F 25 25
+F 26 26
+F 27 27
+F 28 28
+F 29 29
+F 30 30
+DROP TABLE t0,t1,t2;
diff --git a/mysql-test/r/innodb_load_xa.result b/mysql-test/r/innodb_load_xa.result
new file mode 100644
index 00000000000..85e6d52c098
--- /dev/null
+++ b/mysql-test/r/innodb_load_xa.result
@@ -0,0 +1,21 @@
+install plugin innodb soname 'ha_innodb';
+Warnings:
+Warning 1105 Cannot enable tc-log at run-time. XA features of InnoDB are disabled
+select engine,support,transactions,xa from information_schema.engines where engine='innodb';
+engine support transactions xa
+InnoDB YES YES NO
+create table t1 (a int) engine=innodb;
+start transaction;
+insert t1 values (1);
+insert t1 values (2);
+commit;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+mysqld-bin.000001 # Gtid # # GTID #-#-#
+mysqld-bin.000001 # Query # # use `test`; create table t1 (a int) engine=innodb
+mysqld-bin.000001 # Gtid # # BEGIN GTID #-#-#
+mysqld-bin.000001 # Query # # use `test`; insert t1 values (1)
+mysqld-bin.000001 # Query # # use `test`; insert t1 values (2)
+mysqld-bin.000001 # Query # # COMMIT
+drop table t1;
+uninstall plugin innodb;
diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result
index d39e50a991c..360421514ac 100644
--- a/mysql-test/r/mysqld--help.result
+++ b/mysql-test/r/mysqld--help.result
@@ -1014,8 +1014,8 @@ The following options may be given as the first argument:
created to handle remaining clients.
--thread-stack=# The stack size for each thread
--time-format=name The TIME format (ignored)
- --timed-mutexes Specify whether to time mutexes (only InnoDB mutexes are
- currently supported)
+ --timed-mutexes Specify whether to time mutexes. Deprecated, has no
+ effect.
--tmp-table-size=# If an internal in-memory temporary table exceeds this
size, MySQL will automatically convert it to an on-disk
MyISAM or Aria table
diff --git a/mysql-test/r/order_by_innodb.result b/mysql-test/r/order_by_innodb.result
new file mode 100644
index 00000000000..3c6c4053741
--- /dev/null
+++ b/mysql-test/r/order_by_innodb.result
@@ -0,0 +1,13 @@
+drop table if exists t0,t1,t2,t3;
+#
+# MDEV-6434: Wrong result (extra rows) with ORDER BY, multiple-column index, InnoDB
+#
+CREATE TABLE t1 (a INT, b INT, c INT, d TEXT, KEY idx(a,b,c)) ENGINE=InnoDB;
+INSERT INTO t1 (a,c) VALUES
+(8, 9),(8, 10),(13, 15),(16, 17),(16, 18),(16, 19),(20, 21),
+(20, 22),(20, 24),(20, 25),(20, 26),(20, 27),(20, 28);
+SELECT * FROM t1 WHERE a = 8 AND (b = 1 OR b IS NULL) ORDER BY c;
+a b c d
+8 NULL 9 NULL
+8 NULL 10 NULL
+DROP TABLE t1;
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index b8011656415..233494238a5 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -2562,6 +2562,50 @@ id id2 dob address city hours_worked_per_week weeks_worked_last_year
16 16 1949-11-07 address16 city16 40 52
50 50 1923-09-08 address50 city50 40 52
drop table t1;
+#
+# MDEV-6322: The PARTITION engine can return wrong query results
+#
+CREATE TABLE t1 (
+CustomerID varchar(5) DEFAULT NULL,
+CompanyName varchar(40) DEFAULT NULL,
+ContactName varchar(30) DEFAULT NULL,
+ContactTitle varchar(30) DEFAULT NULL,
+Address varchar(60) DEFAULT NULL,
+City varchar(15) DEFAULT NULL,
+Region varchar(15) DEFAULT NULL,
+PostalCode varchar(10) DEFAULT NULL,
+Country varchar(15) NOT NULL,
+Phone varchar(24) DEFAULT NULL,
+Fax varchar(24) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+PARTITION BY LIST COLUMNS(Country)
+(PARTITION p1 VALUES IN ('Germany','Austria','Switzerland','Poland'),
+PARTITION p2 VALUES IN ('USA','Canada','Mexico'),
+PARTITION p3 VALUES IN ('Spain','Portugal','Italy'),
+PARTITION p4 VALUES IN ('UK','Ireland'),
+PARTITION p5 VALUES IN ('France','Belgium'),
+PARTITION p6 VALUES IN ('Sweden','Finland','Denmark','Norway'),
+PARTITION p7 VALUES IN ('Venezuela','Argentina','Brazil')
+);
+INSERT INTO t1 (CustomerID, City, Country) VALUES
+('ANATR','México D.F','Mexico'),
+('ANTON','México D.F','Mexico'),
+('BOTTM','Tsawassen','Canada'),
+('CENTC','México D.F','Mexico'),
+('GREAL','Eugene','USA'),
+('HUNGC','Elgin','USA'),
+('LAUGB','Vancouver','Canada'),
+('LAZYK','Walla Walla','USA'),
+('LETSS','San Francisco','USA'),
+('LONEP','Portland','USA');
+SELECT * FROM t1 WHERE Country = 'USA';
+CustomerID CompanyName ContactName ContactTitle Address City Region PostalCode Country Phone Fax
+GREAL NULL NULL NULL NULL Eugene NULL NULL USA NULL NULL
+HUNGC NULL NULL NULL NULL Elgin NULL NULL USA NULL NULL
+LAZYK NULL NULL NULL NULL Walla Walla NULL NULL USA NULL NULL
+LETSS NULL NULL NULL NULL San Francisco NULL NULL USA NULL NULL
+LONEP NULL NULL NULL NULL Portland NULL NULL USA NULL NULL
+DROP TABLE t1;
CREATE TABLE t1 ( d DATE NOT NULL)
PARTITION BY RANGE( YEAR(d) ) (
PARTITION p0 VALUES LESS THAN (1960),
diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result
index 82ccbe9c6a8..92c9c01db2d 100644
--- a/mysql-test/r/partition_innodb.result
+++ b/mysql-test/r/partition_innodb.result
@@ -694,6 +694,34 @@ count(*)
drop table t3;
drop table t1,t2;
#
+# MySQL Bug#71095: Wrong results with PARTITION BY LIST COLUMNS()
+#
+create table t1(c1 int, c2 int, c3 int, c4 int,
+primary key(c1,c2)) engine=InnoDB
+partition by list columns(c2)
+(partition p1 values in (1,2) engine=InnoDB,
+partition p2 values in (3,4) engine=InnoDB);
+insert into t1 values (1,1,1,1),(2,3,1,1);
+select * from t1 where c1=2 and c2=3;
+c1 c2 c3 c4
+2 3 1 1
+drop table t1;
+#
+# MySQL Bug#72803: Wrong "Impossible where" with LIST partitioning
+# also MDEV-6240: Wrong "Impossible where" with LIST partitioning
+#
+CREATE TABLE t1 ( d DATE) ENGINE = InnoDB
+PARTITION BY LIST COLUMNS (d)
+(
+PARTITION p0 VALUES IN ('1990-01-01','1991-01-01'),
+PARTITION p1 VALUES IN ('1981-01-01')
+);
+INSERT INTO t1 (d) VALUES ('1991-01-01');
+SELECT * FROM t1 WHERE d = '1991-01-01';
+d
+1991-01-01
+DROP TABLE t1;
+#
# MDEV-5963: InnoDB: Assertion failure in file row0sel.cc line 2503,
# Failing assertion: 0 with "key ptr now exceeds key end by 762 bytes"
# (independent testcase for Oracle Bug#13947868)
diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result
index 0a4cf9932c0..e52c2c7d886 100644
--- a/mysql-test/r/partition_pruning.result
+++ b/mysql-test/r/partition_pruning.result
@@ -3302,6 +3302,120 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p0,p1,p2 ALL NULL NULL NULL NULL 100 Using where
drop table t0, t1;
#
+# Bug#71095: Wrong results with PARTITION BY LIST COLUMNS()
+#
+CREATE TABLE t1
+(c1 int,
+c2 int,
+c3 int,
+c4 int,
+PRIMARY KEY (c1,c2))
+PARTITION BY LIST COLUMNS (c2)
+(PARTITION p1 VALUES IN (1,2),
+PARTITION p2 VALUES IN (3,4));
+INSERT INTO t1 VALUES (1, 1, 1, 1), (2, 3, 1, 1);
+INSERT INTO t1 VALUES (1, 2, 1, 1), (2, 4, 1, 1);
+SELECT * FROM t1 WHERE c1 = 1 AND c2 < 1;
+c1 c2 c3 c4
+SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 1;
+c1 c2 c3 c4
+1 1 1 1
+SELECT * FROM t1 WHERE c1 = 1 AND c2 = 1;
+c1 c2 c3 c4
+1 1 1 1
+SELECT * FROM t1 WHERE c1 = 1 AND c2 >= 1;
+c1 c2 c3 c4
+1 1 1 1
+1 2 1 1
+SELECT * FROM t1 WHERE c1 = 1 AND c2 > 1;
+c1 c2 c3 c4
+1 2 1 1
+SELECT * FROM t1 WHERE c1 = 1 AND c2 < 3;
+c1 c2 c3 c4
+1 1 1 1
+1 2 1 1
+SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 3;
+c1 c2 c3 c4
+1 1 1 1
+1 2 1 1
+SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 3;
+c1 c2 c3 c4
+2 3 1 1
+SELECT * FROM t1 WHERE c1 = 2 AND c2 = 3;
+c1 c2 c3 c4
+2 3 1 1
+SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 3;
+c1 c2 c3 c4
+2 3 1 1
+2 4 1 1
+SELECT * FROM t1 WHERE c1 = 2 AND c2 > 3;
+c1 c2 c3 c4
+2 4 1 1
+SELECT * FROM t1 WHERE c1 = 2 AND c2 < 4;
+c1 c2 c3 c4
+2 3 1 1
+SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 4;
+c1 c2 c3 c4
+2 3 1 1
+2 4 1 1
+SELECT * FROM t1 WHERE c1 = 2 AND c2 = 4;
+c1 c2 c3 c4
+2 4 1 1
+SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 4;
+c1 c2 c3 c4
+2 4 1 1
+SELECT * FROM t1 WHERE c1 = 2 AND c2 > 4;
+c1 c2 c3 c4
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 < 1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1 range PRIMARY PRIMARY 8 NULL 1 Using where
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 = 1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1 const PRIMARY PRIMARY 8 const,const 1
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 >= 1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 > 1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 < 3;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1 range PRIMARY PRIMARY 8 NULL 1 Using where
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 3;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 3;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 = 3;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p2 const PRIMARY PRIMARY 8 const,const 1
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 3;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p2 range PRIMARY PRIMARY 8 NULL 1 Using where
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 > 3;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p2 range PRIMARY PRIMARY 8 NULL 1 Using where
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 < 4;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 4;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 = 4;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p2 const PRIMARY PRIMARY 8 const,const 1
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 4;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 p2 range PRIMARY PRIMARY 8 NULL 1 Using where
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 > 4;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+DROP TABLE t1;
+#
# MDEV-6239: Partition pruning is not working as expected in an inner query
#
create table t1
diff --git a/mysql-test/r/plugin_loaderr.result b/mysql-test/r/plugin_loaderr.result
index 95e5ec794d2..d1189217355 100644
--- a/mysql-test/r/plugin_loaderr.result
+++ b/mysql-test/r/plugin_loaderr.result
@@ -8,3 +8,6 @@ PLUGIN_TYPE STORAGE ENGINE
PLUGIN_LIBRARY NULL
PLUGIN_LIBRARY_VERSION NULL
LOAD_OPTION ON
+#
+# MDEV-6351 --plugin=force has no effect for built-in plugins
+#
diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result
index 6cc627ad16c..4103a3424e9 100644
--- a/mysql-test/r/subselect_mat.result
+++ b/mysql-test/r/subselect_mat.result
@@ -2108,6 +2108,43 @@ EXECUTE stmt;
a
DROP TABLE t1, t2;
DROP VIEW v2;
+#
+# MDEV-6289 : Unexpected results when querying information_schema
+#
+CREATE TABLE t1 (
+id int(11) unsigned NOT NULL AUTO_INCREMENT,
+db varchar(254) NOT NULL DEFAULT '',
+PRIMARY KEY (id),
+UNIQUE KEY db (db)
+) DEFAULT CHARSET=utf8;
+INSERT INTO t1 (db) VALUES ('mysqltest1'),('mysqltest2'),('mysqltest3'),('mysqltest4');
+drop database if exists mysqltest1;
+drop database if exists mysqltest2;
+drop database if exists mysqltest3;
+drop database if exists mysqltest4;
+create database mysqltest1;
+create database mysqltest2;
+create database mysqltest3;
+create database mysqltest4;
+SELECT db FROM t1 WHERE db IN (SELECT SCHEMA_NAME FROM information_schema.schemata) ORDER BY db DESC;
+db
+mysqltest4
+mysqltest3
+mysqltest2
+mysqltest1
+EXPLAIN EXTENDED
+SELECT db FROM t1 WHERE db IN (SELECT SCHEMA_NAME FROM information_schema.schemata) ORDER BY db DESC;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 PRIMARY t1 eq_ref db db 764 information_schema.schemata.SCHEMA_NAME 1 100.00 Using where; Using index
+2 MATERIALIZED schemata ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select `test`.`t1`.`db` AS `db` from `test`.`t1` semi join (`information_schema`.`schemata`) where (`test`.`t1`.`db` = `information_schema`.`schemata`.`SCHEMA_NAME`) order by `test`.`t1`.`db` desc
+drop table t1;
+drop database mysqltest1;
+drop database mysqltest2;
+drop database mysqltest3;
+drop database mysqltest4;
# End of 5.5 tests
set @subselect_mat_test_optimizer_switch_value=null;
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result
index 95dfc34777b..c6a0344c8a3 100644
--- a/mysql-test/r/subselect_sj_mat.result
+++ b/mysql-test/r/subselect_sj_mat.result
@@ -2148,4 +2148,41 @@ EXECUTE stmt;
a
DROP TABLE t1, t2;
DROP VIEW v2;
+#
+# MDEV-6289 : Unexpected results when querying information_schema
+#
+CREATE TABLE t1 (
+id int(11) unsigned NOT NULL AUTO_INCREMENT,
+db varchar(254) NOT NULL DEFAULT '',
+PRIMARY KEY (id),
+UNIQUE KEY db (db)
+) DEFAULT CHARSET=utf8;
+INSERT INTO t1 (db) VALUES ('mysqltest1'),('mysqltest2'),('mysqltest3'),('mysqltest4');
+drop database if exists mysqltest1;
+drop database if exists mysqltest2;
+drop database if exists mysqltest3;
+drop database if exists mysqltest4;
+create database mysqltest1;
+create database mysqltest2;
+create database mysqltest3;
+create database mysqltest4;
+SELECT db FROM t1 WHERE db IN (SELECT SCHEMA_NAME FROM information_schema.schemata) ORDER BY db DESC;
+db
+mysqltest4
+mysqltest3
+mysqltest2
+mysqltest1
+EXPLAIN EXTENDED
+SELECT db FROM t1 WHERE db IN (SELECT SCHEMA_NAME FROM information_schema.schemata) ORDER BY db DESC;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 PRIMARY t1 eq_ref db db 764 information_schema.schemata.SCHEMA_NAME 1 100.00 Using where; Using index
+2 MATERIALIZED schemata ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select `test`.`t1`.`db` AS `db` from `test`.`t1` semi join (`information_schema`.`schemata`) where (`test`.`t1`.`db` = `information_schema`.`schemata`.`SCHEMA_NAME`) order by `test`.`t1`.`db` desc
+drop table t1;
+drop database mysqltest1;
+drop database mysqltest2;
+drop database mysqltest3;
+drop database mysqltest4;
# End of 5.5 tests
diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result
index fa36e9b5567..f8649f030bb 100644
--- a/mysql-test/r/type_decimal.result
+++ b/mysql-test/r/type_decimal.result
@@ -810,10 +810,10 @@ c1
drop table t1;
SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS '%';
%
-0.012345687012345687012345687012345687012345687012345687012345687012345687000000000
+0.012345687012345687012345687012
SELECT MOD(1, .123456789123456789123456789123456789123456789123456789123456789123456789123456789) AS 'MOD()';
MOD()
-0.012345687012345687012345687012345687012345687012345687012345687012345687000000000
+0.012345687012345687012345687012
create table t1 (f1 decimal(6,6),f2 decimal(6,6) zerofill);
insert into t1 values (-0.123456,0.123456);
select group_concat(f1),group_concat(f2) from t1;
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index 5b3594fe503..fb10e65c0ce 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -703,7 +703,7 @@ select .7777777777777777777777777777777777777 *
777777777777777777.777777777777777777700000000000
select .7777777777777777777777777777777777777 - 0.1;
.7777777777777777777777777777777777777 - 0.1
-0.6777777777777777777777777777777777777
+0.677777777777777777777777777778
select .343434343434343434 + .343434343434343434;
.343434343434343434 + .343434343434343434
0.686868686868686868
@@ -1840,7 +1840,7 @@ Warnings:
Note 1265 Data truncated for column 'c1' at row 4
DESC t2;
Field Type Null Key Default Extra
-c1 decimal(32,30) YES NULL
+c1 decimal(33,30) YES NULL
DROP TABLE t1,t2;
CREATE TABLE t1 (a DECIMAL(30,30));
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
@@ -1851,7 +1851,7 @@ Note 1265 Data truncated for column 'c1' at row 2
Note 1265 Data truncated for column 'c1' at row 3
DESC t2;
Field Type Null Key Default Extra
-c1 decimal(34,0) YES NULL
+c1 decimal(33,30) YES NULL
DROP TABLE t1,t2;
CREATE TABLE t1 (a DECIMAL(30,30));
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index 6d99cad30f0..4ecac34d9fa 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -1876,6 +1876,40 @@ SELECT(SELECT 1 AS a FROM dual ORDER BY a DESC LIMIT 1) AS dev;
dev
1
#
+# Bug #17059925 : UNIONS COMPUTES ROWS_EXAMINED INCORRECTLY
+#
+SET @old_slow_query_log= @@global.slow_query_log;
+SET @old_log_output= @@global.log_output;
+SET @old_long_query_time= @@long_query_time;
+SET GLOBAL log_output= "TABLE";
+SET GLOBAL slow_query_log= ON;
+SET SESSION long_query_time= 0;
+CREATE TABLE t17059925 (a INT);
+CREATE TABLE t2 (b INT);
+CREATE TABLE t3 (c INT);
+INSERT INTO t17059925 VALUES (1), (2), (3);
+INSERT INTO t2 VALUES (4), (5), (6);
+INSERT INTO t3 VALUES (7), (8), (9);
+TRUNCATE table mysql.slow_log;
+SELECT * FROM t17059925 UNION SELECT * FROM t2 UNION SELECT * FROM t3;
+a
+1
+2
+3
+4
+5
+6
+7
+8
+9
+SELECT sql_text, rows_examined FROM mysql.slow_log WHERE sql_text LIKE '%SELECT%t17059925%';
+sql_text rows_examined
+SELECT * FROM t17059925 UNION SELECT * FROM t2 UNION SELECT * FROM t3 18
+DROP TABLE t17059925, t2, t3;
+SET @@long_query_time= @old_long_query_time;
+SET @@global.log_output= @old_log_output;
+SET @@global.slow_query_log= @old_slow_query_log;
+#
# lp:1010729: Unexpected syntax error from UNION
# (bug #54382) with single-table join nest
#
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index 2ba64ed3003..a93e3a210ed 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -189,6 +189,8 @@ select @@concurrent_insert;
@@concurrent_insert
AUTO
set global timed_mutexes=ON;
+Warnings:
+Warning 1287 '@@timed_mutexes' is deprecated and will be removed in a future release.
show variables like 'timed_mutexes';
Variable_name Value
timed_mutexes ON
@@ -196,6 +198,8 @@ select * from information_schema.session_variables where variable_name like 'tim
VARIABLE_NAME VARIABLE_VALUE
TIMED_MUTEXES ON
set global timed_mutexes=0;
+Warnings:
+Warning 1287 '@@timed_mutexes' is deprecated and will be removed in a future release.
show variables like 'timed_mutexes';
Variable_name Value
timed_mutexes OFF
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 64b329e9e01..ca08c53cabe 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -4789,6 +4789,45 @@ DROP DATABASE IF EXISTS nodb;
CREATE VIEW nodb.a AS SELECT 1;
ERROR 42000: Unknown database 'nodb'
#
+# BUG#14117018 - MYSQL SERVER CREATES INVALID VIEW DEFINITION
+# BUG#18405221 - SHOW CREATE VIEW OUTPUT INCORRECT
+#
+CREATE VIEW v1 AS (SELECT '' FROM DUAL);
+CREATE VIEW v2 AS (SELECT 'BUG#14117018' AS col1 FROM DUAL) UNION ALL
+(SELECT '' FROM DUAL);
+CREATE VIEW v3 AS (SELECT 'BUG#14117018' AS col1 FROM DUAL) UNION ALL
+(SELECT '' FROM DUAL) UNION ALL
+(SELECT '' FROM DUAL);
+CREATE VIEW v4 AS (SELECT 'BUG#14117018' AS col1 FROM DUAL) UNION ALL
+(SELECT '' AS col2 FROM DUAL) UNION ALL
+(SELECT '' FROM DUAL);
+CREATE VIEW v5 AS (SELECT 'buggy' AS col1, 'fix' as col2 FROM DUAL) UNION ALL
+(SELECT 'buggy' as a, 'fix' as a FROM DUAL);
+# Name for the column in select1 is set properly with or
+# without this fix.
+SHOW CREATE VIEW v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS (select '' AS `Name_exp_1`) latin1 latin1_swedish_ci
+# Name for the column in select2 is set with this fix.
+# Without this fix, name would not have set for the
+# columns in select2.
+SHOW CREATE VIEW v2;
+View Create View character_set_client collation_connection
+v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS (select 'BUG#14117018' AS `col1`) union all (select '' AS `Name_exp_1`) latin1 latin1_swedish_ci
+# Name for the field item in select2 & select3 is set with this fix.
+# Without this fix, name would not have set for the
+# columns in select2 & select3.
+SHOW CREATE VIEW v3;
+View Create View character_set_client collation_connection
+v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS (select 'BUG#14117018' AS `col1`) union all (select '' AS `Name_exp_1`) union all (select '' AS `Name_exp_1`) latin1 latin1_swedish_ci
+# Name for the field item in select3 is set with this fix.
+# Without this fix, name would not have set for the
+# columns in select3.
+SHOW CREATE VIEW v4;
+View Create View character_set_client collation_connection
+v4 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS (select 'BUG#14117018' AS `col1`) union all (select '' AS `col2`) union all (select '' AS `Name_exp_1`) latin1 latin1_swedish_ci
+DROP VIEW v1, v2, v3, v4, v5;
+#
# lp:833600 Wrong result with view + outer join + uncorrelated subquery (non-semijoin)
#
CREATE TABLE t1 ( a int, b int );
@@ -5300,6 +5339,61 @@ NULL 8
drop view v1;
drop table t1,t2,t3;
SET optimizer_switch=@save_optimizer_switch_MDEV_3874;
+CREATE TABLE `t1` (
+`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+`f0` int(11) unsigned NOT NULL DEFAULT '0',
+`f1` int(11) unsigned NOT NULL DEFAULT '0',
+PRIMARY KEY (`id`),
+UNIQUE KEY `id` (`id`)
+);
+CREATE TABLE `t2` (
+`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+`f02` bigint(20) unsigned NOT NULL DEFAULT '0',
+`f03` int(11) unsigned NOT NULL DEFAULT '0',
+PRIMARY KEY (`id`),
+UNIQUE KEY `id` (`id`)
+);
+CREATE ALGORITHM=UNDEFINED SQL SECURITY DEFINER VIEW `v1` AS
+SELECT
+`t1`.`f0` AS `f0`,
+`t1`.`f1` AS `f1`,
+`t2`.`f02` AS `f02`,
+`t2`.`f03` AS `f03`
+FROM
+(`t1` LEFT JOIN `t2` ON((`t1`.`id` = `t2`.`f02`)));
+CREATE FUNCTION `f1`(
+p0 BIGINT(20) UNSIGNED
+)
+RETURNS bigint(20) unsigned
+DETERMINISTIC
+CONTAINS SQL
+SQL SECURITY DEFINER
+COMMENT ''
+BEGIN
+DECLARE k0 INTEGER UNSIGNED DEFAULT 0;
+DECLARE lResult INTEGER UNSIGNED DEFAULT 0;
+SET k0 = 0;
+WHILE k0 < 1 DO
+SELECT COUNT(*) as `f00` INTO lResult FROM `v1` WHERE `v1`.`f0` = p0; -- BUG
+SET k0 = k0 + 1;
+END WHILE;
+RETURN(k0);
+END|
+SELECT `f1`(1);
+`f1`(1)
+1
+SELECT `f1`(1);
+`f1`(1)
+1
+SELECT `f1`(1);
+`f1`(1)
+1
+SELECT `f1`(1);
+`f1`(1)
+1
+DROP FUNCTION f1;
+DROP VIEW v1;
+DROP TABLE t1, t2;
# -----------------------------------------------------------------
# -- End of 5.5 tests.
# -----------------------------------------------------------------
diff --git a/mysql-test/std_data/checkDBI_DBD-mysql.pl b/mysql-test/std_data/checkDBI_DBD-mysql.pl
index d62d2f8bfc0..d62d2f8bfc0 100644..100755
--- a/mysql-test/std_data/checkDBI_DBD-mysql.pl
+++ b/mysql-test/std_data/checkDBI_DBD-mysql.pl
diff --git a/mysql-test/suite/archive/partition_archive.result b/mysql-test/suite/archive/partition_archive.result
index bb3e531a2ed..eb1fca46522 100644
--- a/mysql-test/suite/archive/partition_archive.result
+++ b/mysql-test/suite/archive/partition_archive.result
@@ -127,3 +127,29 @@ select count(*) from t1;
count(*)
100
drop table t1;
+#
+#BUG 18618561: FAILED ALTER TABLE ENGINE CHANGE WITH PARTITIONS
+# CORRUPTS FRM
+CREATE TABLE t1 (fld1 INT PRIMARY KEY) ENGINE= MYISAM PARTITION BY HASH(fld1)
+PARTITIONS 5;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `fld1` int(11) NOT NULL,
+ PRIMARY KEY (`fld1`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (fld1)
+PARTITIONS 5 */
+ALTER TABLE t1 ENGINE= ARCHIVE;
+ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options")
+#After the patch, the ENGINE is correctly displayed as MyISAM
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `fld1` int(11) NOT NULL,
+ PRIMARY KEY (`fld1`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (fld1)
+PARTITIONS 5 */
+#Cleanup.
+DROP TABLE t1;
diff --git a/mysql-test/suite/archive/partition_archive.test b/mysql-test/suite/archive/partition_archive.test
index be2abeada73..899f266c09c 100644
--- a/mysql-test/suite/archive/partition_archive.test
+++ b/mysql-test/suite/archive/partition_archive.test
@@ -129,3 +129,21 @@ show create table t1;
select count(*) from t1;
drop table t1;
+
+--echo #
+--echo #BUG 18618561: FAILED ALTER TABLE ENGINE CHANGE WITH PARTITIONS
+--echo # CORRUPTS FRM
+
+CREATE TABLE t1 (fld1 INT PRIMARY KEY) ENGINE= MYISAM PARTITION BY HASH(fld1)
+PARTITIONS 5;
+SHOW CREATE TABLE t1;
+
+--replace_regex /#sql-[0-9a-f_]*/#sql-temporary/
+--error ER_CANT_CREATE_TABLE
+ALTER TABLE t1 ENGINE= ARCHIVE;
+
+--echo #After the patch, the ENGINE is correctly displayed as MyISAM
+SHOW CREATE TABLE t1;
+
+--echo #Cleanup.
+DROP TABLE t1;
diff --git a/mysql-test/suite/binlog/t/binlog_killed.test b/mysql-test/suite/binlog/t/binlog_killed.test
index 0a2ba084d78..73759ee5aa5 100644
--- a/mysql-test/suite/binlog/t/binlog_killed.test
+++ b/mysql-test/suite/binlog/t/binlog_killed.test
@@ -353,6 +353,10 @@ drop function bug27563;
# common cleanup
#
+connection default;
+disconnect con1;
+disconnect con2;
+
drop table t1,t2,t3;
--echo end of the tests
diff --git a/mysql-test/suite/engines/iuds/r/insert_time.result b/mysql-test/suite/engines/iuds/r/insert_time.result
index dceba37ae8e..6680886aad1 100644
--- a/mysql-test/suite/engines/iuds/r/insert_time.result
+++ b/mysql-test/suite/engines/iuds/r/insert_time.result
@@ -5035,9 +5035,9 @@ CAST(0.2359591234567e6 AS TIME)
23:59:59
SELECT CAST(0.2359591234567e+30 AS TIME);
CAST(0.2359591234567e+30 AS TIME)
-NULL
+838:59:59
Warnings:
-Warning 1292 Incorrect datetime value: '2.359591234567e29'
+Warning 1292 Truncated incorrect time value: '2.359591234567e29'
select cast('100:55:50' as time) < cast('24:00:00' as time);
cast('100:55:50' as time) < cast('24:00:00' as time)
0
diff --git a/mysql-test/suite/engines/iuds/suite.opt b/mysql-test/suite/engines/iuds/suite.opt
new file mode 100644
index 00000000000..e5648163418
--- /dev/null
+++ b/mysql-test/suite/engines/iuds/suite.opt
@@ -0,0 +1,2 @@
+--timezone=GMT-3
+
diff --git a/mysql-test/suite/innodb/r/blob_unique2pk.result b/mysql-test/suite/innodb/r/blob_unique2pk.result
new file mode 100644
index 00000000000..57953dc8624
--- /dev/null
+++ b/mysql-test/suite/innodb/r/blob_unique2pk.result
@@ -0,0 +1,15 @@
+create table t1 (f1 tinyblob not null) engine=innodb;
+alter table t1 add unique index (f1(255));
+drop table t1;
+create table t1 (f1 tinyblob not null) engine=innodb;
+alter table t1 add unique index (f1(356));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f1` tinyblob NOT NULL,
+ UNIQUE KEY `f1` (`f1`(255))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (f1 point not null) engine=innodb;
+alter table t1 add unique index (f1);
+drop table t1;
diff --git a/mysql-test/suite/innodb/r/innodb-fk.result b/mysql-test/suite/innodb/r/innodb-fk.result
new file mode 100644
index 00000000000..cf883d83874
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-fk.result
@@ -0,0 +1,35 @@
+#
+# Bug #18806829 OPENING INNODB TABLES WITH MANY FOREIGN KEY
+# REFERENCES IS SLOW/CRASHES SEMAPHORE
+#
+create table t1 (f1 int primary key) engine=innodb;
+insert into t1 values (5);
+insert into t1 values (2882);
+insert into t1 values (10);
+update t1 set f1 = 28 where f1 = 2882;
+select * from fk_120;
+f1
+5
+10
+28
+select * from fk_1;
+f1
+5
+10
+28
+select * from fk_50;
+f1
+5
+10
+28
+drop table t1;
+#
+# Check if restrict is working fine.
+#
+create table t1 (f1 int primary key) engine=innodb;
+delete from t1 where f1 = 29;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`fk_29`, CONSTRAINT `pc29` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`))
+select * from fk_29;
+f1
+29
+drop table t1;
diff --git a/mysql-test/suite/innodb/t/blob_unique2pk.test b/mysql-test/suite/innodb/t/blob_unique2pk.test
new file mode 100644
index 00000000000..ff6720690dd
--- /dev/null
+++ b/mysql-test/suite/innodb/t/blob_unique2pk.test
@@ -0,0 +1,20 @@
+--source include/have_innodb.inc
+
+
+#
+# Bug#16368875 INNODB: FAILING ASSERTION: PRIMARY_KEY_NO == -1 || PRIMARY_KEY_NO == 0
+#
+create table t1 (f1 tinyblob not null) engine=innodb;
+alter table t1 add unique index (f1(255));
+drop table t1;
+
+create table t1 (f1 tinyblob not null) engine=innodb;
+alter table t1 add unique index (f1(356));
+show create table t1;
+drop table t1;
+
+create table t1 (f1 point not null) engine=innodb;
+alter table t1 add unique index (f1);
+drop table t1;
+
+
diff --git a/mysql-test/suite/innodb/t/innodb-fk.test b/mysql-test/suite/innodb/t/innodb-fk.test
new file mode 100644
index 00000000000..9839cd2d084
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-fk.test
@@ -0,0 +1,86 @@
+--source include/have_innodb.inc
+--source include/not_embedded.inc
+
+--echo #
+--echo # Bug #18806829 OPENING INNODB TABLES WITH MANY FOREIGN KEY
+--echo # REFERENCES IS SLOW/CRASHES SEMAPHORE
+--echo #
+
+create table t1 (f1 int primary key) engine=innodb;
+insert into t1 values (5);
+insert into t1 values (2882);
+insert into t1 values (10);
+
+let $fk_tables = 120;
+
+--disable_query_log
+let $i = $fk_tables;
+while ($i)
+{
+ eval create table fk_$i (f1 int primary key,
+ constraint pc$i foreign key (f1) references t1(f1)
+ on delete cascade on update cascade) engine=innodb;
+ eval insert into fk_$i values (5);
+ eval insert into fk_$i values (2882);
+ eval insert into fk_$i values (10);
+ dec $i;
+}
+--enable_query_log
+
+--source include/restart_mysqld.inc
+
+update t1 set f1 = 28 where f1 = 2882;
+
+select * from fk_120;
+select * from fk_1;
+select * from fk_50;
+
+--disable_query_log
+let $i = $fk_tables;
+while ($i)
+{
+ eval drop table fk_$i;
+ dec $i;
+}
+--enable_query_log
+
+drop table t1;
+
+--echo #
+--echo # Check if restrict is working fine.
+--echo #
+
+create table t1 (f1 int primary key) engine=innodb;
+
+let $fk_tables = 30;
+
+--disable_query_log
+let $i = $fk_tables;
+while ($i)
+{
+ eval create table fk_$i (f1 int primary key,
+ constraint pc$i foreign key (f1) references t1(f1)
+ on delete restrict on update restrict) engine=innodb;
+ eval insert into t1 values ($i);
+ eval insert into fk_$i values ($i);
+ dec $i;
+}
+--enable_query_log
+
+--source include/restart_mysqld.inc
+
+--error ER_ROW_IS_REFERENCED_2
+delete from t1 where f1 = 29;
+select * from fk_29;
+
+--disable_query_log
+let $i = $fk_tables;
+while ($i)
+{
+ eval drop table fk_$i;
+ dec $i;
+}
+--enable_query_log
+
+drop table t1;
+
diff --git a/mysql-test/suite/maria/maria_partition.result b/mysql-test/suite/maria/maria_partition.result
index 372230c0b71..1c4f0fbaf05 100644
--- a/mysql-test/suite/maria/maria_partition.result
+++ b/mysql-test/suite/maria/maria_partition.result
@@ -33,3 +33,18 @@ insert into t1 values (2);
select * from t2 left join t1 on (t2.a=t1.a) where t2.a='bbb';
a a
drop table t1,t2;
+CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=Aria PARTITION BY KEY() PARTITIONS 2;
+CREATE VIEW v1 AS SELECT * FROM t1;
+LOCK TABLE v1 WRITE;
+CREATE TABLE v1 (i INT);
+ERROR HY000: Table 'v1' was not locked with LOCK TABLES
+INSERT INTO v1 VALUES (1);
+UNLOCK TABLES;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SELECT * FROM t1;
+pk
+1
+drop table t1;
+drop view v1;
diff --git a/mysql-test/suite/maria/maria_partition.test b/mysql-test/suite/maria/maria_partition.test
index 47571c7a4be..ca2651bcdc3 100644
--- a/mysql-test/suite/maria/maria_partition.test
+++ b/mysql-test/suite/maria/maria_partition.test
@@ -49,6 +49,28 @@ insert into t1 values (2);
select * from t2 left join t1 on (t2.a=t1.a) where t2.a='bbb';
drop table t1,t2;
+#
+# MDEV-6493
+# Assertion `table->file->stats.records > 0 || error'
+# failure, or 'Invalid write' valgrind warnings, or crash on scenario
+# with Aria table, view, LOCK TABLES #
+#
+
+CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=Aria PARTITION BY KEY() PARTITIONS 2;
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+LOCK TABLE v1 WRITE;
+--error 1100
+CREATE TABLE v1 (i INT);
+INSERT INTO v1 VALUES (1);
+UNLOCK TABLES;
+check table t1;
+
+SELECT * FROM t1;
+
+drop table t1;
+drop view v1;
+
# Set defaults back
--disable_result_log
--disable_query_log
diff --git a/mysql-test/suite/rpl/r/failed_create_view-6409.result b/mysql-test/suite/rpl/r/failed_create_view-6409.result
new file mode 100644
index 00000000000..6b04f2960d1
--- /dev/null
+++ b/mysql-test/suite/rpl/r/failed_create_view-6409.result
@@ -0,0 +1,15 @@
+create table v1 (a int);
+include/master-slave.inc
+[connection master]
+create table t1 (a int);
+create view v1 as select * from t1;
+ERROR 42S01: Table 'v1' already exists
+show tables;
+Tables_in_test
+t1
+v1
+show tables;
+Tables_in_test
+t1
+drop table if exists t1, v1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/kill_hard-6290.result b/mysql-test/suite/rpl/r/kill_hard-6290.result
new file mode 100644
index 00000000000..27b62416368
--- /dev/null
+++ b/mysql-test/suite/rpl/r/kill_hard-6290.result
@@ -0,0 +1,4 @@
+include/master-slave.inc
+[connection master]
+kill user test2@nohost;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_heartbeat_debug.result b/mysql-test/suite/rpl/r/rpl_heartbeat_debug.result
new file mode 100644
index 00000000000..b9dec686e4a
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_heartbeat_debug.result
@@ -0,0 +1,25 @@
+include/master-slave.inc
+[connection master]
+include/stop_slave.inc
+set @restore_slave_net_timeout= @@global.slave_net_timeout;
+set @@global.slave_net_timeout= 10;
+show status like 'Slave_heartbeat_period';;
+Variable_name Slave_heartbeat_period
+Value 60.000
+SET @save_dbug= @@GLOBAL.debug_dbug;
+SET GLOBAL debug_dbug="+d,simulate_slave_heartbeat_network_error";
+CALL mtr.add_suppression('SET @master_heartbeat_period to master failed with error');
+CALL mtr.add_suppression('Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again');
+include/start_slave.inc
+drop table if exists t1;
+CREATE TABLE t1 (a INT PRIMARY KEY);
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
+a
+1
+drop table t1;
+include/stop_slave.inc
+SET GLOBAL debug_dbug=@save_dbug;
+set @@global.slave_net_timeout= @restore_slave_net_timeout;
+include/start_slave.inc
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_uninstall_plugin.result b/mysql-test/suite/rpl/r/rpl_semi_sync_uninstall_plugin.result
new file mode 100644
index 00000000000..c1d09e04cd0
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_semi_sync_uninstall_plugin.result
@@ -0,0 +1,61 @@
+include/master-slave.inc
+[connection master]
+INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master';
+[connection slave]
+INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave';
+UNINSTALL PLUGIN rpl_semi_sync_slave;
+[connection master]
+UNINSTALL PLUGIN rpl_semi_sync_master;
+CREATE TABLE t1(i int);
+INSERT INTO t1 values (1);
+DROP TABLE t1;
+[connection slave]
+include/install_semisync.inc
+[connection slave]
+UNINSTALL PLUGIN rpl_semi_sync_slave;
+Warnings:
+Warning 1620 Plugin is busy and will be uninstalled on shutdown
+select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
+plugin_name plugin_status
+rpl_semi_sync_slave DELETED
+[connection master]
+UNINSTALL PLUGIN rpl_semi_sync_master;
+Warnings:
+Warning 1620 Plugin is busy and will be uninstalled on shutdown
+select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
+plugin_name plugin_status
+rpl_semi_sync_master DELETED
+CREATE TABLE t1(i int);
+INSERT INTO t1 values (2);
+DROP TABLE t1;
+[connection slave]
+show status like "Rpl_semi_sync_slave_status";
+Variable_name Value
+Rpl_semi_sync_slave_status ON
+[connection master]
+show status like "Rpl_semi_sync_master_status";
+Variable_name Value
+Rpl_semi_sync_master_status ON
+show status like "Rpl_semi_sync_master_clients";
+Variable_name Value
+Rpl_semi_sync_master_clients 1
+select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
+plugin_name plugin_status
+rpl_semi_sync_master DELETED
+[connection slave]
+include/stop_slave.inc
+select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
+plugin_name plugin_status
+include/start_slave.inc
+select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
+plugin_name plugin_status
+[connection master]
+show status like "Rpl_semi_sync_master_clients";
+Variable_name Value
+select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
+plugin_name plugin_status
+CREATE TABLE t1(i int);
+INSERT INTO t1 values (3);
+DROP TABLE t1;
+[connection slave]
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_stop_slave.result b/mysql-test/suite/rpl/r/rpl_stop_slave.result
index 5959ee09993..b93ecce3597 100644
--- a/mysql-test/suite/rpl/r/rpl_stop_slave.result
+++ b/mysql-test/suite/rpl/r/rpl_stop_slave.result
@@ -94,10 +94,12 @@ DROP TABLE t1, t2;
CREATE TABLE t1 (c1 INT KEY, c2 INT) ENGINE=InnoDB;
CREATE TABLE t2 (c1 INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES(1, 1);
+include/stop_slave.inc
[connection master]
+include/stop_dump_threads.inc
SET GLOBAL debug_dbug= '+d,dump_thread_wait_before_send_xid,*';
[connection slave]
-include/restart_slave.inc
+include/start_slave.inc
BEGIN;
UPDATE t1 SET c2 = 2 WHERE c1 = 1;
[connection master]
@@ -116,6 +118,9 @@ SET DEBUG_SYNC= 'now WAIT_FOR signal.continued';
[connection slave]
include/wait_for_slave_to_stop.inc
[connection slave1]
+[connection master]
+include/stop_dump_threads.inc
+[connection slave1]
include/start_slave.inc
[connection master]
DROP TABLE t1, t2;
diff --git a/mysql-test/suite/rpl/t/failed_create_view-6409.test b/mysql-test/suite/rpl/t/failed_create_view-6409.test
new file mode 100644
index 00000000000..5d96e6f8a93
--- /dev/null
+++ b/mysql-test/suite/rpl/t/failed_create_view-6409.test
@@ -0,0 +1,24 @@
+#
+# MDEV-6409 CREATE VIEW replication problem if error occurs in mysql_register_view
+#
+
+#
+#
+# verify that failed CREATE VIEW is not replicated
+
+create table v1 (a int);
+
+source include/master-slave.inc;
+
+connection master;
+create table t1 (a int);
+--error ER_TABLE_EXISTS_ERROR
+create view v1 as select * from t1;
+show tables;
+sync_slave_with_master;
+show tables;
+
+connection master;
+drop table if exists t1, v1;
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/kill_hard-6290.test b/mysql-test/suite/rpl/t/kill_hard-6290.test
new file mode 100644
index 00000000000..7624235666a
--- /dev/null
+++ b/mysql-test/suite/rpl/t/kill_hard-6290.test
@@ -0,0 +1,11 @@
+#
+# MDEV-6290 Crash in KILL HARD QUERY USER x@y when slave threads are running
+#
+
+# this test doesn't depend on the binlog format, no need to run it three times
+--source include/have_binlog_format_mixed.inc
+
+--source include/master-slave.inc
+--connection server_2
+kill user test2@nohost;
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat_debug.test b/mysql-test/suite/rpl/t/rpl_heartbeat_debug.test
new file mode 100644
index 00000000000..7cdf67d6532
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_heartbeat_debug.test
@@ -0,0 +1,52 @@
+# Testing master to slave heartbeat protocol, test cases that need debug build.
+
+--source include/master-slave.inc
+--source include/have_debug.inc
+
+connection slave;
+--source include/stop_slave.inc
+set @restore_slave_net_timeout= @@global.slave_net_timeout;
+--disable_warnings
+set @@global.slave_net_timeout= 10;
+--enable_warnings
+
+###
+### Checking the range
+###
+
+#
+# default period slave_net_timeout/2
+#
+--query_vertical show status like 'Slave_heartbeat_period';
+SET @save_dbug= @@GLOBAL.debug_dbug;
+SET GLOBAL debug_dbug="+d,simulate_slave_heartbeat_network_error";
+CALL mtr.add_suppression('SET @master_heartbeat_period to master failed with error');
+CALL mtr.add_suppression('Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again');
+--source include/start_slave.inc
+
+
+connection master;
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT PRIMARY KEY);
+INSERT INTO t1 VALUES (1);
+
+sync_slave_with_master;
+
+--connection slave
+SELECT * FROM t1;
+
+connection master;
+drop table t1;
+
+connection slave;
+--source include/stop_slave.inc
+--disable_warnings
+SET GLOBAL debug_dbug=@save_dbug;
+set @@global.slave_net_timeout= @restore_slave_net_timeout;
+--enable_warnings
+--source include/start_slave.inc
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_uninstall_plugin.test b/mysql-test/suite/rpl/t/rpl_semi_sync_uninstall_plugin.test
new file mode 100644
index 00000000000..60636da35dd
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_semi_sync_uninstall_plugin.test
@@ -0,0 +1,130 @@
+###############################################################################
+# Bug#17638477 UNINSTALL AND INSTALL SEMI-SYNC PLUGIN CAUSES SLAVES TO BREAK
+# Problem: Uninstallation of Semi sync plugin should be blocked when it is
+# in use.
+# Test case: Uninstallation of semi sync should be allowed
+# On Master:
+# 1) When there is no dump thread
+# 2) When there are no semi sync slaves (i.e., async replication).
+# On Slave:
+# 1) When there is no I/O thread
+# 2) When there are no semi sync enabled I/O thread (i.e.,async replication).
+###############################################################################
+
+--source include/have_semisync_plugin.inc
+--source include/not_embedded.inc
+--source include/have_binlog_format_statement.inc
+--source include/master-slave.inc
+
+###############################################################################
+# Case 1: Uninstallation of semi sync plugins should be allowed when it is
+# not in use i.e., when asynchronous replication is active.
+###############################################################################
+# Step 1.1: Install semi sync master plugin on master
+INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master';
+
+# Step 1.2: Install semi sync slave plugin on slave
+--connection slave
+--echo [connection slave]
+INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave';
+
+# Step 1.3: Uninstallation of semisync plugin on master and slave should be
+# allowed at this state as there is no semi sync replication enabled between
+# master and slave.
+UNINSTALL PLUGIN rpl_semi_sync_slave;
+--connection master
+--echo [connection master]
+UNINSTALL PLUGIN rpl_semi_sync_master;
+
+# Step 1.4: Check that replication is working fine at the end of the test case.
+CREATE TABLE t1(i int);
+INSERT INTO t1 values (1);
+DROP TABLE t1;
+--sync_slave_with_master
+--echo [connection slave]
+
+###############################################################################
+# Case 2: Uninstallation of semi sync plugins should be disallowed
+# when it is in use i.e., when semi sync replication is active
+###############################################################################
+# Step 2.1: Install and enable semi sync replication between master and slave
+--source include/install_semisync.inc
+
+# Step 2.2: Check that rpl_semi_sync_slave uninstallation on Slave is not
+# possible at this state
+--connection slave
+--echo [connection slave]
+UNINSTALL PLUGIN rpl_semi_sync_slave;
+select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
+
+# Step 2.3: Check that rpl_semi_sync_master uninstallation on Master is not
+# possible at this state
+--connection master
+--echo [connection master]
+UNINSTALL PLUGIN rpl_semi_sync_master;
+select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
+
+# Step 2.4: Check that replication is working fine at the end of the test case.
+CREATE TABLE t1(i int);
+INSERT INTO t1 values (2);
+DROP TABLE t1;
+--sync_slave_with_master
+--echo [connection slave]
+
+# Step 2.5: Make sure rpl_semi_sync_master_status on Master and
+# rpl_semi_sync_slave_staus on Slave are ON
+show status like "Rpl_semi_sync_slave_status";
+
+###############################################################################
+# Case 3: Uninstallation of semi sync plugin should be disallowed when there
+# are semi sync slaves even though rpl_semi_sync_master_enabled= OFF;.
+###############################################################################
+# Step 3.1: Disable semi sync on master
+--connection master
+--echo [connection master]
+show status like "Rpl_semi_sync_master_status";
+
+# Step 3.2: Check that still Rpl_semi_sync_master_clients is 1
+show status like "Rpl_semi_sync_master_clients";
+
+# Step 3.3: Since Rpl_semi_sync_master_clients is 1, uninstallation of
+# rpl_semi_sync_master should be disallowed.
+select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
+
+###############################################################################
+# Case 4: Uninstallation of semi sync plugin should be allowed when it is not
+# in use. Same as Case 1 but this case is to check the case after enabling and
+# disabling semi sync replication.
+###############################################################################
+
+# Step 4.1: Stop IO thread on slave.
+--connection slave
+--echo [connection slave]
+--source include/stop_slave.inc
+
+# Step 4.2: Disable semi sync on slave.
+select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
+
+# Step 4.3: Start IO thread on slave.
+--source include/start_slave.inc
+
+# Step 4.4: Uninstall semi sync plugin, it should be successful now.
+select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
+
+# Step 4.5: On Master, check that semi sync slaves are now '0'.
+--connection master
+--echo [connection master]
+show status like "Rpl_semi_sync_master_clients";
+
+# Step 4.6: So uninstalling semi sync plugin should be allowed
+select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%';
+
+# Step 4.7: Check that replication is working fine at the end of the test case
+CREATE TABLE t1(i int);
+INSERT INTO t1 values (3);
+DROP TABLE t1;
+--sync_slave_with_master
+--echo [connection slave]
+
+# Cleanup
+source include/rpl_end.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_stop_slave.test b/mysql-test/suite/rpl/t/rpl_stop_slave.test
index d9d7f39c321..340738f8cb2 100644
--- a/mysql-test/suite/rpl/t/rpl_stop_slave.test
+++ b/mysql-test/suite/rpl/t/rpl_stop_slave.test
@@ -74,14 +74,17 @@ CREATE TABLE t2 (c1 INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES(1, 1);
sync_slave_with_master;
+--source include/stop_slave.inc
--source include/rpl_connection_master.inc
+# make sure that there are no zombie threads
+--source include/stop_dump_threads.inc
let $debug_save= `SELECT @@GLOBAL.debug`;
SET GLOBAL debug_dbug= '+d,dump_thread_wait_before_send_xid,*';
--source include/rpl_connection_slave.inc
-source include/restart_slave_sql.inc;
+--source include/start_slave.inc
BEGIN;
UPDATE t1 SET c2 = 2 WHERE c1 = 1;
@@ -93,6 +96,10 @@ INSERT INTO t2 VALUES(1);
UPDATE t1 SET c2 = 3 WHERE c1 = 1;
COMMIT;
+# wait for the dump thread reach the sync point
+--let $wait_condition= select count(*)=1 from information_schema.processlist where state LIKE '%debug sync point%' and command='Binlog Dump'
+--source include/wait_condition.inc
+
--source include/rpl_connection_slave1.inc
let $show_statement= SHOW PROCESSLIST;
let $field= Info;
@@ -105,6 +112,7 @@ send STOP SLAVE;
ROLLBACK;
--source include/rpl_connection_master.inc
+
SET DEBUG_SYNC= 'now SIGNAL signal.continue';
SET DEBUG_SYNC= 'now WAIT_FOR signal.continued';
@@ -113,12 +121,25 @@ source include/wait_for_slave_to_stop.inc;
--source include/rpl_connection_slave1.inc
reap;
-source include/start_slave.inc;
+# Slave has stopped, thence lets make sure that
+# we kill the zombie dump threads. Also, make
+# sure that we disable the DBUG_EXECUTE_IF
+# that would set the dump thread to wait
--source include/rpl_connection_master.inc
-DROP TABLE t1, t2;
--disable_query_log
eval SET GLOBAL debug_dbug= '$debug_save';
--enable_query_log
+# make sure that there are no zombie threads
+--source include/stop_dump_threads.inc
+
+--source include/rpl_connection_slave1.inc
+# now the dump thread on the master will start
+# from a clean slate, i.e. without the
+# DBUG_EXECUTE_IF set
+source include/start_slave.inc;
+
+--source include/rpl_connection_master.inc
+DROP TABLE t1, t2;
--source include/rpl_end.inc
SET DEBUG_SYNC= 'RESET';
diff --git a/mysql-test/suite/sys_vars/r/timed_mutexes_basic.result b/mysql-test/suite/sys_vars/r/timed_mutexes_basic.result
index 50a5285b0d7..8c295fe8063 100644
--- a/mysql-test/suite/sys_vars/r/timed_mutexes_basic.result
+++ b/mysql-test/suite/sys_vars/r/timed_mutexes_basic.result
@@ -4,7 +4,11 @@ SELECT @global_start_value;
0
'#--------------------FN_DYNVARS_177_01------------------------#'
SET @@global.timed_mutexes = 1;
+Warnings:
+Warning 1287 '@@timed_mutexes' is deprecated and will be removed in a future release.
SET @@global.timed_mutexes = DEFAULT;
+Warnings:
+Warning 1287 '@@timed_mutexes' is deprecated and will be removed in a future release.
SELECT @@global.timed_mutexes;
@@global.timed_mutexes
0
@@ -17,15 +21,21 @@ SELECT @@timed_mutexes;
SELECT global.timed_mutexes;
ERROR 42S02: Unknown table 'global' in field list
SET global timed_mutexes = 1;
+Warnings:
+Warning 1287 '@@timed_mutexes' is deprecated and will be removed in a future release.
SELECT @@global.timed_mutexes;
@@global.timed_mutexes
1
'#--------------------FN_DYNVARS_177_03------------------------#'
SET @@global.timed_mutexes = 0;
+Warnings:
+Warning 1287 '@@timed_mutexes' is deprecated and will be removed in a future release.
SELECT @@global.timed_mutexes;
@@global.timed_mutexes
0
SET @@global.timed_mutexes = 1;
+Warnings:
+Warning 1287 '@@timed_mutexes' is deprecated and will be removed in a future release.
SELECT @@global.timed_mutexes;
@@global.timed_mutexes
1
@@ -82,23 +92,33 @@ VARIABLE_VALUE
ON
'#---------------------FN_DYNVARS_177_08-------------------------#'
SET @@global.timed_mutexes = OFF;
+Warnings:
+Warning 1287 '@@timed_mutexes' is deprecated and will be removed in a future release.
SELECT @@global.timed_mutexes;
@@global.timed_mutexes
0
SET @@global.timed_mutexes = ON;
+Warnings:
+Warning 1287 '@@timed_mutexes' is deprecated and will be removed in a future release.
SELECT @@global.timed_mutexes;
@@global.timed_mutexes
1
'#---------------------FN_DYNVARS_177_09----------------------#'
SET @@global.timed_mutexes = TRUE;
+Warnings:
+Warning 1287 '@@timed_mutexes' is deprecated and will be removed in a future release.
SELECT @@global.timed_mutexes;
@@global.timed_mutexes
1
SET @@global.timed_mutexes = FALSE;
+Warnings:
+Warning 1287 '@@timed_mutexes' is deprecated and will be removed in a future release.
SELECT @@global.timed_mutexes;
@@global.timed_mutexes
0
SET @@global.timed_mutexes = @global_start_value;
+Warnings:
+Warning 1287 '@@timed_mutexes' is deprecated and will be removed in a future release.
SELECT @@global.timed_mutexes;
@@global.timed_mutexes
0
diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index 09294b60a04..3040c5b5392 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -796,6 +796,23 @@ DROP TABLE t1;
--echo #
+--echo # MDEV-5745 analyze MySQL fix for bug#12368495
+--echo #
+SELECT CHAR_LENGTH(TRIM(LEADING 0x000000 FROM _ucs2 0x0061));
+SELECT CHAR_LENGTH(TRIM(LEADING 0x0001 FROM _ucs2 0x0061));
+SELECT CHAR_LENGTH(TRIM(LEADING 0x00 FROM _ucs2 0x0061));
+
+SELECT CHAR_LENGTH(TRIM(TRAILING 0x000000 FROM _ucs2 0x0061));
+SELECT CHAR_LENGTH(TRIM(TRAILING 0x0001 FROM _ucs2 0x0061));
+SELECT CHAR_LENGTH(TRIM(TRAILING 0x61 FROM _ucs2 0x0061));
+
+SELECT CHAR_LENGTH(TRIM(BOTH 0x000000 FROM _ucs2 0x0061));
+SELECT CHAR_LENGTH(TRIM(BOTH 0x0001 FROM _ucs2 0x0061));
+SELECT CHAR_LENGTH(TRIM(BOTH 0x61 FROM _ucs2 0x0061));
+SELECT CHAR_LENGTH(TRIM(BOTH 0x00 FROM _ucs2 0x0061));
+
+
+--echo #
--echo # End of 5.5 tests
--echo #
diff --git a/mysql-test/t/ctype_utf32.test b/mysql-test/t/ctype_utf32.test
index 2fbe452a716..b4ed48d07a5 100644
--- a/mysql-test/t/ctype_utf32.test
+++ b/mysql-test/t/ctype_utf32.test
@@ -873,6 +873,22 @@ ORDER BY l DESC;
SELECT '2010-10-10 10:10:10' + INTERVAL GeometryType(GeomFromText('POINT(1 1)')) hour_second;
--echo #
+--echo # MDEV-5745 analyze MySQL fix for bug#12368495
+--echo #
+SELECT CHAR_LENGTH(TRIM(LEADING 0x0000000000 FROM _utf32 0x00000061));
+SELECT CHAR_LENGTH(TRIM(LEADING 0x0001 FROM _utf32 0x00000061));
+SELECT CHAR_LENGTH(TRIM(LEADING 0x00 FROM _utf32 0x00000061));
+
+SELECT CHAR_LENGTH(TRIM(TRAILING 0x0000000000 FROM _utf32 0x00000061));
+SELECT CHAR_LENGTH(TRIM(TRAILING 0x0001 FROM _utf32 0x00000061));
+SELECT CHAR_LENGTH(TRIM(TRAILING 0x61 FROM _utf32 0x00000061));
+
+SELECT CHAR_LENGTH(TRIM(BOTH 0x0000000000 FROM _utf32 0x00000061));
+SELECT CHAR_LENGTH(TRIM(BOTH 0x0001 FROM _utf32 0x00000061));
+SELECT CHAR_LENGTH(TRIM(BOTH 0x61 FROM _utf32 0x00000061));
+SELECT CHAR_LENGTH(TRIM(BOTH 0x00 FROM _utf32 0x00000061));
+
+--echo #
--echo # End of 5.5 tests
--echo #
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index 61a237cb447..f04fda55608 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -1595,6 +1595,11 @@ call foo('(( 00000000 ++ 00000000 ))');
drop procedure foo;
drop table t1,t2;
+#
+# Bug#18786138 SHA/MD5 HASHING FUNCTIONS DIE WITH "FILENAME" CHARACTER SET
+#
+select md5(_filename "a"), sha(_filename "a");
+
--echo #
--echo # End of 5.5 tests
--echo #
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 6bea1aab392..a3f488a8d1e 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -1243,13 +1243,47 @@ CREATE TABLE t1 AS SELECT
SHOW COLUMNS FROM t1;
DROP TABLE t1;
+CREATE TABLE t1 (a DATE) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('2005-05-04'),('2000-02-23');
+SELECT * FROM t1 GROUP BY FROM_UNIXTIME(concat(a,'10'))*1;
+SELECT * FROM t1 GROUP BY (-FROM_UNIXTIME(concat(a,'10')))*1;
+SELECT * FROM t1 GROUP BY (-FROM_UNIXTIME(concat(a,'10')));
+SELECT * FROM t1 GROUP BY ABS(FROM_UNIXTIME(concat(a,'10')));
+SELECT * FROM t1 GROUP BY @a:=(FROM_UNIXTIME(concat(a,'10'))*1);
+
+DROP TABLE t1;
+
+SET TIME_ZONE='+02:00';
+
+--echo #
+--echo # MDEV-6302 Wrong result set when using GROUP BY FROM_UNIXTIME(...)+0
+--echo #
+CREATE TABLE t1 (a DATE);
+INSERT INTO t1 VALUES ('2005-05-04'),('2000-02-23');
+SELECT a, FROM_UNIXTIME(CONCAT(a,'10')) AS f1, FROM_UNIXTIME(CONCAT(a,'10'))+0 AS f2 FROM t1;
+SELECT * FROM t1 GROUP BY FROM_UNIXTIME(CONCAT(a,'10'))+0;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a DATE) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('2005-05-04'),('2000-02-23');
+SELECT * FROM t1 GROUP BY FROM_UNIXTIME(concat(a,'10'))/1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a DATE);
+INSERT INTO t1 VALUES ('2005-05-04');
+SELECT CONCAT(FROM_UNIXTIME(CONCAT(a,'10')) MOD FROM_UNIXTIME(CONCAT(a,'10'))) AS f2 FROM t1;
+SELECT CHAR_LENGTH(CONCAT(FROM_UNIXTIME(CONCAT(a,'10')) MOD FROM_UNIXTIME(CONCAT(a,'10')))) AS f2 FROM t1;
+CREATE TABLE t2 AS SELECT CONCAT(FROM_UNIXTIME(CONCAT(a,'10')) MOD FROM_UNIXTIME(CONCAT(a,'10'))) AS f2 FROM t1;
+SHOW CREATE TABLE t2;
+SELECT * FROM t2;
+DROP TABLE t1,t2;
+
--echo #
--echo # MDEV-4635 Crash in UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y'))
--echo #
-SET TIME_ZONE='+02:00';
SELECT UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y'));
-SET TIME_ZONE=DEFAULT;
+SET TIME_ZONE=DEFAULT;
--echo #
--echo # MDEV-4863 COALESCE(time_or_datetime) returns wrong results in numeric context
@@ -1589,3 +1623,11 @@ SELECT IFNULL(TIME'10:20:30',DATE'2001-01-01');
SELECT CASE WHEN 1 THEN TIME'10:20:30' ELSE DATE'2001-01-01' END;
SELECT COALESCE(TIME'10:20:30',DATE'2001-01-01');
SET timestamp=DEFAULT;
+
+--echo #
+--echo # MDEV-5750 Assertion `ltime->year == 0' fails on a query with EXTRACT DAY_MINUTE and TIME column
+--echo #
+CREATE TABLE t1 ( d DATE, t TIME );
+INSERT INTO t1 VALUES ('2008-12-05','22:34:09'),('2005-03-27','14:26:02');
+SELECT EXTRACT(DAY_MINUTE FROM GREATEST(t,d)), GREATEST(t,d) FROM t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test
index f1a287054ca..c809401bbf8 100644
--- a/mysql-test/t/group_min_max.test
+++ b/mysql-test/t/group_min_max.test
@@ -1418,6 +1418,31 @@ drop table t1;
--echo # End of test#50539.
--echo #
+--echo # Bug#17217128 - BAD INTERACTION BETWEEN MIN/MAX AND
+--echo # "HAVING SUM(DISTINCT)": WRONG RESULTS.
+--echo #
+
+CREATE TABLE t (a INT, b INT, KEY(a,b));
+INSERT INTO t VALUES (1,1), (2,2), (3,3), (4,4), (1,0), (3,2), (4,5);
+ANALYZE TABLE t;
+
+SELECT a, SUM(DISTINCT a), MIN(b) FROM t GROUP BY a;
+EXPLAIN SELECT a, SUM(DISTINCT a), MIN(b) FROM t GROUP BY a;
+
+SELECT a, SUM(DISTINCT a), MAX(b) FROM t GROUP BY a;
+EXPLAIN SELECT a, SUM(DISTINCT a), MAX(b) FROM t GROUP BY a;
+
+SELECT a, MAX(b) FROM t GROUP BY a HAVING SUM(DISTINCT a);
+EXPLAIN SELECT a, MAX(b) FROM t GROUP BY a HAVING SUM(DISTINCT a);
+
+SELECT SUM(DISTINCT a), MIN(b), MAX(b) FROM t;
+EXPLAIN SELECT SUM(DISTINCT a), MIN(b), MAX(b) FROM t;
+
+SELECT a, SUM(DISTINCT a), MIN(b), MAX(b) FROM t GROUP BY a;
+EXPLAIN SELECT a, SUM(DISTINCT a), MIN(b), MAX(b) FROM t GROUP BY a;
+DROP TABLE t;
+
+--echo #
--echo # MDEV-4219 A simple select query returns random data (upstream bug#68473)
--echo #
diff --git a/mysql-test/t/group_min_max_innodb.test b/mysql-test/t/group_min_max_innodb.test
index 7038eb2ff47..6967f847147 100644
--- a/mysql-test/t/group_min_max_innodb.test
+++ b/mysql-test/t/group_min_max_innodb.test
@@ -137,3 +137,96 @@ SELECT COUNT(DISTINCT a) FROM t1 WHERE b = 'b';
DROP TABLE t1;
--echo End of 5.5 tests
+
+--echo #
+--echo # Bug#17909656 - WRONG RESULTS FOR A SIMPLE QUERY WITH GROUP BY
+--echo #
+
+CREATE TABLE t0 (
+ i1 INTEGER NOT NULL
+);
+
+INSERT INTO t0 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),
+ (11),(12),(13),(14),(15),(16),(17),(18),(19),(20),
+ (21),(22),(23),(24),(25),(26),(27),(28),(29),(30);
+
+CREATE TABLE t1 (
+ c1 CHAR(1) NOT NULL,
+ i1 INTEGER NOT NULL,
+ i2 INTEGER NOT NULL,
+ UNIQUE KEY k1 (c1,i2)
+) ENGINE=InnoDB;
+
+INSERT INTO t1 SELECT 'A',i1,i1 FROM t0;
+INSERT INTO t1 SELECT 'B',i1,i1 FROM t0;
+INSERT INTO t1 SELECT 'C',i1,i1 FROM t0;
+INSERT INTO t1 SELECT 'D',i1,i1 FROM t0;
+INSERT INTO t1 SELECT 'E',i1,i1 FROM t0;
+INSERT INTO t1 SELECT 'F',i1,i1 FROM t0;
+
+CREATE TABLE t2 (
+ c1 CHAR(1) NOT NULL,
+ i1 INTEGER NOT NULL,
+ i2 INTEGER NOT NULL,
+ UNIQUE KEY k2 (c1,i1,i2)
+) ENGINE=InnoDB;
+
+INSERT INTO t2 SELECT 'A',i1,i1 FROM t0;
+INSERT INTO t2 SELECT 'B',i1,i1 FROM t0;
+INSERT INTO t2 SELECT 'C',i1,i1 FROM t0;
+INSERT INTO t2 SELECT 'D',i1,i1 FROM t0;
+INSERT INTO t2 SELECT 'E',i1,i1 FROM t0;
+INSERT INTO t2 SELECT 'F',i1,i1 FROM t0;
+
+-- disable_result_log
+ANALYZE TABLE t1;
+ANALYZE TABLE t2;
+-- enable_result_log
+
+let query=
+SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' AND i2 = 17) OR ( c1 = 'F')
+GROUP BY c1;
+eval EXPLAIN $query;
+eval $query;
+
+let query=
+SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' OR ( c1 = 'F' AND i2 = 17))
+GROUP BY c1;
+eval EXPLAIN $query;
+eval $query;
+
+let query=
+SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' OR c1 = 'F' ) AND ( i2 = 17 )
+GROUP BY c1;
+eval EXPLAIN $query;
+eval $query;
+
+let query=
+SELECT c1, max(i2) FROM t1
+WHERE ((c1 = 'C' AND (i2 = 40 OR i2 = 30)) OR ( c1 = 'F' AND (i2 = 40 )))
+GROUP BY c1;
+eval EXPLAIN $query;
+eval $query;
+
+let query=
+SELECT c1, i1, max(i2) FROM t2
+WHERE (c1 = 'C' OR ( c1 = 'F' AND i1 < 35)) AND ( i2 = 17 )
+GROUP BY c1,i1;
+eval EXPLAIN $query;
+eval $query;
+
+let query=
+SELECT c1, i1, max(i2) FROM t2
+WHERE (((c1 = 'C' AND i1 < 40) OR ( c1 = 'F' AND i1 < 35)) AND ( i2 = 17 ))
+GROUP BY c1,i1;
+eval EXPLAIN $query;
+eval $query;
+
+let query=
+SELECT c1, i1, max(i2) FROM t2
+WHERE ((c1 = 'C' AND i1 < 40) OR ( c1 = 'F' AND i1 < 35) OR ( i2 = 17 ))
+GROUP BY c1,i1;
+eval EXPLAIN $query;
+eval $query;
+
+DROP TABLE t0,t1,t2;
diff --git a/mysql-test/t/innodb_load_xa.opt b/mysql-test/t/innodb_load_xa.opt
new file mode 100644
index 00000000000..4ff27e659ce
--- /dev/null
+++ b/mysql-test/t/innodb_load_xa.opt
@@ -0,0 +1 @@
+--ignore-builtin-innodb --loose-innodb --log-bin
diff --git a/mysql-test/t/innodb_load_xa.test b/mysql-test/t/innodb_load_xa.test
new file mode 100644
index 00000000000..52862151b22
--- /dev/null
+++ b/mysql-test/t/innodb_load_xa.test
@@ -0,0 +1,18 @@
+#
+# MDEV-6082 Assertion `0' fails in TC_LOG_DUMMY::log_and_order on DML after installing TokuDB at runtime on server with disabled InnoDB
+#
+--source include/not_embedded.inc
+
+if (!$HA_INNODB_SO) {
+ --skip Need InnoDB plugin
+}
+install plugin innodb soname 'ha_innodb';
+select engine,support,transactions,xa from information_schema.engines where engine='innodb';
+create table t1 (a int) engine=innodb;
+start transaction;
+insert t1 values (1);
+insert t1 values (2);
+commit;
+--source include/show_binlog_events.inc
+drop table t1;
+uninstall plugin innodb;
diff --git a/mysql-test/t/long_tmpdir-master.sh b/mysql-test/t/long_tmpdir-master.sh
index 7bcbee26105..7bcbee26105 100644..100755
--- a/mysql-test/t/long_tmpdir-master.sh
+++ b/mysql-test/t/long_tmpdir-master.sh
diff --git a/mysql-test/t/lowercase_mixed_tmpdir-master.sh b/mysql-test/t/lowercase_mixed_tmpdir-master.sh
index 9330d0581ee..9330d0581ee 100644..100755
--- a/mysql-test/t/lowercase_mixed_tmpdir-master.sh
+++ b/mysql-test/t/lowercase_mixed_tmpdir-master.sh
diff --git a/mysql-test/t/order_by_innodb.test b/mysql-test/t/order_by_innodb.test
new file mode 100644
index 00000000000..c20eaceb053
--- /dev/null
+++ b/mysql-test/t/order_by_innodb.test
@@ -0,0 +1,23 @@
+#
+# ORDER BY handling (e.g. filesort) tests that require innodb
+#
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t0,t1,t2,t3;
+--enable_warnings
+
+--echo #
+--echo # MDEV-6434: Wrong result (extra rows) with ORDER BY, multiple-column index, InnoDB
+--echo #
+
+CREATE TABLE t1 (a INT, b INT, c INT, d TEXT, KEY idx(a,b,c)) ENGINE=InnoDB;
+
+INSERT INTO t1 (a,c) VALUES
+(8, 9),(8, 10),(13, 15),(16, 17),(16, 18),(16, 19),(20, 21),
+(20, 22),(20, 24),(20, 25),(20, 26),(20, 27),(20, 28);
+
+SELECT * FROM t1 WHERE a = 8 AND (b = 1 OR b IS NULL) ORDER BY c;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test
index 1e1150157c7..754677e9b37 100644
--- a/mysql-test/t/partition.test
+++ b/mysql-test/t/partition.test
@@ -2816,6 +2816,47 @@ select * from t1 IGNORE INDEX(dob, weeks_worked_last_year, hours_worked_per_week
drop table t1;
+--echo #
+--echo # MDEV-6322: The PARTITION engine can return wrong query results
+--echo #
+CREATE TABLE t1 (
+ CustomerID varchar(5) DEFAULT NULL,
+ CompanyName varchar(40) DEFAULT NULL,
+ ContactName varchar(30) DEFAULT NULL,
+ ContactTitle varchar(30) DEFAULT NULL,
+ Address varchar(60) DEFAULT NULL,
+ City varchar(15) DEFAULT NULL,
+ Region varchar(15) DEFAULT NULL,
+ PostalCode varchar(10) DEFAULT NULL,
+ Country varchar(15) NOT NULL,
+ Phone varchar(24) DEFAULT NULL,
+ Fax varchar(24) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+PARTITION BY LIST COLUMNS(Country)
+(PARTITION p1 VALUES IN ('Germany','Austria','Switzerland','Poland'),
+ PARTITION p2 VALUES IN ('USA','Canada','Mexico'),
+ PARTITION p3 VALUES IN ('Spain','Portugal','Italy'),
+ PARTITION p4 VALUES IN ('UK','Ireland'),
+ PARTITION p5 VALUES IN ('France','Belgium'),
+ PARTITION p6 VALUES IN ('Sweden','Finland','Denmark','Norway'),
+ PARTITION p7 VALUES IN ('Venezuela','Argentina','Brazil')
+);
+
+INSERT INTO t1 (CustomerID, City, Country) VALUES
+('ANATR','México D.F','Mexico'),
+('ANTON','México D.F','Mexico'),
+('BOTTM','Tsawassen','Canada'),
+('CENTC','México D.F','Mexico'),
+('GREAL','Eugene','USA'),
+('HUNGC','Elgin','USA'),
+('LAUGB','Vancouver','Canada'),
+('LAZYK','Walla Walla','USA'),
+('LETSS','San Francisco','USA'),
+('LONEP','Portland','USA');
+
+SELECT * FROM t1 WHERE Country = 'USA';
+DROP TABLE t1;
+
#
# Test ALTER TABLE ADD/DROP PARTITION IF EXISTS
#
diff --git a/mysql-test/t/partition_innodb.test b/mysql-test/t/partition_innodb.test
index 43f409731a6..1e2aacd474a 100644
--- a/mysql-test/t/partition_innodb.test
+++ b/mysql-test/t/partition_innodb.test
@@ -777,6 +777,34 @@ drop table t3;
drop table t1,t2;
--echo #
+--echo # MySQL Bug#71095: Wrong results with PARTITION BY LIST COLUMNS()
+--echo #
+create table t1(c1 int, c2 int, c3 int, c4 int,
+primary key(c1,c2)) engine=InnoDB
+partition by list columns(c2)
+(partition p1 values in (1,2) engine=InnoDB,
+partition p2 values in (3,4) engine=InnoDB);
+
+insert into t1 values (1,1,1,1),(2,3,1,1);
+select * from t1 where c1=2 and c2=3;
+drop table t1;
+
+--echo #
+--echo # MySQL Bug#72803: Wrong "Impossible where" with LIST partitioning
+--echo # also MDEV-6240: Wrong "Impossible where" with LIST partitioning
+--echo #
+CREATE TABLE t1 ( d DATE) ENGINE = InnoDB
+PARTITION BY LIST COLUMNS (d)
+(
+ PARTITION p0 VALUES IN ('1990-01-01','1991-01-01'),
+ PARTITION p1 VALUES IN ('1981-01-01')
+);
+
+INSERT INTO t1 (d) VALUES ('1991-01-01');
+SELECT * FROM t1 WHERE d = '1991-01-01';
+DROP TABLE t1;
+
+--echo #
--echo # MDEV-5963: InnoDB: Assertion failure in file row0sel.cc line 2503,
--echo # Failing assertion: 0 with "key ptr now exceeds key end by 762 bytes"
--echo # (independent testcase for Oracle Bug#13947868)
diff --git a/mysql-test/t/partition_pruning.test b/mysql-test/t/partition_pruning.test
index 4c97bab454d..06ef99e1e70 100644
--- a/mysql-test/t/partition_pruning.test
+++ b/mysql-test/t/partition_pruning.test
@@ -1414,6 +1414,54 @@ explain partitions select * from t1 where a between 10 and 10+33;
drop table t0, t1;
--echo #
+--echo # Bug#71095: Wrong results with PARTITION BY LIST COLUMNS()
+--echo #
+CREATE TABLE t1
+(c1 int,
+ c2 int,
+ c3 int,
+ c4 int,
+ PRIMARY KEY (c1,c2))
+PARTITION BY LIST COLUMNS (c2)
+(PARTITION p1 VALUES IN (1,2),
+ PARTITION p2 VALUES IN (3,4));
+INSERT INTO t1 VALUES (1, 1, 1, 1), (2, 3, 1, 1);
+INSERT INTO t1 VALUES (1, 2, 1, 1), (2, 4, 1, 1);
+SELECT * FROM t1 WHERE c1 = 1 AND c2 < 1;
+SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 1;
+SELECT * FROM t1 WHERE c1 = 1 AND c2 = 1;
+SELECT * FROM t1 WHERE c1 = 1 AND c2 >= 1;
+SELECT * FROM t1 WHERE c1 = 1 AND c2 > 1;
+SELECT * FROM t1 WHERE c1 = 1 AND c2 < 3;
+SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 3;
+SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 3;
+SELECT * FROM t1 WHERE c1 = 2 AND c2 = 3;
+SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 3;
+SELECT * FROM t1 WHERE c1 = 2 AND c2 > 3;
+SELECT * FROM t1 WHERE c1 = 2 AND c2 < 4;
+SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 4;
+SELECT * FROM t1 WHERE c1 = 2 AND c2 = 4;
+SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 4;
+SELECT * FROM t1 WHERE c1 = 2 AND c2 > 4;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 < 1;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 1;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 = 1;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 >= 1;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 > 1;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 < 3;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 3;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 3;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 = 3;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 3;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 > 3;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 < 4;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 4;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 = 4;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 4;
+EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 > 4;
+DROP TABLE t1;
+
+--echo #
--echo # MDEV-6239: Partition pruning is not working as expected in an inner query
--echo #
diff --git a/mysql-test/t/plugin_loaderr.test b/mysql-test/t/plugin_loaderr.test
index e319e2fb54d..7b98a94afd4 100644
--- a/mysql-test/t/plugin_loaderr.test
+++ b/mysql-test/t/plugin_loaderr.test
@@ -1,4 +1,6 @@
+--source include/not_embedded.inc
+
# We used an invalid command-line option and InnoDB failed to start.
# Ignore all related warnings
call mtr.add_suppression("InnoDB");
@@ -8,3 +10,17 @@ SELECT
PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE,PLUGIN_LIBRARY,PLUGIN_LIBRARY_VERSION,LOAD_OPTION
FROM INFORMATION_SCHEMA.PLUGINS WHERE plugin_name = 'innodb';
+--echo #
+--echo # MDEV-6351 --plugin=force has no effect for built-in plugins
+--echo #
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--shutdown_server
+--source include/wait_until_disconnected.inc
+
+--error 1
+--exec $MYSQLD_CMD --innodb=force --innodb-page-size=6000
+
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+--disable_reconnect
diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test
index 91b69a6a09c..912e9d5befd 100644
--- a/mysql-test/t/subselect_sj_mat.test
+++ b/mysql-test/t/subselect_sj_mat.test
@@ -1808,5 +1808,38 @@ EXECUTE stmt;
DROP TABLE t1, t2;
DROP VIEW v2;
+--echo #
+--echo # MDEV-6289 : Unexpected results when querying information_schema
+--echo #
+CREATE TABLE t1 (
+ id int(11) unsigned NOT NULL AUTO_INCREMENT,
+ db varchar(254) NOT NULL DEFAULT '',
+ PRIMARY KEY (id),
+ UNIQUE KEY db (db)
+) DEFAULT CHARSET=utf8;
+INSERT INTO t1 (db) VALUES ('mysqltest1'),('mysqltest2'),('mysqltest3'),('mysqltest4');
+
+--disable_warnings
+drop database if exists mysqltest1;
+drop database if exists mysqltest2;
+drop database if exists mysqltest3;
+drop database if exists mysqltest4;
+--enable_warnings
+create database mysqltest1;
+create database mysqltest2;
+create database mysqltest3;
+create database mysqltest4;
+
+SELECT db FROM t1 WHERE db IN (SELECT SCHEMA_NAME FROM information_schema.schemata) ORDER BY db DESC;
+
+EXPLAIN EXTENDED
+SELECT db FROM t1 WHERE db IN (SELECT SCHEMA_NAME FROM information_schema.schemata) ORDER BY db DESC;
+
+drop table t1;
+drop database mysqltest1;
+drop database mysqltest2;
+drop database mysqltest3;
+drop database mysqltest4;
+
--echo # End of 5.5 tests
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index 877509a9fc0..a5d7dae606f 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -1273,6 +1273,36 @@ SELECT(SELECT 1 AS a ORDER BY a) AS dev;
SELECT(SELECT 1 AS a LIMIT 1) AS dev;
SELECT(SELECT 1 AS a FROM dual ORDER BY a DESC LIMIT 1) AS dev;
+
+--echo #
+--echo # Bug #17059925 : UNIONS COMPUTES ROWS_EXAMINED INCORRECTLY
+--echo #
+
+## Save current state of slow log variables
+SET @old_slow_query_log= @@global.slow_query_log;
+SET @old_log_output= @@global.log_output;
+SET @old_long_query_time= @@long_query_time;
+SET GLOBAL log_output= "TABLE";
+SET GLOBAL slow_query_log= ON;
+SET SESSION long_query_time= 0;
+
+CREATE TABLE t17059925 (a INT);
+CREATE TABLE t2 (b INT);
+CREATE TABLE t3 (c INT);
+INSERT INTO t17059925 VALUES (1), (2), (3);
+INSERT INTO t2 VALUES (4), (5), (6);
+INSERT INTO t3 VALUES (7), (8), (9);
+TRUNCATE table mysql.slow_log;
+--sorted_result
+SELECT * FROM t17059925 UNION SELECT * FROM t2 UNION SELECT * FROM t3;
+SELECT sql_text, rows_examined FROM mysql.slow_log WHERE sql_text LIKE '%SELECT%t17059925%';
+DROP TABLE t17059925, t2, t3;
+
+## Reset to initial values
+SET @@long_query_time= @old_long_query_time;
+SET @@global.log_output= @old_log_output;
+SET @@global.slow_query_log= @old_slow_query_log;
+
--echo #
--echo # lp:1010729: Unexpected syntax error from UNION
--echo # (bug #54382) with single-table join nest
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index d1d4b936aba..6029ad471f6 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -4700,6 +4700,47 @@ DROP DATABASE IF EXISTS nodb;
--error ER_BAD_DB_ERROR
CREATE VIEW nodb.a AS SELECT 1;
+
+--echo #
+--echo # BUG#14117018 - MYSQL SERVER CREATES INVALID VIEW DEFINITION
+--echo # BUG#18405221 - SHOW CREATE VIEW OUTPUT INCORRECT
+--echo #
+
+CREATE VIEW v1 AS (SELECT '' FROM DUAL);
+CREATE VIEW v2 AS (SELECT 'BUG#14117018' AS col1 FROM DUAL) UNION ALL
+ (SELECT '' FROM DUAL);
+CREATE VIEW v3 AS (SELECT 'BUG#14117018' AS col1 FROM DUAL) UNION ALL
+ (SELECT '' FROM DUAL) UNION ALL
+ (SELECT '' FROM DUAL);
+CREATE VIEW v4 AS (SELECT 'BUG#14117018' AS col1 FROM DUAL) UNION ALL
+ (SELECT '' AS col2 FROM DUAL) UNION ALL
+ (SELECT '' FROM DUAL);
+
+# In the second (and later) UNIONed queries, duplicate column names are allowed
+CREATE VIEW v5 AS (SELECT 'buggy' AS col1, 'fix' as col2 FROM DUAL) UNION ALL
+ (SELECT 'buggy' as a, 'fix' as a FROM DUAL);
+
+--echo # Name for the column in select1 is set properly with or
+--echo # without this fix.
+SHOW CREATE VIEW v1;
+
+--echo # Name for the column in select2 is set with this fix.
+--echo # Without this fix, name would not have set for the
+--echo # columns in select2.
+SHOW CREATE VIEW v2;
+
+--echo # Name for the field item in select2 & select3 is set with this fix.
+--echo # Without this fix, name would not have set for the
+--echo # columns in select2 & select3.
+SHOW CREATE VIEW v3;
+
+--echo # Name for the field item in select3 is set with this fix.
+--echo # Without this fix, name would not have set for the
+--echo # columns in select3.
+SHOW CREATE VIEW v4;
+
+DROP VIEW v1, v2, v3, v4, v5;
+
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc
@@ -5231,6 +5272,69 @@ drop view v1;
drop table t1,t2,t3;
SET optimizer_switch=@save_optimizer_switch_MDEV_3874;
+#
+# MDEV-5515: sub-bug test of 3rd execution crash
+#
+
+CREATE TABLE `t1` (
+ `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ `f0` int(11) unsigned NOT NULL DEFAULT '0',
+ `f1` int(11) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `id` (`id`)
+);
+
+CREATE TABLE `t2` (
+ `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ `f02` bigint(20) unsigned NOT NULL DEFAULT '0',
+ `f03` int(11) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `id` (`id`)
+);
+
+CREATE ALGORITHM=UNDEFINED SQL SECURITY DEFINER VIEW `v1` AS
+ SELECT
+ `t1`.`f0` AS `f0`,
+ `t1`.`f1` AS `f1`,
+ `t2`.`f02` AS `f02`,
+ `t2`.`f03` AS `f03`
+ FROM
+ (`t1` LEFT JOIN `t2` ON((`t1`.`id` = `t2`.`f02`)));
+
+--delimiter |
+CREATE FUNCTION `f1`(
+ p0 BIGINT(20) UNSIGNED
+ )
+ RETURNS bigint(20) unsigned
+ DETERMINISTIC
+ CONTAINS SQL
+ SQL SECURITY DEFINER
+ COMMENT ''
+BEGIN
+
+DECLARE k0 INTEGER UNSIGNED DEFAULT 0;
+DECLARE lResult INTEGER UNSIGNED DEFAULT 0;
+
+ SET k0 = 0;
+ WHILE k0 < 1 DO
+ SELECT COUNT(*) as `f00` INTO lResult FROM `v1` WHERE `v1`.`f0` = p0; -- BUG
+ SET k0 = k0 + 1;
+ END WHILE;
+
+ RETURN(k0);
+END|
+--delimiter ;
+
+
+SELECT `f1`(1);
+SELECT `f1`(1);
+SELECT `f1`(1);
+SELECT `f1`(1);
+
+DROP FUNCTION f1;
+DROP VIEW v1;
+DROP TABLE t1, t2;
+
--echo # -----------------------------------------------------------------
--echo # -- End of 5.5 tests.
--echo # -----------------------------------------------------------------
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index f0d25dae6b9..4756bbccf2f 100644
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2013, Oracle and/or its affiliates
+# Copyright (c) 2006, 2014, Oracle and/or its affiliates
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -89,7 +89,6 @@ ADD_EXECUTABLE(thr_lock thr_lock.c)
TARGET_LINK_LIBRARIES(thr_lock mysys)
SET_TARGET_PROPERTIES(thr_lock PROPERTIES COMPILE_FLAGS "-DMAIN")
-INSTALL_DEBUG_SYMBOLS(mysys)
IF(MSVC)
INSTALL_DEBUG_TARGET(mysys DESTINATION ${INSTALL_LIBDIR}/debug)
ENDIF()
diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c
index 22def2e0923..06dfc9f2079 100644
--- a/mysys/mf_iocache2.c
+++ b/mysys/mf_iocache2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -456,6 +456,13 @@ process_flags:
goto err;
}
}
+ else if (*fmt == 'c') /* char type parameter */
+ {
+ char par[2];
+ par[0] = va_arg(args, int);
+ if (my_b_write(info, (uchar*) par, 1))
+ goto err;
+ }
else if (*fmt == 'b') /* Sized buffer parameter, only precision makes sense */
{
char *par = va_arg(args, char *);
diff --git a/packaging/rpm-oel/filter-requires.sh b/packaging/rpm-oel/filter-requires.sh
index 521eb0ca7d9..3fdf43870fa 100755
--- a/packaging/rpm-oel/filter-requires.sh
+++ b/packaging/rpm-oel/filter-requires.sh
@@ -2,5 +2,5 @@
#
/usr/lib/rpm/perl.req $* |
-sed -e '/perl(hostnames)/d' -e '/perl(lib::mtr.*/d' -e '/perl(lib::v1.*/d' -e '/perl(mtr_.*/d' -e '/perl(My::.*/d'
+sed -e '/perl(GD)/d' -e '/perl(hostnames)/d' -e '/perl(lib::mtr.*/d' -e '/perl(lib::v1.*/d' -e '/perl(mtr_.*/d' -e '/perl(My::.*/d'
diff --git a/packaging/rpm-oel/mysql.spec.in b/packaging/rpm-oel/mysql.spec.in
index d28e89b4216..ba57515678c 100644
--- a/packaging/rpm-oel/mysql.spec.in
+++ b/packaging/rpm-oel/mysql.spec.in
@@ -85,7 +85,7 @@ Name: mysql-%{product_suffix}
Summary: A very fast and reliable SQL database server
Group: Applications/Databases
Version: @VERSION@
-Release: 2%{?commercial:.1}%{?dist}
+Release: 4%{?commercial:.1}%{?dist}
License: Copyright (c) 2000, @MYSQL_COPYRIGHT_YEAR@, %{mysql_vendor}. All rights reserved. Under %{?license_type} license as shown in the Description field.
Source0: https://cdn.mysql.com/Downloads/MySQL-@MYSQL_BASE_VERSION@/%{src_dir}.tar.gz
URL: http://www.mysql.com/
@@ -118,7 +118,7 @@ BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
%if 0%{?rhel} > 6
# For rpm => 4.9 only: https://fedoraproject.org/wiki/Packaging:AutoProvidesAndRequiresFiltering
-%global __requires_exclude ^perl\\((hostnames|lib::mtr|lib::v1|mtr_|My::)
+%global __requires_exclude ^perl\\((GD|hostnames|lib::mtr|lib::v1|mtr_|My::)
%global __provides_exclude_from ^(/usr/share/(mysql|mysql-test)/.*|%{_libdir}/mysql/plugin/.*\\.so)$
%else
# https://fedoraproject.org/wiki/EPEL:Packaging#Generic_Filtering_on_EPEL6
@@ -166,6 +166,7 @@ Requires: mysql-community-common%{?_isa} = %{version}-%{release}
Obsoletes: MySQL-server < %{version}-%{release}
Obsoletes: mysql-server < %{version}-%{release}
Obsoletes: mariadb-server
+Obsoletes: mariadb-galera-server
Provides: mysql-server = %{version}-%{release}
Provides: mysql-server%{?_isa} = %{version}-%{release}
%if 0%{?systemd}
@@ -262,6 +263,25 @@ This package contains the MySQL regression test suite for MySQL
database server.
+%package bench
+Summary: MySQL benchmark suite
+Group: Applications/Databases
+%if 0%{?commercial}
+Obsoletes: mysql-community-bench < %{version}-%{release}
+Requires: mysql-enterprise-server%{?_isa} = %{version}-%{release}
+%else
+Requires: mysql-community-server%{?_isa} = %{version}-%{release}
+%endif
+Obsoletes: mariadb-bench
+Obsoletes: community-mysql-bench < %{version}-%{release}
+Obsoletes: mysql-bench < %{version}-%{release}
+Provides: mysql-bench = %{version}-%{release}
+Provides: mysql-bench%{?_isa} = %{version}-%{release}
+
+%description bench
+This package contains the MySQL Benchmark Suite for MySQL database
+server.
+
%package devel
Summary: Development header files and libraries for MySQL database client applications
Group: Applications/Databases
@@ -344,6 +364,7 @@ Requires: mysql-enterprise-common%{?_isa} = %{version}-%{release}
Provides: MySQL-embedded%{?_isa} = %{version}-%{release}
Requires: mysql-community-common%{?_isa} = %{version}-%{release}
%endif
+Obsoletes: mariadb-embedded
Obsoletes: MySQL-embedded < %{version}-%{release}
Obsoletes: mysql-embedded < %{version}-%{release}
Provides: mysql-embedded = %{version}-%{release}
@@ -372,6 +393,7 @@ Requires: mysql-enterprise-embedded%{?_isa} = %{version}-%{release}
Requires: mysql-community-devel%{?_isa} = %{version}-%{release}
Requires: mysql-community-embedded%{?_isa} = %{version}-%{release}
%endif
+Obsoletes: mariadb-embedded-devel
Obsoletes: mysql-embedded-devel < %{version}-%{release}
Provides: mysql-embedded-devel = %{version}-%{release}
Provides: mysql-embedded-devel%{?_isa} = %{version}-%{release}
@@ -472,11 +494,13 @@ mkdir debug
cmake ../%{src_dir} \
-DBUILD_CONFIG=mysql_release \
-DINSTALL_LAYOUT=RPM \
- -DCMAKE_BUILD_TYPE=Debug %{?el7:-DENABLE_DTRACE=OFF} \
+ -DCMAKE_BUILD_TYPE=Debug \
+ -DENABLE_DTRACE=OFF \
-DCMAKE_C_FLAGS="$optflags" \
-DCMAKE_CXX_FLAGS="$optflags" \
-DINSTALL_LIBDIR="%{_lib}/mysql" \
-DINSTALL_PLUGINDIR="%{_lib}/mysql/plugin" \
+ -DINSTALL_SQLBENCHDIR=share \
-DMYSQL_UNIX_ADDR="%{mysqldatadir}/mysql.sock" \
-DFEATURE_SET="%{feature_set}" \
-DWITH_EMBEDDED_SERVER=1 \
@@ -495,11 +519,13 @@ mkdir release
cmake ../%{src_dir} \
-DBUILD_CONFIG=mysql_release \
-DINSTALL_LAYOUT=RPM \
- -DCMAKE_BUILD_TYPE=RelWithDebInfo %{?el7:-DENABLE_DTRACE=OFF} \
+ -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+ -DENABLE_DTRACE=OFF \
-DCMAKE_C_FLAGS="%{optflags}" \
-DCMAKE_CXX_FLAGS="%{optflags}" \
-DINSTALL_LIBDIR="%{_lib}/mysql" \
-DINSTALL_PLUGINDIR="%{_lib}/mysql/plugin" \
+ -DINSTALL_SQLBENCHDIR=share \
-DMYSQL_UNIX_ADDR="%{mysqldatadir}/mysql.sock" \
-DFEATURE_SET="%{feature_set}" \
-DWITH_EMBEDDED_SERVER=1 \
@@ -862,6 +888,10 @@ fi
%attr(644, root, root) %{_mandir}/man1/mysql_client_test_embedded.1*
%attr(644, root, root) %{_mandir}/man1/mysqltest_embedded.1*
+%files bench
+%defattr(-, root, root, -)
+%{_datadir}/sql-bench
+
%files embedded
%defattr(-, root, root, -)
%dir %attr(755, root, root) %{_libdir}/mysql
@@ -881,6 +911,19 @@ fi
%endif
%changelog
+* Tue Jul 08 2014 Balasubramanian Kandasamy <balasubramanian.kandasamy@oracle.com> - 5.5.39-4
+- Remove perl(GD) and dtrace dependencies
+
+* Tue Jul 01 2014 Bjorn Munch <bjorn.munch@oracle.com> - 5.5.39-3
+- Disable dtrace, as it fails on OEL6 boxes with Oracle dtrace installed
+
+* Thu Jun 26 2014 Balasubramanian Kandasamy <balasubramanian.kandasamy@oracle.com> - 5.5.39-2
+- Resolve embedded-devel conflict issue
+
+* Wed Jun 25 2014 Balasubramanian Kandasamy <balasubramanian.kandasamy@oracle.com> - 5.5.39-1
+- Add bench package
+- Enable dtrace
+
* Sun May 11 2014 Balasubramanian Kandasamy <balasubramanian.kandasamy@oracle.com> - 5.5.38-2
- Increment release version to resolve upgrade conflict issue
diff --git a/packaging/rpm-uln/CMakeLists.txt b/packaging/rpm-uln/CMakeLists.txt
deleted file mode 100644
index c8f13379697..00000000000
--- a/packaging/rpm-uln/CMakeLists.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software 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-1301 USA
-
-
-IF(UNIX)
- SET(prefix ${CMAKE_INSTALL_PREFIX})
-
- SET(SPECFILENAME "mysql.${VERSION}.spec")
- IF("${VERSION}" MATCHES "-ndb-")
- STRING(REGEX REPLACE "^.*-ndb-" "" NDBVERSION "${VERSION}")
- SET(SPECFILENAME "mysql-cluster-${NDBVERSION}.spec")
- ENDIF()
-
- # Left in current directory, to be taken during build
- CONFIGURE_FILE(mysql.spec.sh ${CMAKE_CURRENT_BINARY_DIR}/${SPECFILENAME} @ONLY)
-
- FOREACH(ulnfile filter-requires-mysql.sh generate-tarball.sh my.cnf my_config.h
- mysql-5.5-errno.patch mysql-5.5-fix-tests.patch mysql-5.5-libdir.patch
- mysql-5.5-mtr1.patch mysql-5.5-stack-guard.patch mysql-5.5-testing.patch
- mysql-chain-certs.patch mysql-embedded-check.c mysql-expired-certs.patch
- mysql.init mysql-install-test.patch mysql-strmov.patch scriptstub.c
- README.mysql-docs)
- CONFIGURE_FILE(${ulnfile} ${CMAKE_CURRENT_BINARY_DIR}/${ulnfile} COPYONLY)
- ENDFOREACH()
-ENDIF()
-
diff --git a/packaging/rpm-uln/README-ULN b/packaging/rpm-uln/README-ULN
deleted file mode 100644
index 8ae44a18605..00000000000
--- a/packaging/rpm-uln/README-ULN
+++ /dev/null
@@ -1,15 +0,0 @@
-In order to have RPMs of MySQL which are distributed via ULN for Oracle Linux
-to be as closely compatible to such RPMs built and distributed by RedHat,
-this directory contains additional files which originated at RedHat
-and are used only for such RPMs intended for distribution via ULN.
-
-Especially, this directory contains the spec file used to build these RPMs,
-named "mysql.spec". Please regard the following note:
-
- You are receiving a copy of the Red Hat spec file.
- The terms of the Oracle license do NOT apply to the Red Hat spec file;
- it is licensed under the
- GNU GENERAL PUBLIC LICENSE Version 2, June 1991
- separately from the Oracle programs you receive.
-
-
diff --git a/packaging/rpm-uln/README.mysql-docs b/packaging/rpm-uln/README.mysql-docs
deleted file mode 100644
index dd894a7b9c0..00000000000
--- a/packaging/rpm-uln/README.mysql-docs
+++ /dev/null
@@ -1,4 +0,0 @@
-The official MySQL documentation is not freely redistributable, so we cannot
-include it in RHEL or Fedora. You can find it on-line at
-
-http://dev.mysql.com/doc/
diff --git a/packaging/rpm-uln/filter-requires-mysql.sh b/packaging/rpm-uln/filter-requires-mysql.sh
deleted file mode 100755
index d435062b8dc..00000000000
--- a/packaging/rpm-uln/filter-requires-mysql.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-/usr/lib/rpm/perl.req $* | grep -v -e "perl(th" -e "perl(lib::mtr" -e "perl(mtr"
diff --git a/packaging/rpm-uln/generate-tarball.sh b/packaging/rpm-uln/generate-tarball.sh
deleted file mode 100755
index 2ff4bff2349..00000000000
--- a/packaging/rpm-uln/generate-tarball.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-VERSION=$1
-
-rm -rf mysql-$VERSION
-
-tar xfz mysql-$VERSION.tar.gz || exit 1
-
-rm mysql-$VERSION/Docs/mysql.info
-
-tar cfz mysql-$VERSION-nodocs.tar.gz mysql-$VERSION || exit 1
-
-rm -rf mysql-$VERSION
-
-exit 0
diff --git a/packaging/rpm-uln/my.cnf b/packaging/rpm-uln/my.cnf
deleted file mode 100644
index fae0fa276e1..00000000000
--- a/packaging/rpm-uln/my.cnf
+++ /dev/null
@@ -1,10 +0,0 @@
-[mysqld]
-datadir=/var/lib/mysql
-socket=/var/lib/mysql/mysql.sock
-user=mysql
-# Disabling symbolic-links is recommended to prevent assorted security risks
-symbolic-links=0
-
-[mysqld_safe]
-log-error=/var/log/mysqld.log
-pid-file=/var/run/mysqld/mysqld.pid
diff --git a/packaging/rpm-uln/my_config.h b/packaging/rpm-uln/my_config.h
deleted file mode 100644
index 435a126ac97..00000000000
--- a/packaging/rpm-uln/my_config.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Kluge to support multilib installation of both 32- and 64-bit RPMS:
- * we need to arrange that header files that appear in both RPMs are
- * identical. Hence, this file is architecture-independent and calls
- * in an arch-dependent file that will appear in just one RPM.
- *
- * To avoid breaking arches not explicitly supported by Red Hat, we
- * use this indirection file *only* on known multilib arches.
- *
- * Note: this may well fail if user tries to use gcc's -I- option.
- * But that option is deprecated anyway.
- */
-#if defined(__x86_64__)
-#include "my_config_x86_64.h"
-#elif defined(__i386__)
-#include "my_config_i386.h"
-#elif defined(__ppc64__) || defined(__powerpc64__)
-#include "my_config_ppc64.h"
-#elif defined(__ppc__) || defined(__powerpc__)
-#include "my_config_ppc.h"
-#elif defined(__s390x__)
-#include "my_config_s390x.h"
-#elif defined(__s390__)
-#include "my_config_s390.h"
-#elif defined(__sparc__) && defined(__arch64__)
-#include "my_config_sparc64.h"
-#elif defined(__sparc__)
-#include "my_config_sparc.h"
-#endif
diff --git a/packaging/rpm-uln/mysql-5.5-errno.patch b/packaging/rpm-uln/mysql-5.5-errno.patch
deleted file mode 100644
index 033e5195973..00000000000
--- a/packaging/rpm-uln/mysql-5.5-errno.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-"extern int errno" is just a really bad idea.
-
-
-diff -Naur mysql-5.1.32.orig/include/my_sys.h mysql-5.1.32/include/my_sys.h
---- mysql-5.1.32.orig/include/my_sys.h 2009-02-13 19:52:19.000000000 -0500
-+++ mysql-5.1.32/include/my_sys.h 2009-03-04 18:08:40.000000000 -0500
-@@ -199,13 +199,8 @@
- #define my_afree(PTR) my_free(PTR)
- #endif /* HAVE_ALLOCA */
-
--#ifndef errno /* did we already get it? */
--#ifdef HAVE_ERRNO_AS_DEFINE
- #include <errno.h> /* errno is a define */
--#else
--extern int errno; /* declare errno */
--#endif
--#endif /* #ifndef errno */
-+
- extern char *home_dir; /* Home directory for user */
- extern const char *my_progname; /* program-name (printed in errors) */
- extern char curr_dir[]; /* Current directory for user */
diff --git a/packaging/rpm-uln/mysql-5.5-fix-tests.patch b/packaging/rpm-uln/mysql-5.5-fix-tests.patch
deleted file mode 100644
index a1ab7a82210..00000000000
--- a/packaging/rpm-uln/mysql-5.5-fix-tests.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-Adapt tests (where needed) to RedHat conventions.
-
-1) The RedHat convention uses the package name "mysql*" whereas upstream uses "MySQL*".
- Test "file_contents" constructs path names and needs to be adapted.
-
-=== modified file 'mysql-test/t/file_contents.test'
---- mysql-5.5.17-orig/mysql-test/t/file_contents.test 2011-10-10 12:03:29 +0000
-+++ mysql-5.5.17/mysql-test/t/file_contents.test 2011-11-16 18:07:55 +0000
-@@ -17,20 +17,20 @@ if ($dir_bin =~ m|/usr/|) {
- $dir_docs =~ s|/lib|/share/doc|;
- if(-d "$dir_docs/packages") {
- # SuSE: "packages/" in the documentation path
-- $dir_docs = glob "$dir_docs/packages/MySQL-server*";
-+ $dir_docs = glob "$dir_docs/packages/mysql-server*";
- } else {
- # RedHat: version number in directory name
-- $dir_docs = glob "$dir_docs/MySQL-server*";
-+ $dir_docs = glob "$dir_docs/mysql-server*";
- }
- } elsif ($dir_bin =~ m|/usr$|) {
- # RPM build during development
- $dir_docs = "$dir_bin/share/doc";
- if(-d "$dir_docs/packages") {
- # SuSE: "packages/" in the documentation path
-- $dir_docs = glob "$dir_docs/packages/MySQL-server*";
-+ $dir_docs = glob "$dir_docs/packages/mysql-server*";
- } else {
- # RedHat: version number in directory name
-- $dir_docs = glob "$dir_docs/MySQL-server*";
-+ $dir_docs = glob "$dir_docs/mysql-server*";
- }
- } else {
- # tar.gz package, Windows, or developer work (in BZR)
-
diff --git a/packaging/rpm-uln/mysql-5.5-libdir.patch b/packaging/rpm-uln/mysql-5.5-libdir.patch
deleted file mode 100644
index 2ab3e9eec27..00000000000
--- a/packaging/rpm-uln/mysql-5.5-libdir.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-The RPMs built by MySQL AB (-> Sun -> Oracle) put the libraries into "/usr/lib".
-Those built by RedHat put them into "/usr/lib/mysql".
-This patch is to modify the cmake files to follow the RedHat convention.
-Similar, the server is now in "/usr/libexec" (formerly "/usr/sbin").
-
-
-diff -Naur mysql-5.5.17.orig/cmake/install_layout.cmake mysql-5.5.17/cmake/install_layout.cmake
---- mysql-5.5.17.orig/cmake/install_layout.cmake 2011-06-30 15:46:53 +0000
-+++ mysql-5.5.17/cmake/install_layout.cmake 2011-10-27 16:40:10 +0000
-@@ -140,14 +140,14 @@ SET(INSTALL_SBINDIR_RPM
- # be applied at build time via "rpmbuild".
- #
- SET(INSTALL_BINDIR_RPM "bin")
--SET(INSTALL_SBINDIR_RPM "sbin")
-+SET(INSTALL_SBINDIR_RPM "libexec")
- SET(INSTALL_SCRIPTDIR_RPM "bin")
- #
- IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
-- SET(INSTALL_LIBDIR_RPM "lib64")
-+ SET(INSTALL_LIBDIR_RPM "lib64/mysql")
- SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
- ELSE()
-- SET(INSTALL_LIBDIR_RPM "lib")
-+ SET(INSTALL_LIBDIR_RPM "lib/mysql")
- SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
- ENDIF()
- #
-
diff --git a/packaging/rpm-uln/mysql-5.5-mtr1.patch b/packaging/rpm-uln/mysql-5.5-mtr1.patch
deleted file mode 100644
index 7a7dc85f16c..00000000000
--- a/packaging/rpm-uln/mysql-5.5-mtr1.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-Drop support for version 1 of "mysql-test-run.pl" from the RPMs:
-
-1) The auto-generation of Perl dependencies will mishandle that code,
- probably because its run directory differs from its storage location.
-2) It does not provide several variables which are used in tests of MySQL 5.5
-
-If you really need it, take it from the source tarball.
-
-=== modified file 'mysql-test/mysql-test-run.pl'
---- mysql-5.5.17-orig/mysql-test/mysql-test-run.pl 2011-10-03 11:16:40 +0000
-+++ mysql-5.5.17/mysql-test/mysql-test-run.pl 2011-11-16 19:06:38 +0000
-@@ -58,10 +58,9 @@ BEGIN {
- if ( $version == 1 )
- {
- print "=======================================================\n";
-- print " WARNING: Using mysql-test-run.pl version 1! \n";
-+ print " ERROR: Support for version 1 is dropped in this distribution! \n";
- print "=======================================================\n";
-- # Should use exec() here on *nix but this appears not to work on Windows
-- exit(system($^X, "lib/v1/mysql-test-run.pl", @ARGV) >> 8);
-+ exit(1);
- }
- elsif ( $version == 2 )
- {
-
diff --git a/packaging/rpm-uln/mysql-5.5-stack-guard.patch b/packaging/rpm-uln/mysql-5.5-stack-guard.patch
deleted file mode 100644
index b2624d982de..00000000000
--- a/packaging/rpm-uln/mysql-5.5-stack-guard.patch
+++ /dev/null
@@ -1,140 +0,0 @@
-mysql is not accounting for the "guard page" when setting thread stack size
-requests. This is fatal on PPC systems, which may use guard pages as large
-as 64K. This patch also documents the IA64 situation a bit better.
-
-Note: there are quite a few other setstacksize calls besides the two in
-mysqld.cc; is it important to fix any of the others?
-
-Filed upstream at http://bugs.mysql.com/bug.php?id=35019
-
-
-diff -Naur mysql-5.1.30.orig/sql/mysqld.cc mysql-5.1.30/sql/mysqld.cc
---- mysql-5.1.30.orig/sql/mysqld.cc 2008-11-14 11:37:13.000000000 -0500
-+++ mysql-5.1.30/sql/mysqld.cc 2009-01-13 12:08:35.000000000 -0500
-@@ -2653,6 +2653,70 @@
- }
-
-
-+/* pthread_attr_setstacksize without so much platform-dependency */
-+/* returns the actual stack size if possible */
-+static size_t my_setstacksize(pthread_attr_t *attr, size_t stacksize)
-+{
-+ size_t guard_size = 0;
-+
-+#if defined(__ia64__) || defined(__ia64)
-+ /*
-+ On IA64, half of the requested stack size is used for "normal stack"
-+ and half for "register stack". The space measured by check_stack_overrun
-+ is the "normal stack", so double the request to make sure we have the
-+ caller-expected amount of normal stack.
-+
-+ NOTE: there is no guarantee that the register stack can't grow faster
-+ than normal stack, so it's very unclear that we won't dump core due to
-+ stack overrun despite check_stack_overrun's efforts. Experimentation
-+ shows that in the execution_constants test, the register stack grows
-+ less than half as fast as normal stack, but perhaps other scenarios are
-+ less forgiving. If it turns out that more space is needed for the
-+ register stack, that could be forced (rather inefficiently) by using a
-+ multiplier higher than 2 here.
-+ */
-+ stacksize *= 2;
-+#endif
-+
-+ /*
-+ On many machines, the "guard space" is subtracted from the requested
-+ stack size, and that space is quite large on some platforms. So add
-+ it to our request, if we can find out what it is.
-+
-+ FIXME: autoconfiscate use of pthread_attr_getguardsize
-+ */
-+ if (pthread_attr_getguardsize(attr, &guard_size))
-+ guard_size = 0; /* if can't find it out, treat as 0 */
-+
-+ pthread_attr_setstacksize(attr, stacksize + guard_size);
-+
-+ /* Retrieve actual stack size if possible */
-+#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
-+ {
-+ size_t real_stack_size= 0;
-+ /* We must ignore real_stack_size = 0 as Solaris 2.9 can return 0 here */
-+ if (pthread_attr_getstacksize(attr, &real_stack_size) == 0 &&
-+ real_stack_size > guard_size)
-+ {
-+ real_stack_size -= guard_size;
-+ if (real_stack_size < stacksize)
-+ {
-+ if (global_system_variables.log_warnings)
-+ sql_print_warning("Asked for %ld thread stack, but got %ld",
-+ (long) stacksize, (long) real_stack_size);
-+ stacksize= real_stack_size;
-+ }
-+ }
-+ }
-+#endif
-+
-+#if defined(__ia64__) || defined(__ia64)
-+ stacksize /= 2;
-+#endif
-+ return stacksize;
-+}
-+
-+
- static void start_signal_handler(void)
- {
- int error;
-@@ -2663,15 +2727,7 @@
- #if !defined(HAVE_DEC_3_2_THREADS)
- pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
- (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
--#if defined(__ia64__) || defined(__ia64)
-- /*
-- Peculiar things with ia64 platforms - it seems we only have half the
-- stack size in reality, so we have to double it here
-- */
-- pthread_attr_setstacksize(&thr_attr,my_thread_stack_size*2);
--#else
-- pthread_attr_setstacksize(&thr_attr,my_thread_stack_size);
--#endif
-+ (void) my_setstacksize(&thr_attr,my_thread_stack_size);
- #endif
-
- mysql_mutex_lock(&LOCK_thread_count);
-@@ -4445,37 +4501,7 @@
- unireg_abort(1); // Will do exit
-
- init_signals();
--#if defined(__ia64__) || defined(__ia64)
-- /*
-- Peculiar things with ia64 platforms - it seems we only have half the
-- stack size in reality, so we have to double it here
-- */
-- pthread_attr_setstacksize(&connection_attrib,my_thread_stack_size*2);
--#else
-- pthread_attr_setstacksize(&connection_attrib,my_thread_stack_size);
--#endif
--#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
-- {
-- /* Retrieve used stack size; Needed for checking stack overflows */
-- size_t stack_size= 0;
-- pthread_attr_getstacksize(&connection_attrib, &stack_size);
--#if defined(__ia64__) || defined(__ia64)
-- stack_size/= 2;
--#endif
-- /* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */
-- if (stack_size && stack_size < my_thread_stack_size)
-- {
-- if (global_system_variables.log_warnings)
-- sql_print_warning("Asked for %lu thread stack, but got %ld",
-- my_thread_stack_size, (long) stack_size);
--#if defined(__ia64__) || defined(__ia64)
-- my_thread_stack_size= stack_size*2;
--#else
-- my_thread_stack_size= stack_size;
--#endif
-- }
-- }
--#endif
-+ my_thread_stack_size = my_setstacksize(&connection_attrib,my_thread_stack_size);
-
- (void) thr_setconcurrency(concurrency); // 10 by default
-
diff --git a/packaging/rpm-uln/mysql-5.5-testing.patch b/packaging/rpm-uln/mysql-5.5-testing.patch
deleted file mode 100644
index 74387135346..00000000000
--- a/packaging/rpm-uln/mysql-5.5-testing.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-Hack the top-level Makefile to enable the openssl regression tests.
-(Why doesn't this happen automatically given the configure option??)
-
-Also, increase the overall timeout for the regression tests to 12 hours,
-because on a slow or heavily-loaded build machine sometimes the default of
-5 hours isn't enough. (This has been demonstrated to fail in mass-rebuild
-scenarios, which aren't that uncommon for Fedora.) Similarly increase the
-per-testcase timeout to 30 minutes, since the default of 15 hasn't got a
-great deal of headroom either.
-
-
-diff -Naur mysql-5.1.32.orig/Makefile.am mysql-5.1.32/Makefile.am
---- mysql-5.1.32.orig/Makefile.am 2009-02-13 19:51:56.000000000 -0500
-+++ mysql-5.1.32/Makefile.am 2009-03-04 18:12:36.000000000 -0500
-@@ -98,7 +98,7 @@
-
- test-ns:
- cd mysql-test ; \
-- @PERL@ ./mysql-test-run.pl $(force) $(mem) --mysqld=--binlog-format=mixed
-+ @PERL@ ./mysql-test-run.pl $(force) $(mem) --ssl --mysqld=--binlog-format=mixed --suite-timeout=720 --testcase-timeout=30
-
- test-binlog-statement:
- cd mysql-test ; \
diff --git a/packaging/rpm-uln/mysql-chain-certs.patch b/packaging/rpm-uln/mysql-chain-certs.patch
deleted file mode 100644
index 4e26af16cb0..00000000000
--- a/packaging/rpm-uln/mysql-chain-certs.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-Fix things so that chains of certificates work in the server and client
-certificate files.
-
-This only really works for OpenSSL-based builds, as yassl is unable to read
-multiple certificates from a file. The patch below to yassl/src/ssl.cpp
-doesn't fix that, but just arranges that the viosslfactories.c patch won't
-have any ill effects in a yassl build. Since we don't use yassl in Red Hat/
-Fedora builds, I'm not feeling motivated to try to fix yassl for this.
-
-See RH bug #598656. Filed upstream at http://bugs.mysql.com/bug.php?id=54158
-
- ===
-
-Joerg Bruehe, MySQL Build Team at Oracle: First patch adapted to code changes in MySQL 5.5
-
-
-diff -Naur mysql-5.5.29.orig/vio/viosslfactories.c mysql-5.5.29/vio/viosslfactories.c
---- mysql-5.5.29.orig/vio/viosslfactories.c 2010-05-06 11:28:07.000000000 -0400
-+++ mysql-5.5.29/vio/viosslfactories.c 2010-05-26 23:23:46.000000000 -0400
-@@ -106,7 +106,7 @@
- key_file= cert_file;
-
- if (cert_file &&
-- SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0)
-+ SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0)
- {
- *error= SSL_INITERR_CERT;
- DBUG_PRINT("error",("%s from file '%s'", sslGetErrString(*error), cert_file));
-diff -Naur mysql-5.1.47.orig/extra/yassl/src/ssl.cpp mysql-5.1.47/extra/yassl/src/ssl.cpp
---- mysql-5.1.47.orig/extra/yassl/src/ssl.cpp 2010-05-06 11:24:26.000000000 -0400
-+++ mysql-5.1.47/extra/yassl/src/ssl.cpp 2010-05-26 23:29:13.000000000 -0400
-@@ -1606,10 +1606,10 @@
- }
-
-
-- int SSL_CTX_use_certificate_chain_file(SSL_CTX*, const char*)
-+ int SSL_CTX_use_certificate_chain_file(SSL_CTX* ctx, const char* file)
- {
-- // TDOD:
-- return SSL_SUCCESS;
-+ // For the moment, treat like use_certificate_file
-+ return read_file(ctx, file, SSL_FILETYPE_PEM, Cert);
- }
-
-
diff --git a/packaging/rpm-uln/mysql-embedded-check.c b/packaging/rpm-uln/mysql-embedded-check.c
deleted file mode 100644
index 8bf8ca53dad..00000000000
--- a/packaging/rpm-uln/mysql-embedded-check.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* simple test program to see if we can link the embedded server library */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-#include "mysql.h"
-
-MYSQL *mysql;
-
-static char *server_options[] = \
- { "mysql_test", "--defaults-file=my.cnf", NULL };
-int num_elements = (sizeof(server_options) / sizeof(char *)) - 1;
-
-static char *server_groups[] = { "libmysqld_server",
- "libmysqld_client", NULL };
-
-int main(int argc, char **argv)
-{
- mysql_library_init(num_elements, server_options, server_groups);
- mysql = mysql_init(NULL);
- mysql_close(mysql);
- mysql_library_end();
-
- return 0;
-}
diff --git a/packaging/rpm-uln/mysql-expired-certs.patch b/packaging/rpm-uln/mysql-expired-certs.patch
deleted file mode 100644
index acd3a78cce7..00000000000
--- a/packaging/rpm-uln/mysql-expired-certs.patch
+++ /dev/null
@@ -1,555 +0,0 @@
-Upstream insists on generating SSL testing certificates with relatively short
-lifespan, which has repeatedly caused problems (ie, one day the regression
-tests suddenly stop working). Replace them with certificates with 20-year
-lifespan. We should periodically regenerate these, too, but at least not
-very often.
-
-
-diff -Naur mysql-5.1.50.orig/mysql-test/std_data/cacert.pem mysql-5.1.50/mysql-test/std_data/cacert.pem
---- mysql-5.1.50.orig/mysql-test/std_data/cacert.pem 2010-08-03 13:55:04.000000000 -0400
-+++ mysql-5.1.50/mysql-test/std_data/cacert.pem 2010-08-27 23:42:05.751428144 -0400
-@@ -1,17 +1,22 @@
- -----BEGIN CERTIFICATE-----
--MIICrTCCAhagAwIBAgIJAMI7xZKjhrDbMA0GCSqGSIb3DQEBBAUAMEQxCzAJBgNV
-+MIIDsjCCApqgAwIBAgIJAL5YrUwfPSWVMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
- BAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxhMREwDwYD
--VQQKEwhNeVNRTCBBQjAeFw0xMDAxMjkxMTQ3MTBaFw0xNTAxMjgxMTQ3MTBaMEQx
-+VQQKEwhNeVNRTCBBQjAeFw0xMDAxMjkwNTU5NTNaFw0xNTAxMjgwNTU5NTNaMEQx
- CzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxh
--MREwDwYDVQQKEwhNeVNRTCBBQjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
--wQYsOEfrN4ESP3FjsI8cghE+tZVuyK2gck61lwieVxjgFMtBd65mI5a1y9pmlOI1
--yM4SB2Ppqcuw7/e1CdV1y7lvHrGNt5yqEHbN4QX1gvsN8TQauP/2WILturk4R4Hq
--rKg0ZySu7f1Xhl0ed9a48LpaEHD17IcxWEGMMJwAxF0CAwEAAaOBpjCBozAMBgNV
--HRMEBTADAQH/MB0GA1UdDgQWBBSvktYQ0ahLnyxyVKqty+WpBbBrDTB0BgNVHSME
--bTBrgBSvktYQ0ahLnyxyVKqty+WpBbBrDaFIpEYwRDELMAkGA1UEBhMCU0UxEDAO
--BgNVBAgTB1VwcHNhbGExEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FM
--IEFCggkAwjvFkqOGsNswDQYJKoZIhvcNAQEEBQADgYEAdKN1PjwMHAKG2Ww1145g
--JQGBnKxSFOUaoSvkBi/4ntTM+ysnViWh7WvxyWjR9zU9arfr7aqsDeQxm0XDOqzj
--AQ/cQIla2/Li8tXyfc06bisH/IHRaSc2zWqioTKbEwMdVOdrvq4a8V8ic3xYyIWn
--7F4WeS07J8LKardSvM0+hOA=
-+MREwDwYDVQQKEwhNeVNRTCBBQjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-+ggEBAL6kNN4peX7uhK9rb06W/QbPEpVuejmdWdl2PqMshP/eSuXXw7kwVgfpxx9R
-+vC000CKQQSG9MCoZjtqPnFRsetmWLZgApRpEalGXTXJqq9sEbCfoFizg94U8G7d2
-+u5XJjLVmcG34ru36KoBgVx1zeH1puBAf8dOzrE4L7Y+ZQBFzFohjh8C2LqWC4nM5
-+qsLmOkDWMipGqYU5DvkKjIbTbwTyRNRgZHWSPfVDDPUIUOsY4BGUp2DpgeGY9aEv
-+lIs57Ev9JqlIUCV65lOhhDkG+xwmkHKHA+ECEU9cALI8+uXbh48MB9XpMOuk408X
-+/lX89aZwD0/G9kmObVGnE2G+H5UCAwEAAaOBpjCBozAdBgNVHQ4EFgQUsft+d7VA
-+jWgRftkR5cPG2k2sUbAwdAYDVR0jBG0wa4AUsft+d7VAjWgRftkR5cPG2k2sUbCh
-+SKRGMEQxCzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdV
-+cHBzYWxhMREwDwYDVQQKEwhNeVNRTCBBQoIJAL5YrUwfPSWVMAwGA1UdEwQFMAMB
-+Af8wDQYJKoZIhvcNAQEFBQADggEBALRUOAmdL8R8sl1y8kiEiFgDatdXK5RDqWai
-+8yZChfmwTIToHhmQsOEshJe2e8hky3huUj+33VyXjINoMbebIwMuXPwEkbJal8RZ
-+nSJmF0jN1Qz7J/jFffwK9xmejWZJx49Kt2+Qwrwp6kDeq9TLFqQOoVczgyJPYsTL
-+NAOib5WqTud3XWvCwxrhqmWu7JZq6sp1fomP/uunprb8y2miWfLESZN2mKAhm44Q
-+Lws867LT8v2lskEjq2dT1LutD5+R66XcdjgSr0uDziDs64jZwCD6ea94hVFM7ej0
-+ZOXYeSEZJ56FjUxu632e9fY8NyMh30yKjjmQf1mM9PuGJvdvsWU=
- -----END CERTIFICATE-----
-diff -Naur mysql-5.1.50.orig/mysql-test/std_data/client-cert.pem mysql-5.1.50/mysql-test/std_data/client-cert.pem
---- mysql-5.1.50.orig/mysql-test/std_data/client-cert.pem 2010-08-03 13:55:04.000000000 -0400
-+++ mysql-5.1.50/mysql-test/std_data/client-cert.pem 2010-08-27 23:42:05.752428395 -0400
-@@ -1,46 +1,69 @@
- Certificate:
- Data:
-- Version: 1 (0x0)
-- Serial Number: 1048577 (0x100001)
-- Signature Algorithm: md5WithRSAEncryption
-+ Version: 3 (0x2)
-+ Serial Number: 6 (0x6)
-+ Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB
- Validity
-- Not Before: Jan 29 11:50:22 2010 GMT
-- Not After : Jan 28 11:50:22 2015 GMT
-+ Not Before: Feb 20 03:03:26 2010 GMT
-+ Not After : Sep 3 03:03:26 2030 GMT
- Subject: C=SE, ST=Uppsala, O=MySQL AB
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
-- Public-Key: (1024 bit)
-- Modulus:
-- 00:cc:9a:37:49:13:66:dc:cf:e3:0b:13:a1:23:ed:
-- 78:db:4e:bd:11:f6:8c:0d:76:f9:a3:32:56:9a:f8:
-- a1:21:6a:55:4e:4d:3f:e6:67:9d:26:99:b2:cd:a4:
-- 9a:d2:2b:59:5c:d7:8a:d3:60:68:f8:18:bd:c5:be:
-- 15:e1:2a:3c:a3:d4:61:cb:f5:11:94:17:81:81:f7:
-- 87:8c:f6:6a:d2:ee:d8:e6:77:f6:62:66:4d:2e:16:
-- 8d:08:81:4a:c9:c6:4b:31:e5:b9:c7:8a:84:96:48:
-- a7:47:8c:0d:26:90:56:4e:e6:a5:6e:8c:b3:f2:9f:
-- fc:3d:78:9b:49:6e:86:83:77
-+ RSA Public Key: (1024 bit)
-+ Modulus (1024 bit):
-+ 00:c2:e7:20:cf:89:59:2f:67:cb:4c:9f:e8:11:f2:
-+ 23:e5:f1:b1:ee:3f:66:5f:c3:f5:fd:1e:31:ee:8f:
-+ 4c:2a:bd:c0:4a:a5:9f:c8:44:d5:77:8f:15:1b:4d:
-+ 78:6e:b2:a2:48:a5:24:33:05:40:02:b3:c1:87:8d:
-+ 59:3c:1a:07:aa:86:f0:04:e1:9c:20:4b:22:32:c4:
-+ 51:9e:40:e4:31:c3:57:f5:98:bf:2e:b1:fd:2c:56:
-+ bf:49:d9:9b:e7:17:cc:95:5f:b5:08:19:5e:9d:df:
-+ 65:22:39:2c:48:fb:69:96:31:7a:35:4d:de:60:b4:
-+ c1:60:19:5f:96:56:7e:55:19
- Exponent: 65537 (0x10001)
-- Signature Algorithm: md5WithRSAEncryption
-- 5e:1f:a3:53:5f:24:13:1c:f8:28:32:b0:7f:69:69:f3:0e:c0:
-- 34:87:10:03:7d:da:15:8b:bd:19:b8:1a:56:31:e7:85:49:81:
-- c9:7f:45:20:74:3e:89:c0:e0:26:84:51:cc:04:16:ce:69:99:
-- 01:e1:26:99:b3:e3:f5:bd:ec:5f:a0:84:e4:38:da:75:78:7b:
-- 89:9c:d2:cd:60:95:20:ba:8e:e3:7c:e6:df:76:3a:7c:89:77:
-- 02:94:86:11:3a:c4:61:7d:6f:71:83:21:8a:17:fb:17:e2:ee:
-- 02:6b:61:c1:b4:52:63:d7:d8:46:b2:c5:9c:6f:38:91:8a:35:
-- 32:0b
-+ X509v3 extensions:
-+ X509v3 Basic Constraints:
-+ CA:FALSE
-+ X509v3 Subject Key Identifier:
-+ 8D:10:67:91:33:76:9C:02:E5:78:5D:D8:C5:EF:25:96:B2:D7:FA:1F
-+ X509v3 Authority Key Identifier:
-+ keyid:B1:FB:7E:77:B5:40:8D:68:11:7E:D9:11:E5:C3:C6:DA:4D:AC:51:B0
-+ DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB
-+ serial:BE:58:AD:4C:1F:3D:25:95
-+
-+ Signature Algorithm: sha1WithRSAEncryption
-+ a9:88:10:3e:5d:2a:47:29:c8:03:27:7a:31:5a:8e:10:03:bc:
-+ b5:4e:37:1d:12:7b:eb:5f:50:71:70:b1:a3:8e:93:0e:77:17:
-+ 6c:47:b6:c9:a4:4d:2a:c4:38:f0:61:55:b2:7f:28:ba:06:79:
-+ ee:67:11:7d:d4:c9:7f:0a:18:c8:c1:cb:d0:2c:f9:63:0f:bb:
-+ 45:ca:de:ea:bb:ac:00:01:52:48:36:2b:07:2b:c8:46:c7:b1:
-+ 21:81:bd:77:39:e7:4c:39:aa:bd:ac:60:d8:a7:bf:cf:14:98:
-+ 4a:0b:a1:40:55:06:8d:6f:35:a9:39:a0:71:a9:97:ba:7c:73:
-+ 3c:41:ba:c5:1c:11:4b:2b:43:1d:2d:ba:7b:5f:14:b5:3d:64:
-+ 62:15:36:b4:16:bd:78:c8:43:8d:f9:1c:a5:d2:ac:a1:58:74:
-+ e1:99:de:ad:04:19:43:a8:bd:0a:fd:19:9b:50:44:46:6d:18:
-+ 55:4d:bf:b4:5b:a4:93:62:c7:64:91:6c:54:34:d1:f8:f3:ff:
-+ 12:6d:5f:85:e7:35:9e:5c:42:81:5e:fb:c8:bb:44:51:98:b2:
-+ ef:1b:9f:5a:22:77:28:7d:da:fb:08:c2:94:9a:0f:42:08:93:
-+ 54:10:1e:ad:f2:4f:fc:62:98:51:e9:9b:b9:3a:93:d9:e4:1f:
-+ 1d:c4:76:d0
- -----BEGIN CERTIFICATE-----
--MIIB5zCCAVACAxAAATANBgkqhkiG9w0BAQQFADBEMQswCQYDVQQGEwJTRTEQMA4G
--A1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwg
--QUIwHhcNMTAwMTI5MTE1MDIyWhcNMTUwMTI4MTE1MDIyWjAyMQswCQYDVQQGEwJT
--RTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIwgZ8wDQYJKoZI
--hvcNAQEBBQADgY0AMIGJAoGBAMyaN0kTZtzP4wsToSPteNtOvRH2jA12+aMyVpr4
--oSFqVU5NP+ZnnSaZss2kmtIrWVzXitNgaPgYvcW+FeEqPKPUYcv1EZQXgYH3h4z2
--atLu2OZ39mJmTS4WjQiBSsnGSzHluceKhJZIp0eMDSaQVk7mpW6Ms/Kf/D14m0lu
--hoN3AgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAXh+jU18kExz4KDKwf2lp8w7ANIcQ
--A33aFYu9GbgaVjHnhUmByX9FIHQ+icDgJoRRzAQWzmmZAeEmmbPj9b3sX6CE5Dja
--dXh7iZzSzWCVILqO43zm33Y6fIl3ApSGETrEYX1vcYMhihf7F+LuAmthwbRSY9fY
--RrLFnG84kYo1Mgs=
-+MIIDETCCAfmgAwIBAgIBBjANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJTRTEQ
-+MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT
-+UUwgQUIwHhcNMTAwMjIwMDMwMzI2WhcNMzAwOTAzMDMwMzI2WjAyMQswCQYDVQQG
-+EwJTRTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIwgZ8wDQYJ
-+KoZIhvcNAQEBBQADgY0AMIGJAoGBAMLnIM+JWS9ny0yf6BHyI+Xxse4/Zl/D9f0e
-+Me6PTCq9wEqln8hE1XePFRtNeG6yokilJDMFQAKzwYeNWTwaB6qG8AThnCBLIjLE
-+UZ5A5DHDV/WYvy6x/SxWv0nZm+cXzJVftQgZXp3fZSI5LEj7aZYxejVN3mC0wWAZ
-+X5ZWflUZAgMBAAGjgaMwgaAwCQYDVR0TBAIwADAdBgNVHQ4EFgQUjRBnkTN2nALl
-+eF3Yxe8llrLX+h8wdAYDVR0jBG0wa4AUsft+d7VAjWgRftkR5cPG2k2sUbChSKRG
-+MEQxCzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBz
-+YWxhMREwDwYDVQQKEwhNeVNRTCBBQoIJAL5YrUwfPSWVMA0GCSqGSIb3DQEBBQUA
-+A4IBAQCpiBA+XSpHKcgDJ3oxWo4QA7y1TjcdEnvrX1BxcLGjjpMOdxdsR7bJpE0q
-+xDjwYVWyfyi6BnnuZxF91Ml/ChjIwcvQLPljD7tFyt7qu6wAAVJINisHK8hGx7Eh
-+gb13OedMOaq9rGDYp7/PFJhKC6FAVQaNbzWpOaBxqZe6fHM8QbrFHBFLK0MdLbp7
-+XxS1PWRiFTa0Fr14yEON+Ryl0qyhWHThmd6tBBlDqL0K/RmbUERGbRhVTb+0W6ST
-+YsdkkWxUNNH48/8SbV+F5zWeXEKBXvvIu0RRmLLvG59aIncofdr7CMKUmg9CCJNU
-+EB6t8k/8YphR6Zu5OpPZ5B8dxHbQ
- -----END CERTIFICATE-----
-diff -Naur mysql-5.1.50.orig/mysql-test/std_data/client-key.pem mysql-5.1.50/mysql-test/std_data/client-key.pem
---- mysql-5.1.50.orig/mysql-test/std_data/client-key.pem 2010-08-03 13:55:05.000000000 -0400
-+++ mysql-5.1.50/mysql-test/std_data/client-key.pem 2010-08-27 23:42:05.752428395 -0400
-@@ -1,15 +1,15 @@
- -----BEGIN RSA PRIVATE KEY-----
--MIICXQIBAAKBgQDMmjdJE2bcz+MLE6Ej7XjbTr0R9owNdvmjMlaa+KEhalVOTT/m
--Z50mmbLNpJrSK1lc14rTYGj4GL3FvhXhKjyj1GHL9RGUF4GB94eM9mrS7tjmd/Zi
--Zk0uFo0IgUrJxksx5bnHioSWSKdHjA0mkFZO5qVujLPyn/w9eJtJboaDdwIDAQAB
--AoGASqk/4We2En+93y3jkIO4pXafIe3w/3zZ7caRue1ehx4RUQh5d+95djuB9u7J
--HEZ7TpjM7QNyao5EueL6gvbxt0LXFvqAMni7yM9tt/HUYtHHPqYiRtUny9bKYFTm
--l8szCCMal/wD9GZU9ByHDNHm7tHUMyMhARNTYSgx+SERFmECQQD/6jJocC4SXf6f
--T3LqimWR02lbJ7qCoDgRglsUXh0zjrG+IIiAyE+QOCCx1GMe3Uw6bsIuYwdHT6as
--WcdPs04xAkEAzKulvEvLVvN5zfa/DTYRTV7jh6aDleOxjsD5oN/oJXoACnPzVuUL
--qQQMNtuAXm6Q1QItrRxpQsSKbY0UQka6JwJBAOSgoNoG5lIIYTKIMvzwGV+XBLeo
--HYsXgh+6Wo4uql3mLErUG78ZtWL9kc/tE4R+ZdyKGLaCR/1gXmH5bwN4B/ECQEBb
--uUH8k3REG4kojesZlVc+/00ojzgS4UKCa/yqa9VdB6ZBz8MDQydinnShkTwgiGpy
--xOoqhO753o2UT0qH8wECQQC99IEJWUnwvExVMkLaZH5NjAFJkb22sjkmuT11tAgU
--RQgOMoDOm6driojnOnDWOkx1r1Gy9NgMLooduja4v6cx
-+MIICWwIBAAKBgQDC5yDPiVkvZ8tMn+gR8iPl8bHuP2Zfw/X9HjHuj0wqvcBKpZ/I
-+RNV3jxUbTXhusqJIpSQzBUACs8GHjVk8GgeqhvAE4ZwgSyIyxFGeQOQxw1f1mL8u
-+sf0sVr9J2ZvnF8yVX7UIGV6d32UiOSxI+2mWMXo1Td5gtMFgGV+WVn5VGQIDAQAB
-+AoGARXcXLKDpVooJ3W+IyQyiWsw//IhANpWjUOm4JiyQmxMyO+i4ACr4Yjpu7WI5
-+MEseqAGj20NdwxjKO0PXsCIe5LmrGZ+SI8+CSERFOWXWRtCWz7y7SG30i1k6suvM
-+mwqWom0tJLwn93uA1lm/WSwKQwUrJRahRQd3EaZqrl7DP5kCQQD/8gbuYAT5pxQe
-+ULLGM0RvEsXxDYbEDxNbY5wrBazfklBwpumxZpFl6jEAT++7Kh2Ns3A7kB1oUNlA
-+FPYr+dYPAkEAwvHEwRtoyUr8jqoqVVJWI76CDmBjEOzVeMKW97ztqbs2LxZW8dYI
-+iOh/myFGpdoUwgu0U8w9MmXcj3ZeZCYKVwJALyQ+AJPw9qa+fuLwOq9gsHCtwrty
-+EhSQxSlwrz/pWniRll439vPkXfgntF4E0t1r+hiN2Hqv3/HcQgBaYzkuIwJAG023
-+bACFxaOuCeFFepvEms8E8jSHy4gQQhCnCl24v8wLw76SQN7kZSCDNtwLRBFuVNtE
-+z3PMonFn2eQPRmGZkwJAP1c1BHprMQx/ruafdscROILv3JrH40C1bR6KVVBKt1dK
-+Qpnpgi7hK5rUQjDF8k3bn9ugTt06jyeHe/QhAml0kg==
- -----END RSA PRIVATE KEY-----
-diff -Naur mysql-5.1.50.orig/mysql-test/std_data/server-cert.pem mysql-5.1.50/mysql-test/std_data/server-cert.pem
---- mysql-5.1.50.orig/mysql-test/std_data/server-cert.pem 2010-08-03 13:55:08.000000000 -0400
-+++ mysql-5.1.50/mysql-test/std_data/server-cert.pem 2010-08-27 23:42:05.753428361 -0400
-@@ -1,41 +1,69 @@
- Certificate:
- Data:
-- Version: 1 (0x0)
-- Serial Number: 1048578 (0x100002)
-- Signature Algorithm: md5WithRSAEncryption
-+ Version: 3 (0x2)
-+ Serial Number: 4 (0x4)
-+ Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB
- Validity
-- Not Before: Jan 29 11:56:49 2010 GMT
-- Not After : Jan 28 11:56:49 2015 GMT
-+ Not Before: Feb 20 02:55:06 2010 GMT
-+ Not After : Sep 3 02:55:06 2030 GMT
- Subject: C=SE, ST=Uppsala, O=MySQL AB, CN=localhost
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
-- Public-Key: (512 bit)
-- Modulus:
-- 00:cd:e4:87:51:9d:72:11:a0:d1:fa:f3:92:8b:13:
-- 1c:eb:f7:e2:9a:2f:72:a8:d6:65:48:d1:69:af:1b:
-- c0:4c:13:e5:60:60:51:41:e9:ab:a6:bc:13:bb:0c:
-- 5e:32:7c:d9:6c:9e:cd:05:24:84:78:db:80:91:2e:
-- d8:88:2b:c2:ed
-+ RSA Public Key: (1024 bit)
-+ Modulus (1024 bit):
-+ 00:e3:7d:4f:c2:23:77:a9:3a:2c:d2:69:59:a0:2f:
-+ 4e:d1:51:4c:ae:8d:f5:17:cc:ce:58:9c:83:4f:0b:
-+ a3:bb:29:a2:b8:1d:3e:1b:04:f9:a9:3e:e2:61:d0:
-+ e6:7b:b9:7c:12:d8:1f:86:c9:53:b5:04:dd:df:26:
-+ e9:c0:2b:de:4a:96:2e:f3:23:6f:79:6d:a9:d2:4e:
-+ 17:af:2f:de:8b:68:44:ae:de:a3:e2:c4:37:1c:04:
-+ ad:73:4b:85:f9:83:ac:fe:b7:c1:54:47:2e:96:d4:
-+ 31:96:85:94:69:d6:5a:63:24:04:99:89:19:1d:56:
-+ 8a:d1:77:aa:87:fb:38:cd:b7
- Exponent: 65537 (0x10001)
-- Signature Algorithm: md5WithRSAEncryption
-- 73:ce:9c:6e:39:46:b4:14:be:da:3f:f3:1b:ba:90:bc:23:43:
-- d7:82:2a:70:4e:a6:d9:5a:65:5c:b7:df:71:df:75:77:c5:80:
-- a4:af:fa:d2:59:e2:fd:c9:9c:f0:98:95:8e:69:a9:8c:7c:d8:
-- 6f:48:d2:e3:36:e0:cd:ff:3f:d1:a5:e6:ab:75:09:c4:50:10:
-- c4:96:dd:bf:3b:de:32:46:da:ca:4a:f1:d6:52:8a:33:2f:ab:
-- f5:2e:70:3f:d4:9c:be:00:c8:03:f9:39:8a:df:5b:70:3c:40:
-- ef:03:be:7c:3d:1d:32:32:f3:51:81:e2:83:30:6e:3d:38:9b:
-- fb:3c
-+ X509v3 extensions:
-+ X509v3 Basic Constraints:
-+ CA:FALSE
-+ X509v3 Subject Key Identifier:
-+ CC:8C:71:40:D0:0F:BF:D1:99:79:3F:1B:E9:10:76:19:67:36:0F:A3
-+ X509v3 Authority Key Identifier:
-+ keyid:B1:FB:7E:77:B5:40:8D:68:11:7E:D9:11:E5:C3:C6:DA:4D:AC:51:B0
-+ DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB
-+ serial:BE:58:AD:4C:1F:3D:25:95
-+
-+ Signature Algorithm: sha1WithRSAEncryption
-+ 6f:ad:5e:59:fa:84:3a:be:e2:72:b1:e8:66:2a:4e:f8:73:19:
-+ 11:06:11:92:78:56:3e:d6:e8:68:29:90:8b:59:d2:fe:aa:ae:
-+ 25:59:c7:e9:99:bb:4a:06:43:dd:40:bd:cb:f4:ae:79:95:7d:
-+ 8e:90:ef:58:d2:a8:fc:bf:07:f3:37:b2:9b:bd:da:e6:8c:56:
-+ dd:5e:c6:4a:70:7c:3e:3d:a1:e8:35:06:b8:a7:7b:ac:26:85:
-+ 54:5d:09:a2:7b:77:b4:17:7f:72:31:cb:ff:cc:67:6d:e6:3e:
-+ c6:dc:96:eb:4a:0a:ae:e9:48:ae:8a:e0:d6:73:57:6e:32:4c:
-+ 00:dc:28:da:55:b3:9f:9f:d8:98:cc:d9:f1:b6:b3:14:67:2e:
-+ a1:47:1e:51:11:cf:70:9f:31:8f:ba:59:29:f2:d0:88:0b:e2:
-+ 51:6b:f8:31:ed:6d:ac:00:5e:d3:78:4c:95:97:02:cc:74:2b:
-+ 3b:c6:28:e6:2a:c3:30:99:35:b4:4d:31:46:d4:90:f2:47:ed:
-+ 64:85:1a:75:2a:72:0a:2f:c6:3a:2f:d2:ac:6b:31:cc:e5:a8:
-+ 07:c2:d6:22:f3:c6:0f:bf:67:d9:d6:b2:79:cd:48:b5:c3:e0:
-+ e3:18:7f:b5:74:c9:43:19:fb:c4:93:29:ca:cc:90:2b:1b:6f:
-+ 45:f6:25:f9
- -----BEGIN CERTIFICATE-----
--MIIBtzCCASACAxAAAjANBgkqhkiG9w0BAQQFADBEMQswCQYDVQQGEwJTRTEQMA4G
--A1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwg
--QUIwHhcNMTAwMTI5MTE1NjQ5WhcNMTUwMTI4MTE1NjQ5WjBGMQswCQYDVQQGEwJT
--RTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxEjAQBgNVBAMT
--CWxvY2FsaG9zdDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDN5IdRnXIRoNH685KL
--Exzr9+KaL3Ko1mVI0WmvG8BME+VgYFFB6aumvBO7DF4yfNlsns0FJIR424CRLtiI
--K8LtAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAc86cbjlGtBS+2j/zG7qQvCND14Iq
--cE6m2VplXLffcd91d8WApK/60lni/cmc8JiVjmmpjHzYb0jS4zbgzf8/0aXmq3UJ
--xFAQxJbdvzveMkbaykrx1lKKMy+r9S5wP9ScvgDIA/k5it9bcDxA7wO+fD0dMjLz
--UYHigzBuPTib+zw=
-+MIIDJTCCAg2gAwIBAgIBBDANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJTRTEQ
-+MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT
-+UUwgQUIwHhcNMTAwMjIwMDI1NTA2WhcNMzAwOTAzMDI1NTA2WjBGMQswCQYDVQQG
-+EwJTRTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxEjAQBgNV
-+BAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA431PwiN3
-+qTos0mlZoC9O0VFMro31F8zOWJyDTwujuymiuB0+GwT5qT7iYdDme7l8EtgfhslT
-+tQTd3ybpwCveSpYu8yNveW2p0k4Xry/ei2hErt6j4sQ3HAStc0uF+YOs/rfBVEcu
-+ltQxloWUadZaYyQEmYkZHVaK0Xeqh/s4zbcCAwEAAaOBozCBoDAJBgNVHRMEAjAA
-+MB0GA1UdDgQWBBTMjHFA0A+/0Zl5PxvpEHYZZzYPozB0BgNVHSMEbTBrgBSx+353
-+tUCNaBF+2RHlw8baTaxRsKFIpEYwRDELMAkGA1UEBhMCU0UxEDAOBgNVBAgTB1Vw
-+cHNhbGExEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCggkAvlit
-+TB89JZUwDQYJKoZIhvcNAQEFBQADggEBAG+tXln6hDq+4nKx6GYqTvhzGREGEZJ4
-+Vj7W6GgpkItZ0v6qriVZx+mZu0oGQ91Avcv0rnmVfY6Q71jSqPy/B/M3spu92uaM
-+Vt1exkpwfD49oeg1Brine6wmhVRdCaJ7d7QXf3Ixy//MZ23mPsbclutKCq7pSK6K
-+4NZzV24yTADcKNpVs5+f2JjM2fG2sxRnLqFHHlERz3CfMY+6WSny0IgL4lFr+DHt
-+bawAXtN4TJWXAsx0KzvGKOYqwzCZNbRNMUbUkPJH7WSFGnUqcgovxjov0qxrMczl
-+qAfC1iLzxg+/Z9nWsnnNSLXD4OMYf7V0yUMZ+8STKcrMkCsbb0X2Jfk=
- -----END CERTIFICATE-----
-diff -Naur mysql-5.1.50.orig/mysql-test/std_data/server-key.pem mysql-5.1.50/mysql-test/std_data/server-key.pem
---- mysql-5.1.50.orig/mysql-test/std_data/server-key.pem 2010-08-03 13:55:08.000000000 -0400
-+++ mysql-5.1.50/mysql-test/std_data/server-key.pem 2010-08-27 23:42:05.754428433 -0400
-@@ -1,9 +1,15 @@
- -----BEGIN RSA PRIVATE KEY-----
--MIIBOwIBAAJBAM3kh1GdchGg0frzkosTHOv34povcqjWZUjRaa8bwEwT5WBgUUHp
--q6a8E7sMXjJ82WyezQUkhHjbgJEu2Igrwu0CAwEAAQJBAJuwhFbF3NzRpBbEmnqJ
--4GPa1UJMQMLFJF+04tqj/HxJcAIVhOJhGmmtYNw1yjz/ZsPnfJCMz4eFOtdjvGtf
--peECIQDmFFg2WLvYo+2m9w9V7z4ZIkg7ixYkI/ObUUctfZkPOQIhAOUWnrvjFrAX
--bIvYT/YR50+3ZDLEc51XxNgJnWqWYl1VAiEAnTOFWgyivFC1DgF8PvDp8u5TgCt2
--A1d1GMgd490O+TECIC/WMl0/hTxOF9930vKqOGf//o9PUGkZq8QE9fcM4gtlAiAE
--iOcFpnLjtWj57jrhuw214ucnB5rklkQQe+AtcARNkg==
-+MIICXgIBAAKBgQDjfU/CI3epOizSaVmgL07RUUyujfUXzM5YnINPC6O7KaK4HT4b
-+BPmpPuJh0OZ7uXwS2B+GyVO1BN3fJunAK95Kli7zI295banSThevL96LaESu3qPi
-+xDccBK1zS4X5g6z+t8FURy6W1DGWhZRp1lpjJASZiRkdVorRd6qH+zjNtwIDAQAB
-+AoGAUb0o91y/FjMs/72S0pes/lDz+JRRSGfyjKxQEgrgndNsADOhqRu0iTdrKDJj
-+XnlbN3ooecnFJfnFrvTQcJhSmlS30j6VrBw6LXpCBK3dvjYgJ9LOne7WK+dF1+vS
-+FMQtsP04C56Sxy6HJDpMyWJ6oS3Bu169ygG2AxKo+Fk+E6ECQQD38w/MzmrARz2Z
-+AGeEPDUnVZPYgtmXkmks95S0/2jSoLhmgpvJimzxwpYwVG/BG8dSDVuTDu5kp05D
-+3bZIp3EzAkEA6uAwJsCZPtHXlWU3wYZJsA697rUNjPaCQOIaZ/lnh5RUHTmUiw1h
-+Oj/VORqKB0kXqcDfawwLjZEvh1Xli+H5bQJBANTmhw2TvEPnp/OFTl1UGUvyBmXl
-+TRMB639qAu07VfVtfYi/4ya1zn/0VmOfTOoigQ5qW9Q1AOu6YNCTQl62L9MCQQDc
-+YfEsW2kvNYxYJHoVfuBjbuGuOnn1e1Oqd70ZND59S6NFLMMBWlORaVWzWACNZ3rp
-+kAzSj6HDeqgjD2jsQONdAkEAt7S1YHUn8F760bRn4AnAto2TVOYdArtTP/wYjd4o
-+9rJREO/d8AYkYJ96APLvF0SZ4n3t1pLwQRsKKN8ZGTmzLA==
- -----END RSA PRIVATE KEY-----
-diff -Naur mysql-5.1.50.orig/mysql-test/std_data/server8k-cert.pem mysql-5.1.50/mysql-test/std_data/server8k-cert.pem
---- mysql-5.1.50.orig/mysql-test/std_data/server8k-cert.pem 2010-08-03 13:55:08.000000000 -0400
-+++ mysql-5.1.50/mysql-test/std_data/server8k-cert.pem 2010-08-27 23:43:00.005366270 -0400
-@@ -1,51 +1,69 @@
-+Certificate:
-+ Data:
-+ Version: 3 (0x2)
-+ Serial Number: 5 (0x5)
-+ Signature Algorithm: sha1WithRSAEncryption
-+ Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB
-+ Validity
-+ Not Before: Feb 20 03:00:54 2010 GMT
-+ Not After : Sep 3 03:00:54 2030 GMT
-+ Subject: C=SE, ST=Uppsala, O=MySQL AB, CN=server
-+ Subject Public Key Info:
-+ Public Key Algorithm: rsaEncryption
-+ RSA Public Key: (1024 bit)
-+ Modulus (1024 bit):
-+ 00:c5:da:44:95:06:77:16:21:af:a0:c4:3c:e9:f8:
-+ 1d:2d:95:f9:63:90:8c:3f:86:ba:77:76:4a:52:4b:
-+ 6b:af:29:f5:1c:aa:d4:3f:3e:42:9f:6d:46:ba:86:
-+ 90:b1:2d:cc:db:c6:33:15:a3:f4:af:53:33:4f:a1:
-+ 56:d1:aa:3b:26:10:f7:64:b5:f9:bf:1b:b1:47:8e:
-+ cc:a6:d6:0d:aa:4a:77:e3:a3:63:9d:2a:dc:65:f4:
-+ 7f:91:17:38:2d:d6:cd:4e:8d:53:52:97:6e:87:fc:
-+ 64:60:a6:a1:00:ac:96:6c:e4:42:94:75:17:46:6f:
-+ 91:b5:dd:06:47:ed:05:e3:db
-+ Exponent: 65537 (0x10001)
-+ X509v3 extensions:
-+ X509v3 Basic Constraints:
-+ CA:FALSE
-+ X509v3 Subject Key Identifier:
-+ 6E:60:3F:29:13:60:99:ED:0C:F7:15:B5:DB:7B:1C:FB:6F:60:19:ED
-+ X509v3 Authority Key Identifier:
-+ keyid:B1:FB:7E:77:B5:40:8D:68:11:7E:D9:11:E5:C3:C6:DA:4D:AC:51:B0
-+ DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB
-+ serial:BE:58:AD:4C:1F:3D:25:95
-+
-+ Signature Algorithm: sha1WithRSAEncryption
-+ 63:2e:0f:07:14:06:cf:74:90:3d:37:42:f2:48:70:60:21:bc:
-+ 34:52:31:f1:87:70:d2:b2:fb:ff:13:38:dc:f0:5e:43:d7:ee:
-+ a7:c7:1f:ac:aa:d2:8c:4f:fa:3c:4c:73:f6:b6:c2:0c:a0:ea:
-+ a2:c9:e2:73:61:c3:2e:78:40:0f:2a:d3:63:50:9b:b8:f9:89:
-+ 40:ed:98:08:97:c3:07:24:17:34:b5:78:89:0a:bb:83:4c:e2:
-+ 5c:2e:13:d6:21:30:ad:30:48:b5:70:12:ff:4a:6f:42:f0:f8:
-+ 9f:b1:4b:bd:89:2b:f0:9d:e2:49:2b:35:69:18:1f:76:40:b4:
-+ 76:bd:cb:dd:27:2f:c0:c1:e2:33:3e:6e:df:68:54:19:92:8a:
-+ bb:13:9c:cf:d6:17:56:da:bf:0d:64:70:3a:45:b7:aa:5f:e3:
-+ f5:96:ae:34:f2:17:37:27:d0:4b:e8:30:4a:c0:02:42:e2:d2:
-+ 30:eb:eb:c7:d7:ec:d8:df:5c:43:58:e2:6f:b7:58:54:0d:c4:
-+ 01:71:2d:59:8f:44:c7:a1:6c:0b:41:28:fa:b7:63:a7:68:d3:
-+ 4f:c3:0f:17:9e:b2:32:50:e6:0b:87:3d:e2:39:47:c0:d8:0a:
-+ 3b:f6:af:50:68:0f:9d:ef:6e:34:0d:3a:07:94:f8:a4:d7:24:
-+ 86:32:d3:b4
- -----BEGIN CERTIFICATE-----
--MIIJFDCCBPwCAQEwDQYJKoZIhvcNAQEEBQAwTjELMAkGA1UEBhMCU0UxEDAOBgNV
--BAgTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCMQ0wCwYDVQQLEwRUZXN0MQsw
--CQYDVQQDEwJDQTAeFw0xMDA3MjgxNDA3MjhaFw0xODEwMTQxNDA3MjhaMFIxCzAJ
--BgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMREwDwYDVQQKEwhNeVNRTCBBQjEN
--MAsGA1UECxMEVGVzdDEPMA0GA1UEAxMGc2VydmVyMIIEIjANBgkqhkiG9w0BAQEF
--AAOCBA8AMIIECgKCBAEA6h3v1OWb9I9U/Z8diBu/xYGS8NCTD3ZESboHxVI2qSEC
--PgxNNcG8Lh0ktQdgYcOe64MnDTZX0Bibm47hoDldrAlTSffFxQhylqBBoXxDF+Lr
--hXIqCz7K0PsK+bYusL9ezJ7PETDnCT7oy95q4GXbKsutbNsm9if4ZE41gs2KnoU2
--DA7kvMmkKojrMIL4+BqTXA20LLo0iSbgvUTvpSJw4u96BeyzMNnxK2wP5vvTtUo5
--hACbfU87YjaSKs+q2VXCzfyYGZk1L1xk5GUI0bP+jutf1dDzNttW2/q2Nf5rxx09
--Gh/GwmOnEk1O7cOZ8VQCsOHirIM39NuSARsY6Y3G5XM4k2W4nxyR/RtdG9bvs/33
--aGsZ5V5yp7WSs8s9HHwaCPSsUiLKckQ7uA0TTRgbeweMrrLKovG57jsbBBB8pQD4
--PRd31qgxCdstWXHiWwRyI8vOLWENPXPFqA/rJwwqNdWTogy38aqVXxGYR8PIwjA2
--OaIwFjwGZcsPNLqw6bgAN8O2UBqZHWiMF8mi7brvioDvAIufZuqa2SqT/At45H83
--psQ6R4FsxZt6SAK7EsdPo8OYTrY1i4iPZd/eKhnEu2srEZgsKRwY5H1mvDH5fWCc
--HSFu07sWmlmK6Or65Fsa0IaKLJiQDVVETd6xrI0wkM4AOcbKDrS7aywJ426dopbs
--+LFdt4N0cdII4gBgJAfLuuA2yrDXRq4P6cgpVMy0R+0dEYE8zzm8zf1a+Ud273LS
--9+LB+LJKwqbW8nOPBoiekimIKfJYoOA4+C/mAjsYl1sVjjEhXJAs9S9L2UvnUk1P
--sZi4UKHI6eAIEl7VM1sQ4GbdZ0px2dF2Ax7pGkhD+DLpYyYkCprharKZdmuUNLUd
--NhXxi/HSEiE+Uy+o8RIzmH7LuROl/ZgnfHjJEiBLt2qPvwrwYd4c3XuXWs4YsWfV
--JTt8Mx2ihgVcdGy9//shCSmgJwR1oWrhgC10AEL2fKeRnYUal1i+IxFPp7nb8uwx
--UADgR0cY4A3qR/JP489QFIcxBTVs65De+Bq3ecnujk6yeGpD9iptonq4Y8uNZMc1
--kOE7GiFGwR4EufT5SEMh+tUkjth2r+842vmZZuxrVQaohDiATmIJA07W51zKH+nQ
--uw4qVKnAhPaDLCLc7YMIH9JcmkeQX0nf8/S2O2WYDH8glVDi5hfW08tCmV647vRY
--nTIywUTO0lFpz7M+VyMNaJ6yXU6biBV5hLAI8C5ldr/SWI789W2+ebBaJ9gfK+PT
--trohFSK37GcoSH4V6qSLJHCBASEsiddqHIHMLJZRYD+B6J3tLhjVUM43u+MEGbFT
--d33ZDke/WzLTExWkaOv36e67gDBmgDuj9yroq3wGfwIDAQABMA0GCSqGSIb3DQEB
--BAUAA4IEAQCc9RBhRbuWlmRZPZkqIdi5/+enyjoMmOa6ryJPxFSP8D2jrlHgQsk1
--+GsJmPFT3rwWfoGAQu/aeSX4sp8OhKVJtqNA6MJrGYnZIMolgYa1wZPbkjJsdEfi
--UsZdIB0n2+KA0xwEdGPdkGCfNPBtOg557DkcyEvsIZ9ELp4Pp2XzWRhyFGasJZc4
--YwgD/3K2rpOPZoMkBKeKqV19j41OfLKGBVyuaqzitbu9+KT4RU1ibr2a+UuFCwdT
--oqyN7bfWXjcjXOMkxCsOmLfKmqQxs7TEOVrYPTdYjamDxLy/e5g5FgoCxGY8iil0
--+YFLZyH6eEx/Os9DlG/M3O1MeRD9U97CdsphbDVZIDyWw5xeX8qQHJe0KSprAgiG
--TLhTZHeyrKujQCQS1oFFmNy4gSqXt0j1/6/9T80j6HeyjiiYEaEQK9YLTAjRoA7W
--VN8wtHI5F3RlNOVQEJks/bjdlpLL3VhaWtfewGh/mXRGcow84cgcsejMexmhreHm
--JfTUl9+X1IFFxGq2/606A9ROQ7kN/s4rXu7/TiMODXI/kZijoWd2SCc7Z0YWoNo7
--IRKkmZtrsflJbObEuK2Jk59uqzSxyQOBId8qtbPo8qJJyHGV5GCp34g4x67BxJBo
--h1iyVMamBAS5Ip1ejghuROrB8Hit8NhAZApXju62btJeXLX+mQayXb/wC/IXNJJD
--83tXiLfZgs6GzLAq7+KW/64sZSvj87CPiNtxkvjchAvyr+fhbBXCrf4rlOjJE6SH
--Je2/Jon7uqijncARGLBeYUT0Aa6k1slpXuSKxDNt7EIkP21kDZ5/OJ0Y1u587KVB
--dEhuDgNf2/8ij7gAQBwBoZMe1DrwddrxgLLBlyHpAZetNYFZNT+Cs/OlpqI0Jm59
--kK9pX0BY4AGOd23XM3K/uLawdmf67kkftim7aVaqXFHPiWsJVtlzmidKvNSmbmZe
--dOmMXp6PBoqcdusFVUS7vjd3KAes5wUX/CaTyOOPRu0LMSnpwEnaL76IC9x4Jd6d
--7QqY/OFTjpPH8nP57LwouiT6MgSUCWGaOkPuBJ9w9sENSbbINpgJJ42iAe2kE+R7
--qEIvf/2ETCTseeQUqm2nWiSPLkNagEh6kojmEoKrGyrv3YjrSXSOY1a70tDVy43+
--ueQDQzNZm3Q7inpke2ZKvWyY0LQmLzP2te+tnNBcdLyKJx7emPRTuMUlEdK7cLbt
--V3Sy9IKtyAXqqd66fPFj4NhJygyncj8M6CSqhG5L0GhDbkA8UJ8yK/gfKm3h5xe2
--utULK5VMtAhQt6cVahO59A9t/OI17y45bmlIgdlEQISzVFe9ZbIUJW44zBfPx74k
--/w8pMRr8gEuRqpL2WdJiKGG6lhMHLVFo
-+MIIDIjCCAgqgAwIBAgIBBTANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJTRTEQ
-+MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT
-+UUwgQUIwHhcNMTAwMjIwMDMwMDU0WhcNMzAwOTAzMDMwMDU0WjBDMQswCQYDVQQG
-+EwJTRTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxDzANBgNV
-+BAMTBnNlcnZlcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxdpElQZ3FiGv
-+oMQ86fgdLZX5Y5CMP4a6d3ZKUktrryn1HKrUPz5Cn21GuoaQsS3M28YzFaP0r1Mz
-+T6FW0ao7JhD3ZLX5vxuxR47MptYNqkp346NjnSrcZfR/kRc4LdbNTo1TUpduh/xk
-+YKahAKyWbORClHUXRm+Rtd0GR+0F49sCAwEAAaOBozCBoDAJBgNVHRMEAjAAMB0G
-+A1UdDgQWBBRuYD8pE2CZ7Qz3FbXbexz7b2AZ7TB0BgNVHSMEbTBrgBSx+353tUCN
-+aBF+2RHlw8baTaxRsKFIpEYwRDELMAkGA1UEBhMCU0UxEDAOBgNVBAgTB1VwcHNh
-+bGExEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCggkAvlitTB89
-+JZUwDQYJKoZIhvcNAQEFBQADggEBAGMuDwcUBs90kD03QvJIcGAhvDRSMfGHcNKy
-++/8TONzwXkPX7qfHH6yq0oxP+jxMc/a2wgyg6qLJ4nNhwy54QA8q02NQm7j5iUDt
-+mAiXwwckFzS1eIkKu4NM4lwuE9YhMK0wSLVwEv9Kb0Lw+J+xS72JK/Cd4kkrNWkY
-+H3ZAtHa9y90nL8DB4jM+bt9oVBmSirsTnM/WF1bavw1kcDpFt6pf4/WWrjTyFzcn
-+0EvoMErAAkLi0jDr68fX7NjfXENY4m+3WFQNxAFxLVmPRMehbAtBKPq3Y6do00/D
-+DxeesjJQ5guHPeI5R8DYCjv2r1BoD53vbjQNOgeU+KTXJIYy07Q=
- -----END CERTIFICATE-----
-diff -Naur mysql-5.1.50.orig/mysql-test/std_data/server8k-key.pem mysql-5.1.50/mysql-test/std_data/server8k-key.pem
---- mysql-5.1.50.orig/mysql-test/std_data/server8k-key.pem 2010-08-03 13:55:08.000000000 -0400
-+++ mysql-5.1.50/mysql-test/std_data/server8k-key.pem 2010-08-27 23:43:10.165365998 -0400
-@@ -1,99 +1,15 @@
- -----BEGIN RSA PRIVATE KEY-----
--MIISKQIBAAKCBAEA6h3v1OWb9I9U/Z8diBu/xYGS8NCTD3ZESboHxVI2qSECPgxN
--NcG8Lh0ktQdgYcOe64MnDTZX0Bibm47hoDldrAlTSffFxQhylqBBoXxDF+LrhXIq
--Cz7K0PsK+bYusL9ezJ7PETDnCT7oy95q4GXbKsutbNsm9if4ZE41gs2KnoU2DA7k
--vMmkKojrMIL4+BqTXA20LLo0iSbgvUTvpSJw4u96BeyzMNnxK2wP5vvTtUo5hACb
--fU87YjaSKs+q2VXCzfyYGZk1L1xk5GUI0bP+jutf1dDzNttW2/q2Nf5rxx09Gh/G
--wmOnEk1O7cOZ8VQCsOHirIM39NuSARsY6Y3G5XM4k2W4nxyR/RtdG9bvs/33aGsZ
--5V5yp7WSs8s9HHwaCPSsUiLKckQ7uA0TTRgbeweMrrLKovG57jsbBBB8pQD4PRd3
--1qgxCdstWXHiWwRyI8vOLWENPXPFqA/rJwwqNdWTogy38aqVXxGYR8PIwjA2OaIw
--FjwGZcsPNLqw6bgAN8O2UBqZHWiMF8mi7brvioDvAIufZuqa2SqT/At45H83psQ6
--R4FsxZt6SAK7EsdPo8OYTrY1i4iPZd/eKhnEu2srEZgsKRwY5H1mvDH5fWCcHSFu
--07sWmlmK6Or65Fsa0IaKLJiQDVVETd6xrI0wkM4AOcbKDrS7aywJ426dopbs+LFd
--t4N0cdII4gBgJAfLuuA2yrDXRq4P6cgpVMy0R+0dEYE8zzm8zf1a+Ud273LS9+LB
--+LJKwqbW8nOPBoiekimIKfJYoOA4+C/mAjsYl1sVjjEhXJAs9S9L2UvnUk1PsZi4
--UKHI6eAIEl7VM1sQ4GbdZ0px2dF2Ax7pGkhD+DLpYyYkCprharKZdmuUNLUdNhXx
--i/HSEiE+Uy+o8RIzmH7LuROl/ZgnfHjJEiBLt2qPvwrwYd4c3XuXWs4YsWfVJTt8
--Mx2ihgVcdGy9//shCSmgJwR1oWrhgC10AEL2fKeRnYUal1i+IxFPp7nb8uwxUADg
--R0cY4A3qR/JP489QFIcxBTVs65De+Bq3ecnujk6yeGpD9iptonq4Y8uNZMc1kOE7
--GiFGwR4EufT5SEMh+tUkjth2r+842vmZZuxrVQaohDiATmIJA07W51zKH+nQuw4q
--VKnAhPaDLCLc7YMIH9JcmkeQX0nf8/S2O2WYDH8glVDi5hfW08tCmV647vRYnTIy
--wUTO0lFpz7M+VyMNaJ6yXU6biBV5hLAI8C5ldr/SWI789W2+ebBaJ9gfK+PTtroh
--FSK37GcoSH4V6qSLJHCBASEsiddqHIHMLJZRYD+B6J3tLhjVUM43u+MEGbFTd33Z
--Dke/WzLTExWkaOv36e67gDBmgDuj9yroq3wGfwIDAQABAoIEAQCSt6YoZqigz/50
--XvYT6Uf6T6S1lBDFXNmY1qOuDkLBJTWRiwYMDViQEaWCaZgGTKDYeT3M8uR/Phyu
--lRFi5vCEMufmcAeZ3hxptw7KU+R8ILJ207/zgit6YglTys9h5txTIack39+6FJmx
--wbZ64HpETJZnpMO6+fuZaMXyLjuT8mmXjvHcOgXOvjWeFkZOveDhjJkAesUXuqyX
--EI+ajoXuQiPXeKonkD2qd7NTjzfy4gw/ZF4NXs0ZVJeviqtIPo2xp33udOw2vRFh
--bMvlF4cNLAbIKYVyOG0ruOfd2I7Unsc/CvD1u5vlRVuUd8OO0JZLIZR7hlRX+A58
--8O1g2H/wJZAsF1BnLnFzDGYCX2WjCCK3Zn85FkKGRa0lTdYDduad/C/N3Y2/pHFE
--e7U/2D7IkEei59tD2HcsDBB3MJnckkn/hyiL9qWcxqWZ61vurE+XjU6tc6fnfhk9
--pJQ6yU3epPU7Vfsk0UGA7bbgKpsyzyH8Zl76YC2mN2ZVJjZekfhY+ibT9odEPdOl
--yLB5iXA6/WhKkDWaOqZGOH+7MblWgT9wHINlcn+nKzOr00JHl26ac6aMlXXi9vbe
--4jgJbFK1HYlFIndyX/BdqRTsFemDoDrVqrEYsaONoVYDd9c5qrqYOeh34DhOksQW
--hNwWBfmMlfzgOGtCYhMeK+AajqTtUbMYQA6qp47KJd/Oa5Dvi3ZCpvZh3Ll5iIau
--rqCtmojsWCqmpWSu7P+Wu4+O3XkUMPdQUuQ5rJFESEBB3yEJcxqk/RItTcKNElNC
--PASrPrMD9cli7S/pJ+frbhu1Gna1ArXzXQE9pMozPaBpjCig7+15R0lL3pmOKO6e
--WK3dgSwrnW6TQdLPlSD4lbRoiIdTHVBczztDeUqVvFiV3/cuaEi1nvaVdAYLqjuL
--ogK4HwE/FQ54S0ijAsP52n25usoH6OTU3bSd/7NTp0vZCy3yf10x7HUdsh2DvhRO
--3+TSK5t0yz0Nt7hNwcI6pLmWUIYcZgpFc/WsiiGscTfhy8rh3kRHI8ylGq53KNF+
--yCVmjqnBRWs91ArxmeF1ctX2t3w5p7gf65hJWqoX/2DiSi5FBsr6HLxa5sUi4wRZ
--136aCNt5Wu7w+AzPDbQW6qKUGSyfHJAw4JZasZcaZLise5IWb1ks0DtFbWWdT3ux
--8r2AM7IO1WopnekrYCnx/aBvBAv4NjWozVA517ztVttPERt3AGb4nm387nYt5R2U
--NO2GBWcDyT8JQLKmffE1AkWolCR1GsvcNLQfLCbnNppgsnsLE/viTG4mq1wjnd8O
--2Q8nH1SVTuyGFREMp/zsiAEaGfdd0hI2r1J7OdNPBBCtmhITsy9ZYHqm5vrGvy3s
--vi2GuB2RAoICAQD/oWUsg4eTJxHifTJLz/tVSTXnw7DhfbFVa1K1rUV63/MRQAFW
--pabN4T6Yfp3CpdRkljCA8KPJZj7euwhm4OEg1ulpOouA+cfWlE9RFE8wyOK5SYwM
--k+nk31P9MUC866pZg/ghzBGDub91OW1+ZGEtqnLI/n/LhiAIWt0hJvgZclTc1cAL
--xffHVlFwoSyNl/nc3ueZCC95nOLst2XcuxZLLbOFtZCmDYsp49q/Jn6EFjn4Ge2o
--qp38z6eZgDMP1F4lb9nDqXPHfUSt2jxKlmpfXS+IPKdba67+EjhbtmUYzaR4EoPI
--zh+o6SrVWT6Yve7KGiYv06fuRz1m/lLQO/Arbd9ntSjgn+ZEXGOkbhnHUX3DJ4ny
--/6XEGB9NLQjern4uNTn0AaV+uvhncapFMaIBnVfq0Cw8eog0136PBYRaVX7T44j5
--HwIyGXWtYGA/SzDEQoksD0Y/T61BEGnLZaKeavNd82WwFvcYHZtE0J4aQGjCEE7N
--+nijzCy+j5ETmme9KJvQHpEyXP3N4RBko1eWvyTwFZDdIXtoa6TTEI51lm+FXJ/b
--Y+BzMr6KRo29FB+7//1ptUoMvn5hzL0PwOv2ZSTQuoG5hLDEbxWXLNhd1VHcfznF
--3EZHwfD2F8aGQ3kz+fkMTNfK955KorDrmLgvmV9eZZ5yQxGZrs5H5YfKpwKCAgEA
--6nSUbzfSdVFUH89NM5FmEJgkD06vqCgHl2mpyF+VmDGcay4K06eA4QbRO5kns13+
--n6PcBl/YVW/rNE8iFi+WxfqUpAjdR1HlShvTuTRVqtFTfuN8XhbYU6VMjKyuE0kd
--LKe3KRdwubjVNhXRZLBknU+3Y/4hnIR7mcE3/M5Zv5hjb7XnwWg/SzxV9WojCKiu
--vQ7cXhH5/o7EuKcl1d6vueGhWsRylCG9RimwgViR2H7zD9kpkOc0nNym9cSpb0Gv
--Lui4cf/fVwIt2HfNEGBjbM/83e2MH6b8Xp1fFAy0aXCdRtOo4LVOzJVAxn5dERMX
--4JJ4d5cSFbssDN1bITOKzuytfBqRIQGNkOfizgQNWUiaFI0MhEN/icymjm1ybOIh
--Gc9tzqKI4wP2X9g+u3+Oof1QaBcZ4UbZEU9ITN87Pa6XVJmpNx7A81BafWoEPFeE
--ahoO4XDwlHZazDuSlOseEShxXcVwaIiqySy7OBEPBVuYdEd2Qw/z3JTx9Kw8MKnf
--hu+ar5tz5dPnJIsvLeYCcJDe/K6loiZuHTtPbWEy9p6It7qubQNPBvTSBN5eVDKc
--Q2bTQNCx8SAAA9C5gJiwWoQKsXJzbRFRY77P9JjuGpua3YJ2nYBHEJmF+fp1R33c
--uHIyMphPMkKC4GC3/43kkMr6tck8kZbXGSYsLsBr2GkCggIBAJvvrjILQianzKcm
--zAmnI6AQ+ssYesvyyrxaraeZvSqJdlLtgmOCxVANuQt5IW9djUSWwZvGL4Np1aw0
--15k6UNqhftzsE7FnrVneOsww4WXXBUcV8FKz4Bf3i9qFswILmGzmrfSf8YczRfGS
--SJKzVPxwX3jwlrBmbx/pnb7dcLbFIbNcyLvl1ZJJu4BDMVRmgssTRp/5eExtQZg4
--//A4SA8wH7TO3yAMXvn8vrGgH8kfbdlEp88d1SYk3g4rP/rGB3A63NIYikIEzmJn
--ICQ3wUfPJnGq3kRMWgEuyCZaCy2oNE3yrWVPJ8z3/2MJ/79ZDVNHxEeki2o1FuW+
--+nGAPq+fZIp03iy4HdVRro7dgugtc9QaSHJtNId8V4vSjviX5Oz3FxUb9AJst58S
--nVV8Q2FMxBa/SlzSOkhRtCg2q1gXkzhaMnIVUleRZFGQ2uWBToxKMjcoUifIyN1J
--z999bkfI4hBLq5pRSAXz+YVu5SMKa10GaawIwJLat+i+1zboF6QyI2o/Wz8nrsNq
--KX/ajFGu5C94WFgsVoWKNI90KBLe48Ssje9c68waBlV/WHMg1YLvU3yqVDOV+K5c
--IHB9tPMnG+AgBYZPxSzuvnLrrkj/GeKx0WI7TrvzOLRGKJo6irMEJ8IzFegASRUq
--TVZKYQDYRG7m+lKlSxU+pyMAh2c9AoICAE4kavCip1eIssQjYLTGSkFPo/0iGbOv
--G9CgXAE3snFWX67tWphupKrbjdMSWcQTmPD2OTg6q6zWL4twsIi6dcMooHAHsFC7
--//LyUV/SDJdxSyXohiQJ8zH1zwy35RDydnHSuF5OvLh53T44iWDI1dAEqLgAFI3J
--LjTxzEpLMGiGTuYFt+ejai0WQAQayvBw4ESM9m+4CB2K0hBFTXv5y5HlnNTW0uWC
--VUZUUMrbjUieDz8B/zOXi9aYSGFzmZFGUDAPSqJcSMEELemPDF7f8WNr8vi42tIV
--4tlaFD1nep4F9bWMiCXU6B2RxVQi+7vcJEIqL1KUnGd3ydfD00K+ng4Xnj7Vz/cz
--QE7CqrpFaXmPlCMzW6+dm51/AyhHXDLkL2od05hiXcNkJ7KMLWRqwExHVIxM3shR
--x7lYNl3ArUsCrNd6m4aOjnrKFk7kjeLavHxskPccoGKrC9o0JMfTkWLgmuBJFQ0S
--N/HzIbcvIFWF0Ms4ojb50yp6ziXhXfJOO/0KUQEki71XIhvw89mVZszDzD5lqzjf
--HCZMBU4MbmL6NdEevFIDH0zPPkx3HPNtJt3kIJbit9wI8VhUMe+ldGnGxpWb8tKw
--SfM3vrHkYr+lizk26XfXMFhdAuVtT7dzQKSNEyP/1a2Hs307Xzgiv8JulJ8QIkrX
--/nsYWPOAGLG5AoICABmdW9Ppkvuhb1AEcjTWb+XCyopoBc6vit/uQWD9uO+CeX7a
--cfzq+iH01CAjyVMc4E1JDc5Lpi106U+GRGcAAaPJB2Sp5NznoxaOVrb71blu4Q4x
--bNjtKM/P/DXpO+yJYoOPdKtaSDhtnfNDM7H/jztJ3XIrOltKA7CcRDohbBWIx8Q0
--0uEpvfFpZZBco3yVmjP0RLgIVYn/ZDj9wGhSvFWIJ5vv6GXmtDrcHGMLxcfv7t76
--UVcMW/Yy4mYJRCzGOrWagyVijJ6MTVNciqadWcH1KcbB3EGoMFYMn61or2qJABPM
--xz89IlhnROU1Re3X/QRx5t86cw6oa+FqrWMOhSs31I0dNWSuS/xDympG27YIYSDd
--mv5seT78GjFmMJC5pPOLoXsbTPB0HpsX2/UL/w/eRAfilTOef/Cf9VE5MP/C2YR7
--NBxUU7/+21D6WvdtBTcZbrXWGroAo8zPP+PwX0+c6WoAvqDJvCPndp8xZhSgEJN/
--0kScptezi8n3ZHI95EA9U5mAHxHz0IhDDVzWw/z1f1SBPxKVX3+By3zaa3lrD2ch
--cHq7nBkX72veEevnHUY8Z2rHE2G2jdmRfOtwm4sjL0VBV9fRRoxzJWRduKyeOtDL
--EhhBhUoTrT48UnfW9hxnbNLB9P/hh+UJu9HrS2uAwHoGE1+8gcyundupGDBn
-+MIICXgIBAAKBgQDF2kSVBncWIa+gxDzp+B0tlfljkIw/hrp3dkpSS2uvKfUcqtQ/
-+PkKfbUa6hpCxLczbxjMVo/SvUzNPoVbRqjsmEPdktfm/G7FHjsym1g2qSnfjo2Od
-+Ktxl9H+RFzgt1s1OjVNSl26H/GRgpqEArJZs5EKUdRdGb5G13QZH7QXj2wIDAQAB
-+AoGBAJLCjh7Q9eLnx+QDzH9s+Q/IcH4nSbERmh1lFEopAc6j29qQ6PGkmDy0DUPs
-+70VOCOh5A4mo3aZzm9sUfVb24/nRtmyTP/AtMuIVGCsUqzI28dJRGvRlY0aSQG/C
-+ILqMP69kiMNGBvuyEIiJhisOmMvDFEp7HrrXHJM9qcc217DpAkEA4nzJ9yyy2e4O
-+r6/D711hdfcU/F+ktXw+pL77kSSdTABUap92Uv2RL36UA4q5h8RNvq/GrzMNm6Ye
-+u2IMvBCiTQJBAN+iRbiMJCSitTg5YVMluVbT87co7jbTqk7LN1ujyIFEklm4xlHG
-+DLJNgEoDR7QJtAkL++FyogC4zsQsey5voscCQQCp54trTbDuI9QIoAaQrrDKWgz4
-+NpfNPeOQm2UFQT5vIWAyjGWrZGViB8bp0UvVOcJI5nxaOiZfOYOcdrWu75uRAkAn
-+67zMc9/j1lPJRJz2Dc7nDBD+ikTz7pcBV897AWLCiK4jbBOi91q+3YzgKXO8VNsZ
-+nlUJasA2psbqSBJ5OJ5zAkEA2UxoMju54hASjT54Z92IzraVw4Vo8CYwOcw5fr7z
-++m5xg1mmWdLBclmZ+WjARzDuTHIW6u/WCxNGg42AykWzfw==
- -----END RSA PRIVATE KEY-----
diff --git a/packaging/rpm-uln/mysql-install-test.patch b/packaging/rpm-uln/mysql-install-test.patch
deleted file mode 100644
index 5980aea6a9f..00000000000
--- a/packaging/rpm-uln/mysql-install-test.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-Improve the documentation that will be installed in the mysql-test RPM.
-
-
-diff -Naur mysql-5.1.43.orig/mysql-test/README mysql-5.1.43/mysql-test/README
---- mysql-5.1.43.orig/mysql-test/README 2010-01-15 12:14:43.000000000 -0500
-+++ mysql-5.1.43/mysql-test/README 2010-02-13 21:18:06.000000000 -0500
-@@ -6,6 +6,16 @@
- actually have a co-existing MySQL installation. The tests will not
- conflict with it.
-
-+For use in Red Hat distributions, you should run the script as user mysql,
-+so the best bet is something like
-+ cd /usr/share/mysql-test
-+ sudo -u mysql ./mysql-test-run
-+This will use the installed mysql executables, but will run a private copy
-+of the server process (using data files within /usr/share/mysql-test),
-+so you need not start the mysqld service beforehand.
-+To clean up afterwards, remove the created "var" subdirectory, eg
-+ sudo -u mysql rm -rf /usr/share/mysql-test/var
-+
- All tests must pass. If one or more of them fail on your system, please
- read the following manual section for instructions on how to report the
- problem:
-@@ -25,7 +35,8 @@
-
- With no test cases named on the command line, mysql-test-run falls back
- to the normal "non-extern" behavior. The reason for this is that some
--tests cannot run with an external server.
-+tests cannot run with an external server (because they need to control the
-+options with which the server is started).
-
-
- You can create your own test cases. To create a test case, create a new
diff --git a/packaging/rpm-uln/mysql-strmov.patch b/packaging/rpm-uln/mysql-strmov.patch
deleted file mode 100644
index a144d0936e4..00000000000
--- a/packaging/rpm-uln/mysql-strmov.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-Remove overly optimistic definition of strmov() as stpcpy().
-
-mysql uses this macro with overlapping source and destination strings,
-which is verboten per spec, and fails on some Red Hat platforms.
-Deleting the definition is sufficient to make it fall back to a
-byte-at-a-time copy loop, which should consistently give the
-expected behavior.
-
-Note: the particular case that prompted this patch is reported and fixed
-at http://bugs.mysql.com/bug.php?id=48864. However, my faith in upstream's
-ability to detect this type of error is low, and I also see little evidence
-of any real performance gain from optimizing these calls. So I'm keeping
-this patch.
-
-
-diff -Naur mysql-5.1.37.orig/include/m_string.h mysql-5.1.37/include/m_string.h
---- mysql-5.1.37.orig/include/m_string.h 2009-07-13 19:08:50.000000000 -0400
-+++ mysql-5.1.37/include/m_string.h 2009-08-31 21:49:49.000000000 -0400
-@@ -81,13 +81,6 @@
- extern void *(*my_str_malloc)(size_t);
- extern void (*my_str_free)(void *);
-
--#if defined(HAVE_STPCPY)
--#define strmov(A,B) stpcpy((A),(B))
--#ifndef stpcpy
--extern char *stpcpy(char *, const char *); /* For AIX with gcc 2.95.3 */
--#endif
--#endif
--
- /* Declared in int2str() */
- extern char NEAR _dig_vec_upper[];
- extern char NEAR _dig_vec_lower[];
diff --git a/packaging/rpm-uln/mysql.init b/packaging/rpm-uln/mysql.init
deleted file mode 100644
index 310e8cfa023..00000000000
--- a/packaging/rpm-uln/mysql.init
+++ /dev/null
@@ -1,209 +0,0 @@
-#!/bin/sh
-#
-# mysqld This shell script takes care of starting and stopping
-# the MySQL subsystem (mysqld).
-#
-# chkconfig: - 64 36
-# description: MySQL database server.
-# processname: mysqld
-# config: /etc/my.cnf
-# pidfile: /var/run/mysqld/mysqld.pid
-
-# Source function library.
-. /etc/rc.d/init.d/functions
-
-# Source networking configuration.
-. /etc/sysconfig/network
-
-
-exec="/usr/bin/mysqld_safe"
-prog="mysqld"
-
-# Set timeouts here so they can be overridden from /etc/sysconfig/mysqld
-STARTTIMEOUT=120
-STOPTIMEOUT=60
-
-[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
-
-lockfile=/var/lock/subsys/$prog
-
-
-# extract value of a MySQL option from config files
-# Usage: get_mysql_option SECTION VARNAME DEFAULT
-# result is returned in $result
-# We use my_print_defaults which prints all options from multiple files,
-# with the more specific ones later; hence take the last match.
-get_mysql_option(){
- result=`/usr/bin/my_print_defaults "$1" | sed -n "s/^--$2=//p" | tail -n 1`
- if [ -z "$result" ]; then
- # not found, use default
- result="$3"
- fi
-}
-
-get_mysql_option mysqld datadir "/var/lib/mysql"
-datadir="$result"
-get_mysql_option mysqld socket "$datadir/mysql.sock"
-socketfile="$result"
-get_mysql_option mysqld_safe log-error "/var/log/mysqld.log"
-errlogfile="$result"
-get_mysql_option mysqld_safe pid-file "/var/run/mysqld/mysqld.pid"
-mypidfile="$result"
-
-
-start(){
- [ -x $exec ] || exit 5
- # check to see if it's already running
- RESPONSE=`/usr/bin/mysqladmin --socket="$socketfile" --user=UNKNOWN_MYSQL_USER ping 2>&1`
- if [ $? = 0 ]; then
- # already running, do nothing
- action $"Starting $prog: " /bin/true
- ret=0
- elif echo "$RESPONSE" | grep -q "Access denied for user"
- then
- # already running, do nothing
- action $"Starting $prog: " /bin/true
- ret=0
- else
- # prepare for start
- touch "$errlogfile"
- chown mysql:mysql "$errlogfile"
- chmod 0640 "$errlogfile"
- [ -x /sbin/restorecon ] && /sbin/restorecon "$errlogfile"
- if [ ! -d "$datadir/mysql" ] ; then
- # First, make sure $datadir is there with correct permissions
- if [ ! -e "$datadir" -a ! -h "$datadir" ]
- then
- mkdir -p "$datadir" || exit 1
- fi
- chown mysql:mysql "$datadir"
- chmod 0755 "$datadir"
- [ -x /sbin/restorecon ] && /sbin/restorecon "$datadir"
- # Now create the database
- action $"Initializing MySQL database: " /usr/bin/mysql_install_db --datadir="$datadir" --user=mysql
- ret=$?
- chown -R mysql:mysql "$datadir"
- if [ $ret -ne 0 ] ; then
- return $ret
- fi
- fi
- chown mysql:mysql "$datadir"
- chmod 0755 "$datadir"
- # Pass all the options determined above, to ensure consistent behavior.
- # In many cases mysqld_safe would arrive at the same conclusions anyway
- # but we need to be sure. (An exception is that we don't force the
- # log-error setting, since this script doesn't really depend on that,
- # and some users might prefer to configure logging to syslog.)
- # Note: set --basedir to prevent probes that might trigger SELinux
- # alarms, per bug #547485
- $exec --datadir="$datadir" --socket="$socketfile" \
- --pid-file="$mypidfile" \
- --basedir=/usr --user=mysql >/dev/null 2>&1 &
- safe_pid=$!
- # Spin for a maximum of N seconds waiting for the server to come up;
- # exit the loop immediately if mysqld_safe process disappears.
- # Rather than assuming we know a valid username, accept an "access
- # denied" response as meaning the server is functioning.
- ret=0
- TIMEOUT="$STARTTIMEOUT"
- while [ $TIMEOUT -gt 0 ]; do
- RESPONSE=`/usr/bin/mysqladmin --socket="$socketfile" --user=UNKNOWN_MYSQL_USER ping 2>&1` && break
- echo "$RESPONSE" | grep -q "Access denied for user" && break
- if ! /bin/kill -0 $safe_pid 2>/dev/null; then
- echo "MySQL Daemon failed to start."
- ret=1
- break
- fi
- sleep 1
- let TIMEOUT=${TIMEOUT}-1
- done
- if [ $TIMEOUT -eq 0 ]; then
- echo "Timeout error occurred trying to start MySQL Daemon."
- ret=1
- fi
- if [ $ret -eq 0 ]; then
- action $"Starting $prog: " /bin/true
- touch $lockfile
- else
- action $"Starting $prog: " /bin/false
- fi
- fi
- return $ret
-}
-
-stop(){
- if [ ! -f "$mypidfile" ]; then
- # not running; per LSB standards this is "ok"
- action $"Stopping $prog: " /bin/true
- return 0
- fi
- MYSQLPID=`cat "$mypidfile"`
- if [ -n "$MYSQLPID" ]; then
- /bin/kill "$MYSQLPID" >/dev/null 2>&1
- ret=$?
- if [ $ret -eq 0 ]; then
- TIMEOUT="$STOPTIMEOUT"
- while [ $TIMEOUT -gt 0 ]; do
- /bin/kill -0 "$MYSQLPID" >/dev/null 2>&1 || break
- sleep 1
- let TIMEOUT=${TIMEOUT}-1
- done
- if [ $TIMEOUT -eq 0 ]; then
- echo "Timeout error occurred trying to stop MySQL Daemon."
- ret=1
- action $"Stopping $prog: " /bin/false
- else
- rm -f $lockfile
- rm -f "$socketfile"
- action $"Stopping $prog: " /bin/true
- fi
- else
- action $"Stopping $prog: " /bin/false
- fi
- else
- # failed to read pidfile, probably insufficient permissions
- action $"Stopping $prog: " /bin/false
- ret=4
- fi
- return $ret
-}
-
-restart(){
- stop
- start
-}
-
-condrestart(){
- [ -e $lockfile ] && restart || :
-}
-
-
-# See how we were called.
-case "$1" in
- start)
- start
- ;;
- stop)
- stop
- ;;
- status)
- status -p "$mypidfile" $prog
- ;;
- restart)
- restart
- ;;
- condrestart|try-restart)
- condrestart
- ;;
- reload)
- exit 3
- ;;
- force-reload)
- restart
- ;;
- *)
- echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
- exit 2
-esac
-
-exit $?
diff --git a/packaging/rpm-uln/mysql.spec.sh b/packaging/rpm-uln/mysql.spec.sh
deleted file mode 100644
index 34aed51048f..00000000000
--- a/packaging/rpm-uln/mysql.spec.sh
+++ /dev/null
@@ -1,1991 +0,0 @@
-#
-# This file was modified by Oracle in 2011 and later.
-# Details of the modifications are described in the "changelog" section.
-#
-# Modifications copyright (c) 2011, 2012, Oracle and/or its
-# affiliates. All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software 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; see the file COPYING. If not, write to the
-# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston
-# MA 02110-1301 USA.
-
-##############################################################################
-# Some common macro definitions
-##############################################################################
-
-# NOTE: "vendor" is used in upgrade/downgrade check, so you can't
-# change these, has to be exactly as is.
-# %define mysql_old_vendor MySQL AB # Applies to traditional MySQL RPMs only.
-# %define mysql_vendor_2 Sun Microsystems, Inc.
-%define mysql_vendor Oracle and/or its affiliates
-
-%define mysql_version @VERSION@
-
-%define mysqldatadir /var/lib/mysql
-
-%define release 1
-
-##############################################################################
-# Command line handling
-##############################################################################
-#
-# To set options:
-#
-# $ rpmbuild --define="option <x>" ...
-#
-
-# ----------------------------------------------------------------------------
-# Commercial builds
-# ----------------------------------------------------------------------------
-%if %{undefined commercial}
-%define commercial 0
-%endif
-
-# ----------------------------------------------------------------------------
-# Source name
-# ----------------------------------------------------------------------------
-%if %{undefined src_base}
-%define src_base mysql
-%endif
-%define src_dir %{src_base}-%{mysql_version}
-
-# ----------------------------------------------------------------------------
-# Feature set (storage engines, options). Default to community (everything)
-# ----------------------------------------------------------------------------
-%if %{undefined feature_set}
-%define feature_set community
-%endif
-
-# ----------------------------------------------------------------------------
-# Server comment strings
-# ----------------------------------------------------------------------------
-%if %{undefined compilation_comment_debug}
-%define compilation_comment_debug MySQL Community Server - Debug (GPL)
-%endif
-%if %{undefined compilation_comment_release}
-%define compilation_comment_release MySQL Community Server (GPL)
-%endif
-
-# ----------------------------------------------------------------------------
-# Product and server suffixes
-# ----------------------------------------------------------------------------
-%if %{undefined product_suffix}
- %if %{defined short_product_tag}
- %define product_suffix -%{short_product_tag}
- %else
- %define product_suffix %{nil}
- %endif
-%endif
-
-%if %{undefined server_suffix}
-%define server_suffix %{nil}
-%endif
-
-# ----------------------------------------------------------------------------
-# Distribution support
-# ----------------------------------------------------------------------------
-%if %{undefined distro_specific}
-%define distro_specific 0
-%endif
-%if %{distro_specific}
- %if %(test -f /etc/oracle-release && echo 1 || echo 0)
- %define elver %(rpm -qf --qf '%%{version}\\n' /etc/oracle-release | sed -e 's/^\\([0-9]*\\).*/\\1/g')
- %if "%elver" == "6"
- %define distro_description Oracle Linux 6
- %define distro_releasetag el6
- %define distro_buildreq gcc-c++ ncurses-devel perl readline-devel time zlib-devel
- %define distro_requires chkconfig coreutils grep procps shadow-utils net-tools
- %else
- %{error:Oracle Linux %{elver} is unsupported}
- %endif
- %else
- %if %(test -f /etc/redhat-release && echo 1 || echo 0)
- %define rhelver %(rpm -qf --qf '%%{version}\\n' /etc/redhat-release | sed -e 's/^\\([0-9]*\\).*/\\1/g')
- %if "%rhelver" == "5"
- %define distro_description Red Hat Enterprise Linux 5
- %define distro_releasetag rhel5
- %define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel
- %define distro_requires chkconfig coreutils grep procps shadow-utils net-tools
- %else
- %if "%rhelver" == "6"
- %define distro_description Red Hat Enterprise Linux 6
- %define distro_releasetag rhel6
- %define distro_buildreq gcc-c++ ncurses-devel perl readline-devel time zlib-devel
- %define distro_requires chkconfig coreutils grep procps shadow-utils net-tools
- %else
- %{error:Red Hat Enterprise Linux %{rhelver} is unsupported}
- %endif
- %endif
- %else
- %if %(test -f /etc/SuSE-release && echo 1 || echo 0)
- %define susever %(rpm -qf --qf '%%{version}\\n' /etc/SuSE-release | cut -d. -f1)
- %if "%susever" == "10"
- %define distro_description SUSE Linux Enterprise Server 10
- %define distro_releasetag sles10
- %define distro_buildreq gcc-c++ gdbm-devel gperf ncurses-devel openldap2-client readline-devel zlib-devel
- %define distro_requires aaa_base coreutils grep procps pwdutils
- %else
- %if "%susever" == "11"
- %define distro_description SUSE Linux Enterprise Server 11
- %define distro_releasetag sles11
- %define distro_buildreq gcc-c++ gdbm-devel gperf ncurses-devel openldap2-client procps pwdutils readline-devel zlib-devel
- %define distro_requires aaa_base coreutils grep procps pwdutils
- %else
- %{error:SuSE %{susever} is unsupported}
- %endif
- %endif
- %else
- %{error:Unsupported distribution}
- %endif
- %endif
- %endif
-%else
- %define generic_kernel %(uname -r | cut -d. -f1-2)
- %define distro_description Generic Linux (kernel %{generic_kernel})
- %define distro_releasetag linux%{generic_kernel}
- %define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel
- %define distro_requires coreutils grep procps /sbin/chkconfig /usr/sbin/useradd /usr/sbin/groupadd
-%endif
-
-# Avoid debuginfo RPMs, leaves binaries unstripped
-%define debug_package %{nil}
-
-# Hack to work around bug in RHEL5 __os_install_post macro, wrong inverted
-# test for __debug_package
-%define __strip /bin/true
-
-# ----------------------------------------------------------------------------
-# Support optional "tcmalloc" library (experimental)
-# ----------------------------------------------------------------------------
-%if %{defined malloc_lib_target}
-%define WITH_TCMALLOC 1
-%else
-%define WITH_TCMALLOC 0
-%endif
-
-##############################################################################
-# Configuration based upon above user input, not to be set directly
-##############################################################################
-
-%if %{commercial}
-%define license_files_server %{src_dir}/LICENSE.mysql
-%define license_type Commercial
-%else
-%define license_files_server %{src_dir}/COPYING %{src_dir}/README
-%define license_type GPL
-%endif
-
-##############################################################################
-# Main spec file section
-##############################################################################
-
-Name: mysql%{product_suffix}
-Summary: MySQL client programs and shared libraries
-Group: Applications/Databases
-Version: @MYSQL_RPM_VERSION@
-Release: %{release}%{?distro_releasetag:.%{distro_releasetag}}
-# exceptions allow client libraries to be linked with most open source SW,
-# not only GPL code.
-License: Copyright (c) 2000, @MYSQL_COPYRIGHT_YEAR@, %{mysql_vendor}. All rights reserved. Under %{license_type} license as shown in the Description field.
-URL: http://www.mysql.com/
-Packager: MySQL Release Engineering <mysql-build@oss.oracle.com>
-Vendor: %{mysql_vendor}
-
-# Regression tests may take a long time, override the default to skip them
-%{!?runselftest:%global runselftest 1}
-
-# Upstream has a mirror redirector for downloads, so the URL is hard to
-# represent statically. You can get the tarball by following a link from
-# http://dev.mysql.com/downloads/mysql/
-Source0: %{src_dir}.tar.gz
-# The upstream tarball includes non-free documentation that only the
-# copyright holder (MySQL -> Sun -> Oracle) may ship.
-# To remove the non-free documentation, run this script after downloading
-# the tarball into the current directory:
-# ./generate-tarball.sh $VERSION
-# Then, source name changes:
-# Source0: mysql-%{version}-nodocs.tar.gz
-%if %{commercial}
-NoSource: 0
-%endif
-Source1: generate-tarball.sh
-Source2: mysql.init
-Source3: my.cnf
-Source4: scriptstub.c
-Source5: my_config.h
-# The below is only needed for packages built outside MySQL -> Sun -> Oracle:
-Source6: README.mysql-docs
-Source9: mysql-embedded-check.c
-# Working around perl dependency checking bug in rpm FTTB. Remove later.
-Source999: filter-requires-mysql.sh
-
-# Patch1: mysql-ssl-multilib.patch Not needed by MySQL (yaSSL), will not work in 5.5 (cmake)
-Patch2: mysql-5.5-errno.patch
-Patch4: mysql-5.5-testing.patch
-Patch5: mysql-install-test.patch
-Patch6: mysql-5.5-stack-guard.patch
-# Patch7: mysql-disable-test.patch Already fixed in current 5.1
-# Patch8: mysql-setschedparam.patch Will not work in 5.5 (cmake)
-# Patch9: mysql-no-docs.patch Will not work in 5.5 (cmake)
-Patch10: mysql-strmov.patch
- # Not used by MySQL
-# Patch12: mysql-cve-2008-7247.patch Already fixed in 5.5
-Patch13: mysql-expired-certs.patch
- # Will not be used by MySQL
-# Patch14: mysql-missing-string-code.patch Undecided, will not work in 5.5 (cmake)
-# Patch15: mysql-lowercase-bug.patch Fixed in MySQL 5.1.54 and 5.5.9
-Patch16: mysql-chain-certs.patch
-Patch17: mysql-5.5-libdir.patch
-Patch18: mysql-5.5-fix-tests.patch
-Patch19: mysql-5.5-mtr1.patch
-
-BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
-BuildRequires: %{distro_buildreq}
-BuildRequires: gawk
-# make test requires time and ps
-BuildRequires: procps
-# Socket and Time::HiRes are needed to run regression tests
-BuildRequires: perl(Socket), perl(Time::HiRes)
-
-Requires: %{distro_requires}
-Requires: fileutils
-Requires: mysql-libs%{product_suffix} = %{version}-%{release}
-Requires: bash
-
-# If %%{product_suffix} is non-empty, the auto-generated capability is insufficient:
-# We want all dependency handling to use the generic name only.
-# Similar in other sub-packages
-Provides: mysql
-
-# MySQL (with caps) is upstream's spelling of their own RPMs for mysql
-Obsoletes: MySQL
-# mysql-cluster used to be built from this SRPM, but no more
-Obsoletes: mysql-cluster < 5.1.44
-# We need cross-product "Obsoletes:" to allow cross-product upgrades:
-Obsoletes: mysql < %{version}-%{release}
-Obsoletes: mysql-advanced < %{version}-%{release}
-
-# Working around perl dependency checking bug in rpm FTTB. Remove later.
-%global __perl_requires %{SOURCE999}
-
-%description -n mysql%{product_suffix}
-MySQL is a multi-user, multi-threaded SQL database server. MySQL is a
-client/server implementation consisting of a server daemon (mysqld)
-and many different client programs and libraries. The base package
-contains the standard MySQL client programs and generic MySQL files.
-
-The MySQL software has Dual Licensing, which means you can use the MySQL
-software free of charge under the GNU General Public License
-(http://www.gnu.org/licenses/). You can also purchase commercial MySQL
-licenses from %{mysql_vendor} if you do not wish to be bound by the terms of
-the GPL. See the chapter "Licensing and Support" in the manual for
-further info.
-
-%package -n mysql-libs%{product_suffix}
-
-Summary: The shared libraries required for MySQL clients
-Group: Applications/Databases
-Requires: /sbin/ldconfig
-Obsoletes: mysql-libs < %{version}-%{release}
-Obsoletes: mysql-libs-advanced < %{version}-%{release}
-Provides: mysql-libs
-
-%description -n mysql-libs%{product_suffix}
-The mysql-libs package provides the essential shared libraries for any
-MySQL client program or interface. You will need to install this package
-to use any other MySQL package or any clients that need to connect to a
-MySQL server.
-
-%package -n mysql-server%{product_suffix}
-
-Summary: The MySQL server and related files
-Group: Applications/Databases
-Requires: mysql%{product_suffix} = %{version}-%{release}
-Requires: sh-utils
-Requires(pre): /usr/sbin/useradd
-Requires(post): chkconfig
-Requires(preun): chkconfig
-# This is for /sbin/service
-Requires(preun): initscripts
-Requires(postun): initscripts
-# mysqlhotcopy needs DBI/DBD support
-Requires: perl-DBI, perl-DBD-MySQL
-Obsoletes: MySQL-server
-Obsoletes: mysql-server < %{version}-%{release}
-Obsoletes: mysql-server-advanced < %{version}-%{release}
-Provides: mysql-server
-
-%description -n mysql-server%{product_suffix}
-MySQL is a multi-user, multi-threaded SQL database server. MySQL is a
-client/server implementation consisting of a server daemon (mysqld)
-and many different client programs and libraries. This package contains
-the MySQL server and some accompanying files and directories.
-
-%package -n mysql-devel%{product_suffix}
-
-Summary: Files for development of MySQL applications
-Group: Applications/Databases
-Requires: mysql%{product_suffix} = %{version}-%{release}
-Requires: openssl-devel
-Obsoletes: MySQL-devel
-Obsoletes: mysql-devel < %{version}-%{release}
-Obsoletes: mysql-devel-advanced < %{version}-%{release}
-Provides: mysql-devel
-
-%description -n mysql-devel%{product_suffix}
-MySQL is a multi-user, multi-threaded SQL database server. This
-package contains the libraries and header files that are needed for
-developing MySQL client applications.
-
-%package -n mysql-embedded%{product_suffix}
-
-Summary: MySQL as an embeddable library
-Group: Applications/Databases
-Obsoletes: mysql-embedded < %{version}-%{release}
-Obsoletes: mysql-embedded-advanced < %{version}-%{release}
-Provides: mysql-embedded
-
-%description -n mysql-embedded%{product_suffix}
-MySQL is a multi-user, multi-threaded SQL database server. This
-package contains a version of the MySQL server that can be embedded
-into a client application instead of running as a separate process,
-as well as a command line client with such an embedded server.
-
-%package -n mysql-embedded-devel%{product_suffix}
-
-Summary: Development files for MySQL as an embeddable library
-Group: Applications/Databases
-Requires: mysql-embedded%{product_suffix} = %{version}-%{release}
-Requires: mysql-devel%{product_suffix} = %{version}-%{release}
-Obsoletes: mysql-embedded-devel < %{version}-%{release}
-Obsoletes: mysql-embedded-devel-advanced < %{version}-%{release}
-Provides: mysql-embedded-devel
-
-%description -n mysql-embedded-devel%{product_suffix}
-MySQL is a multi-user, multi-threaded SQL database server. This
-package contains files needed for developing and testing with
-the embedded version of the MySQL server.
-
-%package -n mysql-test%{product_suffix}
-
-Summary: The test suite distributed with MySQL
-Group: Applications/Databases
-Requires: mysql%{product_suffix} = %{version}-%{release}
-Requires: mysql-server%{product_suffix} = %{version}-%{release}
-Obsoletes: MySQL-test
-Obsoletes: mysql-test < %{version}-%{release}
-Obsoletes: mysql-test-advanced < %{version}-%{release}
-Provides: mysql-test
-
-%description -n mysql-test%{product_suffix}
-MySQL is a multi-user, multi-threaded SQL database server. This
-package contains the regression test suite distributed with
-the MySQL sources.
-
-%prep
-%setup -T -a 0 -c -n %{src_dir}
-
-cd %{src_dir} # read about "%setup -n"
-# %patch1 -p1
-%patch2 -p1
-# %patch4 -p1 TODO / FIXME: if wanted, needs to be adapted to new mysql-test-run setup
-%patch5 -p1
-%patch6 -p1
-# %patch8 -p1
-# %patch9 -p1
-# %patch10 -p1
-# %patch13 -p1
-# %patch14 -p1
-%patch16 -p1
-%patch17 -p1
-%patch18 -p1
-%patch19 -p1
-
-# workaround for upstream bug #56342
-rm -f mysql-test/t/ssl_8k_key-master.opt
-
-%build
-
-# Fail quickly and obviously if user tries to build as root
-%if %runselftest
- if [ x"`id -u`" = x0 ]; then
- echo "The MySQL regression tests may fail if run as root."
- echo "If you really need to build the RPM as root, use"
- echo "--define='runselftest 0' to skip the regression tests."
- exit 1
- fi
-%endif
-
-# Be strict about variables, bail at earliest opportunity, etc.
-set -eu
-
-# Optional package files
-touch optional-files-devel
-
-#
-# Set environment in order of preference, MYSQL_BUILD_* first, then variable
-# name, finally a default. RPM_OPT_FLAGS is assumed to be a part of the
-# default RPM build environment.
-#
-# We set CXX=gcc by default to support so-called 'generic' binaries, where we
-# do not have a dependancy on libgcc/libstdc++. This only works while we do
-# not require C++ features such as exceptions, and may need to be removed at
-# a later date.
-#
-
-# This is a hack, $RPM_OPT_FLAGS on ia64 hosts contains flags which break
-# the compile in cmd-line-utils/readline - needs investigation, but for now
-# we simply unset it and use those specified directly in cmake.
-%if "%{_arch}" == "ia64"
-RPM_OPT_FLAGS=
-%endif
-
-# This goes in sync with Patch19. "rm" is faster than "patch" for this.
-rm -rf %{src_dir}/mysql-test/lib/v1
-
-export PATH=${MYSQL_BUILD_PATH:-$PATH}
-export CC=${MYSQL_BUILD_CC:-${CC:-gcc}}
-export CXX=${MYSQL_BUILD_CXX:-${CXX:-gcc}}
-export CFLAGS=${MYSQL_BUILD_CFLAGS:-${CFLAGS:-$RPM_OPT_FLAGS}}
-# Following "%ifarch" developed by RedHat, MySQL/Oracle does not support/maintain Linux/Sparc:
-# gcc seems to have some bugs on sparc as of 4.4.1, back off optimization
-# submitted as bz #529298
-%ifarch sparc sparcv9 sparc64
-CFLAGS=`echo $CFLAGS| sed -e "s|-O2|-O1|g" `
-%endif
-export CXXFLAGS=${MYSQL_BUILD_CXXFLAGS:-${CXXFLAGS:-$RPM_OPT_FLAGS -felide-constructors -fno-exceptions -fno-rtti}}
-export LDFLAGS=${MYSQL_BUILD_LDFLAGS:-${LDFLAGS:-}}
-export CMAKE=${MYSQL_BUILD_CMAKE:-${CMAKE:-cmake}}
-export MAKE_JFLAG=${MYSQL_BUILD_MAKE_JFLAG:-%{?_smp_mflags}}
-
-# Build debug mysqld and libmysqld.a
-mkdir debug
-(
- cd debug
- # Attempt to remove any optimisation flags from the debug build
- CFLAGS=`echo " ${CFLAGS} " | \
- sed -e 's/ -O[0-9]* / /' \
- -e 's/ -unroll2 / /' \
- -e 's/ -ip / /' \
- -e 's/^ //' \
- -e 's/ $//'`
- CXXFLAGS=`echo " ${CXXFLAGS} " | \
- sed -e 's/ -O[0-9]* / /' \
- -e 's/ -unroll2 / /' \
- -e 's/ -ip / /' \
- -e 's/^ //' \
- -e 's/ $//'`
- # XXX: MYSQL_UNIX_ADDR should be in cmake/* but mysql_version is included before
- # XXX: install_layout so we can't just set it based on INSTALL_LAYOUT=RPM
- ${CMAKE} ../%{src_dir} -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM \
- -DCMAKE_BUILD_TYPE=Debug \
- -DMYSQL_UNIX_ADDR="%{mysqldatadir}/mysql.sock" \
- -DFEATURE_SET="%{feature_set}" \
- -DCOMPILATION_COMMENT="%{compilation_comment_debug}" \
- -DMYSQL_SERVER_SUFFIX="%{server_suffix}"
- echo BEGIN_DEBUG_CONFIG ; egrep '^#define' include/config.h ; echo END_DEBUG_CONFIG
- make ${MAKE_JFLAG} VERBOSE=1
-)
-# Build full release
-mkdir release
-(
- cd release
- # XXX: MYSQL_UNIX_ADDR should be in cmake/* but mysql_version is included before
- # XXX: install_layout so we can't just set it based on INSTALL_LAYOUT=RPM
- ${CMAKE} ../%{src_dir} -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM \
- -DCMAKE_BUILD_TYPE=RelWithDebInfo \
- -DMYSQL_UNIX_ADDR="%{mysqldatadir}/mysql.sock" \
- -DFEATURE_SET="%{feature_set}" \
- -DCOMPILATION_COMMENT="%{compilation_comment_release}" \
- -DMYSQL_SERVER_SUFFIX="%{server_suffix}"
- echo BEGIN_NORMAL_CONFIG ; egrep '^#define' include/config.h ; echo END_NORMAL_CONFIG
- make ${MAKE_JFLAG} VERBOSE=1
-)
-
-# TODO / FIXME: Do we need "scriptstub"?
-gcc $CFLAGS $LDFLAGS -o scriptstub "-DLIBDIR=\"%{_libdir}/mysql\"" %{SOURCE4}
-
-# TODO / FIXME: "libmysqld.so" should have been produced above
-# regular build will make libmysqld.a but not libmysqld.so :-(
-cd release
-mkdir libmysqld/work
-cd libmysqld/work
-# "libmysqld" provides the same ABI as "libmysqlclient", but it implements the server:
-# The shared object is identified by the full version,
-# for linkage selection the first two levels are sufficient so that upgrades are possible
-# (see "man ld", option "-soname").
-SO_FULL='%{mysql_version}'
-SO_USE=`echo $SO_FULL | sed -e 's/\([0-9]\.[0-9]\)\.[0-9]*/\1/'`
-# These two modules should pull everything else which is needed:
-ar -x ../libmysqld.a client.c.o signal_handler.cc.o
-gcc $CFLAGS $LDFLAGS -shared -Wl,-soname,libmysqld.so.$SO_USE -o libmysqld.so.$SO_FULL \
- *.o ../libmysqld.a \
- -lpthread -lcrypt -laio -lnsl -lssl -lcrypto -lz -lrt -lstdc++ -lm -lc
-# this is to check that we built a complete library
-cp %{SOURCE9} .
-PROGNAME=`basename %{SOURCE9} .c`
-ln -s libmysqld.so.$SO_FULL libmysqld.so.$SO_USE
-gcc -I../../include -I../../../%{src_dir}/include $CFLAGS -o $PROGNAME %{SOURCE9} libmysqld.so.$SO_USE
-LD_LIBRARY_PATH=. ldd $PROGNAME
-cd ../..
-cd ..
-
-# TODO / FIXME: autotools only?
-# make check
-
-# TODO / FIXME: Test suite is run elsewhere in release builds -
-# do we need this for users who want to build from source?
-# Also, check whether MTR_BUILD_THREAD=auto would solve all issues
-%if %runselftest
- # hack to let 32- and 64-bit tests run concurrently on same build machine
- case `uname -m` in
- ppc64 | s390x | x86_64 | sparc64 )
- MTR_BUILD_THREAD=7
- ;;
- *)
- MTR_BUILD_THREAD=11
- ;;
- esac
- export MTR_BUILD_THREAD
-
- # if you want to change which tests are run, look at mysql-5.5-testing.patch too.
- (cd release && make test-bt-fast )
-%endif
-
-%install
-RBR=$RPM_BUILD_ROOT
-MBD=$RPM_BUILD_DIR/%{src_dir}
-[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
-
-# Ensure that needed directories exists
-# TODO / FIXME: needed ? install -d $RBR%{mysqldatadir}/mysql
-# TODO / FIXME: needed ? install -d $RBR%{_datadir}/mysql-test
-# TODO / FIXME: needed ? install -d $RBR%{_datadir}/mysql/SELinux/RHEL4
-# TODO / FIXME: needed ? install -d $RBR%{_includedir}
-# TODO / FIXME: needed ? install -d $RBR%{_libdir}
-# TODO / FIXME: needed ? install -d $RBR%{_mandir}
-# TODO / FIXME: needed ? install -d $RBR%{_sbindir}
-
-# Install all binaries
-(
- cd $MBD/release
- make DESTDIR=$RBR install
-)
-
-# For gcc builds, include libgcc.a in the devel subpackage (BUG 4921). Do
-# this in a sub-shell to ensure we don't pollute the install environment
-# with compiler bits.
-(
- PATH=${MYSQL_BUILD_PATH:-$PATH}
- CC=${MYSQL_BUILD_CC:-${CC:-gcc}}
- CFLAGS=${MYSQL_BUILD_CFLAGS:-${CFLAGS:-$RPM_OPT_FLAGS}}
- if "${CC}" -v 2>&1 | grep '^gcc.version' >/dev/null 2>&1; then
- libgcc=`${CC} ${CFLAGS} --print-libgcc-file`
- if [ -f ${libgcc} ]; then
- mkdir -p $RBR%{_libdir}/mysql
- install -m 644 ${libgcc} $RBR%{_libdir}/mysql/libmygcc.a
- echo "%{_libdir}/mysql/libmygcc.a" >>optional-files-devel
- fi
- fi
-)
-
-# multilib header hacks
-# we only apply this to known Red Hat multilib arches, per bug #181335
-case `uname -i` in
- i386 | x86_64 | ppc | ppc64 | s390 | s390x | sparc | sparc64 )
- mv $RPM_BUILD_ROOT/usr/include/mysql/my_config.h $RPM_BUILD_ROOT/usr/include/mysql/my_config_`uname -i`.h
- install -m 644 %{SOURCE5} $RPM_BUILD_ROOT/usr/include/mysql/
- ;;
- *)
- ;;
-esac
-
-mkdir -p $RPM_BUILD_ROOT/var/log
-touch $RPM_BUILD_ROOT/var/log/mysqld.log
-
-# List the installed tree for RPM package maintenance purposes.
-find $RPM_BUILD_ROOT -print | sed "s|^$RPM_BUILD_ROOT||" | sort > ROOTFILES
-
-mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d
-mkdir -p $RPM_BUILD_ROOT/var/run/mysqld
-install -m 0755 -d $RPM_BUILD_ROOT/var/lib/mysql
-install -m 0755 %{SOURCE2} $RPM_BUILD_ROOT/etc/rc.d/init.d/mysqld
-install -m 0644 %{SOURCE3} $RPM_BUILD_ROOT/etc/my.cnf
-# obsolete: mv $RPM_BUILD_ROOT/usr/sql-bench $RPM_BUILD_ROOT%{_datadir}/sql-bench # 'sql-bench' is dropped
-# obsolete: mv $RPM_BUILD_ROOT/usr/mysql-test $RPM_BUILD_ROOT%{_datadir}/mysql-test # 'mysql-test' is there already
-# 5.1.32 forgets to install the mysql-test README file
-# obsolete: install -m 0644 mysql-test/README $RPM_BUILD_ROOT%{_datadir}/mysql-test/README # 'README' is there already
-
-mv ${RPM_BUILD_ROOT}%{_bindir}/mysqlbug ${RPM_BUILD_ROOT}%{_libdir}/mysql/mysqlbug
-install -m 0755 scriptstub ${RPM_BUILD_ROOT}%{_bindir}/mysqlbug
-mv ${RPM_BUILD_ROOT}%{_bindir}/mysql_config ${RPM_BUILD_ROOT}%{_libdir}/mysql/mysql_config
-install -m 0755 scriptstub ${RPM_BUILD_ROOT}%{_bindir}/mysql_config
-
-rm -f ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.a
-SO_FULL='%{mysql_version}'
-SO_USE=`echo $SO_FULL | sed -e 's/\([0-9]\.[0-9]\)\.[0-9]*/\1/'`
-install -m 0755 release/libmysqld/work/libmysqld.so.$SO_FULL ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.so.$SO_FULL
-ln -s libmysqld.so.$SO_FULL ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.so.$SO_USE
-ln -s libmysqld.so.$SO_USE ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.so
-
-rm -f ${RPM_BUILD_ROOT}%{_bindir}/comp_err
-rm -f ${RPM_BUILD_ROOT}%{_mandir}/man1/comp_err.1*
-rm -f ${RPM_BUILD_ROOT}%{_bindir}/make_win_binary_distribution
-rm -f ${RPM_BUILD_ROOT}%{_bindir}/make_win_src_distribution
-rm -f ${RPM_BUILD_ROOT}%{_mandir}/man1/make_win_bin_dist.1*
-rm -f ${RPM_BUILD_ROOT}%{_mandir}/man1/make_win_src_distribution.1*
-rm -f ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqlclient*.la
-rm -f ${RPM_BUILD_ROOT}%{_libdir}/mysql/*.a
-rm -f ${RPM_BUILD_ROOT}%{_libdir}/mysql/plugin/*.la
-rm -f ${RPM_BUILD_ROOT}%{_libdir}/mysql/plugin/*.a
-rm -f ${RPM_BUILD_ROOT}%{_datadir}/mysql/binary-configure
-rm -f ${RPM_BUILD_ROOT}%{_datadir}/mysql/make_binary_distribution
-rm -f ${RPM_BUILD_ROOT}%{_datadir}/mysql/make_sharedlib_distribution
-rm -f ${RPM_BUILD_ROOT}%{_datadir}/mysql/mi_test_all*
-rm -f ${RPM_BUILD_ROOT}%{_datadir}/mysql/ndb-config-2-node.ini
-rm -f ${RPM_BUILD_ROOT}%{_datadir}/mysql/mysql.server
-rm -f ${RPM_BUILD_ROOT}%{_datadir}/mysql/mysqld_multi.server
-rm -f ${RPM_BUILD_ROOT}%{_datadir}/mysql/MySQL-shared-compat.spec
-rm -f ${RPM_BUILD_ROOT}%{_datadir}/mysql/*.plist
-rm -f ${RPM_BUILD_ROOT}%{_datadir}/mysql/preinstall
-rm -f ${RPM_BUILD_ROOT}%{_datadir}/mysql/postinstall
-rm -f ${RPM_BUILD_ROOT}%{_datadir}/mysql/mysql-*.spec
-rm -f ${RPM_BUILD_ROOT}%{_datadir}/mysql/mysql-log-rotate
-rm -f ${RPM_BUILD_ROOT}%{_datadir}/mysql/ChangeLog
-rm -f ${RPM_BUILD_ROOT}%{_mandir}/man1/mysql-stress-test.pl.1*
-rm -f ${RPM_BUILD_ROOT}%{_mandir}/man1/mysql-test-run.pl.1*
-rm -rf ${RPM_BUILD_ROOT}%{_datadir}/mysql/solaris
-
-mkdir -p $RPM_BUILD_ROOT/etc/ld.so.conf.d
-echo "%{_libdir}/mysql" > $RPM_BUILD_ROOT/etc/ld.so.conf.d/%{name}-%{_arch}.conf
-
-# The below *only* applies to builds not done by MySQL / Sun / Oracle:
-# copy additional docs into build tree so %%doc will find them
-# cp %{SOURCE6} README.mysql-docs
-
-%clean
-[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
-
-%pre -n mysql-server%{product_suffix}
-
-# Check if we can safely upgrade. An upgrade is only safe if it's from one
-# of our RPMs in the same version family.
-
-# Handle both ways of spelling the capability.
-installed=`rpm -q --whatprovides mysql-server 2> /dev/null`
-if [ $? -ne 0 -o -z "$installed" ]; then
- installed=`rpm -q --whatprovides MySQL-server 2> /dev/null`
-fi
-if [ $? -eq 0 -a -n "$installed" ]; then
- installed=`echo $installed | sed 's/\([^ ]*\) .*/\1/'` # Tests have shown duplicated package names
- vendor=`rpm -q --queryformat='%{VENDOR}' "$installed" 2>&1`
- version=`rpm -q --queryformat='%{VERSION}' "$installed" 2>&1`
- myvendor='%{mysql_vendor}'
- myversion='%{mysql_version}'
-
- old_family=`echo $version \
- | sed -n -e 's,^\([1-9][0-9]*\.[0-9][0-9]*\)\..*$,\1,p'`
- new_family=`echo $myversion \
- | sed -n -e 's,^\([1-9][0-9]*\.[0-9][0-9]*\)\..*$,\1,p'`
-
- [ -z "$vendor" ] && vendor='<unknown>'
- [ -z "$old_family" ] && old_family="<unrecognized version $version>"
- [ -z "$new_family" ] && new_family="<bad package specification: version $myversion>"
-
- error_text=
- if [ "$vendor" != "$myvendor" ]; then
- error_text="$error_text
-The current MySQL server package is provided by a different
-vendor ($vendor) than $myvendor.
-Some files may be installed to different locations, including log
-files and the service startup script in %{_sysconfdir}/init.d/.
-"
- fi
-
- if [ "$old_family" != "$new_family" ]; then
- error_text="$error_text
-Upgrading directly from MySQL $old_family to MySQL $new_family may not
-be safe in all cases. A manual dump and restore using mysqldump is
-recommended. It is important to review the MySQL manual's Upgrading
-section for version-specific incompatibilities.
-"
- fi
-
- if [ -n "$error_text" ]; then
- cat <<HERE >&2
-
-******************************************************************
-A MySQL server package ($installed) is installed.
-$error_text
-A manual upgrade is required.
-
-- Ensure that you have a complete, working backup of your data and my.cnf
- files
-- Shut down the MySQL server cleanly
-- Remove the existing MySQL packages. Usually this command will
- list the packages you should remove:
- rpm -qa | grep -i '^mysql-'
-
- You may choose to use 'rpm --nodeps -ev <package-name>' to remove
- the package which contains the mysqlclient shared library. The
- library will be reinstalled by the MySQL-shared-compat package.
-- Install the new MySQL packages supplied by $myvendor
-- Ensure that the MySQL server is started
-- Run the 'mysql_upgrade' program
-
-This is a brief description of the upgrade process. Important details
-can be found in the MySQL manual, in the Upgrading section.
-******************************************************************
-HERE
- exit 1
- fi
-fi
-
-/usr/sbin/groupadd -g 27 -o -r mysql >/dev/null 2>&1 || :
-/usr/sbin/useradd -M -N -g mysql -o -r -d /var/lib/mysql -s /bin/bash \
- -c "MySQL Server" -u 27 mysql >/dev/null 2>&1 || :
-
-%post -n mysql-libs%{product_suffix}
-/sbin/ldconfig
-
-%post -n mysql-server%{product_suffix}
-if [ $1 = 1 ]; then
- /sbin/chkconfig --add mysqld
-fi
-/bin/chmod 0755 /var/lib/mysql
-/bin/touch /var/log/mysqld.log
-
-%preun -n mysql-server%{product_suffix}
-if [ $1 = 0 ]; then
- /sbin/service mysqld stop >/dev/null 2>&1
- /sbin/chkconfig --del mysqld
-fi
-
-%postun -n mysql-libs%{product_suffix}
-if [ $1 = 0 ] ; then
- /sbin/ldconfig
-fi
-
-%postun -n mysql-server%{product_suffix}
-if [ $1 -ge 1 ]; then
- /sbin/service mysqld condrestart >/dev/null 2>&1 || :
-fi
-
-
-%files -n mysql%{product_suffix}
-%defattr(-,root,root)
-%doc %{license_files_server}
-
-# The below file *only* applies to builds not done by MySQL / Sun / Oracle:
-# %doc README.mysql-docs
-
-%{_bindir}/msql2mysql
-%{_bindir}/mysql
-%{_bindir}/mysql_config
-%{_bindir}/mysql_find_rows
-%{_bindir}/mysql_waitpid
-%{_bindir}/mysqlaccess
-%{_bindir}/mysqlaccess.conf
-%{_bindir}/mysqladmin
-%{_bindir}/mysqlbinlog
-%{_bindir}/mysqlcheck
-%{_bindir}/mysqldump
-%{_bindir}/mysqlimport
-%{_bindir}/mysqlshow
-%{_bindir}/mysqlslap
-%{_bindir}/my_print_defaults
-
-%{_mandir}/man1/mysql.1*
-%{_mandir}/man1/mysql_config.1*
-%{_mandir}/man1/mysql_find_rows.1*
-%{_mandir}/man1/mysql_waitpid.1*
-%{_mandir}/man1/mysqlaccess.1*
-%{_mandir}/man1/mysqladmin.1*
-%{_mandir}/man1/mysqldump.1*
-%{_mandir}/man1/mysqlshow.1*
-%{_mandir}/man1/mysqlslap.1*
-%{_mandir}/man1/my_print_defaults.1*
-
-%{_libdir}/mysql/mysqlbug
-%{_libdir}/mysql/mysql_config
-
-%files -n mysql-libs%{product_suffix}
-%defattr(-,root,root)
-%doc %{license_files_server}
-# although the default my.cnf contains only server settings, we put it in the
-# libs package because it can be used for client settings too.
-%config(noreplace) /etc/my.cnf
-%dir %{_libdir}/mysql
-%{_libdir}/mysql/libmysqlclient*.so.*
-/etc/ld.so.conf.d/*
-
-%dir %{_datadir}/mysql
-%{_datadir}/mysql/english
-%lang(cs) %{_datadir}/mysql/czech
-%lang(da) %{_datadir}/mysql/danish
-%lang(nl) %{_datadir}/mysql/dutch
-%lang(et) %{_datadir}/mysql/estonian
-%lang(fr) %{_datadir}/mysql/french
-%lang(de) %{_datadir}/mysql/german
-%lang(el) %{_datadir}/mysql/greek
-%lang(hu) %{_datadir}/mysql/hungarian
-%lang(it) %{_datadir}/mysql/italian
-%lang(ja) %{_datadir}/mysql/japanese
-%lang(ko) %{_datadir}/mysql/korean
-%lang(no) %{_datadir}/mysql/norwegian
-%lang(no) %{_datadir}/mysql/norwegian-ny
-%lang(pl) %{_datadir}/mysql/polish
-%lang(pt) %{_datadir}/mysql/portuguese
-%lang(ro) %{_datadir}/mysql/romanian
-%lang(ru) %{_datadir}/mysql/russian
-%lang(sr) %{_datadir}/mysql/serbian
-%lang(sk) %{_datadir}/mysql/slovak
-%lang(es) %{_datadir}/mysql/spanish
-%lang(sv) %{_datadir}/mysql/swedish
-%lang(uk) %{_datadir}/mysql/ukrainian
-%{_datadir}/mysql/charsets
-
-%files -n mysql-server%{product_suffix} -f release/support-files/plugins.files
-%defattr(-,root,root)
-%doc release/support-files/*.cnf
-%if 0%{?commercial}
- %doc %{_datadir}/info/mysql.info*
-%endif
-%doc %{src_dir}/Docs/ChangeLog
-%doc %{src_dir}/Docs/INFO_SRC*
-%doc release/Docs/INFO_BIN*
-
-%{_bindir}/myisamchk
-%{_bindir}/myisam_ftdump
-%{_bindir}/myisamlog
-%{_bindir}/myisampack
-%{_bindir}/mysql_convert_table_format
-%{_bindir}/mysql_fix_extensions
-%{_bindir}/mysql_install_db
-%{_bindir}/mysql_plugin
-%{_bindir}/mysql_secure_installation
-%if %{commercial}
-%else
-%{_bindir}/mysql_setpermission
-%endif
-%{_bindir}/mysql_tzinfo_to_sql
-%{_bindir}/mysql_upgrade
-%{_bindir}/mysql_zap
-%{_bindir}/mysqlbug
-%{_bindir}/mysqldumpslow
-%{_bindir}/mysqld_multi
-%{_bindir}/mysqld_safe
-%{_bindir}/mysqlhotcopy
-%{_bindir}/mysqltest
-%{_bindir}/innochecksum
-%{_bindir}/perror
-%{_bindir}/replace
-%{_bindir}/resolve_stack_dump
-%{_bindir}/resolveip
-
-/usr/libexec/mysqld
-/usr/libexec/mysqld-debug
-%{_libdir}/mysql/plugin/daemon_example.ini
-
-%if %{WITH_TCMALLOC}
-%{_libdir}/mysql/%{malloc_lib_target}
-%endif
-
-# obsolete by "-f release/support-files/plugins.files" above
-# %{_libdir}/mysql/plugin
-
-%{_mandir}/man1/msql2mysql.1*
-%{_mandir}/man1/myisamchk.1*
-%{_mandir}/man1/myisamlog.1*
-%{_mandir}/man1/myisampack.1*
-%{_mandir}/man1/mysql_convert_table_format.1*
-%{_mandir}/man1/myisam_ftdump.1*
-%{_mandir}/man1/mysql.server.1*
-%{_mandir}/man1/mysql_fix_extensions.1*
-%{_mandir}/man1/mysql_install_db.1*
-%{_mandir}/man1/mysql_plugin.1*
-%{_mandir}/man1/mysql_secure_installation.1*
-%{_mandir}/man1/mysql_upgrade.1*
-%{_mandir}/man1/mysql_zap.1*
-%{_mandir}/man1/mysqlbug.1*
-%{_mandir}/man1/mysqldumpslow.1*
-%{_mandir}/man1/mysqlbinlog.1*
-%{_mandir}/man1/mysqlcheck.1*
-%{_mandir}/man1/mysqld_multi.1*
-%{_mandir}/man1/mysqld_safe.1*
-%{_mandir}/man1/mysqlhotcopy.1*
-%{_mandir}/man1/mysqlimport.1*
-%{_mandir}/man1/mysqlman.1*
-%if %{commercial}
-%else
-%{_mandir}/man1/mysql_setpermission.1*
-%endif
-%{_mandir}/man1/mysqltest.1*
-%{_mandir}/man1/innochecksum.1*
-%{_mandir}/man1/perror.1*
-%{_mandir}/man1/replace.1*
-%{_mandir}/man1/resolve_stack_dump.1*
-%{_mandir}/man1/resolveip.1*
-%{_mandir}/man1/mysql_tzinfo_to_sql.1*
-%{_mandir}/man8/mysqld.8*
-
-%{_datadir}/mysql/errmsg-utf8.txt
-%{_datadir}/mysql/fill_help_tables.sql
-%{_datadir}/mysql/magic
-%{_datadir}/mysql/mysql_system_tables.sql
-%{_datadir}/mysql/mysql_system_tables_data.sql
-%{_datadir}/mysql/mysql_test_data_timezone.sql
-%{_datadir}/mysql/my-*.cnf
-%{_datadir}/mysql/config.*.ini
-
-/etc/rc.d/init.d/mysqld
-%attr(0755,mysql,mysql) %dir /var/run/mysqld
-%attr(0755,mysql,mysql) %dir /var/lib/mysql
-%attr(0640,mysql,mysql) %config(noreplace) %verify(not md5 size mtime) /var/log/mysqld.log
-
-# TODO / FIXME: Do we need "libmygcc.a"? If yes, append "-f optional-files-devel"
-# and fix the "rm -f" list in the "install" section.
-%files -n mysql-devel%{product_suffix}
-%defattr(-,root,root)
-/usr/include/mysql
-/usr/share/aclocal/mysql.m4
-%{_libdir}/mysql/libmysqlclient*.so
-
-%files -n mysql-embedded%{product_suffix}
-%defattr(-,root,root)
-%doc %{license_files_server}
-%{_libdir}/mysql/libmysqld.so.*
-%{_bindir}/mysql_embedded
-
-%files -n mysql-embedded-devel%{product_suffix}
-%defattr(-,root,root)
-%{_libdir}/mysql/libmysqld.so
-%{_bindir}/mysql_client_test_embedded
-%{_bindir}/mysqltest_embedded
-%{_mandir}/man1/mysql_client_test_embedded.1*
-%{_mandir}/man1/mysqltest_embedded.1*
-
-%files -n mysql-test%{product_suffix}
-%defattr(-,root,root)
-%{_bindir}/mysql_client_test
-%attr(-,mysql,mysql) %{_datadir}/mysql-test
-
-%{_mandir}/man1/mysql_client_test.1*
-
-%changelog
-* Tue Nov 05 2013 Balasubramanian Kandasamy <balasubramanian.kandasamy@oracle.com>
-- Removed non gpl file mysql.info from community packages
-
-* Wed Jul 10 2013 Balasubramanian Kandasamy <balasubramanian.kandasamy@oracle.com>
-- Removed directory /usr/share/mysql/solaris/postinstall-solaris to resolve build
- error
-
-* Thu Dec 7 2012 Joerg Bruehe <joerg.bruehe@oracle.com>
-- Change the way in which "libmysqld.so" is created: Using all object modules
- was wrong, gcc / ld can resolve the dependencies from "libmysqld.a".
- Also, identify the ".so" version from the MySQL version, "0.0.1" was wrong.
- Bug#15972480
-
-* Tue Sep 18 2012 Joerg Bruehe <joerg.bruehe@oracle.com>
-- Restrict the vendor check to Oracle: There is no history here
- which we have to allow for.
-
-* Thu Jul 26 2012 Joerg Bruehe <joerg.bruehe@oracle.com>
-- Add the vendor and release series checks from the traditional MySQL RPM
- spec file, to protect against errors happening during upgrades.
-- Do some code alignment with the traditional MySQL RPM spec file,
- to make synchronous maintenance (and possibly even integration?) easier.
-
-* Mon Feb 13 2012 Joerg Bruehe <joerg.bruehe@oracle.com>
-- Add "Provides:" lines for the generic names of the subpackages,
- independent of "product_suffix".
-
-* Tue Feb 7 2012 Joerg Bruehe <joerg.bruehe@oracle.com>
-- Make "mysql_setpermission" and its man page appear in GPL builds only.
-
-* Thu Nov 24 2011 Joerg Bruehe <joerg.bruehe@oracle.com>
-- Add two patches (#18 + #19) regarding the test suite;
- version 1 of "mysql-test-run.pl" had to go because the auto-detection
- of Perl dependencies does not handle differences between run directory
- and delivery location.
-
-* Thu Nov 3 2011 Joerg Bruehe <joerg.bruehe@oracle.com>
-- Adapt from MySQL 5.1 to 5.5, tested using 5.5.17:
- - Done by the MySQL Build Team at Oracle:
- set as packager, set copyright owner and related info;
- - handle command line options, allowing different configurations, platforms, ...
- - configurations will show up in the file name as "product_suffix",
- - use "-n" for all subpackage specifications,
- - license may be GPL or commercial, mention that in the description,
- the license output and the included license files will vary,
- - commercial is "nosource",
- - improve "requires" listings for different platforms,
- - explicitly use "product_suffix" in the "requires" entries;
- - adapt to 5.5 changes in features and function:
- - remove "mysql-bench" package (files are outdated, not maintained),
- - no InnoDB plugin,
- - the set of plugins will vary by configuration, to control the "server"
- package contents use "-f release/support-files/plugins.files" in the
- "files" section,
- - remove "mysqlmanager", "mysql_fix_privilege_tables",
- - add "mysql_embedded", "mysql-plugin", "mysqlaccess.conf", "magic",
- - "errmsg.txt" is now in UTF8: "errmsg-utf8.txt",
- - adapt patches to changed code where needed, rename these to include "5.5",
- - stop using patches which are not applicable to 5.5;
- - 5.5 uses a different way of building:
- - autotools are replaced by cmake,
- - both a "release" and a "debug" server are built in separate subtrees
- ("out of source"!), this also affects path names in further handling,
- - the debug server is added to the "server" subpackage,
- - add "mysql-5.5-libdir.patch" to handle file placement at user site.
-
-* Mon Dec 20 2010 Tom Lane <tgl@redhat.com> 5.1.52-1.1
-- Update to MySQL 5.1.52, for various fixes described at
- http://dev.mysql.com/doc/refman/5.1/en/news-5-1-52.html
- including numerous small security issues
-Resolves: #652553
-- Sync with current Fedora package; this includes:
-- Duplicate COPYING and EXCEPTIONS-CLIENT in -libs and -embedded subpackages,
- to ensure they are available when any subset of mysql RPMs are installed,
- per revised packaging guidelines
-- Allow init script's STARTTIMEOUT/STOPTIMEOUT to be overridden from sysconfig
-
-* Thu Jul 15 2010 Tom Lane <tgl@redhat.com> 5.1.47-4
-- Add backported patch for CVE-2010-2008 (upstream bug 53804)
-Resolves: #614215
-- Add BuildRequires perl(Time::HiRes) ... seems to no longer be installed
- by just pulling in perl.
-
-* Mon Jun 28 2010 Tom Lane <tgl@redhat.com> 5.1.47-3
-- Add -p "$mypidfile" to initscript's status call to improve corner cases.
- (Note: can't be fixed in Fedora until 595597 is fixed there.)
-Resolves: #596008
-
-* Mon Jun 7 2010 Tom Lane <tgl@redhat.com> 5.1.47-2
-- Add back "partition" storage engine
-Resolves: #598585
-- Fix broken "federated" storage engine plugin
-Resolves: #587170
-- Read all certificates in SSL certificate files, to support chained certs
-Resolves: #598656
-
-* Mon May 24 2010 Tom Lane <tgl@redhat.com> 5.1.47-1
-- Update to MySQL 5.1.47, for various fixes described at
- http://dev.mysql.com/doc/refman/5.1/en/news-5-1-47.html
- http://dev.mysql.com/doc/refman/5.1/en/news-5-1-46.html
- http://dev.mysql.com/doc/refman/5.1/en/news-5-1-45.html
- including fixes for CVE-2010-1621, CVE-2010-1626,
- CVE-2010-1848, CVE-2010-1849, CVE-2010-1850
-Resolves: #590598
-- Create mysql group explicitly in pre-server script, to ensure correct GID
-
-* Mon Mar 8 2010 Tom Lane <tgl@redhat.com> 5.1.44-2
-- Update to MySQL 5.1.44, for various fixes described at
- http://dev.mysql.com/doc/refman/5.1/en/news-5-1-44.html
-Resolves: #565554
-- Remove mysql.info, which is not freely redistributable
-Related: #560181
-- Revert broken upstream fix for their bug 45058
-Related: #566547
-- Bring init script into some modicum of compliance with Fedora/LSB standards
-Resolves: #557711
-Resolves: #562749
-
-* Mon Feb 15 2010 Tom Lane <tgl@redhat.com> 5.1.43-2
-- Update to MySQL 5.1.43, for various fixes described at
- http://dev.mysql.com/doc/refman/5.1/en/news-5-1-43.html
-Resolves: #565554
-- Remove mysql-cluster, which is no longer supported by upstream in this
- source distribution. If we want it we'll need a separate SRPM for it.
-Resolves: #565210
-
-* Fri Jan 29 2010 Tom Lane <tgl@redhat.com> 5.1.42-7
-- Add backported patch for CVE-2008-7247 (upstream bug 39277)
-Resolves: #549329
-- Use non-expired certificates for SSL testing (upstream bug 50702)
-
-* Tue Jan 26 2010 Tom Lane <tgl@redhat.com> 5.1.42-6
-- Emit explicit error message if user tries to build RPM as root
-Resolves: #558915
-
-* Wed Jan 20 2010 Tom Lane <tgl@redhat.com> 5.1.42-5
-- Correct Source0: tag and comment to reflect how to get the tarball
-
-* Fri Jan 8 2010 Tom Lane <tgl@redhat.com> 5.1.42-4
-- Sync with current Fedora build, including:
-- Update to MySQL 5.1.42, for various fixes described at
- http://dev.mysql.com/doc/refman/5.1/en/news-5-1-42.html
-- Disable symbolic links by default in /etc/my.cnf
-Resolves: #553653
-- Remove static libraries (.a files) from package, per packaging guidelines
-- Change %%define to %%global, per packaging guidelines
-- Disable building the innodb plugin; it tickles assorted gcc bugs and
- doesn't seem entirely ready for prime time anyway.
-Resolves: #553632
-- Start mysqld_safe with --basedir=/usr, to avoid unwanted SELinux messages
- (see 547485)
-- Stop waiting during "service mysqld start" if mysqld_safe exits
-Resolves: #544095
-
-* Mon Nov 23 2009 Tom Lane <tgl@redhat.com> 5.1.41-1
-- Update to MySQL 5.1.41, for various fixes described at
- http://dev.mysql.com/doc/refman/5.1/en/news-5-1-41.html
- including fixes for CVE-2009-4019
-Resolves: #549327
-- Don't set old_passwords=1; we aren't being bug-compatible with 3.23 anymore
-Resolves: #540735
-
-* Tue Nov 10 2009 Tom Lane <tgl@redhat.com> 5.1.40-1
-- Update to MySQL 5.1.40, for various fixes described at
- http://dev.mysql.com/doc/refman/5.1/en/news-5-1-40.html
-- Do not force the --log-error setting in mysqld init script
-Resolves: #533736
-
-* Sat Oct 17 2009 Tom Lane <tgl@redhat.com> 5.1.39-4
-- Replace kluge fix for ndbd sparc crash with a real fix (mysql bug 48132)
-
-* Thu Oct 15 2009 Tom Lane <tgl@redhat.com> 5.1.39-3
-- Work around two different compiler bugs on sparc, one by backing off
- optimization from -O2 to -O1, and the other with a klugy patch
-Related: #529298, #529299
-- Clean up bogosity in multilib stub header support: ia64 should not be
- listed (it's not multilib), sparc and sparc64 should be
-
-* Wed Sep 23 2009 Tom Lane <tgl@redhat.com> 5.1.39-2
-- Work around upstream bug 46895 by disabling outfile_loaddata test
-
-* Tue Sep 22 2009 Tom Lane <tgl@redhat.com> 5.1.39-1
-- Update to MySQL 5.1.39, for various fixes described at
- http://dev.mysql.com/doc/refman/5.1/en/news-5-1-39.html
-
-* Mon Aug 31 2009 Tom Lane <tgl@redhat.com> 5.1.37-5
-- Work around unportable assumptions about stpcpy(); re-enable main.mysql test
-- Clean up some obsolete parameters to the configure script
-
-* Sat Aug 29 2009 Tom Lane <tgl@redhat.com> 5.1.37-4
-- Remove one misguided patch; turns out I was chasing a glibc bug
-- Temporarily disable "main.mysql" test; there's something broken there too,
- but we need to get mysql built in rawhide for dependency reasons
-
-* Fri Aug 21 2009 Tomas Mraz <tmraz@redhat.com> - 5.1.37-3
-- rebuilt with new openssl
-
-* Fri Aug 14 2009 Tom Lane <tgl@redhat.com> 5.1.37-2
-- Add a couple of patches to improve the probability of the regression tests
- completing in koji builds
-
-* Sun Aug 2 2009 Tom Lane <tgl@redhat.com> 5.1.37-1
-- Update to MySQL 5.1.37, for various fixes described at
- http://dev.mysql.com/doc/refman/5.1/en/news-5-1-37.html
-
-* Sat Jul 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 5.1.36-2
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
-
-* Fri Jul 10 2009 Tom Lane <tgl@redhat.com> 5.1.36-1
-- Update to MySQL 5.1.36, for various fixes described at
- http://dev.mysql.com/doc/refman/5.1/en/news-5-1-36.html
-
-* Sat Jun 6 2009 Tom Lane <tgl@redhat.com> 5.1.35-1
-- Update to MySQL 5.1.35, for various fixes described at
- http://dev.mysql.com/doc/refman/5.1/en/news-5-1-35.html
-- Ensure that /var/lib/mysql is created with the right SELinux context
-Resolves: #502966
-
-* Fri May 15 2009 Tom Lane <tgl@redhat.com> 5.1.34-1
-- Update to MySQL 5.1.34, for various fixes described at
- http://dev.mysql.com/doc/refman/5.1/en/news-5-1-34.html
-- Increase startup timeout per bug #472222
-
-* Wed Apr 15 2009 Tom Lane <tgl@redhat.com> 5.1.33-2
-- Increase stack size of ndbd threads for safety's sake.
-Related: #494631
-
-* Tue Apr 7 2009 Tom Lane <tgl@redhat.com> 5.1.33-1
-- Update to MySQL 5.1.33.
-- Disable use of pthread_setschedparam; doesn't work the way code expects.
-Related: #477624
-
-* Wed Mar 4 2009 Tom Lane <tgl@redhat.com> 5.1.32-1
-- Update to MySQL 5.1.32.
-
-* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 5.1.31-2
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
-
-* Fri Feb 13 2009 Tom Lane <tgl@redhat.com> 5.1.31-1
-- Update to MySQL 5.1.31.
-
-* Thu Jan 22 2009 Tom Lane <tgl@redhat.com> 5.1.30-2
-- hm, apparently --with-innodb and --with-ndbcluster are still needed
- even though no longer documented ...
-
-* Thu Jan 22 2009 Tom Lane <tgl@redhat.com> 5.1.30-1
-- Update to MySQL 5.1.30. Note that this includes an ABI break for
- libmysqlclient (it's now got .so major version 16).
-- This also updates mysql for new openssl build
-
-* Wed Oct 1 2008 Tom Lane <tgl@redhat.com> 5.0.67-2
-- Build the "embedded server" library, and package it in a new sub-RPM
- mysql-embedded, along with mysql-embedded-devel for devel support files.
-Resolves: #149829
-
-* Sat Aug 23 2008 Tom Lane <tgl@redhat.com> 5.0.67-1
-- Update to mysql version 5.0.67
-- Move mysql_config's man page to base package, again (apparently I synced
- that change the wrong way while importing specfile changes for ndbcluster)
-
-* Sun Jul 27 2008 Tom Lane <tgl@redhat.com> 5.0.51a-2
-- Enable ndbcluster support
-Resolves: #163758
-- Suppress odd crash messages during package build, caused by trying to
- build dbug manual (which we don't install anyway) with dbug disabled
-Resolves: #437053
-- Improve mysql.init to pass configured datadir to mysql_install_db,
- and to force user=mysql for both mysql_install_db and mysqld_safe.
-Related: #450178
-
-* Mon Mar 3 2008 Tom Lane <tgl@redhat.com> 5.0.51a-1
-- Update to mysql version 5.0.51a
-
-* Mon Mar 3 2008 Tom Lane <tgl@redhat.com> 5.0.45-11
-- Fix mysql-stack-guard patch to work correctly on IA64
-- Fix mysql.init to wait correctly when socket is not in default place
-Related: #435494
-
-* Mon Mar 03 2008 Dennis Gilmore <dennis@ausil.us> 5.0.45-10
-- add sparc64 to 64 bit arches for test suite checking
-- add sparc, sparcv9 and sparc64 to multilib handling
-
-* Thu Feb 28 2008 Tom Lane <tgl@redhat.com> 5.0.45-9
-- Fix the stack overflow problem encountered in January. It seems the real
-issue is that the buildfarm machines were moved to RHEL5, which uses 64K not
-4K pages on PPC, and because RHEL5 takes the guard area out of the requested
-thread stack size we no longer had enough headroom.
-Related: #435337
-
-* Tue Feb 19 2008 Fedora Release Engineering <rel-eng@fedoraproject.org> - 5.0.45-8
-- Autorebuild for GCC 4.3
-
-* Tue Jan 8 2008 Tom Lane <tgl@redhat.com> 5.0.45-7
-- Unbelievable ... upstream still thinks that it's a good idea to have a
- regression test that is guaranteed to begin failing come January 1.
-- ... and it seems we need to raise STACK_MIN_SIZE again too.
-
-* Thu Dec 13 2007 Tom Lane <tgl@redhat.com> 5.0.45-6
-- Back-port upstream fixes for CVE-2007-5925, CVE-2007-5969, CVE-2007-6303.
-Related: #422211
-
-* Wed Dec 5 2007 Tom Lane <tgl@redhat.com> 5.0.45-5
-- Rebuild for new openssl
-
-* Sat Aug 25 2007 Tom Lane <tgl@redhat.com> 5.0.45-4
-- Seems we need explicit BuildRequires on gawk and procps now
-- Rebuild to fix Fedora toolchain issues
-
-* Sun Aug 12 2007 Tom Lane <tgl@redhat.com> 5.0.45-3
-- Recent perl changes in rawhide mean we need a more specific BuildRequires
-
-* Thu Aug 2 2007 Tom Lane <tgl@redhat.com> 5.0.45-2
-- Update License tag to match code.
-- Work around recent Fedora change that makes "open" a macro name.
-
-* Sun Jul 22 2007 Tom Lane <tgl@redhat.com> 5.0.45-1
-- Update to MySQL 5.0.45
-Resolves: #246535
-- Move mysql_config's man page to base package
-Resolves: #245770
-- move my_print_defaults to base RPM, for consistency with Stacks packaging
-- mysql user is no longer deleted at RPM uninstall
-Resolves: #241912
-
-* Thu Mar 29 2007 Tom Lane <tgl@redhat.com> 5.0.37-2
-- Use a less hacky method of getting default values in initscript
-Related: #233771, #194596
-- Improve packaging of mysql-libs per suggestions from Remi Collet
-Resolves: #233731
-- Update default /etc/my.cnf ([mysql.server] has been bogus for a long time)
-
-* Mon Mar 12 2007 Tom Lane <tgl@redhat.com> 5.0.37-1
-- Update to MySQL 5.0.37
-Resolves: #231838
-- Put client library into a separate mysql-libs RPM to reduce dependencies
-Resolves: #205630
-
-* Fri Feb 9 2007 Tom Lane <tgl@redhat.com> 5.0.33-1
-- Update to MySQL 5.0.33
-- Install band-aid fix for "view" regression test designed to fail after 2006
-- Don't chmod -R the entire database directory tree on every startup
-Related: #221085
-- Fix unsafe use of install-info
-Resolves: #223713
-- Cope with new automake in F7
-Resolves: #224171
-
-* Thu Nov 9 2006 Tom Lane <tgl@redhat.com> 5.0.27-1
-- Update to MySQL 5.0.27 (see CVE-2006-4031, CVE-2006-4226, CVE-2006-4227)
-Resolves: #202247, #202675, #203427, #203428, #203432, #203434, #208641
-- Fix init script to return status 1 on server start timeout
-Resolves: #203910
-- Move mysqldumpslow from base package to mysql-server
-Resolves: #193559
-- Adjust link options for BDB module
-Resolves: #199368
-
-* Wed Jul 12 2006 Jesse Keating <jkeating@redhat.com> - 5.0.22-2.1
-- rebuild
-
-* Sat Jun 10 2006 Tom Lane <tgl@redhat.com> 5.0.22-2
-- Work around brew's tendency not to clean up failed builds completely,
- by adding code in mysql-testing.patch to kill leftover mysql daemons.
-
-* Thu Jun 8 2006 Tom Lane <tgl@redhat.com> 5.0.22-1
-- Update to MySQL 5.0.22 (fixes CVE-2006-2753)
-- Install temporary workaround for gcc bug on s390x (bz #193912)
-
-* Tue May 2 2006 Tom Lane <tgl@redhat.com> 5.0.21-2
-- Fix bogus perl Requires for mysql-test
-
-* Mon May 1 2006 Tom Lane <tgl@redhat.com> 5.0.21-1
-- Update to MySQL 5.0.21
-
-* Mon Mar 27 2006 Tom Lane <tgl@redhat.com> 5.0.18-4
-- Modify multilib header hack to not break non-RH arches, per bug #181335
-- Remove logrotate script, per bug #180639.
-- Add a new mysql-test RPM to carry the regression test files;
- hack up test scripts as needed to make them run in /usr/share/mysql-test.
-
-* Fri Feb 10 2006 Jesse Keating <jkeating@redhat.com> - 5.0.18-2.1
-- bump again for double-long bug on ppc(64)
-
-* Thu Feb 9 2006 Tom Lane <tgl@redhat.com> 5.0.18-2
-- err-log option has been renamed to log-error, fix my.cnf and initscript
-
-* Tue Feb 07 2006 Jesse Keating <jkeating@redhat.com> - 5.0.18-1.1
-- rebuilt for new gcc4.1 snapshot and glibc changes
-
-* Thu Jan 5 2006 Tom Lane <tgl@redhat.com> 5.0.18-1
-- Update to MySQL 5.0.18
-
-* Thu Dec 15 2005 Tom Lane <tgl@redhat.com> 5.0.16-4
-- fix my_config.h for ppc platforms
-
-* Thu Dec 15 2005 Tom Lane <tgl@redhat.com> 5.0.16-3
-- my_config.h needs to guard against 64-bit platforms that also define the
- 32-bit symbol
-
-* Wed Dec 14 2005 Tom Lane <tgl@redhat.com> 5.0.16-2
-- oops, looks like we want uname -i not uname -m
-
-* Mon Dec 12 2005 Tom Lane <tgl@redhat.com> 5.0.16-1
-- Update to MySQL 5.0.16
-- Add EXCEPTIONS-CLIENT license info to the shipped documentation
-- Make my_config.h architecture-independent for multilib installs;
- put the original my_config.h into my_config_$ARCH.h
-- Add -fwrapv to CFLAGS so that gcc 4.1 doesn't break it
-
-* Fri Dec 09 2005 Jesse Keating <jkeating@redhat.com>
-- rebuilt
-
-* Mon Nov 14 2005 Tom Lane <tgl@redhat.com> 5.0.15-3
-- Make stop script wait for daemon process to disappear (bz#172426)
-
-* Wed Nov 9 2005 Tom Lane <tgl@redhat.com> 5.0.15-2
-- Rebuild due to openssl library update.
-
-* Thu Nov 3 2005 Tom Lane <tgl@redhat.com> 5.0.15-1
-- Update to MySQL 5.0.15 (scratch build for now)
-
-* Wed Oct 5 2005 Tom Lane <tgl@redhat.com> 4.1.14-1
-- Update to MySQL 4.1.14
-
-* Tue Aug 23 2005 Tom Lane <tgl@redhat.com> 4.1.12-3
-- Use politically correct patch name.
-
-* Tue Jul 12 2005 Tom Lane <tgl@redhat.com> 4.1.12-2
-- Fix buffer overflow newly exposed in isam code; it's the same issue
- previously found in myisam, and not very exciting, but I'm tired of
- seeing build warnings.
-
-* Mon Jul 11 2005 Tom Lane <tgl@redhat.com> 4.1.12-1
-- Update to MySQL 4.1.12 (includes a fix for bz#158688, bz#158689)
-- Extend mysql-test-ssl.patch to solve rpl_openssl test failure (bz#155850)
-- Update mysql-lock-ssl.patch to match the upstream committed version
-- Add --with-isam to re-enable the old ISAM table type, per bz#159262
-- Add dependency on openssl-devel per bz#159569
-- Remove manual.txt, as upstream decided not to ship it anymore;
- it was redundant with the mysql.info file anyway.
-
-* Mon May 9 2005 Tom Lane <tgl@redhat.com> 4.1.11-4
-- Include proper locking for OpenSSL in the server, per bz#155850
-
-* Mon Apr 25 2005 Tom Lane <tgl@redhat.com> 4.1.11-3
-- Enable openssl tests during build, per bz#155850
-- Might as well turn on --disable-dependency-tracking
-
-* Fri Apr 8 2005 Tom Lane <tgl@redhat.com> 4.1.11-2
-- Avoid dependency on <asm/atomic.h>, cause it won't build anymore on ia64.
- This is probably a cleaner solution for bz#143537, too.
-
-* Thu Apr 7 2005 Tom Lane <tgl@redhat.com> 4.1.11-1
-- Update to MySQL 4.1.11 to fix bz#152911 as well as other issues
-- Move perl-DBI, perl-DBD-MySQL dependencies to server package (bz#154123)
-- Override configure thread library test to suppress HAVE_LINUXTHREADS check
-- Fix BDB failure on s390x (bz#143537)
-- At last we can enable "make test" on all arches
-
-* Fri Mar 11 2005 Tom Lane <tgl@redhat.com> 4.1.10a-1
-- Update to MySQL 4.1.10a to fix security vulnerabilities (bz#150868,
- for CAN-2005-0711, and bz#150871 for CAN-2005-0709, CAN-2005-0710).
-
-* Sun Mar 6 2005 Tom Lane <tgl@redhat.com> 4.1.10-3
-- Fix package Requires: interdependencies.
-
-* Sat Mar 5 2005 Tom Lane <tgl@redhat.com> 4.1.10-2
-- Need -fno-strict-aliasing in at least one place, probably more.
-- Work around some C spec violations in mysql.
-
-* Fri Feb 18 2005 Tom Lane <tgl@redhat.com> 4.1.10-1
-- Update to MySQL 4.1.10.
-
-* Sat Jan 15 2005 Tom Lane <tgl@redhat.com> 4.1.9-1
-- Update to MySQL 4.1.9.
-
-* Wed Jan 12 2005 Tom Lane <tgl@redhat.com> 4.1.7-10
-- Don't assume /etc/my.cnf will specify pid-file (bz#143724)
-
-* Wed Jan 12 2005 Tim Waugh <twaugh@redhat.com> 4.1.7-9
-- Rebuilt for new readline.
-
-* Tue Dec 21 2004 Tom Lane <tgl@redhat.com> 4.1.7-8
-- Run make test on all archs except s390x (which seems to have a bdb issue)
-
-* Mon Dec 13 2004 Tom Lane <tgl@redhat.com> 4.1.7-7
-- Suppress someone's silly idea that libtool overhead can be skipped
-
-* Sun Dec 12 2004 Tom Lane <tgl@redhat.com> 4.1.7-6
-- Fix init script to not need a valid username for startup check (bz#142328)
-- Fix init script to honor settings appearing in /etc/my.cnf (bz#76051)
-- Enable SSL (bz#142032)
-
-* Thu Dec 2 2004 Tom Lane <tgl@redhat.com> 4.1.7-5
-- Add a restorecon to keep the mysql.log file in the right context (bz#143887)
-
-* Tue Nov 23 2004 Tom Lane <tgl@redhat.com> 4.1.7-4
-- Turn off old_passwords in default /etc/my.cnf file, for better compatibility
- with mysql 3.x clients (per suggestion from Joe Orton).
-
-* Fri Oct 29 2004 Tom Lane <tgl@redhat.com> 4.1.7-3
-- Handle ldconfig more cleanly (put a file in /etc/ld.so.conf.d/).
-
-* Thu Oct 28 2004 Tom Lane <tgl@redhat.com> 4.1.7-2
-- rebuild in devel branch
-
-* Wed Oct 27 2004 Tom Lane <tgl@redhat.com> 4.1.7-1
-- Update to MySQL 4.1.x.
-
-* Tue Oct 12 2004 Tom Lane <tgl@redhat.com> 3.23.58-13
-- fix security issues CAN-2004-0835, CAN-2004-0836, CAN-2004-0837
- (bugs #135372, 135375, 135387)
-- fix privilege escalation on GRANT ALL ON `Foo\_Bar` (CAN-2004-0957)
-
-* Wed Oct 06 2004 Tom Lane <tgl@redhat.com> 3.23.58-12
-- fix multilib problem with mysqlbug and mysql_config
-- adjust chkconfig priority per bug #128852
-- remove bogus quoting per bug #129409 (MySQL 4.0 has done likewise)
-- add sleep to mysql.init restart(); may or may not fix bug #133993
-
-* Tue Oct 05 2004 Tom Lane <tgl@redhat.com> 3.23.58-11
-- fix low-priority security issues CAN-2004-0388, CAN-2004-0381, CAN-2004-0457
- (bugs #119442, 125991, 130347, 130348)
-- fix bug with dropping databases under recent kernels (bug #124352)
-
-* Tue Jun 15 2004 Elliot Lee <sopwith@redhat.com> 3.23.58-10
-- rebuilt
-
-* Sat Apr 17 2004 Warren Togami <wtogami@redhat.com> 3.23.58-9
-- remove redundant INSTALL-SOURCE, manual.*
-- compress manual.txt.bz2
-- BR time
-
-* Tue Mar 16 2004 Tom Lane <tgl@redhat.com> 3.23.58-8
-- repair logfile attributes in %%files, per bug #102190
-- repair quoting problem in mysqlhotcopy, per bug #112693
-- repair missing flush in mysql_setpermission, per bug #113960
-- repair broken error message printf, per bug #115165
-- delete mysql user during uninstall, per bug #117017
-- rebuilt
-
-* Tue Mar 02 2004 Elliot Lee <sopwith@redhat.com>
-- rebuilt
-
-* Tue Feb 24 2004 Tom Lane <tgl@redhat.com>
-- fix chown syntax in mysql.init
-- rebuild
-
-* Fri Feb 13 2004 Elliot Lee <sopwith@redhat.com>
-- rebuilt
-
-* Tue Nov 18 2003 Kim Ho <kho@redhat.com> 3.23.58-5
-- update mysql.init to use anonymous user (UNKNOWN_MYSQL_USER) for
- pinging mysql server (#108779)
-
-* Mon Oct 27 2003 Kim Ho <kho@redhat.com> 3.23.58-4
-- update mysql.init to wait (max 10 seconds) for mysql server to
- start (#58732)
-
-* Mon Oct 27 2003 Patrick Macdonald <patrickm@redhat.com> 3.23.58-3
-- re-enable Berkeley DB support (#106832)
-- re-enable ia64 testing
-
-* Fri Sep 19 2003 Patrick Macdonald <patrickm@redhat.com> 3.23.58-2
-- rebuilt
-
-* Mon Sep 15 2003 Patrick Macdonald <patrickm@redhat.com> 3.23.58-1
-- upgrade to 3.23.58 for security fix
-
-* Tue Aug 26 2003 Patrick Macdonald <patrickm@redhat.com> 3.23.57-2
-- rebuilt
-
-* Wed Jul 02 2003 Patrick Macdonald <patrickm@redhat.com> 3.23.57-1
-- revert to prior version of MySQL due to license incompatibilities
- with packages that link against the client. The MySQL folks are
- looking into the issue.
-
-* Wed Jun 18 2003 Patrick Macdonald <patrickm@redhat.com> 4.0.13-4
-- restrict test on ia64 (temporary)
-
-* Wed Jun 04 2003 Elliot Lee <sopwith@redhat.com> 4.0.13-3
-- rebuilt
-
-* Thu May 29 2003 Patrick Macdonald <patrickm@redhat.com> 4.0.13-2
-- fix filter-requires-mysql.sh with less restrictive for mysql-bench
-
-* Wed May 28 2003 Patrick Macdonald <patrickm@redhat.com> 4.0.13-1
-- update for MySQL 4.0
-- back-level shared libraries available in mysqlclient10 package
-
-* Fri May 09 2003 Patrick Macdonald <patrickm@redhat.com> 3.23.56-2
-- add sql-bench package (#90110)
-
-* Wed Mar 19 2003 Patrick Macdonald <patrickm@redhat.com> 3.23.56-1
-- upgrade to 3.23.56 for security fixes
-- remove patch for double-free (included in 3.23.56)
-
-* Tue Feb 18 2003 Patrick Macdonald <patrickm@redhat.com> 3.23.54a-11
-- enable thread safe client
-- add patch for double free fix
-
-* Wed Jan 22 2003 Tim Powers <timp@redhat.com>
-- rebuilt
-
-* Mon Jan 13 2003 Karsten Hopp <karsten@redhat.de> 3.23.54a-9
-- disable checks on s390x
-
-* Sat Jan 4 2003 Jeff Johnson <jbj@redhat.com> 3.23.54a-8
-- use internal dep generator.
-
-* Wed Jan 1 2003 Bill Nottingham <notting@redhat.com> 3.23.54a-7
-- fix mysql_config on hammer
-
-* Sun Dec 22 2002 Tim Powers <timp@redhat.com> 3.23.54a-6
-- don't use rpms internal dep generator
-
-* Tue Dec 17 2002 Elliot Lee <sopwith@redhat.com> 3.23.54a-5
-- Push it into the build system
-
-* Mon Dec 16 2002 Joe Orton <jorton@redhat.com> 3.23.54a-4
-- upgrade to 3.23.54a for safe_mysqld fix
-
-* Thu Dec 12 2002 Joe Orton <jorton@redhat.com> 3.23.54-3
-- upgrade to 3.23.54 for latest security fixes
-
-* Tue Nov 19 2002 Jakub Jelinek <jakub@redhat.com> 3.23.52-5
-- Always include <errno.h> for errno
-- Remove unpackaged files
-
-* Tue Nov 12 2002 Florian La Roche <Florian.LaRoche@redhat.de>
-- do not prereq userdel, not used at all
-
-* Mon Sep 9 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.52-4
-- Use %%{_libdir}
-- Add patch for x86-64
-
-* Wed Sep 4 2002 Jakub Jelinek <jakub@redhat.com> 3.23.52-3
-- rebuilt with gcc-3.2-7
-
-* Thu Aug 29 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.52-2
-- Add --enable-local-infile to configure - a new option
- which doesn't default to the old behaviour (#72885)
-
-* Fri Aug 23 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.52-1
-- 3.23.52. Fixes a minor security problem, various bugfixes.
-
-* Sat Aug 10 2002 Elliot Lee <sopwith@redhat.com> 3.23.51-5
-- rebuilt with gcc-3.2 (we hope)
-
-* Mon Jul 22 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.51-4
-- rebuild
-
-* Thu Jul 18 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.51-3
-- Fix #63543 and #63542
-
-* Thu Jul 11 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.51-2
-- Turn off bdb on PPC(#68591)
-- Turn off the assembly optimizations, for safety.
-
-* Wed Jun 26 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.51-1
-- Work around annoying auto* thinking this is a crosscompile
-- 3.23.51
-
-* Fri Jun 21 2002 Tim Powers <timp@redhat.com>
-- automated rebuild
-
-* Mon Jun 10 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.50-2
-- Add dependency on perl-DBI and perl-DBD-MySQL (#66349)
-
-* Thu May 30 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.50-1
-- 3.23.50
-
-* Thu May 23 2002 Tim Powers <timp@redhat.com>
-- automated rebuild
-
-* Mon May 13 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.49-4
-- Rebuild
-- Don't set CXX to gcc, it doesn't work anymore
-- Exclude Alpha
-
-* Mon Apr 8 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.49-3
-- Add the various .cnf examples as doc files to mysql-server (#60349)
-- Don't include manual.ps, it's just 200 bytes with a URL inside (#60349)
-- Don't include random files in /usr/share/mysql (#60349)
-- langify (#60349)
-
-* Thu Feb 21 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.49-2
-- Rebuild
-
-* Sun Feb 17 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.49-1
-- 3.23.49
-
-* Thu Feb 14 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.48-2
-- work around perl dependency bug.
-
-* Mon Feb 11 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.48-1
-- 3.23.48
-
-* Thu Jan 17 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.47-4
-- Use kill, not mysqladmin, to flush logs and shut down. Thus,
- an admin password can be set with no problems.
-- Remove reload from init script
-
-* Wed Jan 16 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.47-3
-- remove db3-devel from buildrequires,
- MySQL has had its own bundled copy since the mid thirties
-
-* Sun Jan 6 2002 Trond Eivind Glomsrd <teg@redhat.com> 3.23.47-1
-- 3.23.47
-- Don't build for alpha, toolchain immature.
-
-* Mon Dec 3 2001 Trond Eivind Glomsrd <teg@redhat.com> 3.23.46-1
-- 3.23.46
-- use -fno-rtti and -fno-exceptions, and set CXX to increase stability.
- Recommended by mysql developers.
-
-* Sun Nov 25 2001 Trond Eivind Glomsrd <teg@redhat.com> 3.23.45-1
-- 3.23.45
-
-* Wed Nov 14 2001 Trond Eivind Glomsrd <teg@redhat.com> 3.23.44-2
-- centralize definition of datadir in the initscript (#55873)
-
-* Fri Nov 2 2001 Trond Eivind Glomsrd <teg@redhat.com> 3.23.44-1
-- 3.23.44
-
-* Thu Oct 4 2001 Trond Eivind Glomsrd <teg@redhat.com> 3.23.43-1
-- 3.23.43
-
-* Mon Sep 10 2001 Trond Eivind Glomsrd <teg@redhat.com> 3.23.42-1
-- 3.23.42
-- reenable innodb
-
-* Tue Aug 14 2001 Trond Eivind Glomsrd <teg@redhat.com> 3.23.41-1
-- 3.23.41 bugfix release
-- disable innodb, to avoid the broken updates
-- Use "mysqladmin flush_logs" instead of kill -HUP in logrotate
- script (#51711)
-
-* Sat Jul 21 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.40, bugfix release
-- Add zlib-devel to buildrequires:
-
-* Fri Jul 20 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- BuildRequires-tweaking
-
-* Thu Jun 28 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- Reenable test, but don't run them for s390, s390x or ia64
-- Make /etc/my.cnf config(noplace). Same for /etc/logrotate.d/mysqld
-
-* Thu Jun 14 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.29
-- enable innodb
-- enable assembly again
-- disable tests for now...
-
-* Tue May 15 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.38
-- Don't use BDB on Alpha - no fast mutexes
-
-* Tue Apr 24 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.37
-- Add _GNU_SOURCE to the compile flags
-
-* Wed Mar 28 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- Make it obsolete our 6.2 PowerTools packages
-- 3.23.36 bugfix release - fixes some security issues
- which didn't apply to our standard configuration
-- Make "make test" part of the build process, except on IA64
- (it fails there)
-
-* Tue Mar 20 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.35 bugfix release
-- Don't delete the mysql user on uninstall
-
-* Tue Mar 13 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.34a bugfix release
-
-* Wed Feb 7 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- added readline-devel to BuildRequires:
-
-* Tue Feb 6 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- small i18n-fixes to initscript (action needs $)
-
-* Tue Jan 30 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- make it shut down and rotate logs without using mysqladmin
- (from #24909)
-
-* Mon Jan 29 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- conflict with "MySQL"
-
-* Tue Jan 23 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- improve gettextizing
-
-* Mon Jan 22 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.32
-- fix logrotate script (#24589)
-
-* Wed Jan 17 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- gettextize
-- move the items in Requires(post): to Requires: in preparation
- for an errata for 7.0 when 3.23.31 is released
-- 3.23.31
-
-* Tue Jan 16 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- add the log file to the rpm database, and make it 0640
- (#24116)
-- as above in logrotate script
-- changes to the init sequence - put most of the data
- in /etc/my.cnf instead of hardcoding in the init script
-- use /var/run/mysqld/mysqld.pid instead of
- /var/run/mysqld/pid
-- use standard safe_mysqld
-- shut down cleaner
-
-* Mon Jan 08 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.30
-- do an explicit chmod on /var/lib/mysql in post, to avoid
- any problems with broken permissons. There is a report
- of rm not changing this on its own (#22989)
-
-* Mon Jan 01 2001 Trond Eivind Glomsrd <teg@redhat.com>
-- bzipped source
-- changed from 85 to 78 in startup, so it starts before
- apache (which can use modules requiring mysql)
-
-* Wed Dec 27 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.29a
-
-* Tue Dec 19 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- add requirement for new libstdc++, build for errata
-
-* Mon Dec 18 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.29
-
-* Mon Nov 27 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.28 (gamma)
-- remove old patches, as they are now upstreamed
-
-* Thu Nov 14 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- Add a requirement for a new glibc (#20735)
-- build on IA64
-
-* Wed Nov 1 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- disable more assembly
-
-* Wed Nov 1 2000 Jakub Jelinek <jakub@redhat.com>
-- fix mysql on SPARC (#20124)
-
-* Tue Oct 31 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.27
-
-* Wed Oct 25 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- add patch for fixing bogus aliasing in mysql from Jakub,
- which should fix #18905 and #18620
-
-* Mon Oct 23 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- check for negative niceness values, and negate it
- if present (#17899)
-- redefine optflags on IA32 FTTB
-
-* Wed Oct 18 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.26, which among other fixes now uses mkstemp()
- instead of tempnam().
-- revert changes made yesterday, the problem is now
- isolated
-
-* Tue Oct 17 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- use the compat C++ compiler FTTB. Argh.
-- add requirement of ncurses4 (see above)
-
-* Sun Oct 01 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.25
-- fix shutdown problem (#17956)
-
-* Tue Sep 26 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- Don't try to include no-longer-existing PUBLIC file
- as doc (#17532)
-
-* Thu Sep 12 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- rename config file to /etc/my.cnf, which is what
- mysqld wants... doh. (#17432)
-- include a changed safe_mysqld, so the pid file option
- works.
-- make mysql dir world readable to they can access the
- mysql socket. (#17432)
-- 3.23.24
-
-* Wed Sep 06 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.23
-
-* Sun Aug 27 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- Add "|| :" to condrestart to avoid non-zero exit code
-
-* Thu Aug 24 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- it's mysql.com, not mysql.org and use correct path to
- source (#16830)
-
-* Wed Aug 16 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- source file from /etc/rc.d, not /etc/rd.d. Doh.
-
-* Sun Aug 13 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- don't run ldconfig -n, it doesn't update ld.so.cache
- (#16034)
-- include some missing binaries
-- use safe_mysqld to start the server (request from
- mysql developers)
-
-* Sat Aug 05 2000 Bill Nottingham <notting@redhat.com>
-- condrestart fixes
-
-* Mon Aug 01 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.22. Disable the old patches, they're now in.
-
-* Thu Jul 27 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- bugfixes in the initscript
-- move the .so link to the devel package
-
-* Wed Jul 19 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- rebuild due to glibc changes
-
-* Tue Jul 18 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- disable compiler patch
-- don't include info directory file
-
-* Mon Jul 17 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- move back to /etc/rc.d/init.d
-
-* Fri Jul 14 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- more cleanups in initscript
-
-* Thu Jul 13 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- add a patch to work around compiler bug
- (from monty@mysql.com)
-
-* Wed Jul 12 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- don't build the SQL daemon statically (glibc problems)
-- fix the logrotate script - only flush log if mysql
- is running
-- change the reloading procedure
-- remove icon - glint is obsolete a long time ago
-
-* Wed Jul 12 2000 Prospector <bugzilla@redhat.com>
-- automatic rebuild
-
-* Mon Jul 10 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- try the new compiler again
-- build the SQL daemon statically
-- add compile time support for complex charsets
-- enable assembler
-- more cleanups in initscript
-
-* Sun Jul 09 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- use old C++ compiler
-- Exclusivearch x86
-
-* Sat Jul 08 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- move .so files to devel package
-- more cleanups
-- exclude sparc for now
-
-* Wed Jul 05 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- 3.23.21
-- remove file from /etc/sysconfig
-- Fix initscript a bit - initialization of databases doesn't
- work yet
-- specify the correct licenses
-- include a /etc/my.conf (empty, FTTB)
-- add conditional restart to spec file
-
-* Tue Jul 2 2000 Jakub Jelinek <jakub@redhat.com>
-- Rebuild with new C++
-
-* Fri Jun 30 2000 Trond Eivind Glomsrd <teg@redhat.com>
-- update to 3.23.20
-- use %%configure, %%makeinstall, %%{_tmppath}, %%{_mandir},
- %%{_infodir}, /etc/init.d
-- remove the bench package
-- change some of the descriptions a little bit
-- fix the init script
-- some compile fixes
-- specify mysql user
-- use mysql uid 27 (postgresql is 26)
-- don't build on ia64
-
-* Sat Feb 26 2000 Jos Vos <jos@xos.nl>
-- Version 3.22.32 release XOS.1 for LinuX/OS 1.8.0
-- Upgrade from version 3.22.27 to 3.22.32.
-- Do "make install" instead of "make install-strip", because "install -s"
- now appears to fail on various scripts. Afterwards, strip manually.
-- Reorganize subpackages, according to common Red Hat packages: the client
- program and shared library become the base package and the server and
- some accompanying files are now in a separate server package. The
- server package implicitly requires the base package (shared library),
- but we have added a manual require tag anyway (because of the shared
- config file, and more).
-- Rename the mysql-benchmark subpackage to mysql-bench.
-
-* Mon Jan 31 2000 Jos Vos <jos@xos.nl>
-- Version 3.22.27 release XOS.2 for LinuX/OS 1.7.1
-- Add post(un)install scripts for updating ld.so.conf (client subpackage).
-
-* Sun Nov 21 1999 Jos Vos <jos@xos.nl>
-- Version 3.22.27 release XOS.1 for LinuX/OS 1.7.0
-- Initial version.
-- Some ideas borrowed from Red Hat Powertools 6.1, although this spec
- file is a full rewrite from scratch.
diff --git a/packaging/rpm-uln/scriptstub.c b/packaging/rpm-uln/scriptstub.c
deleted file mode 100644
index de942c136e7..00000000000
--- a/packaging/rpm-uln/scriptstub.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-/* Translate call of myself into call of same-named script in LIBDIR */
-/* The macro LIBDIR must be defined as a double-quoted string */
-
-int main (int argc, char **argv)
-{
- char *basename;
- char *fullname;
- char **newargs;
- int i;
-
- basename = strrchr(argv[0], '/');
- if (basename)
- basename++;
- else
- basename = argv[0];
- fullname = malloc(strlen(LIBDIR) + strlen(basename) + 2);
- sprintf(fullname, "%s/%s", LIBDIR, basename);
- newargs = malloc((argc+1) * sizeof(char *));
- newargs[0] = fullname;
- for (i = 1; i < argc; i++)
- newargs[i] = argv[i];
- newargs[argc] = NULL;
-
- execvp(fullname, newargs);
-
- return 1;
-}
diff --git a/plugin/win_auth_client/CMakeLists.txt b/plugin/win_auth_client/CMakeLists.txt
index a017410252d..75ee55117bd 100644
--- a/plugin/win_auth_client/CMakeLists.txt
+++ b/plugin/win_auth_client/CMakeLists.txt
@@ -31,7 +31,6 @@ IF(WIN32)
LINK_LIBRARIES Secur32
MODULE_ONLY COMPONENT SharedLibraries)
- #INSTALL_DEBUG_SYMBOLS(auth_win_client)
#IF(MSVC)
# INSTALL_DEBUG_TARGET(auth_win_client DESTINATION ${INSTALL_LIBDIR}/debug)
#ENDIF()
diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
index 13a89368ee6..b99b14bf464 100644
--- a/scripts/CMakeLists.txt
+++ b/scripts/CMakeLists.txt
@@ -231,6 +231,7 @@ SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
SET(scriptdir ${prefix}/${INSTALL_BINDIR})
SET(datadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
+SET(libsubdir ${INSTALL_LIBDIR})
SET(pkgincludedir ${prefix}/${INSTALL_INCLUDEDIR})
SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
diff --git a/scripts/mysql_config.sh b/scripts/mysql_config.sh
index 4bf95cccbe6..4909d5d0a87 100644
--- a/scripts/mysql_config.sh
+++ b/scripts/mysql_config.sh
@@ -76,7 +76,8 @@ get_full_path ()
me=`get_full_path $0`
-basedir=`echo $me | sed -e 's;/bin/mysql_config;;'`
+# Script might have been renamed but assume mysql_<something>config<something>
+basedir=`echo $me | sed -e 's;/bin/mysql_.*config.*;;'`
ldata='@localstatedir@'
execdir='@libexecdir@'
@@ -85,11 +86,11 @@ bindir='@bindir@'
# If installed, search for the compiled in directory first (might be "lib64")
pkglibdir='@pkglibdir@'
pkglibdir_rel=`echo $pkglibdir | sed -e "s;^$basedir/;;"`
-fix_path pkglibdir $pkglibdir_rel lib64/mysql lib64 lib/mysql lib
+fix_path pkglibdir $pkglibdir_rel @libsubdir@/mysql @libsubdir@
plugindir='@pkgplugindir@'
plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
-fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+fix_path plugindir $plugindir_rel @libsubdir@/mysql/plugin @libsubdir@/plugin
pkgincludedir='@pkgincludedir@'
fix_path pkgincludedir include/mysql
diff --git a/scripts/mysqlaccess.conf b/scripts/mysqlaccess.conf
index faf47da5f6c..faf47da5f6c 100755..100644
--- a/scripts/mysqlaccess.conf
+++ b/scripts/mysqlaccess.conf
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
index 9d0dd0e68ac..7c43558523b 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -190,16 +190,6 @@ shell_quote_string() {
}
parse_arguments() {
- # We only need to pass arguments through to the server if we don't
- # handle them here. So, we collect unrecognized options (passed on
- # the command line) into the args variable.
- pick_args=
- if test "$1" = PICK-ARGS-FROM-ARGV
- then
- pick_args=1
- shift
- fi
-
for arg do
val=`echo "$arg" | sed -e "s;--[^=]*=;;"`
case "$arg" in
@@ -249,11 +239,10 @@ parse_arguments() {
--help) usage ;;
*)
- if test -n "$pick_args"
- then
- append_arg_to_args "$arg"
- fi
- ;;
+ case "$unrecognized_handling" in
+ collect) append_arg_to_args "$arg" ;;
+ complain) log_error "unknown option '$arg'" ;;
+ esac
esac
done
}
@@ -510,8 +499,16 @@ then
SET_USER=0
fi
+# If arguments come from [mysqld_safe] section of my.cnf
+# we complain about unrecognized options
+unrecognized_handling=complain
parse_arguments `$print_defaults $defaults --loose-verbose mysqld_safe safe_mysqld mariadb_safe`
-parse_arguments PICK-ARGS-FROM-ARGV "$@"
+
+# We only need to pass arguments through to the server if we don't
+# handle them here. So, we collect unrecognized options (passed on
+# the command line) into the args variable.
+unrecognized_handling=collect
+parse_arguments "$@"
#
diff --git a/sql-bench/graph-compare-results.sh b/sql-bench/graph-compare-results.sh
index ddc9080acd6..ddc9080acd6 100644..100755
--- a/sql-bench/graph-compare-results.sh
+++ b/sql-bench/graph-compare-results.sh
diff --git a/sql/field.h b/sql/field.h
index b5f332f5edc..06e7429c812 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -183,6 +183,29 @@ inline bool is_temporal_type(enum_field_types type)
return mysql_type_to_time_type(type) != MYSQL_TIMESTAMP_ERROR;
}
+
+/**
+ Tests if field type is temporal and has time part,
+ i.e. represents TIME, DATETIME or TIMESTAMP types in SQL.
+
+ @param type Field type, as returned by field->type().
+ @retval true If field type is temporal type with time part.
+ @retval false If field type is not temporal type with time part.
+*/
+inline bool is_temporal_type_with_time(enum_field_types type)
+{
+ switch (type)
+ {
+ case MYSQL_TYPE_TIME:
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_TIMESTAMP:
+ return true;
+ default:
+ return false;
+ }
+}
+
+
/*
Virtual_column_info is the class to contain additional
characteristics that is specific for a virtual/computed
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 737165fc6d1..23cfd6a1817 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -721,6 +721,9 @@ static ha_rows find_all_keys(Sort_param *param, SQL_SELECT *select,
/* Temporary set for register_used_fields and register_field_in_read_map */
sort_form->read_set= &sort_form->tmp_set;
register_used_fields(param);
+ if (quick_select)
+ select->quick->add_used_key_part_to_set(sort_form->read_set);
+
Item *sort_cond= !select ?
0 : !select->pre_idx_push_select_cond ?
select->cond : select->pre_idx_push_select_cond;
diff --git a/sql/handler.cc b/sql/handler.cc
index 638723306fb..ff33243ebc9 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -588,7 +588,19 @@ int ha_initialize_handlerton(st_plugin_int *plugin)
savepoint_alloc_size+= tmp;
hton2plugin[hton->slot]=plugin;
if (hton->prepare)
+ {
total_ha_2pc++;
+ if (tc_log && tc_log != get_tc_log_implementation())
+ {
+ total_ha_2pc--;
+ hton->prepare= 0;
+ push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_UNKNOWN_ERROR,
+ "Cannot enable tc-log at run-time. "
+ "XA features of %s are disabled",
+ plugin->name.str);
+ }
+ }
break;
}
/* fall through */
diff --git a/sql/item.cc b/sql/item.cc
index 95df347f71a..107468030bb 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2124,7 +2124,7 @@ bool agg_item_collations(DTCollation &c, const char *fname,
bool unknown_cs= 0;
c.set(av[0]->collation);
- for (i= 1, arg= &av[item_sep]; i < count; i++, arg++)
+ for (i= 1, arg= &av[item_sep]; i < count; i++, arg+= item_sep)
{
if (c.aggregate((*arg)->collation, flags))
{
diff --git a/sql/item.h b/sql/item.h
index 29e727b8d5f..00c1468bb48 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1034,9 +1034,47 @@ public:
virtual cond_result eq_cmp_result() const { return COND_OK; }
inline uint float_length(uint decimals_par) const
{ return decimals != NOT_FIXED_DEC ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
+ /* Returns total number of decimal digits */
virtual uint decimal_precision() const;
+ /* Returns the number of integer part digits only */
inline int decimal_int_part() const
{ return my_decimal_int_part(decimal_precision(), decimals); }
+ /*
+ Returns the number of fractional digits only.
+ NOT_FIXED_DEC is replaced to the maximum possible number
+ of fractional digits, taking into account the data type.
+ */
+ uint decimal_scale() const
+ {
+ return decimals < NOT_FIXED_DEC ? decimals :
+ is_temporal_type_with_time(field_type()) ?
+ TIME_SECOND_PART_DIGITS :
+ MY_MIN(max_length, DECIMAL_MAX_SCALE);
+ }
+ /*
+ Returns how many digits a divisor adds into a division result.
+ This is important when the integer part of the divisor can be 0.
+ In this example:
+ SELECT 1 / 0.000001; -> 1000000.0000
+ the divisor adds 5 digits into the result precision.
+
+ Currently this method only replaces NOT_FIXED_DEC to
+ TIME_SECOND_PART_DIGITS for temporal data types.
+ This method can be made virtual, to create more efficient (smaller)
+ data types for division results.
+ For example, in
+ SELECT 1/1.000001;
+ the divisor could provide no additional precision into the result,
+ so could any other items that are know to return a result
+ with non-zero integer part.
+ */
+ uint divisor_precision_increment() const
+ {
+ return decimals < NOT_FIXED_DEC ? decimals :
+ is_temporal_type_with_time(field_type()) ?
+ TIME_SECOND_PART_DIGITS :
+ decimals;
+ }
/**
TIME or DATETIME precision of the item: 0..6
*/
diff --git a/sql/item_func.cc b/sql/item_func.cc
index ccb7ec56021..51a85e71f20 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -593,7 +593,7 @@ my_decimal *Item_real_func::val_decimal(my_decimal *decimal_value)
}
-void Item_func::fix_num_length_and_dec()
+void Item_udf_func::fix_num_length_and_dec()
{
uint fl_length= 0;
decimals=0;
@@ -611,11 +611,6 @@ void Item_func::fix_num_length_and_dec()
}
-void Item_func_numhybrid::fix_num_length_and_dec()
-{}
-
-
-
/**
Count max_length and decimals for temporal functions.
@@ -803,9 +798,9 @@ bool Item_func_connection_id::fix_fields(THD *thd, Item **ref)
function of two arguments.
*/
-void Item_num_op::find_num_type(void)
+void Item_num_op::fix_length_and_dec(void)
{
- DBUG_ENTER("Item_num_op::find_num_type");
+ DBUG_ENTER("Item_num_op::fix_length_and_dec");
DBUG_PRINT("info", ("name %s", func_name()));
DBUG_ASSERT(arg_count == 2);
Item_result r0= args[0]->cast_to_int_type();
@@ -849,22 +844,26 @@ void Item_num_op::find_num_type(void)
type depends only on the first argument)
*/
-void Item_func_num1::find_num_type()
+void Item_func_num1::fix_length_and_dec()
{
- DBUG_ENTER("Item_func_num1::find_num_type");
+ DBUG_ENTER("Item_func_num1::fix_length_and_dec");
DBUG_PRINT("info", ("name %s", func_name()));
switch (cached_result_type= args[0]->cast_to_int_type()) {
case INT_RESULT:
+ max_length= args[0]->max_length;
unsigned_flag= args[0]->unsigned_flag;
break;
case STRING_RESULT:
case REAL_RESULT:
cached_result_type= REAL_RESULT;
+ decimals= args[0]->decimals; // Preserve NOT_FIXED_DEC
max_length= float_length(decimals);
break;
case TIME_RESULT:
cached_result_type= DECIMAL_RESULT;
case DECIMAL_RESULT:
+ decimals= args[0]->decimal_scale(); // Do not preserve NOT_FIXED_DEC
+ max_length= args[0]->max_length;
break;
case ROW_RESULT:
case IMPOSSIBLE_RESULT:
@@ -879,20 +878,6 @@ void Item_func_num1::find_num_type()
}
-void Item_func_num1::fix_num_length_and_dec()
-{
- decimals= args[0]->decimals;
- max_length= args[0]->max_length;
-}
-
-
-void Item_func_numhybrid::fix_length_and_dec()
-{
- fix_num_length_and_dec();
- find_num_type();
-}
-
-
String *Item_func_hybrid_result_type::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
@@ -1537,11 +1522,14 @@ my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
*/
void Item_func_additive_op::result_precision()
{
- decimals= MY_MAX(args[0]->decimals, args[1]->decimals);
- int arg1_int= args[0]->decimal_precision() - args[0]->decimals;
- int arg2_int= args[1]->decimal_precision() - args[1]->decimals;
+ decimals= MY_MAX(args[0]->decimal_scale(), args[1]->decimal_scale());
+ int arg1_int= args[0]->decimal_precision() - args[0]->decimal_scale();
+ int arg2_int= args[1]->decimal_precision() - args[1]->decimal_scale();
int precision= MY_MAX(arg1_int, arg2_int) + 1 + decimals;
+ DBUG_ASSERT(arg1_int >= 0);
+ DBUG_ASSERT(arg2_int >= 0);
+
/* Integer operations keep unsigned_flag if one of arguments is unsigned */
if (result_type() == INT_RESULT)
unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
@@ -1778,7 +1766,8 @@ void Item_func_mul::result_precision()
unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
else
unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
- decimals= MY_MIN(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
+ decimals= MY_MIN(args[0]->decimal_scale() + args[1]->decimal_scale(),
+ DECIMAL_MAX_SCALE);
uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision();
uint precision= MY_MIN(est_prec, DECIMAL_MAX_PRECISION);
max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
@@ -1832,8 +1821,20 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value)
void Item_func_div::result_precision()
{
+ /*
+ We need to add args[1]->divisor_precision_increment(),
+ to properly handle the cases like this:
+ SELECT 5.05 / 0.014; -> 360.714286
+ i.e. when the divisor has a zero integer part
+ and non-zero digits appear only after the decimal point.
+ Precision in this example is calculated as
+ args[0]->decimal_precision() + // 3
+ args[1]->divisor_precision_increment() + // 3
+ prec_increment // 4
+ which gives 10 decimals digits.
+ */
uint precision=MY_MIN(args[0]->decimal_precision() +
- args[1]->decimals + prec_increment,
+ args[1]->divisor_precision_increment() + prec_increment,
DECIMAL_MAX_PRECISION);
/* Integer operations keep unsigned_flag if one of arguments is unsigned */
@@ -1841,7 +1842,7 @@ void Item_func_div::result_precision()
unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
else
unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
- decimals= MY_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ decimals= MY_MIN(args[0]->decimal_scale() + prec_increment, DECIMAL_MAX_SCALE);
max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
unsigned_flag);
}
@@ -2047,7 +2048,7 @@ my_decimal *Item_func_mod::decimal_op(my_decimal *decimal_value)
void Item_func_mod::result_precision()
{
- decimals= MY_MAX(args[0]->decimals, args[1]->decimals);
+ decimals= MY_MAX(args[0]->decimal_scale(), args[1]->decimal_scale());
max_length= MY_MAX(args[0]->max_length, args[1]->max_length);
}
@@ -2103,18 +2104,12 @@ my_decimal *Item_func_neg::decimal_op(my_decimal *decimal_value)
}
-void Item_func_neg::fix_num_length_and_dec()
-{
- decimals= args[0]->decimals;
- /* 1 add because sign can appear */
- max_length= args[0]->max_length + 1;
-}
-
-
void Item_func_neg::fix_length_and_dec()
{
DBUG_ENTER("Item_func_neg::fix_length_and_dec");
Item_func_num1::fix_length_and_dec();
+ /* 1 add because sign can appear */
+ max_length= args[0]->max_length + 1;
/*
If this is in integer context keep the context as integer if possible
@@ -2421,8 +2416,12 @@ void Item_func_integer::fix_length_and_dec()
decimals=0;
}
-void Item_func_int_val::fix_num_length_and_dec()
+
+void Item_func_int_val::fix_length_and_dec()
{
+ DBUG_ENTER("Item_func_int_val::fix_length_and_dec");
+ DBUG_PRINT("info", ("name %s", func_name()));
+
ulonglong tmp_max_length= (ulonglong ) args[0]->max_length -
(args[0]->decimals ? args[0]->decimals + 1 : 0) + 2;
max_length= tmp_max_length > (ulonglong) 4294967295U ?
@@ -2430,13 +2429,7 @@ void Item_func_int_val::fix_num_length_and_dec()
uint tmp= float_length(decimals);
set_if_smaller(max_length,tmp);
decimals= 0;
-}
-
-void Item_func_int_val::find_num_type()
-{
- DBUG_ENTER("Item_func_int_val::find_num_type");
- DBUG_PRINT("info", ("name %s", func_name()));
switch (cached_result_type= args[0]->cast_to_int_type())
{
case STRING_RESULT:
@@ -2960,7 +2953,7 @@ bool Item_func_min_max::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
{
ltime->time_type= MYSQL_TIMESTAMP_TIME;
ltime->hour+= (ltime->month * 32 + ltime->day) * 24;
- ltime->month= ltime->day= 0;
+ ltime->year= ltime->month= ltime->day= 0;
if (adjust_time_range_with_warn(ltime,
std::min<uint>(decimals, TIME_SECOND_PART_DIGITS)))
return (null_value= true);
@@ -3894,12 +3887,6 @@ String *Item_func_udf_decimal::val_str(String *str)
}
-void Item_func_udf_decimal::fix_length_and_dec()
-{
- fix_num_length_and_dec();
-}
-
-
/* Default max_length is max argument length */
void Item_func_udf_str::fix_length_and_dec()
diff --git a/sql/item_func.h b/sql/item_func.h
index 1696898812d..18265f672dd 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -154,7 +154,6 @@ public:
virtual void print(String *str, enum_query_type query_type);
void print_op(String *str, enum_query_type query_type);
void print_args(String *str, uint from, enum_query_type query_type);
- virtual void fix_num_length_and_dec();
void count_only_length(Item **item, uint nitems);
void count_real_length();
void count_decimal_length();
@@ -541,9 +540,6 @@ public:
Item_func_numhybrid(List<Item> &list)
:Item_func_hybrid_result_type(list)
{ }
- void fix_length_and_dec();
- void fix_num_length_and_dec();
- virtual void find_num_type()= 0; /* To be called from fix_length_and_dec */
String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
bool date_op(MYSQL_TIME *ltime, uint fuzzydate) { DBUG_ASSERT(0); return true; }
};
@@ -555,9 +551,7 @@ class Item_func_num1: public Item_func_numhybrid
public:
Item_func_num1(Item *a) :Item_func_numhybrid(a) {}
Item_func_num1(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
-
- void fix_num_length_and_dec();
- void find_num_type();
+ void fix_length_and_dec();
};
@@ -573,7 +567,7 @@ class Item_num_op :public Item_func_numhybrid
print_op(str, query_type);
}
- void find_num_type();
+ void fix_length_and_dec();
};
@@ -795,7 +789,6 @@ public:
const char *func_name() const { return "-"; }
enum Functype functype() const { return NEG_FUNC; }
void fix_length_and_dec();
- void fix_num_length_and_dec();
uint decimal_precision() const { return args[0]->decimal_precision(); }
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
@@ -962,8 +955,7 @@ class Item_func_int_val :public Item_func_num1
{
public:
Item_func_int_val(Item *a) :Item_func_num1(a) {}
- void fix_num_length_and_dec();
- void find_num_type();
+ void fix_length_and_dec();
};
@@ -1376,6 +1368,7 @@ public:
fixed= 1;
return res;
}
+ void fix_num_length_and_dec();
void update_used_tables()
{
/*
@@ -1489,7 +1482,7 @@ public:
my_decimal *val_decimal(my_decimal *);
String *val_str(String *str);
enum Item_result result_type () const { return DECIMAL_RESULT; }
- void fix_length_and_dec();
+ void fix_length_and_dec() { fix_num_length_and_dec(); }
};
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index bee1b600d8f..bb999f132c4 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -180,16 +180,27 @@ String *Item_func_md5::val_str_ascii(String *str)
}
+/*
+ The MD5()/SHA() functions treat their parameter as being a case sensitive.
+ Thus we set binary collation on it so different instances of MD5() will be
+ compared properly.
+*/
+static CHARSET_INFO *get_checksum_charset(const char *csname)
+{
+ CHARSET_INFO *cs= get_charset_by_csname(csname, MY_CS_BINSORT, MYF(0));
+ if (!cs)
+ {
+ // Charset has no binary collation: use my_charset_bin.
+ cs= &my_charset_bin;
+ }
+ return cs;
+}
+
+
void Item_func_md5::fix_length_and_dec()
{
- /*
- The MD5() function treats its parameter as being a case sensitive. Thus
- we set binary collation on it so different instances of MD5() will be
- compared properly.
- */
- args[0]->collation.set(
- get_charset_by_csname(args[0]->collation.collation->csname,
- MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE);
+ CHARSET_INFO *cs= get_checksum_charset(args[0]->collation.collation->csname);
+ args[0]->collation.set(cs, DERIVATION_COERCIBLE);
fix_length_and_charset(32, default_charset());
}
@@ -219,14 +230,8 @@ String *Item_func_sha::val_str_ascii(String *str)
void Item_func_sha::fix_length_and_dec()
{
- /*
- The SHA() function treats its parameter as being a case sensitive. Thus
- we set binary collation on it so different instances of MD5() will be
- compared properly.
- */
- args[0]->collation.set(
- get_charset_by_csname(args[0]->collation.collation->csname,
- MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE);
+ CHARSET_INFO *cs= get_checksum_charset(args[0]->collation.collation->csname);
+ args[0]->collation.set(cs, DERIVATION_COERCIBLE);
// size of hex representation of hash
fix_length_and_charset(SHA1_HASH_SIZE * 2, default_charset());
}
@@ -349,18 +354,9 @@ void Item_func_sha2::fix_length_and_dec()
ER(ER_WRONG_PARAMETERS_TO_NATIVE_FCT), "sha2");
}
- /*
- The SHA2() function treats its parameter as being a case sensitive.
- Thus we set binary collation on it so different instances of SHA2()
- will be compared properly.
- */
+ CHARSET_INFO *cs= get_checksum_charset(args[0]->collation.collation->csname);
+ args[0]->collation.set(cs, DERIVATION_COERCIBLE);
- args[0]->collation.set(
- get_charset_by_csname(
- args[0]->collation.collation->csname,
- MY_CS_BINSORT,
- MYF(0)),
- DERIVATION_COERCIBLE);
#else
push_warning_printf(current_thd,
Sql_condition::WARN_LEVEL_WARN,
@@ -1966,7 +1962,7 @@ String *Item_func_ltrim::val_str(String *str)
if ((remove_length= remove_str->length()) == 0 ||
remove_length > res->length())
- return res;
+ return non_trimmed_value(res);
ptr= (char*) res->ptr();
end= ptr+res->length();
@@ -1985,9 +1981,8 @@ String *Item_func_ltrim::val_str(String *str)
end+=remove_length;
}
if (ptr == res->ptr())
- return res;
- tmp_value.set(*res,(uint) (ptr - res->ptr()),(uint) (end-ptr));
- return &tmp_value;
+ return non_trimmed_value(res);
+ return trimmed_value(res, (uint32) (ptr - res->ptr()), (uint32) (end - ptr));
}
@@ -2013,7 +2008,7 @@ String *Item_func_rtrim::val_str(String *str)
if ((remove_length= remove_str->length()) == 0 ||
remove_length > res->length())
- return res;
+ return non_trimmed_value(res);
ptr= (char*) res->ptr();
end= ptr+res->length();
@@ -2025,11 +2020,11 @@ String *Item_func_rtrim::val_str(String *str)
{
char chr=(*remove_str)[0];
#ifdef USE_MB
- if (use_mb(res->charset()))
+ if (use_mb(collation.collation))
{
while (ptr < end)
{
- if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l,p=ptr;
+ if ((l= my_ismbchar(collation.collation, ptr, end))) ptr+= l, p=ptr;
else ++ptr;
}
ptr=p;
@@ -2042,12 +2037,12 @@ String *Item_func_rtrim::val_str(String *str)
{
const char *r_ptr=remove_str->ptr();
#ifdef USE_MB
- if (use_mb(res->charset()))
+ if (use_mb(collation.collation))
{
loop:
while (ptr + remove_length < end)
{
- if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l;
+ if ((l= my_ismbchar(collation.collation, ptr, end))) ptr+= l;
else ++ptr;
}
if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length))
@@ -2066,9 +2061,8 @@ String *Item_func_rtrim::val_str(String *str)
}
}
if (end == res->ptr()+res->length())
- return res;
- tmp_value.set(*res,0,(uint) (end-res->ptr()));
- return &tmp_value;
+ return non_trimmed_value(res);
+ return trimmed_value(res, 0, (uint32) (end - res->ptr()));
}
@@ -2095,37 +2089,22 @@ String *Item_func_trim::val_str(String *str)
if ((remove_length= remove_str->length()) == 0 ||
remove_length > res->length())
- return res;
+ return non_trimmed_value(res);
ptr= (char*) res->ptr();
end= ptr+res->length();
r_ptr= remove_str->ptr();
+ while (ptr+remove_length <= end && !memcmp(ptr,r_ptr,remove_length))
+ ptr+=remove_length;
#ifdef USE_MB
- if (use_mb(res->charset()))
+ if (use_mb(collation.collation))
{
- while (ptr + remove_length <= end)
- {
- uint num_bytes= 0;
- while (num_bytes < remove_length)
- {
- uint len;
- if ((len= my_ismbchar(res->charset(), ptr + num_bytes, end)))
- num_bytes+= len;
- else
- ++num_bytes;
- }
- if (num_bytes != remove_length)
- break;
- if (memcmp(ptr, r_ptr, remove_length))
- break;
- ptr+= remove_length;
- }
char *p=ptr;
register uint32 l;
loop:
while (ptr + remove_length < end)
{
- if ((l= my_ismbchar(res->charset(), ptr,end)))
+ if ((l= my_ismbchar(collation.collation, ptr, end)))
ptr+= l;
else
++ptr;
@@ -2141,16 +2120,13 @@ String *Item_func_trim::val_str(String *str)
else
#endif /* USE_MB */
{
- while (ptr+remove_length <= end && !memcmp(ptr,r_ptr,remove_length))
- ptr+=remove_length;
while (ptr + remove_length <= end &&
!memcmp(end-remove_length,r_ptr,remove_length))
end-=remove_length;
}
if (ptr == res->ptr() && end == ptr+res->length())
- return res;
- tmp_value.set(*res,(uint) (ptr - res->ptr()),(uint) (end-ptr));
- return &tmp_value;
+ return non_trimmed_value(res);
+ return trimmed_value(res, (uint32) (ptr - res->ptr()), (uint32) (end - ptr));
}
void Item_func_trim::fix_length_and_dec()
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index f3d5c064423..4551cc1ab46 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -349,6 +349,21 @@ class Item_func_trim :public Item_str_func
protected:
String tmp_value;
String remove;
+ String *trimmed_value(String *res, uint32 offset, uint32 length)
+ {
+ tmp_value.set(*res, offset, length);
+ /*
+ Make sure to return correct charset and collation:
+ TRIM(0x000000 FROM _ucs2 0x0061)
+ should set charset to "binary" rather than to "ucs2".
+ */
+ tmp_value.set_charset(collation.collation);
+ return &tmp_value;
+ }
+ String *non_trimmed_value(String *res)
+ {
+ return trimmed_value(res, 0, res->length());
+ }
public:
Item_func_trim(Item *a,Item *b) :Item_str_func(a,b) {}
Item_func_trim(Item *a) :Item_str_func(a) {}
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 38bb3121ed8..7db7b014d28 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -3654,8 +3654,9 @@ int subselect_single_select_engine::exec()
pushed down into the subquery. Those optimizations are ref[_or_null]
acceses. Change them to be full table scans.
*/
- for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES); tab;
- tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
+ JOIN_TAB *tab;
+ for (tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES);
+ tab; tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
if (tab && tab->keyuse)
{
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 29badddad8e..cb8b59501a4 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -413,16 +413,15 @@ protected:
public:
Item_func_seconds_hybrid() :Item_func_numhybrid() {}
Item_func_seconds_hybrid(Item *a) :Item_func_numhybrid(a) {}
- void fix_num_length_and_dec()
+ void fix_length_and_dec()
{
if (arg_count)
decimals= args[0]->temporal_precision(arg0_expected_type());
set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
max_length=17 + (decimals ? decimals + 1 : 0);
maybe_null= true;
+ cached_result_type= decimals ? DECIMAL_RESULT : INT_RESULT;
}
- void find_num_type()
- { cached_result_type= decimals ? DECIMAL_RESULT : INT_RESULT; }
double real_op() { DBUG_ASSERT(0); return 0; }
String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
bool date_op(MYSQL_TIME *ltime, uint fuzzydate) { DBUG_ASSERT(0); return true; }
@@ -470,11 +469,6 @@ protected:
public:
Item_func_time_to_sec(Item *item) :Item_func_seconds_hybrid(item) {}
const char *func_name() const { return "time_to_sec"; }
- void fix_num_length_and_dec()
- {
- maybe_null= true;
- Item_func_seconds_hybrid::fix_num_length_and_dec();
- }
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_vcol_func_processor(uchar *int_arg) { return FALSE;}
bool check_valid_arguments_processor(uchar *int_arg)
diff --git a/sql/log.cc b/sql/log.cc
index 42d0a897eaa..71975cd83b7 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -2369,7 +2369,7 @@ static int find_uniq_filename(char *name)
file_info= dir_info->dir_entry;
for (i= dir_info->number_of_files ; i-- ; file_info++)
{
- if (memcmp(file_info->name, start, length) == 0 &&
+ if (strncmp(file_info->name, start, length) == 0 &&
test_if_number(file_info->name+length, &number,0))
{
set_if_bigger(max_found,(ulong) number);
@@ -2649,9 +2649,10 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
if (DBUG_EVALUATE_IF("binlog_inject_new_name_error", TRUE, FALSE) ||
find_uniq_filename(new_name))
{
- my_printf_error(ER_NO_UNIQUE_LOGFILE, ER(ER_NO_UNIQUE_LOGFILE),
- MYF(ME_FATALERROR), log_name);
- sql_print_error(ER(ER_NO_UNIQUE_LOGFILE), log_name);
+ if (current_thd)
+ my_printf_error(ER_NO_UNIQUE_LOGFILE, ER(ER_NO_UNIQUE_LOGFILE),
+ MYF(ME_FATALERROR), log_name);
+ sql_print_error(ER_DEFAULT(ER_NO_UNIQUE_LOGFILE), log_name);
return 1;
}
}
diff --git a/sql/log.h b/sql/log.h
index 67fcf068ec4..1bf87733ce2 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -1077,6 +1077,13 @@ end:
DBUG_RETURN(error);
}
-
+static inline TC_LOG *get_tc_log_implementation()
+{
+ if (total_ha_2pc <= 1)
+ return &tc_log_dummy;
+ if (opt_bin_log)
+ return &mysql_bin_log;
+ return &tc_log_mmap;
+}
#endif /* LOG_H */
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 188aa87ae51..20e71a48ed3 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -9009,9 +9009,9 @@ void Execute_load_query_log_event::print(FILE* file,
if (local_fname)
{
my_b_write(&cache, (uchar*) query, fn_pos_start);
- my_b_write_string(&cache, " LOCAL INFILE \'");
- my_b_printf(&cache, "%s", local_fname);
- my_b_write_string(&cache, "\'");
+ my_b_write_string(&cache, " LOCAL INFILE ");
+ pretty_print_str(&cache, local_fname, strlen(local_fname));
+
if (dup_handling == LOAD_DUP_REPLACE)
my_b_write_string(&cache, " REPLACE");
my_b_write_string(&cache, " INTO");
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index a23afb939a3..d751d6b7318 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -4802,6 +4802,8 @@ a file name for --log-bin-index option", opt_binlog_index_name);
if (ha_init_errors())
DBUG_RETURN(1);
+ tc_log= 0; // ha_initialize_handlerton() needs that
+
if (plugin_init(&remaining_argc, remaining_argv,
(opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
(opt_abort ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
@@ -4937,10 +4939,7 @@ a file name for --log-bin-index option", opt_binlog_index_name);
internal_tmp_table_max_key_segments= myisam_max_key_segments();
#endif
- tc_log= (total_ha_2pc > 1 ? (opt_bin_log ?
- (TC_LOG *) &mysql_bin_log :
- (TC_LOG *) &tc_log_mmap) :
- (TC_LOG *) &tc_log_dummy);
+ tc_log= get_tc_log_implementation();
if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file))
{
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index fc2aa75e604..b38b048c344 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2008, 2013, Monty Program Ab.
+/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2008, 2014, Monty Program Ab.
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
@@ -359,31 +359,54 @@ public:
elements(1),use_count(1),left(0),right(0),
next_key_part(0), color(BLACK), type(type_arg)
{}
- inline bool is_same(SEL_ARG *arg)
+ /**
+ returns true if a range predicate is equal. Use all_same()
+ to check for equality of all the predicates on this keypart.
+ */
+ inline bool is_same(const SEL_ARG *arg) const
{
if (type != arg->type || part != arg->part)
- return 0;
+ return false;
if (type != KEY_RANGE)
- return 1;
+ return true;
return cmp_min_to_min(arg) == 0 && cmp_max_to_max(arg) == 0;
}
+ /**
+ returns true if all the predicates in the keypart tree are equal
+ */
+ bool all_same(const SEL_ARG *arg) const
+ {
+ if (type != arg->type || part != arg->part)
+ return false;
+ if (type != KEY_RANGE)
+ return true;
+ if (arg == this)
+ return true;
+ const SEL_ARG *cmp_arg= arg->first();
+ const SEL_ARG *cur_arg= first();
+ for (; cur_arg && cmp_arg && cur_arg->is_same(cmp_arg);
+ cur_arg= cur_arg->next, cmp_arg= cmp_arg->next) ;
+ if (cur_arg || cmp_arg)
+ return false;
+ return true;
+ }
inline void merge_flags(SEL_ARG *arg) { maybe_flag|=arg->maybe_flag; }
inline void maybe_smaller() { maybe_flag=1; }
/* Return true iff it's a single-point null interval */
inline bool is_null_interval() { return maybe_null && max_value[0] == 1; }
- inline int cmp_min_to_min(SEL_ARG* arg)
+ inline int cmp_min_to_min(const SEL_ARG* arg) const
{
return sel_cmp(field,min_value, arg->min_value, min_flag, arg->min_flag);
}
- inline int cmp_min_to_max(SEL_ARG* arg)
+ inline int cmp_min_to_max(const SEL_ARG* arg) const
{
return sel_cmp(field,min_value, arg->max_value, min_flag, arg->max_flag);
}
- inline int cmp_max_to_max(SEL_ARG* arg)
+ inline int cmp_max_to_max(const SEL_ARG* arg) const
{
return sel_cmp(field,max_value, arg->max_value, max_flag, arg->max_flag);
}
- inline int cmp_max_to_min(SEL_ARG* arg)
+ inline int cmp_max_to_min(const SEL_ARG* arg) const
{
return sel_cmp(field,max_value, arg->min_value, max_flag, arg->min_flag);
}
@@ -563,6 +586,7 @@ public:
void test_use_count(SEL_ARG *root);
#endif
SEL_ARG *first();
+ const SEL_ARG *first() const;
SEL_ARG *last();
void make_root();
inline bool simple_key()
@@ -652,6 +676,18 @@ public:
SEL_ARG *clone_tree(RANGE_OPT_PARAM *param);
};
+/**
+ Helper function to compare two SEL_ARG's.
+*/
+static bool all_same(const SEL_ARG *sa1, const SEL_ARG *sa2)
+{
+ if (sa1 == NULL && sa2 == NULL)
+ return true;
+ if ((sa1 != NULL && sa2 == NULL) || (sa1 == NULL && sa2 != NULL))
+ return false;
+ return sa1->all_same(sa2);
+}
+
class SEL_IMERGE;
#define CLONE_KEY1_MAYBE 1
@@ -2495,6 +2531,13 @@ SEL_ARG *SEL_ARG::clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent,
return tmp;
}
+/**
+ This gives the first SEL_ARG in the interval list, and the minimal element
+ in the red-black tree
+
+ @return
+ SEL_ARG first SEL_ARG in the interval list
+*/
SEL_ARG *SEL_ARG::first()
{
SEL_ARG *next_arg=this;
@@ -2505,6 +2548,11 @@ SEL_ARG *SEL_ARG::first()
return next_arg;
}
+const SEL_ARG *SEL_ARG::first() const
+{
+ return const_cast<SEL_ARG*>(this)->first();
+}
+
SEL_ARG *SEL_ARG::last()
{
SEL_ARG *next_arg=this;
@@ -11043,6 +11091,7 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
uint part;
bool create_err= FALSE;
Cost_estimate cost;
+ uint max_used_key_len;
old_root= thd->mem_root;
/* The following call may change thd->mem_root */
@@ -11069,12 +11118,13 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
range->min_length= range->max_length= ref->key_length;
range->min_keypart_map= range->max_keypart_map=
make_prev_keypart_map(ref->key_parts);
- range->flag= (ref->key_length == key_info->key_length ? EQ_RANGE : 0);
+ range->flag= EQ_RANGE;
if (!(quick->key_parts=key_part=(KEY_PART *)
alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts)))
goto err;
-
+
+ max_used_key_len=0;
for (part=0 ; part < ref->key_parts ;part++,key_part++)
{
key_part->part=part;
@@ -11083,7 +11133,12 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
key_part->store_length= key_info->key_part[part].store_length;
key_part->null_bit= key_info->key_part[part].null_bit;
key_part->flag= (uint8) key_info->key_part[part].key_part_flag;
+
+ max_used_key_len +=key_info->key_part[part].store_length;
}
+
+ quick->max_used_key_length= max_used_key_len;
+
if (insert_dynamic(&quick->ranges,(uchar*)&range))
goto err;
@@ -12334,6 +12389,66 @@ void QUICK_ROR_UNION_SELECT::add_keys_and_lengths(String *key_names,
}
+void QUICK_RANGE_SELECT::add_used_key_part_to_set(MY_BITMAP *col_set)
+{
+ uint key_len;
+ KEY_PART *part= key_parts;
+ for (key_len=0; key_len < max_used_key_length;
+ key_len += (part++)->store_length)
+ {
+ bitmap_set_bit(col_set, part->field->field_index);
+ }
+}
+
+
+void QUICK_GROUP_MIN_MAX_SELECT::add_used_key_part_to_set(MY_BITMAP *col_set)
+{
+ uint key_len;
+ KEY_PART_INFO *part= index_info->key_part;
+ for (key_len=0; key_len < max_used_key_length;
+ key_len += (part++)->store_length)
+ {
+ bitmap_set_bit(col_set, part->field->field_index);
+ }
+}
+
+
+void QUICK_ROR_INTERSECT_SELECT::add_used_key_part_to_set(MY_BITMAP *col_set)
+{
+ List_iterator_fast<QUICK_SELECT_WITH_RECORD> it(quick_selects);
+ QUICK_SELECT_WITH_RECORD *quick;
+ while ((quick= it++))
+ {
+ quick->quick->add_used_key_part_to_set(col_set);
+ }
+}
+
+
+void QUICK_INDEX_SORT_SELECT::add_used_key_part_to_set(MY_BITMAP *col_set)
+{
+ QUICK_RANGE_SELECT *quick;
+ List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
+ while ((quick= it++))
+ {
+ quick->add_used_key_part_to_set(col_set);
+ }
+ if (pk_quick_select)
+ pk_quick_select->add_used_key_part_to_set(col_set);
+}
+
+
+void QUICK_ROR_UNION_SELECT::add_used_key_part_to_set(MY_BITMAP *col_set)
+{
+ QUICK_SELECT_I *quick;
+ List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
+
+ while ((quick= it++))
+ {
+ quick->add_used_key_part_to_set(col_set);
+ }
+}
+
+
/*******************************************************************************
* Implementation of QUICK_GROUP_MIN_MAX_SELECT
*******************************************************************************/
@@ -12341,6 +12456,8 @@ void QUICK_ROR_UNION_SELECT::add_keys_and_lengths(String *key_names,
static inline uint get_field_keypart(KEY *index, Field *field);
static inline SEL_ARG * get_index_range_tree(uint index, SEL_TREE* range_tree,
PARAM *param, uint *param_idx);
+static bool get_sel_arg_for_keypart(Field *field, SEL_ARG *index_range_tree,
+ SEL_ARG **cur_range);
static bool get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
KEY_PART_INFO *first_non_group_part,
KEY_PART_INFO *min_max_arg_part,
@@ -12406,6 +12523,16 @@ cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
never stored after a unique key lookup in the clustered index and
furhter index_next/prev calls can not be used. So loose index scan
optimization can not be used in this case.
+ SA7. If Q has both AGG_FUNC(DISTINCT ...) and MIN/MAX() functions then this
+ access method is not used.
+ For above queries MIN/MAX() aggregation has to be done at
+ nested_loops_join (end_send_group). But with current design MIN/MAX()
+ is always set as part of loose index scan. Because of this mismatch
+ MIN() and MAX() values will be set incorrectly. For such queries to
+ work we need a new interface for loose index scan. This new interface
+ should only fetch records with min and max values and let
+ end_send_group to do aggregation. Until then do not use
+ loose_index_scan.
GA1. If Q has a GROUP BY clause, then GA is a prefix of I. That is, if
G_i = A_j => i = j.
GA2. If Q has a DISTINCT clause, then there is a permutation of SA that
@@ -12437,6 +12564,8 @@ cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
above tests. By transitivity then it also follows that each WA_i
participates in the index I (if this was already tested for GA, NGA
and C).
+ WA2. If there is a predicate on C, then it must be in conjunction
+ to all predicates on all earlier keyparts in I.
C) Overall query form:
SELECT EXPR([A_1,...,A_k], [B_1,...,B_m], [MIN(C)], [MAX(C)])
@@ -12571,6 +12700,13 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
DBUG_RETURN(NULL);
}
}
+
+ /* Check (SA7). */
+ if (is_agg_distinct && (have_max || have_min))
+ {
+ DBUG_RETURN(NULL);
+ }
+
/* Check (SA5). */
if (join->select_distinct)
{
@@ -12860,6 +12996,25 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
}
}
+ /**
+ Test WA2:If there are conditions on a column C participating in
+ MIN/MAX, those conditions must be conjunctions to all earlier
+ keyparts. Otherwise, Loose Index Scan cannot be used.
+ */
+ if (tree && min_max_arg_item)
+ {
+ uint dummy;
+ SEL_ARG *index_range_tree= get_index_range_tree(cur_index, tree, param,
+ &dummy);
+ SEL_ARG *cur_range= NULL;
+ if (get_sel_arg_for_keypart(min_max_arg_part->field,
+ index_range_tree, &cur_range) ||
+ (cur_range && cur_range->type != SEL_ARG::KEY_RANGE))
+ {
+ goto next_index;
+ }
+ }
+
/* If we got to this point, cur_index_info passes the test. */
key_infix_parts= cur_key_infix_len ? (uint)
(first_non_infix_part - first_non_group_part) : 0;
@@ -13177,73 +13332,75 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
/*
- Get SEL_ARG tree, if any, for the keypart covering non grouping
- attribute (NGA) field 'nga_field'.
+ Get the SEL_ARG tree 'tree' for the keypart covering 'field', if
+ any. 'tree' must be a unique conjunction to ALL predicates in earlier
+ keyparts of 'keypart_tree'.
+
+ E.g., if 'keypart_tree' is for a composite index (kp1,kp2) and kp2
+ covers 'field', all these conditions satisfies the requirement:
- This function enforces the NGA3 test: If 'keypart_tree' contains a
- condition for 'nga_field', there can only be one range. In the
- opposite case, this function returns with error and 'cur_range'
- should not be used.
+ 1. "(kp1=2 OR kp1=3) AND kp2=10" => returns "kp2=10"
+ 2. "(kp1=2 AND kp2=10) OR (kp1=3 AND kp2=10)" => returns "kp2=10"
+ 3. "(kp1=2 AND (kp2=10 OR kp2=11)) OR (kp1=3 AND (kp2=10 OR kp2=11))"
+ => returns "kp2=10 OR kp2=11"
- Note that the NGA1 and NGA2 requirements, like whether or not the
- range predicate for 'nga_field' is equality, is not tested by this
- function.
+ whereas these do not
+ 1. "(kp1=2 AND kp2=10) OR kp1=3"
+ 2. "(kp1=2 AND kp2=10) OR (kp1=3 AND kp2=11)"
+ 3. "(kp1=2 AND kp2=10) OR (kp1=3 AND (kp2=10 OR kp2=11))"
- @param[in] nga_field The NGA field we want the SEL_ARG tree for
+ This function effectively tests requirement WA2. In combination with
+ a test that the returned tree has no more than one range it is also
+ a test of NGA3.
+
+ @param[in] field The field we want the SEL_ARG tree for
@param[in] keypart_tree Root node of the SEL_ARG* tree for the index
@param[out] cur_range The SEL_ARG tree, if any, for the keypart
covering field 'keypart_field'
- @retval true 'keypart_tree' contained a predicate for 'nga_field' but
- multiple ranges exists. 'cur_range' should not be used.
+ @retval true 'keypart_tree' contained a predicate for 'field' that
+ is not conjunction to all predicates on earlier keyparts
@retval false otherwise
*/
static bool
-get_sel_arg_for_keypart(Field *nga_field,
+get_sel_arg_for_keypart(Field *field,
SEL_ARG *keypart_tree,
SEL_ARG **cur_range)
{
- if(keypart_tree == NULL)
+ if (keypart_tree == NULL)
return false;
- if(keypart_tree->field->eq(nga_field))
+ if (keypart_tree->field->eq(field))
{
- /*
- Enforce NGA3: If a condition for nga_field has been found, only
- a single range is allowed.
- */
- if (keypart_tree->prev || keypart_tree->next)
- return true; // There are multiple ranges
-
*cur_range= keypart_tree;
return false;
}
- SEL_ARG *found_tree= NULL;
+ SEL_ARG *tree_first_range= NULL;
SEL_ARG *first_kp= keypart_tree->first();
- for (SEL_ARG *cur_kp= first_kp; cur_kp && !found_tree;
- cur_kp= cur_kp->next)
+ for (SEL_ARG *cur_kp= first_kp; cur_kp; cur_kp= cur_kp->next)
{
+ SEL_ARG *curr_tree= NULL;
if (cur_kp->next_key_part)
{
- if (get_sel_arg_for_keypart(nga_field,
+ if (get_sel_arg_for_keypart(field,
cur_kp->next_key_part,
- &found_tree))
+ &curr_tree))
return true;
-
}
/*
- Enforce NGA3: If a condition for nga_field has been found,only
- a single range is allowed.
- */
- if (found_tree && first_kp->next)
- return true; // There are multiple ranges
+ Check if the SEL_ARG tree for 'field' is identical for all ranges in
+ 'keypart_tree
+ */
+ if (cur_kp == first_kp)
+ tree_first_range= curr_tree;
+ else if (!all_same(tree_first_range, curr_tree))
+ return true;
}
- *cur_range= found_tree;
+ *cur_range= tree_first_range;
return false;
}
-
/*
Extract a sequence of constants from a conjunction of equality predicates.
@@ -13266,7 +13423,8 @@ get_sel_arg_for_keypart(Field *nga_field,
(const_ci = NG_i).. In addition, there can only be one range when there is
such a gap.
Thus all the NGF_i attributes must fill the 'gap' between the last group-by
- attribute and the MIN/MAX attribute in the index (if present). If these
+ attribute and the MIN/MAX attribute in the index (if present). Also ensure
+ that there is only a single range on NGF_i (NGA3). If these
conditions hold, copy each constant from its corresponding predicate into
key_infix, in the order its NG_i attribute appears in the index, and update
key_infix_len with the total length of the key parts in key_infix.
@@ -13275,7 +13433,6 @@ get_sel_arg_for_keypart(Field *nga_field,
TRUE if the index passes the test
FALSE o/w
*/
-
static bool
get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
KEY_PART_INFO *first_non_group_part,
@@ -13295,32 +13452,42 @@ get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
{
cur_range= NULL;
/*
- Find the range tree for the current keypart. We assume that
- index_range_tree points to the first keypart in the index.
+ Check NGA3:
+ 1. get_sel_arg_for_keypart gets the range tree for the 'field' and also
+ checks for a unique conjunction of this tree with all the predicates
+ on the earlier keyparts in the index.
+ 2. Check for multiple ranges on the found keypart tree.
+
+ We assume that index_range_tree points to the leftmost keypart in
+ the index.
*/
- if(get_sel_arg_for_keypart(cur_part->field, index_range_tree, &cur_range))
+ if (get_sel_arg_for_keypart(cur_part->field, index_range_tree,
+ &cur_range))
+ return false;
+
+ if (cur_range && cur_range->elements > 1)
return false;
if (!cur_range || cur_range->type != SEL_ARG::KEY_RANGE)
{
if (min_max_arg_part)
- return FALSE; /* The current keypart has no range predicates at all. */
+ return false; /* The current keypart has no range predicates at all. */
else
{
*first_non_infix_part= cur_part;
- return TRUE;
+ return true;
}
}
if ((cur_range->min_flag & NO_MIN_RANGE) ||
(cur_range->max_flag & NO_MAX_RANGE) ||
(cur_range->min_flag & NEAR_MIN) || (cur_range->max_flag & NEAR_MAX))
- return FALSE;
+ return false;
uint field_length= cur_part->store_length;
if (cur_range->maybe_null &&
cur_range->min_value[0] && cur_range->max_value[0])
- {
+ {
/*
cur_range specifies 'IS NULL'. In this case the argument points
to a "null value" (is_null_string) that may not always be long
@@ -13339,7 +13506,7 @@ get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
*key_infix_len+= field_length;
}
else
- return FALSE;
+ return false;
}
if (!min_max_arg_part && (cur_part == last_part))
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 1ca245ea420..54b15826d1b 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -389,6 +389,13 @@ public:
Returns a QUICK_SELECT with reverse order of to the index.
*/
virtual QUICK_SELECT_I *make_reverse(uint used_key_parts_arg) { return NULL; }
+
+ /*
+ Add the key columns used by the quick select into table's read set.
+
+ This is used by an optimization in filesort.
+ */
+ virtual void add_used_key_part_to_set(MY_BITMAP *col_set)=0;
};
@@ -479,6 +486,9 @@ public:
#endif
virtual void replace_handler(handler *new_file) { file= new_file; }
QUICK_SELECT_I *make_reverse(uint used_key_parts_arg);
+
+ virtual void add_used_key_part_to_set(MY_BITMAP *col_set);
+
private:
/* Default copy ctor used by QUICK_SELECT_DESC */
friend class TRP_ROR_INTERSECT;
@@ -640,6 +650,8 @@ public:
virtual int read_keys_and_merge()= 0;
/* used to get rows collected in Unique */
READ_RECORD read_record;
+
+ virtual void add_used_key_part_to_set(MY_BITMAP *col_set);
};
@@ -714,6 +726,7 @@ public:
void add_keys_and_lengths(String *key_names, String *used_lengths);
Explain_quick_select *get_explain(MEM_ROOT *alloc);
bool is_keys_used(const MY_BITMAP *fields);
+ void add_used_key_part_to_set(MY_BITMAP *col_set);
#ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose);
#endif
@@ -793,6 +806,7 @@ public:
void add_keys_and_lengths(String *key_names, String *used_lengths);
Explain_quick_select *get_explain(MEM_ROOT *alloc);
bool is_keys_used(const MY_BITMAP *fields);
+ void add_used_key_part_to_set(MY_BITMAP *col_set);
#ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose);
#endif
@@ -935,6 +949,7 @@ public:
bool unique_key_range() { return false; }
int get_type() { return QS_TYPE_GROUP_MIN_MAX; }
void add_keys_and_lengths(String *key_names, String *used_lengths);
+ void add_used_key_part_to_set(MY_BITMAP *col_set);
#ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose);
#endif
diff --git a/sql/replication.h b/sql/replication.h
index 510e56a3085..fc48ecd9ffc 100644
--- a/sql/replication.h
+++ b/sql/replication.h
@@ -16,6 +16,20 @@
#ifndef REPLICATION_H
#define REPLICATION_H
+/***************************************************************************
+ NOTE: plugin locking.
+ This API was created specifically for the semisync plugin and its locking
+ logic is also matches semisync plugin usage pattern. In particular, a plugin
+ is locked on Binlog_transmit_observer::transmit_start and is unlocked after
+ Binlog_transmit_observer::transmit_stop. All other master observable events
+ happen between these two and don't lock the plugin at all. This works well
+ for the semisync_master plugin.
+
+ Also a plugin is locked on Binlog_relay_IO_observer::thread_start
+ and unlocked after Binlog_relay_IO_observer::thread_stop. This works well for
+ the semisync_slave plugin.
+***************************************************************************/
+
#include <mysql.h>
typedef struct st_mysql MYSQL;
diff --git a/sql/rpl_handler.cc b/sql/rpl_handler.cc
index 2777dabf451..34d3df23435 100644
--- a/sql/rpl_handler.cc
+++ b/sql/rpl_handler.cc
@@ -170,40 +170,16 @@ void delegates_destroy()
/*
This macro is used by almost all the Delegate methods to iterate
over all the observers running given callback function of the
- delegate .
-
- Add observer plugins to the thd->lex list, after each statement, all
- plugins add to thd->lex will be automatically unlocked.
+ delegate.
*/
-#define FOREACH_OBSERVER(r, f, thd, args) \
+#define FOREACH_OBSERVER(r, f, do_lock, args) \
param.server_id= thd->variables.server_id; \
- /*
- Use a struct to make sure that they are allocated adjacent, check
- delete_dynamic().
- */ \
- struct { \
- DYNAMIC_ARRAY plugins; \
- /* preallocate 8 slots */ \
- plugin_ref plugins_buffer[8]; \
- } s; \
- DYNAMIC_ARRAY *plugins= &s.plugins; \
- plugin_ref *plugins_buffer= s.plugins_buffer; \
- my_init_dynamic_array2(plugins, sizeof(plugin_ref), \
- plugins_buffer, 8, 8, MYF(0)); \
read_lock(); \
Observer_info_iterator iter= observer_info_iter(); \
Observer_info *info= iter++; \
for (; info; info= iter++) \
{ \
- plugin_ref plugin= \
- my_plugin_lock(0, info->plugin); \
- if (!plugin) \
- { \
- /* plugin is not intialized or deleted, this is not an error */ \
- r= 0; \
- break; \
- } \
- insert_dynamic(plugins, (uchar *)&plugin); \
+ if (do_lock) plugin_lock(thd, plugin_int_to_ref(info->plugin_int)); \
if (((Observer *)info->observer)->f \
&& ((Observer *)info->observer)->f args) \
{ \
@@ -213,17 +189,7 @@ void delegates_destroy()
break; \
} \
} \
- unlock(); \
- /*
- Unlock plugins should be done after we released the Delegate lock
- to avoid possible deadlock when this is the last user of the
- plugin, and when we unlock the plugin, it will try to
- deinitialize the plugin, which will try to lock the Delegate in
- order to remove the observers.
- */ \
- plugin_unlock_list(0, (plugin_ref*)plugins->buffer, \
- plugins->elements); \
- delete_dynamic(plugins)
+ unlock();
int Trans_delegate::after_commit(THD *thd, bool all)
@@ -240,7 +206,7 @@ int Trans_delegate::after_commit(THD *thd, bool all)
param.log_pos= log_info ? log_info->log_pos : 0;
int ret= 0;
- FOREACH_OBSERVER(ret, after_commit, thd, (&param));
+ FOREACH_OBSERVER(ret, after_commit, false, (&param));
/*
This is the end of a real transaction or autocommit statement, we
@@ -268,7 +234,7 @@ int Trans_delegate::after_rollback(THD *thd, bool all)
param.log_pos= log_info ? log_info->log_pos : 0;
int ret= 0;
- FOREACH_OBSERVER(ret, after_rollback, thd, (&param));
+ FOREACH_OBSERVER(ret, after_rollback, false, (&param));
/*
This is the end of a real transaction or autocommit statement, we
@@ -307,7 +273,7 @@ int Binlog_storage_delegate::after_flush(THD *thd,
log_info->log_pos = log_pos;
int ret= 0;
- FOREACH_OBSERVER(ret, after_flush, thd,
+ FOREACH_OBSERVER(ret, after_flush, false,
(&param, log_info->log_file, log_info->log_pos, flags));
return ret;
}
@@ -321,7 +287,7 @@ int Binlog_transmit_delegate::transmit_start(THD *thd, ushort flags,
param.flags= flags;
int ret= 0;
- FOREACH_OBSERVER(ret, transmit_start, thd, (&param, log_file, log_pos));
+ FOREACH_OBSERVER(ret, transmit_start, true, (&param, log_file, log_pos));
return ret;
}
@@ -331,7 +297,7 @@ int Binlog_transmit_delegate::transmit_stop(THD *thd, ushort flags)
param.flags= flags;
int ret= 0;
- FOREACH_OBSERVER(ret, transmit_stop, thd, (&param));
+ FOREACH_OBSERVER(ret, transmit_stop, false, (&param));
return ret;
}
@@ -356,13 +322,6 @@ int Binlog_transmit_delegate::reserve_header(THD *thd, ushort flags,
Observer_info *info= iter++;
for (; info; info= iter++)
{
- plugin_ref plugin=
- my_plugin_lock(thd, info->plugin);
- if (!plugin)
- {
- ret= 1;
- break;
- }
hlen= 0;
if (((Observer *)info->observer)->reserve_header
&& ((Observer *)info->observer)->reserve_header(&param,
@@ -371,10 +330,8 @@ int Binlog_transmit_delegate::reserve_header(THD *thd, ushort flags,
&hlen))
{
ret= 1;
- plugin_unlock(thd, plugin);
break;
}
- plugin_unlock(thd, plugin);
if (hlen == 0)
continue;
if (hlen > RESERVE_HEADER_SIZE || packet->append((char *)header, hlen))
@@ -396,7 +353,7 @@ int Binlog_transmit_delegate::before_send_event(THD *thd, ushort flags,
param.flags= flags;
int ret= 0;
- FOREACH_OBSERVER(ret, before_send_event, thd,
+ FOREACH_OBSERVER(ret, before_send_event, false,
(&param, (uchar *)packet->c_ptr(),
packet->length(),
log_file+dirname_length(log_file), log_pos));
@@ -410,7 +367,7 @@ int Binlog_transmit_delegate::after_send_event(THD *thd, ushort flags,
param.flags= flags;
int ret= 0;
- FOREACH_OBSERVER(ret, after_send_event, thd,
+ FOREACH_OBSERVER(ret, after_send_event, false,
(&param, packet->c_ptr(), packet->length()));
return ret;
}
@@ -422,7 +379,7 @@ int Binlog_transmit_delegate::after_reset_master(THD *thd, ushort flags)
param.flags= flags;
int ret= 0;
- FOREACH_OBSERVER(ret, after_reset_master, thd, (&param));
+ FOREACH_OBSERVER(ret, after_reset_master, false, (&param));
return ret;
}
@@ -443,7 +400,7 @@ int Binlog_relay_IO_delegate::thread_start(THD *thd, Master_info *mi)
init_param(&param, mi);
int ret= 0;
- FOREACH_OBSERVER(ret, thread_start, thd, (&param));
+ FOREACH_OBSERVER(ret, thread_start, true, (&param));
return ret;
}
@@ -455,7 +412,7 @@ int Binlog_relay_IO_delegate::thread_stop(THD *thd, Master_info *mi)
init_param(&param, mi);
int ret= 0;
- FOREACH_OBSERVER(ret, thread_stop, thd, (&param));
+ FOREACH_OBSERVER(ret, thread_stop, false, (&param));
return ret;
}
@@ -467,7 +424,7 @@ int Binlog_relay_IO_delegate::before_request_transmit(THD *thd,
init_param(&param, mi);
int ret= 0;
- FOREACH_OBSERVER(ret, before_request_transmit, thd, (&param, (uint32)flags));
+ FOREACH_OBSERVER(ret, before_request_transmit, false, (&param, (uint32)flags));
return ret;
}
@@ -480,7 +437,7 @@ int Binlog_relay_IO_delegate::after_read_event(THD *thd, Master_info *mi,
init_param(&param, mi);
int ret= 0;
- FOREACH_OBSERVER(ret, after_read_event, thd,
+ FOREACH_OBSERVER(ret, after_read_event, false,
(&param, packet, len, event_buf, event_len));
return ret;
}
@@ -498,7 +455,7 @@ int Binlog_relay_IO_delegate::after_queue_event(THD *thd, Master_info *mi,
flags |= BINLOG_STORAGE_IS_SYNCED;
int ret= 0;
- FOREACH_OBSERVER(ret, after_queue_event, thd,
+ FOREACH_OBSERVER(ret, after_queue_event, false,
(&param, event_buf, event_len, flags));
return ret;
}
@@ -510,7 +467,7 @@ int Binlog_relay_IO_delegate::after_reset_slave(THD *thd, Master_info *mi)
init_param(&param, mi);
int ret= 0;
- FOREACH_OBSERVER(ret, after_reset_slave, thd, (&param));
+ FOREACH_OBSERVER(ret, after_reset_slave, false, (&param));
return ret;
}
#endif /* HAVE_REPLICATION */
diff --git a/sql/rpl_handler.h b/sql/rpl_handler.h
index e028fb49808..e262ebdbd6b 100644
--- a/sql/rpl_handler.h
+++ b/sql/rpl_handler.h
@@ -26,13 +26,10 @@ class Observer_info {
public:
void *observer;
st_plugin_int *plugin_int;
- plugin_ref plugin;
Observer_info(void *ob, st_plugin_int *p)
:observer(ob), plugin_int(p)
- {
- plugin= plugin_int_to_ref(plugin_int);
- }
+ { }
};
class Delegate {
diff --git a/sql/scheduler.cc b/sql/scheduler.cc
index ecf49e633ab..a9b253e478a 100644
--- a/sql/scheduler.cc
+++ b/sql/scheduler.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
- Copyright (c) 2012, 2013, Monty Program Ab
+/* Copyright (c) 2007, 2013, Oracle and/or its affiliates.
+ Copyright (c) 2012, 2014, SkySQL Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/slave.cc b/sql/slave.cc
index 5d6ce9287f2..cdab2779e86 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1772,15 +1772,35 @@ when it try to get the value of TIME_ZONE global variable from master.";
llstr((ulonglong) (mi->heartbeat_period*1000000000UL), llbuf);
sprintf(query, query_format, llbuf);
- if (mysql_real_query(mysql, query, strlen(query))
- && !check_io_slave_killed(mi, NULL))
+ DBUG_EXECUTE_IF("simulate_slave_heartbeat_network_error",
+ { static ulong dbug_count= 0;
+ if (++dbug_count < 3)
+ goto heartbeat_network_error;
+ });
+ if (mysql_real_query(mysql, query, strlen(query)))
{
- errmsg= "The slave I/O thread stops because SET @master_heartbeat_period "
- "on master failed.";
- err_code= ER_SLAVE_FATAL_ERROR;
- sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
- mysql_free_result(mysql_store_result(mysql));
- goto err;
+ if (check_io_slave_killed(mi, NULL))
+ goto slave_killed_err;
+
+ if (is_network_error(mysql_errno(mysql)))
+ {
+ IF_DBUG(heartbeat_network_error: , )
+ mi->report(WARNING_LEVEL, mysql_errno(mysql),
+ "SET @master_heartbeat_period to master failed with error: %s",
+ mysql_error(mysql));
+ mysql_free_result(mysql_store_result(mysql));
+ goto network_err;
+ }
+ else
+ {
+ /* Fatal error */
+ errmsg= "The slave I/O thread stops because a fatal error is encountered "
+ "when it tries to SET @master_heartbeat_period on master.";
+ err_code= ER_SLAVE_FATAL_ERROR;
+ sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
+ mysql_free_result(mysql_store_result(mysql));
+ goto err;
+ }
}
mysql_free_result(mysql_store_result(mysql));
}
@@ -4179,9 +4199,10 @@ err_during_init:
// TODO: make rpl_status part of Master_info
change_rpl_status(RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE);
mysql_mutex_lock(&LOCK_thread_count);
+ thd->unlink();
+ mysql_mutex_unlock(&LOCK_thread_count);
THD_CHECK_SENTRY(thd);
delete thd;
- mysql_mutex_unlock(&LOCK_thread_count);
mi->abort_slave= 0;
mi->slave_running= MYSQL_SLAVE_NOT_RUN;
mi->io_thd= 0;
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index cf68ba36997..6001517b0c7 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1711,7 +1711,7 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
DBUG_ENTER("Query_cache::send_result_to_client");
/*
- Testing 'query_cache_size' without a lock here is safe: the thing
+ Testing without a lock here is safe: the thing
we may loose is that the query won't be served from cache, but we
save on mutex locking in the case when query cache is disabled.
@@ -1731,8 +1731,6 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
goto err;
}
- DBUG_ASSERT(query_cache_size != 0); // otherwise cache would be disabled
-
thd->query_cache_is_applicable= 1;
sql= org_sql; sql_end= sql + query_length;
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 27e195e52d4..650966dd78a 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2008, 2013, Monty Program Ab.
+ Copyright (c) 2008, 2014, SkySQL Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index b3a8eb2a97b..a8f7e270891 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -912,7 +912,8 @@ multi_delete::initialize_tables(JOIN *join)
walk= delete_tables;
- for (JOIN_TAB *tab= first_linear_tab(join, WITH_CONST_TABLES);
+ for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_BUSH_ROOTS,
+ WITH_CONST_TABLES);
tab;
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
{
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index a910ed6290f..c62fb81334a 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -614,6 +614,7 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
SELECT_LEX_UNIT *unit= derived->get_unit();
DBUG_ENTER("mysql_derived_prepare");
bool res= FALSE;
+ DBUG_PRINT("enter", ("unit 0x%lx", (ulong) unit));
// Skip already prepared views/DT
if (!unit || unit->prepared ||
@@ -623,9 +624,6 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
thd->lex->sql_command == SQLCOM_DELETE_MULTI))))
DBUG_RETURN(FALSE);
- Query_arena *arena, backup;
- arena= thd->activate_stmt_arena_if_needed(&backup);
-
SELECT_LEX *first_select= unit->first_select();
/* prevent name resolving out of derived table */
@@ -743,8 +741,6 @@ exit:
if (derived->outer_join)
table->maybe_null= 1;
}
- if (arena)
- thd->restore_active_arena(arena, &backup);
DBUG_RETURN(res);
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index d1b9961503f..e0f6a998e66 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2009, 2013, Monty Program Ab.
+ Copyright (c) 2010, 2014, SkySQL Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index c549a7be2cc..e38075f1746 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2009, 2013, Monty Program Ab.
+/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2014, Monty Program Ab.
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
@@ -30,7 +30,7 @@
#include "sp.h"
#include "sql_select.h"
-static int lex_one_token(void *arg, THD *thd);
+static int lex_one_token(YYSTYPE *yylval, THD *thd);
/*
We are using pointer to this variable for distinguishing between assignment
@@ -958,15 +958,17 @@ bool consume_comment(Lex_input_stream *lip, int remaining_recursions_permitted)
/*
MYSQLlex remember the following states from the following MYSQLlex()
+ @param yylval [out] semantic value of the token being parsed (yylval)
+ @param thd THD
+
- MY_LEX_EOQ Found end of query
- MY_LEX_OPERATOR_OR_IDENT Last state was an ident, text or number
(which can't be followed by a signed number)
*/
-int MYSQLlex(void *arg, THD *thd)
+int MYSQLlex(YYSTYPE *yylval, THD *thd)
{
Lex_input_stream *lip= & thd->m_parser_state->m_lip;
- YYSTYPE *yylval=(YYSTYPE*) arg;
int token;
if (lip->lookahead_token >= 0)
@@ -983,7 +985,7 @@ int MYSQLlex(void *arg, THD *thd)
return token;
}
- token= lex_one_token(arg, thd);
+ token= lex_one_token(yylval, thd);
switch(token) {
case WITH:
@@ -994,7 +996,7 @@ int MYSQLlex(void *arg, THD *thd)
to transform the grammar into a LALR(1) grammar,
which sql_yacc.yy can process.
*/
- token= lex_one_token(arg, thd);
+ token= lex_one_token(yylval, thd);
switch(token) {
case CUBE_SYM:
lip->m_digest_psi= MYSQL_ADD_TOKEN(lip->m_digest_psi, WITH_CUBE_SYM,
@@ -1023,7 +1025,7 @@ int MYSQLlex(void *arg, THD *thd)
return token;
}
-int lex_one_token(void *arg, THD *thd)
+static int lex_one_token(YYSTYPE *yylval, THD *thd)
{
reg1 uchar c;
bool comment_closed;
@@ -1032,7 +1034,6 @@ int lex_one_token(void *arg, THD *thd)
enum my_lex_states state;
Lex_input_stream *lip= & thd->m_parser_state->m_lip;
LEX *lex= thd->lex;
- YYSTYPE *yylval=(YYSTYPE*) arg;
CHARSET_INFO *const cs= thd->charset();
const uchar *const state_map= cs->state_map;
const uchar *const ident_map= cs->ident_map;
@@ -3281,7 +3282,7 @@ static void fix_prepare_info_in_table_list(THD *thd, TABLE_LIST *tbl)
{
for (; tbl; tbl= tbl->next_local)
{
- if (tbl->on_expr)
+ if (tbl->on_expr && !tbl->prep_on_expr)
{
thd->check_and_register_item_tree(&tbl->prep_on_expr, &tbl->on_expr);
tbl->on_expr= tbl->on_expr->copy_andor_structure(thd);
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 76288e94c75..e15901a9c54 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2010, 2013, Monty Program Ab.
+/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2014, Monty Program Ab.
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
@@ -2911,7 +2911,7 @@ extern void lex_start(THD *thd);
extern void lex_end(LEX *lex);
void end_lex_with_single_table(THD *thd, TABLE *table, LEX *old_lex);
int init_lex_with_single_table(THD *thd, TABLE *table, LEX *lex);
-extern int MYSQLlex(void *arg, THD *thd);
+extern int MYSQLlex(union YYSTYPE *yylval, THD *thd);
extern void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index d3f1ad9afba..4070a833f82 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2008, 2013, Monty Program Ab
+ Copyright (c) 2008, 2014, SkySQL Ab.
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
@@ -7390,7 +7390,7 @@ static uint kill_threads_for_user(THD *thd, LEX_USER *user,
I_List_iterator<THD> it(threads);
while ((tmp=it++))
{
- if (tmp->get_command() == COM_DAEMON)
+ if (!tmp->security_ctx->user)
continue;
/*
Check that hostname (if given) and user name matches.
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 1ce952b9030..18e49d878cd 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2005, 2013, Oracle and/or its affiliates.
- Copyright (c) 2009, 2013, Monty Program Ab.
+/* Copyright (c) 2005, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2014, SkySQL Ab.
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
@@ -3167,19 +3167,28 @@ uint32 get_partition_id_cols_list_for_endpoint(partition_info *part_info,
uint num_columns= part_info->part_field_list.elements;
uint list_index;
uint min_list_index= 0;
+ int cmp;
+ /* Notice that max_list_index = last_index + 1 here! */
uint max_list_index= part_info->num_list_values;
DBUG_ENTER("get_partition_id_cols_list_for_endpoint");
/* Find the matching partition (including taking endpoint into account). */
do
{
- /* Midpoint, adjusted down, so it can never be > last index. */
+ /* Midpoint, adjusted down, so it can never be >= max_list_index. */
list_index= (max_list_index + min_list_index) >> 1;
- if (cmp_rec_and_tuple_prune(list_col_array + list_index*num_columns,
- nparts, left_endpoint, include_endpoint) > 0)
+ cmp= cmp_rec_and_tuple_prune(list_col_array + list_index*num_columns,
+ nparts, left_endpoint, include_endpoint);
+ if (cmp > 0)
+ {
min_list_index= list_index + 1;
+ }
else
+ {
max_list_index= list_index;
+ if (cmp == 0)
+ break;
+ }
} while (max_list_index > min_list_index);
list_index= max_list_index;
@@ -3196,12 +3205,10 @@ uint32 get_partition_id_cols_list_for_endpoint(partition_info *part_info,
nparts, left_endpoint,
include_endpoint)));
- if (!left_endpoint)
- {
- /* Set the end after this list tuple if not already after the last. */
- if (list_index < part_info->num_parts)
- list_index++;
- }
+ /* Include the right endpoint if not already passed end of array. */
+ if (!left_endpoint && include_endpoint && cmp == 0 &&
+ list_index < part_info->num_list_values)
+ list_index++;
DBUG_RETURN(list_index);
}
@@ -7573,15 +7580,13 @@ static int cmp_rec_and_tuple_prune(part_column_list_val *val,
field= val->part_info->part_field_array + n_vals_in_rec;
if (!(*field))
{
- /*
- Full match, if right endpoint and not including the endpoint,
- (rec < part) return lesser.
- */
- if (!is_left_endpoint && !include_endpoint)
- return -4;
+ /* Full match. Only equal if including endpoint. */
+ if (include_endpoint)
+ return 0;
- /* Otherwise they are equal! */
- return 0;
+ if (is_left_endpoint)
+ return +4; /* Start of range, part_tuple < rec, return higher. */
+ return -4; /* End of range, rec < part_tupe, return lesser. */
}
/*
The prefix is equal and there are more partition columns to compare.
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index d79cc0aaada..0521baaf77f 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1613,7 +1613,7 @@ int plugin_init(int *argc, char **argv, int flags)
if (plugin_initialize(&tmp_root, plugin_ptr, argc, argv, !is_myisam &&
(flags & PLUGIN_INIT_SKIP_INITIALIZATION)))
{
- if (mandatory)
+ if (plugin_ptr->load_option == PLUGIN_FORCE)
goto err_unlock;
plugin_ptr->state= PLUGIN_IS_DISABLED;
}
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index e2ba5197dc4..0f4a7c5133e 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2008, 2013, Monty Program Ab
+ Copyright (c) 2008, 2014, SkySQL Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 3b3d1527607..160ffe11abc 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1441,7 +1441,8 @@ TODO: make view to decide if it is possible to write to WHERE directly or make S
Perform the optimization on fields evaluation mentioned above
for all on expressions.
*/
- for (JOIN_TAB *tab= first_linear_tab(this, WITHOUT_CONST_TABLES); tab;
+ JOIN_TAB *tab;
+ for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); tab;
tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
{
if (*tab->on_expr_ref)
@@ -1464,7 +1465,7 @@ TODO: make view to decide if it is possible to write to WHERE directly or make S
Perform the optimization on fields evaliation mentioned above
for all used ref items.
*/
- for (JOIN_TAB *tab= first_linear_tab(this, WITHOUT_CONST_TABLES); tab;
+ for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); tab;
tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
{
uint key_copy_index=0;
@@ -2099,7 +2100,8 @@ bool JOIN::setup_subquery_caches()
if (conds)
conds= conds->transform(&Item::expr_cache_insert_transformer,
(uchar*) thd);
- for (JOIN_TAB *tab= first_linear_tab(this, WITHOUT_CONST_TABLES);
+ JOIN_TAB *tab;
+ for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES);
tab; tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
{
if (tab->select_cond)
@@ -2261,7 +2263,8 @@ JOIN::reinit()
/* need to reset ref access state (see join_read_key) */
if (join_tab)
{
- for (JOIN_TAB *tab= first_linear_tab(this, WITH_CONST_TABLES); tab;
+ JOIN_TAB *tab;
+ for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITH_CONST_TABLES); tab;
tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
{
tab->ref.key_err= TRUE;
@@ -3120,8 +3123,9 @@ JOIN::destroy()
{
if (join_tab != tmp_join->join_tab)
{
- for (JOIN_TAB *tab= first_linear_tab(this, WITH_CONST_TABLES); tab;
- tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
+ JOIN_TAB *tab;
+ for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITH_CONST_TABLES);
+ tab; tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
{
tab->cleanup();
}
@@ -8186,14 +8190,24 @@ JOIN_TAB *next_top_level_tab(JOIN *join, JOIN_TAB *tab)
}
-JOIN_TAB *first_linear_tab(JOIN *join, enum enum_with_const_tables const_tbls)
+JOIN_TAB *first_linear_tab(JOIN *join,
+ enum enum_with_bush_roots include_bush_roots,
+ enum enum_with_const_tables const_tbls)
{
JOIN_TAB *first= join->join_tab;
if (const_tbls == WITHOUT_CONST_TABLES)
first+= join->const_tables;
- if (first < join->join_tab + join->top_join_tab_count)
- return first;
- return NULL; /* All tables were const tables */
+
+ if (first >= join->join_tab + join->top_join_tab_count)
+ return NULL; /* All are const tables */
+
+ if (first->bush_children && include_bush_roots == WITHOUT_BUSH_ROOTS)
+ {
+ /* This JOIN_TAB is a SJM nest; Start from first table in nest */
+ return first->bush_children->start;
+ }
+
+ return first;
}
@@ -9045,9 +9059,10 @@ inline void add_cond_and_fix(THD *thd, Item **e1, Item *e2)
static void add_not_null_conds(JOIN *join)
{
+ JOIN_TAB *tab;
DBUG_ENTER("add_not_null_conds");
- for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
+ for (tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES);
tab;
tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
@@ -9218,7 +9233,7 @@ make_outerjoin_info(JOIN *join)
tab->table->pos_in_table_list being set.
*/
JOIN_TAB *tab;
- for (tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
+ for (tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES);
tab;
tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
@@ -9230,7 +9245,7 @@ make_outerjoin_info(JOIN *join)
}
}
- for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES); tab;
+ for (JOIN_TAB *tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); tab;
tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
TABLE *table= tab->table;
@@ -9982,7 +9997,7 @@ bool generate_derived_keys(DYNAMIC_ARRAY *keyuse_array)
void JOIN::drop_unused_derived_keys()
{
JOIN_TAB *tab;
- for (tab= first_linear_tab(this, WITHOUT_CONST_TABLES);
+ for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES);
tab;
tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
{
@@ -10670,7 +10685,7 @@ void check_join_cache_usage_for_tables(JOIN *join, ulonglong options,
JOIN_TAB *tab;
JOIN_TAB *prev_tab;
- for (tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
+ for (tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES);
tab;
tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
@@ -10678,7 +10693,7 @@ void check_join_cache_usage_for_tables(JOIN *join, ulonglong options,
}
uint idx= join->const_tables;
- for (tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
+ for (tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES);
tab;
tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
@@ -10852,7 +10867,8 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
tab->partial_join_cardinality= 1;
JOIN_TAB *prev_tab= NULL;
- for (tab= first_linear_tab(join, WITHOUT_CONST_TABLES), i= join->const_tables;
+ i= join->const_tables;
+ for (tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES);
tab;
prev_tab=tab, tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
@@ -10877,7 +10893,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
check_join_cache_usage_for_tables(join, options, no_jbuf_after);
JOIN_TAB *first_tab;
- for (tab= first_tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
+ for (tab= first_tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES);
tab;
tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
@@ -11571,7 +11587,8 @@ void JOIN::cleanup(bool full)
}
if (full)
{
- JOIN_TAB *sort_tab= first_linear_tab(this, WITHOUT_CONST_TABLES);
+ JOIN_TAB *sort_tab= first_linear_tab(this, WITH_BUSH_ROOTS,
+ WITHOUT_CONST_TABLES);
if (pre_sort_join_tab)
{
if (sort_tab && sort_tab->select == pre_sort_join_tab->select)
@@ -11618,7 +11635,7 @@ void JOIN::cleanup(bool full)
}
else
{
- for (tab= first_linear_tab(this, WITH_CONST_TABLES); tab;
+ for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITH_CONST_TABLES); tab;
tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
{
if (tab->table)
@@ -11780,7 +11797,9 @@ only_eq_ref_tables(JOIN *join,ORDER *order,table_map tables)
static void update_depend_map(JOIN *join)
{
- for (JOIN_TAB *join_tab= first_linear_tab(join, WITH_CONST_TABLES); join_tab;
+ JOIN_TAB *join_tab;
+ for (join_tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITH_CONST_TABLES);
+ join_tab;
join_tab= next_linear_tab(join, join_tab, WITH_BUSH_ROOTS))
{
TABLE_REF *ref= &join_tab->ref;
diff --git a/sql/sql_select.h b/sql/sql_select.h
index dc86825e8e9..490d8c91a9e 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1500,7 +1500,9 @@ private:
enum enum_with_bush_roots { WITH_BUSH_ROOTS, WITHOUT_BUSH_ROOTS};
enum enum_with_const_tables { WITH_CONST_TABLES, WITHOUT_CONST_TABLES};
-JOIN_TAB *first_linear_tab(JOIN *join, enum enum_with_const_tables const_tbls);
+JOIN_TAB *first_linear_tab(JOIN *join,
+ enum enum_with_bush_roots include_bush_roots,
+ enum enum_with_const_tables const_tbls);
JOIN_TAB *next_linear_tab(JOIN* join, JOIN_TAB* tab,
enum enum_with_bush_roots include_bush_roots);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 025eee72878..3916b7acf6b 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -8072,8 +8072,9 @@ bool get_schema_tables_result(JOIN *join,
Warnings_only_error_handler err_handler;
thd->push_internal_handler(&err_handler);
old_proc_info= thd_proc_info(thd, "Filling schema table");
-
- for (JOIN_TAB *tab= first_linear_tab(join, WITH_CONST_TABLES);
+
+ JOIN_TAB *tab;
+ for (tab= first_linear_tab(join, WITHOUT_BUSH_ROOTS, WITH_CONST_TABLES);
tab;
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
{
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 3a44303e3ba..5f2f1141a04 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2014, Oracle and/or its affiliates.
- Copyright (c) 2010, 2014, Monty Program Ab.
+ Copyright (c) 2010, 2014, SkySQL Ab.
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
@@ -75,6 +75,7 @@ static bool prepare_blob_field(THD *thd, Create_field *sql_field);
static bool check_engine(THD *, const char *, const char *, HA_CREATE_INFO *);
static int mysql_prepare_create_table(THD *, HA_CREATE_INFO *, Alter_info *,
uint *, handler *, KEY **, uint *, int);
+static uint blob_length_by_type(enum_field_types type);
/**
@brief Helper function for explain_filename
@@ -3812,7 +3813,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
CHARSET_INFO *ft_key_charset=0; // for FULLTEXT
for (uint column_nr=0 ; (column=cols++) ; column_nr++)
{
- uint length;
Key_part_spec *dup_column;
it.rewind();
@@ -3890,7 +3890,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
if (f_is_geom(sql_field->pack_flag) && sql_field->geom_type ==
Field::GEOM_POINT)
- column->length= 25;
+ column->length= MAX_LEN_GEOM_POINT_FIELD;
if (!column->length)
{
my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name.str);
@@ -3956,30 +3956,31 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
key_part_info->fieldnr= field;
key_part_info->offset= (uint16) sql_field->offset;
key_part_info->key_type=sql_field->pack_flag;
- length= sql_field->key_length;
+ uint key_part_length= sql_field->key_length;
if (column->length)
{
if (f_is_blob(sql_field->pack_flag))
{
- if ((length=column->length) > max_key_length ||
- length > file->max_key_part_length())
+ key_part_length= MY_MIN(column->length,
+ blob_length_by_type(sql_field->sql_type)
+ * sql_field->charset->mbmaxlen);
+ if (key_part_length > max_key_length ||
+ key_part_length > file->max_key_part_length())
{
- length=MY_MIN(max_key_length, file->max_key_part_length());
+ key_part_length= MY_MIN(max_key_length, file->max_key_part_length());
if (key->type == Key::MULTIPLE)
{
/* not a critical problem */
- char warn_buff[MYSQL_ERRMSG_SIZE];
- my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
- length);
- push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_TOO_LONG_KEY, warn_buff);
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_TOO_LONG_KEY, ER(ER_TOO_LONG_KEY),
+ key_part_length);
/* Align key length to multibyte char boundary */
- length-= length % sql_field->charset->mbmaxlen;
+ key_part_length-= key_part_length % sql_field->charset->mbmaxlen;
}
else
{
- my_error(ER_TOO_LONG_KEY,MYF(0),length);
+ my_error(ER_TOO_LONG_KEY, MYF(0), key_part_length);
DBUG_RETURN(TRUE);
}
}
@@ -3987,9 +3988,9 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
// Catch invalid use of partial keys
else if (!f_is_geom(sql_field->pack_flag) &&
// is the key partial?
- column->length != length &&
+ column->length != key_part_length &&
// is prefix length bigger than field length?
- (column->length > length ||
+ (column->length > key_part_length ||
// can the field have a partial key?
!Field::type_can_have_key_part (sql_field->sql_type) ||
// a packed field can't be used in a partial key
@@ -3998,44 +3999,43 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
((file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
// and is this a 'unique' key?
(key_info->flags & HA_NOSAME))))
- {
+ {
my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0));
DBUG_RETURN(TRUE);
}
else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS))
- length=column->length;
+ key_part_length= column->length;
}
- else if (length == 0 && (sql_field->flags & NOT_NULL_FLAG))
+ else if (key_part_length == 0 && (sql_field->flags & NOT_NULL_FLAG))
{
my_error(ER_WRONG_KEY_COLUMN, MYF(0), file->table_type(),
column->field_name.str);
DBUG_RETURN(TRUE);
}
- if (length > file->max_key_part_length() && key->type != Key::FULLTEXT)
+ if (key_part_length > file->max_key_part_length() &&
+ key->type != Key::FULLTEXT)
{
- length= file->max_key_part_length();
+ key_part_length= file->max_key_part_length();
if (key->type == Key::MULTIPLE)
{
/* not a critical problem */
- char warn_buff[MYSQL_ERRMSG_SIZE];
- my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
- length);
- push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_TOO_LONG_KEY, warn_buff);
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_TOO_LONG_KEY, ER(ER_TOO_LONG_KEY),
+ key_part_length);
/* Align key length to multibyte char boundary */
- length-= length % sql_field->charset->mbmaxlen;
+ key_part_length-= key_part_length % sql_field->charset->mbmaxlen;
}
else
{
- my_error(ER_TOO_LONG_KEY,MYF(0),length);
+ my_error(ER_TOO_LONG_KEY, MYF(0), key_part_length);
DBUG_RETURN(TRUE);
}
}
- key_part_info->length=(uint16) length;
+ key_part_info->length= (uint16) key_part_length;
/* Use packed keys for long strings on the first column */
if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
!((create_info->table_options & HA_OPTION_NO_PACK_KEYS)) &&
- (length >= KEY_DEFAULT_PACK_LENGTH &&
+ (key_part_length >= KEY_DEFAULT_PACK_LENGTH &&
(sql_field->sql_type == MYSQL_TYPE_STRING ||
sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
sql_field->pack_flag & FIELDFLAG_BLOB)))
@@ -4047,10 +4047,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
key_info->flags|= HA_PACK_KEY;
}
/* Check if the key segment is partial, set the key flag accordingly */
- if (length != sql_field->key_length)
+ if (key_part_length != sql_field->key_length)
key_info->flags|= HA_KEY_HAS_PART_KEY_SEG;
- key_length+=length;
+ key_length+= key_part_length;
key_part_info++;
/* Create the key name based on the first column (if not given) */
diff --git a/sql/sql_table.h b/sql/sql_table.h
index 444626e0363..2b383623873 100644
--- a/sql/sql_table.h
+++ b/sql/sql_table.h
@@ -117,6 +117,9 @@ enum enum_explain_filename_mode
EXPLAIN_PARTITIONS_AS_COMMENT
};
+/* Maximum length of GEOM_POINT Field */
+#define MAX_LEN_GEOM_POINT_FIELD 25
+
/* depends on errmsg.txt Database `db`, Table `t` ... */
#define EXPLAIN_FILENAME_MAX_EXTRA_LENGTH 63
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 9d068e464f5..fe8bb7a6620 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2014, SkySQL Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index a18193c6eb6..07169f299d7 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -400,9 +400,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
TABLE_LIST *tables= lex->query_tables;
TABLE_LIST *tbl;
SELECT_LEX *select_lex= &lex->select_lex;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
SELECT_LEX *sl;
-#endif
SELECT_LEX_UNIT *unit= &lex->unit;
bool res= FALSE;
DBUG_ENTER("mysql_create_view");
@@ -547,7 +545,8 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
}
/* Check if the auto generated column names are conforming. */
- make_valid_column_names(select_lex->item_list);
+ for (sl= select_lex; sl; sl= sl->next_select())
+ make_valid_column_names(sl->item_list);
if (check_duplicate_names(select_lex->item_list, 1))
{
@@ -624,7 +623,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
if (!res)
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, view->db, view->table_name, false);
- if (mysql_bin_log.is_open())
+ if (!res && mysql_bin_log.is_open())
{
String buff;
const LEX_STRING command[3]=
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index d6b3fa41c78..7aaa8d31ee5 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -76,7 +76,7 @@ int yylex(void *yylval, void *yythd);
ulong val= *(F); \
if (my_yyoverflow((B), (D), &val)) \
{ \
- yyerror(current_thd, (char*) (A)); \
+ yyerror(thd, (char*) (A)); \
return 2; \
} \
else \
@@ -6296,7 +6296,8 @@ spatial_type:
| GEOMETRYCOLLECTION { $$= Field::GEOM_GEOMETRYCOLLECTION; }
| POINT_SYM
{
- Lex->length= (char*)"25";
+ Lex->length= const_cast<char*>(STRINGIFY_ARG
+ (MAX_LEN_GEOM_POINT_FIELD));
$$= Field::GEOM_POINT;
}
| MULTIPOINT { $$= Field::GEOM_MULTIPOINT; }
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 24e64ed5756..9a38b2269ac 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002, 2013, Oracle and/or its affiliates.
+/* Copyright (c) 2002, 2014, Oracle and/or its affiliates.
Copyright (c) 2012, 2014, SkySQL Ab.
This program is free software; you can redistribute it and/or modify
@@ -3244,9 +3244,10 @@ static Sys_var_ulonglong Sys_tmp_table_size(
static Sys_var_mybool Sys_timed_mutexes(
"timed_mutexes",
- "Specify whether to time mutexes (only InnoDB mutexes are currently "
- "supported)",
- GLOBAL_VAR(timed_mutexes), CMD_LINE(OPT_ARG), DEFAULT(0));
+ "Specify whether to time mutexes. Deprecated, has no effect.",
+ GLOBAL_VAR(timed_mutexes), CMD_LINE(OPT_ARG), DEFAULT(0),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(NULL), ON_UPDATE(NULL),
+ DEPRECATED(""));
static char *server_version_ptr;
static Sys_var_charptr Sys_version(
diff --git a/sql/table.cc b/sql/table.cc
index 23761e02831..c951351fba8 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1774,13 +1774,25 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
key_part= keyinfo->key_part;
for (i=0 ; i < keyinfo->user_defined_key_parts ;i++)
{
- uint fieldnr= key_part[i].fieldnr;
- if (!fieldnr ||
- share->field[fieldnr-1]->null_ptr ||
- share->field[fieldnr-1]->key_length() !=
- key_part[i].length)
+ DBUG_ASSERT(key_part[i].fieldnr > 0);
+ // Table field corresponding to the i'th key part.
+ Field *table_field= share->field[key_part[i].fieldnr - 1];
+
+ /*
+ If the key column is of NOT NULL BLOB type, then it
+ will definitly have key prefix. And if key part prefix size
+ is equal to the BLOB column max size, then we can promote
+ it to primary key.
+ */
+ if (!table_field->real_maybe_null() &&
+ table_field->type() == MYSQL_TYPE_BLOB &&
+ table_field->field_length == key_part[i].length)
+ continue;
+
+ if (table_field->real_maybe_null() ||
+ table_field->key_length() != key_part[i].length)
{
- primary_key=MAX_KEY; // Can't be used
+ primary_key= MAX_KEY; // Can't be used
break;
}
}
@@ -4210,7 +4222,8 @@ bool TABLE_LIST::create_field_translation(THD *thd)
while ((item= it++))
{
- transl[field_count].name= item->name;
+ DBUG_ASSERT(item->name && item->name[0]);
+ transl[field_count].name= thd->strdup(item->name);
transl[field_count++].item= item;
}
field_translation= transl;
diff --git a/storage/heap/hp_block.c b/storage/heap/hp_block.c
index 1c40f982422..aa5343a0717 100644
--- a/storage/heap/hp_block.c
+++ b/storage/heap/hp_block.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -76,8 +76,8 @@ int hp_get_new_block(HP_SHARE *info, HP_BLOCK *block, size_t *alloc_length)
When level 1 is full, we allocate data for HPTRS_IN_NODE at level 2 and 1
+ X rows at level 0.
*/
- *alloc_length= (sizeof(HP_PTRS)* ((i == block->levels) ? i : i - 1) +
- block->records_in_block* block->recbuffer);
+ *alloc_length= (sizeof(HP_PTRS) * ((i == block->levels) ? i : i - 1) +
+ (ulonglong)block->records_in_block * block->recbuffer);
if (!(root=(HP_PTRS*) my_malloc(*alloc_length,
MYF(MY_WME |
(info->internal ?
diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c
index 30831f229ac..a68a35e63fb 100644
--- a/storage/heap/hp_create.c
+++ b/storage/heap/hp_create.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2014, SkySQL Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 19137dabe24..bd2c66b42c2 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -3440,6 +3440,14 @@ innobase_end(
if (innodb_inited) {
+ THD *thd= current_thd;
+ if (thd) { // may be UNINSTALL PLUGIN statement
+ trx_t* trx = thd_to_trx(thd);
+ if (trx) {
+ trx_free_for_mysql(trx);
+ }
+ }
+
srv_fast_shutdown = (ulint) innobase_fast_shutdown;
innodb_inited = 0;
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 359ae3f2c21..e5a7694cb93 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -877,16 +877,15 @@ row_sel_get_clust_rec(
if (!node->read_view) {
/* Try to place a lock on the index record */
-
- /* If innodb_locks_unsafe_for_binlog option is used
- or this session is using READ COMMITTED isolation level
- we lock only the record, i.e., next-key locking is
- not used. */
ulint lock_type;
trx_t* trx;
trx = thr_get_trx(thr);
+ /* If innodb_locks_unsafe_for_binlog option is used
+ or this session is using READ COMMITTED or lower isolation level
+ we lock only the record, i.e., next-key locking is
+ not used. */
if (srv_locks_unsafe_for_binlog
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
lock_type = LOCK_REC_NOT_GAP;
@@ -1502,12 +1501,6 @@ rec_loop:
search result set, resulting in the phantom problem. */
if (!consistent_read) {
-
- /* If innodb_locks_unsafe_for_binlog option is used
- or this session is using READ COMMITTED isolation
- level, we lock only the record, i.e., next-key
- locking is not used. */
-
rec_t* next_rec = page_rec_get_next(rec);
ulint lock_type;
trx_t* trx;
@@ -1517,6 +1510,10 @@ rec_loop:
offsets = rec_get_offsets(next_rec, index, offsets,
ULINT_UNDEFINED, &heap);
+ /* If innodb_locks_unsafe_for_binlog option is used
+ or this session is using READ COMMITTED or lower isolation
+ level, we lock only the record, i.e., next-key
+ locking is not used. */
if (srv_locks_unsafe_for_binlog
|| trx->isolation_level
<= TRX_ISO_READ_COMMITTED) {
@@ -1565,12 +1562,6 @@ skip_lock:
if (!consistent_read) {
/* Try to place a lock on the index record */
-
- /* If innodb_locks_unsafe_for_binlog option is used
- or this session is using READ COMMITTED isolation level,
- we lock only the record, i.e., next-key locking is
- not used. */
-
ulint lock_type;
trx_t* trx;
@@ -1579,6 +1570,10 @@ skip_lock:
trx = thr_get_trx(thr);
+ /* If innodb_locks_unsafe_for_binlog option is used
+ or this session is using READ COMMITTED or lower isolation level,
+ we lock only the record, i.e., next-key locking is
+ not used. */
if (srv_locks_unsafe_for_binlog
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
@@ -4227,7 +4222,7 @@ rec_loop:
/* Try to place a lock on the index record */
/* If innodb_locks_unsafe_for_binlog option is used
- or this session is using a READ COMMITTED isolation
+ or this session is using a READ COMMITTED or lower isolation
level we do not lock gaps. Supremum record is really
a gap and therefore we do not set locks there. */
@@ -4369,7 +4364,7 @@ wrong_offs:
/* Try to place a gap lock on the index
record only if innodb_locks_unsafe_for_binlog
option is not set or this session is not
- using a READ COMMITTED isolation level. */
+ using a READ COMMITTED or lower isolation level. */
err = sel_set_rec_lock(
btr_pcur_get_block(pcur),
@@ -4418,7 +4413,7 @@ wrong_offs:
/* Try to place a gap lock on the index
record only if innodb_locks_unsafe_for_binlog
option is not set or this session is not
- using a READ COMMITTED isolation level. */
+ using a READ COMMITTED or lower isolation level. */
err = sel_set_rec_lock(
btr_pcur_get_block(pcur),
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 075b097aa93..7155faa72f4 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -2834,7 +2834,8 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn)
TRN *trn;
int error;
uint locked_tables;
- TABLE *table;
+ DYNAMIC_ARRAY used_tables;
+
DBUG_ENTER("ha_maria::implicit_commit");
if (!maria_hton || !(trn= THD_TRN))
DBUG_RETURN(0);
@@ -2850,7 +2851,38 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn)
DBUG_PRINT("info", ("locked_tables, skipping"));
DBUG_RETURN(0);
}
+
locked_tables= trnman_has_locked_tables(trn);
+
+ if (new_trn && trn && trn->used_tables)
+ {
+ MARIA_USED_TABLES *tables;
+ /*
+ Save locked tables so that we can move them to another transaction
+ We are using a dynamic array as locked_tables in some cases can be
+ smaller than the used_tables list (for example when the server does
+ early unlock of tables.
+ */
+
+ my_init_dynamic_array2(&used_tables, sizeof(MARIA_SHARE*), (void*) 0,
+ locked_tables, 8, MYF(MY_THREAD_SPECIFIC));
+ for (tables= (MARIA_USED_TABLES*) trn->used_tables;
+ tables;
+ tables= tables->next)
+ {
+ if (tables->share->base.born_transactional)
+ {
+ if (insert_dynamic(&used_tables, (uchar*) &tables->share))
+ {
+ error= HA_ERR_OUT_OF_MEM;
+ goto end_and_free;
+ }
+ }
+ }
+ }
+ else
+ bzero(&used_tables, sizeof(used_tables));
+
error= 0;
if (unlikely(ma_commit(trn)))
error= 1;
@@ -2874,7 +2906,7 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn)
if (unlikely(trn == NULL))
{
error= HA_ERR_OUT_OF_MEM;
- goto end;
+ goto end_and_free;
}
/*
Move all locked tables to the new transaction
@@ -2883,13 +2915,21 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn)
when we should call _ma_setup_live_state() and in some cases, like
in check table, we use the table without calling start_stmt().
*/
- for (table=thd->open_tables; table ; table=table->next)
+
+ uint i;
+ for (i= 0 ; i < used_tables.elements ; i++)
{
- if (table->db_stat && table->file->ht == maria_hton)
+ MARIA_SHARE *share;
+ LIST *handlers;
+
+ share= *(dynamic_element(&used_tables, i, MARIA_SHARE**));
+ /* Find table instances that was used in this transaction */
+ for (handlers= share->open_list; handlers; handlers= handlers->next)
{
- MARIA_HA *handler= ((ha_maria*) table->file)->file;
- if (handler->s->base.born_transactional)
- {
+ MARIA_HA *handler= (MARIA_HA*) handlers->data;
+ if (handler->external_ref &&
+ ((TABLE*) handler->external_ref)->in_use == thd)
+ {
_ma_set_trn_for_table(handler, trn);
/* If handler uses versioning */
if (handler->s->lock_key_trees)
@@ -2903,6 +2943,8 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn)
/* This is just a commit, tables stay locked if they were: */
trnman_reset_locked_tables(trn, locked_tables);
+end_and_free:
+ delete_dynamic(&used_tables);
end:
DBUG_RETURN(error);
}
diff --git a/storage/maria/ma_close.c b/storage/maria/ma_close.c
index dd3a034425a..4532b029126 100644
--- a/storage/maria/ma_close.c
+++ b/storage/maria/ma_close.c
@@ -80,7 +80,10 @@ int maria_close(register MARIA_HA *info)
}
flag= !--share->reopen;
if (!internal_table)
- maria_open_list=list_delete(maria_open_list,&info->open_list);
+ {
+ maria_open_list= list_delete(maria_open_list,&info->open_list);
+ share->open_list= list_delete(share->open_list, &info->share_list);
+ }
my_free(info->rec_buff);
(*share->end)(info);
@@ -91,6 +94,7 @@ int maria_close(register MARIA_HA *info)
/* Check that we don't have any dangling pointers from the transaction */
DBUG_ASSERT(share->in_trans == 0);
+ DBUG_ASSERT(share->open_list == 0);
if (share->kfile.file >= 0)
{
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index e06084cef07..1d274d796be 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -211,8 +211,9 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, const char *name,
if (!internal_table)
{
- m_info->open_list.data=(void*) m_info;
- maria_open_list=list_add(maria_open_list,&m_info->open_list);
+ m_info->open_list.data= m_info->share_list.data= (void*) m_info;
+ maria_open_list= list_add(maria_open_list, &m_info->open_list);
+ share->open_list= list_add(share->open_list, &m_info->share_list);
}
else
{
diff --git a/storage/maria/ma_state.c b/storage/maria/ma_state.c
index f130da21d07..0c673ded04e 100644
--- a/storage/maria/ma_state.c
+++ b/storage/maria/ma_state.c
@@ -240,6 +240,7 @@ void _ma_reset_state(MARIA_HA *info)
MARIA_STATE_HISTORY *history= share->state_history;
DBUG_ENTER("_ma_reset_state");
+ /* Always true if share->now_transactional is set */
if (history)
{
MARIA_STATE_HISTORY *next;
@@ -769,7 +770,7 @@ void _ma_copy_nontrans_state_information(MARIA_HA *info)
/**
Reset history
- This is only called during repair when we the only one using the table.
+ This is only called during repair when we are the only one using the table.
*/
void _ma_reset_history(MARIA_SHARE *share)
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index ab4ade30c44..b878aaa0f7d 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -364,6 +364,7 @@ typedef struct st_maria_share
LEX_STRING index_file_name;
LEX_STRING open_file_name; /* parameter to open filename */
uchar *file_map; /* mem-map of file if possible */
+ LIST *open_list; /* Tables open with this share */
PAGECACHE *pagecache; /* ref to the current key cache */
MARIA_DECODE_TREE *decode_trees;
/*
@@ -629,6 +630,7 @@ struct st_maria_handler
PAGECACHE_FILE dfile; /* The datafile */
IO_CACHE rec_cache; /* When cacheing records */
LIST open_list;
+ LIST share_list;
MY_BITMAP changed_fields;
ulong row_base_length; /* Length of row header */
uint row_flag; /* Flag to store in row header */
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index ff3af8bac05..f90e01d8cc9 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -1088,7 +1088,6 @@ int ha_myisam::repair(THD *thd, HA_CHECK &param, bool do_optimize)
param.db_name= table->s->db.str;
param.table_name= table->alias.c_ptr();
- param.tmpfile_createflag= O_RDWR | O_TRUNC | O_EXCL;
param.using_global_keycache = 1;
param.thd= thd;
param.tmpdir= &mysql_tmpdir_list;
diff --git a/storage/tokudb/CMakeLists.in b/storage/tokudb/CMakeLists.in
deleted file mode 100644
index 20c05126841..00000000000
--- a/storage/tokudb/CMakeLists.in
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2006 MySQL AB
-#
-# 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-1301 USA
-
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTOKUDB_VERSION=\\\"TOKUDB_VERSION_REPLACE_ME\\\"")
-SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-
-INCLUDE_DIRECTORIES(TOKUDB_DIR_REPLACE_ME/windows
- TOKUDB_DIR_REPLACE_ME/src
- TOKUDB_DIR_REPLACE_ME/include
- TOKUDB_DIR_REPLACE_ME/toku_include)
-
-INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
-SET(TOKUDB_SOURCES hatoku_hton.cc ha_tokudb.cc hatoku_cmp.cc)
-MYSQL_STORAGE_ENGINE(TOKUDB)
-
-TARGET_LINK_LIBRARIES(ha_tokudb PowrProf optimized TOKUDB_OBJ_DIR_REPLACE_ME/opt/ipo_libtokudb optimized TOKUDB_OBJ_DIR_REPLACE_ME/opt/libtokuportability debug TOKUDB_OBJ_DIR_REPLACE_ME/debug/static_libtokudb debug TOKUDB_OBJ_DIR_REPLACE_ME/debug/libtokuportability)
diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt
index dc545ee6791..6cbad7162ff 100644
--- a/storage/tokudb/CMakeLists.txt
+++ b/storage/tokudb/CMakeLists.txt
@@ -14,11 +14,12 @@ IF(NOT TOKUDB_OK OR WITHOUT_TOKUDB OR WITHOUT_TOKUDB_STORAGE_ENGINE)
ENDIF()
############################################
-SET(TOKUDB_VERSION "7.1.6")
+SET(TOKUDB_VERSION "7.1.7")
SET(TOKUDB_DEB_FILES "usr/lib/mysql/plugin/ha_tokudb.so\netc/mysql/conf.d/tokudb.cnf\nusr/bin/tokuftdump\nusr/share/doc/mariadb-server-10.0/README-TOKUDB\nusr/share/doc/mariadb-server-10.0/README.md" PARENT_SCOPE)
SET(USE_BDB OFF CACHE BOOL "")
SET(USE_VALGRIND OFF CACHE BOOL "")
SET(BUILD_TESTING OFF CACHE BOOL "")
+SET(TOKU_DEBUG_PARANOID OFF CACHE BOOL "")
MARK_AS_ADVANCED(BUILDNAME)
MARK_AS_ADVANCED(BUILD_TESTING)
MARK_AS_ADVANCED(CMAKE_TOKUDB_REVISION)
diff --git a/storage/tokudb/README.md b/storage/tokudb/README.md
index 7d4ebcefce1..1deb3699c5a 100644
--- a/storage/tokudb/README.md
+++ b/storage/tokudb/README.md
@@ -24,14 +24,14 @@ working MySQL or MariaDB with Tokutek patches, and with the TokuDB storage
engine, called `make.mysql.bash`. This script will download copies of the
needed source code from github and build everything.
-To build MySQL 5.5.36 with TokuDB 7.1.5:
+To build MySQL 5.5.37 with TokuDB 7.1.6:
```sh
-scripts/make.mysql.bash --mysqlbuild=mysql-5.5.36-tokudb-7.1.5-linux-x86_64
+scripts/make.mysql.bash --mysqlbuild=mysql-5.5.37-tokudb-7.1.6-linux-x86_64
```
-To build MariaDB 5.5.36 with TokuDB 7.1.5:
+To build MariaDB 5.5.37 with TokuDB 7.1.6:
```sh
-scripts/make.mysql.bash --mysqlbuild=mariadb-5.5.36-tokudb-7.1.5-linux-x86_64
+scripts/make.mysql.bash --mysqlbuild=mariadb-5.5.37-tokudb-7.1.6-linux-x86_64
```
Before you start, make sure you have a C++11-compatible compiler (GCC >=
diff --git a/storage/tokudb/ft-index/CMakeLists.txt b/storage/tokudb/ft-index/CMakeLists.txt
index 1228da8c35d..f28e7745295 100644
--- a/storage/tokudb/ft-index/CMakeLists.txt
+++ b/storage/tokudb/ft-index/CMakeLists.txt
@@ -6,6 +6,31 @@ project(TokuDB)
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
+## Versions of gcc >= 4.9.0 require special version of 'ar' and 'ranlib' for
+## link-time optimizations to work properly.
+##
+## From https://gcc.gnu.org/gcc-4.9/changes.html:
+##
+## When using a linker plugin, compiling with the -flto option now
+## generates slim objects files (.o) which only contain intermediate
+## language representation for LTO. Use -ffat-lto-objects to create
+## files which contain additionally the object code. To generate
+## static libraries suitable for LTO processing, use gcc-ar and
+## gcc-ranlib; to list symbols from a slim object file use
+## gcc-nm. (Requires that ar, ranlib and nm have been compiled with
+## plugin support.)
+if ((CMAKE_CXX_COMPILER_ID STREQUAL GNU) AND
+ NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9.0"))
+ find_program(gcc_ar "gcc-ar")
+ if (gcc_ar)
+ set(CMAKE_AR "${gcc_ar}")
+ endif ()
+ find_program(gcc_ranlib "gcc-ranlib")
+ if (gcc_ranlib)
+ set(CMAKE_RANLIB "${gcc_ranlib}")
+ endif ()
+endif()
+
include(TokuFeatureDetection)
include(TokuSetupCompiler)
include(TokuSetupCTest)
diff --git a/storage/tokudb/ft-index/cmake_modules/TokuThirdParty.cmake b/storage/tokudb/ft-index/cmake_modules/TokuThirdParty.cmake
index 461390ffb7c..cb474c385af 100644
--- a/storage/tokudb/ft-index/cmake_modules/TokuThirdParty.cmake
+++ b/storage/tokudb/ft-index/cmake_modules/TokuThirdParty.cmake
@@ -3,35 +3,34 @@ include(ExternalProject)
if (CMAKE_PROJECT_NAME STREQUAL TokuDB)
## add jemalloc with an external project
set(JEMALLOC_SOURCE_DIR "${TokuDB_SOURCE_DIR}/third_party/jemalloc" CACHE FILEPATH "Where to find jemalloc sources.")
- if (NOT EXISTS "${JEMALLOC_SOURCE_DIR}/configure")
- message(FATAL_ERROR "Can't find jemalloc sources. Please check them out to ${JEMALLOC_SOURCE_DIR} or modify JEMALLOC_SOURCE_DIR.")
- endif ()
- set(jemalloc_configure_opts "CC=${CMAKE_C_COMPILER}" "--with-jemalloc-prefix=" "--with-private-namespace=tokudb_jemalloc_internal_" "--enable-cc-silence")
- option(JEMALLOC_DEBUG "Build jemalloc with --enable-debug." OFF)
- if (JEMALLOC_DEBUG)
- list(APPEND jemalloc_configure_opts --enable-debug)
- endif ()
- ExternalProject_Add(build_jemalloc
- PREFIX jemalloc
- SOURCE_DIR "${JEMALLOC_SOURCE_DIR}"
- CONFIGURE_COMMAND
- "${JEMALLOC_SOURCE_DIR}/configure" ${jemalloc_configure_opts}
- "--prefix=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/jemalloc"
- )
+ if (EXISTS "${JEMALLOC_SOURCE_DIR}/configure")
+ set(jemalloc_configure_opts "CC=${CMAKE_C_COMPILER}" "--with-jemalloc-prefix=" "--with-private-namespace=tokudb_jemalloc_internal_" "--enable-cc-silence")
+ option(JEMALLOC_DEBUG "Build jemalloc with --enable-debug." OFF)
+ if (JEMALLOC_DEBUG)
+ list(APPEND jemalloc_configure_opts --enable-debug)
+ endif ()
+ ExternalProject_Add(build_jemalloc
+ PREFIX jemalloc
+ SOURCE_DIR "${JEMALLOC_SOURCE_DIR}"
+ CONFIGURE_COMMAND
+ "${JEMALLOC_SOURCE_DIR}/configure" ${jemalloc_configure_opts}
+ "--prefix=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/jemalloc"
+ )
- add_library(jemalloc STATIC IMPORTED GLOBAL)
- set_target_properties(jemalloc PROPERTIES IMPORTED_LOCATION
- "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/jemalloc/lib/libjemalloc_pic.a")
- add_dependencies(jemalloc build_jemalloc)
- add_library(jemalloc_nopic STATIC IMPORTED GLOBAL)
- set_target_properties(jemalloc_nopic PROPERTIES IMPORTED_LOCATION
- "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/jemalloc/lib/libjemalloc.a")
- add_dependencies(jemalloc_nopic build_jemalloc)
+ add_library(jemalloc STATIC IMPORTED GLOBAL)
+ set_target_properties(jemalloc PROPERTIES IMPORTED_LOCATION
+ "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/jemalloc/lib/libjemalloc_pic.a")
+ add_dependencies(jemalloc build_jemalloc)
+ add_library(jemalloc_nopic STATIC IMPORTED GLOBAL)
+ set_target_properties(jemalloc_nopic PROPERTIES IMPORTED_LOCATION
+ "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/jemalloc/lib/libjemalloc.a")
+ add_dependencies(jemalloc_nopic build_jemalloc)
- # detect when we are being built as a subproject
- if (NOT DEFINED MYSQL_PROJECT_NAME_DOCSTRING)
- install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/jemalloc/lib" DESTINATION .
- COMPONENT tokukv_libs_extra)
+ # detect when we are being built as a subproject
+ if (NOT DEFINED MYSQL_PROJECT_NAME_DOCSTRING)
+ install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/jemalloc/lib" DESTINATION .
+ COMPONENT tokukv_libs_extra)
+ endif ()
endif ()
endif ()
diff --git a/storage/tokudb/ft-index/ft/checkpoint.cc b/storage/tokudb/ft-index/ft/checkpoint.cc
index 3d26c3a460e..bc4629a1d08 100644
--- a/storage/tokudb/ft-index/ft/checkpoint.cc
+++ b/storage/tokudb/ft-index/ft/checkpoint.cc
@@ -158,8 +158,8 @@ status_init(void) {
STATUS_INIT(CP_TIME_LAST_CHECKPOINT_BEGIN, CHECKPOINT_LAST_BEGAN, UNIXTIME, "last checkpoint began ", TOKU_ENGINE_STATUS|TOKU_GLOBAL_STATUS);
STATUS_INIT(CP_TIME_LAST_CHECKPOINT_BEGIN_COMPLETE, CHECKPOINT_LAST_COMPLETE_BEGAN, UNIXTIME, "last complete checkpoint began ", TOKU_ENGINE_STATUS|TOKU_GLOBAL_STATUS);
STATUS_INIT(CP_TIME_LAST_CHECKPOINT_END, CHECKPOINT_LAST_COMPLETE_ENDED, UNIXTIME, "last complete checkpoint ended", TOKU_ENGINE_STATUS|TOKU_GLOBAL_STATUS);
- STATUS_INIT(CP_TIME_CHECKPOINT_DURATION, CHECKPOINT_DURATION, UNIXTIME, "time spent during checkpoint (begin and end phases)", TOKU_ENGINE_STATUS|TOKU_GLOBAL_STATUS);
- STATUS_INIT(CP_TIME_CHECKPOINT_DURATION_LAST, CHECKPOINT_DURATION_LAST, UNIXTIME, "time spent during last checkpoint (begin and end phases)", TOKU_ENGINE_STATUS|TOKU_GLOBAL_STATUS);
+ STATUS_INIT(CP_TIME_CHECKPOINT_DURATION, CHECKPOINT_DURATION, UINT64, "time spent during checkpoint (begin and end phases)", TOKU_ENGINE_STATUS|TOKU_GLOBAL_STATUS);
+ STATUS_INIT(CP_TIME_CHECKPOINT_DURATION_LAST, CHECKPOINT_DURATION_LAST, UINT64, "time spent during last checkpoint (begin and end phases)", TOKU_ENGINE_STATUS|TOKU_GLOBAL_STATUS);
STATUS_INIT(CP_LAST_LSN, nullptr, UINT64, "last complete checkpoint LSN", TOKU_ENGINE_STATUS);
STATUS_INIT(CP_CHECKPOINT_COUNT, CHECKPOINT_TAKEN, UINT64, "checkpoints taken ", TOKU_ENGINE_STATUS|TOKU_GLOBAL_STATUS);
STATUS_INIT(CP_CHECKPOINT_COUNT_FAIL, CHECKPOINT_FAILED, UINT64, "checkpoints failed", TOKU_ENGINE_STATUS|TOKU_GLOBAL_STATUS);
@@ -381,8 +381,8 @@ toku_checkpoint(CHECKPOINTER cp, TOKULOGGER logger,
STATUS_VALUE(CP_LONG_BEGIN_TIME) += duration;
STATUS_VALUE(CP_LONG_BEGIN_COUNT) += 1;
}
- STATUS_VALUE(CP_TIME_CHECKPOINT_DURATION) += ((time_t) STATUS_VALUE(CP_TIME_LAST_CHECKPOINT_END)) - ((time_t) STATUS_VALUE(CP_TIME_LAST_CHECKPOINT_BEGIN));
- STATUS_VALUE(CP_TIME_CHECKPOINT_DURATION_LAST) = ((time_t) STATUS_VALUE(CP_TIME_LAST_CHECKPOINT_END)) - ((time_t) STATUS_VALUE(CP_TIME_LAST_CHECKPOINT_BEGIN));
+ STATUS_VALUE(CP_TIME_CHECKPOINT_DURATION) += (uint64_t) ((time_t) STATUS_VALUE(CP_TIME_LAST_CHECKPOINT_END)) - ((time_t) STATUS_VALUE(CP_TIME_LAST_CHECKPOINT_BEGIN));
+ STATUS_VALUE(CP_TIME_CHECKPOINT_DURATION_LAST) = (uint64_t) ((time_t) STATUS_VALUE(CP_TIME_LAST_CHECKPOINT_END)) - ((time_t) STATUS_VALUE(CP_TIME_LAST_CHECKPOINT_BEGIN));
STATUS_VALUE(CP_FOOTPRINT) = 0;
checkpoint_safe_checkpoint_unlock();
diff --git a/storage/tokudb/ft-index/ft/ft-cachetable-wrappers.cc b/storage/tokudb/ft-index/ft/ft-cachetable-wrappers.cc
index 1f3aa3e0baa..91a0040b02e 100644
--- a/storage/tokudb/ft-index/ft/ft-cachetable-wrappers.cc
+++ b/storage/tokudb/ft-index/ft/ft-cachetable-wrappers.cc
@@ -403,3 +403,25 @@ toku_unpin_ftnode_read_only(FT ft, FTNODE node)
);
assert(r==0);
}
+
+void toku_ftnode_swap_pair_values(FTNODE a, FTNODE b)
+// Effect: Swap the blocknum, fullhash, and PAIR for for a and b
+// Requires: Both nodes are pinned
+{
+ BLOCKNUM tmp_blocknum = a->thisnodename;
+ uint32_t tmp_fullhash = a->fullhash;
+ PAIR tmp_pair = a->ct_pair;
+
+ a->thisnodename = b->thisnodename;
+ a->fullhash = b->fullhash;
+ a->ct_pair = b->ct_pair;
+
+ b->thisnodename = tmp_blocknum;
+ b->fullhash = tmp_fullhash;
+ b->ct_pair = tmp_pair;
+
+ // A and B swapped pair pointers, but we still have to swap
+ // the actual pair values (ie: the FTNODEs they represent)
+ // in the cachetable.
+ toku_cachetable_swap_pair_values(a->ct_pair, b->ct_pair);
+}
diff --git a/storage/tokudb/ft-index/ft/ft-cachetable-wrappers.h b/storage/tokudb/ft-index/ft/ft-cachetable-wrappers.h
index 9a56f4ff220..dc84d7f006b 100644
--- a/storage/tokudb/ft-index/ft/ft-cachetable-wrappers.h
+++ b/storage/tokudb/ft-index/ft/ft-cachetable-wrappers.h
@@ -190,4 +190,7 @@ int toku_maybe_pin_ftnode_clean(FT ft, BLOCKNUM blocknum, uint32_t fullhash, pai
void toku_unpin_ftnode(FT h, FTNODE node);
void toku_unpin_ftnode_read_only(FT ft, FTNODE node);
+// Effect: Swaps pair values of two pinned nodes
+void toku_ftnode_swap_pair_values(FTNODE nodea, FTNODE nodeb);
+
#endif
diff --git a/storage/tokudb/ft-index/ft/ft-flusher.cc b/storage/tokudb/ft-index/ft/ft-flusher.cc
index 0fe556aec0f..dc4096a7993 100644
--- a/storage/tokudb/ft-index/ft/ft-flusher.cc
+++ b/storage/tokudb/ft-index/ft/ft-flusher.cc
@@ -565,6 +565,7 @@ static bool may_node_be_reactive(FT ft, FTNODE node)
*/
static void
handle_split_of_child(
+ FT ft,
FTNODE node,
int childnum,
FTNODE childa,
@@ -607,8 +608,20 @@ handle_split_of_child(
paranoid_invariant(BP_BLOCKNUM(node, childnum).b==childa->thisnodename.b); // use the same child
+ // We never set the rightmost blocknum to be the root.
+ // Instead, we wait for the root to split and let promotion initialize the rightmost
+ // blocknum to be the first non-root leaf node on the right extreme to recieve an insert.
+ invariant(ft->h->root_blocknum.b != ft->rightmost_blocknum.b);
+ if (childa->thisnodename.b == ft->rightmost_blocknum.b) {
+ // The rightmost leaf (a) split into (a) and (b). We want (b) to swap pair values
+ // with (a), now that it is the new rightmost leaf. This keeps the rightmost blocknum
+ // constant, the same the way we keep the root blocknum constant.
+ toku_ftnode_swap_pair_values(childa, childb);
+ BP_BLOCKNUM(node, childnum) = childa->thisnodename;
+ }
+
BP_BLOCKNUM(node, childnum+1) = childb->thisnodename;
- BP_WORKDONE(node, childnum+1) = 0;
+ BP_WORKDONE(node, childnum+1) = 0;
BP_STATE(node,childnum+1) = PT_AVAIL;
NONLEAF_CHILDINFO new_bnc = toku_create_empty_nl();
@@ -1071,7 +1084,7 @@ ft_split_child(
ft_nonleaf_split(h, child, &nodea, &nodeb, &splitk, 2, dep_nodes);
}
// printf("%s:%d child did split\n", __FILE__, __LINE__);
- handle_split_of_child (node, childnum, nodea, nodeb, &splitk);
+ handle_split_of_child (h, node, childnum, nodea, nodeb, &splitk);
// for test
call_flusher_thread_callback(flt_flush_during_split);
@@ -1489,6 +1502,14 @@ ft_merge_child(
&node->childkeys[childnuma+1],
(node->n_children-childnumb)*sizeof(node->childkeys[0]));
REALLOC_N(node->n_children-1, node->childkeys);
+
+ // Handle a merge of the rightmost leaf node.
+ if (did_merge && childb->thisnodename.b == h->rightmost_blocknum.b) {
+ invariant(childb->thisnodename.b != h->h->root_blocknum.b);
+ toku_ftnode_swap_pair_values(childa, childb);
+ BP_BLOCKNUM(node, childnuma) = childa->thisnodename;
+ }
+
paranoid_invariant(BP_BLOCKNUM(node, childnuma).b == childa->thisnodename.b);
childa->dirty = 1; // just to make sure
childb->dirty = 1; // just to make sure
diff --git a/storage/tokudb/ft-index/ft/ft-internal.h b/storage/tokudb/ft-index/ft/ft-internal.h
index 42d27638330..378e8921328 100644
--- a/storage/tokudb/ft-index/ft/ft-internal.h
+++ b/storage/tokudb/ft-index/ft/ft-internal.h
@@ -123,6 +123,10 @@ enum { FT_DEFAULT_FANOUT = 16 };
enum { FT_DEFAULT_NODE_SIZE = 4 * 1024 * 1024 };
enum { FT_DEFAULT_BASEMENT_NODE_SIZE = 128 * 1024 };
+// We optimize for a sequential insert pattern if 100 consecutive injections
+// happen into the rightmost leaf node due to promotion.
+enum { FT_SEQINSERT_SCORE_THRESHOLD = 100 };
+
//
// Field in ftnode_fetch_extra that tells the
// partial fetch callback what piece of the node
@@ -572,6 +576,22 @@ struct ft {
// is this ft a blackhole? if so, all messages are dropped.
bool blackhole;
+
+ // The blocknum of the rightmost leaf node in the tree. Stays constant through splits
+ // and merges using pair-swapping (like the root node, see toku_ftnode_swap_pair_values())
+ //
+ // This field only transitions from RESERVED_BLOCKNUM_NULL to non-null, never back.
+ // We initialize it when promotion inserts into a non-root leaf node on the right extreme.
+ // We use the blocktable lock to protect the initialize transition, though it's not really
+ // necessary since all threads should be setting it to the same value. We maintain that invariant
+ // on first initialization, see ft_set_or_verify_rightmost_blocknum()
+ BLOCKNUM rightmost_blocknum;
+
+ // sequential access pattern heuristic
+ // - when promotion pushes a message directly into the rightmost leaf, the score goes up.
+ // - if the score is high enough, we optimistically attempt to insert directly into the rightmost leaf
+ // - if our attempt fails because the key was not in range of the rightmost leaf, we reset the score back to 0
+ uint32_t seqinsert_score;
};
// Allocate a DB struct off the stack and only set its comparison
@@ -1037,7 +1057,7 @@ toku_get_node_for_verify(
int
toku_verify_ftnode (FT_HANDLE ft_h,
- MSN rootmsn, MSN parentmsn, bool messages_exist_above,
+ MSN rootmsn, MSN parentmsn_with_messages, bool messages_exist_above,
FTNODE node, int height,
const DBT *lesser_pivot, // Everything in the subtree should be > lesser_pivot. (lesser_pivot==NULL if there is no lesser pivot.)
const DBT *greatereq_pivot, // Everything in the subtree should be <= lesser_pivot. (lesser_pivot==NULL if there is no lesser pivot.)
@@ -1186,6 +1206,9 @@ typedef enum {
FT_PRO_NUM_DIDNT_WANT_PROMOTE,
FT_BASEMENT_DESERIALIZE_FIXED_KEYSIZE, // how many basement nodes were deserialized with a fixed keysize
FT_BASEMENT_DESERIALIZE_VARIABLE_KEYSIZE, // how many basement nodes were deserialized with a variable keysize
+ FT_PRO_RIGHTMOST_LEAF_SHORTCUT_SUCCESS,
+ FT_PRO_RIGHTMOST_LEAF_SHORTCUT_FAIL_POS,
+ FT_PRO_RIGHTMOST_LEAF_SHORTCUT_FAIL_REACTIVE,
FT_STATUS_NUM_ROWS
} ft_status_entry;
diff --git a/storage/tokudb/ft-index/ft/ft-ops.cc b/storage/tokudb/ft-index/ft/ft-ops.cc
index 64b6b498c9a..f9701ec34b1 100644
--- a/storage/tokudb/ft-index/ft/ft-ops.cc
+++ b/storage/tokudb/ft-index/ft/ft-ops.cc
@@ -367,6 +367,9 @@ status_init(void)
STATUS_INIT(FT_PRO_NUM_DIDNT_WANT_PROMOTE, PROMOTION_STOPPED_AFTER_LOCKING_CHILD, PARCOUNT, "promotion: stopped anyway, after locking the child", TOKU_ENGINE_STATUS|TOKU_GLOBAL_STATUS);
STATUS_INIT(FT_BASEMENT_DESERIALIZE_FIXED_KEYSIZE, BASEMENT_DESERIALIZATION_FIXED_KEY, PARCOUNT, "basement nodes deserialized with fixed-keysize", TOKU_ENGINE_STATUS|TOKU_GLOBAL_STATUS);
STATUS_INIT(FT_BASEMENT_DESERIALIZE_VARIABLE_KEYSIZE, BASEMENT_DESERIALIZATION_VARIABLE_KEY, PARCOUNT, "basement nodes deserialized with variable-keysize", TOKU_ENGINE_STATUS|TOKU_GLOBAL_STATUS);
+ STATUS_INIT(FT_PRO_RIGHTMOST_LEAF_SHORTCUT_SUCCESS, nullptr, PARCOUNT, "promotion: succeeded in using the rightmost leaf shortcut", TOKU_ENGINE_STATUS);
+ STATUS_INIT(FT_PRO_RIGHTMOST_LEAF_SHORTCUT_FAIL_POS, nullptr, PARCOUNT, "promotion: tried the rightmost leaf shorcut but failed (out-of-bounds)", TOKU_ENGINE_STATUS);
+ STATUS_INIT(FT_PRO_RIGHTMOST_LEAF_SHORTCUT_FAIL_REACTIVE,nullptr, PARCOUNT, "promotion: tried the rightmost leaf shorcut but failed (child reactive)", TOKU_ENGINE_STATUS);
ft_status.initialized = true;
}
@@ -890,6 +893,11 @@ void toku_ftnode_clone_callback(
for (int i = 0; i < node->n_children-1; i++) {
toku_clone_dbt(&cloned_node->childkeys[i], node->childkeys[i]);
}
+ if (node->height > 0) {
+ // need to move messages here so that we don't serialize stale
+ // messages to the fresh tree - ft verify code complains otherwise.
+ toku_move_ftnode_messages_to_stale(ft, node);
+ }
// clone partition
ftnode_clone_partitions(node, cloned_node);
@@ -932,11 +940,14 @@ void toku_ftnode_flush_callback(
int height = ftnode->height;
if (write_me) {
toku_assert_entire_node_in_memory(ftnode);
- if (height == 0) {
+ if (height > 0 && !is_clone) {
+ // cloned nodes already had their stale messages moved, see toku_ftnode_clone_callback()
+ toku_move_ftnode_messages_to_stale(h, ftnode);
+ } else if (height == 0) {
ft_leaf_run_gc(h, ftnode);
- }
- if (height == 0 && !is_clone) {
- ftnode_update_disk_stats(ftnode, h, for_checkpoint);
+ if (!is_clone) {
+ ftnode_update_disk_stats(ftnode, h, for_checkpoint);
+ }
}
int r = toku_serialize_ftnode_to(fd, ftnode->thisnodename, ftnode, ndd, !is_clone, h, for_checkpoint);
assert_zero(r);
@@ -1079,9 +1090,10 @@ exit:
return;
}
+static void ft_bnc_move_messages_to_stale(FT ft, NONLEAF_CHILDINFO bnc);
+
// replace the child buffer with a compressed version of itself.
-// @return the old child buffer
-static NONLEAF_CHILDINFO
+static void
compress_internal_node_partition(FTNODE node, int i, enum toku_compression_method compression_method)
{
// if we should evict, compress the
@@ -1092,11 +1104,9 @@ compress_internal_node_partition(FTNODE node, int i, enum toku_compression_metho
sub_block_init(sb);
toku_create_compressed_partition_from_available(node, i, compression_method, sb);
- // now set the state to compressed and return the old, available partition
- NONLEAF_CHILDINFO bnc = BNC(node, i);
+ // now set the state to compressed
set_BSB(node, i, sb);
BP_STATE(node,i) = PT_COMPRESSED;
- return bnc;
}
void toku_evict_bn_from_memory(FTNODE node, int childnum, FT h) {
@@ -1149,18 +1159,27 @@ int toku_ftnode_pe_callback(void *ftnode_pv, PAIR_ATTR old_attr, void *write_ext
for (int i = 0; i < node->n_children; i++) {
if (BP_STATE(node,i) == PT_AVAIL) {
if (BP_SHOULD_EVICT(node,i)) {
- NONLEAF_CHILDINFO bnc;
- if (ft_compress_buffers_before_eviction) {
- // When partially evicting, always compress with quicklz
- bnc = compress_internal_node_partition(
+ NONLEAF_CHILDINFO bnc = BNC(node, i);
+ if (ft_compress_buffers_before_eviction &&
+ // We may not serialize and compress a partition in memory if its
+ // in memory layout version is different than what's on disk (and
+ // therefore requires upgrade).
+ //
+ // Auto-upgrade code assumes that if a node's layout version read
+ // from disk is not current, it MUST require upgrade. Breaking
+ // this rule would cause upgrade code to upgrade this partition
+ // again after we serialize it as the current version, which is bad.
+ node->layout_version == node->layout_version_read_from_disk) {
+ ft_bnc_move_messages_to_stale(ft, bnc);
+ compress_internal_node_partition(
node,
i,
+ // Always compress with quicklz
TOKU_QUICKLZ_METHOD
);
} else {
// We're not compressing buffers before eviction. Simply
// detach the buffer and set the child's state to on-disk.
- bnc = BNC(node, i);
set_BNULL(node, i);
BP_STATE(node, i) = PT_ON_DISK;
}
@@ -1626,12 +1645,10 @@ ft_init_new_root(FT ft, FTNODE oldroot, FTNODE *newrootp)
BLOCKNUM old_blocknum = oldroot->thisnodename;
uint32_t old_fullhash = oldroot->fullhash;
- PAIR old_pair = oldroot->ct_pair;
int new_height = oldroot->height+1;
uint32_t new_fullhash;
BLOCKNUM new_blocknum;
- PAIR new_pair = NULL;
cachetable_put_empty_node_with_dep_nodes(
ft,
@@ -1641,7 +1658,6 @@ ft_init_new_root(FT ft, FTNODE oldroot, FTNODE *newrootp)
&new_fullhash,
&newroot
);
- new_pair = newroot->ct_pair;
assert(newroot);
assert(new_height > 0);
@@ -1653,22 +1669,18 @@ ft_init_new_root(FT ft, FTNODE oldroot, FTNODE *newrootp)
ft->h->layout_version,
ft->h->flags
);
+ newroot->fullhash = new_fullhash;
MSN msna = oldroot->max_msn_applied_to_node_on_disk;
newroot->max_msn_applied_to_node_on_disk = msna;
BP_STATE(newroot,0) = PT_AVAIL;
newroot->dirty = 1;
- // now do the "switcheroo"
- BP_BLOCKNUM(newroot,0) = new_blocknum;
- newroot->thisnodename = old_blocknum;
- newroot->fullhash = old_fullhash;
- newroot->ct_pair = old_pair;
-
- oldroot->thisnodename = new_blocknum;
- oldroot->fullhash = new_fullhash;
- oldroot->ct_pair = new_pair;
-
- toku_cachetable_swap_pair_values(old_pair, new_pair);
+ // Set the first child to have the new blocknum,
+ // and then swap newroot with oldroot. The new root
+ // will inherit the hash/blocknum/pair from oldroot,
+ // keeping the root blocknum constant.
+ BP_BLOCKNUM(newroot, 0) = new_blocknum;
+ toku_ftnode_swap_pair_values(newroot, oldroot);
toku_ft_split_child(
ft,
@@ -2757,6 +2769,16 @@ static void inject_message_in_locked_node(
// verify that msn of latest message was captured in root node
paranoid_invariant(msg->msn.msn == node->max_msn_applied_to_node_on_disk.msn);
+ if (node->thisnodename.b == ft->rightmost_blocknum.b) {
+ if (ft->seqinsert_score < FT_SEQINSERT_SCORE_THRESHOLD) {
+ // we promoted to the rightmost leaf node and the seqinsert score has not yet saturated.
+ toku_sync_fetch_and_add(&ft->seqinsert_score, 1);
+ }
+ } else if (ft->seqinsert_score != 0) {
+ // we promoted to something other than the rightmost leaf node and the score should reset
+ ft->seqinsert_score = 0;
+ }
+
// if we call toku_ft_flush_some_child, then that function unpins the root
// otherwise, we unpin ourselves
if (node->height > 0 && toku_ft_nonleaf_is_gorged(node, ft->h->nodesize)) {
@@ -2913,6 +2935,21 @@ static inline bool should_inject_in_node(seqinsert_loc loc, int height, int dept
return (height == 0 || (loc == NEITHER_EXTREME && (height <= 1 || depth >= 2)));
}
+static void ft_set_or_verify_rightmost_blocknum(FT ft, BLOCKNUM b)
+// Given: 'b', the _definitive_ and constant rightmost blocknum of 'ft'
+{
+ if (ft->rightmost_blocknum.b == RESERVED_BLOCKNUM_NULL) {
+ toku_ft_lock(ft);
+ if (ft->rightmost_blocknum.b == RESERVED_BLOCKNUM_NULL) {
+ ft->rightmost_blocknum = b;
+ }
+ toku_ft_unlock(ft);
+ }
+ // The rightmost blocknum only transitions from RESERVED_BLOCKNUM_NULL to non-null.
+ // If it's already set, verify that the stored value is consistent with 'b'
+ invariant(ft->rightmost_blocknum.b == b.b);
+}
+
static void push_something_in_subtree(
FT ft,
FTNODE subtree_root,
@@ -2960,6 +2997,14 @@ static void push_something_in_subtree(
default:
STATUS_INC(FT_PRO_NUM_INJECT_DEPTH_GT3, 1); break;
}
+ // If the target node is a non-root leaf node on the right extreme,
+ // set the rightmost blocknum. We know there are no messages above us
+ // because promotion would not chose to inject directly into this leaf
+ // otherwise. We explicitly skip the root node because then we don't have
+ // to worry about changing the rightmost blocknum when the root splits.
+ if (subtree_root->height == 0 && loc == RIGHT_EXTREME && subtree_root->thisnodename.b != ft->h->root_blocknum.b) {
+ ft_set_or_verify_rightmost_blocknum(ft, subtree_root->thisnodename);
+ }
inject_message_in_locked_node(ft, subtree_root, target_childnum, msg, flow_deltas, gc_info);
} else {
int r;
@@ -3230,7 +3275,260 @@ void toku_ft_root_put_msg(
}
}
-// Effect: Insert the key-val pair into ft.
+static int ft_compare_keys(FT ft, const DBT *a, const DBT *b)
+// Effect: Compare two keys using the given fractal tree's comparator/descriptor
+{
+ FAKE_DB(db, &ft->cmp_descriptor);
+ return ft->compare_fun(&db, a, b);
+}
+
+static LEAFENTRY bn_get_le_and_key(BASEMENTNODE bn, int idx, DBT *key)
+// Effect: Gets the i'th leafentry from the given basement node and
+// fill its key in *key
+// Requires: The i'th leafentry exists.
+{
+ LEAFENTRY le;
+ uint32_t le_len;
+ void *le_key;
+ int r = bn->data_buffer.fetch_klpair(idx, &le, &le_len, &le_key);
+ invariant_zero(r);
+ toku_fill_dbt(key, le_key, le_len);
+ return le;
+}
+
+static LEAFENTRY ft_leaf_leftmost_le_and_key(FTNODE leaf, DBT *leftmost_key)
+// Effect: If a leftmost key exists in the given leaf, toku_fill_dbt()
+// the key into *leftmost_key
+// Requires: Leaf is fully in memory and pinned for read or write.
+// Return: leafentry if it exists, nullptr otherwise
+{
+ for (int i = 0; i < leaf->n_children; i++) {
+ BASEMENTNODE bn = BLB(leaf, i);
+ if (bn->data_buffer.num_klpairs() > 0) {
+ // Get the first (leftmost) leafentry and its key
+ return bn_get_le_and_key(bn, 0, leftmost_key);
+ }
+ }
+ return nullptr;
+}
+
+static LEAFENTRY ft_leaf_rightmost_le_and_key(FTNODE leaf, DBT *rightmost_key)
+// Effect: If a rightmost key exists in the given leaf, toku_fill_dbt()
+// the key into *rightmost_key
+// Requires: Leaf is fully in memory and pinned for read or write.
+// Return: leafentry if it exists, nullptr otherwise
+{
+ for (int i = leaf->n_children - 1; i >= 0; i--) {
+ BASEMENTNODE bn = BLB(leaf, i);
+ size_t num_les = bn->data_buffer.num_klpairs();
+ if (num_les > 0) {
+ // Get the last (rightmost) leafentry and its key
+ return bn_get_le_and_key(bn, num_les - 1, rightmost_key);
+ }
+ }
+ return nullptr;
+}
+
+static int ft_leaf_get_relative_key_pos(FT ft, FTNODE leaf, const DBT *key, bool *nondeleted_key_found, int *target_childnum)
+// Effect: Determines what the relative position of the given key is with
+// respect to a leaf node, and if it exists.
+// Requires: Leaf is fully in memory and pinned for read or write.
+// Requires: target_childnum is non-null
+// Return: < 0 if key is less than the leftmost key in the leaf OR the relative position is unknown, for any reason.
+// 0 if key is in the bounds [leftmost_key, rightmost_key] for this leaf or the leaf is empty
+// > 0 if key is greater than the rightmost key in the leaf
+// *nondeleted_key_found is set (if non-null) if the target key was found and is not deleted, unmodified otherwise
+// *target_childnum is set to the child that (does or would) contain the key, if calculated, unmodified otherwise
+{
+ DBT rightmost_key;
+ LEAFENTRY rightmost_le = ft_leaf_rightmost_le_and_key(leaf, &rightmost_key);
+ if (rightmost_le == nullptr) {
+ // If we can't get a rightmost key then the leaf is empty.
+ // In such a case, we don't have any information about what keys would be in this leaf.
+ // We have to assume the leaf node that would contain this key is to the left.
+ return -1;
+ }
+ // We have a rightmost leafentry, so it must exist in some child node
+ invariant(leaf->n_children > 0);
+
+ int relative_pos = 0;
+ int c = ft_compare_keys(ft, key, &rightmost_key);
+ if (c > 0) {
+ relative_pos = 1;
+ *target_childnum = leaf->n_children - 1;
+ } else if (c == 0) {
+ if (nondeleted_key_found != nullptr && !le_latest_is_del(rightmost_le)) {
+ *nondeleted_key_found = true;
+ }
+ relative_pos = 0;
+ *target_childnum = leaf->n_children - 1;
+ } else {
+ // The key is less than the rightmost. It may still be in bounds if it's >= the leftmost.
+ DBT leftmost_key;
+ LEAFENTRY leftmost_le = ft_leaf_leftmost_le_and_key(leaf, &leftmost_key);
+ invariant_notnull(leftmost_le); // Must exist because a rightmost exists
+ c = ft_compare_keys(ft, key, &leftmost_key);
+ if (c > 0) {
+ if (nondeleted_key_found != nullptr) {
+ // The caller wants to know if a nondeleted key can be found.
+ LEAFENTRY target_le;
+ int childnum = toku_ftnode_which_child(leaf, key, &ft->cmp_descriptor, ft->compare_fun);
+ BASEMENTNODE bn = BLB(leaf, childnum);
+ struct msg_leafval_heaviside_extra extra = { ft->compare_fun, &ft->cmp_descriptor, key };
+ int r = bn->data_buffer.find_zero<decltype(extra), toku_msg_leafval_heaviside>(
+ extra,
+ &target_le,
+ nullptr, nullptr, nullptr
+ );
+ *target_childnum = childnum;
+ if (r == 0 && !le_latest_is_del(leftmost_le)) {
+ *nondeleted_key_found = true;
+ }
+ }
+ relative_pos = 0;
+ } else if (c == 0) {
+ if (nondeleted_key_found != nullptr && !le_latest_is_del(leftmost_le)) {
+ *nondeleted_key_found = true;
+ }
+ relative_pos = 0;
+ *target_childnum = 0;
+ } else {
+ relative_pos = -1;
+ }
+ }
+
+ return relative_pos;
+}
+
+static void ft_insert_directly_into_leaf(FT ft, FTNODE leaf, int target_childnum, DBT *key, DBT *val,
+ XIDS message_xids, enum ft_msg_type type, txn_gc_info *gc_info);
+static int getf_nothing(ITEMLEN, bytevec, ITEMLEN, bytevec, void *, bool);
+
+static int ft_maybe_insert_into_rightmost_leaf(FT ft, DBT *key, DBT *val, XIDS message_xids, enum ft_msg_type type,
+ txn_gc_info *gc_info, bool unique)
+// Effect: Pins the rightmost leaf node and attempts to do an insert.
+// There are three reasons why we may not succeed.
+// - The rightmost leaf is too full and needs a split.
+// - The key to insert is not within the provable bounds of this leaf node.
+// - The key is within bounds, but it already exists.
+// Return: 0 if this function did insert, DB_KEYEXIST if a unique key constraint exists and
+// some nondeleted leafentry with the same key exists
+// < 0 if this function did not insert, for a reason other than DB_KEYEXIST.
+// Note: Treat this function as a possible, but not necessary, optimization for insert.
+// Rationale: We want O(1) insertions down the rightmost path of the tree.
+{
+ int r = -1;
+
+ uint32_t rightmost_fullhash;
+ BLOCKNUM rightmost_blocknum = ft->rightmost_blocknum;
+ FTNODE rightmost_leaf = nullptr;
+
+ // Don't do the optimization if our heurstic suggests that
+ // insertion pattern is not sequential.
+ if (ft->seqinsert_score < FT_SEQINSERT_SCORE_THRESHOLD) {
+ goto cleanup;
+ }
+
+ // We know the seqinsert score is high enough that we should
+ // attemp to directly insert into the right most leaf. Because
+ // the score is non-zero, the rightmost blocknum must have been
+ // set. See inject_message_in_locked_node(), which only increases
+ // the score if the target node blocknum == rightmost_blocknum
+ invariant(rightmost_blocknum.b != RESERVED_BLOCKNUM_NULL);
+
+ // Pin the rightmost leaf with a write lock.
+ rightmost_fullhash = toku_cachetable_hash(ft->cf, rightmost_blocknum);
+ struct ftnode_fetch_extra bfe;
+ fill_bfe_for_full_read(&bfe, ft);
+ toku_pin_ftnode(ft, rightmost_blocknum, rightmost_fullhash, &bfe, PL_WRITE_CHEAP, &rightmost_leaf, true);
+
+ // The rightmost blocknum never chances once it is initialized to something
+ // other than null. Verify that the pinned node has the correct blocknum.
+ invariant(rightmost_leaf->thisnodename.b == rightmost_blocknum.b);
+
+ // If the rightmost leaf is reactive, bail out out and let the normal promotion pass
+ // take care of it. This also ensures that if any of our ancestors are reactive,
+ // they'll be taken care of too.
+ if (get_leaf_reactivity(rightmost_leaf, ft->h->nodesize) != RE_STABLE) {
+ STATUS_INC(FT_PRO_RIGHTMOST_LEAF_SHORTCUT_FAIL_REACTIVE, 1);
+ goto cleanup;
+ }
+
+ // The groundwork has been laid for an insertion directly into the rightmost
+ // leaf node. We know that it is pinned for write, fully in memory, has
+ // no messages above it, and is not reactive.
+ //
+ // Now, two more things must be true for this insertion to actually happen:
+ // 1. The key to insert is within the bounds of this leafnode, or to the right.
+ // 2. If there is a uniqueness constraint, it passes.
+ bool nondeleted_key_found;
+ int relative_pos;
+ int target_childnum;
+
+ nondeleted_key_found = false;
+ target_childnum = -1;
+ relative_pos = ft_leaf_get_relative_key_pos(ft, rightmost_leaf, key,
+ unique ? &nondeleted_key_found : nullptr,
+ &target_childnum);
+ if (relative_pos >= 0) {
+ STATUS_INC(FT_PRO_RIGHTMOST_LEAF_SHORTCUT_SUCCESS, 1);
+ if (unique && nondeleted_key_found) {
+ r = DB_KEYEXIST;
+ } else {
+ ft_insert_directly_into_leaf(ft, rightmost_leaf, target_childnum,
+ key, val, message_xids, type, gc_info);
+ r = 0;
+ }
+ } else {
+ STATUS_INC(FT_PRO_RIGHTMOST_LEAF_SHORTCUT_FAIL_POS, 1);
+ r = -1;
+ }
+
+cleanup:
+ // If we did the insert, the rightmost leaf was unpinned for us.
+ if (r != 0 && rightmost_leaf != nullptr) {
+ toku_unpin_ftnode(ft, rightmost_leaf);
+ }
+
+ return r;
+}
+
+static void ft_txn_log_insert(FT ft, DBT *key, DBT *val, TOKUTXN txn, bool do_logging, enum ft_msg_type type);
+
+int toku_ft_insert_unique(FT_HANDLE ft_h, DBT *key, DBT *val, TOKUTXN txn, bool do_logging) {
+// Effect: Insert a unique key-val pair into the fractal tree.
+// Return: 0 on success, DB_KEYEXIST if the overwrite constraint failed
+ XIDS message_xids = txn != nullptr ? toku_txn_get_xids(txn) : xids_get_root_xids();
+
+ TXN_MANAGER txn_manager = toku_ft_get_txn_manager(ft_h);
+ txn_manager_state txn_state_for_gc(txn_manager);
+
+ TXNID oldest_referenced_xid_estimate = toku_ft_get_oldest_referenced_xid_estimate(ft_h);
+ txn_gc_info gc_info(&txn_state_for_gc,
+ oldest_referenced_xid_estimate,
+ // no messages above us, we can implicitly promote uxrs based on this xid
+ oldest_referenced_xid_estimate,
+ true);
+ int r = ft_maybe_insert_into_rightmost_leaf(ft_h->ft, key, val, message_xids, FT_INSERT, &gc_info, true);
+ if (r != 0 && r != DB_KEYEXIST) {
+ // Default to a regular unique check + insert algorithm if we couldn't
+ // do it based on the rightmost leaf alone.
+ int lookup_r = toku_ft_lookup(ft_h, key, getf_nothing, nullptr);
+ if (lookup_r == DB_NOTFOUND) {
+ toku_ft_send_insert(ft_h, key, val, message_xids, FT_INSERT, &gc_info);
+ r = 0;
+ } else {
+ r = DB_KEYEXIST;
+ }
+ }
+
+ if (r == 0) {
+ ft_txn_log_insert(ft_h->ft, key, val, txn, do_logging, FT_INSERT);
+ }
+ return r;
+}
+
+// Effect: Insert the key-val pair into an ft.
void toku_ft_insert (FT_HANDLE ft_handle, DBT *key, DBT *val, TOKUTXN txn) {
toku_ft_maybe_insert(ft_handle, key, val, txn, false, ZERO_LSN, true, FT_INSERT);
}
@@ -3356,32 +3654,38 @@ TXNID toku_ft_get_oldest_referenced_xid_estimate(FT_HANDLE ft_h) {
return txn_manager != nullptr ? toku_txn_manager_get_oldest_referenced_xid_estimate(txn_manager) : TXNID_NONE;
}
-void toku_ft_maybe_insert (FT_HANDLE ft_h, DBT *key, DBT *val, TOKUTXN txn, bool oplsn_valid, LSN oplsn, bool do_logging, enum ft_msg_type type) {
- paranoid_invariant(type==FT_INSERT || type==FT_INSERT_NO_OVERWRITE);
- XIDS message_xids = xids_get_root_xids(); //By default use committed messages
+static void ft_txn_log_insert(FT ft, DBT *key, DBT *val, TOKUTXN txn, bool do_logging, enum ft_msg_type type) {
+ paranoid_invariant(type == FT_INSERT || type == FT_INSERT_NO_OVERWRITE);
+
+ //By default use committed messages
TXNID_PAIR xid = toku_txn_get_txnid(txn);
if (txn) {
BYTESTRING keybs = {key->size, (char *) key->data};
- toku_logger_save_rollback_cmdinsert(txn, toku_cachefile_filenum(ft_h->ft->cf), &keybs);
- toku_txn_maybe_note_ft(txn, ft_h->ft);
- message_xids = toku_txn_get_xids(txn);
+ toku_logger_save_rollback_cmdinsert(txn, toku_cachefile_filenum(ft->cf), &keybs);
+ toku_txn_maybe_note_ft(txn, ft);
}
TOKULOGGER logger = toku_txn_logger(txn);
if (do_logging && logger) {
BYTESTRING keybs = {.len=key->size, .data=(char *) key->data};
BYTESTRING valbs = {.len=val->size, .data=(char *) val->data};
if (type == FT_INSERT) {
- toku_log_enq_insert(logger, (LSN*)0, 0, txn, toku_cachefile_filenum(ft_h->ft->cf), xid, keybs, valbs);
+ toku_log_enq_insert(logger, (LSN*)0, 0, txn, toku_cachefile_filenum(ft->cf), xid, keybs, valbs);
}
else {
- toku_log_enq_insert_no_overwrite(logger, (LSN*)0, 0, txn, toku_cachefile_filenum(ft_h->ft->cf), xid, keybs, valbs);
+ toku_log_enq_insert_no_overwrite(logger, (LSN*)0, 0, txn, toku_cachefile_filenum(ft->cf), xid, keybs, valbs);
}
}
+}
+
+void toku_ft_maybe_insert (FT_HANDLE ft_h, DBT *key, DBT *val, TOKUTXN txn, bool oplsn_valid, LSN oplsn, bool do_logging, enum ft_msg_type type) {
+ ft_txn_log_insert(ft_h->ft, key, val, txn, do_logging, type);
LSN treelsn;
if (oplsn_valid && oplsn.lsn <= (treelsn = toku_ft_checkpoint_lsn(ft_h->ft)).lsn) {
// do nothing
} else {
+ XIDS message_xids = txn ? toku_txn_get_xids(txn) : xids_get_root_xids();
+
TXN_MANAGER txn_manager = toku_ft_get_txn_manager(ft_h);
txn_manager_state txn_state_for_gc(txn_manager);
@@ -3391,10 +3695,26 @@ void toku_ft_maybe_insert (FT_HANDLE ft_h, DBT *key, DBT *val, TOKUTXN txn, bool
// no messages above us, we can implicitly promote uxrs based on this xid
oldest_referenced_xid_estimate,
txn != nullptr ? !txn->for_recovery : false);
- toku_ft_send_insert(ft_h, key, val, message_xids, type, &gc_info);
+ int r = ft_maybe_insert_into_rightmost_leaf(ft_h->ft, key, val, message_xids, FT_INSERT, &gc_info, false);
+ if (r != 0) {
+ toku_ft_send_insert(ft_h, key, val, message_xids, type, &gc_info);
+ }
}
}
+static void ft_insert_directly_into_leaf(FT ft, FTNODE leaf, int target_childnum, DBT *key, DBT *val,
+ XIDS message_xids, enum ft_msg_type type, txn_gc_info *gc_info)
+// Effect: Insert directly into a leaf node a fractal tree. Does not do any logging.
+// Requires: Leaf is fully in memory and pinned for write.
+// Requires: If this insertion were to happen through the root node, the promotion
+// algorithm would have selected the given leaf node as the point of injection.
+// That means this function relies on the current implementation of promotion.
+{
+ FT_MSG_S ftcmd = { type, ZERO_MSN, message_xids, .u = { .id = { key, val } } };
+ size_t flow_deltas[] = { 0, 0 };
+ inject_message_in_locked_node(ft, leaf, target_childnum, &ftcmd, flow_deltas, gc_info);
+}
+
static void
ft_send_update_msg(FT_HANDLE ft_h, FT_MSG_S *msg, TOKUTXN txn) {
msg->xids = (txn
@@ -4894,6 +5214,13 @@ int copy_to_stale(const int32_t &offset, const uint32_t UU(idx), struct copy_to_
return 0;
}
+static void ft_bnc_move_messages_to_stale(FT ft, NONLEAF_CHILDINFO bnc) {
+ struct copy_to_stale_extra cts_extra = { .ft = ft, .bnc = bnc };
+ int r = bnc->fresh_message_tree.iterate_over_marked<struct copy_to_stale_extra, copy_to_stale>(&cts_extra);
+ invariant_zero(r);
+ bnc->fresh_message_tree.delete_all_marked();
+}
+
__attribute__((nonnull))
void
toku_move_ftnode_messages_to_stale(FT ft, FTNODE node) {
@@ -4906,10 +5233,7 @@ toku_move_ftnode_messages_to_stale(FT ft, FTNODE node) {
// We can't delete things out of the fresh tree inside the above
// procedures because we're still looking at the fresh tree. Instead
// we have to move messages after we're done looking at it.
- struct copy_to_stale_extra cts_extra = { .ft = ft, .bnc = bnc };
- int r = bnc->fresh_message_tree.iterate_over_marked<struct copy_to_stale_extra, copy_to_stale>(&cts_extra);
- invariant_zero(r);
- bnc->fresh_message_tree.delete_all_marked();
+ ft_bnc_move_messages_to_stale(ft, bnc);
}
}
diff --git a/storage/tokudb/ft-index/ft/ft-ops.h b/storage/tokudb/ft-index/ft/ft-ops.h
index b482d2b8206..cfa6ba20f6f 100644
--- a/storage/tokudb/ft-index/ft/ft-ops.h
+++ b/storage/tokudb/ft-index/ft/ft-ops.h
@@ -213,6 +213,9 @@ int toku_ft_lookup (FT_HANDLE ft_h, DBT *k, FT_GET_CALLBACK_FUNCTION getf, void
// Effect: Insert a key and data pair into an ft
void toku_ft_insert (FT_HANDLE ft_h, DBT *k, DBT *v, TOKUTXN txn);
+// Returns: 0 if the key was inserted, DB_KEYEXIST if the key already exists
+int toku_ft_insert_unique(FT_HANDLE ft, DBT *k, DBT *v, TOKUTXN txn, bool do_logging);
+
// Effect: Optimize the ft
void toku_ft_optimize (FT_HANDLE ft_h);
diff --git a/storage/tokudb/ft-index/ft/ft-serialize.cc b/storage/tokudb/ft-index/ft/ft-serialize.cc
index 4a4817e7f6c..1879561f20a 100644
--- a/storage/tokudb/ft-index/ft/ft-serialize.cc
+++ b/storage/tokudb/ft-index/ft/ft-serialize.cc
@@ -462,6 +462,7 @@ serialize_ft_min_size (uint32_t version) {
size_t size = 0;
switch(version) {
+ case FT_LAYOUT_VERSION_27:
case FT_LAYOUT_VERSION_26:
case FT_LAYOUT_VERSION_25:
case FT_LAYOUT_VERSION_24:
diff --git a/storage/tokudb/ft-index/ft/ft-verify.cc b/storage/tokudb/ft-index/ft/ft-verify.cc
index 506a54a07a0..7e8d241cce2 100644
--- a/storage/tokudb/ft-index/ft/ft-verify.cc
+++ b/storage/tokudb/ft-index/ft/ft-verify.cc
@@ -310,7 +310,7 @@ toku_get_node_for_verify(
static int
toku_verify_ftnode_internal(FT_HANDLE ft_handle,
- MSN rootmsn, MSN parentmsn, bool messages_exist_above,
+ MSN rootmsn, MSN parentmsn_with_messages, bool messages_exist_above,
FTNODE node, int height,
const DBT *lesser_pivot, // Everything in the subtree should be > lesser_pivot. (lesser_pivot==NULL if there is no lesser pivot.)
const DBT *greatereq_pivot, // Everything in the subtree should be <= lesser_pivot. (lesser_pivot==NULL if there is no lesser pivot.)
@@ -328,7 +328,7 @@ toku_verify_ftnode_internal(FT_HANDLE ft_handle,
invariant(height == node->height); // this is a bad failure if wrong
}
if (node->height > 0 && messages_exist_above) {
- VERIFY_ASSERTION((parentmsn.msn >= this_msn.msn), 0, "node msn must be descending down tree, newest messages at top");
+ VERIFY_ASSERTION((parentmsn_with_messages.msn >= this_msn.msn), 0, "node msn must be descending down tree, newest messages at top");
}
// Verify that all the pivot keys are in order.
for (int i = 0; i < node->n_children-2; i++) {
@@ -450,7 +450,7 @@ done:
// input is a pinned node, on exit, node is unpinned
int
toku_verify_ftnode (FT_HANDLE ft_handle,
- MSN rootmsn, MSN parentmsn, bool messages_exist_above,
+ MSN rootmsn, MSN parentmsn_with_messages, bool messages_exist_above,
FTNODE node, int height,
const DBT *lesser_pivot, // Everything in the subtree should be > lesser_pivot. (lesser_pivot==NULL if there is no lesser pivot.)
const DBT *greatereq_pivot, // Everything in the subtree should be <= lesser_pivot. (lesser_pivot==NULL if there is no lesser pivot.)
@@ -469,7 +469,7 @@ toku_verify_ftnode (FT_HANDLE ft_handle,
// Otherwise we'll just do the next call
result = toku_verify_ftnode_internal(
- ft_handle, rootmsn, parentmsn, messages_exist_above, node, height, lesser_pivot, greatereq_pivot,
+ ft_handle, rootmsn, parentmsn_with_messages, messages_exist_above, node, height, lesser_pivot, greatereq_pivot,
verbose, keep_going_on_failure, false);
if (result != 0 && (!keep_going_on_failure || result != TOKUDB_NEEDS_REPAIR)) goto done;
}
@@ -477,7 +477,7 @@ toku_verify_ftnode (FT_HANDLE ft_handle,
toku_move_ftnode_messages_to_stale(ft_handle->ft, node);
}
result2 = toku_verify_ftnode_internal(
- ft_handle, rootmsn, parentmsn, messages_exist_above, node, height, lesser_pivot, greatereq_pivot,
+ ft_handle, rootmsn, parentmsn_with_messages, messages_exist_above, node, height, lesser_pivot, greatereq_pivot,
verbose, keep_going_on_failure, true);
if (result == 0) {
result = result2;
@@ -489,12 +489,16 @@ toku_verify_ftnode (FT_HANDLE ft_handle,
for (int i = 0; i < node->n_children; i++) {
FTNODE child_node;
toku_get_node_for_verify(BP_BLOCKNUM(node, i), ft_handle, &child_node);
- int r = toku_verify_ftnode(ft_handle, rootmsn, this_msn, messages_exist_above || toku_bnc_n_entries(BNC(node, i)) > 0,
- child_node, node->height-1,
- (i==0) ? lesser_pivot : &node->childkeys[i-1],
- (i==node->n_children-1) ? greatereq_pivot : &node->childkeys[i],
- progress_callback, progress_extra,
- recurse, verbose, keep_going_on_failure);
+ int r = toku_verify_ftnode(ft_handle, rootmsn,
+ (toku_bnc_n_entries(BNC(node, i)) > 0
+ ? this_msn
+ : parentmsn_with_messages),
+ messages_exist_above || toku_bnc_n_entries(BNC(node, i)) > 0,
+ child_node, node->height-1,
+ (i==0) ? lesser_pivot : &node->childkeys[i-1],
+ (i==node->n_children-1) ? greatereq_pivot : &node->childkeys[i],
+ progress_callback, progress_extra,
+ recurse, verbose, keep_going_on_failure);
if (r) {
result = r;
if (!keep_going_on_failure || result != TOKUDB_NEEDS_REPAIR) goto done;
diff --git a/storage/tokudb/ft-index/ft/ft_layout_version.h b/storage/tokudb/ft-index/ft/ft_layout_version.h
index e9c6a68328b..01c7363e98d 100644
--- a/storage/tokudb/ft-index/ft/ft_layout_version.h
+++ b/storage/tokudb/ft-index/ft/ft_layout_version.h
@@ -120,6 +120,7 @@ enum ft_layout_version_e {
FT_LAYOUT_VERSION_24 = 24, // Riddler: change logentries that log transactions to store TXNID_PAIRs instead of TXNIDs
FT_LAYOUT_VERSION_25 = 25, // SecretSquirrel: ROLLBACK_LOG_NODES (on disk and in memory) now just use blocknum (instead of blocknum + hash) to point to other log nodes. same for xstillopen log entry
FT_LAYOUT_VERSION_26 = 26, // Hojo: basements store key/vals separately on disk for fixed klpair length BNs
+ FT_LAYOUT_VERSION_27 = 27, // serialize message trees with nonleaf buffers to avoid key, msn sort on deserialize
FT_NEXT_VERSION, // the version after the current version
FT_LAYOUT_VERSION = FT_NEXT_VERSION-1, // A hack so I don't have to change this line.
FT_LAYOUT_MIN_SUPPORTED_VERSION = FT_LAYOUT_VERSION_13, // Minimum version supported
diff --git a/storage/tokudb/ft-index/ft/ft_node-serialize.cc b/storage/tokudb/ft-index/ft/ft_node-serialize.cc
index fcb38f11834..91ea0890c30 100644
--- a/storage/tokudb/ft-index/ft/ft_node-serialize.cc
+++ b/storage/tokudb/ft-index/ft/ft_node-serialize.cc
@@ -291,8 +291,13 @@ serialize_ftnode_partition_size (FTNODE node, int i)
paranoid_invariant(node->bp[i].state == PT_AVAIL);
result++; // Byte that states what the partition is
if (node->height > 0) {
- result += 4; // size of bytes in buffer table
- result += toku_bnc_nbytesinbuf(BNC(node, i));
+ NONLEAF_CHILDINFO bnc = BNC(node, i);
+ // number of messages (4 bytes) plus size of the buffer
+ result += (4 + toku_bnc_nbytesinbuf(bnc));
+ // number of offsets (4 bytes) plus an array of 4 byte offsets, for each message tree
+ result += (4 + (4 * bnc->fresh_message_tree.size()));
+ result += (4 + (4 * bnc->stale_message_tree.size()));
+ result += (4 + (4 * bnc->broadcast_list.size()));
}
else {
result += 4 + bn_data::HEADER_LENGTH; // n_entries in buffer table + basement header
@@ -305,8 +310,35 @@ serialize_ftnode_partition_size (FTNODE node, int i)
#define FTNODE_PARTITION_DMT_LEAVES 0xaa
#define FTNODE_PARTITION_FIFO_MSG 0xbb
+UU() static int
+assert_fresh(const int32_t &offset, const uint32_t UU(idx), struct fifo *const f) {
+ struct fifo_entry *entry = toku_fifo_get_entry(f, offset);
+ assert(entry->is_fresh);
+ return 0;
+}
+
+UU() static int
+assert_stale(const int32_t &offset, const uint32_t UU(idx), struct fifo *const f) {
+ struct fifo_entry *entry = toku_fifo_get_entry(f, offset);
+ assert(!entry->is_fresh);
+ return 0;
+}
+
+static void bnc_verify_message_trees(NONLEAF_CHILDINFO UU(bnc)) {
+#ifdef TOKU_DEBUG_PARANOID
+ bnc->fresh_message_tree.iterate<struct fifo, assert_fresh>(bnc->buffer);
+ bnc->stale_message_tree.iterate<struct fifo, assert_stale>(bnc->buffer);
+#endif
+}
+
+static int
+wbuf_write_offset(const int32_t &offset, const uint32_t UU(idx), struct wbuf *const wb) {
+ wbuf_nocrc_int(wb, offset);
+ return 0;
+}
+
static void
-serialize_nonleaf_childinfo(NONLEAF_CHILDINFO bnc, struct wbuf *wb)
+serialize_child_buffer(NONLEAF_CHILDINFO bnc, struct wbuf *wb)
{
unsigned char ch = FTNODE_PARTITION_FIFO_MSG;
wbuf_nocrc_char(wb, ch);
@@ -323,6 +355,19 @@ serialize_nonleaf_childinfo(NONLEAF_CHILDINFO bnc, struct wbuf *wb)
wbuf_nocrc_bytes(wb, key, keylen);
wbuf_nocrc_bytes(wb, data, datalen);
});
+
+ bnc_verify_message_trees(bnc);
+
+ // serialize the message trees (num entries, offsets array):
+ // fresh, stale, broadcast
+ wbuf_nocrc_int(wb, bnc->fresh_message_tree.size());
+ bnc->fresh_message_tree.iterate<struct wbuf, wbuf_write_offset>(wb);
+
+ wbuf_nocrc_int(wb, bnc->stale_message_tree.size());
+ bnc->stale_message_tree.iterate<struct wbuf, wbuf_write_offset>(wb);
+
+ wbuf_nocrc_int(wb, bnc->broadcast_list.size());
+ bnc->broadcast_list.iterate<struct wbuf, wbuf_write_offset>(wb);
}
//
@@ -346,7 +391,7 @@ serialize_ftnode_partition(FTNODE node, int i, struct sub_block *sb) {
wbuf_init(&wb, sb->uncompressed_ptr, sb->uncompressed_size);
if (node->height > 0) {
// TODO: (Zardosht) possibly exit early if there are no messages
- serialize_nonleaf_childinfo(BNC(node, i), &wb);
+ serialize_child_buffer(BNC(node, i), &wb);
}
else {
unsigned char ch = FTNODE_PARTITION_DMT_LEAVES;
@@ -1024,8 +1069,8 @@ toku_serialize_ftnode_to (int fd, BLOCKNUM blocknum, FTNODE node, FTNODE_DISK_DA
}
static void
-deserialize_child_buffer(NONLEAF_CHILDINFO bnc, struct rbuf *rbuf,
- DESCRIPTOR desc, ft_compare_func cmp) {
+deserialize_child_buffer_v26(NONLEAF_CHILDINFO bnc, struct rbuf *rbuf,
+ DESCRIPTOR desc, ft_compare_func cmp) {
int r;
int n_in_this_buffer = rbuf_int(rbuf);
int32_t *fresh_offsets = NULL, *stale_offsets = NULL;
@@ -1090,6 +1135,68 @@ deserialize_child_buffer(NONLEAF_CHILDINFO bnc, struct rbuf *rbuf,
}
}
+// effect: deserialize a single message from rbuf and enqueue the result into the given fifo
+static void
+fifo_deserialize_msg_from_rbuf(FIFO fifo, struct rbuf *rbuf) {
+ bytevec key, val;
+ ITEMLEN keylen, vallen;
+ enum ft_msg_type type = (enum ft_msg_type) rbuf_char(rbuf);
+ bool is_fresh = rbuf_char(rbuf);
+ MSN msn = rbuf_msn(rbuf);
+ XIDS xids;
+ xids_create_from_buffer(rbuf, &xids);
+ rbuf_bytes(rbuf, &key, &keylen); /* Returns a pointer into the rbuf. */
+ rbuf_bytes(rbuf, &val, &vallen);
+ int r = toku_fifo_enq(fifo, key, keylen, val, vallen, type, msn, xids, is_fresh, nullptr);
+ lazy_assert_zero(r);
+ xids_destroy(&xids);
+}
+
+static void
+deserialize_child_buffer(NONLEAF_CHILDINFO bnc, struct rbuf *rbuf) {
+ int n_in_this_buffer = rbuf_int(rbuf);
+ int nfresh = 0, nstale = 0, nbroadcast_offsets = 0;
+ int32_t *XMALLOC_N(n_in_this_buffer, stale_offsets);
+ int32_t *XMALLOC_N(n_in_this_buffer, fresh_offsets);
+ int32_t *XMALLOC_N(n_in_this_buffer, broadcast_offsets);
+
+ toku_fifo_resize(bnc->buffer, rbuf->size + 64);
+ for (int i = 0; i < n_in_this_buffer; i++) {
+ fifo_deserialize_msg_from_rbuf(bnc->buffer, rbuf);
+ }
+
+ // read in each message tree (fresh, stale, broadcast)
+ nfresh = rbuf_int(rbuf);
+ bytevec fresh_offsets_src_v;
+ rbuf_literal_bytes(rbuf, &fresh_offsets_src_v, nfresh * (sizeof *fresh_offsets));
+ const int32_t *fresh_offsets_src = (const int32_t *) fresh_offsets_src_v;
+ for (int i = 0; i < nfresh; i++) {
+ fresh_offsets[i] = toku_dtoh32(fresh_offsets_src[i]);
+ }
+ nstale = rbuf_int(rbuf);
+ bytevec stale_offsets_src_v;
+ rbuf_literal_bytes(rbuf, &stale_offsets_src_v, nstale * (sizeof *stale_offsets));
+ const int32_t *stale_offsets_src = (const int32_t *) stale_offsets_src_v;
+ for (int i = 0; i < nstale; i++) {
+ stale_offsets[i] = toku_dtoh32(stale_offsets_src[i]);
+ }
+ nbroadcast_offsets = rbuf_int(rbuf);
+ bytevec broadcast_offsets_src_v;
+ rbuf_literal_bytes(rbuf, &broadcast_offsets_src_v, nbroadcast_offsets * (sizeof *broadcast_offsets));
+ const int32_t *broadcast_offsets_src = (const int32_t *) broadcast_offsets_src_v;
+ for (int i = 0; i < nbroadcast_offsets; i++) {
+ broadcast_offsets[i] = toku_dtoh32(broadcast_offsets_src[i]);
+ }
+
+ // build OMTs out of each offset array
+ bnc->fresh_message_tree.destroy();
+ bnc->fresh_message_tree.create_steal_sorted_array(&fresh_offsets, nfresh, n_in_this_buffer);
+ bnc->stale_message_tree.destroy();
+ bnc->stale_message_tree.create_steal_sorted_array(&stale_offsets, nstale, n_in_this_buffer);
+ bnc->broadcast_list.destroy();
+ bnc->broadcast_list.create_steal_sorted_array(&broadcast_offsets, nbroadcast_offsets, n_in_this_buffer);
+}
+
// dump a buffer to stderr
// no locking around this for now
void
@@ -1161,13 +1268,16 @@ NONLEAF_CHILDINFO toku_create_empty_nl(void) {
return cn;
}
-// does NOT create OMTs, just the FIFO
+// must clone the OMTs, since we serialize them along with the FIFO
NONLEAF_CHILDINFO toku_clone_nl(NONLEAF_CHILDINFO orig_childinfo) {
NONLEAF_CHILDINFO XMALLOC(cn);
toku_fifo_clone(orig_childinfo->buffer, &cn->buffer);
cn->fresh_message_tree.create_no_array();
+ cn->fresh_message_tree.clone(orig_childinfo->fresh_message_tree);
cn->stale_message_tree.create_no_array();
+ cn->stale_message_tree.clone(orig_childinfo->stale_message_tree);
cn->broadcast_list.create_no_array();
+ cn->broadcast_list.clone(orig_childinfo->broadcast_list);
memset(cn->flow, 0, sizeof cn->flow);
return cn;
}
@@ -1513,7 +1623,13 @@ deserialize_ftnode_partition(
if (node->height > 0) {
assert(ch == FTNODE_PARTITION_FIFO_MSG);
- deserialize_child_buffer(BNC(node, childnum), &rb, desc, cmp);
+ NONLEAF_CHILDINFO bnc = BNC(node, childnum);
+ if (node->layout_version_read_from_disk <= FT_LAYOUT_VERSION_26) {
+ // Layout version <= 26 did not serialize sorted message trees to disk.
+ deserialize_child_buffer_v26(bnc, &rb, desc, cmp);
+ } else {
+ deserialize_child_buffer(bnc, &rb);
+ }
BP_WORKDONE(node, childnum) = 0;
}
else {
diff --git a/storage/tokudb/ft-index/ft/ftloader-internal.h b/storage/tokudb/ft-index/ft/ftloader-internal.h
index be1ded59890..d60537490dd 100644
--- a/storage/tokudb/ft-index/ft/ftloader-internal.h
+++ b/storage/tokudb/ft-index/ft/ftloader-internal.h
@@ -245,6 +245,7 @@ struct ft_loader_s {
CACHETABLE cachetable;
bool did_reserve_memory;
bool compress_intermediates;
+ bool allow_puts;
uint64_t reserved_memory; // how much memory are we allowed to use?
/* To make it easier to recover from errors, we don't use FILE*, instead we use an index into the file_infos. */
@@ -346,7 +347,8 @@ int toku_ft_loader_internal_init (/* out */ FTLOADER *blp,
TOKUTXN txn,
bool reserve_memory,
uint64_t reserve_memory_size,
- bool compress_intermediates);
+ bool compress_intermediates,
+ bool allow_puts);
void toku_ft_loader_internal_destroy (FTLOADER bl, bool is_error);
diff --git a/storage/tokudb/ft-index/ft/ftloader.cc b/storage/tokudb/ft-index/ft/ftloader.cc
index 2df6d0a1cda..67b3cf9905e 100644
--- a/storage/tokudb/ft-index/ft/ftloader.cc
+++ b/storage/tokudb/ft-index/ft/ftloader.cc
@@ -356,6 +356,8 @@ int ft_loader_open_temp_file (FTLOADER bl, FIDX *file_idx)
*/
{
int result = 0;
+ if (result) // debug hack
+ return result;
FILE *f = NULL;
int fd = -1;
char *fname = toku_strdup(bl->temp_file_template);
@@ -420,6 +422,10 @@ void toku_ft_loader_internal_destroy (FTLOADER bl, bool is_error) {
}
destroy_rowset(&bl->primary_rowset);
+ if (bl->primary_rowset_queue) {
+ queue_destroy(bl->primary_rowset_queue);
+ bl->primary_rowset_queue = nullptr;
+ }
for (int i=0; i<bl->N; i++) {
if ( bl->fractal_queues ) {
@@ -543,7 +549,8 @@ int toku_ft_loader_internal_init (/* out */ FTLOADER *blp,
TOKUTXN txn,
bool reserve_memory,
uint64_t reserve_memory_size,
- bool compress_intermediates)
+ bool compress_intermediates,
+ bool allow_puts)
// Effect: Allocate and initialize a FTLOADER, but do not create the extractor thread.
{
FTLOADER CALLOC(bl); // initialized to all zeros (hence CALLOC)
@@ -560,10 +567,7 @@ int toku_ft_loader_internal_init (/* out */ FTLOADER *blp,
bl->reserved_memory = 512*1024*1024; // if no cache table use 512MB.
}
bl->compress_intermediates = compress_intermediates;
- if (0) { // debug
- fprintf(stderr, "%s Reserved memory=%" PRId64 "\n", __FUNCTION__, bl->reserved_memory);
- }
-
+ bl->allow_puts = allow_puts;
bl->src_db = src_db;
bl->N = N;
bl->load_lsn = load_lsn;
@@ -628,7 +632,6 @@ int toku_ft_loader_internal_init (/* out */ FTLOADER *blp,
{ int r = queue_create(&bl->primary_rowset_queue, EXTRACTOR_QUEUE_DEPTH);
if (r!=0) { toku_ft_loader_internal_destroy(bl, true); return r; }
}
- //printf("%s:%d toku_pthread_create\n", __FILE__, __LINE__);
{
ft_loader_lock_init(bl);
}
@@ -650,34 +653,38 @@ int toku_ft_loader_open (/* out */ FTLOADER *blp,
TOKUTXN txn,
bool reserve_memory,
uint64_t reserve_memory_size,
- bool compress_intermediates)
-/* Effect: called by DB_ENV->create_loader to create an ft loader.
- * Arguments:
- * blp Return the ft loader here.
- * g The function for generating a row
- * src_db The source database. Needed by g. May be NULL if that's ok with g.
- * N The number of dbs to create.
- * dbs An array of open databases. Used by g. The data will be put in these database.
- * new_fnames The file names (these strings are owned by the caller: we make a copy for our own purposes).
- * temp_file_template A template suitable for mkstemp()
- * Return value: 0 on success, an error number otherwise.
- */
-{
+ bool compress_intermediates,
+ bool allow_puts) {
+// Effect: called by DB_ENV->create_loader to create a brt loader.
+// Arguments:
+// blp Return the brt loader here.
+// g The function for generating a row
+// src_db The source database. Needed by g. May be NULL if that's ok with g.
+// N The number of dbs to create.
+// dbs An array of open databases. Used by g. The data will be put in these database.
+// new_fnames The file names (these strings are owned by the caller: we make a copy for our own purposes).
+// temp_file_template A template suitable for mkstemp()
+// reserve_memory Cause the loader to reserve memory for its use from the cache table.
+// compress_intermediates Cause the loader to compress intermediate loader files.
+// allow_puts Prepare the loader for rows to insert. When puts are disabled, the loader does not run the
+// extractor or the fractal tree writer threads.
+// Return value: 0 on success, an error number otherwise.
int result = 0;
{
int r = toku_ft_loader_internal_init(blp, cachetable, g, src_db,
- N, fts, dbs,
- new_fnames_in_env,
- bt_compare_functions,
- temp_file_template,
- load_lsn,
- txn,
- reserve_memory,
- reserve_memory_size,
- compress_intermediates);
+ N, fts, dbs,
+ new_fnames_in_env,
+ bt_compare_functions,
+ temp_file_template,
+ load_lsn,
+ txn,
+ reserve_memory,
+ reserve_memory_size,
+ compress_intermediates,
+ allow_puts);
if (r!=0) result = r;
}
- if (result==0) {
+ if (result==0 && allow_puts) {
FTLOADER bl = *blp;
int r = toku_pthread_create(&bl->extractor_thread, NULL, extractor_thread, (void*)bl);
if (r==0) {
@@ -1213,6 +1220,7 @@ finish_extractor (FTLOADER bl) {
{
int r = queue_destroy(bl->primary_rowset_queue);
invariant(r==0);
+ bl->primary_rowset_queue = nullptr;
}
rval = ft_loader_fi_close_all(&bl->file_infos);
@@ -1374,10 +1382,9 @@ int toku_ft_loader_put (FTLOADER bl, DBT *key, DBT *val)
* Return value: 0 on success, an error number otherwise.
*/
{
- if (ft_loader_get_error(&bl->error_callback))
+ if (!bl->allow_puts || ft_loader_get_error(&bl->error_callback))
return EINVAL; // previous panic
bl->n_rows++;
-// return loader_write_row(key, val, bl->fprimary_rows, &bl->fprimary_offset, bl);
return loader_do_put(bl, key, val);
}
@@ -2425,6 +2432,8 @@ static int toku_loader_write_ft_from_q (FTLOADER bl,
if (r) {
result = r;
drain_writer_q(q);
+ r = toku_os_close(fd);
+ assert_zero(r);
return result;
}
FILE *pivots_stream = toku_bl_fidx2file(bl, pivots_file);
@@ -2714,12 +2723,7 @@ static int loader_do_i (FTLOADER bl,
struct rowset *rows = &(bl->rows[which_db]);
invariant(rows->data==NULL); // the rows should be all cleaned up already
- // a better allocation would be to figure out roughly how many merge passes we'll need.
- int allocation_for_merge = (2*progress_allocation)/3;
- progress_allocation -= allocation_for_merge;
-
- int r;
- r = queue_create(&bl->fractal_queues[which_db], FRACTAL_WRITER_QUEUE_DEPTH);
+ int r = queue_create(&bl->fractal_queues[which_db], FRACTAL_WRITER_QUEUE_DEPTH);
if (r) goto error;
{
@@ -2740,49 +2744,62 @@ static int loader_do_i (FTLOADER bl,
r = dest_db->get_fanout(dest_db, &target_fanout);
invariant_zero(r);
- // This structure must stay live until the join below.
- struct fractal_thread_args fta = { bl,
- descriptor,
- fd,
- progress_allocation,
- bl->fractal_queues[which_db],
- bl->extracted_datasizes[which_db],
- 0,
- which_db,
- target_nodesize,
- target_basementnodesize,
- target_compression_method,
- target_fanout
- };
-
- r = toku_pthread_create(bl->fractal_threads+which_db, NULL, fractal_thread, (void*)&fta);
- if (r) {
- int r2 __attribute__((__unused__)) = queue_destroy(bl->fractal_queues[which_db]);
- // ignore r2, since we already have an error
- goto error;
- }
- invariant(bl->fractal_threads_live[which_db]==false);
- bl->fractal_threads_live[which_db] = true;
+ if (bl->allow_puts) {
+ // a better allocation would be to figure out roughly how many merge passes we'll need.
+ int allocation_for_merge = (2*progress_allocation)/3;
+ progress_allocation -= allocation_for_merge;
+
+ // This structure must stay live until the join below.
+ struct fractal_thread_args fta = {
+ bl,
+ descriptor,
+ fd,
+ progress_allocation,
+ bl->fractal_queues[which_db],
+ bl->extracted_datasizes[which_db],
+ 0,
+ which_db,
+ target_nodesize,
+ target_basementnodesize,
+ target_compression_method,
+ target_fanout
+ };
+
+ r = toku_pthread_create(bl->fractal_threads+which_db, NULL, fractal_thread, (void*)&fta);
+ if (r) {
+ int r2 __attribute__((__unused__)) = queue_destroy(bl->fractal_queues[which_db]);
+ // ignore r2, since we already have an error
+ bl->fractal_queues[which_db] = nullptr;
+ goto error;
+ }
+ invariant(bl->fractal_threads_live[which_db]==false);
+ bl->fractal_threads_live[which_db] = true;
- r = merge_files(fs, bl, which_db, dest_db, compare, allocation_for_merge, bl->fractal_queues[which_db]);
+ r = merge_files(fs, bl, which_db, dest_db, compare, allocation_for_merge, bl->fractal_queues[which_db]);
- {
- void *toku_pthread_retval;
- int r2 = toku_pthread_join(bl->fractal_threads[which_db], &toku_pthread_retval);
- invariant(fta.bl==bl); // this is a gratuitous assertion to make sure that the fta struct is still live here. A previous bug but that struct into a C block statement.
- resource_assert_zero(r2);
- invariant(toku_pthread_retval==NULL);
- invariant(bl->fractal_threads_live[which_db]);
- bl->fractal_threads_live[which_db] = false;
- if (r == 0) r = fta.errno_result;
+ {
+ void *toku_pthread_retval;
+ int r2 = toku_pthread_join(bl->fractal_threads[which_db], &toku_pthread_retval);
+ invariant(fta.bl==bl); // this is a gratuitous assertion to make sure that the fta struct is still live here. A previous bug put that struct into a C block statement.
+ resource_assert_zero(r2);
+ invariant(toku_pthread_retval==NULL);
+ invariant(bl->fractal_threads_live[which_db]);
+ bl->fractal_threads_live[which_db] = false;
+ if (r == 0) r = fta.errno_result;
+ }
+ } else {
+ queue_eof(bl->fractal_queues[which_db]);
+ r = toku_loader_write_ft_from_q(bl, descriptor, fd, progress_allocation,
+ bl->fractal_queues[which_db], bl->extracted_datasizes[which_db], which_db,
+ target_nodesize, target_basementnodesize, target_compression_method, target_fanout);
}
}
error: // this is the cleanup code. Even if r==0 (no error) we fall through to here.
- {
+ if (bl->fractal_queues[which_db]) {
int r2 = queue_destroy(bl->fractal_queues[which_db]);
invariant(r2==0);
- bl->fractal_queues[which_db]=NULL;
+ bl->fractal_queues[which_db] = nullptr;
}
// if we get here we need to free up the merge_fileset and the rowset, as well as the keys
@@ -2851,6 +2868,10 @@ int toku_ft_loader_close (FTLOADER bl,
if (r)
result = r;
invariant(!bl->extractor_live);
+ } else {
+ r = finish_primary_rows(bl);
+ if (r)
+ result = r;
}
// check for an error during extraction
diff --git a/storage/tokudb/ft-index/ft/ftloader.h b/storage/tokudb/ft-index/ft/ftloader.h
index c3376c90e91..c920b4c5362 100644
--- a/storage/tokudb/ft-index/ft/ftloader.h
+++ b/storage/tokudb/ft-index/ft/ftloader.h
@@ -113,7 +113,8 @@ int toku_ft_loader_open (FTLOADER *bl,
TOKUTXN txn,
bool reserve_memory,
uint64_t reserve_memory_size,
- bool compress_intermediates);
+ bool compress_intermediates,
+ bool allow_puts);
int toku_ft_loader_put (FTLOADER bl, DBT *key, DBT *val);
diff --git a/storage/tokudb/ft-index/ft/log_upgrade.cc b/storage/tokudb/ft-index/ft/log_upgrade.cc
index e5a36a88cff..8dba57e9d8d 100644
--- a/storage/tokudb/ft-index/ft/log_upgrade.cc
+++ b/storage/tokudb/ft-index/ft/log_upgrade.cc
@@ -321,8 +321,8 @@ toku_maybe_upgrade_log(const char *env_dir, const char *log_dir, LSN * lsn_of_cl
r = 0; //Logs are up to date
else {
FOOTPRINT(4);
- LSN last_lsn;
- TXNID last_xid;
+ LSN last_lsn = ZERO_LSN;
+ TXNID last_xid = TXNID_NONE;
r = verify_clean_shutdown_of_log_version(log_dir, version_of_logs_on_disk, &last_lsn, &last_xid);
if (r != 0) {
goto cleanup;
diff --git a/storage/tokudb/ft-index/ft/logger.cc b/storage/tokudb/ft-index/ft/logger.cc
index e4fd854c637..bbac5cf7de3 100644
--- a/storage/tokudb/ft-index/ft/logger.cc
+++ b/storage/tokudb/ft-index/ft/logger.cc
@@ -621,7 +621,7 @@ int toku_logger_find_next_unused_log_file(const char *directory, long long *resu
if (d==0) return get_error_errno();
while ((de=readdir(d))) {
if (de==0) return get_error_errno();
- long long thisl;
+ long long thisl = -1;
if ( is_a_logfile(de->d_name, &thisl) ) {
if ((long long)thisl > maxf) maxf = thisl;
}
diff --git a/storage/tokudb/ft-index/ft/tests/ftloader-test-bad-generate.cc b/storage/tokudb/ft-index/ft/tests/ftloader-test-bad-generate.cc
index 1ecae89da78..9ae24f7c4ec 100644
--- a/storage/tokudb/ft-index/ft/tests/ftloader-test-bad-generate.cc
+++ b/storage/tokudb/ft-index/ft/tests/ftloader-test-bad-generate.cc
@@ -170,7 +170,7 @@ static void test_extractor(int nrows, int nrowsets, bool expect_fail) {
}
FTLOADER loader;
- r = toku_ft_loader_open(&loader, NULL, generate, NULL, N, fts, dbs, fnames, compares, "tempXXXXXX", ZERO_LSN, nullptr, true, 0, false);
+ r = toku_ft_loader_open(&loader, NULL, generate, NULL, N, fts, dbs, fnames, compares, "tempXXXXXX", ZERO_LSN, nullptr, true, 0, false, true);
assert(r == 0);
struct rowset *rowset[nrowsets];
diff --git a/storage/tokudb/ft-index/ft/tests/ftloader-test-extractor-errors.cc b/storage/tokudb/ft-index/ft/tests/ftloader-test-extractor-errors.cc
index 4dcd7fb2f8c..007fd39fe08 100644
--- a/storage/tokudb/ft-index/ft/tests/ftloader-test-extractor-errors.cc
+++ b/storage/tokudb/ft-index/ft/tests/ftloader-test-extractor-errors.cc
@@ -180,7 +180,7 @@ static void test_extractor(int nrows, int nrowsets, bool expect_fail, const char
sprintf(temp, "%s/%s", testdir, "tempXXXXXX");
FTLOADER loader;
- r = toku_ft_loader_open(&loader, NULL, generate, NULL, N, fts, dbs, fnames, compares, "tempXXXXXX", ZERO_LSN, nullptr, true, 0, false);
+ r = toku_ft_loader_open(&loader, NULL, generate, NULL, N, fts, dbs, fnames, compares, "tempXXXXXX", ZERO_LSN, nullptr, true, 0, false, true);
assert(r == 0);
struct rowset *rowset[nrowsets];
diff --git a/storage/tokudb/ft-index/ft/tests/ftloader-test-extractor.cc b/storage/tokudb/ft-index/ft/tests/ftloader-test-extractor.cc
index 0a8ce157269..afba44a7a22 100644
--- a/storage/tokudb/ft-index/ft/tests/ftloader-test-extractor.cc
+++ b/storage/tokudb/ft-index/ft/tests/ftloader-test-extractor.cc
@@ -402,7 +402,7 @@ static void test_extractor(int nrows, int nrowsets, const char *testdir) {
sprintf(temp, "%s/%s", testdir, "tempXXXXXX");
FTLOADER loader;
- r = toku_ft_loader_open(&loader, NULL, generate, NULL, N, fts, dbs, fnames, compares, temp, ZERO_LSN, nullptr, true, 0, false);
+ r = toku_ft_loader_open(&loader, NULL, generate, NULL, N, fts, dbs, fnames, compares, temp, ZERO_LSN, nullptr, true, 0, false, true);
assert(r == 0);
struct rowset *rowset[nrowsets];
diff --git a/storage/tokudb/ft-index/ft/tests/ftloader-test-merge-files-dbufio.cc b/storage/tokudb/ft-index/ft/tests/ftloader-test-merge-files-dbufio.cc
index 82583595470..cdd4c1d6691 100644
--- a/storage/tokudb/ft-index/ft/tests/ftloader-test-merge-files-dbufio.cc
+++ b/storage/tokudb/ft-index/ft/tests/ftloader-test-merge-files-dbufio.cc
@@ -412,7 +412,7 @@ static void test (const char *directory, bool is_error) {
bt_compare_functions,
"tempxxxxxx",
*lsnp,
- nullptr, true, 0, false);
+ nullptr, true, 0, false, true);
assert(r==0);
}
@@ -500,11 +500,6 @@ static void test (const char *directory, bool is_error) {
assert(cthunk.n_read == N_RECORDS);
}
}
- //printf("%s:%d Destroying\n", __FILE__, __LINE__);
- {
- int r = queue_destroy(bl->primary_rowset_queue);
- assert(r==0);
- }
{
int r = queue_destroy(q);
assert(r==0);
diff --git a/storage/tokudb/ft-index/ft/tests/ftloader-test-open.cc b/storage/tokudb/ft-index/ft/tests/ftloader-test-open.cc
index f2919f04d3d..cdf0a14ab00 100644
--- a/storage/tokudb/ft-index/ft/tests/ftloader-test-open.cc
+++ b/storage/tokudb/ft-index/ft/tests/ftloader-test-open.cc
@@ -143,7 +143,7 @@ static void test_loader_open(int ndbs) {
for (i = 0; ; i++) {
set_my_malloc_trigger(i+1);
- r = toku_ft_loader_open(&loader, NULL, NULL, NULL, ndbs, fts, dbs, fnames, compares, "", ZERO_LSN, nullptr, true, 0, false);
+ r = toku_ft_loader_open(&loader, NULL, NULL, NULL, ndbs, fts, dbs, fnames, compares, "", ZERO_LSN, nullptr, true, 0, false, true);
if (r == 0)
break;
}
diff --git a/storage/tokudb/ft-index/ft/tests/test_rightmost_leaf_seqinsert_heuristic.cc b/storage/tokudb/ft-index/ft/tests/test_rightmost_leaf_seqinsert_heuristic.cc
new file mode 100644
index 00000000000..100e5153636
--- /dev/null
+++ b/storage/tokudb/ft-index/ft/tests/test_rightmost_leaf_seqinsert_heuristic.cc
@@ -0,0 +1,183 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
+#ident "$Id$"
+/*
+COPYING CONDITIONS NOTICE:
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation, and provided that the
+ following conditions are met:
+
+ * Redistributions of source code must retain this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below).
+
+ * Redistributions in binary form must reproduce this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below) in the documentation and/or other materials
+ provided with the distribution.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+COPYRIGHT NOTICE:
+
+ TokuDB, Tokutek Fractal Tree Indexing Library.
+ Copyright (C) 2007-2014 Tokutek, Inc.
+
+DISCLAIMER:
+
+ 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.
+
+UNIVERSITY PATENT NOTICE:
+
+ The technology is licensed by the Massachusetts Institute of
+ Technology, Rutgers State University of New Jersey, and the Research
+ Foundation of State University of New York at Stony Brook under
+ United States of America Serial No. 11/760379 and to the patents
+ and/or patent applications resulting from it.
+
+PATENT MARKING NOTICE:
+
+ This software is covered by US Patent No. 8,185,551.
+ This software is covered by US Patent No. 8,489,638.
+
+PATENT RIGHTS GRANT:
+
+ "THIS IMPLEMENTATION" means the copyrightable works distributed by
+ Tokutek as part of the Fractal Tree project.
+
+ "PATENT CLAIMS" means the claims of patents that are owned or
+ licensable by Tokutek, both currently or in the future; and that in
+ the absence of this license would be infringed by THIS
+ IMPLEMENTATION or by using or running THIS IMPLEMENTATION.
+
+ "PATENT CHALLENGE" shall mean a challenge to the validity,
+ patentability, enforceability and/or non-infringement of any of the
+ PATENT CLAIMS or otherwise opposing any of the PATENT CLAIMS.
+
+ Tokutek hereby grants to you, for the term and geographical scope of
+ the PATENT CLAIMS, a non-exclusive, no-charge, royalty-free,
+ irrevocable (except as stated in this section) patent license to
+ make, have made, use, offer to sell, sell, import, transfer, and
+ otherwise run, modify, and propagate the contents of THIS
+ IMPLEMENTATION, where such license applies only to the PATENT
+ CLAIMS. This grant does not include claims that would be infringed
+ only as a consequence of further modifications of THIS
+ IMPLEMENTATION. If you or your agent or licensee institute or order
+ or agree to the institution of patent litigation against any entity
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
+ THIS IMPLEMENTATION constitutes direct or contributory patent
+ infringement, or inducement of patent infringement, then any rights
+ granted to you under this License shall terminate as of the date
+ such litigation is filed. If you or your agent or exclusive
+ licensee institute or order or agree to the institution of a PATENT
+ CHALLENGE, then Tokutek may terminate any rights granted to you
+ under this License.
+*/
+
+#ident "Copyright (c) 2014 Tokutek Inc. All rights reserved."
+
+#include "test.h"
+
+#include <ft/ybt.h>
+#include <ft/ft-cachetable-wrappers.h>
+
+// Each FT maintains a sequential insert heuristic to determine if its
+// worth trying to insert directly into a well-known rightmost leaf node.
+//
+// The heuristic is only maintained when a rightmost leaf node is known.
+//
+// This test verifies that sequential inserts increase the seqinsert score
+// and that a single non-sequential insert resets the score.
+
+static void test_seqinsert_heuristic(void) {
+ int r = 0;
+ char name[TOKU_PATH_MAX + 1];
+ toku_path_join(name, 2, TOKU_TEST_FILENAME, "ftdata");
+ toku_os_recursive_delete(TOKU_TEST_FILENAME);
+ r = toku_os_mkdir(TOKU_TEST_FILENAME, S_IRWXU); CKERR(r);
+
+ FT_HANDLE ft_handle;
+ CACHETABLE ct;
+ toku_cachetable_create(&ct, 0, ZERO_LSN, NULL_LOGGER);
+ r = toku_open_ft_handle(name, 1, &ft_handle,
+ 4*1024*1024, 64*1024,
+ TOKU_DEFAULT_COMPRESSION_METHOD, ct, NULL,
+ toku_builtin_compare_fun); CKERR(r);
+ FT ft = ft_handle->ft;
+
+ int k;
+ DBT key, val;
+ const int val_size = 1024 * 1024;
+ char *XMALLOC_N(val_size, val_buf);
+ memset(val_buf, 'x', val_size);
+ toku_fill_dbt(&val, val_buf, val_size);
+
+ // Insert many rows sequentially. This is enough data to:
+ // - force the root to split (the righmost leaf will then be known)
+ // - raise the seqinsert score high enough to enable direct rightmost injections
+ const int rows_to_insert = 200;
+ for (int i = 0; i < rows_to_insert; i++) {
+ k = toku_htonl(i);
+ toku_fill_dbt(&key, &k, sizeof(k));
+ toku_ft_insert(ft_handle, &key, &val, NULL);
+ }
+ invariant(ft->rightmost_blocknum.b != RESERVED_BLOCKNUM_NULL);
+ invariant(ft->seqinsert_score == FT_SEQINSERT_SCORE_THRESHOLD);
+
+ // Insert on the left extreme. The seq insert score is high enough
+ // that we will attempt to insert into the rightmost leaf. We won't
+ // be successful because key 0 won't be in the bounds of the rightmost leaf.
+ // This failure should reset the seqinsert score back to 0.
+ k = toku_htonl(0);
+ toku_fill_dbt(&key, &k, sizeof(k));
+ toku_ft_insert(ft_handle, &key, &val, NULL);
+ invariant(ft->seqinsert_score == 0);
+
+ // Insert in the middle. The score should not go up.
+ k = toku_htonl(rows_to_insert / 2);
+ toku_fill_dbt(&key, &k, sizeof(k));
+ toku_ft_insert(ft_handle, &key, &val, NULL);
+ invariant(ft->seqinsert_score == 0);
+
+ // Insert on the right extreme. The score should go up.
+ k = toku_htonl(rows_to_insert);
+ toku_fill_dbt(&key, &k, sizeof(k));
+ toku_ft_insert(ft_handle, &key, &val, NULL);
+ invariant(ft->seqinsert_score == 1);
+
+ // Insert again on the right extreme again, the score should go up.
+ k = toku_htonl(rows_to_insert + 1);
+ toku_fill_dbt(&key, &k, sizeof(k));
+ toku_ft_insert(ft_handle, &key, &val, NULL);
+ invariant(ft->seqinsert_score == 2);
+
+ // Insert close to, but not at, the right extreme. The score should reset.
+ // -- the magic number 4 derives from the fact that vals are 1mb and nodes are 4mb
+ k = toku_htonl(rows_to_insert - 4);
+ toku_fill_dbt(&key, &k, sizeof(k));
+ toku_ft_insert(ft_handle, &key, &val, NULL);
+ invariant(ft->seqinsert_score == 0);
+
+ toku_free(val_buf);
+ toku_ft_handle_close(ft_handle);
+ toku_cachetable_close(&ct);
+ toku_os_recursive_delete(TOKU_TEST_FILENAME);
+}
+
+int test_main(int argc, const char *argv[]) {
+ default_parse_args(argc, argv);
+ test_seqinsert_heuristic();
+ return 0;
+}
diff --git a/storage/tokudb/ft-index/ft/tests/test_rightmost_leaf_split_merge.cc b/storage/tokudb/ft-index/ft/tests/test_rightmost_leaf_split_merge.cc
new file mode 100644
index 00000000000..517fc277fd3
--- /dev/null
+++ b/storage/tokudb/ft-index/ft/tests/test_rightmost_leaf_split_merge.cc
@@ -0,0 +1,212 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
+#ident "$Id$"
+/*
+COPYING CONDITIONS NOTICE:
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation, and provided that the
+ following conditions are met:
+
+ * Redistributions of source code must retain this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below).
+
+ * Redistributions in binary form must reproduce this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below) in the documentation and/or other materials
+ provided with the distribution.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+COPYRIGHT NOTICE:
+
+ TokuDB, Tokutek Fractal Tree Indexing Library.
+ Copyright (C) 2007-2014 Tokutek, Inc.
+
+DISCLAIMER:
+
+ 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.
+
+UNIVERSITY PATENT NOTICE:
+
+ The technology is licensed by the Massachusetts Institute of
+ Technology, Rutgers State University of New Jersey, and the Research
+ Foundation of State University of New York at Stony Brook under
+ United States of America Serial No. 11/760379 and to the patents
+ and/or patent applications resulting from it.
+
+PATENT MARKING NOTICE:
+
+ This software is covered by US Patent No. 8,185,551.
+ This software is covered by US Patent No. 8,489,638.
+
+PATENT RIGHTS GRANT:
+
+ "THIS IMPLEMENTATION" means the copyrightable works distributed by
+ Tokutek as part of the Fractal Tree project.
+
+ "PATENT CLAIMS" means the claims of patents that are owned or
+ licensable by Tokutek, both currently or in the future; and that in
+ the absence of this license would be infringed by THIS
+ IMPLEMENTATION or by using or running THIS IMPLEMENTATION.
+
+ "PATENT CHALLENGE" shall mean a challenge to the validity,
+ patentability, enforceability and/or non-infringement of any of the
+ PATENT CLAIMS or otherwise opposing any of the PATENT CLAIMS.
+
+ Tokutek hereby grants to you, for the term and geographical scope of
+ the PATENT CLAIMS, a non-exclusive, no-charge, royalty-free,
+ irrevocable (except as stated in this section) patent license to
+ make, have made, use, offer to sell, sell, import, transfer, and
+ otherwise run, modify, and propagate the contents of THIS
+ IMPLEMENTATION, where such license applies only to the PATENT
+ CLAIMS. This grant does not include claims that would be infringed
+ only as a consequence of further modifications of THIS
+ IMPLEMENTATION. If you or your agent or licensee institute or order
+ or agree to the institution of patent litigation against any entity
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
+ THIS IMPLEMENTATION constitutes direct or contributory patent
+ infringement, or inducement of patent infringement, then any rights
+ granted to you under this License shall terminate as of the date
+ such litigation is filed. If you or your agent or exclusive
+ licensee institute or order or agree to the institution of a PATENT
+ CHALLENGE, then Tokutek may terminate any rights granted to you
+ under this License.
+*/
+
+#ident "Copyright (c) 2014 Tokutek Inc. All rights reserved."
+
+#include "test.h"
+
+#include <ft/ybt.h>
+#include <ft/ft-cachetable-wrappers.h>
+
+// Promotion tracks the rightmost blocknum in the FT when a message
+// is successfully promoted to a non-root leaf node on the right extreme.
+//
+// This test verifies that a split or merge of the rightmost leaf properly
+// maintains the rightmost blocknum (which is constant - the pair's swap values,
+// like the root blocknum).
+
+static void test_split_merge(void) {
+ int r = 0;
+ char name[TOKU_PATH_MAX + 1];
+ toku_path_join(name, 2, TOKU_TEST_FILENAME, "ftdata");
+ toku_os_recursive_delete(TOKU_TEST_FILENAME);
+ r = toku_os_mkdir(TOKU_TEST_FILENAME, S_IRWXU); CKERR(r);
+
+ FT_HANDLE ft_handle;
+ CACHETABLE ct;
+ toku_cachetable_create(&ct, 0, ZERO_LSN, NULL_LOGGER);
+ r = toku_open_ft_handle(name, 1, &ft_handle,
+ 4*1024*1024, 64*1024,
+ TOKU_DEFAULT_COMPRESSION_METHOD, ct, NULL,
+ toku_builtin_compare_fun); CKERR(r);
+
+ // We have a root blocknum, but no rightmost blocknum yet.
+ FT ft = ft_handle->ft;
+ invariant(ft->h->root_blocknum.b != RESERVED_BLOCKNUM_NULL);
+ invariant(ft->rightmost_blocknum.b == RESERVED_BLOCKNUM_NULL);
+
+ int k;
+ DBT key, val;
+ const int val_size = 1 * 1024 * 1024;
+ char *XMALLOC_N(val_size, val_buf);
+ memset(val_buf, 'x', val_size);
+ toku_fill_dbt(&val, val_buf, val_size);
+
+ // Insert 16 rows (should induce a few splits)
+ const int rows_to_insert = 16;
+ for (int i = 0; i < rows_to_insert; i++) {
+ k = toku_htonl(i);
+ toku_fill_dbt(&key, &k, sizeof(k));
+ toku_ft_insert(ft_handle, &key, &val, NULL);
+ }
+
+ // rightmost blocknum should be set, because the root split and promotion
+ // did a rightmost insertion directly into the rightmost leaf, lazily
+ // initializing the rightmost blocknum.
+ invariant(ft->rightmost_blocknum.b != RESERVED_BLOCKNUM_NULL);
+
+ BLOCKNUM root_blocknum = ft->h->root_blocknum;
+ FTNODE root_node;
+ struct ftnode_fetch_extra bfe;
+ fill_bfe_for_full_read(&bfe, ft);
+ toku_pin_ftnode(ft, root_blocknum,
+ toku_cachetable_hash(ft->cf, ft->h->root_blocknum),
+ &bfe, PL_WRITE_EXPENSIVE, &root_node, true);
+ // root blocknum should be consistent
+ invariant(root_node->thisnodename.b == ft->h->root_blocknum.b);
+ // root should have split at least once, and it should now be at height 1
+ invariant(root_node->n_children > 1);
+ invariant(root_node->height == 1);
+ // rightmost blocknum should no longer be the root, since the root split
+ invariant(ft->h->root_blocknum.b != ft->rightmost_blocknum.b);
+ // the right child should have the rightmost blocknum
+ invariant(BP_BLOCKNUM(root_node, root_node->n_children - 1).b == ft->rightmost_blocknum.b);
+
+ BLOCKNUM rightmost_blocknum_before_merge = ft->rightmost_blocknum;
+ const int num_children_before_merge = root_node->n_children;
+
+ // delete the last 6 rows.
+ // - 1mb each, so 6mb deleted
+ // - should be enough to delete the entire rightmost leaf + some of its neighbor
+ const int rows_to_delete = 6;
+ toku_unpin_ftnode(ft, root_node);
+ for (int i = 0; i < rows_to_delete; i++) {
+ k = toku_htonl(rows_to_insert - i);
+ toku_fill_dbt(&key, &k, sizeof(k));
+ toku_ft_delete(ft_handle, &key, NULL);
+ }
+ toku_pin_ftnode(ft, root_blocknum,
+ toku_cachetable_hash(ft->cf, root_blocknum),
+ &bfe, PL_WRITE_EXPENSIVE, &root_node, true);
+
+ // - rightmost leaf should be fusible after those deletes (which were promoted directly to the leaf)
+ FTNODE rightmost_leaf;
+ toku_pin_ftnode(ft, rightmost_blocknum_before_merge,
+ toku_cachetable_hash(ft->cf, rightmost_blocknum_before_merge),
+ &bfe, PL_WRITE_EXPENSIVE, &rightmost_leaf, true);
+ invariant(get_node_reactivity(ft, rightmost_leaf) == RE_FUSIBLE);
+ toku_unpin_ftnode(ft, rightmost_leaf);
+
+ // - merge the rightmost child now that it's fusible
+ toku_ft_merge_child(ft, root_node, root_node->n_children - 1);
+ toku_pin_ftnode(ft, root_blocknum,
+ toku_cachetable_hash(ft->cf, root_blocknum),
+ &bfe, PL_WRITE_EXPENSIVE, &root_node, true);
+
+ // the merge should have worked, and the root should still be at height 1
+ invariant(root_node->n_children < num_children_before_merge);
+ invariant(root_node->height == 1);
+ // the rightmost child of the root has the rightmost blocknum
+ invariant(BP_BLOCKNUM(root_node, root_node->n_children - 1).b == ft->rightmost_blocknum.b);
+ // the value for rightmost blocknum itself should not have changed
+ // (we keep it constant, like the root blocknum)
+ invariant(rightmost_blocknum_before_merge.b == ft->rightmost_blocknum.b);
+
+ toku_unpin_ftnode(ft, root_node);
+
+ toku_free(val_buf);
+ toku_ft_handle_close(ft_handle);
+ toku_cachetable_close(&ct);
+ toku_os_recursive_delete(TOKU_TEST_FILENAME);
+}
+
+int test_main(int argc, const char *argv[]) {
+ default_parse_args(argc, argv);
+ test_split_merge();
+ return 0;
+}
diff --git a/storage/tokudb/ft-index/ft/tokuftdump.cc b/storage/tokudb/ft-index/ft/tokuftdump.cc
index f2d4fce83cb..a7d94f41d78 100644
--- a/storage/tokudb/ft-index/ft/tokuftdump.cc
+++ b/storage/tokudb/ft-index/ft/tokuftdump.cc
@@ -89,7 +89,7 @@ PATENT RIGHTS GRANT:
#ident "Copyright (c) 2007-2013 Tokutek Inc. All rights reserved."
#ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it."
-/* Tell me the diff between two FT files. */
+// Dump a fractal tree file
#include "cachetable.h"
#include "ft.h"
@@ -102,20 +102,26 @@ PATENT RIGHTS GRANT:
#include <inttypes.h>
#include <limits.h>
-static void
-format_time(const uint64_t time_int, char *buf) {
+static int do_dump_data = 1;
+static int do_interactive = 0;
+static int do_header = 0;
+static int do_fragmentation = 0;
+static int do_garbage = 0;
+static int do_translation_table = 0;
+static int do_rootnode = 0;
+static int do_tsv = 0;
+
+static const char *arg0;
+static const char *fname;
+
+static void format_time(const uint64_t time_int, char *buf) {
time_t timer = (time_t) time_int;
ctime_r(&timer, buf);
assert(buf[24] == '\n');
buf[24] = 0;
}
-static int dump_data = 1;
-
-static CACHETABLE ct;
-
-static void
-print_item (bytevec val, ITEMLEN len) {
+static void print_item(bytevec val, ITEMLEN len) {
printf("\"");
ITEMLEN i;
for (i=0; i<len; i++) {
@@ -129,16 +135,14 @@ print_item (bytevec val, ITEMLEN len) {
printf("\"");
}
-static void
-simple_hex_dump(unsigned char *vp, uint64_t size) {
+static void simple_hex_dump(unsigned char *vp, uint64_t size) {
for (uint64_t i = 0; i < size; i++) {
unsigned char c = vp[i];
printf("%2.2X", c);
}
}
-static void
-hex_dump(unsigned char *vp, uint64_t offset, uint64_t size) {
+static void hex_dump(unsigned char *vp, uint64_t offset, uint64_t size) {
uint64_t n = size / 32;
for (uint64_t i = 0; i < n; i++) {
printf("%" PRIu64 ": ", offset);
@@ -169,25 +173,26 @@ hex_dump(unsigned char *vp, uint64_t offset, uint64_t size) {
printf("\n");
}
-static void
-dump_descriptor(DESCRIPTOR d) {
+static void dump_descriptor(DESCRIPTOR d) {
printf(" descriptor size %u ", d->dbt.size);
simple_hex_dump((unsigned char*) d->dbt.data, d->dbt.size);
printf("\n");
}
-static void
-open_header (int f, FT *header, CACHEFILE cf) {
+static void open_header(int fd, FT *header, CACHEFILE cf) {
FT ft = NULL;
int r;
- r = toku_deserialize_ft_from (f, MAX_LSN, &ft);
- assert(r==0);
+ r = toku_deserialize_ft_from (fd, MAX_LSN, &ft);
+ if (r != 0) {
+ fprintf(stderr, "%s: can not deserialize from %s error %d\n", arg0, fname, r);
+ exit(1);
+ }
+ assert_zero(r);
ft->cf = cf;
*header = ft;
}
-static void
-dump_header(FT ft) {
+static void dump_header(FT ft) {
char timestr[26];
printf("ft:\n");
printf(" layout_version=%d\n", ft->h->layout_version);
@@ -212,29 +217,19 @@ dump_header(FT ft) {
printf(" estimated numbytes=%" PRId64 "\n", ft->in_memory_stats.numbytes);
}
-static int
-print_le(
- const void* key,
- const uint32_t keylen,
- const LEAFENTRY &le,
- const uint32_t idx UU(),
- void *const ai UU()
- )
-{
+static int print_le(const void* key, const uint32_t keylen, const LEAFENTRY &le, const uint32_t idx UU(), void *const ai UU()) {
print_klpair(stdout, key, keylen, le);
printf("\n");
return 0;
}
-
-static void
-dump_node (int f, BLOCKNUM blocknum, FT h) {
+static void dump_node(int fd, BLOCKNUM blocknum, FT h) {
FTNODE n;
struct ftnode_fetch_extra bfe;
FTNODE_DISK_DATA ndd = NULL;
fill_bfe_for_full_read(&bfe, h);
- int r = toku_deserialize_ftnode_from (f, blocknum, 0 /*pass zero for hash, it doesn't matter*/, &n, &ndd, &bfe);
- assert(r==0);
+ int r = toku_deserialize_ftnode_from (fd, blocknum, 0 /*pass zero for hash, it doesn't matter*/, &n, &ndd, &bfe);
+ assert_zero(r);
assert(n!=0);
printf("ftnode\n");
DISKOFF disksize, diskoffset;
@@ -271,15 +266,16 @@ dump_node (int f, BLOCKNUM blocknum, FT h) {
}
printf(" children:\n");
for (int i=0; i<n->n_children; i++) {
+ printf(" child %d: ", i);
if (n->height > 0) {
- printf(" child %d: %" PRId64 "\n", i, BP_BLOCKNUM(n, i).b);
+ printf("%" PRId64 "\n", BP_BLOCKNUM(n, i).b);
NONLEAF_CHILDINFO bnc = BNC(n, i);
unsigned int n_bytes = toku_bnc_nbytesinbuf(bnc);
int n_entries = toku_bnc_n_entries(bnc);
if (n_bytes > 0 || n_entries > 0) {
printf(" buffer contains %u bytes (%d items)\n", n_bytes, n_entries);
}
- if (dump_data) {
+ if (do_dump_data) {
FIFO_ITERATE(bnc->buffer, key, keylen, data, datalen, typ, msn, xids, UU(is_fresh),
{
printf(" msn=%" PRIu64 " (0x%" PRIx64 ") ", msn.msn, msn.msn);
@@ -316,7 +312,7 @@ dump_node (int f, BLOCKNUM blocknum, FT h) {
} else {
printf(" n_bytes_in_buffer= %" PRIu64 "", BLB_DATA(n, i)->get_disk_size());
printf(" items_in_buffer=%u\n", BLB_DATA(n, i)->num_klpairs());
- if (dump_data) {
+ if (do_dump_data) {
BLB_DATA(n, i)->iterate<void, print_le>(NULL);
}
}
@@ -325,13 +321,11 @@ dump_node (int f, BLOCKNUM blocknum, FT h) {
toku_free(ndd);
}
-static void
-dump_block_translation(FT h, uint64_t offset) {
+static void dump_block_translation(FT h, uint64_t offset) {
toku_blocknum_dump_translation(h->blocktable, make_blocknum(offset));
}
-static void
-dump_fragmentation(int UU(f), FT h, int tsv) {
+static void dump_fragmentation(int UU(f), FT h, int tsv) {
int64_t used_space;
int64_t total_space;
toku_blocktable_internal_fragmentation(h->blocktable, &total_space, &used_space);
@@ -349,21 +343,20 @@ dump_fragmentation(int UU(f), FT h, int tsv) {
}
typedef struct {
- int f;
+ int fd;
FT h;
uint64_t blocksizes;
uint64_t leafsizes;
uint64_t leafblocks;
} frag_help_extra;
-static int
-nodesizes_helper(BLOCKNUM b, int64_t size, int64_t UU(address), void *extra) {
+static int nodesizes_helper(BLOCKNUM b, int64_t size, int64_t UU(address), void *extra) {
frag_help_extra *CAST_FROM_VOIDP(info, extra);
FTNODE n;
FTNODE_DISK_DATA ndd = NULL;
struct ftnode_fetch_extra bfe;
fill_bfe_for_full_read(&bfe, info->h);
- int r = toku_deserialize_ftnode_from(info->f, b, 0 /*pass zero for hash, it doesn't matter*/, &n, &ndd, &bfe);
+ int r = toku_deserialize_ftnode_from(info->fd, b, 0 /*pass zero for hash, it doesn't matter*/, &n, &ndd, &bfe);
if (r==0) {
info->blocksizes += size;
if (n->height == 0) {
@@ -376,11 +369,10 @@ nodesizes_helper(BLOCKNUM b, int64_t size, int64_t UU(address), void *extra) {
return 0;
}
-static void
-dump_nodesizes(int f, FT h) {
+static void dump_nodesizes(int fd, FT h) {
frag_help_extra info;
memset(&info, 0, sizeof(info));
- info.f = f;
+ info.fd = fd;
info.h = h;
toku_blocktable_iterate(h->blocktable, TRANSLATION_CHECKPOINTED,
nodesizes_helper, &info, true, true);
@@ -389,36 +381,45 @@ dump_nodesizes(int f, FT h) {
printf("leafsizes\t%" PRIu64 "\n", info.leafsizes);
}
-static void
-dump_garbage_stats(int f, FT ft) {
- invariant(f == toku_cachefile_get_fd(ft->cf));
+static void dump_garbage_stats(int fd, FT ft) {
+ assert(fd == toku_cachefile_get_fd(ft->cf));
uint64_t total_space = 0;
uint64_t used_space = 0;
toku_ft_get_garbage(ft, &total_space, &used_space);
- printf("total_size\t%" PRIu64 "\n", total_space);
- printf("used_size\t%" PRIu64 "\n", used_space);
+ printf("garbage total size\t%" PRIu64 "\n", total_space);
+ printf("garbage used size\t%" PRIu64 "\n", used_space);
}
-static uint32_t
-get_unaligned_uint32(unsigned char *p) {
- return *(uint32_t *)p;
+typedef struct __dump_node_extra {
+ int fd;
+ FT h;
+} dump_node_extra;
+
+static int dump_node_wrapper(BLOCKNUM b, int64_t UU(size), int64_t UU(address), void *extra) {
+ dump_node_extra *CAST_FROM_VOIDP(info, extra);
+ dump_node(info->fd, b, info->h);
+ return 0;
+}
+
+static uint32_t get_unaligned_uint32(unsigned char *p) {
+ uint32_t n;
+ memcpy(&n, p, sizeof n);
+ return n;
}
struct dump_sub_block {
- uint32_t compressed_size;
- uint32_t uncompressed_size;
- uint32_t xsum;
+ uint32_t compressed_size;
+ uint32_t uncompressed_size;
+ uint32_t xsum;
};
-static void
-sub_block_deserialize(struct dump_sub_block *sb, unsigned char *sub_block_header) {
+static void sub_block_deserialize(struct dump_sub_block *sb, unsigned char *sub_block_header) {
sb->compressed_size = toku_dtoh32(get_unaligned_uint32(sub_block_header+0));
sb->uncompressed_size = toku_dtoh32(get_unaligned_uint32(sub_block_header+4));
sb->xsum = toku_dtoh32(get_unaligned_uint32(sub_block_header+8));
}
-static void
-verify_block(unsigned char *cp, uint64_t file_offset, uint64_t size) {
+static void verify_block(unsigned char *cp, uint64_t file_offset, uint64_t size) {
// verify the header checksum
const size_t node_header = 8 + sizeof (uint32_t) + sizeof (uint32_t) + sizeof (uint32_t);
@@ -461,24 +462,22 @@ verify_block(unsigned char *cp, uint64_t file_offset, uint64_t size) {
printf("offset %u expected %" PRIu64 "\n", offset, size);
}
-static void
-dump_block(int f, BLOCKNUM blocknum, FT h) {
+static void dump_block(int fd, BLOCKNUM blocknum, FT h) {
DISKOFF offset, size;
toku_translate_blocknum_to_offset_size(h->blocktable, blocknum, &offset, &size);
printf("%" PRId64 " at %" PRId64 " size %" PRId64 "\n", blocknum.b, offset, size);
unsigned char *CAST_FROM_VOIDP(vp, toku_malloc(size));
- uint64_t r = pread(f, vp, size, offset);
+ uint64_t r = pread(fd, vp, size, offset);
if (r == (uint64_t)size) {
verify_block(vp, offset, size);
}
toku_free(vp);
}
-static void
-dump_file(int f, uint64_t offset, uint64_t size, FILE *outfp) {
+static void dump_file(int fd, uint64_t offset, uint64_t size, FILE *outfp) {
unsigned char *XMALLOC_N(size, vp);
- uint64_t r = pread(f, vp, size, offset);
+ uint64_t r = pread(fd, vp, size, offset);
if (r == size) {
if (outfp == stdout) {
hex_dump(vp, offset, size);
@@ -490,13 +489,11 @@ dump_file(int f, uint64_t offset, uint64_t size, FILE *outfp) {
toku_free(vp);
}
-static void
-set_file(int f, uint64_t offset, unsigned char newc) {
- toku_os_pwrite(f, &newc, sizeof newc, offset);
+static void set_file(int fd, uint64_t offset, unsigned char newc) {
+ toku_os_pwrite(fd, &newc, sizeof newc, offset);
}
-static int
-readline (char *line, int maxline) {
+static int readline(char *line, int maxline) {
int i = 0;
int c;
while ((c = getchar()) != EOF && c != '\n' && i < maxline) {
@@ -506,8 +503,7 @@ readline (char *line, int maxline) {
return c == EOF ? EOF : i;
}
-static int
-split_fields (char *line, char *fields[], int maxfields) {
+static int split_fields(char *line, char *fields[], int maxfields) {
int i;
for (i=0; i<maxfields; i++)
fields[i] = NULL;
@@ -520,26 +516,16 @@ split_fields (char *line, char *fields[], int maxfields) {
return i;
}
-static int
-usage(const char *arg0) {
- printf("Usage: %s [--nodata] [--i[nteractive]|--fragmentation [--tsv]|--translation-table|--rootnode] ftfilename\n", arg0);
- return 1;
-}
-
-typedef struct __dump_node_extra {
- int f;
- FT h;
-} dump_node_extra;
-
-static int
-dump_node_wrapper(BLOCKNUM b, int64_t UU(size), int64_t UU(address), void *extra) {
- dump_node_extra *CAST_FROM_VOIDP(info, extra);
- dump_node(info->f, b, info->h);
- return 0;
+static uint64_t getuint64(const char *f) {
+ if (strncmp(f, "0x", 2) == 0 || strncmp(f, "0X", 2) == 0)
+ return strtoull(f, 0, 16);
+ else if (strncmp(f, "0", 1) == 0)
+ return strtoull(f, 0, 8);
+ else
+ return strtoull(f, 0, 10);
}
-static void
-interactive_help(void) {
+static void interactive_help(void) {
fprintf(stderr, "help\n");
fprintf(stderr, "header\n");
fprintf(stderr, "node NUMBER\n");
@@ -552,133 +538,160 @@ interactive_help(void) {
fprintf(stderr, "quit\n");
}
-static uint64_t
-getuint64(const char *f) {
- if (strncmp(f, "0x", 2) == 0 || strncmp(f, "0X", 2) == 0)
- return strtoull(f, 0, 16);
- else if (strncmp(f, "0", 1) == 0)
- return strtoull(f, 0, 8);
- else
- return strtoull(f, 0, 10);
+static void run_iteractive_loop(int fd, FT ft, CACHEFILE cf) {
+ while (1) {
+ printf("ftdump>"); fflush(stdout);
+ enum { maxline = 64};
+ char line[maxline+1];
+ int r = readline(line, maxline);
+ if (r == EOF)
+ break;
+ const int maxfields = 4;
+ char *fields[maxfields];
+ int nfields = split_fields(line, fields, maxfields);
+ if (nfields == 0)
+ continue;
+ if (strcmp(fields[0], "help") == 0) {
+ interactive_help();
+ } else if (strcmp(fields[0], "header") == 0) {
+ toku_ft_free(ft);
+ open_header(fd, &ft, cf);
+ dump_header(ft);
+ } else if (strcmp(fields[0], "block") == 0 && nfields == 2) {
+ BLOCKNUM blocknum = make_blocknum(getuint64(fields[1]));
+ dump_block(fd, blocknum, ft);
+ } else if (strcmp(fields[0], "node") == 0 && nfields == 2) {
+ BLOCKNUM off = make_blocknum(getuint64(fields[1]));
+ dump_node(fd, off, ft);
+ } else if (strcmp(fields[0], "dumpdata") == 0 && nfields == 2) {
+ do_dump_data = strtol(fields[1], NULL, 10);
+ } else if (strcmp(fields[0], "block_translation") == 0 || strcmp(fields[0], "bx") == 0) {
+ uint64_t offset = 0;
+ if (nfields == 2)
+ offset = getuint64(fields[1]);
+ dump_block_translation(ft, offset);
+ } else if (strcmp(fields[0], "fragmentation") == 0) {
+ dump_fragmentation(fd, ft, do_tsv);
+ } else if (strcmp(fields[0], "nodesizes") == 0) {
+ dump_nodesizes(fd, ft);
+ } else if (strcmp(fields[0], "garbage") == 0) {
+ dump_garbage_stats(fd, ft);
+ } else if (strcmp(fields[0], "file") == 0 && nfields >= 3) {
+ uint64_t offset = getuint64(fields[1]);
+ uint64_t size = getuint64(fields[2]);
+ FILE *outfp = stdout;
+ if (nfields >= 4)
+ outfp = fopen(fields[3], "w");
+ dump_file(fd, offset, size, outfp);
+ } else if (strcmp(fields[0], "setfile") == 0 && nfields == 3) {
+ uint64_t offset = getuint64(fields[1]);
+ unsigned char newc = getuint64(fields[2]);
+ set_file(fd, offset, newc);
+ } else if (strcmp(fields[0], "quit") == 0 || strcmp(fields[0], "q") == 0) {
+ break;
+ }
+ }
}
-int
-main (int argc, const char *const argv[]) {
- int interactive = 0;
- int fragmentation = 0;
- int translation_table = 0;
- int rootnode = 0;
- int tsv = 0;
+static int usage(void) {
+ fprintf(stderr, "Usage: %s ", arg0);
+ fprintf(stderr, "--interactive ");
+ fprintf(stderr, "--nodata ");
+ fprintf(stderr, "--dumpdata 0|1 ");
+ fprintf(stderr, "--header ");
+ fprintf(stderr, "--rootnode ");
+ fprintf(stderr, "--fragmentation ");
+ fprintf(stderr, "--garbage ");
+ fprintf(stderr, "--tsv ");
+ fprintf(stderr, "--translation-table ");
+ fprintf(stderr, "--tsv ");
+ fprintf(stderr, "ftfilename \n");
+ return 1;
+}
- const char *arg0 = argv[0];
+int main (int argc, const char *const argv[]) {
+ arg0 = argv[0];
argc--; argv++;
while (argc>0) {
- if (strcmp(argv[0], "--nodata") == 0) {
- dump_data = 0;
- } else if (strcmp(argv[0], "--interactive") == 0 || strcmp(argv[0], "--i") == 0) {
- interactive = 1;
+ if (strcmp(argv[0], "--interactive") == 0 || strcmp(argv[0], "--i") == 0) {
+ do_interactive = 1;
+ } else if (strcmp(argv[0], "--nodata") == 0) {
+ do_dump_data = 0;
+ } else if (strcmp(argv[0], "--dumpdata") == 0 && argc > 1) {
+ argc--; argv++;
+ do_dump_data = atoi(argv[0]);
+ } else if (strcmp(argv[0], "--header") == 0) {
+ do_header = 1;
+ } else if (strcmp(argv[0], "--rootnode") == 0) {
+ do_rootnode = 1;
} else if (strcmp(argv[0], "--fragmentation") == 0) {
- fragmentation = 1;
+ do_fragmentation = 1;
+ } else if (strcmp(argv[0], "--garbage") == 0) {
+ do_garbage = 1;
} else if (strcmp(argv[0], "--tsv") == 0) {
- tsv = 1;
+ do_tsv = 1;
} else if (strcmp(argv[0], "--translation-table") == 0) {
- translation_table = 1;
- } else if (strcmp(argv[0], "--rootnode") == 0) {
- rootnode = 1;
- } else if (strcmp(argv[0], "--help") == 0) {
- return usage(arg0);
+ do_translation_table = 1;
+ } else if (strcmp(argv[0], "--help") == 0 || strcmp(argv[0], "-?") == 0 || strcmp(argv[0], "-h") == 0) {
+ return usage();
} else {
break;
}
argc--; argv++;
}
- if (argc != 1) return usage(arg0);
+ if (argc != 1)
+ return usage();
int r = toku_ft_layer_init();
- invariant_zero(r);
+ assert_zero(r);
+
+ fname = argv[0];
+ int fd = open(fname, O_RDWR + O_BINARY);
+ if (fd < 0) {
+ fprintf(stderr, "%s: can not open %s errno %d\n", arg0, fname, errno);
+ return 1;
+ }
- const char *n = argv[0];
- int f = open(n, O_RDWR + O_BINARY); assert(f>=0);
- FT ft;
// create a cachefile for the header
+ CACHETABLE ct = NULL;
toku_cachetable_create(&ct, 1<<25, (LSN){0}, 0);
+
CACHEFILE cf = NULL;
- r = toku_cachetable_openfd (&cf, ct, f, n);
- assert(r==0);
- open_header(f, &ft, cf);
- if (!fragmentation && !translation_table) {
- // quick fix for now, we want those two to have clean output
- dump_header(ft);
- }
- if (interactive) {
- while (1) {
- printf("ftdump>"); fflush(stdout);
- enum { maxline = 64};
- char line[maxline+1];
- r = readline(line, maxline);
- if (r == EOF)
- break;
- const int maxfields = 4;
- char *fields[maxfields];
- int nfields = split_fields(line, fields, maxfields);
- if (nfields == 0)
- continue;
- if (strcmp(fields[0], "help") == 0) {
- interactive_help();
- } else if (strcmp(fields[0], "header") == 0) {
- toku_ft_free(ft);
- open_header(f, &ft, cf);
- dump_header(ft);
- } else if (strcmp(fields[0], "block") == 0 && nfields == 2) {
- BLOCKNUM blocknum = make_blocknum(getuint64(fields[1]));
- dump_block(f, blocknum, ft);
- } else if (strcmp(fields[0], "node") == 0 && nfields == 2) {
- BLOCKNUM off = make_blocknum(getuint64(fields[1]));
- dump_node(f, off, ft);
- } else if (strcmp(fields[0], "dumpdata") == 0 && nfields == 2) {
- dump_data = strtol(fields[1], NULL, 10);
- } else if (strcmp(fields[0], "block_translation") == 0 || strcmp(fields[0], "bx") == 0) {
- uint64_t offset = 0;
- if (nfields == 2)
- offset = getuint64(fields[1]);
- dump_block_translation(ft, offset);
- } else if (strcmp(fields[0], "fragmentation") == 0) {
- dump_fragmentation(f, ft, tsv);
- } else if (strcmp(fields[0], "nodesizes") == 0) {
- dump_nodesizes(f, ft);
- } else if (strcmp(fields[0], "garbage") == 0) {
- dump_garbage_stats(f, ft);
- } else if (strcmp(fields[0], "file") == 0 && nfields >= 3) {
- uint64_t offset = getuint64(fields[1]);
- uint64_t size = getuint64(fields[2]);
- FILE *outfp = stdout;
- if (nfields >= 4)
- outfp = fopen(fields[3], "w");
- dump_file(f, offset, size, outfp);
- } else if (strcmp(fields[0], "setfile") == 0 && nfields == 3) {
- uint64_t offset = getuint64(fields[1]);
- unsigned char newc = getuint64(fields[2]);
- set_file(f, offset, newc);
- } else if (strcmp(fields[0], "quit") == 0 || strcmp(fields[0], "q") == 0) {
- break;
- }
- }
- } else if (rootnode) {
- dump_node(f, ft->h->root_blocknum, ft);
- } else if (fragmentation) {
- dump_fragmentation(f, ft, tsv);
- } else if (translation_table) {
- toku_dump_translation_table_pretty(stdout, ft->blocktable);
- } else {
- printf("Block translation:");
+ r = toku_cachetable_openfd (&cf, ct, fd, fname);
+ assert_zero(r);
- toku_dump_translation_table(stdout, ft->blocktable);
+ FT ft = NULL;
+ open_header(fd, &ft, cf);
- struct __dump_node_extra info;
- info.f = f;
- info.h = ft;
- toku_blocktable_iterate(ft->blocktable, TRANSLATION_CHECKPOINTED,
- dump_node_wrapper, &info, true, true);
+ if (do_interactive) {
+ run_iteractive_loop(fd, ft, cf);
+ } else {
+ if (do_header) {
+ dump_header(ft);
+ }
+ if (do_rootnode) {
+ dump_node(fd, ft->h->root_blocknum, ft);
+ }
+ if (do_fragmentation) {
+ dump_fragmentation(fd, ft, do_tsv);
+ }
+ if (do_translation_table) {
+ toku_dump_translation_table_pretty(stdout, ft->blocktable);
+ }
+ if (do_garbage) {
+ dump_garbage_stats(fd, ft);
+ }
+ if (!do_header && !do_rootnode && !do_fragmentation && !do_translation_table && !do_garbage) {
+ printf("Block translation:");
+
+ toku_dump_translation_table(stdout, ft->blocktable);
+
+ struct __dump_node_extra info;
+ info.fd = fd;
+ info.h = ft;
+ toku_blocktable_iterate(ft->blocktable, TRANSLATION_CHECKPOINTED,
+ dump_node_wrapper, &info, true, true);
+ }
}
toku_cachefile_close(&cf, false, ZERO_LSN);
toku_cachetable_close(&ct);
diff --git a/storage/tokudb/ft-index/scripts/run.stress-tests.py b/storage/tokudb/ft-index/scripts/run.stress-tests.py
index fbbf5ee6472..d4245a7c4b4 100755
--- a/storage/tokudb/ft-index/scripts/run.stress-tests.py
+++ b/storage/tokudb/ft-index/scripts/run.stress-tests.py
@@ -735,6 +735,7 @@ if __name__ == '__main__':
'test_stress6.tdb',
'test_stress7.tdb',
'test_stress_hot_indexing.tdb',
+ 'test_stress_with_verify.tdb',
'test_stress_openclose.tdb']
default_recover_testnames = ['recover-test_stress1.tdb',
'recover-test_stress2.tdb',
@@ -766,8 +767,8 @@ if __name__ == '__main__':
help="skip the tests that don't involve upgrade [default=False]")
upgrade_group.add_option('--double_upgrade', action='store_true', dest='double_upgrade', default=False,
help='run the upgrade tests twice in a row [default=False]')
- upgrade_group.add_option('--add_old_version', action='append', type='choice', dest='old_versions', choices=['4.2.0', '5.0.8', '5.2.7', '6.0.0', '6.1.0', '6.5.1', '6.6.3'],
- help='which old versions to use for running the stress tests in upgrade mode. can be specified multiple times [options=4.2.0, 5.0.8, 5.2.7, 6.0.0, 6.1.0, 6.5.1, 6.6.3]')
+ upgrade_group.add_option('--add_old_version', action='append', type='choice', dest='old_versions', choices=['4.2.0', '5.0.8', '5.2.7', '6.0.0', '6.1.0', '6.5.1', '6.6.3', '7.1.6'],
+ help='which old versions to use for running the stress tests in upgrade mode. can be specified multiple times [options=4.2.0, 5.0.8, 5.2.7, 6.0.0, 6.1.0, 6.5.1, 6.6.3, 7.1.6]')
upgrade_group.add_option('--old_environments_dir', type='string', dest='old_environments_dir',
default=('%s/old-stress-test-envs' % default_tokudb_data),
help='directory containing old version environments (should contain 5.0.8/, 5.2.7/, etc, and the environments should be in those) [default=../../tokudb.data/stress_environments]')
diff --git a/storage/tokudb/ft-index/src/loader.cc b/storage/tokudb/ft-index/src/loader.cc
index 88db258e1ff..62b4f0b6cef 100644
--- a/storage/tokudb/ft-index/src/loader.cc
+++ b/storage/tokudb/ft-index/src/loader.cc
@@ -172,6 +172,13 @@ struct __toku_loader_internal {
char **inames_in_env; /* [N] inames of new files to be created */
};
+static void free_inames(char **inames, int n) {
+ for (int i = 0; i < n; i++) {
+ toku_free(inames[i]);
+ }
+ toku_free(inames);
+}
+
/*
* free_loader_resources() frees all of the resources associated with
* struct __toku_loader_internal
@@ -185,16 +192,15 @@ static void free_loader_resources(DB_LOADER *loader)
toku_destroy_dbt(&loader->i->err_val);
if (loader->i->inames_in_env) {
- for (int i=0; i<loader->i->N; i++) {
- if (loader->i->inames_in_env[i]) toku_free(loader->i->inames_in_env[i]);
- }
- toku_free(loader->i->inames_in_env);
+ free_inames(loader->i->inames_in_env, loader->i->N);
+ loader->i->inames_in_env = nullptr;
}
- if (loader->i->temp_file_template) toku_free(loader->i->temp_file_template);
+ toku_free(loader->i->temp_file_template);
+ loader->i->temp_file_template = nullptr;
// loader->i
toku_free(loader->i);
- loader->i = NULL;
+ loader->i = nullptr;
}
}
@@ -245,6 +251,7 @@ toku_loader_create_loader(DB_ENV *env,
bool check_empty) {
int rval;
HANDLE_READ_ONLY_TXN(txn);
+ DB_TXN *loader_txn = nullptr;
*blp = NULL; // set later when created
@@ -299,6 +306,13 @@ toku_loader_create_loader(DB_ENV *env,
}
{
+ if (env->i->open_flags & DB_INIT_TXN) {
+ rval = env->txn_begin(env, txn, &loader_txn, 0);
+ if (rval) {
+ goto create_exit;
+ }
+ }
+
ft_compare_func compare_functions[N];
for (int i=0; i<N; i++) {
compare_functions[i] = env->i->bt_compare;
@@ -306,18 +320,21 @@ toku_loader_create_loader(DB_ENV *env,
// time to open the big kahuna
char **XMALLOC_N(N, new_inames_in_env);
+ for (int i = 0; i < N; i++) {
+ new_inames_in_env[i] = nullptr;
+ }
FT_HANDLE *XMALLOC_N(N, fts);
for (int i=0; i<N; i++) {
fts[i] = dbs[i]->i->ft_handle;
}
LSN load_lsn;
- rval = locked_load_inames(env, txn, N, dbs, new_inames_in_env, &load_lsn, puts_allowed);
+ rval = locked_load_inames(env, loader_txn, N, dbs, new_inames_in_env, &load_lsn, puts_allowed);
if ( rval!=0 ) {
- toku_free(new_inames_in_env);
+ free_inames(new_inames_in_env, N);
toku_free(fts);
goto create_exit;
}
- TOKUTXN ttxn = txn ? db_txn_struct_i(txn)->tokutxn : NULL;
+ TOKUTXN ttxn = loader_txn ? db_txn_struct_i(loader_txn)->tokutxn : NULL;
rval = toku_ft_loader_open(&loader->i->ft_loader,
env->i->cachetable,
env->i->generate_row_for_put,
@@ -331,12 +348,14 @@ toku_loader_create_loader(DB_ENV *env,
ttxn,
puts_allowed,
env->get_loader_memory_size(env),
- compress_intermediates);
+ compress_intermediates,
+ puts_allowed);
if ( rval!=0 ) {
- toku_free(new_inames_in_env);
+ free_inames(new_inames_in_env, N);
toku_free(fts);
goto create_exit;
}
+
loader->i->inames_in_env = new_inames_in_env;
toku_free(fts);
@@ -348,10 +367,19 @@ toku_loader_create_loader(DB_ENV *env,
rval = 0;
}
+ rval = loader_txn->commit(loader_txn, 0);
+ assert_zero(rval);
+ loader_txn = nullptr;
+
rval = 0;
}
*blp = loader;
create_exit:
+ if (loader_txn) {
+ int r = loader_txn->abort(loader_txn);
+ assert_zero(r);
+ loader_txn = nullptr;
+ }
if (rval == 0) {
(void) toku_sync_fetch_and_add(&STATUS_VALUE(LOADER_CREATE), 1);
(void) toku_sync_fetch_and_add(&STATUS_VALUE(LOADER_CURRENT), 1);
@@ -441,7 +469,7 @@ static void redirect_loader_to_empty_dictionaries(DB_LOADER *loader) {
loader->i->dbs,
loader->i->db_flags,
loader->i->dbt_flags,
- 0,
+ LOADER_DISALLOW_PUTS,
false
);
lazy_assert_zero(r);
diff --git a/storage/tokudb/ft-index/src/tests/dbremove-nofile-limit.cc b/storage/tokudb/ft-index/src/tests/dbremove-nofile-limit.cc
new file mode 100644
index 00000000000..eb5c6b80b63
--- /dev/null
+++ b/storage/tokudb/ft-index/src/tests/dbremove-nofile-limit.cc
@@ -0,0 +1,177 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
+/*
+COPYING CONDITIONS NOTICE:
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation, and provided that the
+ following conditions are met:
+
+ * Redistributions of source code must retain this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below).
+
+ * Redistributions in binary form must reproduce this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below) in the documentation and/or other materials
+ provided with the distribution.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+COPYRIGHT NOTICE:
+
+ TokuDB, Tokutek Fractal Tree Indexing Library.
+ Copyright (C) 2007-2013 Tokutek, Inc.
+
+DISCLAIMER:
+
+ 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.
+
+UNIVERSITY PATENT NOTICE:
+
+ The technology is licensed by the Massachusetts Institute of
+ Technology, Rutgers State University of New Jersey, and the Research
+ Foundation of State University of New York at Stony Brook under
+ United States of America Serial No. 11/760379 and to the patents
+ and/or patent applications resulting from it.
+
+PATENT MARKING NOTICE:
+
+ This software is covered by US Patent No. 8,185,551.
+ This software is covered by US Patent No. 8,489,638.
+
+PATENT RIGHTS GRANT:
+
+ "THIS IMPLEMENTATION" means the copyrightable works distributed by
+ Tokutek as part of the Fractal Tree project.
+
+ "PATENT CLAIMS" means the claims of patents that are owned or
+ licensable by Tokutek, both currently or in the future; and that in
+ the absence of this license would be infringed by THIS
+ IMPLEMENTATION or by using or running THIS IMPLEMENTATION.
+
+ "PATENT CHALLENGE" shall mean a challenge to the validity,
+ patentability, enforceability and/or non-infringement of any of the
+ PATENT CLAIMS or otherwise opposing any of the PATENT CLAIMS.
+
+ Tokutek hereby grants to you, for the term and geographical scope of
+ the PATENT CLAIMS, a non-exclusive, no-charge, royalty-free,
+ irrevocable (except as stated in this section) patent license to
+ make, have made, use, offer to sell, sell, import, transfer, and
+ otherwise run, modify, and propagate the contents of THIS
+ IMPLEMENTATION, where such license applies only to the PATENT
+ CLAIMS. This grant does not include claims that would be infringed
+ only as a consequence of further modifications of THIS
+ IMPLEMENTATION. If you or your agent or licensee institute or order
+ or agree to the institution of patent litigation against any entity
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
+ THIS IMPLEMENTATION constitutes direct or contributory patent
+ infringement, or inducement of patent infringement, then any rights
+ granted to you under this License shall terminate as of the date
+ such litigation is filed. If you or your agent or exclusive
+ licensee institute or order or agree to the institution of a PATENT
+ CHALLENGE, then Tokutek may terminate any rights granted to you
+ under this License.
+*/
+
+#ident "Copyright (c) 2014 Tokutek Inc. All rights reserved."
+#ident "$Id$"
+
+// This test verifies that the env->dbremove function returns an error rather than
+// crash when the NOFILE resource limit is exceeded.
+
+#include "test.h"
+#include <db.h>
+#include <sys/resource.h>
+
+static const char *envdir = TOKU_TEST_FILENAME;
+
+static void test_dbremove() {
+ int r;
+
+ char rmcmd[32 + strlen(envdir)];
+ snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", envdir);
+ r = system(rmcmd); CKERR(r);
+ r = toku_os_mkdir(envdir, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
+
+ DB_ENV *env;
+ r = db_env_create(&env, 0); CKERR(r);
+ int envflags = DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_CREATE | DB_PRIVATE;
+ r = env->open(env, envdir, envflags, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
+ env->set_errfile(env, stderr);
+
+ DB *db;
+ r = db_create(&db, env, 0); CKERR(r);
+ char fname[32];
+ sprintf(fname, "db%d", 0);
+ r = db->open(db, nullptr, fname, nullptr, DB_BTREE, DB_CREATE, 0666); CKERR(r);
+
+ r = db->close(db, 0); CKERR(r);
+
+ DB_TXN *txn;
+ r = env->txn_begin(env, nullptr, &txn, 0); CKERR(r);
+
+ struct rlimit current_limit;
+ r = getrlimit(RLIMIT_NOFILE, &current_limit);
+ assert(r == 0);
+
+ struct rlimit new_limit = current_limit;
+ new_limit.rlim_cur = 0;
+ r = setrlimit(RLIMIT_NOFILE, &new_limit);
+ assert(r == 0);
+
+ r = env->dbremove(env, txn, fname, nullptr, 0);
+ CKERR2(r, EMFILE);
+
+ r = setrlimit(RLIMIT_NOFILE, &current_limit);
+ assert(r == 0);
+
+ r = env->dbremove(env, txn, fname, nullptr, 0);
+ CKERR(r);
+
+ r = txn->commit(txn, 0); CKERR(r);
+
+ r = env->close(env, 0); CKERR(r);
+}
+
+static void do_args(int argc, char * const argv[]) {
+ int resultcode;
+ char *cmd = argv[0];
+ argc--; argv++;
+ while (argc>0) {
+ if (strcmp(argv[0], "-h")==0) {
+ resultcode=0;
+ do_usage:
+ fprintf(stderr, "Usage: %s -h -v -q\n", cmd);
+ exit(resultcode);
+ } else if (strcmp(argv[0], "-v")==0) {
+ verbose++;
+ } else if (strcmp(argv[0],"-q")==0) {
+ verbose--;
+ if (verbose<0) verbose=0;
+ } else {
+ fprintf(stderr, "Unknown arg: %s\n", argv[0]);
+ resultcode=1;
+ goto do_usage;
+ }
+ argc--;
+ argv++;
+ }
+}
+
+int test_main(int argc, char * const *argv) {
+ do_args(argc, argv);
+ test_dbremove();
+ return 0;
+}
diff --git a/storage/tokudb/ft-index/src/tests/loader-close-nproc-limit.cc b/storage/tokudb/ft-index/src/tests/loader-close-nproc-limit.cc
new file mode 100644
index 00000000000..3ef2b0541f7
--- /dev/null
+++ b/storage/tokudb/ft-index/src/tests/loader-close-nproc-limit.cc
@@ -0,0 +1,198 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
+/*
+COPYING CONDITIONS NOTICE:
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation, and provided that the
+ following conditions are met:
+
+ * Redistributions of source code must retain this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below).
+
+ * Redistributions in binary form must reproduce this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below) in the documentation and/or other materials
+ provided with the distribution.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+COPYRIGHT NOTICE:
+
+ TokuDB, Tokutek Fractal Tree Indexing Library.
+ Copyright (C) 2007-2013 Tokutek, Inc.
+
+DISCLAIMER:
+
+ 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.
+
+UNIVERSITY PATENT NOTICE:
+
+ The technology is licensed by the Massachusetts Institute of
+ Technology, Rutgers State University of New Jersey, and the Research
+ Foundation of State University of New York at Stony Brook under
+ United States of America Serial No. 11/760379 and to the patents
+ and/or patent applications resulting from it.
+
+PATENT MARKING NOTICE:
+
+ This software is covered by US Patent No. 8,185,551.
+ This software is covered by US Patent No. 8,489,638.
+
+PATENT RIGHTS GRANT:
+
+ "THIS IMPLEMENTATION" means the copyrightable works distributed by
+ Tokutek as part of the Fractal Tree project.
+
+ "PATENT CLAIMS" means the claims of patents that are owned or
+ licensable by Tokutek, both currently or in the future; and that in
+ the absence of this license would be infringed by THIS
+ IMPLEMENTATION or by using or running THIS IMPLEMENTATION.
+
+ "PATENT CHALLENGE" shall mean a challenge to the validity,
+ patentability, enforceability and/or non-infringement of any of the
+ PATENT CLAIMS or otherwise opposing any of the PATENT CLAIMS.
+
+ Tokutek hereby grants to you, for the term and geographical scope of
+ the PATENT CLAIMS, a non-exclusive, no-charge, royalty-free,
+ irrevocable (except as stated in this section) patent license to
+ make, have made, use, offer to sell, sell, import, transfer, and
+ otherwise run, modify, and propagate the contents of THIS
+ IMPLEMENTATION, where such license applies only to the PATENT
+ CLAIMS. This grant does not include claims that would be infringed
+ only as a consequence of further modifications of THIS
+ IMPLEMENTATION. If you or your agent or licensee institute or order
+ or agree to the institution of patent litigation against any entity
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
+ THIS IMPLEMENTATION constitutes direct or contributory patent
+ infringement, or inducement of patent infringement, then any rights
+ granted to you under this License shall terminate as of the date
+ such litigation is filed. If you or your agent or exclusive
+ licensee institute or order or agree to the institution of a PATENT
+ CHALLENGE, then Tokutek may terminate any rights granted to you
+ under this License.
+*/
+
+// Verify that loader->close works correctly (does not crash, does not leak memory, returns the right error code)
+// when the NPROC limit is exceeded.
+
+#ident "Copyright (c) 2010-2013 Tokutek Inc. All rights reserved."
+#ident "$Id$"
+
+#include "test.h"
+#include <db.h>
+#include <sys/resource.h>
+
+static int loader_flags = 0;
+static const char *envdir = TOKU_TEST_FILENAME;
+
+static void run_test(int ndb) {
+ int r;
+
+ char rmcmd[32 + strlen(envdir)];
+ snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", envdir);
+ r = system(rmcmd); CKERR(r);
+ r = toku_os_mkdir(envdir, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
+
+ DB_ENV *env;
+ r = db_env_create(&env, 0); CKERR(r);
+ int envflags = DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_CREATE | DB_PRIVATE;
+ r = env->open(env, envdir, envflags, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
+ env->set_errfile(env, stderr);
+
+ DB *dbs[ndb];
+ uint32_t db_flags[ndb];
+ uint32_t dbt_flags[ndb];
+ for (int i = 0; i < ndb; i++) {
+ db_flags[i] = DB_NOOVERWRITE;
+ dbt_flags[i] = 0;
+ r = db_create(&dbs[i], env, 0); CKERR(r);
+ char name[32];
+ sprintf(name, "db%d", i);
+ r = dbs[i]->open(dbs[i], NULL, name, NULL, DB_BTREE, DB_CREATE, 0666); CKERR(r);
+ }
+
+ DB_TXN *txn;
+ r = env->txn_begin(env, NULL, &txn, 0); CKERR(r);
+
+ DB_LOADER *loader;
+ r = env->create_loader(env, txn, &loader, ndb > 0 ? dbs[0] : NULL, ndb, dbs, db_flags, dbt_flags, loader_flags); CKERR(r);
+
+ struct rlimit current_nproc_limit;
+ r = getrlimit(RLIMIT_NPROC, &current_nproc_limit);
+ assert(r == 0);
+
+ struct rlimit new_nproc_limit = current_nproc_limit;
+ new_nproc_limit.rlim_cur = 0;
+ r = setrlimit(RLIMIT_NPROC, &new_nproc_limit);
+ assert(r == 0);
+
+ r = loader->close(loader);
+
+ if (loader_flags & LOADER_DISALLOW_PUTS)
+ CKERR(r);
+ else
+ CKERR2(r, EAGAIN);
+
+ r = setrlimit(RLIMIT_NPROC, &current_nproc_limit);
+ assert(r == 0);
+
+ r = txn->abort(txn); CKERR(r);
+
+ for (int i = 0; i < ndb; i++) {
+ r = dbs[i]->close(dbs[i], 0); CKERR(r);
+ }
+
+ r = env->close(env, 0); CKERR(r);
+}
+
+static void do_args(int argc, char * const argv[]) {
+ int resultcode;
+ char *cmd = argv[0];
+ argc--; argv++;
+ while (argc>0) {
+ if (strcmp(argv[0], "-h")==0) {
+ resultcode=0;
+ do_usage:
+ fprintf(stderr, "Usage: %s -h -v -q -p\n", cmd);
+ exit(resultcode);
+ } else if (strcmp(argv[0], "-v")==0) {
+ verbose++;
+ } else if (strcmp(argv[0],"-q")==0) {
+ verbose--;
+ if (verbose<0) verbose=0;
+ } else if (strcmp(argv[0], "-p") == 0) {
+ loader_flags |= LOADER_DISALLOW_PUTS;
+ } else if (strcmp(argv[0], "-z") == 0) {
+ loader_flags |= LOADER_COMPRESS_INTERMEDIATES;
+ } else if (strcmp(argv[0], "-e") == 0) {
+ argc--; argv++;
+ if (argc > 0)
+ envdir = argv[0];
+ } else {
+ fprintf(stderr, "Unknown arg: %s\n", argv[0]);
+ resultcode=1;
+ goto do_usage;
+ }
+ argc--;
+ argv++;
+ }
+}
+
+int test_main(int argc, char * const *argv) {
+ do_args(argc, argv);
+ run_test(1);
+ return 0;
+}
diff --git a/storage/tokudb/ft-index/src/tests/loader-create-close.cc b/storage/tokudb/ft-index/src/tests/loader-create-close.cc
index 6a04387152f..4d66a9df004 100644
--- a/storage/tokudb/ft-index/src/tests/loader-create-close.cc
+++ b/storage/tokudb/ft-index/src/tests/loader-create-close.cc
@@ -97,11 +97,7 @@ PATENT RIGHTS GRANT:
static int loader_flags = 0;
static const char *envdir = TOKU_TEST_FILENAME;
-static int put_multiple_generate(DB *UU(dest_db), DB *UU(src_db), DBT_ARRAY *UU(dest_keys), DBT_ARRAY *UU(dest_vals), const DBT *UU(src_key), const DBT *UU(src_val)) {
- return ENOMEM;
-}
-
-static void loader_open_abort(int ndb) {
+static void test_loader_create_close(int ndb) {
int r;
char rmcmd[32 + strlen(envdir)];
@@ -111,8 +107,6 @@ static void loader_open_abort(int ndb) {
DB_ENV *env;
r = db_env_create(&env, 0); CKERR(r);
- r = env->set_generate_row_callback_for_put(env, put_multiple_generate);
- CKERR(r);
int envflags = DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_CREATE | DB_PRIVATE;
r = env->open(env, envdir, envflags, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
env->set_errfile(env, stderr);
@@ -181,8 +175,8 @@ static void do_args(int argc, char * const argv[]) {
int test_main(int argc, char * const *argv) {
do_args(argc, argv);
- loader_open_abort(0);
- loader_open_abort(1);
- loader_open_abort(2);
+ test_loader_create_close(0);
+ test_loader_create_close(1);
+ test_loader_create_close(2);
return 0;
}
diff --git a/storage/tokudb/ft-index/src/tests/loader-create-commit-nproc-limit.cc b/storage/tokudb/ft-index/src/tests/loader-create-commit-nproc-limit.cc
new file mode 100644
index 00000000000..091809a8551
--- /dev/null
+++ b/storage/tokudb/ft-index/src/tests/loader-create-commit-nproc-limit.cc
@@ -0,0 +1,211 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
+/*
+COPYING CONDITIONS NOTICE:
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation, and provided that the
+ following conditions are met:
+
+ * Redistributions of source code must retain this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below).
+
+ * Redistributions in binary form must reproduce this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below) in the documentation and/or other materials
+ provided with the distribution.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+COPYRIGHT NOTICE:
+
+ TokuDB, Tokutek Fractal Tree Indexing Library.
+ Copyright (C) 2007-2013 Tokutek, Inc.
+
+DISCLAIMER:
+
+ 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.
+
+UNIVERSITY PATENT NOTICE:
+
+ The technology is licensed by the Massachusetts Institute of
+ Technology, Rutgers State University of New Jersey, and the Research
+ Foundation of State University of New York at Stony Brook under
+ United States of America Serial No. 11/760379 and to the patents
+ and/or patent applications resulting from it.
+
+PATENT MARKING NOTICE:
+
+ This software is covered by US Patent No. 8,185,551.
+ This software is covered by US Patent No. 8,489,638.
+
+PATENT RIGHTS GRANT:
+
+ "THIS IMPLEMENTATION" means the copyrightable works distributed by
+ Tokutek as part of the Fractal Tree project.
+
+ "PATENT CLAIMS" means the claims of patents that are owned or
+ licensable by Tokutek, both currently or in the future; and that in
+ the absence of this license would be infringed by THIS
+ IMPLEMENTATION or by using or running THIS IMPLEMENTATION.
+
+ "PATENT CHALLENGE" shall mean a challenge to the validity,
+ patentability, enforceability and/or non-infringement of any of the
+ PATENT CLAIMS or otherwise opposing any of the PATENT CLAIMS.
+
+ Tokutek hereby grants to you, for the term and geographical scope of
+ the PATENT CLAIMS, a non-exclusive, no-charge, royalty-free,
+ irrevocable (except as stated in this section) patent license to
+ make, have made, use, offer to sell, sell, import, transfer, and
+ otherwise run, modify, and propagate the contents of THIS
+ IMPLEMENTATION, where such license applies only to the PATENT
+ CLAIMS. This grant does not include claims that would be infringed
+ only as a consequence of further modifications of THIS
+ IMPLEMENTATION. If you or your agent or licensee institute or order
+ or agree to the institution of patent litigation against any entity
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
+ THIS IMPLEMENTATION constitutes direct or contributory patent
+ infringement, or inducement of patent infringement, then any rights
+ granted to you under this License shall terminate as of the date
+ such litigation is filed. If you or your agent or exclusive
+ licensee institute or order or agree to the institution of a PATENT
+ CHALLENGE, then Tokutek may terminate any rights granted to you
+ under this License.
+*/
+
+#ident "Copyright (c) 2010-2013 Tokutek Inc. All rights reserved."
+#ident "$Id$"
+
+// This test crashes if a failed loader creation causes the db to be corrupted by unlinking
+// the underlying fractal tree files. This unlinking occurs because the txn that logs the
+// load log entries is committed rather than aborted.
+
+#include "test.h"
+#include <db.h>
+#include <sys/resource.h>
+
+static int loader_flags = 0;
+static const char *envdir = TOKU_TEST_FILENAME;
+
+static void run_test(int ndb) {
+ int r;
+
+ char rmcmd[32 + strlen(envdir)];
+ snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", envdir);
+ r = system(rmcmd); CKERR(r);
+ r = toku_os_mkdir(envdir, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
+
+ DB_ENV *env;
+ r = db_env_create(&env, 0); CKERR(r);
+ int envflags = DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_CREATE | DB_PRIVATE;
+ r = env->open(env, envdir, envflags, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
+ env->set_errfile(env, stderr);
+
+ DB *dbs[ndb];
+ uint32_t db_flags[ndb];
+ uint32_t dbt_flags[ndb];
+ for (int i = 0; i < ndb; i++) {
+ db_flags[i] = DB_NOOVERWRITE;
+ dbt_flags[i] = 0;
+ r = db_create(&dbs[i], env, 0); CKERR(r);
+ char name[32];
+ sprintf(name, "db%d", i);
+ r = dbs[i]->open(dbs[i], NULL, name, NULL, DB_BTREE, DB_CREATE, 0666); CKERR(r);
+ }
+
+ DB_TXN *txn;
+ r = env->txn_begin(env, NULL, &txn, 0); CKERR(r);
+
+ struct rlimit current_nproc_limit;
+ r = getrlimit(RLIMIT_NPROC, &current_nproc_limit);
+ assert(r == 0);
+
+ struct rlimit new_nproc_limit = current_nproc_limit;
+ new_nproc_limit.rlim_cur = 0;
+ r = setrlimit(RLIMIT_NPROC, &new_nproc_limit);
+ assert(r == 0);
+
+ DB_LOADER *loader;
+ int loader_r = env->create_loader(env, txn, &loader, ndb > 0 ? dbs[0] : NULL, ndb, dbs, db_flags, dbt_flags, loader_flags);
+
+ r = setrlimit(RLIMIT_NPROC, &current_nproc_limit);
+ assert(r == 0);
+
+ if (loader_flags & LOADER_DISALLOW_PUTS) {
+ CKERR(loader_r);
+ loader_r = loader->close(loader);
+ CKERR(loader_r);
+ } else {
+ CKERR2(loader_r, EAGAIN);
+ }
+
+ r = txn->commit(txn, 0); CKERR(r);
+
+ for (int i = 0; i < ndb; i++) {
+ r = dbs[i]->close(dbs[i], 0); CKERR(r);
+ }
+
+ for (int i = 0; i < ndb; i++) {
+ r = db_create(&dbs[i], env, 0); CKERR(r);
+ char name[32];
+ sprintf(name, "db%d", i);
+ r = dbs[i]->open(dbs[i], NULL, name, NULL, DB_BTREE, 0, 0666); CKERR(r);
+ }
+
+ for (int i = 0; i < ndb; i++) {
+ r = dbs[i]->close(dbs[i], 0); CKERR(r);
+ }
+
+ r = env->close(env, 0); CKERR(r);
+}
+
+static void do_args(int argc, char * const argv[]) {
+ int resultcode;
+ char *cmd = argv[0];
+ argc--; argv++;
+ while (argc>0) {
+ if (strcmp(argv[0], "-h")==0) {
+ resultcode=0;
+ do_usage:
+ fprintf(stderr, "Usage: %s -h -v -q -p\n", cmd);
+ exit(resultcode);
+ } else if (strcmp(argv[0], "-v")==0) {
+ verbose++;
+ } else if (strcmp(argv[0],"-q")==0) {
+ verbose--;
+ if (verbose<0) verbose=0;
+ } else if (strcmp(argv[0], "-p") == 0) {
+ loader_flags |= LOADER_DISALLOW_PUTS;
+ } else if (strcmp(argv[0], "-z") == 0) {
+ loader_flags |= LOADER_COMPRESS_INTERMEDIATES;
+ } else if (strcmp(argv[0], "-e") == 0) {
+ argc--; argv++;
+ if (argc > 0)
+ envdir = argv[0];
+ } else {
+ fprintf(stderr, "Unknown arg: %s\n", argv[0]);
+ resultcode=1;
+ goto do_usage;
+ }
+ argc--;
+ argv++;
+ }
+}
+
+int test_main(int argc, char * const *argv) {
+ do_args(argc, argv);
+ run_test(1);
+ return 0;
+}
diff --git a/storage/tokudb/ft-index/src/tests/loader-create-nproc-limit.cc b/storage/tokudb/ft-index/src/tests/loader-create-nproc-limit.cc
new file mode 100644
index 00000000000..7a61fce7799
--- /dev/null
+++ b/storage/tokudb/ft-index/src/tests/loader-create-nproc-limit.cc
@@ -0,0 +1,199 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
+/*
+COPYING CONDITIONS NOTICE:
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation, and provided that the
+ following conditions are met:
+
+ * Redistributions of source code must retain this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below).
+
+ * Redistributions in binary form must reproduce this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below) in the documentation and/or other materials
+ provided with the distribution.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+COPYRIGHT NOTICE:
+
+ TokuDB, Tokutek Fractal Tree Indexing Library.
+ Copyright (C) 2007-2013 Tokutek, Inc.
+
+DISCLAIMER:
+
+ 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.
+
+UNIVERSITY PATENT NOTICE:
+
+ The technology is licensed by the Massachusetts Institute of
+ Technology, Rutgers State University of New Jersey, and the Research
+ Foundation of State University of New York at Stony Brook under
+ United States of America Serial No. 11/760379 and to the patents
+ and/or patent applications resulting from it.
+
+PATENT MARKING NOTICE:
+
+ This software is covered by US Patent No. 8,185,551.
+ This software is covered by US Patent No. 8,489,638.
+
+PATENT RIGHTS GRANT:
+
+ "THIS IMPLEMENTATION" means the copyrightable works distributed by
+ Tokutek as part of the Fractal Tree project.
+
+ "PATENT CLAIMS" means the claims of patents that are owned or
+ licensable by Tokutek, both currently or in the future; and that in
+ the absence of this license would be infringed by THIS
+ IMPLEMENTATION or by using or running THIS IMPLEMENTATION.
+
+ "PATENT CHALLENGE" shall mean a challenge to the validity,
+ patentability, enforceability and/or non-infringement of any of the
+ PATENT CLAIMS or otherwise opposing any of the PATENT CLAIMS.
+
+ Tokutek hereby grants to you, for the term and geographical scope of
+ the PATENT CLAIMS, a non-exclusive, no-charge, royalty-free,
+ irrevocable (except as stated in this section) patent license to
+ make, have made, use, offer to sell, sell, import, transfer, and
+ otherwise run, modify, and propagate the contents of THIS
+ IMPLEMENTATION, where such license applies only to the PATENT
+ CLAIMS. This grant does not include claims that would be infringed
+ only as a consequence of further modifications of THIS
+ IMPLEMENTATION. If you or your agent or licensee institute or order
+ or agree to the institution of patent litigation against any entity
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
+ THIS IMPLEMENTATION constitutes direct or contributory patent
+ infringement, or inducement of patent infringement, then any rights
+ granted to you under this License shall terminate as of the date
+ such litigation is filed. If you or your agent or exclusive
+ licensee institute or order or agree to the institution of a PATENT
+ CHALLENGE, then Tokutek may terminate any rights granted to you
+ under this License.
+*/
+
+// Verify that env->create_loader works correctly (does not crash, does not leak memory, returns the right error code)
+// when the NPROC limit is exceeded.
+
+#ident "Copyright (c) 2010-2013 Tokutek Inc. All rights reserved."
+#ident "$Id$"
+
+#include "test.h"
+#include <db.h>
+#include <sys/resource.h>
+
+static int loader_flags = 0;
+static const char *envdir = TOKU_TEST_FILENAME;
+
+static void run_test(int ndb) {
+ int r;
+
+ char rmcmd[32 + strlen(envdir)];
+ snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", envdir);
+ r = system(rmcmd); CKERR(r);
+ r = toku_os_mkdir(envdir, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
+
+ DB_ENV *env;
+ r = db_env_create(&env, 0); CKERR(r);
+ int envflags = DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_CREATE | DB_PRIVATE;
+ r = env->open(env, envdir, envflags, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
+ env->set_errfile(env, stderr);
+
+ DB *dbs[ndb];
+ uint32_t db_flags[ndb];
+ uint32_t dbt_flags[ndb];
+ for (int i = 0; i < ndb; i++) {
+ db_flags[i] = DB_NOOVERWRITE;
+ dbt_flags[i] = 0;
+ r = db_create(&dbs[i], env, 0); CKERR(r);
+ char name[32];
+ sprintf(name, "db%d", i);
+ r = dbs[i]->open(dbs[i], NULL, name, NULL, DB_BTREE, DB_CREATE, 0666); CKERR(r);
+ }
+
+ DB_TXN *txn;
+ r = env->txn_begin(env, NULL, &txn, 0); CKERR(r);
+
+ struct rlimit current_nproc_limit;
+ r = getrlimit(RLIMIT_NPROC, &current_nproc_limit);
+ assert(r == 0);
+
+ struct rlimit new_nproc_limit = current_nproc_limit;
+ new_nproc_limit.rlim_cur = 0;
+ r = setrlimit(RLIMIT_NPROC, &new_nproc_limit);
+ assert(r == 0);
+
+ DB_LOADER *loader;
+ int loader_r = env->create_loader(env, txn, &loader, ndb > 0 ? dbs[0] : NULL, ndb, dbs, db_flags, dbt_flags, loader_flags);
+
+ r = setrlimit(RLIMIT_NPROC, &current_nproc_limit);
+ assert(r == 0);
+
+ if (loader_flags & LOADER_DISALLOW_PUTS) {
+ CKERR(loader_r);
+ loader_r = loader->close(loader);
+ CKERR(loader_r);
+ } else {
+ CKERR2(loader_r, EAGAIN);
+ }
+
+ r = txn->abort(txn); CKERR(r);
+
+ for (int i = 0; i < ndb; i++) {
+ r = dbs[i]->close(dbs[i], 0); CKERR(r);
+ }
+
+ r = env->close(env, 0); CKERR(r);
+}
+
+static void do_args(int argc, char * const argv[]) {
+ int resultcode;
+ char *cmd = argv[0];
+ argc--; argv++;
+ while (argc>0) {
+ if (strcmp(argv[0], "-h")==0) {
+ resultcode=0;
+ do_usage:
+ fprintf(stderr, "Usage: %s -h -v -q -p\n", cmd);
+ exit(resultcode);
+ } else if (strcmp(argv[0], "-v")==0) {
+ verbose++;
+ } else if (strcmp(argv[0],"-q")==0) {
+ verbose--;
+ if (verbose<0) verbose=0;
+ } else if (strcmp(argv[0], "-p") == 0) {
+ loader_flags |= LOADER_DISALLOW_PUTS;
+ } else if (strcmp(argv[0], "-z") == 0) {
+ loader_flags |= LOADER_COMPRESS_INTERMEDIATES;
+ } else if (strcmp(argv[0], "-e") == 0) {
+ argc--; argv++;
+ if (argc > 0)
+ envdir = argv[0];
+ } else {
+ fprintf(stderr, "Unknown arg: %s\n", argv[0]);
+ resultcode=1;
+ goto do_usage;
+ }
+ argc--;
+ argv++;
+ }
+}
+
+int test_main(int argc, char * const *argv) {
+ do_args(argc, argv);
+ run_test(1);
+ return 0;
+}
diff --git a/storage/tokudb/ft-index/src/tests/test_insert_unique.cc b/storage/tokudb/ft-index/src/tests/test_insert_unique.cc
new file mode 100644
index 00000000000..29439f9d704
--- /dev/null
+++ b/storage/tokudb/ft-index/src/tests/test_insert_unique.cc
@@ -0,0 +1,202 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
+#ident "$Id$"
+/*
+COPYING CONDITIONS NOTICE:
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation, and provided that the
+ following conditions are met:
+
+ * Redistributions of source code must retain this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below).
+
+ * Redistributions in binary form must reproduce this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below) in the documentation and/or other materials
+ provided with the distribution.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+COPYRIGHT NOTICE:
+
+ TokuDB, Tokutek Fractal Tree Indexing Library.
+ Copyright (C) 2007-2013 Tokutek, Inc.
+
+DISCLAIMER:
+
+ 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.
+
+UNIVERSITY PATENT NOTICE:
+
+ The technology is licensed by the Massachusetts Institute of
+ Technology, Rutgers State University of New Jersey, and the Research
+ Foundation of State University of New York at Stony Brook under
+ United States of America Serial No. 11/760379 and to the patents
+ and/or patent applications resulting from it.
+
+PATENT MARKING NOTICE:
+
+ This software is covered by US Patent No. 8,185,551.
+ This software is covered by US Patent No. 8,489,638.
+
+PATENT RIGHTS GRANT:
+
+ "THIS IMPLEMENTATION" means the copyrightable works distributed by
+ Tokutek as part of the Fractal Tree project.
+
+ "PATENT CLAIMS" means the claims of patents that are owned or
+ licensable by Tokutek, both currently or in the future; and that in
+ the absence of this license would be infringed by THIS
+ IMPLEMENTATION or by using or running THIS IMPLEMENTATION.
+
+ "PATENT CHALLENGE" shall mean a challenge to the validity,
+ patentability, enforceability and/or non-infringement of any of the
+ PATENT CLAIMS or otherwise opposing any of the PATENT CLAIMS.
+
+ Tokutek hereby grants to you, for the term and geographical scope of
+ the PATENT CLAIMS, a non-exclusive, no-charge, royalty-free,
+ irrevocable (except as stated in this section) patent license to
+ make, have made, use, offer to sell, sell, import, transfer, and
+ otherwise run, modify, and propagate the contents of THIS
+ IMPLEMENTATION, where such license applies only to the PATENT
+ CLAIMS. This grant does not include claims that would be infringed
+ only as a consequence of further modifications of THIS
+ IMPLEMENTATION. If you or your agent or licensee institute or order
+ or agree to the institution of patent litigation against any entity
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
+ THIS IMPLEMENTATION constitutes direct or contributory patent
+ infringement, or inducement of patent infringement, then any rights
+ granted to you under this License shall terminate as of the date
+ such litigation is filed. If you or your agent or exclusive
+ licensee institute or order or agree to the institution of a PATENT
+ CHALLENGE, then Tokutek may terminate any rights granted to you
+ under this License.
+*/
+
+#ident "Copyright (c) 2007-2013 Tokutek Inc. All rights reserved."
+#ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it."
+/**
+ * Test that unique inserts work correctly. This exercises the rightmost leaf inject optimization.
+ */
+
+#include <portability/toku_random.h>
+
+#include "test.h"
+
+static char random_buf[8];
+static struct random_data random_data;
+
+static void test_simple_unique_insert(DB_ENV *env) {
+ int r;
+ DB *db;
+ r = db_create(&db, env, 0); CKERR(r);
+ r = db->open(db, NULL, "db", NULL, DB_BTREE, DB_CREATE, 0644); CKERR(r);
+
+ DBT key1, key2, key3;
+ dbt_init(&key1, "a", sizeof("a"));
+ dbt_init(&key2, "b", sizeof("b"));
+ dbt_init(&key3, "c", sizeof("c"));
+ r = db->put(db, NULL, &key1, &key1, DB_NOOVERWRITE); CKERR(r);
+ r = db->put(db, NULL, &key1, &key1, DB_NOOVERWRITE); CKERR2(r, DB_KEYEXIST);
+ r = db->put(db, NULL, &key3, &key3, DB_NOOVERWRITE); CKERR(r);
+ r = db->put(db, NULL, &key3, &key3, DB_NOOVERWRITE); CKERR2(r, DB_KEYEXIST);
+ r = db->put(db, NULL, &key2, &key2, DB_NOOVERWRITE); CKERR(r);
+ r = db->put(db, NULL, &key2, &key2, DB_NOOVERWRITE); CKERR2(r, DB_KEYEXIST);
+ // sanity check
+ r = db->put(db, NULL, &key1, &key1, DB_NOOVERWRITE); CKERR2(r, DB_KEYEXIST);
+ r = db->put(db, NULL, &key1, &key3, DB_NOOVERWRITE); CKERR2(r, DB_KEYEXIST);
+
+ r = db->close(db, 0); CKERR(r);
+ r = env->dbremove(env, NULL, "db", NULL, 0); CKERR(r);
+}
+
+static void test_large_sequential_insert_unique(DB_ENV *env) {
+ int r;
+ DB *db;
+ r = db_create(&db, env, 0); CKERR(r);
+
+ // very small nodes/basements to make a taller tree
+ r = db->set_pagesize(db, 8 * 1024); CKERR(r);
+ r = db->set_readpagesize(db, 2 * 1024); CKERR(r);
+ r = db->open(db, NULL, "db", NULL, DB_BTREE, DB_CREATE, 0644); CKERR(r);
+
+ const int val_size = 1024;
+ char *XMALLOC_N(val_size, val_buf);
+ memset(val_buf, 'k', val_size);
+ DBT val;
+ dbt_init(&val, val_buf, val_size);
+
+ // grow a tree to about depth 3, taking sanity checks along the way
+ const int start_num_rows = (64 * 1024 * 1024) / val_size;
+ for (int i = 0; i < start_num_rows; i++) {
+ DBT key;
+ int k = toku_htonl(i);
+ dbt_init(&key, &k, sizeof(k));
+ r = db->put(db, NULL, &key, &val, DB_NOOVERWRITE); CKERR(r);
+ if (i % 50 == 0) {
+ // sanity check - should not be able to insert this key twice in a row
+ r = db->put(db, NULL, &key, &val, DB_NOOVERWRITE); CKERR2(r, DB_KEYEXIST);
+
+ // .. but re-inserting is okay, if we provisionally deleted the row
+ DB_TXN *txn;
+ r = env->txn_begin(env, NULL, &txn, 0); CKERR(r);
+ r = db->del(db, NULL, &key, DB_DELETE_ANY); CKERR(r);
+ r = db->put(db, NULL, &key, &val, DB_NOOVERWRITE); CKERR(r);
+ r = txn->commit(txn, 0); CKERR(r);
+ }
+ if (i > 0 && i % 250 == 0) {
+ // sanity check - unique checks on random keys we already inserted should
+ // fail (exercises middle-of-the-tree checks)
+ for (int check_i = 0; check_i < 4; check_i++) {
+ DBT rand_key;
+ int rand_k = toku_htonl(myrandom_r(&random_data) % i);
+ dbt_init(&rand_key, &rand_k, sizeof(rand_k));
+ r = db->put(db, NULL, &rand_key, &val, DB_NOOVERWRITE); CKERR2(r, DB_KEYEXIST);
+ }
+ }
+ }
+
+ toku_free(val_buf);
+ r = db->close(db, 0); CKERR(r);
+ r = env->dbremove(env, NULL, "db", NULL, 0); CKERR(r);
+}
+
+
+int test_main(int argc, char * const argv[]) {
+ default_parse_args(argc, argv);
+
+ int r;
+ const int envflags = DB_INIT_MPOOL | DB_CREATE | DB_THREAD |
+ DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN | DB_PRIVATE;
+
+ // startup
+ DB_ENV *env;
+ toku_os_recursive_delete(TOKU_TEST_FILENAME);
+ r = toku_os_mkdir(TOKU_TEST_FILENAME, 0755); CKERR(r);
+ r = db_env_create(&env, 0); CKERR(r);
+ r = env->open(env, TOKU_TEST_FILENAME, envflags, 0755);
+
+ r = myinitstate_r(random(), random_buf, 8, &random_data); CKERR(r);
+
+ test_simple_unique_insert(env);
+ test_large_sequential_insert_unique(env);
+
+ // cleanup
+ r = env->close(env, 0); CKERR(r);
+
+ return 0;
+}
+
diff --git a/storage/tokudb/ft-index/src/ydb.cc b/storage/tokudb/ft-index/src/ydb.cc
index a2bb221a40b..df4fd6baf87 100644
--- a/storage/tokudb/ft-index/src/ydb.cc
+++ b/storage/tokudb/ft-index/src/ydb.cc
@@ -1160,6 +1160,7 @@ env_close(DB_ENV * env, uint32_t flags) {
goto panic_and_quit_early;
}
}
+ env_fsync_log_cron_destroy(env);
if (env->i->cachetable) {
toku_cachetable_minicron_shutdown(env->i->cachetable);
if (env->i->logger) {
@@ -1200,7 +1201,6 @@ env_close(DB_ENV * env, uint32_t flags) {
}
env_fs_destroy(env);
- env_fsync_log_cron_destroy(env);
env->i->ltm.destroy();
if (env->i->data_dir)
toku_free(env->i->data_dir);
@@ -2901,7 +2901,13 @@ env_dbremove(DB_ENV * env, DB_TXN *txn, const char *fname, const char *dbname, u
r = toku_db_create(&db, env, 0);
lazy_assert_zero(r);
r = toku_db_open_iname(db, txn, iname, 0, 0);
- lazy_assert_zero(r);
+ if (txn && r) {
+ if (r == EMFILE || r == ENFILE)
+ r = toku_ydb_do_error(env, r, "toku dbremove failed because open file limit reached\n");
+ else
+ r = toku_ydb_do_error(env, r, "toku dbremove failed\n");
+ goto exit;
+ }
if (txn) {
// Now that we have a writelock on dname, verify that there are still no handles open. (to prevent race conditions)
if (env_is_db_with_dname_open(env, dname)) {
diff --git a/storage/tokudb/ft-index/src/ydb_db.cc b/storage/tokudb/ft-index/src/ydb_db.cc
index 78e08705ac6..b9fa32eb4a0 100644
--- a/storage/tokudb/ft-index/src/ydb_db.cc
+++ b/storage/tokudb/ft-index/src/ydb_db.cc
@@ -1221,36 +1221,14 @@ load_inames(DB_ENV * env, DB_TXN * txn, int N, DB * dbs[/*N*/], const char * new
int
locked_load_inames(DB_ENV * env, DB_TXN * txn, int N, DB * dbs[/*N*/], char * new_inames_in_env[/*N*/], LSN *load_lsn, bool mark_as_loader) {
- int ret, r;
+ int r;
HANDLE_READ_ONLY_TXN(txn);
- DB_TXN *child_txn = NULL;
- int using_txns = env->i->open_flags & DB_INIT_TXN;
- if (using_txns) {
- ret = toku_txn_begin(env, txn, &child_txn, 0);
- invariant_zero(ret);
- }
-
// cannot begin a checkpoint
toku_multi_operation_client_lock();
- r = load_inames(env, child_txn, N, dbs, (const char **) new_inames_in_env, load_lsn, mark_as_loader);
+ r = load_inames(env, txn, N, dbs, (const char **) new_inames_in_env, load_lsn, mark_as_loader);
toku_multi_operation_client_unlock();
- if (using_txns) {
- if (r == 0) {
- ret = locked_txn_commit(child_txn, DB_TXN_NOSYNC);
- invariant_zero(ret);
- } else {
- ret = locked_txn_abort(child_txn);
- invariant_zero(ret);
- for (int i = 0; i < N; i++) {
- if (new_inames_in_env[i]) {
- toku_free(new_inames_in_env[i]);
- new_inames_in_env[i] = NULL;
- }
- }
- }
- }
return r;
}
diff --git a/storage/tokudb/ft-index/src/ydb_write.cc b/storage/tokudb/ft-index/src/ydb_write.cc
index 4826e418ab5..82fbf439885 100644
--- a/storage/tokudb/ft-index/src/ydb_write.cc
+++ b/storage/tokudb/ft-index/src/ydb_write.cc
@@ -253,6 +253,30 @@ toku_db_del(DB *db, DB_TXN *txn, DBT *key, uint32_t flags, bool holds_mo_lock) {
return r;
}
+static int
+db_put(DB *db, DB_TXN *txn, DBT *key, DBT *val, int flags, bool do_log) {
+ int r = 0;
+ bool unique = false;
+ enum ft_msg_type type = FT_INSERT;
+ if (flags == DB_NOOVERWRITE) {
+ unique = true;
+ } else if (flags == DB_NOOVERWRITE_NO_ERROR) {
+ type = FT_INSERT_NO_OVERWRITE;
+ } else if (flags != 0) {
+ // All other non-zero flags are unsupported
+ r = EINVAL;
+ }
+ if (r == 0) {
+ TOKUTXN ttxn = txn ? db_txn_struct_i(txn)->tokutxn : nullptr;
+ if (unique) {
+ r = toku_ft_insert_unique(db->i->ft_handle, key, val, ttxn, do_log);
+ } else {
+ toku_ft_maybe_insert(db->i->ft_handle, key, val, ttxn, false, ZERO_LSN, do_log, type);
+ }
+ invariant(r == DB_KEYEXIST || r == 0);
+ }
+ return r;
+}
int
toku_db_put(DB *db, DB_TXN *txn, DBT *key, DBT *val, uint32_t flags, bool holds_mo_lock) {
@@ -265,25 +289,16 @@ toku_db_put(DB *db, DB_TXN *txn, DBT *key, DBT *val, uint32_t flags, bool holds_
flags &= ~lock_flags;
r = db_put_check_size_constraints(db, key, val);
- if (r == 0) {
- //Do any checking required by the flags.
- r = db_put_check_overwrite_constraint(db, txn, key, lock_flags, flags);
- }
- //Do locking if necessary. Do not grab the lock again if this DB had a unique
- //check performed because the lock was already grabbed by its cursor callback.
+
+ //Do locking if necessary.
bool do_locking = (bool)(db->i->lt && !(lock_flags&DB_PRELOCKED_WRITE));
- if (r == 0 && do_locking && !(flags & DB_NOOVERWRITE)) {
+ if (r == 0 && do_locking) {
r = toku_db_get_point_write_lock(db, txn, key);
}
if (r == 0) {
//Insert into the ft.
- TOKUTXN ttxn = txn ? db_txn_struct_i(txn)->tokutxn : NULL;
- enum ft_msg_type type = FT_INSERT;
- if (flags==DB_NOOVERWRITE_NO_ERROR) {
- type = FT_INSERT_NO_OVERWRITE;
- }
if (!holds_mo_lock) toku_multi_operation_client_lock();
- toku_ft_maybe_insert(db->i->ft_handle, key, val, ttxn, false, ZERO_LSN, true, type);
+ r = db_put(db, txn, key, val, flags, true);
if (!holds_mo_lock) toku_multi_operation_client_unlock();
}
@@ -635,9 +650,11 @@ log_put_multiple(DB_TXN *txn, DB *src_db, const DBT *src_key, const DBT *src_val
}
}
+// Requires: If remaining_flags is non-null, this function performs any required uniqueness checks
+// Otherwise, the caller is responsible.
static int
-do_put_multiple(DB_TXN *txn, uint32_t num_dbs, DB *db_array[], DBT_ARRAY keys[], DBT_ARRAY vals[], DB *src_db, const DBT *src_key, bool indexer_shortcut) {
- TOKUTXN ttxn = db_txn_struct_i(txn)->tokutxn;
+do_put_multiple(DB_TXN *txn, uint32_t num_dbs, DB *db_array[], DBT_ARRAY keys[], DBT_ARRAY vals[], uint32_t *remaining_flags, DB *src_db, const DBT *src_key, bool indexer_shortcut) {
+ int r = 0;
for (uint32_t which_db = 0; which_db < num_dbs; which_db++) {
DB *db = db_array[which_db];
@@ -666,16 +683,21 @@ do_put_multiple(DB_TXN *txn, uint32_t num_dbs, DB *db_array[], DBT_ARRAY keys[],
}
if (do_put) {
for (uint32_t i = 0; i < keys[which_db].size; i++) {
- // if db is being indexed by an indexer, then put into that db if the src key is to the left or equal to the
- // indexers cursor. we have to get the src_db from the indexer and find it in the db_array.
- toku_ft_maybe_insert(db->i->ft_handle,
- &keys[which_db].dbts[i], &vals[which_db].dbts[i],
- ttxn, false, ZERO_LSN, false, FT_INSERT);
+ int flags = 0;
+ if (remaining_flags != nullptr) {
+ flags = remaining_flags[which_db];
+ invariant(!(flags & DB_NOOVERWRITE_NO_ERROR));
+ }
+ r = db_put(db, txn, &keys[which_db].dbts[i], &vals[which_db].dbts[i], flags, false);
+ if (r != 0) {
+ goto done;
+ }
}
}
}
}
- return 0;
+done:
+ return r;
}
static int
@@ -754,20 +776,14 @@ env_put_multiple_internal(
r = db_put_check_size_constraints(db, &put_key, &put_val);
if (r != 0) goto cleanup;
- //Check overwrite constraints
- r = db_put_check_overwrite_constraint(db, txn,
- &put_key,
- lock_flags[which_db], remaining_flags[which_db]);
- if (r != 0) goto cleanup;
if (remaining_flags[which_db] == DB_NOOVERWRITE_NO_ERROR) {
//put_multiple does not support delaying the no error, since we would
//have to log the flag in the put_multiple.
r = EINVAL; goto cleanup;
}
- //Do locking if necessary. Do not grab the lock again if this DB had a unique
- //check performed because the lock was already grabbed by its cursor callback.
- if (db->i->lt && !(lock_flags[which_db] & DB_PRELOCKED_WRITE) && !(remaining_flags[which_db] & DB_NOOVERWRITE)) {
+ //Do locking if necessary.
+ if (db->i->lt && !(lock_flags[which_db] & DB_PRELOCKED_WRITE)) {
//Needs locking
r = toku_db_get_point_write_lock(db, txn, &put_key);
if (r != 0) goto cleanup;
@@ -790,8 +806,10 @@ env_put_multiple_internal(
}
}
toku_multi_operation_client_lock();
- log_put_multiple(txn, src_db, src_key, src_val, num_dbs, fts);
- r = do_put_multiple(txn, num_dbs, db_array, put_keys, put_vals, src_db, src_key, indexer_shortcut);
+ r = do_put_multiple(txn, num_dbs, db_array, put_keys, put_vals, remaining_flags, src_db, src_key, indexer_shortcut);
+ if (r == 0) {
+ log_put_multiple(txn, src_db, src_key, src_val, num_dbs, fts);
+ }
toku_multi_operation_client_unlock();
if (indexer_lock_taken) {
toku_indexer_unlock(indexer);
@@ -1075,7 +1093,7 @@ env_update_multiple(DB_ENV *env, DB *src_db, DB_TXN *txn,
// recovery so we don't end up losing data.
// So unlike env->put_multiple, we ONLY log a 'put_multiple' log entry.
log_put_multiple(txn, src_db, new_src_key, new_src_data, n_put_dbs, put_fts);
- r = do_put_multiple(txn, n_put_dbs, put_dbs, put_key_arrays, put_val_arrays, src_db, new_src_key, indexer_shortcut);
+ r = do_put_multiple(txn, n_put_dbs, put_dbs, put_key_arrays, put_val_arrays, nullptr, src_db, new_src_key, indexer_shortcut);
}
toku_multi_operation_client_unlock();
if (indexer_lock_taken) {
diff --git a/storage/tokudb/ft-index/util/omt.cc b/storage/tokudb/ft-index/util/omt.cc
index 92cda38aefe..709c7eab4c3 100644
--- a/storage/tokudb/ft-index/util/omt.cc
+++ b/storage/tokudb/ft-index/util/omt.cc
@@ -207,6 +207,9 @@ void omt<omtdata_t, omtdataout_t, supports_marks>::clone(const omt &src) {
src.fill_array_with_subtree_values(&this->d.a.values[0], src.d.t.root);
}
this->d.a.num_values = src.size();
+ if (supports_marks) {
+ this->convert_to_tree();
+ }
}
template<typename omtdata_t, typename omtdataout_t, bool supports_marks>
diff --git a/storage/tokudb/ft-index/util/tests/threadpool-nproc-limit.cc b/storage/tokudb/ft-index/util/tests/threadpool-nproc-limit.cc
new file mode 100644
index 00000000000..f1ba10dad84
--- /dev/null
+++ b/storage/tokudb/ft-index/util/tests/threadpool-nproc-limit.cc
@@ -0,0 +1,171 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
+#ident "$Id$"
+/*
+COPYING CONDITIONS NOTICE:
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation, and provided that the
+ following conditions are met:
+
+ * Redistributions of source code must retain this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below).
+
+ * Redistributions in binary form must reproduce this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below) in the documentation and/or other materials
+ provided with the distribution.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+COPYRIGHT NOTICE:
+
+ TokuDB, Tokutek Fractal Tree Indexing Library.
+ Copyright (C) 2007-2013 Tokutek, Inc.
+
+DISCLAIMER:
+
+ 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.
+
+UNIVERSITY PATENT NOTICE:
+
+ The technology is licensed by the Massachusetts Institute of
+ Technology, Rutgers State University of New Jersey, and the Research
+ Foundation of State University of New York at Stony Brook under
+ United States of America Serial No. 11/760379 and to the patents
+ and/or patent applications resulting from it.
+
+PATENT MARKING NOTICE:
+
+ This software is covered by US Patent No. 8,185,551.
+ This software is covered by US Patent No. 8,489,638.
+
+PATENT RIGHTS GRANT:
+
+ "THIS IMPLEMENTATION" means the copyrightable works distributed by
+ Tokutek as part of the Fractal Tree project.
+
+ "PATENT CLAIMS" means the claims of patents that are owned or
+ licensable by Tokutek, both currently or in the future; and that in
+ the absence of this license would be infringed by THIS
+ IMPLEMENTATION or by using or running THIS IMPLEMENTATION.
+
+ "PATENT CHALLENGE" shall mean a challenge to the validity,
+ patentability, enforceability and/or non-infringement of any of the
+ PATENT CLAIMS or otherwise opposing any of the PATENT CLAIMS.
+
+ Tokutek hereby grants to you, for the term and geographical scope of
+ the PATENT CLAIMS, a non-exclusive, no-charge, royalty-free,
+ irrevocable (except as stated in this section) patent license to
+ make, have made, use, offer to sell, sell, import, transfer, and
+ otherwise run, modify, and propagate the contents of THIS
+ IMPLEMENTATION, where such license applies only to the PATENT
+ CLAIMS. This grant does not include claims that would be infringed
+ only as a consequence of further modifications of THIS
+ IMPLEMENTATION. If you or your agent or licensee institute or order
+ or agree to the institution of patent litigation against any entity
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
+ THIS IMPLEMENTATION constitutes direct or contributory patent
+ infringement, or inducement of patent infringement, then any rights
+ granted to you under this License shall terminate as of the date
+ such litigation is filed. If you or your agent or exclusive
+ licensee institute or order or agree to the institution of a PATENT
+ CHALLENGE, then Tokutek may terminate any rights granted to you
+ under this License.
+*/
+
+#ident "Copyright (c) 2014 Tokutek Inc. All rights reserved."
+
+// this test verifies that the toku thread pool is resilient when hitting the nproc limit.
+
+#include <util/threadpool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/resource.h>
+
+int verbose = 0;
+
+static int usage(void) {
+ fprintf(stderr, "[-q] [-v] [--verbose] (%d)\n", verbose);
+ return 1;
+}
+
+static void *f(void *arg) {
+ return arg;
+}
+
+static int dotest(int the_limit) {
+ if (verbose)
+ fprintf(stderr, "%s:%u %d\n", __FILE__, __LINE__, the_limit);
+ int r;
+ struct toku_thread_pool *pool = nullptr;
+ r = toku_thread_pool_create(&pool, 10);
+ assert(r == 0 && pool != nullptr);
+
+ struct rlimit current_nproc_limit;
+ r = getrlimit(RLIMIT_NPROC, &current_nproc_limit);
+ assert(r == 0);
+
+ struct rlimit new_nproc_limit = current_nproc_limit;
+ new_nproc_limit.rlim_cur = the_limit;
+ r = setrlimit(RLIMIT_NPROC, &new_nproc_limit);
+ assert(r == 0);
+
+ int want_n = 20;
+ int got_n = want_n;
+ r = toku_thread_pool_run(pool, 0, &got_n, f, nullptr);
+ if (r == 0)
+ assert(want_n == got_n);
+ else {
+ assert(r == EWOULDBLOCK);
+ assert(got_n <= want_n);
+ }
+
+ r = setrlimit(RLIMIT_NPROC, &current_nproc_limit);
+ assert(r == 0);
+
+ if (verbose)
+ toku_thread_pool_print(pool, stderr);
+ toku_thread_pool_destroy(&pool);
+ return got_n > 0;
+}
+
+int main(int argc, char *argv[]) {
+ // parse args
+ for (int i = 1; i < argc; i++) {
+ char *arg = argv[i];
+ if (arg[0] != '-')
+ break;
+ if (strcmp(arg, "-v") == 0 || strcmp(arg, "--verbose") == 0) {
+ verbose = verbose+1;
+ continue;
+ }
+ if (strcmp(arg, "-q") == 0) {
+ verbose = verbose > 0 ? verbose-1 : 0;
+ continue;
+ }
+ return usage();
+ }
+ // set increasing nproc limits until the test succeeds in hitting the limit after > 0 threads are created
+ for (int i = 0; 1; i++) {
+ if (dotest(i))
+ break;
+ }
+ return 0;
+}
diff --git a/storage/tokudb/ft-index/util/threadpool.cc b/storage/tokudb/ft-index/util/threadpool.cc
index d6652b7a71c..4f1105d83c2 100644
--- a/storage/tokudb/ft-index/util/threadpool.cc
+++ b/storage/tokudb/ft-index/util/threadpool.cc
@@ -132,13 +132,18 @@ static int
toku_thread_create(struct toku_thread_pool *pool, struct toku_thread **toku_thread_return) {
int r;
struct toku_thread *MALLOC(thread);
- if (thread == NULL) {
+ if (thread == nullptr) {
r = get_error_errno();
} else {
memset(thread, 0, sizeof *thread);
thread->pool = pool;
- toku_cond_init(&thread->wait, NULL);
- r = toku_pthread_create(&thread->tid, NULL, toku_thread_run_internal, thread); resource_assert_zero(r);
+ toku_cond_init(&thread->wait, nullptr);
+ r = toku_pthread_create(&thread->tid, nullptr, toku_thread_run_internal, thread);
+ if (r) {
+ toku_cond_destroy(&thread->wait);
+ toku_free(thread);
+ thread = nullptr;
+ }
*toku_thread_return = thread;
}
return r;
@@ -192,7 +197,7 @@ toku_thread_run_internal(void *arg) {
if (doexit)
break;
toku_thread_pool_lock(pool);
- thread->f = NULL;
+ thread->f = nullptr;
toku_list_push(&pool->free_threads, &thread->free_link);
}
return arg;
@@ -202,13 +207,13 @@ int
toku_thread_pool_create(struct toku_thread_pool **pool_return, int max_threads) {
int r;
struct toku_thread_pool *CALLOC(pool);
- if (pool == NULL) {
+ if (pool == nullptr) {
r = get_error_errno();
} else {
- toku_mutex_init(&pool->lock, NULL);
+ toku_mutex_init(&pool->lock, nullptr);
toku_list_init(&pool->free_threads);
toku_list_init(&pool->all_threads);
- toku_cond_init(&pool->wait_free, NULL);
+ toku_cond_init(&pool->wait_free, nullptr);
pool->cur_threads = 0;
pool->max_threads = max_threads;
*pool_return = pool;
@@ -230,7 +235,7 @@ toku_thread_pool_unlock(struct toku_thread_pool *pool) {
void
toku_thread_pool_destroy(struct toku_thread_pool **poolptr) {
struct toku_thread_pool *pool = *poolptr;
- *poolptr = NULL;
+ *poolptr = nullptr;
// ask the threads to exit
toku_thread_pool_lock(pool);
@@ -260,7 +265,7 @@ toku_thread_pool_destroy(struct toku_thread_pool **poolptr) {
static int
toku_thread_pool_add(struct toku_thread_pool *pool) {
- struct toku_thread *thread = NULL;
+ struct toku_thread *thread = nullptr;
int r = toku_thread_create(pool, &thread);
if (r == 0) {
pool->cur_threads += 1;
@@ -294,7 +299,7 @@ toku_thread_pool_get_one(struct toku_thread_pool *pool, int dowait, struct toku_
struct toku_thread *thread = toku_list_struct(list, struct toku_thread, free_link);
*toku_thread_return = thread;
} else
- *toku_thread_return = NULL;
+ *toku_thread_return = nullptr;
toku_thread_pool_unlock(pool);
return r;
}
diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc
index 27610747a33..5314f86e8ad 100644
--- a/storage/tokudb/ha_tokudb.cc
+++ b/storage/tokudb/ha_tokudb.cc
@@ -120,14 +120,6 @@ extern "C" {
#include "hatoku_defines.h"
#include "hatoku_cmp.h"
-static inline void *thd_data_get(THD *thd, int slot) {
- return thd->ha_data[slot].ha_ptr;
-}
-
-static inline void thd_data_set(THD *thd, int slot, void *data) {
- thd->ha_data[slot].ha_ptr = data;
-}
-
static inline uint get_key_parts(const KEY *key);
#undef PACKAGE
@@ -477,7 +469,6 @@ typedef struct index_read_info {
DBT* orig_key;
} *INDEX_READ_INFO;
-
static int ai_poll_fun(void *extra, float progress) {
LOADER_CONTEXT context = (LOADER_CONTEXT)extra;
if (context->thd->killed) {
@@ -1016,8 +1007,7 @@ static uchar* pack_toku_field_blob(
static int create_tokudb_trx_data_instance(tokudb_trx_data** out_trx) {
int error;
- tokudb_trx_data* trx = NULL;
- trx = (tokudb_trx_data *) tokudb_my_malloc(sizeof(*trx), MYF(MY_ZEROFILL));
+ tokudb_trx_data* trx = (tokudb_trx_data *) tokudb_my_malloc(sizeof(*trx), MYF(MY_ZEROFILL));
if (!trx) {
error = ENOMEM;
goto cleanup;
@@ -1614,8 +1604,7 @@ int ha_tokudb::initialize_share(
DB_TXN* txn = NULL;
bool do_commit = false;
THD* thd = ha_thd();
- tokudb_trx_data *trx = NULL;
- trx = (tokudb_trx_data *) thd_data_get(ha_thd(), tokudb_hton->slot);
+ tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(ha_thd(), tokudb_hton);
if (thd_sql_command(thd) == SQLCOM_CREATE_TABLE && trx && trx->sub_sp_level) {
txn = trx->sub_sp_level;
}
@@ -1727,7 +1716,7 @@ int ha_tokudb::initialize_share(
}
share->ref_length = ref_length;
- error = estimate_num_rows(share->file,&num_rows, txn);
+ error = estimate_num_rows(share->file, &num_rows, txn);
//
// estimate_num_rows should not fail under normal conditions
//
@@ -1937,7 +1926,6 @@ exit:
//
int ha_tokudb::estimate_num_rows(DB* db, uint64_t* num_rows, DB_TXN* txn) {
int error = ENOSYS;
- DBC* crsr = NULL;
bool do_commit = false;
DB_BTREE_STAT64 dict_stats;
DB_TXN* txn_to_use = NULL;
@@ -1951,21 +1939,12 @@ int ha_tokudb::estimate_num_rows(DB* db, uint64_t* num_rows, DB_TXN* txn) {
txn_to_use = txn;
}
- error = db->stat64(
- share->file,
- txn_to_use,
- &dict_stats
- );
+ error = db->stat64(db, txn_to_use, &dict_stats);
if (error) { goto cleanup; }
*num_rows = dict_stats.bt_ndata;
error = 0;
cleanup:
- if (crsr != NULL) {
- int r = crsr->c_close(crsr);
- assert(r==0);
- crsr = NULL;
- }
if (do_commit) {
commit_txn(txn_to_use, 0);
txn_to_use = NULL;
@@ -3271,7 +3250,7 @@ void ha_tokudb::start_bulk_insert(ha_rows rows) {
TOKUDB_HANDLER_DBUG_ENTER("%llu txn %p", (unsigned long long) rows, transaction);
#endif
THD* thd = ha_thd();
- tokudb_trx_data* trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
+ tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);
delay_updating_ai_metadata = true;
ai_metadata_update_required = false;
abort_loader = false;
@@ -3281,7 +3260,7 @@ void ha_tokudb::start_bulk_insert(ha_rows rows) {
num_DBs_locked_in_bulk = true;
lock_count = 0;
- if (share->try_table_lock) {
+ if ((rows == 0 || rows > 1) && share->try_table_lock) {
if (get_prelock_empty(thd) && may_table_be_empty(transaction)) {
if (using_ignore || is_insert_ignore(thd) || thd->lex->duplicates != DUP_ERROR
|| table->s->next_number_key_offset) {
@@ -3340,7 +3319,7 @@ int ha_tokudb::end_bulk_insert(bool abort) {
TOKUDB_HANDLER_DBUG_ENTER("");
int error = 0;
THD* thd = ha_thd();
- tokudb_trx_data* trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
+ tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);
bool using_loader = (loader != NULL);
if (ai_metadata_update_required) {
tokudb_pthread_mutex_lock(&share->mutex);
@@ -3354,10 +3333,10 @@ int ha_tokudb::end_bulk_insert(bool abort) {
if (loader) {
if (!abort_loader && !thd->killed) {
DBUG_EXECUTE_IF("tokudb_end_bulk_insert_sleep", {
- const char *old_proc_info = tokudb_thd_get_proc_info(thd);
+ const char *orig_proc_info = tokudb_thd_get_proc_info(thd);
thd_proc_info(thd, "DBUG sleep");
my_sleep(20000000);
- thd_proc_info(thd, old_proc_info);
+ thd_proc_info(thd, orig_proc_info);
});
error = loader->close(loader);
loader = NULL;
@@ -3374,12 +3353,8 @@ int ha_tokudb::end_bulk_insert(bool abort) {
if (i == primary_key && !share->pk_has_string) {
continue;
}
- error = is_index_unique(
- &is_unique,
- transaction,
- share->key_file[i],
- &table->key_info[i]
- );
+ error = is_index_unique(&is_unique, transaction, share->key_file[i], &table->key_info[i],
+ DB_PRELOCKED_WRITE);
if (error) goto cleanup;
if (!is_unique) {
error = HA_ERR_FOUND_DUPP_KEY;
@@ -3419,6 +3394,7 @@ cleanup:
}
}
trx->stmt_progress.using_loader = false;
+ thd_proc_info(thd, 0);
TOKUDB_HANDLER_DBUG_RETURN(error ? error : loader_error);
}
@@ -3426,7 +3402,7 @@ int ha_tokudb::end_bulk_insert() {
return end_bulk_insert( false );
}
-int ha_tokudb::is_index_unique(bool* is_unique, DB_TXN* txn, DB* db, KEY* key_info) {
+int ha_tokudb::is_index_unique(bool* is_unique, DB_TXN* txn, DB* db, KEY* key_info, int lock_flags) {
int error;
DBC* tmp_cursor1 = NULL;
DBC* tmp_cursor2 = NULL;
@@ -3434,7 +3410,7 @@ int ha_tokudb::is_index_unique(bool* is_unique, DB_TXN* txn, DB* db, KEY* key_in
uint64_t cnt = 0;
char status_msg[MAX_ALIAS_NAME + 200]; //buffer of 200 should be a good upper bound.
THD* thd = ha_thd();
- const char *old_proc_info = tokudb_thd_get_proc_info(thd);
+ const char *orig_proc_info = tokudb_thd_get_proc_info(thd);
memset(&key1, 0, sizeof(key1));
memset(&key2, 0, sizeof(key2));
memset(&val, 0, sizeof(val));
@@ -3442,49 +3418,23 @@ int ha_tokudb::is_index_unique(bool* is_unique, DB_TXN* txn, DB* db, KEY* key_in
memset(&packed_key2, 0, sizeof(packed_key2));
*is_unique = true;
- error = db->cursor(
- db,
- txn,
- &tmp_cursor1,
- DB_SERIALIZABLE
- );
+ error = db->cursor(db, txn, &tmp_cursor1, DB_SERIALIZABLE);
if (error) { goto cleanup; }
- error = db->cursor(
- db,
- txn,
- &tmp_cursor2,
- DB_SERIALIZABLE
- );
+ error = db->cursor(db, txn, &tmp_cursor2, DB_SERIALIZABLE);
if (error) { goto cleanup; }
-
- error = tmp_cursor1->c_get(
- tmp_cursor1,
- &key1,
- &val,
- DB_NEXT
- );
+ error = tmp_cursor1->c_get(tmp_cursor1, &key1, &val, DB_NEXT + lock_flags);
if (error == DB_NOTFOUND) {
*is_unique = true;
error = 0;
goto cleanup;
}
else if (error) { goto cleanup; }
- error = tmp_cursor2->c_get(
- tmp_cursor2,
- &key2,
- &val,
- DB_NEXT
- );
+ error = tmp_cursor2->c_get(tmp_cursor2, &key2, &val, DB_NEXT + lock_flags);
if (error) { goto cleanup; }
- error = tmp_cursor2->c_get(
- tmp_cursor2,
- &key2,
- &val,
- DB_NEXT
- );
+ error = tmp_cursor2->c_get(tmp_cursor2, &key2, &val, DB_NEXT + lock_flags);
if (error == DB_NOTFOUND) {
*is_unique = true;
error = 0;
@@ -3496,59 +3446,25 @@ int ha_tokudb::is_index_unique(bool* is_unique, DB_TXN* txn, DB* db, KEY* key_in
bool has_null1;
bool has_null2;
int cmp;
- place_key_into_mysql_buff(
- key_info,
- table->record[0],
- (uchar *) key1.data + 1
- );
- place_key_into_mysql_buff(
- key_info,
- table->record[1],
- (uchar *) key2.data + 1
- );
+ place_key_into_mysql_buff(key_info, table->record[0], (uchar *) key1.data + 1);
+ place_key_into_mysql_buff(key_info, table->record[1], (uchar *) key2.data + 1);
- create_dbt_key_for_lookup(
- &packed_key1,
- key_info,
- key_buff,
- table->record[0],
- &has_null1
- );
- create_dbt_key_for_lookup(
- &packed_key2,
- key_info,
- key_buff2,
- table->record[1],
- &has_null2
- );
+ create_dbt_key_for_lookup(&packed_key1, key_info, key_buff, table->record[0], &has_null1);
+ create_dbt_key_for_lookup(&packed_key2, key_info, key_buff2, table->record[1], &has_null2);
if (!has_null1 && !has_null2) {
cmp = tokudb_prefix_cmp_dbt_key(db, &packed_key1, &packed_key2);
if (cmp == 0) {
memcpy(key_buff, key1.data, key1.size);
- place_key_into_mysql_buff(
- key_info,
- table->record[0],
- (uchar *) key_buff + 1
- );
+ place_key_into_mysql_buff(key_info, table->record[0], (uchar *) key_buff + 1);
*is_unique = false;
break;
}
}
- error = tmp_cursor1->c_get(
- tmp_cursor1,
- &key1,
- &val,
- DB_NEXT
- );
+ error = tmp_cursor1->c_get(tmp_cursor1, &key1, &val, DB_NEXT + lock_flags);
if (error) { goto cleanup; }
- error = tmp_cursor2->c_get(
- tmp_cursor2,
- &key2,
- &val,
- DB_NEXT
- );
+ error = tmp_cursor2->c_get(tmp_cursor2, &key2, &val, DB_NEXT + lock_flags);
if (error && (error != DB_NOTFOUND)) { goto cleanup; }
cnt++;
@@ -3571,7 +3487,7 @@ int ha_tokudb::is_index_unique(bool* is_unique, DB_TXN* txn, DB* db, KEY* key_in
error = 0;
cleanup:
- thd_proc_info(thd, old_proc_info);
+ thd_proc_info(thd, orig_proc_info);
if (tmp_cursor1) {
tmp_cursor1->c_close(tmp_cursor1);
tmp_cursor1 = NULL;
@@ -4072,7 +3988,7 @@ int ha_tokudb::write_row(uchar * record) {
}
}
- trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
+ trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);
if (!error) {
added_rows++;
trx->stmt_progress.inserted++;
@@ -4129,7 +4045,7 @@ int ha_tokudb::update_row(const uchar * old_row, uchar * new_row) {
THD* thd = ha_thd();
DB_TXN* sub_trans = NULL;
DB_TXN* txn = NULL;
- tokudb_trx_data* trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
+ tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);
uint curr_num_DBs;
LINT_INIT(error);
@@ -4303,7 +4219,7 @@ int ha_tokudb::delete_row(const uchar * record) {
bool has_null;
THD* thd = ha_thd();
uint curr_num_DBs;
- tokudb_trx_data* trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);;
+ tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);;
ha_statistic_increment(&SSV::ha_delete_count);
@@ -4870,7 +4786,7 @@ int ha_tokudb::index_read(uchar * buf, const uchar * key, uint key_len, enum ha_
int error = 0;
uint32_t flags = 0;
THD* thd = ha_thd();
- tokudb_trx_data* trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);;
+ tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);;
struct smart_dbt_info info;
struct index_read_info ir_info;
@@ -5348,7 +5264,7 @@ int ha_tokudb::get_next(uchar* buf, int direction, DBT* key_to_compare, bool do_
int error = 0;
uint32_t flags = SET_PRELOCK_FLAG(0);
THD* thd = ha_thd();
- tokudb_trx_data* trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);;
+ tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);;
bool need_val;
HANDLE_INVALID_CURSOR();
@@ -5501,7 +5417,7 @@ int ha_tokudb::index_first(uchar * buf) {
struct smart_dbt_info info;
uint32_t flags = SET_PRELOCK_FLAG(0);
THD* thd = ha_thd();
- tokudb_trx_data* trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);;
+ tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);;
HANDLE_INVALID_CURSOR();
ha_statistic_increment(&SSV::ha_read_first_count);
@@ -5544,7 +5460,7 @@ int ha_tokudb::index_last(uchar * buf) {
struct smart_dbt_info info;
uint32_t flags = SET_PRELOCK_FLAG(0);
THD* thd = ha_thd();
- tokudb_trx_data* trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);;
+ tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);;
HANDLE_INVALID_CURSOR();
ha_statistic_increment(&SSV::ha_read_last_count);
@@ -5635,7 +5551,7 @@ int ha_tokudb::rnd_next(uchar * buf) {
void ha_tokudb::track_progress(THD* thd) {
- tokudb_trx_data* trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
+ tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);
if (trx) {
ulonglong num_written = trx->stmt_progress.inserted + trx->stmt_progress.updated + trx->stmt_progress.deleted;
bool update_status =
@@ -6225,12 +6141,11 @@ int ha_tokudb::external_lock(THD * thd, int lock_type) {
}
int error = 0;
- tokudb_trx_data *trx = NULL;
- trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
+ tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);
if (!trx) {
error = create_tokudb_trx_data_instance(&trx);
if (error) { goto cleanup; }
- thd_data_set(thd, tokudb_hton->slot, trx);
+ thd_set_ha_data(thd, tokudb_hton, trx);
}
if (trx->all == NULL) {
trx->sp_level = NULL;
@@ -6304,7 +6219,7 @@ int ha_tokudb::start_stmt(THD * thd, thr_lock_type lock_type) {
TOKUDB_HANDLER_TRACE("q %s", thd->query());
int error = 0;
- tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
+ tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);
DBUG_ASSERT(trx);
/*
@@ -6404,7 +6319,7 @@ uint32_t ha_tokudb::get_cursor_isolation_flags(enum thr_lock_type lock_type, THD
lock (if we don't want to use MySQL table locks at all) or add locks
for many tables (like we do when we are using a MERGE handler).
- Tokudb DB changes all WRITE locks to TL_WRITE_ALLOW_WRITE (which
+ TokuDB changes all WRITE locks to TL_WRITE_ALLOW_WRITE (which
signals that we are doing WRITES, but we are still allowing other
reader's and writer's.
@@ -6426,34 +6341,25 @@ THR_LOCK_DATA **ha_tokudb::store_lock(THD * thd, THR_LOCK_DATA ** to, enum thr_l
}
if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
- // if creating a hot index
- if (thd_sql_command(thd)== SQLCOM_CREATE_INDEX && get_create_index_online(thd)) {
- rw_rdlock(&share->num_DBs_lock);
- if (share->num_DBs == (table->s->keys + tokudb_test(hidden_primary_key))) {
- lock_type = TL_WRITE_ALLOW_WRITE;
- }
- lock.type = lock_type;
- rw_unlock(&share->num_DBs_lock);
- }
-
- // 5.5 supports reads concurrent with alter table. just use the default lock type.
-#if MYSQL_VERSION_ID < 50500
- else if (thd_sql_command(thd)== SQLCOM_CREATE_INDEX ||
- thd_sql_command(thd)== SQLCOM_ALTER_TABLE ||
- thd_sql_command(thd)== SQLCOM_DROP_INDEX) {
- // force alter table to lock out other readers
- lock_type = TL_WRITE;
- lock.type = lock_type;
- }
-#endif
- else {
- // If we are not doing a LOCK TABLE, then allow multiple writers
- if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && lock_type <= TL_WRITE) &&
- !thd->in_lock_tables && thd_sql_command(thd) != SQLCOM_TRUNCATE && !thd_tablespace_op(thd)) {
+ enum_sql_command sql_command = (enum_sql_command) thd_sql_command(thd);
+ if (!thd->in_lock_tables) {
+ if (sql_command == SQLCOM_CREATE_INDEX && get_create_index_online(thd)) {
+ // hot indexing
+ rw_rdlock(&share->num_DBs_lock);
+ if (share->num_DBs == (table->s->keys + tokudb_test(hidden_primary_key))) {
+ lock_type = TL_WRITE_ALLOW_WRITE;
+ }
+ rw_unlock(&share->num_DBs_lock);
+ } else if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && lock_type <= TL_WRITE) &&
+ sql_command != SQLCOM_TRUNCATE && !thd_tablespace_op(thd)) {
+ // allow concurrent writes
lock_type = TL_WRITE_ALLOW_WRITE;
+ } else if (sql_command == SQLCOM_OPTIMIZE && lock_type == TL_READ_NO_INSERT) {
+ // hot optimize table
+ lock_type = TL_READ;
}
- lock.type = lock_type;
}
+ lock.type = lock_type;
}
*to++ = &lock;
if (tokudb_debug & TOKUDB_DEBUG_LOCK)
@@ -6909,7 +6815,7 @@ int ha_tokudb::create(const char *name, TABLE * form, HA_CREATE_INFO * create_in
newname = (char *)tokudb_my_malloc(get_max_dict_name_path_length(name),MYF(MY_WME));
if (newname == NULL){ error = ENOMEM; goto cleanup;}
- trx = (tokudb_trx_data *) thd_data_get(ha_thd(), tokudb_hton->slot);
+ trx = (tokudb_trx_data *) thd_get_ha_data(ha_thd(), tokudb_hton);
if (trx && trx->sub_sp_level && thd_sql_command(thd) == SQLCOM_CREATE_TABLE) {
txn = trx->sub_sp_level;
}
@@ -7099,7 +7005,7 @@ int ha_tokudb::delete_or_rename_table (const char* from_name, const char* to_nam
DB_TXN *parent_txn = NULL;
tokudb_trx_data *trx = NULL;
- trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
+ trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);
if (thd_sql_command(ha_thd()) == SQLCOM_CREATE_TABLE && trx && trx->sub_sp_level) {
parent_txn = trx->sub_sp_level;
}
@@ -7540,7 +7446,7 @@ int ha_tokudb::tokudb_add_index(
DBC* tmp_cursor = NULL;
int cursor_ret_val = 0;
DBT curr_pk_key, curr_pk_val;
- THD* thd = ha_thd();
+ THD* thd = ha_thd();
DB_LOADER* loader = NULL;
DB_INDEXER* indexer = NULL;
bool loader_save_space = get_load_save_space(thd);
@@ -7578,7 +7484,7 @@ int ha_tokudb::tokudb_add_index(
//
// status message to be shown in "show process list"
//
- const char *old_proc_info = tokudb_thd_get_proc_info(thd);
+ const char *orig_proc_info = tokudb_thd_get_proc_info(thd);
char status_msg[MAX_ALIAS_NAME + 200]; //buffer of 200 should be a good upper bound.
ulonglong num_processed = 0; //variable that stores number of elements inserted thus far
thd_proc_info(thd, "Adding indexes");
@@ -7804,7 +7710,8 @@ int ha_tokudb::tokudb_add_index(
num_processed++;
if ((num_processed % 1000) == 0) {
- sprintf(status_msg, "Adding indexes: Fetched %llu of about %llu rows, loading of data still remains.", num_processed, (long long unsigned) share->rows);
+ sprintf(status_msg, "Adding indexes: Fetched %llu of about %llu rows, loading of data still remains.",
+ num_processed, (long long unsigned) share->rows);
thd_proc_info(thd, status_msg);
#ifdef HA_TOKUDB_HAS_THD_PROGRESS
@@ -7836,12 +7743,8 @@ int ha_tokudb::tokudb_add_index(
for (uint i = 0; i < num_of_keys; i++, curr_index++) {
if (key_info[i].flags & HA_NOSAME) {
bool is_unique;
- error = is_index_unique(
- &is_unique,
- txn,
- share->key_file[curr_index],
- &key_info[i]
- );
+ error = is_index_unique(&is_unique, txn, share->key_file[curr_index], &key_info[i],
+ creating_hot_index ? 0 : DB_PRELOCKED_WRITE);
if (error) goto cleanup;
if (!is_unique) {
error = HA_ERR_FOUND_DUPP_KEY;
@@ -7899,7 +7802,7 @@ cleanup:
another transaction has accessed the table. \
To add indexes, make sure no transactions touch the table.", share->table_name);
}
- thd_proc_info(thd, old_proc_info);
+ thd_proc_info(thd, orig_proc_info);
TOKUDB_HANDLER_DBUG_RETURN(error ? error : loader_error);
}
@@ -8251,12 +8154,12 @@ void ha_tokudb::cleanup_txn(DB_TXN *txn) {
}
void ha_tokudb::add_to_trx_handler_list() {
- tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(ha_thd(), tokudb_hton->slot);
+ tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(ha_thd(), tokudb_hton);
trx->handlers = list_add(trx->handlers, &trx_handler_list);
}
void ha_tokudb::remove_from_trx_handler_list() {
- tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(ha_thd(), tokudb_hton->slot);
+ tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(ha_thd(), tokudb_hton);
trx->handlers = list_delete(trx->handlers, &trx_handler_list);
}
diff --git a/storage/tokudb/ha_tokudb.h b/storage/tokudb/ha_tokudb.h
index 220ea82f44b..3d7584a308a 100644
--- a/storage/tokudb/ha_tokudb.h
+++ b/storage/tokudb/ha_tokudb.h
@@ -109,15 +109,6 @@ typedef struct loader_context {
ha_tokudb* ha;
} *LOADER_CONTEXT;
-typedef struct hot_optimize_context {
- THD *thd;
- char* write_status_msg;
- ha_tokudb *ha;
- uint progress_stage;
- uint current_table;
- uint num_tables;
-} *HOT_OPTIMIZE_CONTEXT;
-
//
// This object stores table information that is to be shared
// among all ha_tokudb objects.
@@ -475,7 +466,7 @@ private:
);
int create_main_dictionary(const char* name, TABLE* form, DB_TXN* txn, KEY_AND_COL_INFO* kc_info, toku_compression_method compression_method);
void trace_create_table_info(const char *name, TABLE * form);
- int is_index_unique(bool* is_unique, DB_TXN* txn, DB* db, KEY* key_info);
+ int is_index_unique(bool* is_unique, DB_TXN* txn, DB* db, KEY* key_info, int lock_flags);
int is_val_unique(bool* is_unique, uchar* record, KEY* key_info, uint dict_index, DB_TXN* txn);
int do_uniqueness_checks(uchar* record, DB_TXN* txn, THD* thd);
void set_main_dict_put_flags(THD* thd, bool opt_eligible, uint32_t* put_flags);
@@ -804,6 +795,7 @@ private:
void remove_from_trx_handler_list();
private:
+ int do_optimize(THD *thd);
int map_to_handler_error(int error);
};
diff --git a/storage/tokudb/ha_tokudb_admin.cc b/storage/tokudb/ha_tokudb_admin.cc
index 8d202eeda41..100c88a76a8 100644
--- a/storage/tokudb/ha_tokudb_admin.cc
+++ b/storage/tokudb/ha_tokudb_admin.cc
@@ -128,8 +128,15 @@ static int analyze_progress(void *v_extra, uint64_t rows) {
int ha_tokudb::analyze(THD *thd, HA_CHECK_OPT *check_opt) {
TOKUDB_HANDLER_DBUG_ENTER("%s", share->table_name);
+ const char *orig_proc_info = tokudb_thd_get_proc_info(thd);
uint64_t rec_per_key[table_share->key_parts];
int result = HA_ADMIN_OK;
+
+ // stub out analyze if optimize is remapped to alter recreate + analyze
+ if (thd_sql_command(thd) != SQLCOM_ANALYZE) {
+ TOKUDB_HANDLER_DBUG_RETURN(result);
+ }
+
DB_TXN *txn = transaction;
if (!txn) {
result = HA_ADMIN_FAILED;
@@ -168,9 +175,19 @@ int ha_tokudb::analyze(THD *thd, HA_CHECK_OPT *check_opt) {
if (error)
result = HA_ADMIN_FAILED;
}
+ thd_proc_info(thd, orig_proc_info);
TOKUDB_HANDLER_DBUG_RETURN(result);
}
+typedef struct hot_optimize_context {
+ THD *thd;
+ char* write_status_msg;
+ ha_tokudb *ha;
+ uint progress_stage;
+ uint current_table;
+ uint num_tables;
+} *HOT_OPTIMIZE_CONTEXT;
+
static int hot_poll_fun(void *extra, float progress) {
HOT_OPTIMIZE_CONTEXT context = (HOT_OPTIMIZE_CONTEXT)extra;
if (context->thd->killed) {
@@ -194,9 +211,9 @@ static int hot_poll_fun(void *extra, float progress) {
}
// flatten all DB's in this table, to do so, peform hot optimize on each db
-int ha_tokudb::optimize(THD * thd, HA_CHECK_OPT * check_opt) {
+int ha_tokudb::do_optimize(THD *thd) {
TOKUDB_HANDLER_DBUG_ENTER("%s", share->table_name);
-
+ const char *orig_proc_info = tokudb_thd_get_proc_info(thd);
int error;
uint curr_num_DBs = table->s->keys + tokudb_test(hidden_primary_key);
@@ -206,9 +223,7 @@ int ha_tokudb::optimize(THD * thd, HA_CHECK_OPT * check_opt) {
thd_progress_init(thd, curr_num_DBs);
#endif
- //
// for each DB, run optimize and hot_optimize
- //
for (uint i = 0; i < curr_num_DBs; i++) {
DB* db = share->key_file[i];
error = db->optimize(db);
@@ -228,14 +243,24 @@ int ha_tokudb::optimize(THD * thd, HA_CHECK_OPT * check_opt) {
goto cleanup;
}
}
-
error = 0;
-cleanup:
+cleanup:
#ifdef HA_TOKUDB_HAS_THD_PROGRESS
thd_progress_end(thd);
#endif
+ thd_proc_info(thd, orig_proc_info);
+ TOKUDB_HANDLER_DBUG_RETURN(error);
+}
+int ha_tokudb::optimize(THD *thd, HA_CHECK_OPT *check_opt) {
+ TOKUDB_HANDLER_DBUG_ENTER("%s", share->table_name);
+ int error;
+#if TOKU_OPTIMIZE_WITH_RECREATE
+ error = HA_ADMIN_TRY_ALTER;
+#else
+ error = do_optimize(thd);
+#endif
TOKUDB_HANDLER_DBUG_RETURN(error);
}
@@ -266,10 +291,7 @@ static void ha_tokudb_check_info(THD *thd, TABLE *table, const char *msg) {
int ha_tokudb::check(THD *thd, HA_CHECK_OPT *check_opt) {
TOKUDB_HANDLER_DBUG_ENTER("%s", share->table_name);
-
- const char *old_proc_info = tokudb_thd_get_proc_info(thd);
- thd_proc_info(thd, "tokudb::check");
-
+ const char *orig_proc_info = tokudb_thd_get_proc_info(thd);
int result = HA_ADMIN_OK;
int r;
@@ -321,6 +343,6 @@ int ha_tokudb::check(THD *thd, HA_CHECK_OPT *check_opt) {
}
}
}
- thd_proc_info(thd, old_proc_info);
+ thd_proc_info(thd, orig_proc_info);
TOKUDB_HANDLER_DBUG_RETURN(result);
}
diff --git a/storage/tokudb/ha_tokudb_alter_56.cc b/storage/tokudb/ha_tokudb_alter_56.cc
index 93ce40850a7..5062a2ae67b 100644
--- a/storage/tokudb/ha_tokudb_alter_56.cc
+++ b/storage/tokudb/ha_tokudb_alter_56.cc
@@ -122,6 +122,7 @@ public:
expand_varchar_update_needed(false),
expand_fixed_update_needed(false),
expand_blob_update_needed(false),
+ optimize_needed(false),
table_kc_info(NULL),
altered_table_kc_info(NULL) {
}
@@ -141,6 +142,7 @@ public:
bool expand_varchar_update_needed;
bool expand_fixed_update_needed;
bool expand_blob_update_needed;
+ bool optimize_needed;
Dynamic_array<uint> changed_fields;
KEY_AND_COL_INFO *table_kc_info;
KEY_AND_COL_INFO *altered_table_kc_info;
@@ -219,8 +221,10 @@ static bool change_type_is_supported(TABLE *table, TABLE *altered_table, Alter_i
static ulong fix_handler_flags(THD *thd, TABLE *table, TABLE *altered_table, Alter_inplace_info *ha_alter_info) {
ulong handler_flags = ha_alter_info->handler_flags;
+#if 100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100099
// This is automatically supported, hide the flag from later checks
handler_flags &= ~Alter_inplace_info::ALTER_PARTITIONED;
+#endif
// workaround for fill_alter_inplace_info bug (#5193)
// the function erroneously sets the ADD_INDEX and DROP_INDEX flags for a column addition that does not
@@ -437,7 +441,13 @@ enum_alter_inplace_result ha_tokudb::check_if_supported_inplace_alter(TABLE *alt
result = HA_ALTER_INPLACE_EXCLUSIVE_LOCK;
}
}
+ }
+#if TOKU_OPTIMIZE_WITH_RECREATE
+ else if (only_flags(ctx->handler_flags, Alter_inplace_info::RECREATE_TABLE + Alter_inplace_info::ALTER_COLUMN_DEFAULT)) {
+ ctx->optimize_needed = true;
+ result = HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE;
}
+#endif
if (result != HA_ALTER_INPLACE_NOT_SUPPORTED && table->s->null_bytes != altered_table->s->null_bytes &&
(tokudb_debug & TOKUDB_DEBUG_ALTER_TABLE)) {
@@ -520,6 +530,9 @@ bool ha_tokudb::inplace_alter_table(TABLE *altered_table, Alter_inplace_info *ha
if (error == 0 && ctx->reset_card) {
error = tokudb::set_card_from_status(share->status_block, ctx->alter_txn, table->s, altered_table->s);
}
+ if (error == 0 && ctx->optimize_needed) {
+ error = do_optimize(ha_thd());
+ }
#if (50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) || \
(50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799)
@@ -756,7 +769,7 @@ bool ha_tokudb::commit_inplace_alter_table(TABLE *altered_table, Alter_inplace_i
if (!commit) {
// abort the alter transaction NOW so that any alters are rolled back. this allows the following restores to work.
- tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
+ tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);
assert(ctx->alter_txn == trx->stmt);
assert(trx->tokudb_lock_count > 0);
// for partitioned tables, we use a single transaction to do all of the partition changes. the tokudb_lock_count
diff --git a/storage/tokudb/ha_tokudb_alter_common.cc b/storage/tokudb/ha_tokudb_alter_common.cc
index ecef0fb7415..414e8280daf 100644
--- a/storage/tokudb/ha_tokudb_alter_common.cc
+++ b/storage/tokudb/ha_tokudb_alter_common.cc
@@ -814,7 +814,7 @@ int ha_tokudb::write_frm_data(const uchar *frm_data, size_t frm_len) {
if (TOKU_PARTITION_WRITE_FRM_DATA || table->part_info == NULL) {
// write frmdata to status
THD *thd = ha_thd();
- tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
+ tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);
assert(trx);
DB_TXN *txn = trx->stmt; // use alter table transaction
assert(txn);
diff --git a/storage/tokudb/hatoku_defines.h b/storage/tokudb/hatoku_defines.h
index 73e6addb529..d8d8fb479d6 100644
--- a/storage/tokudb/hatoku_defines.h
+++ b/storage/tokudb/hatoku_defines.h
@@ -96,6 +96,10 @@ PATENT RIGHTS GRANT:
#pragma interface /* gcc class implementation */
#endif
+#if !defined(TOKUDB_CHECK_JEMALLOC)
+#define TOKUDB_CHECK_JEMALLOC 1
+#endif
+
#if 100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100099
// mariadb 10.0
#define TOKU_USE_DB_TYPE_TOKUDB 1
@@ -108,6 +112,7 @@ PATENT RIGHTS GRANT:
#define TOKU_INCLUDE_EXTENDED_KEYS 1
#endif
#define TOKU_INCLUDE_OPTION_STRUCTS 1
+#define TOKU_OPTIMIZE_WITH_RECREATE 1
#elif 50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799
// mysql 5.7 with no patches
@@ -130,17 +135,18 @@ PATENT RIGHTS GRANT:
#define TOKU_PARTITION_WRITE_FRM_DATA 0
#else
// mysql 5.6 with tokutek patches
-#define TOKU_USE_DB_TYPE_TOKUDB 1 /* has DB_TYPE_TOKUDB patch */
+#define TOKU_USE_DB_TYPE_TOKUDB 1 // has DB_TYPE_TOKUDB patch
#define TOKU_INCLUDE_ALTER_56 1
-#define TOKU_INCLUDE_ROW_TYPE_COMPRESSION 1 /* has tokudb row format compression patch */
-#define TOKU_INCLUDE_XA 1 /* has patch that fixes TC_LOG_MMAP code */
+#define TOKU_INCLUDE_ROW_TYPE_COMPRESSION 1 // has tokudb row format compression patch
+#define TOKU_INCLUDE_XA 1 // has patch that fixes TC_LOG_MMAP code
#define TOKU_PARTITION_WRITE_FRM_DATA 0
#define TOKU_INCLUDE_WRITE_FRM_DATA 0
-#define TOKU_INCLUDE_UPSERT 1 /* has tokudb upsert patch */
+#define TOKU_INCLUDE_UPSERT 1 // has tokudb upsert patch
#if defined(HTON_SUPPORTS_EXTENDED_KEYS)
#define TOKU_INCLUDE_EXTENDED_KEYS 1
#endif
#endif
+#define TOKU_OPTIMIZE_WITH_RECREATE 1
#elif 50500 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50599
#define TOKU_USE_DB_TYPE_TOKUDB 1
diff --git a/storage/tokudb/hatoku_hton.cc b/storage/tokudb/hatoku_hton.cc
index 2291f2345bb..9e9d90f8c9c 100644
--- a/storage/tokudb/hatoku_hton.cc
+++ b/storage/tokudb/hatoku_hton.cc
@@ -579,9 +579,6 @@ static int tokudb_done_func(void *p) {
toku_global_status_rows = NULL;
my_hash_free(&tokudb_open_tables);
tokudb_pthread_mutex_destroy(&tokudb_mutex);
-#if defined(_WIN64)
- toku_ydb_destroy();
-#endif
TOKUDB_DBUG_RETURN(0);
}
@@ -627,8 +624,7 @@ int tokudb_end(handlerton * hton, ha_panic_function type) {
static int tokudb_close_connection(handlerton * hton, THD * thd) {
int error = 0;
- tokudb_trx_data* trx = NULL;
- trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
+ tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);
if (trx && trx->checkpoint_lock_taken) {
error = db_env->checkpointing_resume(db_env);
}
@@ -692,25 +688,27 @@ static void txn_progress_func(TOKU_TXN_PROGRESS progress, void* extra) {
}
static void commit_txn_with_progress(DB_TXN* txn, uint32_t flags, THD* thd) {
- int r;
+ const char *orig_proc_info = tokudb_thd_get_proc_info(thd);
struct txn_progress_info info;
info.thd = thd;
- r = txn->commit_with_progress(txn, flags, txn_progress_func, &info);
+ int r = txn->commit_with_progress(txn, flags, txn_progress_func, &info);
if (r != 0) {
sql_print_error("tried committing transaction %p and got error code %d", txn, r);
}
assert(r == 0);
+ thd_proc_info(thd, orig_proc_info);
}
static void abort_txn_with_progress(DB_TXN* txn, THD* thd) {
- int r;
+ const char *orig_proc_info = tokudb_thd_get_proc_info(thd);
struct txn_progress_info info;
info.thd = thd;
- r = txn->abort_with_progress(txn, txn_progress_func, &info);
+ int r = txn->abort_with_progress(txn, txn_progress_func, &info);
if (r != 0) {
sql_print_error("tried aborting transaction %p and got error code %d", txn, r);
}
assert(r == 0);
+ thd_proc_info(thd, orig_proc_info);
}
static void tokudb_cleanup_handlers(tokudb_trx_data *trx, DB_TXN *txn) {
@@ -726,7 +724,7 @@ static int tokudb_commit(handlerton * hton, THD * thd, bool all) {
TOKUDB_DBUG_ENTER("");
DBUG_PRINT("trans", ("ending transaction %s", all ? "all" : "stmt"));
uint32_t syncflag = THDVAR(thd, commit_sync) ? 0 : DB_TXN_NOSYNC;
- tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(thd, hton->slot);
+ tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton);
DB_TXN **txn = all ? &trx->all : &trx->stmt;
DB_TXN *this_txn = *txn;
if (this_txn) {
@@ -755,7 +753,7 @@ static int tokudb_commit(handlerton * hton, THD * thd, bool all) {
static int tokudb_rollback(handlerton * hton, THD * thd, bool all) {
TOKUDB_DBUG_ENTER("");
DBUG_PRINT("trans", ("aborting transaction %s", all ? "all" : "stmt"));
- tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(thd, hton->slot);
+ tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton);
DB_TXN **txn = all ? &trx->all : &trx->stmt;
DB_TXN *this_txn = *txn;
if (this_txn) {
@@ -785,7 +783,7 @@ static int tokudb_xa_prepare(handlerton* hton, THD* thd, bool all) {
TOKUDB_DBUG_ENTER("");
int r = 0;
DBUG_PRINT("trans", ("preparing transaction %s", all ? "all" : "stmt"));
- tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(thd, hton->slot);
+ tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton);
DB_TXN* txn = all ? trx->all : trx->stmt;
if (txn) {
if (tokudb_debug & TOKUDB_DEBUG_TXN) {
@@ -864,7 +862,7 @@ static int tokudb_savepoint(handlerton * hton, THD * thd, void *savepoint) {
TOKUDB_DBUG_ENTER("");
int error;
SP_INFO save_info = (SP_INFO)savepoint;
- tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(thd, hton->slot);
+ tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton);
if (thd->in_sub_stmt) {
assert(trx->stmt);
error = txn_begin(db_env, trx->sub_sp_level, &(save_info->txn), DB_INHERIT_ISOLATION, thd);
@@ -895,7 +893,7 @@ static int tokudb_rollback_to_savepoint(handlerton * hton, THD * thd, void *save
DB_TXN* parent = NULL;
DB_TXN* txn_to_rollback = save_info->txn;
- tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(thd, hton->slot);
+ tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton);
parent = txn_to_rollback->parent;
if (!(error = txn_to_rollback->abort(txn_to_rollback))) {
if (save_info->in_sub_stmt) {
@@ -917,7 +915,7 @@ static int tokudb_release_savepoint(handlerton * hton, THD * thd, void *savepoin
DB_TXN* parent = NULL;
DB_TXN* txn_to_commit = save_info->txn;
- tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(thd, hton->slot);
+ tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton);
parent = txn_to_commit->parent;
if (!(error = txn_to_commit->commit(txn_to_commit, 0))) {
if (save_info->in_sub_stmt) {
@@ -974,10 +972,10 @@ static int tokudb_discover3(handlerton *hton, THD* thd, const char *db, const ch
HA_METADATA_KEY curr_key = hatoku_frm_data;
DBT key = {};
DBT value = {};
- bool do_commit;
+ bool do_commit = false;
#if 100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100099
- tokudb_trx_data *trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
+ tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);
if (thd_sql_command(thd) == SQLCOM_CREATE_TABLE && trx && trx->sub_sp_level) {
do_commit = false;
txn = trx->sub_sp_level;
@@ -1132,15 +1130,14 @@ static bool tokudb_show_engine_status(THD * thd, stat_print_fn * stat_print) {
static void tokudb_checkpoint_lock(THD * thd) {
int error;
const char *old_proc_info;
- tokudb_trx_data* trx = NULL;
- trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
+ tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);
if (!trx) {
error = create_tokudb_trx_data_instance(&trx);
//
// can only fail due to memory allocation, so ok to assert
//
assert(!error);
- thd_data_set(thd, tokudb_hton->slot, trx);
+ thd_set_ha_data(thd, tokudb_hton, trx);
}
if (trx->checkpoint_lock_taken) {
@@ -1164,8 +1161,7 @@ cleanup:
static void tokudb_checkpoint_unlock(THD * thd) {
int error;
const char *old_proc_info;
- tokudb_trx_data* trx = NULL;
- trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
+ tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);
if (!trx) {
error = 0;
goto cleanup;
diff --git a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_released.result b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_released.result
index f84be01163f..10431bb812a 100644
--- a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_released.result
+++ b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_released.result
@@ -9,6 +9,7 @@ locks_trx_id locks_mysql_thread_id locks_dname locks_key_left locks_key_right
select * from information_schema.tokudb_lock_waits;
requesting_trx_id blocking_trx_id lock_waits_dname lock_waits_key_left lock_waits_key_right lock_waits_start_time
set autocommit=0;
+set tokudb_prelock_empty=OFF;
insert into t values (1);
set autocommit=0;
insert into t values (1);
@@ -26,7 +27,6 @@ commit;
select * from information_schema.tokudb_locks;
locks_trx_id locks_mysql_thread_id locks_dname locks_key_left locks_key_right
TRX_ID MYSQL_ID ./test/t-main 0001000000 0001000000
-TRX_ID MYSQL_ID ./test/t-main 0001000000 0001000000
select * from information_schema.tokudb_lock_waits;
requesting_trx_id blocking_trx_id lock_waits_dname lock_waits_key_left lock_waits_key_right lock_waits_start_time
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
@@ -38,6 +38,7 @@ locks_trx_id locks_mysql_thread_id locks_dname locks_key_left locks_key_right
select * from information_schema.tokudb_lock_waits;
requesting_trx_id blocking_trx_id lock_waits_dname lock_waits_key_left lock_waits_key_right lock_waits_start_time
set autocommit=0;
+set tokudb_prelock_empty=OFF;
replace into t values (1);
set autocommit=0;
replace into t values (1);
diff --git a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_timeout.result b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_timeout.result
index 1e0668164ff..10e3830506d 100644
--- a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_timeout.result
+++ b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_timeout.result
@@ -9,6 +9,7 @@ locks_trx_id locks_mysql_thread_id locks_dname locks_key_left locks_key_right
select * from information_schema.tokudb_lock_waits;
requesting_trx_id blocking_trx_id lock_waits_dname lock_waits_key_left lock_waits_key_right lock_waits_start_time
set autocommit=0;
+set tokudb_prelock_empty=OFF;
insert into t values (1);
set autocommit=0;
insert into t values (1);
diff --git a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks.result b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks.result
index ad252da448f..9fce0695983 100644
--- a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks.result
+++ b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks.result
@@ -12,7 +12,7 @@ set autocommit=0;
insert into t values (2);
insert into t values (4);
insert into t values (6);
-select * from information_schema.tokudb_locks order by locks_trx_id;
+select * from information_schema.tokudb_locks order by locks_trx_id,locks_key_left;
locks_trx_id locks_mysql_thread_id locks_dname locks_key_left locks_key_right
TRX_ID MYSQL_ID ./test/t-main 0001000000 0001000000
TRX_ID MYSQL_ID ./test/t-main 0003000000 0003000000
diff --git a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks_released.result b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks_released.result
index 21a6b5d308c..c135f3858b4 100644
--- a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks_released.result
+++ b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks_released.result
@@ -6,6 +6,7 @@ set autocommit=0;
select * from information_schema.tokudb_locks;
locks_trx_id locks_mysql_thread_id locks_dname locks_key_left locks_key_right
set autocommit=0;
+set tokudb_prelock_empty=OFF;
insert into t values (1);
set autocommit=0;
insert into t values (1);
@@ -16,7 +17,6 @@ commit;
select * from information_schema.tokudb_locks;
locks_trx_id locks_mysql_thread_id locks_dname locks_key_left locks_key_right
TRX_ID MYSQL_ID ./test/t-main 0001000000 0001000000
-TRX_ID MYSQL_ID ./test/t-main 0001000000 0001000000
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
commit;
select * from information_schema.tokudb_locks;
diff --git a/storage/tokudb/mysql-test/tokudb/r/mvcc-26.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-26.result
index d861a972388..ba5e6ab69f8 100644
--- a/storage/tokudb/mysql-test/tokudb/r/mvcc-26.result
+++ b/storage/tokudb/mysql-test/tokudb/r/mvcc-26.result
@@ -16,6 +16,7 @@ select * from foo;
a
optimize table foo;
Table Op Msg_type Msg_text
+test.foo optimize note Table does not support optimize, doing recreate + analyze instead
test.foo optimize status OK
select * from foo;
a
@@ -27,6 +28,7 @@ a
3
optimize table foo;
Table Op Msg_type Msg_text
+test.foo optimize note Table does not support optimize, doing recreate + analyze instead
test.foo optimize status OK
select * from foo;
a
diff --git a/storage/tokudb/mysql-test/tokudb/r/type_datetime.result b/storage/tokudb/mysql-test/tokudb/r/type_datetime.result
index e6701b0a0b5..82f5ebe9600 100644
--- a/storage/tokudb/mysql-test/tokudb/r/type_datetime.result
+++ b/storage/tokudb/mysql-test/tokudb/r/type_datetime.result
@@ -21,6 +21,7 @@ t
delete from t1 where t > 0;
optimize table t1;
Table Op Msg_type Msg_text
+test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
test.t1 optimize status OK
check table t1;
Table Op Msg_type Msg_text
diff --git a/storage/tokudb/mysql-test/tokudb/r/type_decimal.result b/storage/tokudb/mysql-test/tokudb/r/type_decimal.result
index 647065bdedc..a432927eda2 100644
--- a/storage/tokudb/mysql-test/tokudb/r/type_decimal.result
+++ b/storage/tokudb/mysql-test/tokudb/r/type_decimal.result
@@ -799,10 +799,10 @@ ROUND(qty,3) dps ROUND(qty,dps)
DROP TABLE t1;
SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS '%';
%
-0.012345687012345687012345687012345687012345687012345687012345687012345687000000000
+0.012345687012345687012345687012
SELECT MOD(1, .123456789123456789123456789123456789123456789123456789123456789123456789123456789) AS 'MOD()';
MOD()
-0.012345687012345687012345687012345687012345687012345687012345687012345687000000000
+0.012345687012345687012345687012
create table t1 (f1 decimal(6,6),f2 decimal(6,6) zerofill);
insert into t1 values (-0.123456,0.123456);
select group_concat(f1),group_concat(f2) from t1;
diff --git a/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result b/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result
index 14ff0fbd1ca..3f76f54609f 100644
--- a/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result
+++ b/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result
@@ -704,7 +704,7 @@ select .7777777777777777777777777777777777777 *
777777777777777777.777777777777777777700000000000
select .7777777777777777777777777777777777777 - 0.1;
.7777777777777777777777777777777777777 - 0.1
-0.6777777777777777777777777777777777777
+0.677777777777777777777777777778
select .343434343434343434 + .343434343434343434;
.343434343434343434 + .343434343434343434
0.686868686868686868
@@ -1841,7 +1841,7 @@ Warnings:
Note 1265 Data truncated for column 'c1' at row 4
DESC t2;
Field Type Null Key Default Extra
-c1 decimal(32,30) YES NULL
+c1 decimal(33,30) YES NULL
DROP TABLE t1,t2;
CREATE TABLE t1 (a DECIMAL(30,30));
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
@@ -1852,7 +1852,7 @@ Note 1265 Data truncated for column 'c1' at row 2
Note 1265 Data truncated for column 'c1' at row 3
DESC t2;
Field Type Null Key Default Extra
-c1 decimal(34,0) YES NULL
+c1 decimal(33,30) YES NULL
DROP TABLE t1,t2;
CREATE TABLE t1 (a DECIMAL(30,30));
INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
diff --git a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test
index 6b4e5d88673..3b56660ff83 100644
--- a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test
+++ b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test
@@ -23,6 +23,7 @@ select * from information_schema.tokudb_lock_waits;
connect (conn_a,localhost,root,,);
set autocommit=0;
+set tokudb_prelock_empty=OFF; # disable the bulk loader
insert into t values (1);
connect (conn_b,localhost,root,,);
@@ -72,6 +73,7 @@ select * from information_schema.tokudb_lock_waits;
connect (conn_a,localhost,root,,);
set autocommit=0;
+set tokudb_prelock_empty=OFF; # disable the bulk loader
replace into t values (1);
connect (conn_b,localhost,root,,);
diff --git a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_timeout.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_timeout.test
index ea7eb9a2c89..d7925733a0f 100644
--- a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_timeout.test
+++ b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_timeout.test
@@ -16,6 +16,7 @@ select * from information_schema.tokudb_lock_waits;
connect (conn_a,localhost,root,,);
set autocommit=0;
+set tokudb_prelock_empty=OFF;
insert into t values (1);
connect (conn_b,localhost,root,,);
diff --git a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks.test
index a3745b5471b..e5a67559b1a 100644
--- a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks.test
+++ b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks.test
@@ -29,7 +29,7 @@ insert into t values (6);
# should find 3 locks for 2 transactions
connection default;
replace_column 1 TRX_ID 2 MYSQL_ID;
-eval select * from information_schema.tokudb_locks order by locks_trx_id;
+eval select * from information_schema.tokudb_locks order by locks_trx_id,locks_key_left;
connection conn_a;
commit;
diff --git a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test
index 3a1cf2023da..f2ca9b8ed9c 100644
--- a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test
+++ b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test
@@ -18,20 +18,17 @@ let $default_id=`select connection_id()`;
# should be empty
select * from information_schema.tokudb_locks;
-
connect (conn_a,localhost,root,,);
set autocommit=0;
-let $a_id=`select connection_id()`;
+set tokudb_prelock_empty=OFF; # disable bulk loader
insert into t values (1);
connect (conn_b,localhost,root,,);
set autocommit=0;
-let $b_id=`select connection_id()`;
send insert into t values (1);
-
# should find the presence of a lock on 2nd transaction
connection default;
let $wait_condition= select count(*)=1 from information_schema.processlist where info='insert into t values (1)' and state='update';
diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/lock_uniq_key_empty.result b/storage/tokudb/mysql-test/tokudb_bugs/r/lock_uniq_key_empty.result
index 6966aa24ff8..325aef46afe 100644
--- a/storage/tokudb/mysql-test/tokudb_bugs/r/lock_uniq_key_empty.result
+++ b/storage/tokudb/mysql-test/tokudb_bugs/r/lock_uniq_key_empty.result
@@ -1,6 +1,7 @@
set default_storage_engine=tokudb;
drop table if exists t;
create table t (id int, unique key(id));
+set tokudb_prelock_empty=OFF;
begin;
insert into t values (1);
begin;
@@ -13,6 +14,7 @@ id
2
drop table if exists t;
create table t (id int not null, unique key(id));
+set tokudb_prelock_empty=OFF;
begin;
insert into t values (1);
begin;
diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/optimize_temp_table_tokudb.result b/storage/tokudb/mysql-test/tokudb_bugs/r/optimize_temp_table_tokudb.result
index fe6dba5214e..f3ac15b220d 100644
--- a/storage/tokudb/mysql-test/tokudb_bugs/r/optimize_temp_table_tokudb.result
+++ b/storage/tokudb/mysql-test/tokudb_bugs/r/optimize_temp_table_tokudb.result
@@ -2,5 +2,6 @@ drop table if exists t;
create temporary table t (x int) engine=tokudb;
optimize table t;
Table Op Msg_type Msg_text
+test.t optimize note Table does not support optimize, doing recreate + analyze instead
test.t optimize status OK
drop table t;
diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/lock_uniq_key_empty.test b/storage/tokudb/mysql-test/tokudb_bugs/t/lock_uniq_key_empty.test
index 3f8d7113dff..0a001c2736d 100644
--- a/storage/tokudb/mysql-test/tokudb_bugs/t/lock_uniq_key_empty.test
+++ b/storage/tokudb/mysql-test/tokudb_bugs/t/lock_uniq_key_empty.test
@@ -7,6 +7,7 @@ enable_warnings;
create table t (id int, unique key(id));
connect(c1,localhost,root,,);
+set tokudb_prelock_empty=OFF; # disable the tokudb bulk loader
begin;
insert into t values (1);
connect(c2,localhost,root,,);
@@ -24,6 +25,7 @@ drop table if exists t;
create table t (id int not null, unique key(id));
connect(c1,localhost,root,,);
+set tokudb_prelock_empty=OFF; # disable the tokudb bulk loader
begin;
insert into t values (1);
connect(c2,localhost,root,,);
diff --git a/storage/tokudb/mysql-test/tokudb_mariadb/r/optimize.result b/storage/tokudb/mysql-test/tokudb_mariadb/r/optimize.result
index 5151f2bc895..c32a7d61129 100644
--- a/storage/tokudb/mysql-test/tokudb_mariadb/r/optimize.result
+++ b/storage/tokudb/mysql-test/tokudb_mariadb/r/optimize.result
@@ -9,6 +9,7 @@ a
3
set debug_sync='now SIGNAL go';
Table Op Msg_type Msg_text
+test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
test.t1 optimize status OK
drop table t1;
set debug_sync='reset';
diff --git a/storage/tokudb/scripts/setup.mysql.bash b/storage/tokudb/scripts/setup.mysql.bash
index 6ae604e34c1..85132350289 100755
--- a/storage/tokudb/scripts/setup.mysql.bash
+++ b/storage/tokudb/scripts/setup.mysql.bash
@@ -5,6 +5,39 @@ function usage() {
echo "--mysqlbuild=$mysqlbuild --shutdown=$shutdown --install=$install --startup=$startup"
}
+function download_file() {
+ local file=$1
+ s3get $s3bucket $file $file
+}
+
+function download_tarball() {
+ local tarball=$1
+ if [ ! -f $tarball ] ; then
+ download_file $tarball
+ if [ $? -ne 0 ] ; then test 0 = 1; return; fi
+ fi
+ if [ ! -f $tarball.md5 ] ; then
+ download_file $tarball.md5
+ if [ $? -ne 0 ] ; then test 0 = 1; return; fi
+ fi
+}
+
+function install_tarball() {
+ local basedir=$1; local tarball=$2
+ tar -x -z -f $basedir/$tarball
+ if [ $? -ne 0 ] ; then test 0 = 1; return; fi
+}
+
+function check_md5() {
+ local tarball=$1
+ md5sum --check $tarball.md5
+ if [ $? -ne 0 ] ; then
+ # support jacksum md5 output which is almost the same as md5sum
+ diff -b <(cat $tarball.md5) <(md5sum $tarball)
+ if [ $? -ne 0 ] ; then test 0 = 1; return; fi
+ fi
+}
+
mysqlbuild=
shutdown=1
install=1
@@ -64,30 +97,24 @@ basedir=$PWD
mysqltarball=$mysqlbuild.tar.gz
-if [ -f $mysqlbuild.tar.gz ] ; then
- compression=-z
- mysqltarball=$mysqlbuild.tar.gz
-elif [ -f $mysqlbuild.tar.bz2 ] ; then
- compression=-j
- mysqltarball=$mysqlbuild.tar.bz2
-fi
-
-# get the release
-if [ ! -f $mysqltarball ] ; then
- s3get $s3bucket $mysqltarball $mysqltarball
- if [ $? -ne 0 ] ; then exit 1; fi
-fi
-if [ ! -f $mysqltarball.md5 ] ; then
- s3get $s3bucket $mysqltarball.md5 $mysqltarball.md5
- if [ $? -ne 0 ] ; then exit 1; fi
-fi
+# get the tarball
+download_tarball $mysqltarball
+if [ $? -ne 0 ] ; then exit 1; fi
# check the md5 sum
-md5sum --check $mysqltarball.md5
-if [ $? -ne 0 ] ; then
- # support jacksum md5 output which is almost the same as md5sum
- diff -b <(cat $mysqltarball.md5) <(md5sum $mysqltarball)
- if [ $? -ne 0 ] ; then exit 1; fi
+check_md5 $mysqltarball
+if [ $? -ne 0 ] ; then exit 1; fi
+
+tokudbtarball=""
+if [[ $mysqltarball =~ ^(Percona-Server.*)\.(Linux\.x86_64.*)$ ]] ; then
+ tar tzf $mysqltarball | egrep ha_tokudb.so >/dev/null 2>&1
+ if [ $? -ne 0 ] ; then
+ tokudbtarball=${BASH_REMATCH[1]}.TokuDB.${BASH_REMATCH[2]}
+ download_tarball $tokudbtarball
+ if [ $? -ne 0 ] ; then exit 1; fi
+ check_md5 $tokudbtarball
+ if [ $? -ne 0 ] ; then exit 1; fi
+ fi
fi
# set ldpath
@@ -126,8 +153,14 @@ if [ ! -d $mysqlbuild ] || [ $install -ne 0 ] ; then
rm mysql
if [ -d $mysqlbuild ] ; then $sudo rm -rf $mysqlbuild; fi
- tar -x $compression -f $basedir/$mysqltarball
+ install_tarball $basedir $mysqltarball
if [ $? -ne 0 ] ; then exit 1; fi
+
+ if [ $tokudbtarball ] ; then
+ install_tarball $basedir $tokudbtarball
+ if [ $? -ne 0 ] ; then exit 1; fi
+ fi
+
ln -s $mysqldir /usr/local/mysql
if [ $? -ne 0 ] ; then exit 1; fi
ln -s $mysqldir /usr/local/$mysqlbuild
@@ -180,6 +213,10 @@ if [ $startup -ne 0 ] ; then
else
default_arg="--defaults-file=$defaultsfile"
fi
+ j=/usr/local/mysql/lib/mysql/libjemalloc.so
+ if [ -f $j ] ; then
+ default_arg="$default_arg --malloc-lib=$j"
+ fi
$sudo -b bash -c "$ldpath /usr/local/mysql/bin/mysqld_safe $default_arg $mysqld_args" >/dev/null 2>&1 &
fi
sleep $sleeptime
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 1a8a84a621e..01e79711ada 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -3847,6 +3847,14 @@ innobase_end(
if (innodb_inited) {
+ THD *thd= current_thd;
+ if (thd) { // may be UNINSTALL PLUGIN statement
+ trx_t* trx = thd_to_trx(thd);
+ if (trx) {
+ trx_free_for_mysql(trx);
+ }
+ }
+
srv_fast_shutdown = (ulint) innobase_fast_shutdown;
innodb_inited = 0;
diff --git a/storage/xtradb/os/os0stacktrace.cc b/storage/xtradb/os/os0stacktrace.cc
index 6d5b6781cc1..f7fb1212e5f 100644
--- a/storage/xtradb/os/os0stacktrace.cc
+++ b/storage/xtradb/os/os0stacktrace.cc
@@ -85,7 +85,7 @@ os_stacktrace_print(
caller_address = (void*) uc->uc_mcontext.gregs[REG_RIP] ;
#elif defined(__hppa__)
ucontext_t* uc = (ucontext_t*) ucontext;
- caller_address = (void*) uc->uc_mcontext.sc_iaoq[0] & ~0×3UL ;
+ caller_address = (void*) uc->uc_mcontext.sc_iaoq[0] & ~0x3UL ;
#elif (defined (__ppc__)) || (defined (__powerpc__))
ucontext_t* uc = (ucontext_t*) ucontext;
caller_address = (void*) uc->uc_mcontext.regs->nip ;
diff --git a/storage/xtradb/row/row0sel.cc b/storage/xtradb/row/row0sel.cc
index 67107c34204..fd50e2240b5 100644
--- a/storage/xtradb/row/row0sel.cc
+++ b/storage/xtradb/row/row0sel.cc
@@ -878,16 +878,15 @@ row_sel_get_clust_rec(
if (!node->read_view) {
/* Try to place a lock on the index record */
-
- /* If innodb_locks_unsafe_for_binlog option is used
- or this session is using READ COMMITTED isolation level
- we lock only the record, i.e., next-key locking is
- not used. */
ulint lock_type;
trx_t* trx;
trx = thr_get_trx(thr);
+ /* If innodb_locks_unsafe_for_binlog option is used
+ or this session is using READ COMMITTED or lower isolation level
+ we lock only the record, i.e., next-key locking is
+ not used. */
if (srv_locks_unsafe_for_binlog
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
lock_type = LOCK_REC_NOT_GAP;
@@ -1505,12 +1504,6 @@ rec_loop:
search result set, resulting in the phantom problem. */
if (!consistent_read) {
-
- /* If innodb_locks_unsafe_for_binlog option is used
- or this session is using READ COMMITTED isolation
- level, we lock only the record, i.e., next-key
- locking is not used. */
-
rec_t* next_rec = page_rec_get_next(rec);
ulint lock_type;
trx_t* trx;
@@ -1520,6 +1513,10 @@ rec_loop:
offsets = rec_get_offsets(next_rec, index, offsets,
ULINT_UNDEFINED, &heap);
+ /* If innodb_locks_unsafe_for_binlog option is used
+ or this session is using READ COMMITTED or lower isolation
+ level, we lock only the record, i.e., next-key
+ locking is not used. */
if (srv_locks_unsafe_for_binlog
|| trx->isolation_level
<= TRX_ISO_READ_COMMITTED) {
@@ -1568,12 +1565,6 @@ skip_lock:
if (!consistent_read) {
/* Try to place a lock on the index record */
-
- /* If innodb_locks_unsafe_for_binlog option is used
- or this session is using READ COMMITTED isolation level,
- we lock only the record, i.e., next-key locking is
- not used. */
-
ulint lock_type;
trx_t* trx;
@@ -1582,6 +1573,10 @@ skip_lock:
trx = thr_get_trx(thr);
+ /* If innodb_locks_unsafe_for_binlog option is used
+ or this session is using READ COMMITTED or lower isolation level,
+ we lock only the record, i.e., next-key locking is
+ not used. */
if (srv_locks_unsafe_for_binlog
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
@@ -4228,7 +4223,7 @@ rec_loop:
/* Try to place a lock on the index record */
/* If innodb_locks_unsafe_for_binlog option is used
- or this session is using a READ COMMITTED isolation
+ or this session is using a READ COMMITTED or lower isolation
level we do not lock gaps. Supremum record is really
a gap and therefore we do not set locks there. */
@@ -4379,7 +4374,7 @@ wrong_offs:
/* Try to place a gap lock on the index
record only if innodb_locks_unsafe_for_binlog
option is not set or this session is not
- using a READ COMMITTED isolation level. */
+ using a READ COMMITTED or lower isolation level. */
err = sel_set_rec_lock(
btr_pcur_get_block(pcur),
@@ -4428,7 +4423,7 @@ wrong_offs:
/* Try to place a gap lock on the index
record only if innodb_locks_unsafe_for_binlog
option is not set or this session is not
- using a READ COMMITTED isolation level. */
+ using a READ COMMITTED or lower isolation level. */
err = sel_set_rec_lock(
btr_pcur_get_block(pcur),
diff --git a/strings/CMakeLists.txt b/strings/CMakeLists.txt
index e1cee8d9824..6291d107d90 100644
--- a/strings/CMakeLists.txt
+++ b/strings/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2013, Oracle and/or its affiliates
+# Copyright (c) 2006, 2014, Oracle and/or its affiliates
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -36,7 +36,6 @@ ADD_CONVENIENCE_LIBRARY(strings ${STRINGS_SOURCES})
ADD_EXECUTABLE(conf_to_src EXCLUDE_FROM_ALL conf_to_src.c)
TARGET_LINK_LIBRARIES(conf_to_src strings)
-INSTALL_DEBUG_SYMBOLS(strings)
IF(MSVC)
INSTALL_DEBUG_TARGET(strings DESTINATION ${INSTALL_LIBDIR}/debug)
ENDIF()
diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c
index 6e861f38ae4..4beb7047d00 100644
--- a/strings/ctype-bin.c
+++ b/strings/ctype-bin.c
@@ -1,5 +1,6 @@
/* Copyright (c) 2002-2007 MySQL AB & tommy@valley.ne.jp
- Copyright (c) 2009-2011, Monty Program Ab
+ Copyright (c) 2002, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2014, SkySQL Ab.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/strings/ctype-eucjpms.c b/strings/ctype-eucjpms.c
index d9033a234c4..20972fbe136 100644
--- a/strings/ctype-eucjpms.c
+++ b/strings/ctype-eucjpms.c
@@ -1,5 +1,6 @@
-/* Copyright (c) 2005, 2011, Oracle and/or its affiliates.
- Copyright (c) 2009-2011, Monty Program Ab
+/* Copyright (c) 2002 MySQL AB & tommy@valley.ne.jp
+ Copyright (c) 2002, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2014, SkySQL Ab.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c
index a7f948ebe3a..d2f7d34f0aa 100644
--- a/strings/ctype-ucs2.c
+++ b/strings/ctype-ucs2.c
@@ -2202,10 +2202,10 @@ my_strnncollsp_utf32(CHARSET_INFO *cs,
static uint
my_ismbchar_utf32(CHARSET_INFO *cs __attribute__((unused)),
- const char *b __attribute__((unused)),
- const char *e __attribute__((unused)))
+ const char *b,
+ const char *e)
{
- return 4;
+ return b + 4 > e ? 0 : 4;
}
@@ -3159,10 +3159,10 @@ static int my_strnncollsp_ucs2(CHARSET_INFO *cs __attribute__((unused)),
static uint my_ismbchar_ucs2(CHARSET_INFO *cs __attribute__((unused)),
- const char *b __attribute__((unused)),
- const char *e __attribute__((unused)))
+ const char *b,
+ const char *e)
{
- return 2;
+ return b + 2 > e ? 0 : 2;
}
diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c
index 9a69995b278..a6d9fb96fb1 100644
--- a/strings/ctype-ujis.c
+++ b/strings/ctype-ujis.c
@@ -1,6 +1,6 @@
-/* Copyright tommy@valley.ne.jp.
- Copyright (c) 2002, 2011, Oracle and/or its affiliates.
- Copyright (c) 2009-2011, Monty Program Ab
+/* Copyright (c) 2002 MySQL AB & tommy@valley.ne.jp
+ Copyright (c) 2002, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2014, SkySQL Ab.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt
index 98e1560f5fb..4677bd59415 100644
--- a/support-files/CMakeLists.txt
+++ b/support-files/CMakeLists.txt
@@ -1,5 +1,5 @@
-# Copyright (c) 2006, 2010, Oracle and/or its affiliates.
-# Copyright (c) 2012, Monty Program Ab
+# Copyright (c) 2006, 2014, Oracle and/or its affiliates.
+# Copyright (c) 2012, 2014, SkySQL Ab.
#
# 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
@@ -56,12 +56,14 @@ IF(UNIX)
IF(script MATCHES ".ini")
SET(comp IniFiles)
+ SET(permissions OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
ELSE()
SET(comp Server_Scripts)
+ SET(permissions OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
ENDIF()
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${script}
DESTINATION ${inst_location} COMPONENT ${comp}
- PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+ PERMISSIONS ${permissions})
ENDFOREACH()
IF(INSTALL_SUPPORTFILESDIR)
INSTALL(FILES magic DESTINATION ${inst_location} COMPONENT SupportFiles)
diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh
index a1ee5c4c653..a19f09fc91f 100644
--- a/support-files/mysql.server.sh
+++ b/support-files/mysql.server.sh
@@ -259,6 +259,11 @@ wait_for_ready () {
if $bindir/mysqladmin ping >/dev/null 2>&1; then
log_success_msg
return 0
+ elif kill -0 $! 2>/dev/null ; then
+ : # mysqld_safe is still running
+ else
+ # mysqld_safe is no longer running, abort the wait loop
+ break
fi
echo $echo_n ".$echo_c"
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index d8de3a41e7f..7908e1b5d50 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -30,7 +30,7 @@
%global mysqld_group mysql
%global mysqldatadir /var/lib/mysql
-%global release 1
+%global release 2
#
@@ -511,6 +511,7 @@ mkdir debug
# XXX: install_layout so we can't just set it based on INSTALL_LAYOUT=RPM
${CMAKE} ../%{src_dir} -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM \
-DCMAKE_BUILD_TYPE=Debug \
+ -DENABLE_DTRACE=OFF \
-DMYSQL_UNIX_ADDR="%{mysqldatadir}/mysql.sock" \
-DFEATURE_SET="%{feature_set}" \
-DCOMPILATION_COMMENT="%{compilation_comment_debug}" \
@@ -526,6 +527,7 @@ mkdir release
# XXX: install_layout so we can't just set it based on INSTALL_LAYOUT=RPM
${CMAKE} ../%{src_dir} -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
+ -DENABLE_DTRACE=OFF \
-DMYSQL_UNIX_ADDR="%{mysqldatadir}/mysql.sock" \
-DFEATURE_SET="%{feature_set}" \
-DCOMPILATION_COMMENT="%{compilation_comment_release}" \
@@ -1217,6 +1219,9 @@ echo "=====" >> $STATUS_HISTORY
# merging BK trees)
##############################################################################
%changelog
+* Wed Jul 02 2014 Bjorn Munch <bjorn.munch@oracle.com>
+- Disable dtrace unconditionally, breaks after we install Oracle dtrace
+
* Wed Oct 30 2013 Balasubramanian Kandasamy <balasubramanian.kandasamy@oracle.com>
- Removed non gpl file docs/mysql.info from community packages
diff --git a/vio/CMakeLists.txt b/vio/CMakeLists.txt
index 72059f1ec08..2fb82ef9dd2 100644
--- a/vio/CMakeLists.txt
+++ b/vio/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -21,7 +21,6 @@ SET(VIO_SOURCES vio.c viosocket.c viossl.c viopipe.c vioshm.c viosslfactories.c)
ADD_CONVENIENCE_LIBRARY(vio ${VIO_SOURCES})
TARGET_LINK_LIBRARIES(vio ${LIBSOCKET})
-INSTALL_DEBUG_SYMBOLS(vio)
IF(MSVC)
INSTALL_DEBUG_TARGET(vio DESTINATION ${INSTALL_LIBDIR}/debug)
ENDIF()
diff --git a/zlib/CMakeLists.txt b/zlib/CMakeLists.txt
index 0be1f976b39..7668ce723b8 100644
--- a/zlib/CMakeLists.txt
+++ b/zlib/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -23,7 +23,6 @@ SET(ZLIB_SOURCES adler32.c compress.c crc32.c crc32.h deflate.c deflate.h gzio.
ADD_CONVENIENCE_LIBRARY(zlib ${ZLIB_SOURCES})
RESTRICT_SYMBOL_EXPORTS(zlib)
-INSTALL_DEBUG_SYMBOLS(zlib)
IF(MSVC)
INSTALL_DEBUG_TARGET(zlib DESTINATION ${INSTALL_LIBDIR}/debug)
ENDIF()