summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Nozdrin <alik@sun.com>2010-06-01 16:38:01 +0400
committerAlexander Nozdrin <alik@sun.com>2010-06-01 16:38:01 +0400
commit522d9ac30f3481564ee933aa3f1212fb2992385b (patch)
tree27a04705528c5c8baecb74ee4ea6c6c03fdc56e8
parentce461570ef3c501681bfb68d020a4252f6b51e77 (diff)
parent6962ef4db9f68ba6925f40924d7731bc5a2eca92 (diff)
downloadmariadb-git-522d9ac30f3481564ee933aa3f1212fb2992385b.tar.gz
Auto-merge from mysql-trunk-bugfixing.
Due to a BZR bug, that merge was done by the following command: bzr merge -r 'revid:tor.didriksen@sun.com-20100527074248-6qtv0p1ugy6o1hjo..' <mysql-trunk-bugfixing path>
-rw-r--r--BUILD/Makefile.am2
-rwxr-xr-xBUILD/compile-alpha-ccc41
-rwxr-xr-xBUILD/compile-alpha-cxx43
-rw-r--r--Makefile.am4
-rw-r--r--client/mysql.cc16
-rw-r--r--client/mysqlbinlog.cc4
-rw-r--r--client/sql_string.cc7
-rw-r--r--cmake/os/FreeBSD.cmake9
-rw-r--r--configure.in31
-rw-r--r--include/my_global.h2
-rw-r--r--include/my_pthread.h1
-rw-r--r--include/my_sys.h8
-rw-r--r--include/mysql/plugin.h39
-rw-r--r--include/mysql/plugin.h.pp3
-rw-r--r--include/mysql_com.h10
-rw-r--r--libmysql/Makefile.shared2
-rw-r--r--mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test2
-rw-r--r--mysql-test/extra/rpl_tests/rpl_record_compare.test68
-rwxr-xr-xmysql-test/mysql-test-run.pl1
-rw-r--r--mysql-test/r/archive.result19
-rw-r--r--mysql-test/r/bug46261.result8
-rw-r--r--mysql-test/r/ctype_ucs.result8
-rw-r--r--mysql-test/r/delete.result9
-rw-r--r--mysql-test/r/error_simulation.result23
-rw-r--r--mysql-test/r/errors.result14
-rw-r--r--mysql-test/r/explain.result12
-rw-r--r--mysql-test/r/fulltext.result13
-rw-r--r--mysql-test/r/func_concat.result18
-rw-r--r--mysql-test/r/func_gconcat.result15
-rw-r--r--mysql-test/r/func_str.result14
-rw-r--r--mysql-test/r/gis-rtree.result7
-rw-r--r--mysql-test/r/grant.result16
-rw-r--r--mysql-test/r/group_by.result20
-rw-r--r--mysql-test/r/handler_myisam.result13
-rw-r--r--mysql-test/r/having.result50
-rw-r--r--mysql-test/r/innodb_mysql.result58
-rw-r--r--mysql-test/r/join.result49
-rw-r--r--mysql-test/r/join_outer.result30
-rw-r--r--mysql-test/r/loaddata.result24
-rw-r--r--mysql-test/r/log_state.result33
-rw-r--r--mysql-test/r/mdl_sync.result14
-rw-r--r--mysql-test/r/merge.result7
-rw-r--r--mysql-test/r/myisam.result4
-rw-r--r--mysql-test/r/mysqlbinlog.result75
-rw-r--r--mysql-test/r/mysqld--help-notwin.result1
-rw-r--r--mysql-test/r/mysqld--help-win.result1
-rw-r--r--mysql-test/r/mysqldump.result15
-rw-r--r--mysql-test/r/order_by.result29
-rw-r--r--mysql-test/r/outfile_loaddata.result20
-rw-r--r--mysql-test/r/partition.result11
-rw-r--r--mysql-test/r/ps.result25
-rw-r--r--mysql-test/r/query_cache_with_views.result13
-rw-r--r--mysql-test/r/range.result44
-rw-r--r--mysql-test/r/renamedb.result2
-rw-r--r--mysql-test/r/row.result9
-rw-r--r--mysql-test/r/skip_name_resolve.result27
-rw-r--r--mysql-test/r/subselect.result89
-rw-r--r--mysql-test/r/symlink.result12
-rw-r--r--mysql-test/r/trigger.result38
-rw-r--r--mysql-test/r/type_binary.result2
-rw-r--r--mysql-test/r/type_decimal.result28
-rw-r--r--mysql-test/r/upgrade.result28
-rw-r--r--mysql-test/r/variables.result11
-rw-r--r--mysql-test/r/variables_debug.result15
-rw-r--r--mysql-test/r/view.result8
-rw-r--r--mysql-test/std_data/binlog_savepoint.000001bin0 -> 1014 bytes
-rw-r--r--mysql-test/std_data/bug46565.ARZbin0 -> 8670 bytes
-rw-r--r--mysql-test/std_data/bug46565.frmbin0 -> 8554 bytes
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result12
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result10
-rw-r--r--mysql-test/suite/engines/README12
-rw-r--r--mysql-test/suite/engines/iuds/r/update_delete_calendar.result3
-rw-r--r--mysql-test/suite/engines/iuds/t/disabled.def1
-rw-r--r--mysql-test/suite/engines/iuds/t/insert_number.test3
-rw-r--r--mysql-test/suite/engines/iuds/t/update_delete_calendar.test5
-rw-r--r--mysql-test/suite/parts/r/partition_debug_sync_innodb.result61
-rw-r--r--mysql-test/suite/parts/t/partition_debug_sync_innodb-master.opt1
-rw-r--r--mysql-test/suite/parts/t/partition_debug_sync_innodb.test44
-rw-r--r--mysql-test/suite/rpl/r/rpl_begin_commit_rollback.result68
-rw-r--r--mysql-test/suite/rpl/r/rpl_do_grant.result14
-rw-r--r--mysql-test/suite/rpl/r/rpl_events.result10
-rw-r--r--mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_mixed_mixing_engines.result32
-rw-r--r--mysql-test/suite/rpl/r/rpl_non_direct_mixed_mixing_engines.result32
-rw-r--r--mysql-test/suite/rpl/r/rpl_non_direct_row_mixing_engines.result32
-rw-r--r--mysql-test/suite/rpl/r/rpl_non_direct_stm_mixing_engines.result32
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_mixing_engines.result32
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_rec_comp_innodb.result46
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_rec_comp_myisam.result60
-rw-r--r--mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result52
-rw-r--r--mysql-test/suite/rpl/t/rpl_begin_commit_rollback-master.opt1
-rw-r--r--mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test51
-rw-r--r--mysql-test/suite/rpl/t/rpl_do_grant.test29
-rw-r--r--mysql-test/suite/rpl/t/rpl_events.test6
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_rec_comp_innodb.test10
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_rec_comp_myisam.test31
-rw-r--r--mysql-test/suite/rpl/t/rpl_semi_sync.test4
-rw-r--r--mysql-test/suite/rpl/t/rpl_stm_mixing_engines.test38
-rw-r--r--mysql-test/suite/rpl_ndb/my.cnf4
-rw-r--r--mysql-test/suite/rpl_ndb/r/rpl_ndb_stm_innodb.result1
-rw-r--r--mysql-test/suite/rpl_ndb/t/rpl_ndb_stm_innodb.test4
-rw-r--r--mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_32.result38
-rw-r--r--mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_64.result38
-rw-r--r--mysql-test/suite/sys_vars/r/secure_file_priv.result22
-rw-r--r--mysql-test/suite/sys_vars/r/skip_name_resolve_basic.result23
-rw-r--r--mysql-test/suite/sys_vars/t/secure_file_priv-master.opt1
-rw-r--r--mysql-test/suite/sys_vars/t/secure_file_priv.test21
-rw-r--r--mysql-test/suite/sys_vars/t/secure_file_priv_basic.test2
-rw-r--r--mysql-test/suite/sys_vars/t/skip_name_resolve_basic-master.opt1
-rw-r--r--mysql-test/suite/sys_vars/t/skip_name_resolve_basic.test15
-rw-r--r--mysql-test/t/archive.test23
-rw-r--r--mysql-test/t/bug46261-master.opt1
-rw-r--r--mysql-test/t/bug46261.test16
-rw-r--r--mysql-test/t/ctype_ucs.test9
-rw-r--r--mysql-test/t/delete.test12
-rw-r--r--mysql-test/t/error_simulation.test16
-rw-r--r--mysql-test/t/errors.test15
-rw-r--r--mysql-test/t/explain.test13
-rw-r--r--mysql-test/t/fulltext.test9
-rw-r--r--mysql-test/t/func_concat.test20
-rw-r--r--mysql-test/t/func_gconcat.test12
-rw-r--r--mysql-test/t/func_str.test11
-rw-r--r--mysql-test/t/gis-rtree.test15
-rw-r--r--mysql-test/t/grant.test24
-rw-r--r--mysql-test/t/group_by.test15
-rw-r--r--mysql-test/t/handler_myisam.test11
-rw-r--r--mysql-test/t/having.test45
-rw-r--r--mysql-test/t/innodb_mysql.test60
-rw-r--r--mysql-test/t/join.test45
-rw-r--r--mysql-test/t/join_outer.test23
-rw-r--r--mysql-test/t/loaddata.test25
-rw-r--r--mysql-test/t/log_state.test38
-rw-r--r--mysql-test/t/mdl_sync.test21
-rw-r--r--mysql-test/t/merge.test9
-rw-r--r--mysql-test/t/mysqlbinlog.test11
-rw-r--r--mysql-test/t/mysqldump.test30
-rw-r--r--mysql-test/t/order_by.test24
-rw-r--r--mysql-test/t/outfile_loaddata.test34
-rw-r--r--mysql-test/t/partition.test12
-rw-r--r--mysql-test/t/ps.test14
-rw-r--r--mysql-test/t/query_cache_with_views.test17
-rw-r--r--mysql-test/t/range.test41
-rw-r--r--mysql-test/t/renamedb.test2
-rw-r--r--mysql-test/t/row.test11
-rw-r--r--mysql-test/t/skip_name_resolve.test21
-rw-r--r--mysql-test/t/subselect.test83
-rw-r--r--mysql-test/t/symlink.test22
-rw-r--r--mysql-test/t/trigger.test44
-rw-r--r--mysql-test/t/type_decimal.test41
-rw-r--r--mysql-test/t/upgrade.test34
-rw-r--r--mysql-test/t/variables.test8
-rw-r--r--mysql-test/t/variables_debug.test16
-rw-r--r--mysql-test/t/view.test9
-rwxr-xr-xmysys/CMakeLists.txt2
-rw-r--r--mysys/Makefile.am2
-rw-r--r--mysys/mf_loadpath.c11
-rw-r--r--mysys/mf_pack.c3
-rw-r--r--mysys/my_file.c2
-rw-r--r--mysys/my_getwd.c11
-rw-r--r--mysys/my_init.c2
-rw-r--r--mysys/my_mess.c (renamed from mysys/my_messnc.c)6
-rw-r--r--mysys/my_pthread.c5
-rw-r--r--mysys/my_static.c9
-rw-r--r--plugin/daemon_example/daemon_example.cc3
-rw-r--r--plugin/semisync/semisync_master.cc18
-rw-r--r--scripts/mysqld_safe.sh7
-rw-r--r--scripts/mysqlhotcopy.sh8
-rw-r--r--sql-common/client.c27
-rwxr-xr-xsql/CMakeLists.txt2
-rw-r--r--sql/authors.h1
-rw-r--r--sql/events.cc4
-rw-r--r--sql/field.cc20
-rw-r--r--sql/field.h4
-rw-r--r--sql/field_conv.cc26
-rw-r--r--sql/ha_partition.cc4
-rw-r--r--sql/handler.cc12
-rw-r--r--sql/handler.h2
-rw-r--r--sql/init.cc2
-rw-r--r--sql/item.cc97
-rw-r--r--sql/item.h31
-rw-r--r--sql/item_cmpfunc.cc19
-rw-r--r--sql/item_cmpfunc.h14
-rw-r--r--sql/item_strfunc.cc5
-rw-r--r--sql/item_strfunc.h3
-rw-r--r--sql/item_subselect.cc15
-rw-r--r--sql/item_subselect.h1
-rw-r--r--sql/item_sum.cc2
-rw-r--r--sql/item_sum.h2
-rw-r--r--sql/key.cc10
-rw-r--r--sql/lock.cc14
-rw-r--r--sql/lock.h36
-rw-r--r--sql/log.cc66
-rw-r--r--sql/log.h9
-rw-r--r--sql/log_event.cc111
-rw-r--r--sql/log_event.h28
-rw-r--r--sql/log_event_old.cc36
-rw-r--r--sql/mysqld.cc71
-rw-r--r--sql/mysqld.h2
-rw-r--r--sql/net_serv.cc4
-rw-r--r--sql/opt_range.cc93
-rw-r--r--sql/opt_range.h83
-rw-r--r--sql/opt_sum.cc298
-rw-r--r--sql/partition_info.cc30
-rw-r--r--sql/protocol.cc4
-rw-r--r--sql/slave.cc31
-rw-r--r--sql/sp_head.cc238
-rw-r--r--sql/sp_head.h4
-rw-r--r--sql/sql_acl.cc10
-rw-r--r--sql/sql_base.cc69
-rw-r--r--sql/sql_base.h2
-rw-r--r--sql/sql_class.cc65
-rw-r--r--sql/sql_class.h20
-rw-r--r--sql/sql_connect.cc7
-rw-r--r--sql/sql_const.h6
-rw-r--r--sql/sql_delete.cc7
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_lex.h1
-rw-r--r--sql/sql_load.cc29
-rw-r--r--sql/sql_parse.cc21
-rw-r--r--sql/sql_partition.cc60
-rw-r--r--sql/sql_plugin.cc12
-rw-r--r--sql/sql_priv.h4
-rw-r--r--sql/sql_repl.cc24
-rw-r--r--sql/sql_select.cc94
-rw-r--r--sql/sql_show.cc155
-rw-r--r--sql/sql_string.cc7
-rw-r--r--sql/sql_table.cc46
-rw-r--r--sql/sql_table.h1
-rw-r--r--sql/sql_update.cc13
-rw-r--r--sql/sql_yacc.yy2
-rw-r--r--sql/sys_vars.cc7
-rw-r--r--sql/table.cc71
-rw-r--r--sql/table.h18
-rw-r--r--sql/thr_malloc.cc4
-rw-r--r--sql/thr_malloc.h1
-rw-r--r--storage/archive/ha_archive.cc14
-rwxr-xr-xstorage/myisam/CMakeLists.txt4
-rw-r--r--storage/myisam/Makefile.am9
-rw-r--r--storage/myisam/ft_eval.c252
-rw-r--r--storage/myisam/ft_eval.h41
-rw-r--r--storage/myisam/ft_stem.c18
-rw-r--r--storage/myisam/ft_test1.c315
-rw-r--r--storage/myisam/ft_test1.h420
-rw-r--r--storage/myisam/ha_myisam.cc2
-rw-r--r--storage/myisam/mi_check.c9
-rw-r--r--storage/myisam/mi_delete_all.c2
-rw-r--r--storage/myisam/mi_delete_table.c33
-rw-r--r--storage/myisam/mi_dynrec.c31
-rw-r--r--storage/myisam/mi_extra.c5
-rw-r--r--storage/myisam/mi_open.c3
-rw-r--r--storage/myisam/mi_page.c7
-rw-r--r--storage/myisam/mi_rnext.c17
-rw-r--r--storage/myisam/mi_write.c2
-rw-r--r--storage/myisam/myisamdef.h1
-rw-r--r--storage/myisam/rt_index.c10
-rw-r--r--storage/myisam/rt_split.c11
-rw-r--r--storage/myisam/sort.c26
-rw-r--r--storage/myisammrg/myrg_queue.c12
-rw-r--r--strings/ChangeLog38
-rw-r--r--strings/bcopy-duff.c48
-rw-r--r--strings/bzero.c82
-rw-r--r--strings/macros.asm147
-rw-r--r--strings/memcmp.c44
-rw-r--r--strings/memcpy.c33
-rw-r--r--strings/memset.c50
-rw-r--r--strings/ptr_cmp.asm180
-rw-r--r--strings/strcat.c40
-rw-r--r--strings/strchr.c61
-rw-r--r--strings/strcmp.c35
-rw-r--r--strings/strings.asm1060
-rw-r--r--strings/strlen.c65
-rw-r--r--strings/strrchr.c39
-rw-r--r--strings/strxmov.asm103
-rw-r--r--strings/udiv.c36
-rw-r--r--support-files/mysql.spec.sh181
-rw-r--r--tests/mysql_client_test.c127
277 files changed, 4543 insertions, 4519 deletions
diff --git a/BUILD/Makefile.am b/BUILD/Makefile.am
index 496fb302b16..c7bf813c9fe 100644
--- a/BUILD/Makefile.am
+++ b/BUILD/Makefile.am
@@ -25,8 +25,6 @@ EXTRA_DIST = FINISH.sh \
check-cpu \
cleanup \
compile-alpha \
- compile-alpha-ccc \
- compile-alpha-cxx \
compile-alpha-debug \
compile-amd64-debug-max \
compile-amd64-debug-max-no-ndb \
diff --git a/BUILD/compile-alpha-ccc b/BUILD/compile-alpha-ccc
deleted file mode 100755
index 59ed241d51c..00000000000
--- a/BUILD/compile-alpha-ccc
+++ /dev/null
@@ -1,41 +0,0 @@
-#! /bin/sh
-
-/bin/rm -f */.deps/*.P */*.o
-make -k maintainer-clean
-/bin/rm -f */.deps/*.P */*.o
-/bin/rm -f config.cache mysql-*.tar.gz
-
-path=`dirname $0`
-. "$path/autorun.sh"
-
-CC=ccc CFLAGS="-fast -O3 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O6 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti -mcpu=ev6 -Wa,-mev6" CXXLDFLAGS='/usr/lib/compaq/libots-2.2.7/libots.so /usr/lib/compaq/cpml-5.0.0/libcpml_ev6.a' ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client
-make
-rm */.deps/*
-make
-if [ $? = 0 ]
-then
- rm */.deps/*
- bin/mysqladmin shutdown
- sur make install
- if [ $? = 0 ]
- then
- scripts/make_binary_distribution
- fi
-fi
-
-exit
-
-# This should give better performance by compiling many files at once, but
-# according to our benchmarks there isn't any real difference.
-
-pwd=`pwd`
-for i in */make-ccc
-do
- cd `dirname $i`
- make-ccc
- cd $pwd
-done
-cd sql
-rm mysqld .deps/*.P
-make mysqld
-cd $pwd
diff --git a/BUILD/compile-alpha-cxx b/BUILD/compile-alpha-cxx
deleted file mode 100755
index a1b5605ac5e..00000000000
--- a/BUILD/compile-alpha-cxx
+++ /dev/null
@@ -1,43 +0,0 @@
-#! /bin/sh
-
-/bin/rm -f */.deps/*.P */*.o
-make -k maintainer-clean
-/bin/rm -f */.deps/*.P */*.o
-/bin/rm -f */.deps/*.P config.cache storage/innobase/config.cache mysql-*.tar.gz
-
-path=`dirname $0`
-. "$path/autorun.sh"
-
-CC=ccc CFLAGS="-fast" CXX=cxx CXXFLAGS="-fast -noexceptions -nortti" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared --without-extra-tools --disable-dependency-tracking
-
-make -j2
-find . -name ".deps" | xargs rm -r
-make
-if [ $? = 0 ]
-then
- find . -name ".deps" | xargs rm -r
- bin/mysqladmin shutdown
- sur make install
- if [ $? = 0 ]
- then
- scripts/make_binary_distribution
- fi
- make test
-fi
-
-exit
-
-# This should give better performance by compiling many files at once, but
-# according to our benchmarks there isn't any real difference.
-
-pwd=`pwd`
-for i in */make-ccc
-do
- cd `dirname $i`
- make-ccc
- cd $pwd
-done
-cd sql
-rm mysqld .deps/*.P
-make mysqld
-cd $pwd
diff --git a/Makefile.am b/Makefile.am
index fd7b3ddecc0..91174568026 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -154,8 +154,8 @@ test-bt:
-if [ -e bin/ndbd -o -e storage/ndb/src/kernel/ndbd ] ; then \
cd mysql-test ; \
MTR_BUILD_THREAD=auto \
- @PERL@ ./mysql-test-run.pl --comment=ndb+rpl_ndb+ps --force --timer \
- --ps-protocol --mysqld=--binlog-format=row --suite=ndb,rpl_ndb $(EXP) ; \
+ @PERL@ ./mysql-test-run.pl --comment=ndb+ps --force --timer \
+ --ps-protocol --mysqld=--binlog-format=row --suite=ndb $(EXP) ; \
MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --comment=ndb --force --timer \
--with-ndbcluster-only $(EXP) ; \
diff --git a/client/mysql.cc b/client/mysql.cc
index 86094edc039..4a7a8f0e58c 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -59,8 +59,6 @@ static char *server_version= NULL;
/* Array of options to pass to libemysqld */
#define MAX_SERVER_ARGS 64
-void* sql_alloc(unsigned size); // Don't use mysqld alloc for these
-void sql_element_free(void *ptr);
#include "sql_string.h"
extern "C" {
@@ -4963,17 +4961,3 @@ static int com_prompt(String *buffer, char *line)
tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
return 0;
}
-
-#ifndef EMBEDDED_LIBRARY
-/* Keep sql_string library happy */
-
-void *sql_alloc(size_t Size)
-{
- return my_malloc(Size,MYF(MY_WME));
-}
-
-void sql_element_free(void *ptr)
-{
- my_free(ptr,MYF(0));
-}
-#endif /* EMBEDDED_LIBRARY */
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 410d3a875d7..ecba818a156 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -736,9 +736,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
switch (ev_type) {
case QUERY_EVENT:
- if (strncmp(((Query_log_event*)ev)->query, "BEGIN", 5) &&
- strncmp(((Query_log_event*)ev)->query, "COMMIT", 6) &&
- strncmp(((Query_log_event*)ev)->query, "ROLLBACK", 8) &&
+ if (!((Query_log_event*)ev)->is_trans_keyword() &&
shall_skip_database(((Query_log_event*)ev)->db))
goto end;
if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS)
diff --git a/client/sql_string.cc b/client/sql_string.cc
index ccbc8977e7f..6b749409a64 100644
--- a/client/sql_string.cc
+++ b/client/sql_string.cc
@@ -24,13 +24,6 @@
#include <m_string.h>
#include <m_ctype.h>
#include <mysql_com.h>
-/*
- The following extern declarations are ok as these are interface functions
- required by the string function
-*/
-
-extern void sql_alloc(size_t size);
-extern void sql_element_free(void *ptr);
#include "sql_string.h"
diff --git a/cmake/os/FreeBSD.cmake b/cmake/os/FreeBSD.cmake
index 0b958c61315..be7af778e93 100644
--- a/cmake/os/FreeBSD.cmake
+++ b/cmake/os/FreeBSD.cmake
@@ -1,5 +1,5 @@
-# Copyright (C) 2010 Sun Microsystems, Inc
+# Copyright (c) 2010, 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
@@ -15,6 +15,9 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# This file includes FreeBSD specific options and quirks, related to system checks
-#Legacy option, maybe not needed anymore , taken as is from autotools build
-ADD_DEFINITIONS(-DNET_RETRY_COUNT=1000000)
+# Should not be needed any more, but kept for easy resurrection if needed
+# #Legacy option, maybe not needed anymore , taken as is from autotools build
+# ADD_DEFINITIONS(-DNET_RETRY_COUNT=1000000)
+
+ADD_DEFINITIONS(-DHAVE_BROKEN_REALPATH)
diff --git a/configure.in b/configure.in
index 1fa5a5d8def..b446edb10fe 100644
--- a/configure.in
+++ b/configure.in
@@ -1,7 +1,7 @@
dnl -*- ksh -*-
dnl Process this file with autoconf to produce a configure script.
-# Copyright (C) 2008-2009 Sun Microsystems, Inc
+# Copyright (c) 2000, 2010, 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
@@ -19,15 +19,16 @@ dnl Process this file with autoconf to produce a configure script.
# Minimum Autoconf version required.
AC_PREREQ(2.59)
-# Various people throughout the community may parse configure.in to
-# get the MySQL version from the source branch. If the formatting
-# of this line is going to be changed, please announce the change to
-# internals@lists.mysql.com in advance of pushing the change.
-#
-# Remember to also update version.c in ndb.
-# When changing major version number please also check switch statement
-# in client/mysqlbinlog.cc:check_master_version().
+dnl Various people throughout the community may parse configure.in to
+dnl get the MySQL version from the source branch. If the formatting
+dnl of this line is going to be changed, please announce the change to
+dnl internals@lists.mysql.com in advance of pushing the change.
+dnl
+dnl When changing the major version number please also check the switch
+dnl statement in mysqlbinlog::check_master_version(). You may also need
+dnl to update version.c in ndb.
AC_INIT([MySQL Server], [5.5.5-m3], [], [mysql])
+
AC_CONFIG_SRCDIR([sql/mysqld.cc])
AC_CANONICAL_SYSTEM
# USTAR format gives us the possibility to store longer path names in
@@ -1295,14 +1296,22 @@ case $SYSTEM_TYPE in
fi
;;
*freebsd*|*dragonfly*)
- AC_MSG_WARN([Adding fix for interrupted reads])
+ dnl These dependencies have not really been checked for some time
OSVERSION=`sysctl -a | grep osreldate | awk '{ print $2 }'`
- if test "$OSVERSION" -gt "480100" && \
+ if test "$OSVERSION" -gt "600000"
+ then
+ # Post user-level threads, MYSQLD_NET_RETRY_COUNT is not needed any more
+ AC_MSG_WARN([Adding fix for broken realpath])
+ CFLAGS="$CFLAGS -DHAVE_BROKEN_REALPATH"
+ CXXFLAGS="$CXXFLAGS -DHAVE_BROKEN_REALPATH"
+ elif test "$OSVERSION" -gt "480100" && \
test "$OSVERSION" -lt "500000" || \
test "$OSVERSION" -gt "500109"
then
+ AC_MSG_WARN([Adding fix for interrupted reads])
CXXFLAGS="$CXXFLAGS -DMYSQLD_NET_RETRY_COUNT=1000000"
else
+ AC_MSG_WARN([Adding fix for interrupted reads and broken realpath])
CFLAGS="$CFLAGS -DHAVE_BROKEN_REALPATH"
CXXFLAGS="$CXXFLAGS -DMYSQLD_NET_RETRY_COUNT=1000000 -DHAVE_BROKEN_REALPATH"
fi
diff --git a/include/my_global.h b/include/my_global.h
index 2a65c610604..41735f4e4f5 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -863,7 +863,7 @@ typedef SOCKET_SIZE_TYPE size_socket;
#endif
#ifndef OS_FILE_LIMIT
-#define OS_FILE_LIMIT 65535
+#define OS_FILE_LIMIT UINT_MAX
#endif
/* #define EXT_IN_LIBNAME */
diff --git a/include/my_pthread.h b/include/my_pthread.h
index e41abba950e..ea37f6e6b92 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -712,7 +712,6 @@ extern my_bool my_thread_init(void);
extern void my_thread_end(void);
extern const char *my_thread_name(void);
extern my_thread_id my_thread_dbug_id(void);
-extern int pthread_no_free(void *);
extern int pthread_dummy(int);
/* All thread specific variables are in the following struct */
diff --git a/include/my_sys.h b/include/my_sys.h
index 727ff7c58b4..cca4d713ca6 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -54,8 +54,6 @@ extern int NEAR my_errno; /* Last error in mysys */
#include <malloc.h> /*for alloca*/
#endif
-#define MYSYS_PROGRAM_USES_CURSES() { error_handler_hook = my_message_curses; mysys_uses_curses=1; }
-#define MYSYS_PROGRAM_DONT_USE_CURSES() { error_handler_hook = my_message_no_curses; mysys_uses_curses=0;}
#define MY_INIT(name); { my_progname= name; my_init(); }
/**
@@ -285,7 +283,7 @@ extern int NEAR my_umask_dir,
NEAR my_recived_signals, /* Signals we have got */
NEAR my_safe_to_handle_signal, /* Set when allowed to SIGTSTP */
NEAR my_dont_interrupt; /* call remember_intr when set */
-extern my_bool NEAR mysys_uses_curses, my_use_symdir;
+extern my_bool NEAR my_use_symdir;
extern size_t sf_malloc_cur_memory, sf_malloc_max_memory;
extern ulong my_default_record_cache_size;
@@ -682,7 +680,6 @@ extern int nt_share_delete(const char *name,myf MyFlags);
#ifdef _WIN32
/* Windows-only functions (CRT equivalents)*/
-extern File my_sopen(const char *path, int oflag, int shflag, int pmode);
extern HANDLE my_get_osfhandle(File fd);
extern void my_osmaperr(unsigned long last_error);
#endif
@@ -711,8 +708,7 @@ extern int my_error_register(const char** (*get_errmsgs) (),
int first, int last);
extern const char **my_error_unregister(int first, int last);
extern void my_message(uint my_err, const char *str,myf MyFlags);
-extern void my_message_no_curses(uint my_err, const char *str,myf MyFlags);
-extern void my_message_curses(uint my_err, const char *str,myf MyFlags);
+extern void my_message_stderr(uint my_err, const char *str, myf MyFlags);
extern my_bool my_basic_init(void);
extern my_bool my_init(void);
extern void my_end(int infoflag);
diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h
index 567734c1d5c..19cf0ed050d 100644
--- a/include/mysql/plugin.h
+++ b/include/mysql/plugin.h
@@ -593,30 +593,37 @@ void mysql_query_cache_invalidate4(MYSQL_THD thd,
const char *key, unsigned int key_length,
int using_trx);
-#ifdef __cplusplus
-}
-#endif
-#ifdef __cplusplus
/**
Provide a handler data getter to simplify coding
*/
-inline
-void *
-thd_get_ha_data(const MYSQL_THD thd, const struct handlerton *hton)
-{
- return *thd_ha_data(thd, hton);
-}
+void *thd_get_ha_data(const MYSQL_THD thd, const struct handlerton *hton);
+
/**
Provide a handler data setter to simplify coding
+
+ @details
+ Set ha_data pointer (storage engine per-connection information).
+
+ To avoid unclean deactivation (uninstall) of storage engine plugin
+ in the middle of transaction, additional storage engine plugin
+ lock is acquired.
+
+ If ha_data is not null and storage engine plugin was not locked
+ by thd_set_ha_data() in this connection before, storage engine
+ plugin gets locked.
+
+ If ha_data is null and storage engine plugin was locked by
+ thd_set_ha_data() in this connection before, storage engine
+ plugin lock gets released.
+
+ If handlerton::close_connection() didn't reset ha_data, server does
+ it immediately after calling handlerton::close_connection().
*/
-inline
-void
-thd_set_ha_data(const MYSQL_THD thd, const struct handlerton *hton,
- const void *ha_data)
-{
- *thd_ha_data(thd, hton)= (void*) ha_data;
+void thd_set_ha_data(MYSQL_THD thd, const struct handlerton *hton,
+ const void *ha_data);
+#ifdef __cplusplus
}
#endif
diff --git a/include/mysql/plugin.h.pp b/include/mysql/plugin.h.pp
index 5dad31bd008..3a1b03742da 100644
--- a/include/mysql/plugin.h.pp
+++ b/include/mysql/plugin.h.pp
@@ -165,3 +165,6 @@ void thd_get_xid(const void* thd, MYSQL_XID *xid);
void mysql_query_cache_invalidate4(void* thd,
const char *key, unsigned int key_length,
int using_trx);
+void *thd_get_ha_data(const void* thd, const struct handlerton *hton);
+void thd_set_ha_data(void* thd, const struct handlerton *hton,
+ const void *ha_data);
diff --git a/include/mysql_com.h b/include/mysql_com.h
index c510c12dbf7..90fe4ac1995 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -307,6 +307,16 @@ typedef struct st_net {
/** Client library sqlstate buffer. Set along with the error message. */
char sqlstate[SQLSTATE_LENGTH+1];
void *extension;
+#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
+ /*
+ Controls whether a big packet should be skipped.
+
+ Initially set to FALSE by default. Unauthenticated sessions must have
+ this set to FALSE so that the server can't be tricked to read packets
+ indefinitely.
+ */
+ my_bool skip_big_packet;
+#endif
} NET;
diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared
index 71649b83991..71a4fd867bd 100644
--- a/libmysql/Makefile.shared
+++ b/libmysql/Makefile.shared
@@ -56,7 +56,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
my_create.lo my_delete.lo mf_tempfile.lo my_open.lo \
my_file.lo my_read.lo my_write.lo errors.lo \
my_error.lo my_getwd.lo my_div.lo \
- mf_pack.lo my_messnc.lo mf_dirname.lo mf_fn_ext.lo\
+ mf_pack.lo my_mess.lo mf_dirname.lo mf_fn_ext.lo\
mf_wcomp.lo typelib.lo safemalloc.lo my_alloc.lo \
mf_format.lo mf_path.lo mf_unixpath.lo my_fopen.lo \
my_symlink.lo my_fstream.lo mf_arr_appstr.lo \
diff --git a/mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test b/mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test
index 26a70c4319e..68aa949a7c7 100644
--- a/mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test
+++ b/mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test
@@ -214,7 +214,7 @@ CREATE TABLE t5 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
# execute
--error ER_DUP_ENTRY
- UPDATE t3,t4 SET t3.a=t4.a + bug27417(1);
+ UPDATE t3,t4 SET t3.a = t4.a + bug27417(1) where t3.a = 1;
# check
select count(*) from t1 /* must be 1 */;
diff --git a/mysql-test/extra/rpl_tests/rpl_record_compare.test b/mysql-test/extra/rpl_tests/rpl_record_compare.test
new file mode 100644
index 00000000000..dc27dcb1f9d
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_record_compare.test
@@ -0,0 +1,68 @@
+
+#
+# BUG#52868: Wrong handling of NULL value during update, replication out of sync
+#
+-- echo ## case #1 - last_null_bit_pos==0 in record_compare without X bit
+
+-- source include/master-slave-reset.inc
+-- connection master
+
+-- eval CREATE TABLE t1 (c1 bigint(20) DEFAULT 0, c2 bigint(20) DEFAULT 0, c3 bigint(20) DEFAULT 0, c4 varchar(1) DEFAULT '', c5 bigint(20) DEFAULT 0, c6 bigint(20) DEFAULT 0, c7 bigint(20) DEFAULT 0, c8 bigint(20) DEFAULT 0) ENGINE=$engine DEFAULT CHARSET=latin1
+
+INSERT INTO t1 ( c5, c6 ) VALUES ( 1 , 35 );
+INSERT INTO t1 ( c5, c6 ) VALUES ( NULL, 35 );
+-- disable_warnings
+UPDATE t1 SET c5 = 'a';
+-- enable_warnings
+-- sync_slave_with_master
+
+-- let $diff_table_1= master:test.t1
+-- let $diff_table_2= slave:test.t1
+-- source include/diff_tables.inc
+
+--connection master
+DROP TABLE t1;
+-- sync_slave_with_master
+
+-- echo ## case #1.1 - last_null_bit_pos==0 in record_compare with X bit
+-- echo ## (1 column less and no varchar)
+-- source include/master-slave-reset.inc
+-- connection master
+
+-- eval CREATE TABLE t1 (c1 bigint(20) DEFAULT 0, c2 bigint(20) DEFAULT 0, c3 bigint(20) DEFAULT 0, c4 bigint(20) DEFAULT 0, c5 bigint(20) DEFAULT 0, c6 bigint(20) DEFAULT 0, c7 bigint(20) DEFAULT 0) ENGINE=$engine DEFAULT CHARSET=latin1
+
+INSERT INTO t1 ( c5, c6 ) VALUES ( 1 , 35 );
+INSERT INTO t1 ( c5, c6 ) VALUES ( NULL, 35 );
+-- disable_warnings
+UPDATE t1 SET c5 = 'a';
+-- enable_warnings
+-- sync_slave_with_master
+
+-- let $diff_table_1= master:test.t1
+-- let $diff_table_2= slave:test.t1
+-- source include/diff_tables.inc
+
+--connection master
+DROP TABLE t1;
+-- sync_slave_with_master
+
+-- echo ## case #2 - X bit is wrongly set.
+
+-- source include/master-slave-reset.inc
+-- connection master
+
+-- eval CREATE TABLE t1 (c1 int, c2 varchar(1) default '') ENGINE=$engine DEFAULT CHARSET= latin1
+INSERT INTO t1(c1) VALUES (10);
+INSERT INTO t1(c1) VALUES (NULL);
+UPDATE t1 SET c1= 0;
+-- sync_slave_with_master
+
+-- let $diff_table_1= master:test.t1
+-- let $diff_table_2= slave:test.t1
+-- source include/diff_tables.inc
+
+-- connection master
+DROP TABLE t1;
+-- sync_slave_with_master
+
+
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 58a289422f4..68955010696 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -3811,6 +3811,7 @@ sub extract_warning_lines ($$) {
# Skip valgrind summary from tests where server has been restarted
# Should this contain memory leaks, the final report will find it
$skip_valgrind= 1 if $line =~ /^==\d+== ERROR SUMMARY:/;
+ $skip_valgrind= 1 if $line =~ /^==\d+== HEAP SUMMARY:/;
$skip_valgrind= 0 unless $line =~ /^==\d+==/;
next if $skip_valgrind;
}
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result
index 783a54a6b8c..88f38a13b4a 100644
--- a/mysql-test/r/archive.result
+++ b/mysql-test/r/archive.result
@@ -12748,3 +12748,22 @@ SELECT * FROM t1;
ERROR HY000: Can't find file: 't1' (errno: 2)
DROP TABLE t1;
ERROR 42S02: Unknown table 't1'
+#
+# BUG#46565 - repair of partition fail for archive engine
+#
+# Installing corrupted table files for t1.
+SELECT * FROM t1;
+ERROR HY000: Table 't1' is marked as crashed and should be repaired
+REPAIR TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 repair error Corrupt
+SELECT * FROM t1;
+ERROR HY000: Table 't1' is marked as crashed and should be repaired
+REPAIR TABLE t1 EXTENDED;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+SELECT * FROM t1;
+a
+1
+2
+DROP TABLE t1;
diff --git a/mysql-test/r/bug46261.result b/mysql-test/r/bug46261.result
new file mode 100644
index 00000000000..f54b698e08f
--- /dev/null
+++ b/mysql-test/r/bug46261.result
@@ -0,0 +1,8 @@
+#
+# Bug#46261 Plugins can be installed with --skip-grant-tables
+#
+INSTALL PLUGIN example SONAME 'ha_example.so';
+ERROR HY000: The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement
+UNINSTALL PLUGIN example;
+ERROR HY000: The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement
+End of 5.1 tests
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index 324848be835..4f033d54043 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -1230,6 +1230,14 @@ SELECT HEX(DAYNAME(19700101));
HEX(DAYNAME(19700101))
0427043504420432043504400433
SET character_set_connection=latin1;
+#
+# Bug#52120 create view cause Assertion failed: 0, file .\item_subselect.cc, line 817
+#
+CREATE TABLE t1 (a CHAR(1) CHARSET ascii, b CHAR(1) CHARSET latin1);
+CREATE VIEW v1 AS SELECT 1 from t1
+WHERE t1.b <=> (SELECT a FROM t1 WHERE a < SOME(SELECT '1'));
+DROP VIEW v1;
+DROP TABLE t1;
End of 5.0 tests
#
# Start of 5.5 tests
diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result
index 733614b765a..0c9b0d7d2e5 100644
--- a/mysql-test/r/delete.result
+++ b/mysql-test/r/delete.result
@@ -490,4 +490,13 @@ END |
DELETE IGNORE FROM t1;
ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
DROP TABLE t1;
+#
+# Bug #53450: Crash/assertion
+# "virtual int ha_myisam::index_first(uchar*)") at assert.c:81
+#
+CREATE TABLE t1 (a INT, b INT, c INT,
+INDEX(a), INDEX(b), INDEX(c));
+INSERT INTO t1 VALUES (1,2,3), (4,5,6), (7,8,9);
+DELETE FROM t1 WHERE a = 10 OR b = 20 ORDER BY c LIMIT 1;
+DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/r/error_simulation.result b/mysql-test/r/error_simulation.result
index 6153dad2534..27e51a33112 100644
--- a/mysql-test/r/error_simulation.result
+++ b/mysql-test/r/error_simulation.result
@@ -18,3 +18,26 @@ SELECT MAX(a) FROM t1 GROUP BY a,b;
ERROR 23000: Can't write; duplicate key in table 'tmp_table'
set tmp_table_size=default;
DROP TABLE t1;
+#
+# Bug #50946: fast index creation still seems to copy the table
+#
+CREATE TABLE t1 (a INT(100) NOT NULL);
+INSERT INTO t1 VALUES (1), (0), (2);
+SET SESSION debug='+d,alter_table_only_index_change';
+ALTER TABLE t1 ADD INDEX a(a);
+SET SESSION debug=DEFAULT;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(100) NOT NULL,
+ KEY `a` (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+a
+0
+1
+2
+DROP TABLE t1;
+#
+# End of 5.1 tests
+#
diff --git a/mysql-test/r/errors.result b/mysql-test/r/errors.result
index a3a8fe0b147..3d247a242a3 100644
--- a/mysql-test/r/errors.result
+++ b/mysql-test/r/errors.result
@@ -120,3 +120,17 @@ SET sql_quote_show_create= _utf8 x'5452C39C45';
ERROR 42000: Variable 'sql_quote_show_create' can't be set to the value of 'TRÃœE'
SET sql_quote_show_create=_latin1 x'5452DC45';
ERROR 42000: Variable 'sql_quote_show_create' can't be set to the value of 'TRÃœE'
+#
+# Bug#52430 Incorrect key in the error message for duplicate key error involving BINARY type
+#
+CREATE TABLE t1(c1 BINARY(10), c2 BINARY(10), c3 BINARY(10),
+PRIMARY KEY(c1,c2,c3));
+INSERT INTO t1 (c1,c2,c3) VALUES('abc','abc','abc');
+INSERT INTO t1 (c1,c2,c3) VALUES('abc','abc','abc');
+ERROR 23000: Duplicate entry 'abc-abc-abc' for key 'PRIMARY'
+DROP TABLE t1;
+CREATE TABLE t1 (f1 VARBINARY(19) PRIMARY KEY);
+INSERT INTO t1 VALUES ('abc\0\0');
+INSERT INTO t1 VALUES ('abc\0\0');
+ERROR 23000: Duplicate entry 'abc\x00\x00' for key 'PRIMARY'
+DROP TABLE t1;
diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result
index 9740303c00e..7042a2c6f6c 100644
--- a/mysql-test/r/explain.result
+++ b/mysql-test/r/explain.result
@@ -246,4 +246,16 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select '1' AS `f1`,`test`.`t2`.`f2` AS `f2` from `test`.`t2` where (`test`.`t2`.`f2` = 1)
drop table t1,t2;
+#
+# Bug #48419: another explain crash..
+#
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (b BLOB, KEY b(b(100)));
+INSERT INTO t2 VALUES ('1'), ('2'), ('3');
+FLUSH TABLES;
+EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT 1 FROM t1 t JOIN t2 WHERE b <= 1 AND t.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+DROP TABLE t1, t2;
End of 5.1 tests.
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index 1d9fa20f673..a75f502c735 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -639,4 +639,17 @@ CREATE TABLE t1(a CHAR(1),FULLTEXT(a));
SELECT 1 FROM t1 WHERE MATCH(a) AGAINST ('') AND ROW(a,a) > ROW(1,1);
1
DROP TABLE t1;
+#
+# BUG#51866 - crash with repair by sort and fulltext keys
+#
+CREATE TABLE t1(a CHAR(4), FULLTEXT(a));
+INSERT INTO t1 VALUES('aaaa');
+SET myisam_sort_buffer_size=4;
+Warnings:
+Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '4'
+REPAIR TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
+DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/r/func_concat.result b/mysql-test/r/func_concat.result
index c4c2b46c6c2..fae8979a6e7 100644
--- a/mysql-test/r/func_concat.result
+++ b/mysql-test/r/func_concat.result
@@ -130,4 +130,22 @@ SELECT @query;
@query
abcde,0,1234
DROP PROCEDURE p1;
+#
+# Bug #40625: Concat fails on DOUBLE values in a Stored Procedure,
+# while DECIMAL works
+#
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE v1 DOUBLE(10,3);
+SET v1= 100;
+SET @s = CONCAT('########################################', 40 , v1);
+SELECT @s;
+END;//
+CALL p1();
+@s
+########################################40100.000
+CALL p1();
+@s
+########################################40100.000
+DROP PROCEDURE p1;
# End of 5.1 tests
diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result
index 2d2ca10f54b..1a393b3cdd5 100644
--- a/mysql-test/r/func_gconcat.result
+++ b/mysql-test/r/func_gconcat.result
@@ -1003,6 +1003,21 @@ SELECT 1 FROM
1
1
DROP TABLE t1;
+#
+# Bug #52397: another crash with explain extended and group_concat
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (0), (0);
+EXPLAIN EXTENDED SELECT 1 FROM
+(SELECT GROUP_CONCAT(t1.a ORDER BY t1.a ASC) FROM
+t1 t2, t1 GROUP BY t1.a) AS d;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 1 100.00
+2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using join buffer
+Warnings:
+Note 1003 select 1 AS `1` from dual
+DROP TABLE t1;
End of 5.0 tests
DROP TABLE IF EXISTS t1, t2;
CREATE TABLE t1 (a VARCHAR(6), b INT);
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 39e2cdc97ba..7539cf43dd9 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -2590,6 +2590,20 @@ FROM t2 WHERE t2.b = 1 GROUP BY t2.b;
DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b LIMIT 1), t2.a)
secret
DROP TABLE t1, t2;
+#
+# Bug#52164 Assertion failed: param.sort_length, file .\filesort.cc, line 149
+#
+CREATE TABLE t1 (a LONGBLOB NOT NULL);
+INSERT INTO t1 VALUES (''),('');
+SELECT 1 FROM t1, t1 t2
+ORDER BY QUOTE(t1.a);
+1
+1
+1
+1
+1
+DROP TABLE t1;
+End of 5.1 tests
Start of 5.4 tests
SELECT format(12345678901234567890.123, 3);
format(12345678901234567890.123, 3)
diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result
index 58c603673df..eb9c350f589 100644
--- a/mysql-test/r/gis-rtree.result
+++ b/mysql-test/r/gis-rtree.result
@@ -1540,5 +1540,12 @@ a
HANDLER t1 READ a LAST;
a
HANDLER t1 CLOSE;
+HANDLER t1 OPEN;
+HANDLER t1 READ a FIRST;
+a
+INSERT INTO t1 VALUES (GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
+# should not crash
+HANDLER t1 READ a NEXT;
+HANDLER t1 CLOSE;
DROP TABLE t1;
End of 5.0 tests.
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
index b182ee5656c..65ebbd71c39 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -1437,6 +1437,22 @@ SHOW GRANTS FOR mysqltest_1;
Grants for mysqltest_1@%
GRANT ALL PRIVILEGES ON *.* TO 'mysqltest_1'@'%'
DROP USER mysqltest_1;
+CREATE DATABASE db1;
+CREATE DATABASE db2;
+GRANT SELECT ON db1.* to 'testbug'@localhost;
+USE db2;
+CREATE TABLE t1 (a INT);
+USE test;
+SELECT * FROM `../db2/tb2`;
+ERROR 42S02: Table 'db1.../db2/tb2' doesn't exist
+SELECT * FROM `../db2`.tb2;
+ERROR 42000: SELECT command denied to user 'testbug'@'localhost' for table 'tb2'
+SELECT * FROM `#mysql50#/../db2/tb2`;
+ERROR 42S02: Table 'db1.#mysql50#/../db2/tb2' doesn't exist
+DROP USER 'testbug'@localhost;
+DROP TABLE db2.t1;
+DROP DATABASE db1;
+DROP DATABASE db2;
#########################################################################
#
# Bug#38347: ALTER ROUTINE privilege allows SHOW CREATE TABLE.
diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result
index 9d16e0fb3c5..cdf48376fb0 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -1791,4 +1791,24 @@ aa b COUNT( b)
1 10 1
DROP TABLE t1, t2;
#
+# Bug#52051: Aggregate functions incorrectly returns NULL from outer
+# join query
+#
+CREATE TABLE t1 (a INT PRIMARY KEY);
+CREATE TABLE t2 (a INT PRIMARY KEY);
+INSERT INTO t2 VALUES (1), (2);
+EXPLAIN SELECT MIN(t2.a) FROM t2 LEFT JOIN t1 ON t2.a = t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+SELECT MIN(t2.a) FROM t2 LEFT JOIN t1 ON t2.a = t1.a;
+MIN(t2.a)
+1
+EXPLAIN SELECT MAX(t2.a) FROM t2 LEFT JOIN t1 ON t2.a = t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+SELECT MAX(t2.a) FROM t2 LEFT JOIN t1 ON t2.a = t1.a;
+MAX(t2.a)
+2
+DROP TABLE t1, t2;
+#
# End of 5.1 tests
diff --git a/mysql-test/r/handler_myisam.result b/mysql-test/r/handler_myisam.result
index 2625222ec1a..028397b0b24 100644
--- a/mysql-test/r/handler_myisam.result
+++ b/mysql-test/r/handler_myisam.result
@@ -1721,4 +1721,17 @@ TRUNCATE t1;
HANDLER t1 READ FIRST;
ERROR 42S02: Unknown table 't1' in HANDLER
DROP TABLE t1;
+#
+# BUG#51877 - HANDLER interface causes invalid memory read
+#
+CREATE TABLE t1(a INT, KEY(a));
+HANDLER t1 OPEN;
+HANDLER t1 READ a FIRST;
+a
+INSERT INTO t1 VALUES(1);
+HANDLER t1 READ a NEXT;
+a
+1
+HANDLER t1 CLOSE;
+DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result
index bedccfc0f04..c69de0f307b 100644
--- a/mysql-test/r/having.result
+++ b/mysql-test/r/having.result
@@ -472,7 +472,7 @@ HAVING (table2.f2 = 8 AND table1.f1 >= 6);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING noticed after reading const tables
Warnings:
-Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having (('7' = 8) and (`test`.`table1`.`f1` >= 6))
+Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having 0
EXPLAIN EXTENDED
SELECT table1.f1, table2.f2
FROM t1 AS table1
@@ -483,6 +483,52 @@ HAVING (table2.f2 = 8);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING noticed after reading const tables
Warnings:
-Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having ('7' = 8)
+Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having 0
DROP TABLE t1;
+#
+# Bug#52336 Segfault / crash in 5.1 copy_fields (param=0x9872980) at sql_select.cc:15355
+#
+CREATE TABLE t1(f1 INT, f2 INT);
+INSERT INTO t1 VALUES (10,8);
+CREATE TABLE t2 (f1 INT);
+INSERT INTO t2 VALUES (5);
+SELECT COUNT(f1) FROM t2
+HAVING (7, 9) IN (SELECT f1, MIN(f2) FROM t1);
+COUNT(f1)
+DROP TABLE t1, t2;
+CREATE TABLE t1 (f1 INT, f2 VARCHAR(1));
+INSERT INTO t1 VALUES (16,'f');
+INSERT INTO t1 VALUES (16,'f');
+CREATE TABLE t2 (f1 INT, f2 VARCHAR(1));
+INSERT INTO t2 VALUES (13,'f');
+INSERT INTO t2 VALUES (20,'f');
+CREATE TABLE t3 (f1 INT, f2 VARCHAR(1));
+INSERT INTO t3 VALUES (7,'f');
+SELECT t1.f2 FROM t1
+STRAIGHT_JOIN (t2 JOIN t3 ON t3.f2 = t2.f2 ) ON t3 .f2 = t2 .f2
+HAVING ('v', 'i') NOT IN (SELECT f2, MIN(f2) FROM t1)
+ORDER BY f2;
+f2
+f
+f
+f
+f
+DROP TABLES t1,t2,t3;
+#
+# Bug#52340 Segfault: read_cached_record (tab=0x94a2634) at sql_select.cc:14411
+#
+CREATE TABLE t1 (f1 INT, f2 VARCHAR(1));
+INSERT INTO t1 VALUES (16,'d');
+CREATE TABLE t2 (f1 INT, f2 VARCHAR(1));
+INSERT INTO t2 VALUES (13,'e');
+INSERT INTO t2 VALUES (20,'d');
+SELECT MAX(t2.f2) FROM t2 JOIN t1 ON t1.f2
+HAVING ('e' , 'd') IN
+(SELECT ts1.f2, ts2.f2 FROM t2 ts1 JOIN t2 ts2 ON ts1.f1)
+ORDER BY t1.f2;
+MAX(t2.f2)
+NULL
+Warnings:
+Warning 1292 Truncated incorrect INTEGER value: 'd'
+DROP TABLE t1,t2;
End of 5.0 tests
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index 0a3df1f99b5..1845b32564d 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -2355,6 +2355,64 @@ Index_type BTREE
Comment
Index_comment
DROP TABLE t1;
+#
+# Bug #47453: InnoDB incorrectly changes TIMESTAMP columns when
+# JOINed during an UPDATE
+#
+CREATE TABLE t1 (d INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT, b INT,
+c TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
+ON UPDATE CURRENT_TIMESTAMP) ENGINE=InnoDB;
+set up our data elements
+INSERT INTO t1 (d) VALUES (1);
+INSERT INTO t2 (a,b) VALUES (1,1);
+SELECT SECOND(c) INTO @bug47453 FROM t2;
+SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a;
+SECOND(c)-@bug47453
+0
+UPDATE t1 JOIN t2 ON d=a SET b=1 WHERE a=1;
+SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a;
+SECOND(c)-@bug47453
+0
+SELECT SLEEP(1);
+SLEEP(1)
+0
+UPDATE t1 JOIN t2 ON d=a SET b=1 WHERE a=1;
+#should be 0
+SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a;
+SECOND(c)-@bug47453
+0
+DROP TABLE t1, t2;
+#
+# Bug #53334: wrong result for outer join with impossible ON condition
+# (see the same test case for MyISAM in join.test)
+#
+CREATE TABLE t1 (id INT PRIMARY KEY);
+CREATE TABLE t2 (id INT);
+INSERT INTO t1 VALUES (75);
+INSERT INTO t1 VALUES (79);
+INSERT INTO t1 VALUES (78);
+INSERT INTO t1 VALUES (77);
+REPLACE INTO t1 VALUES (76);
+REPLACE INTO t1 VALUES (76);
+INSERT INTO t1 VALUES (104);
+INSERT INTO t1 VALUES (103);
+INSERT INTO t1 VALUES (102);
+INSERT INTO t1 VALUES (101);
+INSERT INTO t1 VALUES (105);
+INSERT INTO t1 VALUES (106);
+INSERT INTO t1 VALUES (107);
+INSERT INTO t2 VALUES (107),(75),(1000);
+SELECT t1.id,t2.id FROM t2 LEFT JOIN t1 ON t1.id>=74 AND t1.id<=0
+WHERE t2.id=75 AND t1.id IS NULL;
+id id
+NULL 75
+EXPLAIN SELECT t1.id,t2.id FROM t2 LEFT JOIN t1 ON t1.id>=74 AND t1.id<=0
+WHERE t2.id=75 AND t1.id IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY NULL NULL NULL 1 Impossible ON condition
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where
+DROP TABLE t1,t2;
End of 5.1 tests
#
# Test for bug #39932 "create table fails if column for FK is in different
diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result
index d1234ecbd56..9f87ea082db 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -1117,6 +1117,45 @@ ON t4.a = t5.a
ON t1.a = t3.a;
a a a a a a
DROP TABLE t1,t2,t3,t4,t5,t6;
+#
+# Bug#48483: crash in get_best_combination()
+#
+CREATE TABLE t1(f1 INT);
+INSERT INTO t1 VALUES (1),(2);
+CREATE VIEW v1 AS SELECT 1 FROM t1 LEFT JOIN t1 AS t2 on 1=1;
+EXPLAIN EXTENDED
+SELECT 1 FROM v1 right join v1 AS v2 ON RAND();
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` left join `test`.`t1` `t2` on((1 = 1)) left join (`test`.`t1` left join `test`.`t1` `t2` on((1 = 1))) on(rand()) where 1
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# Bug#52177 crash with explain, row comparison, join, text field
+#
+CREATE TABLE t1 (a TINYINT, b TEXT, KEY (a));
+INSERT INTO t1 VALUES (0,''),(0,'');
+FLUSH TABLES;
+EXPLAIN SELECT 1 FROM t1 LEFT JOIN t1 a ON 1
+WHERE ROW(t1.a, 1111.11) = ROW(1111.11, 1111.11) AND
+ROW(t1.b, 1111.11) <=> ROW('','');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+DROP TABLE t1;
+#
+# Bug #50335: Assertion `!(order->used & map)' in eq_ref_table
+#
+CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b));
+INSERT INTO t1 VALUES (0,0), (1,1);
+SELECT * FROM t1 STRAIGHT_JOIN t1 t2 ON t1.a=t2.a AND t1.a=t2.b ORDER BY t2.a, t1.a;
+a b a b
+0 0 0 0
+1 1 1 1
+DROP TABLE t1;
End of 5.0 tests.
CREATE TABLE t1 (f1 int);
CREATE TABLE t2 (f1 int);
@@ -1145,14 +1184,4 @@ NULL
NULL
1
DROP TABLE t1, t2, mm1;
-#
-# Bug #50335: Assertion `!(order->used & map)' in eq_ref_table
-#
-CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b));
-INSERT INTO t1 VALUES (0,0), (1,1);
-SELECT * FROM t1 STRAIGHT_JOIN t1 t2 ON t1.a=t2.a AND t1.a=t2.b ORDER BY t2.a, t1.a;
-a b a b
-0 0 0 0
-1 1 1 1
-DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index 461a553d3f0..17363cbc989 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -1312,4 +1312,34 @@ WHERE (COALESCE(t1.f1, t2.f1), f3) IN ((1, 3), (2, 2));
f1 f2 f3 f1 f2
1 NULL 3 NULL NULL
DROP TABLE t1, t2;
+#
+# Bug#52357: Assertion failed: join->best_read in greedy_search
+# optimizer_search_depth=0
+#
+CREATE TABLE t1( a INT );
+INSERT INTO t1 VALUES (1),(2);
+SET optimizer_search_depth = 0;
+# Should not core dump on query preparation
+EXPLAIN
+SELECT 1
+FROM t1 tt3 LEFT OUTER JOIN t1 tt4 ON 1
+LEFT OUTER JOIN t1 tt5 ON 1
+LEFT OUTER JOIN t1 tt6 ON 1
+LEFT OUTER JOIN t1 tt7 ON 1
+LEFT OUTER JOIN t1 tt8 ON 1
+RIGHT OUTER JOIN t1 tt2 ON 1
+RIGHT OUTER JOIN t1 tt1 ON 1
+STRAIGHT_JOIN t1 tt9 ON 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE tt1 ALL NULL NULL NULL NULL 2
+1 SIMPLE tt2 ALL NULL NULL NULL NULL 2
+1 SIMPLE tt3 ALL NULL NULL NULL NULL 2
+1 SIMPLE tt4 ALL NULL NULL NULL NULL 2
+1 SIMPLE tt5 ALL NULL NULL NULL NULL 2
+1 SIMPLE tt6 ALL NULL NULL NULL NULL 2
+1 SIMPLE tt7 ALL NULL NULL NULL NULL 2
+1 SIMPLE tt8 ALL NULL NULL NULL NULL 2
+1 SIMPLE tt9 ALL NULL NULL NULL NULL 2 Using join buffer
+SET optimizer_search_depth = DEFAULT;
+DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result
index 5e25132880f..7a79603adb3 100644
--- a/mysql-test/r/loaddata.result
+++ b/mysql-test/r/loaddata.result
@@ -202,12 +202,6 @@ select * from t1;
a b c
10 NULL Ten
15 NULL Fifteen
-show variables like "secure_file_pri%";
-Variable_name Value
-secure_file_priv MYSQLTEST_VARDIR/
-select @@secure_file_priv;
-@@secure_file_priv
-MYSQLTEST_VARDIR/
set @@secure_file_priv= 0;
ERROR HY000: Variable 'secure_file_priv' is a read only variable
truncate table t1;
@@ -456,6 +450,13 @@ LOAD_FILE("MYSQLTEST_VARDIR/tmp/bug37114.txt")
set session sql_mode=@OLD_SQL_MODE;
DROP TABLE t1,t2;
+#
+# Bug #51893: crash with certain characters given to load_file
+# function on windows
+#
+select load_file(0x0A9FB76C661B409C4BEC88098C5DD71B1072F9691F2E827D7EC8F092B299868A3CE196C04F0FB18CAB4E1557EB72331D812379DE7A75CA21C32E7C722C59E5CC33EF262EF04187B0F0EE756FA984DF2EAD37B1E4ADB064C3C5038F2E3B2D661B1C1150AAEB5425512E14D7506166D92D4533872E662F4B2D1428AAB5CCA72E75AA2EF325E196A5A02E2E8278873C64375845994B0F39BE2FF7B478332A7B0AA5E48877C47B6F513E997848AF8CCB8A899F3393AB35333CF0871E36698193862D486B4B9078B70C0A0A507B8A250F3F876F5A067632D5E65193E4445A1EC3A2C9B4C6F07AC334F0F62BC33357CB502E9B1C19D2398B6972AEC2EF21630F8C9134C4F7DD662D8AD7BDC9E19C46720F334B66C22D4BF32ED275144E20E7669FFCF6FC143667C9F02A577F32960FA9F2371BE1FA90E49CBC69C01531F140556854D588DD0E55E1307D78CA38E975CD999F9AEA604266329EE62BFB5ADDA67F549E211ECFBA906C60063696352ABB82AA782D25B17E872EA587871F450446DB1BAE0123D20404A8F2D2698B371002E986C8FCB969A99FF0E150A2709E2ED7633D02ADA87D5B3C9487D27B2BD9D21E2EC3215DCC3CDCD884371281B95A2E9987AAF82EB499C058D9C3E7DC1B66635F60DB121C72F929622DD47B6B2E69F59FF2AE6B63CC2EC60FFBA20EA50569DBAB5DAEFAEB4F03966C9637AB55662EDD28439155A82D053A5299448EDB2E7BEB0F62889E2F84E6C7F34B3212C9AAC32D521D5AB8480993F1906D5450FAB342A0FA6ED223E178BAC036B81E15783604C32A961EA1EF20BE2EBB93D34ED37BC03142B7583303E4557E48551E4BD7CBDDEA146D5485A5D212C35189F0BD6497E66912D2780A59A53B532E12C0A5ED1EC0445D96E8F2DD825221CFE4A65A87AA21DC8750481B9849DD81694C3357A0ED9B78D608D8EDDE28FAFBEC17844DE5709F41E121838DB55639D77E32A259A416D7013B2EB1259FDE1B498CBB9CAEE1D601DF3C915EA91C69B44E6B72062F5F4B3C73F06F2D5AD185E1692E2E0A01E7DD5133693681C52EE13B2BE42D03BDCF48E4E133CF06662339B778E1C3034F9939A433E157449172F7969ACCE1F5D2F65A4E09E4A5D5611EBEDDDBDB0C0C0A);
+load_file(0x0A9FB76C661B409C4BEC88098C5DD71B1072F9691F2E827D7EC8F092B299868A3CE196C04F0FB18CAB4E1557EB72331D812379DE7A75CA21C32E7C722C59E5CC33EF262EF04187B0F0EE756FA984DF2EAD37B1E4ADB064C3C5038F2E3B2D661B1C1150AAEB5425512E14D7506166D92D4533872E662F4B2D142
+NULL
End of 5.0 tests
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (1);
@@ -484,4 +485,15 @@ SET character_set_filesystem=default;
select @@character_set_filesystem;
@@character_set_filesystem
binary
+#
+# Bug #51850: crash/memory overlap when using load data infile and set
+# col equal to itself!
+#
+CREATE TABLE t1(col0 LONGBLOB);
+SELECT 'test' INTO OUTFILE 't1.txt';
+LOAD DATA INFILE 't1.txt' IGNORE INTO TABLE t1 SET col0=col0;
+SELECT * FROM t1;
+col0
+test
+DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/r/log_state.result b/mysql-test/r/log_state.result
index 56e30ac59f8..714a14c1f4f 100644
--- a/mysql-test/r/log_state.result
+++ b/mysql-test/r/log_state.result
@@ -308,6 +308,37 @@ SET @@global.general_log = @old_general_log;
SET @@global.general_log_file = @old_general_log_file;
SET @@global.slow_query_log = @old_slow_query_log;
SET @@global.slow_query_log_file = @old_slow_query_log_file;
+#
+# Bug #49756 Rows_examined is always 0 in the slow query log
+# for update statements
+#
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = "TABLE";
+SET GLOBAL slow_query_log = ON;
+SET GLOBAL long_query_time = 0.001;
+TRUNCATE TABLE mysql.slow_log;
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (b INT, PRIMARY KEY (b));
+INSERT INTO t2 VALUES (3),(4);
+INSERT INTO t1 VALUES (1+sleep(.01)),(2);
+INSERT INTO t1 SELECT b+sleep(.01) from t2;
+UPDATE t1 SET a=a+sleep(.01) WHERE a>2;
+UPDATE t1 SET a=a+sleep(.01) ORDER BY a DESC;
+UPDATE t2 set b=b+sleep(.01) limit 1;
+UPDATE t1 SET a=a+sleep(.01) WHERE a in (SELECT b from t2);
+DELETE FROM t1 WHERE a=a+sleep(.01) ORDER BY a LIMIT 2;
+SELECT rows_examined,sql_text FROM mysql.slow_log;
+rows_examined sql_text
+0 INSERT INTO t1 VALUES (1+sleep(.01)),(2)
+2 INSERT INTO t1 SELECT b+sleep(.01) from t2
+4 UPDATE t1 SET a=a+sleep(.01) WHERE a>2
+8 UPDATE t1 SET a=a+sleep(.01) ORDER BY a DESC
+2 UPDATE t2 set b=b+sleep(.01) limit 1
+4 UPDATE t1 SET a=a+sleep(.01) WHERE a in (SELECT b from t2)
+6 DELETE FROM t1 WHERE a=a+sleep(.01) ORDER BY a LIMIT 2
+DROP TABLE t1,t2;
+TRUNCATE TABLE mysql.slow_log;
+# end of bug#49756
End of 5.1 tests
# --
@@ -334,6 +365,8 @@ SELECT @@general_log_file = @my_glf;
1
SET GLOBAL general_log_file = @old_general_log_file;
# Close connection con1
+SET GLOBAL long_query_time = DEFAULT;
+SET GLOBAL log_output = @old_log_output;
SET global general_log = @old_general_log;
SET global general_log_file = @old_general_log_file;
SET global slow_query_log = @old_slow_query_log;
diff --git a/mysql-test/r/mdl_sync.result b/mysql-test/r/mdl_sync.result
index 984f0df3d0e..b78b8dadc77 100644
--- a/mysql-test/r/mdl_sync.result
+++ b/mysql-test/r/mdl_sync.result
@@ -2381,3 +2381,17 @@ commit;
# Reap ALTER TABLE.
set debug_sync= 'RESET';
drop table t1;
+#
+# Bug#52856 concurrent show columns or show full columns causes a crash!!!
+#
+CREATE TABLE t1(a CHAR(255));
+SET DEBUG_SYNC= "get_schema_column SIGNAL waiting WAIT_FOR completed";
+SHOW FULL COLUMNS FROM t1;
+SET DEBUG_SYNC= "now WAIT_FOR waiting";
+SHOW FULL COLUMNS FROM t1;
+Field Type Collation Null Key Default Extra Privileges Comment
+a char(255) latin1_swedish_ci YES NULL #
+SET DEBUG_SYNC= "now SIGNAL completed";
+Field Type Collation Null Key Default Extra Privileges Comment
+a char(255) latin1_swedish_ci YES NULL #
+DROP TABLE t1;
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index ff9b1a84dbc..e46d8e75ab1 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -277,7 +277,7 @@ t3 CREATE TABLE `t3` (
drop table t3,t2,t1;
create table t1 (a int not null, key(a)) engine=merge;
select * from t1;
-ERROR HY000: Got error 124 from storage engine
+a
drop table t1;
create table t1 (a int not null, b int not null, key(a,b));
create table t2 (a int not null, b int not null, key(a,b));
@@ -988,6 +988,11 @@ m1 CREATE TABLE `m1` (
`a` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1, m1;
+CREATE TABLE t1(a INT, KEY(a)) ENGINE=merge;
+SELECT MAX(a) FROM t1;
+MAX(a)
+NULL
+DROP TABLE t1;
CREATE TABLE t1(a INT);
CREATE TABLE t2(a VARCHAR(10));
CREATE TABLE m1(a INT) ENGINE=MERGE UNION=(t1, t2);
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index fa0233ac3a0..e366c5d1110 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -2315,6 +2315,8 @@ INSERT INTO t1 SELECT a+1280,b FROM t1;
INSERT INTO t1 SELECT a+2560,b FROM t1;
INSERT INTO t1 SELECT a+5120,b FROM t1;
SET myisam_sort_buffer_size=4;
+Warnings:
+Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '4'
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair error myisam_sort_buffer_size is too small
@@ -2365,6 +2367,8 @@ CREATE TABLE t1(a CHAR(255), KEY(a));
SELECT * FROM t1, t1 AS a1;
a a
SET myisam_sort_buffer_size=4;
+Warnings:
+Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '4'
INSERT INTO t1 VALUES
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result
index 55e68e9f8f3..e728eb8244d 100644
--- a/mysql-test/r/mysqlbinlog.result
+++ b/mysql-test/r/mysqlbinlog.result
@@ -720,7 +720,7 @@ FLUSH LOGS;
RESET MASTER;
FLUSH LOGS;
#
-# Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified is exist
+# Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified exists
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -773,7 +773,7 @@ DELIMITER ;
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
#
-# Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified is not exist
+# Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified does not exist
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -806,5 +806,76 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+#
+# Test if the 'SAVEPOINT', 'ROLLBACK TO' are output if the database specified exists
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+SET TIMESTAMP=1266652094/*!*/;
+SET @@session.pseudo_thread_id=999999999/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=0/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+BEGIN
+/*!*/;
+use test/*!*/;
+SET TIMESTAMP=1266652094/*!*/;
+SavePoint mixed_cases
+/*!*/;
+use db1/*!*/;
+SET TIMESTAMP=1266652094/*!*/;
+INSERT INTO db1.t2 VALUES("in savepoint mixed_cases")
+/*!*/;
+SET TIMESTAMP=1266652094/*!*/;
+INSERT INTO db1.t1 VALUES(40)
+/*!*/;
+use test/*!*/;
+SET TIMESTAMP=1266652094/*!*/;
+ROLLBACK TO mixed_cases
+/*!*/;
+use db1/*!*/;
+SET TIMESTAMP=1266652094/*!*/;
+INSERT INTO db1.t2 VALUES("after rollback to")
+/*!*/;
+SET TIMESTAMP=1266652094/*!*/;
+INSERT INTO db1.t1 VALUES(50)
+/*!*/;
+COMMIT/*!*/;
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+#
+# Test if the 'SAVEPOINT', 'ROLLBACK TO' are output if the database specified does not exist
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+SET TIMESTAMP=1266652094/*!*/;
+SET @@session.pseudo_thread_id=999999999/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=0/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+BEGIN
+/*!*/;
+use test/*!*/;
+SET TIMESTAMP=1266652094/*!*/;
+SavePoint mixed_cases
+/*!*/;
+SET TIMESTAMP=1266652094/*!*/;
+ROLLBACK TO mixed_cases
+/*!*/;
+COMMIT/*!*/;
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
End of 5.0 tests
End of 5.1 tests
diff --git a/mysql-test/r/mysqld--help-notwin.result b/mysql-test/r/mysqld--help-notwin.result
index 16b493cafec..5f1a25324ed 100644
--- a/mysql-test/r/mysqld--help-notwin.result
+++ b/mysql-test/r/mysqld--help-notwin.result
@@ -901,6 +901,7 @@ secure-file-priv (No default value)
server-id 0
show-slave-auth-info FALSE
skip-grant-tables TRUE
+skip-name-resolve FALSE
skip-networking FALSE
skip-show-database FALSE
skip-slave-start FALSE
diff --git a/mysql-test/r/mysqld--help-win.result b/mysql-test/r/mysqld--help-win.result
index ee2bcb51b04..5d517f06add 100644
--- a/mysql-test/r/mysqld--help-win.result
+++ b/mysql-test/r/mysqld--help-win.result
@@ -907,6 +907,7 @@ shared-memory FALSE
shared-memory-base-name MYSQL
show-slave-auth-info FALSE
skip-grant-tables TRUE
+skip-name-resolve FALSE
skip-networking FALSE
skip-show-database FALSE
skip-slave-start FALSE
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 5bb0524e187..892501f2b28 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -4561,5 +4561,20 @@ a b c
SET NAMES default;
DROP TABLE t1, t2;
#
+# Bug #53088: mysqldump with -T & --default-character-set set
+# truncates text/blob to 766 chars
+#
+# Also see outfile_loaddata.test
+#
+CREATE TABLE t1 (a BLOB) CHARSET latin1;
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t1 VALUES (REPEAT('.', 800));
+LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' INTO TABLE t2 CHARACTER SET latin1;
+# should be 800
+SELECT LENGTH(a) FROM t2;
+LENGTH(a)
+800
+DROP TABLE t1, t2;
+#
# End of 5.1 tests
#
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index 6827fd0bc76..fa5d8142baf 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -1618,3 +1618,32 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer
DROP TABLE t1, t2;
End of 5.1 tests
+#
+# Bug #38745: MySQL 5.1 optimizer uses filesort for ORDER BY
+# when it should use index
+#
+CREATE TABLE t1 (i1 integer NOT NULL PRIMARY KEY);
+CREATE TABLE t2 (i2 integer NOT NULL PRIMARY KEY);
+CREATE TABLE t3 (i3 integer);
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12);
+INSERT INTO t2 SELECT * FROM t1;
+EXPLAIN EXTENDED
+SELECT t1.*, t2.* FROM t1 JOIN t2 ON t1.i1 = t2.i2
+LEFT JOIN t3 ON t2.i2 = t3.i3
+ORDER BY t1.i1 LIMIT 5;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t3 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 5 240.00 Using index
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i1 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t2`.`i2` AS `i2` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`i2` = `test`.`t1`.`i1`) order by `test`.`t1`.`i1` limit 5
+SELECT t1.*, t2.* FROM t1 JOIN t2 ON t1.i1 = t2.i2
+LEFT JOIN t3 ON t2.i2 = t3.i3
+ORDER BY t1.i1 LIMIT 5;
+i1 i2
+1 1
+2 2
+3 3
+4 4
+5 5
+DROP TABLE t1, t2, t3;
diff --git a/mysql-test/r/outfile_loaddata.result b/mysql-test/r/outfile_loaddata.result
index 453e3adb54c..36a72fd84ce 100644
--- a/mysql-test/r/outfile_loaddata.result
+++ b/mysql-test/r/outfile_loaddata.result
@@ -239,4 +239,24 @@ a b c
2 NULL NULL
SET NAMES default;
DROP TABLE t1, t2;
+#
+# Bug #53088: mysqldump with -T & --default-character-set set
+# truncates text/blob to 766 chars
+#
+# Also see mysqldump.test
+#
+CREATE TABLE t1 (a BLOB) CHARSET latin1;
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t1 VALUES (REPEAT('.', 800));
+SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug53088.txt' CHARACTER SET latin1 FROM t1;
+# should be greater than 800
+SELECT LENGTH(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug53088.txt'));
+LENGTH(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug53088.txt'))
+801
+LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug53088.txt' INTO TABLE t2;
+# should be 800
+SELECT LENGTH(a) FROM t2;
+LENGTH(a)
+800
+DROP TABLE t1, t2;
# End of 5.1 tests.
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index 66f8ac68dfe..55366bd2e07 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -2173,4 +2173,15 @@ ERROR HY000: A UNIQUE INDEX must include all columns in the table's partitioning
SELECT * FROM t1;
s1
DROP TABLE t1;
+#
+# BUG#51868 - crash with myisam_use_mmap and partitioned myisam tables
+#
+SET GLOBAL myisam_use_mmap=1;
+CREATE TABLE t1(a INT) PARTITION BY HASH(a) PARTITIONS 1;
+INSERT INTO t1 VALUES(0);
+FLUSH TABLE t1;
+TRUNCATE TABLE t1;
+INSERT INTO t1 VALUES(0);
+DROP TABLE t1;
+SET GLOBAL myisam_use_mmap=default;
End of 5.1 tests
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 0b2002b1350..16f6657ceeb 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -155,24 +155,24 @@ execute stmt1 ;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
-5 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
-4 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
execute stmt1 ;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
-5 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
-4 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
-5 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
-4 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
deallocate prepare stmt1;
@@ -2992,6 +2992,19 @@ select @plaintext;
bcd
deallocate prepare encode;
deallocate prepare decode;
+#
+# Bug#52124 memory leaks like a sieve in datetime, timestamp, time, date fields + warnings
+#
+CREATE TABLE t1 (a DATETIME NOT NULL, b TINYINT);
+INSERT INTO t1 VALUES (0, 0),(0, 0);
+PREPARE stmt FROM "SELECT 1 FROM t1 WHERE
+ROW(a, b) >= ROW('1', (SELECT 1 FROM t1 WHERE a > 1234))";
+EXECUTE stmt;
+1
+EXECUTE stmt;
+1
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
End of 5.1 tests.
diff --git a/mysql-test/r/query_cache_with_views.result b/mysql-test/r/query_cache_with_views.result
index 03430bd504b..7f0417a60c7 100644
--- a/mysql-test/r/query_cache_with_views.result
+++ b/mysql-test/r/query_cache_with_views.result
@@ -193,4 +193,17 @@ show status like "Qcache_hits";
Variable_name Value
Qcache_hits 2
drop table t1;
+#
+# Bug46615 Assertion in Query_cache::invalidate in INSERT in a VIEW of a MERGE table
+#
+CREATE TABLE t1 (c1 INT, c2 INT);
+CREATE TABLE t2 LIKE t1;
+SET AUTOCOMMIT=OFF;
+CREATE VIEW t1_view AS SELECT c1 FROM t1 NATURAL JOIN t2 ;
+INSERT INTO t1_view (c1, c2) SELECT c1, c2 FROM t1;
+ERROR 42S22: Unknown column 'c2' in 'field list'
+DROP TABLE t1;
+DROP TABLE t2;
+DROP VIEW t1_view;
+SET AUTOCOMMIT=DEFAULT;
set GLOBAL query_cache_size=default;
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index aa04bfc25ea..4587a60ca0d 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -1653,4 +1653,48 @@ a b
0 0
1 1
DROP TABLE t1;
+#
+# Bug#50939: Loose Index Scan unduly relies on engine to remember range
+# endpoints
+#
+CREATE TABLE t1 (
+a INT,
+b INT,
+KEY ( a, b )
+) PARTITION BY HASH (a) PARTITIONS 1;
+CREATE TABLE t2 (
+a INT,
+b INT,
+KEY ( a, b )
+);
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
+INSERT INTO t1 SELECT a + 5, b + 5 FROM t1;
+INSERT INTO t1 SELECT a + 10, b + 10 FROM t1;
+INSERT INTO t1 SELECT a + 20, b + 20 FROM t1;
+INSERT INTO t1 SELECT a + 40, b + 40 FROM t1;
+INSERT INTO t2 SELECT * FROM t1;
+# plans should be identical
+EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10,100) GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index for group-by
+EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range a a 5 NULL 2 Using where; Using index for group-by
+FLUSH status;
+SELECT a, MAX(b) FROM t1 WHERE a IN (10, 100) GROUP BY a;
+a MAX(b)
+10 10
+# Should be no more than 4 reads.
+SHOW status LIKE 'handler_read_key';
+Variable_name Value
+Handler_read_key 4
+FLUSH status;
+SELECT a, MAX(b) FROM t2 WHERE a IN (10, 100) GROUP BY a;
+a MAX(b)
+10 10
+# Should be no more than 4 reads.
+SHOW status LIKE 'handler_read_key';
+Variable_name Value
+Handler_read_key 4
+DROP TABLE t1, t2;
End of 5.1 tests
diff --git a/mysql-test/r/renamedb.result b/mysql-test/r/renamedb.result
index ff8f89592fc..e77aca0d0b7 100644
--- a/mysql-test/r/renamedb.result
+++ b/mysql-test/r/renamedb.result
@@ -7,6 +7,6 @@ ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and n
ALTER DATABASE `#mysql51#not-yet` UPGRADE DATA DIRECTORY NAME;
ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name
ALTER DATABASE `#mysql50#` UPGRADE DATA DIRECTORY NAME;
-ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name
+ERROR 42000: Incorrect database name '#mysql50#'
ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
ERROR 42000: Unknown database '#mysql50#upgrade-me'
diff --git a/mysql-test/r/row.result b/mysql-test/r/row.result
index 2eaec67c547..2962123fcb2 100644
--- a/mysql-test/r/row.result
+++ b/mysql-test/r/row.result
@@ -457,3 +457,12 @@ abc 1 abc 1
select host,user from mysql.user where (host,user) = ('localhost','test');
host user
drop table t1,t2;
+#
+# Bug#52124 memory leaks like a sieve in datetime, timestamp, time, date fields + warnings
+#
+CREATE TABLE t1 (a DATETIME NOT NULL, b TINYINT);
+INSERT INTO t1 VALUES (0, 0),(0, 0);
+SELECT 1 FROM t1 WHERE ROW(a, b) >=
+ROW('1', (SELECT 1 FROM t1 WHERE a > 1234));
+1
+DROP TABLE t1;
diff --git a/mysql-test/r/skip_name_resolve.result b/mysql-test/r/skip_name_resolve.result
index 8aa9877a8e9..1d92d52110d 100644
--- a/mysql-test/r/skip_name_resolve.result
+++ b/mysql-test/r/skip_name_resolve.result
@@ -9,3 +9,30 @@ SELECT USER();
USER()
#
SHOW PROCESSLIST;
+#
+# Bug #37168: Missing variable - skip_name_resolve
+#
+SHOW VARIABLES LIKE 'skip_name_resolve';
+Variable_name Value
+skip_name_resolve ON
+SHOW GLOBAL VARIABLES LIKE 'skip_name_resolve';
+Variable_name Value
+skip_name_resolve ON
+SHOW SESSION VARIABLES LIKE 'skip_name_resolve';
+Variable_name Value
+skip_name_resolve ON
+SELECT @@skip_name_resolve;
+@@skip_name_resolve
+1
+SELECT @@LOCAL.skip_name_resolve;
+ERROR HY000: Variable 'skip_name_resolve' is a GLOBAL variable
+SELECT @@GLOBAL.skip_name_resolve;
+@@GLOBAL.skip_name_resolve
+1
+SET @@skip_name_resolve=0;
+ERROR HY000: Variable 'skip_name_resolve' is a read only variable
+SET @@LOCAL.skip_name_resolve=0;
+ERROR HY000: Variable 'skip_name_resolve' is a read only variable
+SET @@GLOBAL.skip_name_resolve=0;
+ERROR HY000: Variable 'skip_name_resolve' is a read only variable
+End of 5.1 tests
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index b23556887c1..e3aa87876ed 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -4899,3 +4899,92 @@ WHERE t1.a = d1.a;
ERROR 42S22: Unknown column 'd1.a' in 'where clause'
DROP TABLE t1;
End of 5.1 tests.
+Set up test tables.
+CREATE TABLE t1 (
+t1_id INT UNSIGNED,
+PRIMARY KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t1 (t1_id) VALUES (1), (2), (3), (4), (5);
+CREATE TABLE t2 SELECT * FROM t1;
+CREATE TABLE t3 (
+t3_id INT UNSIGNED AUTO_INCREMENT,
+t1_id INT UNSIGNED,
+amount DECIMAL(16,2),
+PRIMARY KEY(t3_id),
+KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t3 (t1_id, t3_id, amount)
+VALUES (1, 1, 100.00), (2, 2, 200.00), (4, 4, 400.00);
+This is the 'inner query' running by itself.
+Produces correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query)
+Produces correct results.
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+Now make t2.t1_id part of a key.
+ALTER TABLE t2 ADD PRIMARY KEY(t1_id);
+Same inner query by itself.
+Still correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0
+4 400.00
+5 0
+SELECT * FROM (the same inner query), now with indexes on the LEFT JOIN
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+DROP TABLE t3;
+DROP TABLE t2;
+DROP TABLE t1;
diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result
index 245dcec04da..4dac7443135 100644
--- a/mysql-test/r/symlink.result
+++ b/mysql-test/r/symlink.result
@@ -168,4 +168,16 @@ Warning 1618 <DATA DIRECTORY> option ignored
Warning 1618 <INDEX DIRECTORY> option ignored
DROP TABLE t1;
SET @@SQL_MODE=@OLD_SQL_MODE;
+#
+# BUG#40980 - Drop table can remove another MyISAM table's
+# data and index files
+#
+CREATE TABLE user(a INT) DATA DIRECTORY='MYSQL_TMP_DIR/mysql'
+ INDEX DIRECTORY='MYSQL_TMP_DIR/mysql';
+FLUSH TABLE user;
+# Symlinking mysql database to tmpdir
+FLUSH TABLE mysql.user;
+DROP TABLE user;
+FLUSH TABLE mysql.user;
+SELECT * FROM mysql.user;
End of 5.1 tests
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index 90d6071a767..36d82e4045f 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -2111,6 +2111,44 @@ SET @bug51650 = 1;
INSERT IGNORE INTO t2 SET a = '777';
DROP TRIGGER trg1;
DROP TABLE t1, t2;
+CREATE TABLE t1 (id INT NOT NULL);
+CREATE TABLE t2 (id INT NOT NULL);
+INSERT t1 VALUES (1),(2),(3);
+UPDATE t1 SET id=NULL;
+Warnings:
+Warning 1048 Column 'id' cannot be null
+Warning 1048 Column 'id' cannot be null
+Warning 1048 Column 'id' cannot be null
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+INSERT INTO t2 VALUES (3);
+UPDATE t1 SET id=NULL;
+Warnings:
+Warning 1048 Column 'id' cannot be null
+Warning 1048 Column 'id' cannot be null
+Warning 1048 Column 'id' cannot be null
+DROP TRIGGER t1_bu;
+DROP TABLE t1,t2;
+#
+# Bug#50755: Crash if stored routine def contains version comments
+#
+DROP DATABASE IF EXISTS db1;
+DROP TRIGGER IF EXISTS trg1;
+DROP TABLE IF EXISTS t1, t2;
+CREATE DATABASE db1;
+USE db1;
+CREATE TABLE t1 (b INT);
+CREATE TABLE t2 (a INT);
+CREATE TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERT/*!INTO*/t1 VALUES (1);
+# Used to crash
+SHOW TRIGGERS IN db1;
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+INSERT INTO t2 VALUES (1);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES (1)' at line 1
+SELECT * FROM t1;
+b
+# Work around Bug#45235
+DROP DATABASE db1;
+USE test;
End of 5.1 tests.
#
# Bug#34453 Can't change size of file (Errcode: 1224)
diff --git a/mysql-test/r/type_binary.result b/mysql-test/r/type_binary.result
index 01841bf27fc..b00d1585b29 100644
--- a/mysql-test/r/type_binary.result
+++ b/mysql-test/r/type_binary.result
@@ -47,7 +47,7 @@ create table t1 (s1 binary(2) primary key);
insert into t1 values (0x01);
insert into t1 values (0x0120);
insert into t1 values (0x0100);
-ERROR 23000: Duplicate entry '\x01\x00' for key 'PRIMARY'
+ERROR 23000: Duplicate entry '\x01' for key 'PRIMARY'
select hex(s1) from t1 order by s1;
hex(s1)
0100
diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result
index d131fa2b4d5..d08f86909ba 100644
--- a/mysql-test/r/type_decimal.result
+++ b/mysql-test/r/type_decimal.result
@@ -966,3 +966,31 @@ max(case 1 when 1 then c else null end)
300.00
drop table t1;
End of 5.0 tests
+CREATE TABLE t1 (a INTEGER);
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2 (b INTEGER);
+INSERT INTO t2 VALUES (NULL), (NULL);
+SELECT b FROM t1 JOIN t2 WHERE CONVERT(a, DECIMAL)|CONVERT(b, DECIMAL);
+b
+DROP TABLE t1, t2;
+CREATE TABLE t1 (col0 INTEGER, col1 REAL);
+CREATE TABLE t2 (col0 INTEGER);
+INSERT INTO t1 VALUES (0, 0.0), (NULL, NULL);
+INSERT INTO t2 VALUES (1);
+SELECT 1 FROM t1
+JOIN
+(
+SELECT t2.col0 FROM t2 RIGHT JOIN t1 USING(col0)
+GROUP BY t2.col0
+) AS subq
+WHERE t1.col1 + CAST(subq.col0 AS DECIMAL);
+1
+SELECT 1 FROM t1
+JOIN
+(
+SELECT t2.col0 FROM t2 RIGHT JOIN t1 USING(col0)
+GROUP BY t2.col0
+) AS subq
+WHERE CONCAT(t1.col1, CAST(subq.col0 AS DECIMAL));
+1
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/upgrade.result b/mysql-test/r/upgrade.result
index 034242079b1..da2f55b5bb1 100644
--- a/mysql-test/r/upgrade.result
+++ b/mysql-test/r/upgrade.result
@@ -112,3 +112,31 @@ select * from `a-b-c`.v1;
f1
drop database `a-b-c`;
use test;
+# End of 5.0 tests
+#
+# Bug #53804: serious flaws in the alter database .. upgrade data
+# directory name command
+#
+ALTER DATABASE `#mysql50#:` UPGRADE DATA DIRECTORY NAME;
+ERROR 42000: Unknown database '#mysql50#:'
+ALTER DATABASE `#mysql50#.` UPGRADE DATA DIRECTORY NAME;
+ERROR 42000: Incorrect database name '#mysql50#.'
+ALTER DATABASE `#mysql50#../` UPGRADE DATA DIRECTORY NAME;
+ERROR 42000: Incorrect database name '#mysql50#../'
+ALTER DATABASE `#mysql50#../..` UPGRADE DATA DIRECTORY NAME;
+ERROR 42000: Incorrect database name '#mysql50#../..'
+ALTER DATABASE `#mysql50#../../` UPGRADE DATA DIRECTORY NAME;
+ERROR 42000: Incorrect database name '#mysql50#../../'
+ALTER DATABASE `#mysql50#./blablabla` UPGRADE DATA DIRECTORY NAME;
+ERROR 42000: Incorrect database name '#mysql50#./blablabla'
+ALTER DATABASE `#mysql50#../blablabla` UPGRADE DATA DIRECTORY NAME;
+ERROR 42000: Incorrect database name '#mysql50#../blablabla'
+ALTER DATABASE `#mysql50#/` UPGRADE DATA DIRECTORY NAME;
+ERROR 42000: Incorrect database name '#mysql50#/'
+ALTER DATABASE `#mysql50#/.` UPGRADE DATA DIRECTORY NAME;
+ERROR 42000: Incorrect database name '#mysql50#/.'
+USE `#mysql50#.`;
+ERROR 42000: Incorrect database name '#mysql50#.'
+USE `#mysql50#../blablabla`;
+ERROR 42000: Incorrect database name '#mysql50#../blablabla'
+# End of 5.1 tests
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index b46f7c3bada..b4cfc28319b 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -526,6 +526,8 @@ select @@max_user_connections;
100
set global max_write_lock_count=100;
set myisam_sort_buffer_size=100;
+Warnings:
+Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '100'
set global net_buffer_length=100;
Warnings:
Warning 1292 Truncated incorrect net_buffer_length value: '100'
@@ -1493,6 +1495,15 @@ SELECT @@GLOBAL.max_binlog_cache_size;
@@GLOBAL.max_binlog_cache_size
5368709120
SET GLOBAL max_binlog_cache_size = @old_max_binlog_cache_size;
+#
+# Bug #37168 : Missing variable - skip_name_resolve
+#
+SELECT @@skip_name_resolve;
+@@skip_name_resolve
+0
+SHOW VARIABLES LIKE 'skip_name_resolve';
+Variable_name Value
+skip_name_resolve OFF
End of 5.1 tests
#
diff --git a/mysql-test/r/variables_debug.result b/mysql-test/r/variables_debug.result
index 89a3202b731..a02d285b15b 100644
--- a/mysql-test/r/variables_debug.result
+++ b/mysql-test/r/variables_debug.result
@@ -1,3 +1,4 @@
+SET @old_debug = @@GLOBAL.debug;
set debug= 'T';
select @@debug;
@@debug
@@ -17,3 +18,17 @@ SET SESSION debug = '';
SELECT @@session.debug, @@global.debug;
@@session.debug @@global.debug
+#
+# Bug #52629: memory leak from sys_var_thd_dbug in
+# binlog.binlog_write_error
+#
+SET GLOBAL debug='d,injecting_fault_writing';
+SELECT @@global.debug;
+@@global.debug
+d,injecting_fault_writing
+SET GLOBAL debug='';
+SELECT @@global.debug;
+@@global.debug
+
+SET GLOBAL debug=@old_debug;
+End of 5.1 tests
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index b7660dbcbd8..95d2827c1a6 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -3986,6 +3986,14 @@ CREATE VIEW v1 AS SELECT 1 FROM t1 WHERE
ROW(1,1) >= ROW(1, (SELECT 1 FROM t1 WHERE f1 >= ANY ( SELECT '1' )));
DROP VIEW v1;
DROP TABLE t1;
+#
+# Bug#52120 create view cause Assertion failed: 0, file .\item_subselect.cc, line 817
+#
+CREATE TABLE t1 (a CHAR(1) CHARSET latin1, b CHAR(1) CHARSET utf8);
+CREATE VIEW v1 AS SELECT 1 from t1
+WHERE t1.b <=> (SELECT a FROM t1 WHERE a < SOME(SELECT '1'));
+DROP VIEW v1;
+DROP TABLE t1;
# -----------------------------------------------------------------
# -- End of 5.1 tests.
# -----------------------------------------------------------------
diff --git a/mysql-test/std_data/binlog_savepoint.000001 b/mysql-test/std_data/binlog_savepoint.000001
new file mode 100644
index 00000000000..5109042a184
--- /dev/null
+++ b/mysql-test/std_data/binlog_savepoint.000001
Binary files differ
diff --git a/mysql-test/std_data/bug46565.ARZ b/mysql-test/std_data/bug46565.ARZ
new file mode 100644
index 00000000000..f26b31218a1
--- /dev/null
+++ b/mysql-test/std_data/bug46565.ARZ
Binary files differ
diff --git a/mysql-test/std_data/bug46565.frm b/mysql-test/std_data/bug46565.frm
new file mode 100644
index 00000000000..5c0180bdc1e
--- /dev/null
+++ b/mysql-test/std_data/bug46565.frm
Binary files differ
diff --git a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
index a15e6808a09..6643c4557c2 100644
--- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
+++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
@@ -53,10 +53,10 @@ master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; savepoint my_savepoint
+master-bin.000001 # Query # # SAVEPOINT my_savepoint
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; rollback to savepoint my_savepoint
+master-bin.000001 # Query # # ROLLBACK TO my_savepoint
master-bin.000001 # Xid # # COMMIT /* XID */
delete from t1;
delete from t2;
@@ -84,10 +84,10 @@ master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; savepoint my_savepoint
+master-bin.000001 # Query # # SAVEPOINT my_savepoint
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; rollback to savepoint my_savepoint
+master-bin.000001 # Query # # ROLLBACK TO my_savepoint
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
@@ -848,11 +848,11 @@ delete from t4;
insert into t3 values (1,1),(2,2);
insert into t4 values (1,1),(2,2);
reset master;
-UPDATE t3,t4 SET t3.a=t4.a + bug27417(1);
+UPDATE t3,t4 SET t3.a = t4.a + bug27417(1) where t3.a = 1;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
select count(*) from t1 /* must be 1 */;
count(*)
-2
+1
drop table t4;
delete from t1;
delete from t2;
diff --git a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result
index 837aafb9ae7..cea3819cad3 100644
--- a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result
@@ -51,10 +51,10 @@ show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; insert into t1 values(3)
-master-bin.000001 # Query # # use `test`; savepoint my_savepoint
+master-bin.000001 # Query # # SAVEPOINT my_savepoint
master-bin.000001 # Query # # use `test`; insert into t1 values(4)
master-bin.000001 # Query # # use `test`; insert into t2 select * from t1
-master-bin.000001 # Query # # use `test`; rollback to savepoint my_savepoint
+master-bin.000001 # Query # # ROLLBACK TO my_savepoint
master-bin.000001 # Xid # # COMMIT /* XID */
delete from t1;
delete from t2;
@@ -79,10 +79,10 @@ show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; insert into t1 values(5)
-master-bin.000001 # Query # # use `test`; savepoint my_savepoint
+master-bin.000001 # Query # # SAVEPOINT my_savepoint
master-bin.000001 # Query # # use `test`; insert into t1 values(6)
master-bin.000001 # Query # # use `test`; insert into t2 select * from t1
-master-bin.000001 # Query # # use `test`; rollback to savepoint my_savepoint
+master-bin.000001 # Query # # ROLLBACK TO my_savepoint
master-bin.000001 # Query # # use `test`; insert into t1 values(7)
master-bin.000001 # Xid # # COMMIT /* XID */
delete from t1;
@@ -886,7 +886,7 @@ delete from t4;
insert into t3 values (1,1),(2,2);
insert into t4 values (1,1),(2,2);
reset master;
-UPDATE t3,t4 SET t3.a=t4.a + bug27417(1);
+UPDATE t3,t4 SET t3.a = t4.a + bug27417(1) where t3.a = 1;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
select count(*) from t1 /* must be 1 */;
count(*)
diff --git a/mysql-test/suite/engines/README b/mysql-test/suite/engines/README
index 3ff6fccc689..0f89d5af67f 100644
--- a/mysql-test/suite/engines/README
+++ b/mysql-test/suite/engines/README
@@ -50,22 +50,22 @@ The following suites are included:
Known Issues
------------
-1) The 'funcs' and 'iuds' suites currently runs only against MySQL 5.1 server.
- Running them against MySQL 5.5 will generate errors.
-
-2) The folowing tests in the 'iuds' suite:
+1) The folowing tests in the 'iuds' suite:
- delete_decimal
- insert_decimal
- update_decimal
will return a 'Warning 1264 - Out of range value...' warning if run in a 32-bit environment.
Add the '--force' option to prevent the test run from aborting.
-3) The following tests in the 'funcs' suite will fail when run against the innodb_plugin:
+2) The following tests in the 'funcs' suite will fail when run against the innodb_plugin:
- crash_manycolumns_string (bug 50495)
- ix_unique_lob (bug 52056, masked by an 'Out of memory error' on some 32-bit platforms)
- ix_unique_string_length (bug 52056, masked by an 'Out of memory error' on some 32-bit platforms)
Add the '--force' option to prevent the test run from aborting.
-4) Some of the rpl_xxx tests in the 'funcs' suite require a secific binlog_forat setting and will be
+3) Some of the rpl_xxx tests in the 'funcs' suite require a secific binlog_forat setting and will be
skipped otherwise.
+4) Some of the rpl_xxx tests in the 'funcs' suite will report a 'Statement unsafe for replication' warning
+ when run againsr a server configured to use statement based replication.
+
diff --git a/mysql-test/suite/engines/iuds/r/update_delete_calendar.result b/mysql-test/suite/engines/iuds/r/update_delete_calendar.result
index a04585dfd72..e2dd83e03b4 100644
--- a/mysql-test/suite/engines/iuds/r/update_delete_calendar.result
+++ b/mysql-test/suite/engines/iuds/r/update_delete_calendar.result
@@ -791,9 +791,6 @@ Warning 1292 Truncated incorrect datetime value: '2009-01-10 23:60:59'
SELECT count(*) FROM t1 WHERE c2='2001-01-11 23:59:60' /* returns 0 */;
count(*)
0
-Warnings:
-Warning 1292 Incorrect datetime value: '2001-01-11 23:59:60' for column 'c2' at row 1
-Warning 1292 Incorrect datetime value: '2001-01-11 23:59:60' for column 'c2' at row 1
SELECT * FROM t1 WHERE c1='0000-00-00 00:00:00' OR c2='0000-00-00 00:00:00';
c1 c2 c3
0000-00-00 00:00:00 0000-00-00 00:00:00 6
diff --git a/mysql-test/suite/engines/iuds/t/disabled.def b/mysql-test/suite/engines/iuds/t/disabled.def
index 7fd504c0996..c8fdf80274b 100644
--- a/mysql-test/suite/engines/iuds/t/disabled.def
+++ b/mysql-test/suite/engines/iuds/t/disabled.def
@@ -1,3 +1,2 @@
insert_calendar : Bug#52283 Innodb reports extra warnings when SELECT/WHERE is performed using invalid value
update_delete_calendar : Bug#52824 + Bug#52283(in case of Innodb)
-
diff --git a/mysql-test/suite/engines/iuds/t/insert_number.test b/mysql-test/suite/engines/iuds/t/insert_number.test
index e2c809fad85..b55bd8dc98a 100644
--- a/mysql-test/suite/engines/iuds/t/insert_number.test
+++ b/mysql-test/suite/engines/iuds/t/insert_number.test
@@ -7812,6 +7812,9 @@ SELECT * FROM t2 ORDER BY c1,c6 LIMIT 2;
SELECT * FROM t2 ORDER BY c1,c6 DESC LIMIT 2;
## ref type access
+
+# Bug#52283 : Remove the following --disable_warnings
+# command when the bug is fixed
--disable_warnings
SELECT * FROM t2 WHERE c1 = 18446744073709551616 ORDER BY c1,c6;
SELECT * FROM t2 WHERE c1 = 18446744073709551616 ORDER BY c1,c6 LIMIT 2;
diff --git a/mysql-test/suite/engines/iuds/t/update_delete_calendar.test b/mysql-test/suite/engines/iuds/t/update_delete_calendar.test
index aa695953ce1..c6a22511766 100644
--- a/mysql-test/suite/engines/iuds/t/update_delete_calendar.test
+++ b/mysql-test/suite/engines/iuds/t/update_delete_calendar.test
@@ -300,7 +300,12 @@ INSERT INTO t1 VALUES('2001-01-09','2001-01-10',6),('2001-01-11','2001-01-12',7)
UPDATE t1 SET c1='2001-01-09 24:59:59',c2='2009-01-10 23:60:59' WHERE c1='2001-01-09';
UPDATE t1 SET c2='2001-01-11 23:59:60' WHERE c1='2001-01-11';
SELECT count(*) FROM t1 WHERE c1='2001-01-09 24:59:59' AND c2='2009-01-10 23:60:59';
+
+# Bug#52283 : Remove the following --disable_warnings
+# command when the bug is fixed
+--disable_warnings
SELECT count(*) FROM t1 WHERE c2='2001-01-11 23:59:60' /* returns 0 */;
+--enable_warnings
--sorted_result
SELECT * FROM t1 WHERE c1='0000-00-00 00:00:00' OR c2='0000-00-00 00:00:00';
diff --git a/mysql-test/suite/parts/r/partition_debug_sync_innodb.result b/mysql-test/suite/parts/r/partition_debug_sync_innodb.result
new file mode 100644
index 00000000000..9e72259a150
--- /dev/null
+++ b/mysql-test/suite/parts/r/partition_debug_sync_innodb.result
@@ -0,0 +1,61 @@
+#
+# Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with
+# concurrent I_S query
+create table t1 (a int)
+engine = innodb
+partition by range (a)
+(partition p0 values less than MAXVALUE);
+insert into t1 values (1), (11), (21), (33);
+SELECT * FROM t1;
+a
+1
+11
+21
+33
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY RANGE (a)
+(PARTITION p0 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
+t1#P#p0.ibd
+t1.frm
+t1.par
+SET DEBUG_SYNC='before_open_in_get_all_tables SIGNAL parked WAIT_FOR open';
+SET DEBUG_SYNC='partition_open_error SIGNAL alter WAIT_FOR finish';
+SELECT * FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't1' AND TABLE_SCHEMA = 'test';
+SET DEBUG_SYNC = 'now WAIT_FOR parked';
+# When waiting for the name lock in get_all_tables in sql_show.cc
+# this will not be concurrent any more, thus the TIMEOUT
+SET DEBUG_SYNC = 'before_rename_partitions SIGNAL open WAIT_FOR alter TIMEOUT 1';
+# Needs to be executed twice, since first is this 'SET DEBUG_SYNC ...'
+SET DEBUG_SYNC = 'before_close_thread_tables SIGNAL finish EXECUTE 2';
+ALTER TABLE t1 REORGANIZE PARTITION p0 INTO
+(PARTITION p0 VALUES LESS THAN (10),
+PARTITION p10 VALUES LESS THAN MAXVALUE);
+Warnings:
+Warning 1639 debug sync point wait timed out
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PARTITION_NAME SUBPARTITION_NAME PARTITION_ORDINAL_POSITION SUBPARTITION_ORDINAL_POSITION PARTITION_METHOD SUBPARTITION_METHOD PARTITION_EXPRESSION SUBPARTITION_EXPRESSION PARTITION_DESCRIPTION TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE CREATE_TIME UPDATE_TIME CHECK_TIME CHECKSUM PARTITION_COMMENT NODEGROUP TABLESPACE_NAME
+def test t1 p0 NULL 1 NULL RANGE NULL a NULL 10 1 16384 16384 NULL 0 0 NULL NULL NULL NULL default NULL
+def test t1 p10 NULL 2 NULL RANGE NULL a NULL MAXVALUE 3 5461 16384 NULL 0 0 NULL NULL NULL NULL default NULL
+t1#P#p0.ibd
+t1#P#p10.ibd
+t1.frm
+t1.par
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY RANGE (a)
+(PARTITION p0 VALUES LESS THAN (10) ENGINE = InnoDB,
+ PARTITION p10 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
+SELECT * FROM t1;
+a
+1
+11
+21
+33
+drop table t1;
+SET DEBUG_SYNC = 'RESET';
diff --git a/mysql-test/suite/parts/t/partition_debug_sync_innodb-master.opt b/mysql-test/suite/parts/t/partition_debug_sync_innodb-master.opt
new file mode 100644
index 00000000000..9854fda301d
--- /dev/null
+++ b/mysql-test/suite/parts/t/partition_debug_sync_innodb-master.opt
@@ -0,0 +1 @@
+--innodb_file_per_table=1
diff --git a/mysql-test/suite/parts/t/partition_debug_sync_innodb.test b/mysql-test/suite/parts/t/partition_debug_sync_innodb.test
new file mode 100644
index 00000000000..79ef3d537bf
--- /dev/null
+++ b/mysql-test/suite/parts/t/partition_debug_sync_innodb.test
@@ -0,0 +1,44 @@
+--source include/have_innodb.inc
+--source include/have_partition.inc
+--source include/have_debug_sync.inc
+
+let $MYSQLD_DATADIR=`SELECT @@datadir`;
+
+--echo #
+--echo # Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with
+--echo # concurrent I_S query
+create table t1 (a int)
+engine = innodb
+partition by range (a)
+(partition p0 values less than MAXVALUE);
+insert into t1 values (1), (11), (21), (33);
+SELECT * FROM t1;
+SHOW CREATE TABLE t1;
+--list_files $MYSQLD_DATADIR/test
+
+SET DEBUG_SYNC='before_open_in_get_all_tables SIGNAL parked WAIT_FOR open';
+SET DEBUG_SYNC='partition_open_error SIGNAL alter WAIT_FOR finish';
+send
+SELECT * FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't1' AND TABLE_SCHEMA = 'test';
+
+connect (con1, localhost, root,,);
+SET DEBUG_SYNC = 'now WAIT_FOR parked';
+--echo # When waiting for the name lock in get_all_tables in sql_show.cc
+--echo # this will not be concurrent any more, thus the TIMEOUT
+SET DEBUG_SYNC = 'before_rename_partitions SIGNAL open WAIT_FOR alter TIMEOUT 1';
+--echo # Needs to be executed twice, since first is this 'SET DEBUG_SYNC ...'
+SET DEBUG_SYNC = 'before_close_thread_tables SIGNAL finish EXECUTE 2';
+--error 0,ER_TABLE_EXISTS_ERROR
+ALTER TABLE t1 REORGANIZE PARTITION p0 INTO
+(PARTITION p0 VALUES LESS THAN (10),
+ PARTITION p10 VALUES LESS THAN MAXVALUE);
+
+disconnect con1;
+connection default;
+--reap
+--list_files $MYSQLD_DATADIR/test
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+drop table t1;
+--list_files $MYSQLD_DATADIR/test
+SET DEBUG_SYNC = 'RESET';
diff --git a/mysql-test/suite/rpl/r/rpl_begin_commit_rollback.result b/mysql-test/suite/rpl/r/rpl_begin_commit_rollback.result
index dedfa1e8355..1ed7e0116a2 100644
--- a/mysql-test/suite/rpl/r/rpl_begin_commit_rollback.result
+++ b/mysql-test/suite/rpl/r/rpl_begin_commit_rollback.result
@@ -8,7 +8,9 @@ call mtr.add_suppression("Unsafe statement written to the binary log using state
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
SET @@session.binlog_direct_non_transactional_updates= FALSE;
DROP DATABASE IF EXISTS db1;
+DROP DATABASE IF EXISTS db2;
CREATE DATABASE db1;
+CREATE DATABASE db2;
use db1;
CREATE TABLE db1.t1 (a INT) ENGINE=InnoDB;
CREATE TABLE db1.t2 (s CHAR(255)) ENGINE=MyISAM;
@@ -107,8 +109,72 @@ SELECT * from db1.t2;
s
before call db1.p1()
executed db1.p2()
+START SLAVE;
+#
+# SAVEPOINT and ROLLBACK TO have the same problem in BUG#43263
+# This was reported by BUG#50407
+[on master]
+SET SESSION AUTOCOMMIT=0
+BEGIN;
+INSERT INTO db1.t1 VALUES(20);
+#
+# Verify whether this statement is binlogged correctly
+/*comment*/ SAVEPOINT has_comment;
+USE db1;
+INSERT INTO db1.t1 VALUES(30);
+INSERT INTO db1.t2 VALUES("in savepoint has_comment");
+Warnings:
+Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
+USE db2;
+SavePoint mixed_cases;
+USE db1;
+INSERT INTO db1.t2 VALUES("in savepoint mixed_cases");
+Warnings:
+Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
+INSERT INTO db1.t1 VALUES(40);
+USE db2;
+ROLLBACK TO mixed_cases;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+ROLLBACK TO has_comment;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+USE db1;
+INSERT INTO db1.t2 VALUES("after rollback to");
+Warnings:
+Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.
+INSERT INTO db1.t1 VALUES(50);
+USE db2;
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO db1.t1 VALUES(20)
+master-bin.000001 # Query # # SAVEPOINT has_comment
+master-bin.000001 # Query # # use `db1`; INSERT INTO db1.t1 VALUES(30)
+master-bin.000001 # Query # # use `db1`; INSERT INTO db1.t2 VALUES("in savepoint has_comment")
+master-bin.000001 # Query # # SAVEPOINT mixed_cases
+master-bin.000001 # Query # # use `db1`; INSERT INTO db1.t2 VALUES("in savepoint mixed_cases")
+master-bin.000001 # Query # # use `db1`; INSERT INTO db1.t1 VALUES(40)
+master-bin.000001 # Query # # ROLLBACK TO mixed_cases
+master-bin.000001 # Query # # ROLLBACK TO has_comment
+master-bin.000001 # Query # # use `db1`; INSERT INTO db1.t2 VALUES("after rollback to")
+master-bin.000001 # Query # # use `db1`; INSERT INTO db1.t1 VALUES(50)
+master-bin.000001 # Xid # # COMMIT /* XID */
+[on slave]
+#
+# Verify INSERT statements in savepoints are executed, for MyISAM table
+# is not effected by ROLLBACK TO
+SELECT * FROM db1.t2 WHERE s LIKE '% savepoint %';
+s
+in savepoint has_comment
+in savepoint mixed_cases
+#
+# Verify INSERT statements on the Innodb table are rolled back;
+SELECT * FROM db1.t1 WHERE a IN (30, 40);
+a
#
# Clean up
#
DROP DATABASE db1;
-DROP DATABASE db1;
+DROP DATABASE db2;
diff --git a/mysql-test/suite/rpl/r/rpl_do_grant.result b/mysql-test/suite/rpl/r/rpl_do_grant.result
index 9eecc1bab3f..1cea2cfa9ad 100644
--- a/mysql-test/suite/rpl/r/rpl_do_grant.result
+++ b/mysql-test/suite/rpl/r/rpl_do_grant.result
@@ -246,4 +246,18 @@ GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
DROP TABLE t1;
DROP PROCEDURE p1;
DROP USER 'user49119'@'localhost';
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+grant all on *.* to foo@"1.2.3.4";
+revoke all privileges, grant option from "foo";
+ERROR HY000: Can't revoke all privileges for one or more of the requested users
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; grant all on *.* to foo@"1.2.3.4"
+master-bin.000001 # Query # # use `test`; revoke all privileges, grant option from "foo"
+DROP USER foo@"1.2.3.4";
"End of test"
diff --git a/mysql-test/suite/rpl/r/rpl_events.result b/mysql-test/suite/rpl/r/rpl_events.result
index 11ebb760e86..7d4e8a208eb 100644
--- a/mysql-test/suite/rpl/r/rpl_events.result
+++ b/mysql-test/suite/rpl/r/rpl_events.result
@@ -118,8 +118,14 @@ CREATE /*!50000 DEFINER='user44331' */ EVENT event44331_4
ON SCHEDULE AT CURRENT_TIMESTAMP
ON COMPLETION PRESERVE DISABLE
DO INSERT INTO test.t1 VALUES('event event44331_4 fired - DEFINER=user1');
-Warnings:
-Note 1449 The user specified as a definer ('user44331'@'%') does not exist
+# Test for bug#50095 Multi-statement including CREATE EVENT causes rotten
+# binlog entry
+SELECT 'ABC';
+SELECT '123'|
+ABC
+ABC
+123
+123
#on master
select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events
where EVENT_NAME='event44331_1';
diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result
index 88fe7bce4f6..579c5489823 100644
--- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result
+++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result
@@ -996,7 +996,7 @@ master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES (3, 'before
master-bin.000001 # Xid 1 # #
master-bin.000001 # Query 1 # BEGIN
master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES (5, 'before savepoint s2')
-master-bin.000001 # Query 1 # use `test_rpl`; SAVEPOINT s2
+master-bin.000001 # Query 1 # SAVEPOINT s2
master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES (6, 'after savepoint s2')
master-bin.000001 # Table_map 1 # table_id: # (test_rpl.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
diff --git a/mysql-test/suite/rpl/r/rpl_mixed_mixing_engines.result b/mysql-test/suite/rpl/r/rpl_mixed_mixing_engines.result
index fd7df68640e..e7e4e1b8aa4 100644
--- a/mysql-test/suite/rpl/r/rpl_mixed_mixing_engines.result
+++ b/mysql-test/suite/rpl/r/rpl_mixed_mixing_engines.result
@@ -10762,9 +10762,9 @@ COMMIT;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (318, 4)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (318, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B N T S1 T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -10774,9 +10774,9 @@ master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VA
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (318, 4)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (318, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B N T S1 T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -10815,9 +10815,9 @@ COMMIT;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (319, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (319, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T N S1 T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -10828,9 +10828,9 @@ master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (319, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (319, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B T N S1 T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -10869,9 +10869,9 @@ COMMIT;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (320, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (320, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T S1 N T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -10882,9 +10882,9 @@ master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (320, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (320, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B T S1 N T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -11852,20 +11852,20 @@ ROLLBACK;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (353, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (353, 5)
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tt_xx_12 (a int) engine=Innodb
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Query # # ROLLBACK
-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T S1 T CT R1 R << -b-b-b-b-b-b-b-b-b-b-b-
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (353, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (353, 5)
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tt_xx_12 (a int) engine=Innodb
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Query # # ROLLBACK
-e-e-e-e-e-e-e-e-e-e-e- >> B T S1 T CT R1 R << -e-e-e-e-e-e-e-e-e-e-e-
diff --git a/mysql-test/suite/rpl/r/rpl_non_direct_mixed_mixing_engines.result b/mysql-test/suite/rpl/r/rpl_non_direct_mixed_mixing_engines.result
index fd7df68640e..e7e4e1b8aa4 100644
--- a/mysql-test/suite/rpl/r/rpl_non_direct_mixed_mixing_engines.result
+++ b/mysql-test/suite/rpl/r/rpl_non_direct_mixed_mixing_engines.result
@@ -10762,9 +10762,9 @@ COMMIT;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (318, 4)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (318, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B N T S1 T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -10774,9 +10774,9 @@ master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VA
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (318, 4)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (318, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B N T S1 T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -10815,9 +10815,9 @@ COMMIT;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (319, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (319, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T N S1 T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -10828,9 +10828,9 @@ master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (319, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (319, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B T N S1 T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -10869,9 +10869,9 @@ COMMIT;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (320, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (320, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T S1 N T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -10882,9 +10882,9 @@ master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (320, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (320, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B T S1 N T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -11852,20 +11852,20 @@ ROLLBACK;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (353, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (353, 5)
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tt_xx_12 (a int) engine=Innodb
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Query # # ROLLBACK
-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T S1 T CT R1 R << -b-b-b-b-b-b-b-b-b-b-b-
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (353, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (353, 5)
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tt_xx_12 (a int) engine=Innodb
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Query # # ROLLBACK
-e-e-e-e-e-e-e-e-e-e-e- >> B T S1 T CT R1 R << -e-e-e-e-e-e-e-e-e-e-e-
diff --git a/mysql-test/suite/rpl/r/rpl_non_direct_row_mixing_engines.result b/mysql-test/suite/rpl/r/rpl_non_direct_row_mixing_engines.result
index 366a5342a0e..cde0a9cfa8c 100644
--- a/mysql-test/suite/rpl/r/rpl_non_direct_row_mixing_engines.result
+++ b/mysql-test/suite/rpl/r/rpl_non_direct_row_mixing_engines.result
@@ -12240,10 +12240,10 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B N T S1 T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -12255,10 +12255,10 @@ master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B N T S1 T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -12298,10 +12298,10 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T N S1 T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -12313,10 +12313,10 @@ master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B T N S1 T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -12356,10 +12356,10 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T S1 N T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -12371,10 +12371,10 @@ master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B T S1 N T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -13579,10 +13579,10 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Query # # ROLLBACK
-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T S1 T CT R1 R << -b-b-b-b-b-b-b-b-b-b-b-
@@ -13590,10 +13590,10 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Query # # ROLLBACK
-e-e-e-e-e-e-e-e-e-e-e- >> B T S1 T CT R1 R << -e-e-e-e-e-e-e-e-e-e-e-
diff --git a/mysql-test/suite/rpl/r/rpl_non_direct_stm_mixing_engines.result b/mysql-test/suite/rpl/r/rpl_non_direct_stm_mixing_engines.result
index 92230b5bfa3..dfceb41948d 100644
--- a/mysql-test/suite/rpl/r/rpl_non_direct_stm_mixing_engines.result
+++ b/mysql-test/suite/rpl/r/rpl_non_direct_stm_mixing_engines.result
@@ -9770,9 +9770,9 @@ COMMIT;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (318, 4)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (318, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B N T S1 T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -9782,9 +9782,9 @@ master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VA
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (318, 4)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (318, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B N T S1 T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -9822,9 +9822,9 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (319, 2)
master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (319, 4)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (319, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T N S1 T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -9832,9 +9832,9 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (319, 2)
master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (319, 4)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (319, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B T N S1 T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -9871,20 +9871,20 @@ COMMIT;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (320, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (320, 5)
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (320, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T S1 N T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (320, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (320, 5)
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (320, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B T S1 N T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -10801,20 +10801,20 @@ ROLLBACK;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (353, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (353, 5)
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tt_xx_12 (a int) engine=Innodb
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Query # # ROLLBACK
-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T S1 T CT R1 R << -b-b-b-b-b-b-b-b-b-b-b-
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (353, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (353, 5)
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tt_xx_12 (a int) engine=Innodb
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Query # # ROLLBACK
-e-e-e-e-e-e-e-e-e-e-e- >> B T S1 T CT R1 R << -e-e-e-e-e-e-e-e-e-e-e-
diff --git a/mysql-test/suite/rpl/r/rpl_row_mixing_engines.result b/mysql-test/suite/rpl/r/rpl_row_mixing_engines.result
index 366a5342a0e..cde0a9cfa8c 100644
--- a/mysql-test/suite/rpl/r/rpl_row_mixing_engines.result
+++ b/mysql-test/suite/rpl/r/rpl_row_mixing_engines.result
@@ -12240,10 +12240,10 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B N T S1 T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -12255,10 +12255,10 @@ master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B N T S1 T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -12298,10 +12298,10 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T N S1 T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -12313,10 +12313,10 @@ master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B T N S1 T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -12356,10 +12356,10 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T S1 N T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -12371,10 +12371,10 @@ master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B T S1 N T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -13579,10 +13579,10 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Query # # ROLLBACK
-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T S1 T CT R1 R << -b-b-b-b-b-b-b-b-b-b-b-
@@ -13590,10 +13590,10 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Query # # ROLLBACK
-e-e-e-e-e-e-e-e-e-e-e- >> B T S1 T CT R1 R << -e-e-e-e-e-e-e-e-e-e-e-
diff --git a/mysql-test/suite/rpl/r/rpl_row_rec_comp_innodb.result b/mysql-test/suite/rpl/r/rpl_row_rec_comp_innodb.result
new file mode 100644
index 00000000000..c461cafbd7c
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_row_rec_comp_innodb.result
@@ -0,0 +1,46 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+## case #1 - last_null_bit_pos==0 in record_compare without X bit
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (c1 bigint(20) DEFAULT 0, c2 bigint(20) DEFAULT 0, c3 bigint(20) DEFAULT 0, c4 varchar(1) DEFAULT '', c5 bigint(20) DEFAULT 0, c6 bigint(20) DEFAULT 0, c7 bigint(20) DEFAULT 0, c8 bigint(20) DEFAULT 0) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t1 ( c5, c6 ) VALUES ( 1 , 35 );
+INSERT INTO t1 ( c5, c6 ) VALUES ( NULL, 35 );
+UPDATE t1 SET c5 = 'a';
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
+## case #1.1 - last_null_bit_pos==0 in record_compare with X bit
+## (1 column less and no varchar)
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (c1 bigint(20) DEFAULT 0, c2 bigint(20) DEFAULT 0, c3 bigint(20) DEFAULT 0, c4 bigint(20) DEFAULT 0, c5 bigint(20) DEFAULT 0, c6 bigint(20) DEFAULT 0, c7 bigint(20) DEFAULT 0) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t1 ( c5, c6 ) VALUES ( 1 , 35 );
+INSERT INTO t1 ( c5, c6 ) VALUES ( NULL, 35 );
+UPDATE t1 SET c5 = 'a';
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
+## case #2 - X bit is wrongly set.
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (c1 int, c2 varchar(1) default '') ENGINE=InnoDB DEFAULT CHARSET= latin1;
+INSERT INTO t1(c1) VALUES (10);
+INSERT INTO t1(c1) VALUES (NULL);
+UPDATE t1 SET c1= 0;
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
diff --git a/mysql-test/suite/rpl/r/rpl_row_rec_comp_myisam.result b/mysql-test/suite/rpl/r/rpl_row_rec_comp_myisam.result
new file mode 100644
index 00000000000..38fbe486d2e
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_row_rec_comp_myisam.result
@@ -0,0 +1,60 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+## case #1 - last_null_bit_pos==0 in record_compare without X bit
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (c1 bigint(20) DEFAULT 0, c2 bigint(20) DEFAULT 0, c3 bigint(20) DEFAULT 0, c4 varchar(1) DEFAULT '', c5 bigint(20) DEFAULT 0, c6 bigint(20) DEFAULT 0, c7 bigint(20) DEFAULT 0, c8 bigint(20) DEFAULT 0) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t1 ( c5, c6 ) VALUES ( 1 , 35 );
+INSERT INTO t1 ( c5, c6 ) VALUES ( NULL, 35 );
+UPDATE t1 SET c5 = 'a';
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
+## case #1.1 - last_null_bit_pos==0 in record_compare with X bit
+## (1 column less and no varchar)
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (c1 bigint(20) DEFAULT 0, c2 bigint(20) DEFAULT 0, c3 bigint(20) DEFAULT 0, c4 bigint(20) DEFAULT 0, c5 bigint(20) DEFAULT 0, c6 bigint(20) DEFAULT 0, c7 bigint(20) DEFAULT 0) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t1 ( c5, c6 ) VALUES ( 1 , 35 );
+INSERT INTO t1 ( c5, c6 ) VALUES ( NULL, 35 );
+UPDATE t1 SET c5 = 'a';
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
+## case #2 - X bit is wrongly set.
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (c1 int, c2 varchar(1) default '') ENGINE=MyISAM DEFAULT CHARSET= latin1;
+INSERT INTO t1(c1) VALUES (10);
+INSERT INTO t1(c1) VALUES (NULL);
+UPDATE t1 SET c1= 0;
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
+## coverage purposes - Field_bits
+## 1 X bit + 2 Null bits + 5 bits => last_null_bit_pos==0
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (c1 bigint(20) DEFAULT 0, c2 bit(5)) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t1(c1,c2) VALUES (10, b'1');
+INSERT INTO t1(c1,c2) VALUES (NULL, b'1');
+UPDATE t1 SET c1= 0;
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
diff --git a/mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result b/mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result
index 5cafdf8528d..579e5eb02e9 100644
--- a/mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result
+++ b/mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result
@@ -10042,9 +10042,9 @@ COMMIT;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (318, 4)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (318, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B N T S1 T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -10054,9 +10054,9 @@ master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VA
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (318, 4)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (318, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B N T S1 T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -10096,9 +10096,9 @@ COMMIT;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (319, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (319, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T N S1 T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -10108,9 +10108,9 @@ master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VA
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (319, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (319, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B T N S1 T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -10150,9 +10150,9 @@ COMMIT;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (320, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (320, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T S1 N T R1 C << -b-b-b-b-b-b-b-b-b-b-b-
@@ -10162,9 +10162,9 @@ master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VA
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (320, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (320, 7)
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Xid # # COMMIT /* XID */
-e-e-e-e-e-e-e-e-e-e-e- >> B T S1 N T R1 C << -e-e-e-e-e-e-e-e-e-e-e-
@@ -11097,20 +11097,20 @@ ROLLBACK;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (353, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (353, 5)
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tt_xx_12 (a int) engine=Innodb
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Query # # ROLLBACK
-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> B T S1 T CT R1 R << -b-b-b-b-b-b-b-b-b-b-b-
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (353, 2)
-master-bin.000001 # Query # # use `test`; SAVEPOINT s1
+master-bin.000001 # Query # # SAVEPOINT s1
master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (353, 5)
master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE tt_xx_12 (a int) engine=Innodb
-master-bin.000001 # Query # # use `test`; ROLLBACK TO s1
+master-bin.000001 # Query # # ROLLBACK TO s1
master-bin.000001 # Query # # ROLLBACK
-e-e-e-e-e-e-e-e-e-e-e- >> B T S1 T CT R1 R << -e-e-e-e-e-e-e-e-e-e-e-
@@ -11314,3 +11314,23 @@ master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS tt_xx_1
###################################################################################
# CLEAN
###################################################################################
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE `t1` (
+`c1` int(10) unsigned NOT NULL AUTO_INCREMENT,
+`c2` tinyint(1) unsigned DEFAULT NULL,
+`c3` varchar(300) DEFAULT NULL,
+`c4` int(10) unsigned NOT NULL,
+`c5` int(10) unsigned DEFAULT NULL,
+PRIMARY KEY (`c1`)) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+ALTER TABLE `t1` Engine=InnoDB;
+SET AUTOCOMMIT=0;
+INSERT INTO t1 (c1,c2,c3,c4,c5) VALUES (1, 1, 'X', 1, NULL);
+COMMIT;
+ROLLBACK;
+SET AUTOCOMMIT=1;
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE `t1`;
diff --git a/mysql-test/suite/rpl/t/rpl_begin_commit_rollback-master.opt b/mysql-test/suite/rpl/t/rpl_begin_commit_rollback-master.opt
new file mode 100644
index 00000000000..9e6e2b7829a
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_begin_commit_rollback-master.opt
@@ -0,0 +1 @@
+--innodb --binlog-ignore-db=db2
diff --git a/mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test b/mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test
index 8db4aeccd7a..acb98a0ad88 100644
--- a/mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test
+++ b/mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test
@@ -12,9 +12,11 @@ SET @@session.binlog_direct_non_transactional_updates= FALSE;
disable_warnings;
DROP DATABASE IF EXISTS db1;
+DROP DATABASE IF EXISTS db2;
enable_warnings;
CREATE DATABASE db1;
+CREATE DATABASE db2;
use db1;
@@ -124,10 +126,55 @@ eval SELECT $result as 'Must be 0';
SELECT * from db1.t1;
SELECT * from db1.t2;
+START SLAVE;
+source include/wait_for_slave_sql_to_start.inc;
+
+--echo #
+--echo # SAVEPOINT and ROLLBACK TO have the same problem in BUG#43263
+--echo # This was reported by BUG#50407
+connection master;
+echo [on master]
+SET SESSION AUTOCOMMIT=0;
+let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1);
+
+BEGIN;
+INSERT INTO db1.t1 VALUES(20);
+
+--echo #
+--echo # Verify whether this statement is binlogged correctly
+/*comment*/ SAVEPOINT has_comment;
+USE db1;
+INSERT INTO db1.t1 VALUES(30);
+INSERT INTO db1.t2 VALUES("in savepoint has_comment");
+USE db2;
+SavePoint mixed_cases;
+USE db1;
+INSERT INTO db1.t2 VALUES("in savepoint mixed_cases");
+INSERT INTO db1.t1 VALUES(40);
+USE db2;
+ROLLBACK TO mixed_cases;
+ROLLBACK TO has_comment;
+USE db1;
+INSERT INTO db1.t2 VALUES("after rollback to");
+INSERT INTO db1.t1 VALUES(50);
+USE db2;
+COMMIT;
+source include/show_binlog_events.inc;
+sync_slave_with_master;
+
+--echo [on slave]
+--echo #
+--echo # Verify INSERT statements in savepoints are executed, for MyISAM table
+--echo # is not effected by ROLLBACK TO
+SELECT * FROM db1.t2 WHERE s LIKE '% savepoint %';
+--echo #
+--echo # Verify INSERT statements on the Innodb table are rolled back;
+SELECT * FROM db1.t1 WHERE a IN (30, 40);
+
--echo #
--echo # Clean up
--echo #
connection master;
DROP DATABASE db1;
-connection slave;
-DROP DATABASE db1;
+DROP DATABASE db2;
+source include/master-slave-end.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_do_grant.test b/mysql-test/suite/rpl/t/rpl_do_grant.test
index e3d7784429e..37358077145 100644
--- a/mysql-test/suite/rpl/t/rpl_do_grant.test
+++ b/mysql-test/suite/rpl/t/rpl_do_grant.test
@@ -318,4 +318,33 @@ DROP USER 'user49119'@'localhost';
-- sync_slave_with_master
+#
+# Bug #51987 revoke privileges logs wrong error code
+#
+
+-- connection master
+-- source include/master-slave-reset.inc
+-- connection master
+
+grant all on *.* to foo@"1.2.3.4";
+-- error ER_REVOKE_GRANTS
+revoke all privileges, grant option from "foo";
+
+## assertion: revoke is logged
+-- source include/show_binlog_events.inc
+
+-- sync_slave_with_master
+
+## assertion: slave replicates revoke and does not fail because master
+## logged revoke with correct expected error code
+-- let $err= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1)
+ if ($err)
+{
+ -- die UNEXPECTED ERROR AT SLAVE: $err
+}
+
+-- connection master
+DROP USER foo@"1.2.3.4";
+-- sync_slave_with_master
+
--echo "End of test"
diff --git a/mysql-test/suite/rpl/t/rpl_events.test b/mysql-test/suite/rpl/t/rpl_events.test
index 6e5bed8aa21..45ef12862fc 100644
--- a/mysql-test/suite/rpl/t/rpl_events.test
+++ b/mysql-test/suite/rpl/t/rpl_events.test
@@ -59,10 +59,16 @@ CREATE DEFINER=CURRENT_USER() EVENT event44331_3
ON COMPLETION PRESERVE DISABLE
DO INSERT INTO test.t1 VALUES('event event44331_3 fired - DEFINER=CURRENT_USER() function');
+DELIMITER |;
CREATE /*!50000 DEFINER='user44331' */ EVENT event44331_4
ON SCHEDULE AT CURRENT_TIMESTAMP
ON COMPLETION PRESERVE DISABLE
DO INSERT INTO test.t1 VALUES('event event44331_4 fired - DEFINER=user1');
+# Test for bug#50095 Multi-statement including CREATE EVENT causes rotten
+# binlog entry
+ SELECT 'ABC';
+ SELECT '123'|
+DELIMITER ;|
--echo #on master
select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events
diff --git a/mysql-test/suite/rpl/t/rpl_row_rec_comp_innodb.test b/mysql-test/suite/rpl/t/rpl_row_rec_comp_innodb.test
new file mode 100644
index 00000000000..67e4c4fb14d
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_row_rec_comp_innodb.test
@@ -0,0 +1,10 @@
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+-- source include/have_innodb.inc
+
+#
+# BUG#52868 Wrong handling of NULL value during update, replication out of sync
+#
+
+-- let $engine= InnoDB
+-- source extra/rpl_tests/rpl_record_compare.test
diff --git a/mysql-test/suite/rpl/t/rpl_row_rec_comp_myisam.test b/mysql-test/suite/rpl/t/rpl_row_rec_comp_myisam.test
new file mode 100644
index 00000000000..43fa99a51da
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_row_rec_comp_myisam.test
@@ -0,0 +1,31 @@
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+#
+# BUG#52868 Wrong handling of NULL value during update, replication out of sync
+#
+
+-- let $engine= MyISAM
+-- source extra/rpl_tests/rpl_record_compare.test
+
+-- echo ## coverage purposes - Field_bits
+-- echo ## 1 X bit + 2 Null bits + 5 bits => last_null_bit_pos==0
+## Added here because AFAIK it's only MyISAM and NDB that use Field_bits
+
+-- source include/master-slave-reset.inc
+-- connection master
+
+-- eval CREATE TABLE t1 (c1 bigint(20) DEFAULT 0, c2 bit(5)) ENGINE=$engine DEFAULT CHARSET=latin1
+
+INSERT INTO t1(c1,c2) VALUES (10, b'1');
+INSERT INTO t1(c1,c2) VALUES (NULL, b'1');
+UPDATE t1 SET c1= 0;
+-- sync_slave_with_master
+
+-- let $diff_table_1= master:test.t1
+-- let $diff_table_2= slave:test.t1
+-- source include/diff_tables.inc
+
+-- connection master
+DROP TABLE t1;
+-- sync_slave_with_master
diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync.test b/mysql-test/suite/rpl/t/rpl_semi_sync.test
index 7610ee68417..1bf4f1a3396 100644
--- a/mysql-test/suite/rpl/t/rpl_semi_sync.test
+++ b/mysql-test/suite/rpl/t/rpl_semi_sync.test
@@ -602,7 +602,11 @@ source include/stop_slave.inc;
UNINSTALL PLUGIN rpl_semi_sync_slave;
connection master;
+# The dump thread may still be running on the master, and so the following
+# UNINSTALL could generate a warning about the plugin is busy.
+disable_warnings;
UNINSTALL PLUGIN rpl_semi_sync_master;
+enable_warnings;
connection slave;
source include/start_slave.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_stm_mixing_engines.test b/mysql-test/suite/rpl/t/rpl_stm_mixing_engines.test
index 39a9522bf6c..f32ab1f01f0 100644
--- a/mysql-test/suite/rpl/t/rpl_stm_mixing_engines.test
+++ b/mysql-test/suite/rpl/t/rpl_stm_mixing_engines.test
@@ -8,3 +8,41 @@
let $engine_type=Innodb;
--source extra/rpl_tests/rpl_mixing_engines.test
+
+#
+# BUG#49522: Replication problem with mixed MyISAM/InnoDB
+#
+
+-- source include/master-slave-reset.inc
+-- connection master
+
+CREATE TABLE `t1` (
+ `c1` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `c2` tinyint(1) unsigned DEFAULT NULL,
+ `c3` varchar(300) DEFAULT NULL,
+ `c4` int(10) unsigned NOT NULL,
+ `c5` int(10) unsigned DEFAULT NULL,
+ PRIMARY KEY (`c1`)) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+-- sync_slave_with_master
+ALTER TABLE `t1` Engine=InnoDB;
+
+-- connection master
+SET AUTOCOMMIT=0;
+
+INSERT INTO t1 (c1,c2,c3,c4,c5) VALUES (1, 1, 'X', 1, NULL);
+COMMIT;
+ROLLBACK;
+SET AUTOCOMMIT=1;
+
+-- sync_slave_with_master
+
+-- let $diff_table_1=master:test.t1
+-- let $diff_table_2=slave:test.t1
+-- source include/diff_tables.inc
+
+-- connection master
+DROP TABLE `t1`;
+-- sync_slave_with_master
+
+-- source include/master-slave-end.inc
diff --git a/mysql-test/suite/rpl_ndb/my.cnf b/mysql-test/suite/rpl_ndb/my.cnf
index 191683fc9df..0c62988b220 100644
--- a/mysql-test/suite/rpl_ndb/my.cnf
+++ b/mysql-test/suite/rpl_ndb/my.cnf
@@ -19,6 +19,8 @@ mysqld=
ndbcluster
# Turn on bin logging
log-bin= master-bin
+# Cluster only supports row format
+binlog-format= row
[mysqld.1.1]
@@ -32,6 +34,8 @@ log-bin= master-bin
log-bin= slave-bin
relay-log= slave-relay-bin
+# Cluster only supports row format
+binlog-format= row
init-rpl-role= slave
log-slave-updates
diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_stm_innodb.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_stm_innodb.result
index 675a69d17a4..5327bfde7e0 100644
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_stm_innodb.result
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_stm_innodb.result
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+SET binlog_format = STATEMENT;
*** Test 1 ***
diff --git a/mysql-test/suite/rpl_ndb/t/rpl_ndb_stm_innodb.test b/mysql-test/suite/rpl_ndb/t/rpl_ndb_stm_innodb.test
index 0d915b0aa00..5e54ca38dc1 100644
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_stm_innodb.test
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_stm_innodb.test
@@ -27,9 +27,11 @@
--disable_query_log
--source include/have_ndb.inc
--source include/have_innodb.inc
---source include/have_binlog_format_statement.inc
--source include/ndb_master-slave.inc
--enable_query_log
+
+# statement format is supported because master uses innodb
+SET binlog_format = STATEMENT;
let $off_set = 6;
let $rpl_format = 'SBR';
disable_query_log;
diff --git a/mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_32.result b/mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_32.result
index 5cb52734d21..b9ecef3e8cc 100644
--- a/mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_32.result
+++ b/mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_32.result
@@ -8,11 +8,15 @@ SELECT @start_session_value;
8388608
'#--------------------FN_DYNVARS_005_01-------------------------#'
SET @@global.myisam_sort_buffer_size = 100;
+Warnings:
+Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '100'
SET @@global.myisam_sort_buffer_size = DEFAULT;
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
8388608
SET @@session.myisam_sort_buffer_size = 200;
+Warnings:
+Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '200'
SET @@session.myisam_sort_buffer_size = DEFAULT;
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
@@ -28,9 +32,11 @@ SELECT @@session.myisam_sort_buffer_size = 8388608;
1
'#--------------------FN_DYNVARS_005_03-------------------------#'
SET @@global.myisam_sort_buffer_size = 4;
+Warnings:
+Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '4'
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
-4
+4096
SET @@global.myisam_sort_buffer_size = 4294967295;
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
@@ -41,9 +47,11 @@ SELECT @@global.myisam_sort_buffer_size ;
655354
'#--------------------FN_DYNVARS_005_04-------------------------#'
SET @@session.myisam_sort_buffer_size = 4;
+Warnings:
+Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '4'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
-4
+4096
SET @@session.myisam_sort_buffer_size = 4294967295;
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
@@ -58,13 +66,13 @@ Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '0'
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
-4
+4096
SET @@global.myisam_sort_buffer_size = -1024;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '-1024'
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
-4
+4096
SET @@global.myisam_sort_buffer_size = 429496729533;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '429496729533'
@@ -101,28 +109,28 @@ Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '0'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
-4
+4096
SET @@session.myisam_sort_buffer_size = -2;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '-2'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
-4
+4096
SET @@session.myisam_sort_buffer_size = 65530.34;
ERROR 42000: Incorrect argument type to variable 'myisam_sort_buffer_size'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
-4
+4096
SET @@session.myisam_sort_buffer_size = test;
ERROR 42000: Incorrect argument type to variable 'myisam_sort_buffer_size'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
-4
+4096
SET @@session.myisam_sort_buffer_size = "test";
ERROR 42000: Incorrect argument type to variable 'myisam_sort_buffer_size'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
-4
+4096
'#------------------FN_DYNVARS_005_06-----------------------#'
SELECT @@global.myisam_sort_buffer_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
@@ -141,20 +149,24 @@ Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '1'
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
-4
+4096
SET @@global.myisam_sort_buffer_size = FALSE;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '0'
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
-4
+4096
'#---------------------FN_DYNVARS_001_09----------------------#'
SET @@global.myisam_sort_buffer_size = 10;
+Warnings:
+Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '10'
SELECT @@myisam_sort_buffer_size = @@global.myisam_sort_buffer_size ;
@@myisam_sort_buffer_size = @@global.myisam_sort_buffer_size
-0
+1
'#---------------------FN_DYNVARS_001_10----------------------#'
SET @@myisam_sort_buffer_size = 100;
+Warnings:
+Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '100'
SELECT @@myisam_sort_buffer_size = @@local.myisam_sort_buffer_size ;
@@myisam_sort_buffer_size = @@local.myisam_sort_buffer_size
1
@@ -167,7 +179,7 @@ Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '1'
SELECT @@myisam_sort_buffer_size ;
@@myisam_sort_buffer_size
-4
+4096
SELECT local.myisam_sort_buffer_size ;
ERROR 42S02: Unknown table 'local' in field list
SELECT session.myisam_sort_buffer_size ;
diff --git a/mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_64.result b/mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_64.result
index 2069b32fdcd..e6be3c28251 100644
--- a/mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_64.result
+++ b/mysql-test/suite/sys_vars/r/myisam_sort_buffer_size_basic_64.result
@@ -8,11 +8,15 @@ SELECT @start_session_value;
8388608
'#--------------------FN_DYNVARS_005_01-------------------------#'
SET @@global.myisam_sort_buffer_size = 100;
+Warnings:
+Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '100'
SET @@global.myisam_sort_buffer_size = DEFAULT;
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
8388608
SET @@session.myisam_sort_buffer_size = 200;
+Warnings:
+Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '200'
SET @@session.myisam_sort_buffer_size = DEFAULT;
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
@@ -28,9 +32,11 @@ SELECT @@session.myisam_sort_buffer_size = 8388608;
1
'#--------------------FN_DYNVARS_005_03-------------------------#'
SET @@global.myisam_sort_buffer_size = 4;
+Warnings:
+Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '4'
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
-4
+4096
SET @@global.myisam_sort_buffer_size = 4294967295;
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
@@ -41,9 +47,11 @@ SELECT @@global.myisam_sort_buffer_size ;
655354
'#--------------------FN_DYNVARS_005_04-------------------------#'
SET @@session.myisam_sort_buffer_size = 4;
+Warnings:
+Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '4'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
-4
+4096
SET @@session.myisam_sort_buffer_size = 4294967295;
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
@@ -58,13 +66,13 @@ Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '0'
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
-4
+4096
SET @@global.myisam_sort_buffer_size = -1024;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '-1024'
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
-4
+4096
SET @@global.myisam_sort_buffer_size = 429496729533;
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
@@ -99,28 +107,28 @@ Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '0'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
-4
+4096
SET @@session.myisam_sort_buffer_size = -2;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '-2'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
-4
+4096
SET @@session.myisam_sort_buffer_size = 65530.34;
ERROR 42000: Incorrect argument type to variable 'myisam_sort_buffer_size'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
-4
+4096
SET @@session.myisam_sort_buffer_size = test;
ERROR 42000: Incorrect argument type to variable 'myisam_sort_buffer_size'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
-4
+4096
SET @@session.myisam_sort_buffer_size = "test";
ERROR 42000: Incorrect argument type to variable 'myisam_sort_buffer_size'
SELECT @@session.myisam_sort_buffer_size ;
@@session.myisam_sort_buffer_size
-4
+4096
'#------------------FN_DYNVARS_005_06-----------------------#'
SELECT @@global.myisam_sort_buffer_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
@@ -139,20 +147,24 @@ Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '1'
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
-4
+4096
SET @@global.myisam_sort_buffer_size = FALSE;
Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '0'
SELECT @@global.myisam_sort_buffer_size ;
@@global.myisam_sort_buffer_size
-4
+4096
'#---------------------FN_DYNVARS_001_09----------------------#'
SET @@global.myisam_sort_buffer_size = 10;
+Warnings:
+Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '10'
SELECT @@myisam_sort_buffer_size = @@global.myisam_sort_buffer_size ;
@@myisam_sort_buffer_size = @@global.myisam_sort_buffer_size
-0
+1
'#---------------------FN_DYNVARS_001_10----------------------#'
SET @@myisam_sort_buffer_size = 100;
+Warnings:
+Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '100'
SELECT @@myisam_sort_buffer_size = @@local.myisam_sort_buffer_size ;
@@myisam_sort_buffer_size = @@local.myisam_sort_buffer_size
1
@@ -165,7 +177,7 @@ Warnings:
Warning 1292 Truncated incorrect myisam_sort_buffer_size value: '1'
SELECT @@myisam_sort_buffer_size ;
@@myisam_sort_buffer_size
-4
+4096
SELECT local.myisam_sort_buffer_size ;
ERROR 42S02: Unknown table 'local' in field list
SELECT session.myisam_sort_buffer_size ;
diff --git a/mysql-test/suite/sys_vars/r/secure_file_priv.result b/mysql-test/suite/sys_vars/r/secure_file_priv.result
new file mode 100644
index 00000000000..eeeb9a58c0f
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/secure_file_priv.result
@@ -0,0 +1,22 @@
+#
+# Bug50373 --secure-file-priv=""
+#
+CREATE TABLE t1 (c1 VARCHAR(50));
+INSERT INTO t1 VALUES ("one"),("two"),("three"),("four"),("five");
+SHOW VARIABLES LIKE 'secure_file_priv';
+Variable_name Value
+secure_file_priv
+c1
+one
+two
+three
+four
+five
+loaded_file
+one
+two
+three
+four
+five
+
+DROP TABLE t1;
diff --git a/mysql-test/suite/sys_vars/r/skip_name_resolve_basic.result b/mysql-test/suite/sys_vars/r/skip_name_resolve_basic.result
new file mode 100644
index 00000000000..d22a39b32a0
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/skip_name_resolve_basic.result
@@ -0,0 +1,23 @@
+SHOW VARIABLES LIKE 'skip_name_resolve';
+Variable_name Value
+skip_name_resolve ON
+SHOW GLOBAL VARIABLES LIKE 'skip_name_resolve';
+Variable_name Value
+skip_name_resolve ON
+SHOW SESSION VARIABLES LIKE 'skip_name_resolve';
+Variable_name Value
+skip_name_resolve ON
+SELECT @@skip_name_resolve;
+@@skip_name_resolve
+1
+SELECT @@LOCAL.skip_name_resolve;
+ERROR HY000: Variable 'skip_name_resolve' is a GLOBAL variable
+SELECT @@GLOBAL.skip_name_resolve;
+@@GLOBAL.skip_name_resolve
+1
+SET @@skip_name_resolve=0;
+ERROR HY000: Variable 'skip_name_resolve' is a read only variable
+SET @@LOCAL.skip_name_resolve=0;
+ERROR HY000: Variable 'skip_name_resolve' is a read only variable
+SET @@GLOBAL.skip_name_resolve=0;
+ERROR HY000: Variable 'skip_name_resolve' is a read only variable
diff --git a/mysql-test/suite/sys_vars/t/secure_file_priv-master.opt b/mysql-test/suite/sys_vars/t/secure_file_priv-master.opt
new file mode 100644
index 00000000000..b41d9b04b96
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/secure_file_priv-master.opt
@@ -0,0 +1 @@
+--secure_file_priv=''
diff --git a/mysql-test/suite/sys_vars/t/secure_file_priv.test b/mysql-test/suite/sys_vars/t/secure_file_priv.test
new file mode 100644
index 00000000000..7a534e7d6e4
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/secure_file_priv.test
@@ -0,0 +1,21 @@
+--echo #
+--echo # Bug50373 --secure-file-priv=""
+--echo #
+CREATE TABLE t1 (c1 VARCHAR(50));
+INSERT INTO t1 VALUES ("one"),("two"),("three"),("four"),("five");
+SHOW VARIABLES LIKE 'secure_file_priv';
+--disable_query_log
+# Atempt to create a file where we normally aren't allowed to create one.
+# Doing this in a portable manner is difficult but we should be able to
+# count on the depth of the directory hierarchy used. Three steps up from
+# the datadir is the 'mysql_test' directory.
+--let $PROTECTED_FILE=`SELECT concat(@@datadir,'/../../../bug50373.txt')`;
+--eval SELECT * FROM t1 INTO OUTFILE '$PROTECTED_FILE';
+DELETE FROM t1;
+--eval LOAD DATA INFILE '$PROTECTED_FILE' INTO TABLE t1;
+SELECT * FROM t1;
+--eval SELECT load_file('$PROTECTED_FILE') AS loaded_file;
+--enable_query_log
+remove_file $PROTECTED_FILE;
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/sys_vars/t/secure_file_priv_basic.test b/mysql-test/suite/sys_vars/t/secure_file_priv_basic.test
index fee18e441d1..836990cb70e 100644
--- a/mysql-test/suite/sys_vars/t/secure_file_priv_basic.test
+++ b/mysql-test/suite/sys_vars/t/secure_file_priv_basic.test
@@ -1,3 +1,5 @@
+--source include/not_var_link.inc
+
#
# only global
#
diff --git a/mysql-test/suite/sys_vars/t/skip_name_resolve_basic-master.opt b/mysql-test/suite/sys_vars/t/skip_name_resolve_basic-master.opt
new file mode 100644
index 00000000000..ab6ca1731f5
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/skip_name_resolve_basic-master.opt
@@ -0,0 +1 @@
+--skip-name-resolve
diff --git a/mysql-test/suite/sys_vars/t/skip_name_resolve_basic.test b/mysql-test/suite/sys_vars/t/skip_name_resolve_basic.test
new file mode 100644
index 00000000000..69006a0f2b2
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/skip_name_resolve_basic.test
@@ -0,0 +1,15 @@
+SHOW VARIABLES LIKE 'skip_name_resolve';
+SHOW GLOBAL VARIABLES LIKE 'skip_name_resolve';
+SHOW SESSION VARIABLES LIKE 'skip_name_resolve';
+
+SELECT @@skip_name_resolve;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT @@LOCAL.skip_name_resolve;
+SELECT @@GLOBAL.skip_name_resolve;
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@skip_name_resolve=0;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@LOCAL.skip_name_resolve=0;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@GLOBAL.skip_name_resolve=0;
diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test
index b2545e98f3e..5b61176b0f6 100644
--- a/mysql-test/t/archive.test
+++ b/mysql-test/t/archive.test
@@ -1669,3 +1669,26 @@ FLUSH TABLE t1;
SELECT * FROM t1;
--error ER_BAD_TABLE_ERROR
DROP TABLE t1;
+
+
+--echo #
+--echo # BUG#46565 - repair of partition fail for archive engine
+--echo #
+--echo # Installing corrupted table files for t1.
+# bug46565 was created, filled and damaged as following:
+# CREATE TABLE bug46565(a INT) ENGINE=archive;
+# INSERT INTO bug46565 VALUES(1);
+# FLUSH TABLE bug46565;
+# INSERT INTO bug46565 VALUES(2),(3);
+# FLUSH TABLE bug46565;
+# dd if=bug46565.ARZ of=std_data/bug46565.ARZ bs=1 count=8670
+copy_file std_data/bug46565.frm $MYSQLD_DATADIR/test/t1.frm;
+copy_file std_data/bug46565.ARZ $MYSQLD_DATADIR/test/t1.ARZ;
+--error ER_CRASHED_ON_USAGE
+SELECT * FROM t1;
+REPAIR TABLE t1;
+--error ER_CRASHED_ON_USAGE
+SELECT * FROM t1;
+REPAIR TABLE t1 EXTENDED;
+SELECT * FROM t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/bug46261-master.opt b/mysql-test/t/bug46261-master.opt
new file mode 100644
index 00000000000..6be4269e809
--- /dev/null
+++ b/mysql-test/t/bug46261-master.opt
@@ -0,0 +1 @@
+--skip-grant-tables $EXAMPLE_PLUGIN_OPT
diff --git a/mysql-test/t/bug46261.test b/mysql-test/t/bug46261.test
new file mode 100644
index 00000000000..67bdc995850
--- /dev/null
+++ b/mysql-test/t/bug46261.test
@@ -0,0 +1,16 @@
+--source include/not_embedded.inc
+--source include/have_example_plugin.inc
+
+--echo #
+--echo # Bug#46261 Plugins can be installed with --skip-grant-tables
+--echo #
+
+--replace_regex /\.dll/.so/
+--error ER_OPTION_PREVENTS_STATEMENT
+eval INSTALL PLUGIN example SONAME $HA_EXAMPLE_SO;
+
+--replace_regex /\.dll/.so/
+--error ER_OPTION_PREVENTS_STATEMENT
+eval UNINSTALL PLUGIN example;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index 8d4b478e68d..a6f3a2c2cbf 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -732,6 +732,15 @@ SELECT HEX(MONTHNAME(19700101));
SELECT HEX(DAYNAME(19700101));
SET character_set_connection=latin1;
+--echo #
+--echo # Bug#52120 create view cause Assertion failed: 0, file .\item_subselect.cc, line 817
+--echo #
+CREATE TABLE t1 (a CHAR(1) CHARSET ascii, b CHAR(1) CHARSET latin1);
+CREATE VIEW v1 AS SELECT 1 from t1
+WHERE t1.b <=> (SELECT a FROM t1 WHERE a < SOME(SELECT '1'));
+DROP VIEW v1;
+DROP TABLE t1;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test
index acd67e0e766..a21fff60d33 100644
--- a/mysql-test/t/delete.test
+++ b/mysql-test/t/delete.test
@@ -527,5 +527,17 @@ DELETE IGNORE FROM t1;
DROP TABLE t1;
+--echo #
+--echo # Bug #53450: Crash/assertion
+--echo # "virtual int ha_myisam::index_first(uchar*)") at assert.c:81
+--echo #
+
+CREATE TABLE t1 (a INT, b INT, c INT,
+ INDEX(a), INDEX(b), INDEX(c));
+INSERT INTO t1 VALUES (1,2,3), (4,5,6), (7,8,9);
+
+DELETE FROM t1 WHERE a = 10 OR b = 20 ORDER BY c LIMIT 1;
+
+DROP TABLE t1;
--echo End of 5.1 tests
diff --git a/mysql-test/t/error_simulation.test b/mysql-test/t/error_simulation.test
index f730c95208e..7cd16a6bc5a 100644
--- a/mysql-test/t/error_simulation.test
+++ b/mysql-test/t/error_simulation.test
@@ -33,3 +33,19 @@ set tmp_table_size=default;
DROP TABLE t1;
+--echo #
+--echo # Bug #50946: fast index creation still seems to copy the table
+--echo #
+CREATE TABLE t1 (a INT(100) NOT NULL);
+INSERT INTO t1 VALUES (1), (0), (2);
+SET SESSION debug='+d,alter_table_only_index_change';
+ALTER TABLE t1 ADD INDEX a(a);
+SET SESSION debug=DEFAULT;
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+--echo #
+--echo # End of 5.1 tests
+--echo #
diff --git a/mysql-test/t/errors.test b/mysql-test/t/errors.test
index 5e53eaf0a52..f308c340645 100644
--- a/mysql-test/t/errors.test
+++ b/mysql-test/t/errors.test
@@ -140,3 +140,18 @@ SET sql_quote_show_create= _utf8 x'5452C39C45';
--error ER_WRONG_VALUE_FOR_VAR
SET sql_quote_show_create=_latin1 x'5452DC45';
+--echo #
+--echo # Bug#52430 Incorrect key in the error message for duplicate key error involving BINARY type
+--echo #
+CREATE TABLE t1(c1 BINARY(10), c2 BINARY(10), c3 BINARY(10),
+PRIMARY KEY(c1,c2,c3));
+INSERT INTO t1 (c1,c2,c3) VALUES('abc','abc','abc');
+--error ER_DUP_ENTRY
+INSERT INTO t1 (c1,c2,c3) VALUES('abc','abc','abc');
+DROP TABLE t1;
+
+CREATE TABLE t1 (f1 VARBINARY(19) PRIMARY KEY);
+INSERT INTO t1 VALUES ('abc\0\0');
+--error ER_DUP_ENTRY
+INSERT INTO t1 VALUES ('abc\0\0');
+DROP TABLE t1;
diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test
index 30366f6f67e..72406110de1 100644
--- a/mysql-test/t/explain.test
+++ b/mysql-test/t/explain.test
@@ -210,4 +210,17 @@ explain extended select * from t1 where f1=1;
explain extended select * from t1 join t2 on f1=f2 where f1=1;
drop table t1,t2;
+--echo #
+--echo # Bug #48419: another explain crash..
+--echo #
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (b BLOB, KEY b(b(100)));
+INSERT INTO t2 VALUES ('1'), ('2'), ('3');
+
+FLUSH TABLES;
+
+EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT 1 FROM t1 t JOIN t2 WHERE b <= 1 AND t.a);
+
+DROP TABLE t1, t2;
+
--echo End of 5.1 tests.
diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test
index 97a1b5e39dc..388b1432390 100644
--- a/mysql-test/t/fulltext.test
+++ b/mysql-test/t/fulltext.test
@@ -584,5 +584,14 @@ CREATE TABLE t1(a CHAR(1),FULLTEXT(a));
SELECT 1 FROM t1 WHERE MATCH(a) AGAINST ('') AND ROW(a,a) > ROW(1,1);
DROP TABLE t1;
+--echo #
+--echo # BUG#51866 - crash with repair by sort and fulltext keys
+--echo #
+CREATE TABLE t1(a CHAR(4), FULLTEXT(a));
+INSERT INTO t1 VALUES('aaaa');
+SET myisam_sort_buffer_size=4;
+REPAIR TABLE t1;
+SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
+DROP TABLE t1;
--echo End of 5.1 tests
diff --git a/mysql-test/t/func_concat.test b/mysql-test/t/func_concat.test
index e24b4354b61..e56d1121808 100644
--- a/mysql-test/t/func_concat.test
+++ b/mysql-test/t/func_concat.test
@@ -124,4 +124,24 @@ SELECT @query;
DROP PROCEDURE p1;
+--echo #
+--echo # Bug #40625: Concat fails on DOUBLE values in a Stored Procedure,
+--echo # while DECIMAL works
+--echo #
+
+DELIMITER //;
+CREATE PROCEDURE p1()
+BEGIN
+ DECLARE v1 DOUBLE(10,3);
+ SET v1= 100;
+ SET @s = CONCAT('########################################', 40 , v1);
+ SELECT @s;
+END;//
+DELIMITER ;//
+
+CALL p1();
+CALL p1();
+
+DROP PROCEDURE p1;
+
--echo # End of 5.1 tests
diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test
index 0b4f0be114c..e191b9750e3 100644
--- a/mysql-test/t/func_gconcat.test
+++ b/mysql-test/t/func_gconcat.test
@@ -708,6 +708,18 @@ SELECT 1 FROM
DROP TABLE t1;
+
+--echo #
+--echo # Bug #52397: another crash with explain extended and group_concat
+--echo #
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (0), (0);
+EXPLAIN EXTENDED SELECT 1 FROM
+ (SELECT GROUP_CONCAT(t1.a ORDER BY t1.a ASC) FROM
+ t1 t2, t1 GROUP BY t1.a) AS d;
+DROP TABLE t1;
+
+
--echo End of 5.0 tests
#
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index 556a19efce5..10d35b16315 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -1354,6 +1354,17 @@ SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP
DROP TABLE t1, t2;
+--echo #
+--echo # Bug#52164 Assertion failed: param.sort_length, file .\filesort.cc, line 149
+--echo #
+CREATE TABLE t1 (a LONGBLOB NOT NULL);
+INSERT INTO t1 VALUES (''),('');
+SELECT 1 FROM t1, t1 t2
+ORDER BY QUOTE(t1.a);
+DROP TABLE t1;
+
+--echo End of 5.1 tests
+
--echo Start of 5.4 tests
#
# WL#4584 Internationalized number format
diff --git a/mysql-test/t/gis-rtree.test b/mysql-test/t/gis-rtree.test
index c5d5bfee861..b006096528e 100644
--- a/mysql-test/t/gis-rtree.test
+++ b/mysql-test/t/gis-rtree.test
@@ -914,14 +914,15 @@ HANDLER t1 READ a PREV;
HANDLER t1 READ a LAST;
HANDLER t1 CLOSE;
-#TODO: re-enable this test please when bug #51877 is solved
# second crash fixed when the tree has changed since the last search.
-#HANDLER t1 OPEN;
-#HANDLER t1 READ a FIRST;
-#INSERT INTO t1 VALUES (GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
-#HANDLER t1 READ a NEXT;
-#HANDLER t1 CLOSE;
-#TODO: end of the 51877 dependent section
+HANDLER t1 OPEN;
+HANDLER t1 READ a FIRST;
+INSERT INTO t1 VALUES (GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
+--echo # should not crash
+--disable_result_log
+HANDLER t1 READ a NEXT;
+--enable_result_log
+HANDLER t1 CLOSE;
DROP TABLE t1;
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test
index bda48fb9ecf..de43d6a74b4 100644
--- a/mysql-test/t/grant.test
+++ b/mysql-test/t/grant.test
@@ -1554,6 +1554,30 @@ connection default;
disconnect conn1;
+#
+# Bug #53371: COM_FIELD_LIST can be abused to bypass table level grants.
+#
+
+CREATE DATABASE db1;
+CREATE DATABASE db2;
+GRANT SELECT ON db1.* to 'testbug'@localhost;
+USE db2;
+CREATE TABLE t1 (a INT);
+USE test;
+connect (con1,localhost,testbug,,db1);
+--error ER_NO_SUCH_TABLE
+SELECT * FROM `../db2/tb2`;
+--error ER_TABLEACCESS_DENIED_ERROR
+SELECT * FROM `../db2`.tb2;
+--error ER_NO_SUCH_TABLE
+SELECT * FROM `#mysql50#/../db2/tb2`;
+connection default;
+disconnect con1;
+DROP USER 'testbug'@localhost;
+DROP TABLE db2.t1;
+DROP DATABASE db1;
+DROP DATABASE db2;
+
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test
index 4f92ff65177..f90c1dc3c58 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -1206,6 +1206,21 @@ SELECT (SELECT t2.a FROM t2 WHERE t2.a = t1.a) aa, b, COUNT( b)
DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug#52051: Aggregate functions incorrectly returns NULL from outer
+--echo # join query
+--echo #
+CREATE TABLE t1 (a INT PRIMARY KEY);
+CREATE TABLE t2 (a INT PRIMARY KEY);
+INSERT INTO t2 VALUES (1), (2);
+EXPLAIN SELECT MIN(t2.a) FROM t2 LEFT JOIN t1 ON t2.a = t1.a;
+SELECT MIN(t2.a) FROM t2 LEFT JOIN t1 ON t2.a = t1.a;
+EXPLAIN SELECT MAX(t2.a) FROM t2 LEFT JOIN t1 ON t2.a = t1.a;
+SELECT MAX(t2.a) FROM t2 LEFT JOIN t1 ON t2.a = t1.a;
+DROP TABLE t1, t2;
+
+
--echo #
--echo # End of 5.1 tests
diff --git a/mysql-test/t/handler_myisam.test b/mysql-test/t/handler_myisam.test
index da02a90af0f..868ba14480a 100644
--- a/mysql-test/t/handler_myisam.test
+++ b/mysql-test/t/handler_myisam.test
@@ -37,4 +37,15 @@ TRUNCATE t1;
HANDLER t1 READ FIRST;
DROP TABLE t1;
+--echo #
+--echo # BUG#51877 - HANDLER interface causes invalid memory read
+--echo #
+CREATE TABLE t1(a INT, KEY(a));
+HANDLER t1 OPEN;
+HANDLER t1 READ a FIRST;
+INSERT INTO t1 VALUES(1);
+HANDLER t1 READ a NEXT;
+HANDLER t1 CLOSE;
+DROP TABLE t1;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test
index b68ba69b975..65bf9518a5c 100644
--- a/mysql-test/t/having.test
+++ b/mysql-test/t/having.test
@@ -498,4 +498,49 @@ HAVING (table2.f2 = 8);
DROP TABLE t1;
+--echo #
+--echo # Bug#52336 Segfault / crash in 5.1 copy_fields (param=0x9872980) at sql_select.cc:15355
+--echo #
+CREATE TABLE t1(f1 INT, f2 INT);
+INSERT INTO t1 VALUES (10,8);
+CREATE TABLE t2 (f1 INT);
+INSERT INTO t2 VALUES (5);
+
+SELECT COUNT(f1) FROM t2
+HAVING (7, 9) IN (SELECT f1, MIN(f2) FROM t1);
+
+DROP TABLE t1, t2;
+
+CREATE TABLE t1 (f1 INT, f2 VARCHAR(1));
+INSERT INTO t1 VALUES (16,'f');
+INSERT INTO t1 VALUES (16,'f');
+CREATE TABLE t2 (f1 INT, f2 VARCHAR(1));
+INSERT INTO t2 VALUES (13,'f');
+INSERT INTO t2 VALUES (20,'f');
+CREATE TABLE t3 (f1 INT, f2 VARCHAR(1));
+INSERT INTO t3 VALUES (7,'f');
+
+SELECT t1.f2 FROM t1
+STRAIGHT_JOIN (t2 JOIN t3 ON t3.f2 = t2.f2 ) ON t3 .f2 = t2 .f2
+HAVING ('v', 'i') NOT IN (SELECT f2, MIN(f2) FROM t1)
+ORDER BY f2;
+
+DROP TABLES t1,t2,t3;
+
+--echo #
+--echo # Bug#52340 Segfault: read_cached_record (tab=0x94a2634) at sql_select.cc:14411
+--echo #
+CREATE TABLE t1 (f1 INT, f2 VARCHAR(1));
+INSERT INTO t1 VALUES (16,'d');
+CREATE TABLE t2 (f1 INT, f2 VARCHAR(1));
+INSERT INTO t2 VALUES (13,'e');
+INSERT INTO t2 VALUES (20,'d');
+
+SELECT MAX(t2.f2) FROM t2 JOIN t1 ON t1.f2
+HAVING ('e' , 'd') IN
+(SELECT ts1.f2, ts2.f2 FROM t2 ts1 JOIN t2 ts2 ON ts1.f1)
+ORDER BY t1.f2;
+
+DROP TABLE t1,t2;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test
index 63eff93ba7f..f2c770cce42 100644
--- a/mysql-test/t/innodb_mysql.test
+++ b/mysql-test/t/innodb_mysql.test
@@ -589,6 +589,66 @@ ALTER TABLE t1 DROP INDEX k, ADD UNIQUE INDEX k (a,b);
DROP TABLE t1;
+
+--echo #
+--echo # Bug #47453: InnoDB incorrectly changes TIMESTAMP columns when
+--echo # JOINed during an UPDATE
+--echo #
+
+CREATE TABLE t1 (d INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT, b INT,
+ c TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
+ ON UPDATE CURRENT_TIMESTAMP) ENGINE=InnoDB;
+
+--echo set up our data elements
+INSERT INTO t1 (d) VALUES (1);
+INSERT INTO t2 (a,b) VALUES (1,1);
+SELECT SECOND(c) INTO @bug47453 FROM t2;
+
+SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a;
+UPDATE t1 JOIN t2 ON d=a SET b=1 WHERE a=1;
+SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a;
+
+SELECT SLEEP(1);
+
+UPDATE t1 JOIN t2 ON d=a SET b=1 WHERE a=1;
+
+--echo #should be 0
+SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug #53334: wrong result for outer join with impossible ON condition
+--echo # (see the same test case for MyISAM in join.test)
+--echo #
+
+CREATE TABLE t1 (id INT PRIMARY KEY);
+CREATE TABLE t2 (id INT);
+
+INSERT INTO t1 VALUES (75);
+INSERT INTO t1 VALUES (79);
+INSERT INTO t1 VALUES (78);
+INSERT INTO t1 VALUES (77);
+REPLACE INTO t1 VALUES (76);
+REPLACE INTO t1 VALUES (76);
+INSERT INTO t1 VALUES (104);
+INSERT INTO t1 VALUES (103);
+INSERT INTO t1 VALUES (102);
+INSERT INTO t1 VALUES (101);
+INSERT INTO t1 VALUES (105);
+INSERT INTO t1 VALUES (106);
+INSERT INTO t1 VALUES (107);
+
+INSERT INTO t2 VALUES (107),(75),(1000);
+
+SELECT t1.id,t2.id FROM t2 LEFT JOIN t1 ON t1.id>=74 AND t1.id<=0
+ WHERE t2.id=75 AND t1.id IS NULL;
+EXPLAIN SELECT t1.id,t2.id FROM t2 LEFT JOIN t1 ON t1.id>=74 AND t1.id<=0
+ WHERE t2.id=75 AND t1.id IS NULL;
+
+DROP TABLE t1,t2;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test
index 761121313e5..43b373c9703 100644
--- a/mysql-test/t/join.test
+++ b/mysql-test/t/join.test
@@ -784,6 +784,40 @@ FROM
DROP TABLE t1,t2,t3,t4,t5,t6;
+--echo #
+--echo # Bug#48483: crash in get_best_combination()
+--echo #
+
+CREATE TABLE t1(f1 INT);
+INSERT INTO t1 VALUES (1),(2);
+CREATE VIEW v1 AS SELECT 1 FROM t1 LEFT JOIN t1 AS t2 on 1=1;
+EXPLAIN EXTENDED
+SELECT 1 FROM v1 right join v1 AS v2 ON RAND();
+DROP VIEW v1;
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#52177 crash with explain, row comparison, join, text field
+--echo #
+CREATE TABLE t1 (a TINYINT, b TEXT, KEY (a));
+INSERT INTO t1 VALUES (0,''),(0,'');
+FLUSH TABLES;
+EXPLAIN SELECT 1 FROM t1 LEFT JOIN t1 a ON 1
+WHERE ROW(t1.a, 1111.11) = ROW(1111.11, 1111.11) AND
+ROW(t1.b, 1111.11) <=> ROW('','');
+DROP TABLE t1;
+
+--echo #
+--echo # Bug #50335: Assertion `!(order->used & map)' in eq_ref_table
+--echo #
+
+CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b));
+INSERT INTO t1 VALUES (0,0), (1,1);
+
+SELECT * FROM t1 STRAIGHT_JOIN t1 t2 ON t1.a=t2.a AND t1.a=t2.b ORDER BY t2.a, t1.a;
+
+DROP TABLE t1;
+
--echo End of 5.0 tests.
@@ -817,15 +851,4 @@ ENGINE=MERGE UNION=(t1,t2);
SELECT t1.a FROM mm1,t1;
DROP TABLE t1, t2, mm1;
---echo #
---echo # Bug #50335: Assertion `!(order->used & map)' in eq_ref_table
---echo #
-
-CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b));
-INSERT INTO t1 VALUES (0,0), (1,1);
-
-SELECT * FROM t1 STRAIGHT_JOIN t1 t2 ON t1.a=t2.a AND t1.a=t2.b ORDER BY t2.a, t1.a;
-
-DROP TABLE t1;
-
--echo End of 5.1 tests
diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test
index e3d68d71603..aaea8b3120b 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -913,4 +913,27 @@ WHERE (COALESCE(t1.f1, t2.f1), f3) IN ((1, 3), (2, 2));
DROP TABLE t1, t2;
+--echo #
+--echo # Bug#52357: Assertion failed: join->best_read in greedy_search
+--echo # optimizer_search_depth=0
+--echo #
+CREATE TABLE t1( a INT );
+
+INSERT INTO t1 VALUES (1),(2);
+SET optimizer_search_depth = 0;
+
+--echo # Should not core dump on query preparation
+EXPLAIN
+SELECT 1
+FROM t1 tt3 LEFT OUTER JOIN t1 tt4 ON 1
+ LEFT OUTER JOIN t1 tt5 ON 1
+ LEFT OUTER JOIN t1 tt6 ON 1
+ LEFT OUTER JOIN t1 tt7 ON 1
+ LEFT OUTER JOIN t1 tt8 ON 1
+ RIGHT OUTER JOIN t1 tt2 ON 1
+ RIGHT OUTER JOIN t1 tt1 ON 1
+ STRAIGHT_JOIN t1 tt9 ON 1;
+
+SET optimizer_search_depth = DEFAULT;
+DROP TABLE t1;
--echo End of 5.1 tests
diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test
index 7bfe2491c7c..c10a7d82c43 100644
--- a/mysql-test/t/loaddata.test
+++ b/mysql-test/t/loaddata.test
@@ -153,10 +153,6 @@ select * from t1;
#
# It should not be possible to load from a file outside of vardir
---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-show variables like "secure_file_pri%";
---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-select @@secure_file_priv;
--error 1238
set @@secure_file_priv= 0;
@@ -502,6 +498,13 @@ set session sql_mode=@OLD_SQL_MODE;
DROP TABLE t1,t2;
+--echo #
+--echo # Bug #51893: crash with certain characters given to load_file
+--echo # function on windows
+--echo #
+
+select load_file(0x0A9FB76C661B409C4BEC88098C5DD71B1072F9691F2E827D7EC8F092B299868A3CE196C04F0FB18CAB4E1557EB72331D812379DE7A75CA21C32E7C722C59E5CC33EF262EF04187B0F0EE756FA984DF2EAD37B1E4ADB064C3C5038F2E3B2D661B1C1150AAEB5425512E14D7506166D92D4533872E662F4B2D1428AAB5CCA72E75AA2EF325E196A5A02E2E8278873C64375845994B0F39BE2FF7B478332A7B0AA5E48877C47B6F513E997848AF8CCB8A899F3393AB35333CF0871E36698193862D486B4B9078B70C0A0A507B8A250F3F876F5A067632D5E65193E4445A1EC3A2C9B4C6F07AC334F0F62BC33357CB502E9B1C19D2398B6972AEC2EF21630F8C9134C4F7DD662D8AD7BDC9E19C46720F334B66C22D4BF32ED275144E20E7669FFCF6FC143667C9F02A577F32960FA9F2371BE1FA90E49CBC69C01531F140556854D588DD0E55E1307D78CA38E975CD999F9AEA604266329EE62BFB5ADDA67F549E211ECFBA906C60063696352ABB82AA782D25B17E872EA587871F450446DB1BAE0123D20404A8F2D2698B371002E986C8FCB969A99FF0E150A2709E2ED7633D02ADA87D5B3C9487D27B2BD9D21E2EC3215DCC3CDCD884371281B95A2E9987AAF82EB499C058D9C3E7DC1B66635F60DB121C72F929622DD47B6B2E69F59FF2AE6B63CC2EC60FFBA20EA50569DBAB5DAEFAEB4F03966C9637AB55662EDD28439155A82D053A5299448EDB2E7BEB0F62889E2F84E6C7F34B3212C9AAC32D521D5AB8480993F1906D5450FAB342A0FA6ED223E178BAC036B81E15783604C32A961EA1EF20BE2EBB93D34ED37BC03142B7583303E4557E48551E4BD7CBDDEA146D5485A5D212C35189F0BD6497E66912D2780A59A53B532E12C0A5ED1EC0445D96E8F2DD825221CFE4A65A87AA21DC8750481B9849DD81694C3357A0ED9B78D608D8EDDE28FAFBEC17844DE5709F41E121838DB55639D77E32A259A416D7013B2EB1259FDE1B498CBB9CAEE1D601DF3C915EA91C69B44E6B72062F5F4B3C73F06F2D5AD185E1692E2E0A01E7DD5133693681C52EE13B2BE42D03BDCF48E4E133CF06662339B778E1C3034F9939A433E157449172F7969ACCE1F5D2F65A4E09E4A5D5611EBEDDDBDB0C0C0A);
+
--echo End of 5.0 tests
@@ -532,5 +535,19 @@ SET character_set_filesystem=default;
select @@character_set_filesystem;
+--echo #
+--echo # Bug #51850: crash/memory overlap when using load data infile and set
+--echo # col equal to itself!
+--echo #
+
+CREATE TABLE t1(col0 LONGBLOB);
+SELECT 'test' INTO OUTFILE 't1.txt';
+LOAD DATA INFILE 't1.txt' IGNORE INTO TABLE t1 SET col0=col0;
+SELECT * FROM t1;
+
+DROP TABLE t1;
+let $MYSQLD_DATADIR= `select @@datadir`;
+remove_file $MYSQLD_DATADIR/test/t1.txt;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/log_state.test b/mysql-test/t/log_state.test
index 4d8c8fc6e74..d47044fbbee 100644
--- a/mysql-test/t/log_state.test
+++ b/mysql-test/t/log_state.test
@@ -313,6 +313,42 @@ SET @@global.general_log_file = @old_general_log_file;
SET @@global.slow_query_log = @old_slow_query_log;
SET @@global.slow_query_log_file = @old_slow_query_log_file;
+###########################################################################
+
+--echo #
+--echo # Bug #49756 Rows_examined is always 0 in the slow query log
+--echo # for update statements
+--echo #
+
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = "TABLE";
+SET GLOBAL slow_query_log = ON;
+SET GLOBAL long_query_time = 0.001;
+
+# clear slow_log of any residual slow queries
+TRUNCATE TABLE mysql.slow_log;
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (b INT, PRIMARY KEY (b));
+INSERT INTO t2 VALUES (3),(4);
+
+connect (con2,localhost,root,,);
+INSERT INTO t1 VALUES (1+sleep(.01)),(2);
+INSERT INTO t1 SELECT b+sleep(.01) from t2;
+UPDATE t1 SET a=a+sleep(.01) WHERE a>2;
+UPDATE t1 SET a=a+sleep(.01) ORDER BY a DESC;
+UPDATE t2 set b=b+sleep(.01) limit 1;
+UPDATE t1 SET a=a+sleep(.01) WHERE a in (SELECT b from t2);
+DELETE FROM t1 WHERE a=a+sleep(.01) ORDER BY a LIMIT 2;
+
+SELECT rows_examined,sql_text FROM mysql.slow_log;
+disconnect con2;
+connection default;
+DROP TABLE t1,t2;
+TRUNCATE TABLE mysql.slow_log;
+
+--echo # end of bug#49756
+
+
--echo End of 5.1 tests
@@ -361,6 +397,8 @@ disconnect con1;
connection default;
# Reset global system variables to initial values if forgotten somewhere above.
+SET GLOBAL long_query_time = DEFAULT;
+SET GLOBAL log_output = @old_log_output;
SET global general_log = @old_general_log;
SET global general_log_file = @old_general_log_file;
SET global slow_query_log = @old_slow_query_log;
diff --git a/mysql-test/t/mdl_sync.test b/mysql-test/t/mdl_sync.test
index ef434e33cfa..0b4b9af5bc6 100644
--- a/mysql-test/t/mdl_sync.test
+++ b/mysql-test/t/mdl_sync.test
@@ -3468,6 +3468,27 @@ connection default;
set debug_sync= 'RESET';
drop table t1;
+--echo #
+--echo # Bug#52856 concurrent show columns or show full columns causes a crash!!!
+--echo #
+CREATE TABLE t1(a CHAR(255));
+
+connect(con1, localhost, root);
+SET DEBUG_SYNC= "get_schema_column SIGNAL waiting WAIT_FOR completed";
+--send SHOW FULL COLUMNS FROM t1
+
+connection default;
+SET DEBUG_SYNC= "now WAIT_FOR waiting";
+--replace_column 8 #
+SHOW FULL COLUMNS FROM t1;
+SET DEBUG_SYNC= "now SIGNAL completed";
+--replace_column 8 #
+connection con1;
+--reap
+connection default;
+DROP TABLE t1;
+disconnect con1;
+
# 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.
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index ab901185e43..a9d98da0403 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -126,7 +126,6 @@ drop table t3,t2,t1;
# Test table without unions
#
create table t1 (a int not null, key(a)) engine=merge;
---error 1030
select * from t1;
drop table t1;
@@ -616,6 +615,14 @@ SHOW CREATE TABLE m1;
DROP TABLE t1, m1;
#
+# BUG#35274 - merge table doesn't need any base tables, gives error 124 when
+# key accessed
+#
+CREATE TABLE t1(a INT, KEY(a)) ENGINE=merge;
+SELECT MAX(a) FROM t1;
+DROP TABLE t1;
+
+#
# BUG#32047 - 'Spurious' errors while opening MERGE tables
#
CREATE TABLE t1(a INT);
diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test
index 5cfd7f9008a..8b250dbb586 100644
--- a/mysql-test/t/mysqlbinlog.test
+++ b/mysql-test/t/mysqlbinlog.test
@@ -445,12 +445,19 @@ FLUSH LOGS;
# Transaction3 end
--echo #
---echo # Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified is exist
+--echo # Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified exists
--exec $MYSQL_BINLOG --database=test --short-form $MYSQLTEST_VARDIR/std_data/binlog_transaction.000001
--echo #
---echo # Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified is not exist
+--echo # Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified does not exist
--exec $MYSQL_BINLOG --database=not_exist --short-form $MYSQLTEST_VARDIR/std_data/binlog_transaction.000001
+--echo #
+--echo # Test if the 'SAVEPOINT', 'ROLLBACK TO' are output if the database specified exists
+--exec $MYSQL_BINLOG --database=db1 --short-form $MYSQLTEST_VARDIR/std_data/binlog_savepoint.000001
+--echo #
+--echo # Test if the 'SAVEPOINT', 'ROLLBACK TO' are output if the database specified does not exist
+--exec $MYSQL_BINLOG --database=not_exist --short-form $MYSQLTEST_VARDIR/std_data/binlog_savepoint.000001
+
--echo End of 5.0 tests
--echo End of 5.1 tests
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index a260f13e58b..952a3f94fb2 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -1988,6 +1988,7 @@ drop table if exists `load`;
create table `load` (a varchar(255));
--copy_file std_data/words.dat $MYSQLTEST_VARDIR/tmp/load.txt
+--chmod 0644 $MYSQLTEST_VARDIR/tmp/load.txt
--exec $MYSQL_IMPORT --ignore test $MYSQLTEST_VARDIR/tmp/load.txt
@@ -2137,6 +2138,35 @@ SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c;
SET NAMES default;
DROP TABLE t1, t2;
+###########################################################################
+
+--echo #
+--echo # Bug #53088: mysqldump with -T & --default-character-set set
+--echo # truncates text/blob to 766 chars
+--echo #
+--echo # Also see outfile_loaddata.test
+--echo #
+
+CREATE TABLE t1 (a BLOB) CHARSET latin1;
+CREATE TABLE t2 LIKE t1;
+
+let $table= t1;
+let $dir= $MYSQLTEST_VARDIR/tmp;
+let $file= $dir/$table.txt;
+let $length= 800;
+
+--eval INSERT INTO t1 VALUES (REPEAT('.', $length))
+
+--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --default-character-set=latin1 --tab=$dir/ test $table
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+
+--eval LOAD DATA INFILE '$file' INTO TABLE t2 CHARACTER SET latin1
+--remove_file $file
+
+--echo # should be $length
+SELECT LENGTH(a) FROM t2;
+
+DROP TABLE t1, t2;
###########################################################################
--echo #
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index 36b6015c5d8..2ea169d950d 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -1468,3 +1468,27 @@ SELECT * FROM t1 FORCE INDEX FOR JOIN (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
DROP TABLE t1, t2;
--echo End of 5.1 tests
+
+
+--echo #
+--echo # Bug #38745: MySQL 5.1 optimizer uses filesort for ORDER BY
+--echo # when it should use index
+--echo #
+
+CREATE TABLE t1 (i1 integer NOT NULL PRIMARY KEY);
+CREATE TABLE t2 (i2 integer NOT NULL PRIMARY KEY);
+CREATE TABLE t3 (i3 integer);
+
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12);
+INSERT INTO t2 SELECT * FROM t1;
+
+EXPLAIN EXTENDED
+SELECT t1.*, t2.* FROM t1 JOIN t2 ON t1.i1 = t2.i2
+ LEFT JOIN t3 ON t2.i2 = t3.i3
+ ORDER BY t1.i1 LIMIT 5;
+
+SELECT t1.*, t2.* FROM t1 JOIN t2 ON t1.i1 = t2.i2
+ LEFT JOIN t3 ON t2.i2 = t3.i3
+ ORDER BY t1.i1 LIMIT 5;
+
+DROP TABLE t1, t2, t3;
diff --git a/mysql-test/t/outfile_loaddata.test b/mysql-test/t/outfile_loaddata.test
index 3f62acbd214..26760f9a1b2 100644
--- a/mysql-test/t/outfile_loaddata.test
+++ b/mysql-test/t/outfile_loaddata.test
@@ -251,6 +251,40 @@ SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c;
SET NAMES default;
DROP TABLE t1, t2;
+###########################################################################
+
+--echo #
+--echo # Bug #53088: mysqldump with -T & --default-character-set set
+--echo # truncates text/blob to 766 chars
+--echo #
+--echo # Also see mysqldump.test
+--echo #
+
+CREATE TABLE t1 (a BLOB) CHARSET latin1;
+CREATE TABLE t2 LIKE t1;
+
+let $file= '$MYSQLTEST_VARDIR/tmp/bug53088.txt';
+let $length= 800;
+
+--eval INSERT INTO t1 VALUES (REPEAT('.', $length))
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--eval SELECT * INTO OUTFILE $file CHARACTER SET latin1 FROM t1
+
+--echo # should be greater than $length
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--eval SELECT LENGTH(LOAD_FILE($file))
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--eval LOAD DATA INFILE $file INTO TABLE t2
+
+--remove_file $MYSQLTEST_VARDIR/tmp/bug53088.txt
+
+--echo # should be $length
+SELECT LENGTH(a) FROM t2;
+
+DROP TABLE t1, t2;
+
###########################################################################
--echo # End of 5.1 tests.
diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test
index bcb5d4b5d92..1224dee24ed 100644
--- a/mysql-test/t/partition.test
+++ b/mysql-test/t/partition.test
@@ -2185,4 +2185,16 @@ SELECT * FROM t1;
DROP TABLE t1;
+--echo #
+--echo # BUG#51868 - crash with myisam_use_mmap and partitioned myisam tables
+--echo #
+SET GLOBAL myisam_use_mmap=1;
+CREATE TABLE t1(a INT) PARTITION BY HASH(a) PARTITIONS 1;
+INSERT INTO t1 VALUES(0);
+FLUSH TABLE t1;
+TRUNCATE TABLE t1;
+INSERT INTO t1 VALUES(0);
+DROP TABLE t1;
+SET GLOBAL myisam_use_mmap=default;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index dcea4d9828b..f7ce70c1d3a 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -3065,6 +3065,20 @@ select @plaintext;
deallocate prepare encode;
deallocate prepare decode;
+--echo #
+--echo # Bug#52124 memory leaks like a sieve in datetime, timestamp, time, date fields + warnings
+--echo #
+CREATE TABLE t1 (a DATETIME NOT NULL, b TINYINT);
+INSERT INTO t1 VALUES (0, 0),(0, 0);
+PREPARE stmt FROM "SELECT 1 FROM t1 WHERE
+ROW(a, b) >= ROW('1', (SELECT 1 FROM t1 WHERE a > 1234))";
+--disable_warnings
+EXECUTE stmt;
+EXECUTE stmt;
+--enable_warnings
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+
###########################################################################
--echo
diff --git a/mysql-test/t/query_cache_with_views.test b/mysql-test/t/query_cache_with_views.test
index d4ebe45b7ac..97e37c53aa3 100644
--- a/mysql-test/t/query_cache_with_views.test
+++ b/mysql-test/t/query_cache_with_views.test
@@ -126,5 +126,22 @@ show status like "Qcache_inserts";
show status like "Qcache_hits";
drop table t1;
+--echo #
+--echo # Bug46615 Assertion in Query_cache::invalidate in INSERT in a VIEW of a MERGE table
+--echo #
+CREATE TABLE t1 (c1 INT, c2 INT);
+CREATE TABLE t2 LIKE t1;
+SET AUTOCOMMIT=OFF;
+CREATE VIEW t1_view AS SELECT c1 FROM t1 NATURAL JOIN t2 ;
+# Before the bug patch the below INSERT stmt used to
+# crash when other fields than the ones listed in the
+# view definition were used.
+--error ER_BAD_FIELD_ERROR
+INSERT INTO t1_view (c1, c2) SELECT c1, c2 FROM t1;
+DROP TABLE t1;
+DROP TABLE t2;
+DROP VIEW t1_view;
+SET AUTOCOMMIT=DEFAULT;
+
# Reset default environment.
set GLOBAL query_cache_size=default;
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index 5d5ad180f1a..2d2a6f75d73 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -1313,4 +1313,45 @@ SELECT * FROM t1 FORCE INDEX (PRIMARY)
DROP TABLE t1;
+--echo #
+--echo # Bug#50939: Loose Index Scan unduly relies on engine to remember range
+--echo # endpoints
+--echo #
+CREATE TABLE t1 (
+ a INT,
+ b INT,
+ KEY ( a, b )
+) PARTITION BY HASH (a) PARTITIONS 1;
+
+CREATE TABLE t2 (
+ a INT,
+ b INT,
+ KEY ( a, b )
+);
+
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
+
+INSERT INTO t1 SELECT a + 5, b + 5 FROM t1;
+INSERT INTO t1 SELECT a + 10, b + 10 FROM t1;
+INSERT INTO t1 SELECT a + 20, b + 20 FROM t1;
+INSERT INTO t1 SELECT a + 40, b + 40 FROM t1;
+
+INSERT INTO t2 SELECT * FROM t1;
+
+--echo # plans should be identical
+EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10,100) GROUP BY a;
+EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a;
+
+FLUSH status;
+SELECT a, MAX(b) FROM t1 WHERE a IN (10, 100) GROUP BY a;
+--echo # Should be no more than 4 reads.
+SHOW status LIKE 'handler_read_key';
+
+FLUSH status;
+SELECT a, MAX(b) FROM t2 WHERE a IN (10, 100) GROUP BY a;
+--echo # Should be no more than 4 reads.
+SHOW status LIKE 'handler_read_key';
+
+DROP TABLE t1, t2;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/renamedb.test b/mysql-test/t/renamedb.test
index 84315090b7a..71d0c127058 100644
--- a/mysql-test/t/renamedb.test
+++ b/mysql-test/t/renamedb.test
@@ -44,7 +44,7 @@ ALTER DATABASE `#mysql41#not-supported` UPGRADE DATA DIRECTORY NAME;
--error ER_WRONG_USAGE
ALTER DATABASE `#mysql51#not-yet` UPGRADE DATA DIRECTORY NAME;
---error ER_WRONG_USAGE
+--error ER_WRONG_DB_NAME
ALTER DATABASE `#mysql50#` UPGRADE DATA DIRECTORY NAME;
--error ER_BAD_DB_ERROR
diff --git a/mysql-test/t/row.test b/mysql-test/t/row.test
index fcc4259168b..cec44078279 100644
--- a/mysql-test/t/row.test
+++ b/mysql-test/t/row.test
@@ -255,3 +255,14 @@ select * from t1,t2 where (a,b) = (c,d);
select host,user from mysql.user where (host,user) = ('localhost','test');
drop table t1,t2;
+
+--echo #
+--echo # Bug#52124 memory leaks like a sieve in datetime, timestamp, time, date fields + warnings
+--echo #
+CREATE TABLE t1 (a DATETIME NOT NULL, b TINYINT);
+INSERT INTO t1 VALUES (0, 0),(0, 0);
+--disable_warnings
+SELECT 1 FROM t1 WHERE ROW(a, b) >=
+ROW('1', (SELECT 1 FROM t1 WHERE a > 1234));
+--enable_warnings
+DROP TABLE t1;
diff --git a/mysql-test/t/skip_name_resolve.test b/mysql-test/t/skip_name_resolve.test
index cd7ffe1690d..a14f3af5cd6 100644
--- a/mysql-test/t/skip_name_resolve.test
+++ b/mysql-test/t/skip_name_resolve.test
@@ -29,3 +29,24 @@ disconnect con1;
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
+--echo #
+--echo # Bug #37168: Missing variable - skip_name_resolve
+--echo #
+
+SHOW VARIABLES LIKE 'skip_name_resolve';
+SHOW GLOBAL VARIABLES LIKE 'skip_name_resolve';
+SHOW SESSION VARIABLES LIKE 'skip_name_resolve';
+
+SELECT @@skip_name_resolve;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT @@LOCAL.skip_name_resolve;
+SELECT @@GLOBAL.skip_name_resolve;
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@skip_name_resolve=0;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@LOCAL.skip_name_resolve=0;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@GLOBAL.skip_name_resolve=0;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 50f2644ff9e..06aaf5dfb7f 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -3838,3 +3838,86 @@ DROP TABLE t1;
--echo End of 5.1 tests.
+
+#
+# Bug #47904 Incorrect results w/ table subquery, derived SQs, and LEFT JOIN on index
+#
+
+--echo Set up test tables.
+CREATE TABLE t1 (
+ t1_id INT UNSIGNED,
+
+ PRIMARY KEY(t1_id)
+) Engine=MyISAM;
+
+INSERT INTO t1 (t1_id) VALUES (1), (2), (3), (4), (5);
+
+CREATE TABLE t2 SELECT * FROM t1;
+
+CREATE TABLE t3 (
+ t3_id INT UNSIGNED AUTO_INCREMENT,
+ t1_id INT UNSIGNED,
+ amount DECIMAL(16,2),
+
+ PRIMARY KEY(t3_id),
+ KEY(t1_id)
+) Engine=MyISAM;
+
+INSERT INTO t3 (t1_id, t3_id, amount)
+ VALUES (1, 1, 100.00), (2, 2, 200.00), (4, 4, 400.00);
+
+--echo This is the 'inner query' running by itself.
+--echo Produces correct results.
+SELECT
+ t1.t1_id,
+ IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+ t1
+ LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+ t1.t1_id
+;
+
+--echo SELECT * FROM (the same inner query)
+--echo Produces correct results.
+SELECT * FROM (
+SELECT
+ t1.t1_id,
+ IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+ t1
+ LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+ t1.t1_id
+) AS t;
+
+--echo Now make t2.t1_id part of a key.
+ALTER TABLE t2 ADD PRIMARY KEY(t1_id);
+
+--echo Same inner query by itself.
+--echo Still correct results.
+SELECT
+ t1.t1_id,
+ IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+ t1
+ LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+ t1.t1_id;
+
+--echo SELECT * FROM (the same inner query), now with indexes on the LEFT JOIN
+SELECT * FROM (
+SELECT
+ t1.t1_id,
+ IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+ t1
+ LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+ t1.t1_id
+) AS t;
+
+
+DROP TABLE t3;
+DROP TABLE t2;
+DROP TABLE t1;
diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test
index c805dd40fe8..073fcd28246 100644
--- a/mysql-test/t/symlink.test
+++ b/mysql-test/t/symlink.test
@@ -249,4 +249,26 @@ eval CREATE TABLE t1(a INT) DATA DIRECTORY='$MYSQLTEST_VARDIR/tmp' INDEX DIRECTO
DROP TABLE t1;
SET @@SQL_MODE=@OLD_SQL_MODE;
+--echo #
+--echo # BUG#40980 - Drop table can remove another MyISAM table's
+--echo # data and index files
+--echo #
+--mkdir $MYSQL_TMP_DIR/mysql
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
+eval CREATE TABLE user(a INT) DATA DIRECTORY='$MYSQL_TMP_DIR/mysql'
+ INDEX DIRECTORY='$MYSQL_TMP_DIR/mysql';
+FLUSH TABLE user;
+--echo # Symlinking mysql database to tmpdir
+--remove_file $MYSQL_TMP_DIR/mysql/user.MYD
+--remove_file $MYSQL_TMP_DIR/mysql/user.MYI
+--rmdir $MYSQL_TMP_DIR/mysql
+--exec ln -s $MYSQLD_DATADIR/mysql $MYSQL_TMP_DIR/mysql
+FLUSH TABLE mysql.user;
+DROP TABLE user;
+FLUSH TABLE mysql.user;
+--disable_result_log
+SELECT * FROM mysql.user;
+--enable_result_log
+--remove_file $MYSQL_TMP_DIR/mysql
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index 8ba21ed696a..2eb086cace5 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -2426,6 +2426,50 @@ INSERT IGNORE INTO t2 SET a = '777';
DROP TRIGGER trg1;
DROP TABLE t1, t2;
+#
+# Bug #48525: trigger changes "Column 'id' cannot be null" behaviour
+#
+CREATE TABLE t1 (id INT NOT NULL);
+CREATE TABLE t2 (id INT NOT NULL);
+INSERT t1 VALUES (1),(2),(3);
+UPDATE t1 SET id=NULL;
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+ INSERT INTO t2 VALUES (3);
+UPDATE t1 SET id=NULL;
+DROP TRIGGER t1_bu;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug#50755: Crash if stored routine def contains version comments
+--echo #
+
+--disable_warnings
+DROP DATABASE IF EXISTS db1;
+DROP TRIGGER IF EXISTS trg1;
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+CREATE DATABASE db1;
+USE db1;
+
+CREATE TABLE t1 (b INT);
+CREATE TABLE t2 (a INT);
+
+CREATE TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERT/*!INTO*/t1 VALUES (1);
+--echo # Used to crash
+SHOW TRIGGERS IN db1;
+--error ER_PARSE_ERROR
+INSERT INTO t2 VALUES (1);
+SELECT * FROM t1;
+
+--echo # Work around Bug#45235
+let $MYSQLD_DATADIR = `select @@datadir`;
+--remove_file $MYSQLD_DATADIR/db1/t2.TRG
+--remove_file $MYSQLD_DATADIR/db1/trg1.TRN
+
+DROP DATABASE db1;
+USE test;
+
--echo End of 5.1 tests.
diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test
index 5d9a2aaa5f4..1d4ef345747 100644
--- a/mysql-test/t/type_decimal.test
+++ b/mysql-test/t/type_decimal.test
@@ -542,3 +542,44 @@ select max(case 1 when 1 then c else null end) from t1 group by c;
drop table t1;
--echo End of 5.0 tests
+
+#
+# Bug#52168 decimal casting catastrophes:
+# crashes and valgrind errors on simple casts
+#
+
+# Uninitialized read when calling Item_cache_decimal::val_int()
+CREATE TABLE t1 (a INTEGER);
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2 (b INTEGER);
+INSERT INTO t2 VALUES (NULL), (NULL);
+SELECT b FROM t1 JOIN t2 WHERE CONVERT(a, DECIMAL)|CONVERT(b, DECIMAL);
+DROP TABLE t1, t2;
+
+#
+# Bug#52122 crash when converting derived table column to decimal
+#
+CREATE TABLE t1 (col0 INTEGER, col1 REAL);
+CREATE TABLE t2 (col0 INTEGER);
+INSERT INTO t1 VALUES (0, 0.0), (NULL, NULL);
+INSERT INTO t2 VALUES (1);
+
+# Uninitialized read when calling Item_cache_decimal::val_real()
+SELECT 1 FROM t1
+JOIN
+(
+ SELECT t2.col0 FROM t2 RIGHT JOIN t1 USING(col0)
+ GROUP BY t2.col0
+) AS subq
+WHERE t1.col1 + CAST(subq.col0 AS DECIMAL);
+
+# Uninitialized read when calling Item_cache_decimal::val_str()
+SELECT 1 FROM t1
+JOIN
+(
+ SELECT t2.col0 FROM t2 RIGHT JOIN t1 USING(col0)
+ GROUP BY t2.col0
+) AS subq
+WHERE CONCAT(t1.col1, CAST(subq.col0 AS DECIMAL));
+
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/upgrade.test b/mysql-test/t/upgrade.test
index e390e8a1253..a7b9a1531ff 100644
--- a/mysql-test/t/upgrade.test
+++ b/mysql-test/t/upgrade.test
@@ -137,3 +137,37 @@ select * from `a-b-c`.v1;
--enable_ps_protocol
drop database `a-b-c`;
use test;
+
+--echo # End of 5.0 tests
+
+--echo #
+--echo # Bug #53804: serious flaws in the alter database .. upgrade data
+--echo # directory name command
+--echo #
+
+--error ER_BAD_DB_ERROR
+ALTER DATABASE `#mysql50#:` UPGRADE DATA DIRECTORY NAME;
+--error ER_WRONG_DB_NAME
+ALTER DATABASE `#mysql50#.` UPGRADE DATA DIRECTORY NAME;
+--error ER_WRONG_DB_NAME
+ALTER DATABASE `#mysql50#../` UPGRADE DATA DIRECTORY NAME;
+--error ER_WRONG_DB_NAME
+ALTER DATABASE `#mysql50#../..` UPGRADE DATA DIRECTORY NAME;
+--error ER_WRONG_DB_NAME
+ALTER DATABASE `#mysql50#../../` UPGRADE DATA DIRECTORY NAME;
+--error ER_WRONG_DB_NAME
+ALTER DATABASE `#mysql50#./blablabla` UPGRADE DATA DIRECTORY NAME;
+--error ER_WRONG_DB_NAME
+ALTER DATABASE `#mysql50#../blablabla` UPGRADE DATA DIRECTORY NAME;
+--error ER_WRONG_DB_NAME
+ALTER DATABASE `#mysql50#/` UPGRADE DATA DIRECTORY NAME;
+--error ER_WRONG_DB_NAME
+ALTER DATABASE `#mysql50#/.` UPGRADE DATA DIRECTORY NAME;
+
+--error ER_WRONG_DB_NAME
+USE `#mysql50#.`;
+--error ER_WRONG_DB_NAME
+USE `#mysql50#../blablabla`;
+
+--echo # End of 5.1 tests
+
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index 39fa78ef370..5e9d8473b20 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -1220,6 +1220,14 @@ SET @old_max_binlog_cache_size = @@GLOBAL.max_binlog_cache_size;
SET GLOBAL max_binlog_cache_size = 5 * 1024 * 1024 * 1024;
SELECT @@GLOBAL.max_binlog_cache_size;
SET GLOBAL max_binlog_cache_size = @old_max_binlog_cache_size;
+
+--echo #
+--echo # Bug #37168 : Missing variable - skip_name_resolve
+--echo #
+
+SELECT @@skip_name_resolve;
+SHOW VARIABLES LIKE 'skip_name_resolve';
+
--echo End of 5.1 tests
###########################################################################
diff --git a/mysql-test/t/variables_debug.test b/mysql-test/t/variables_debug.test
index dac85345136..8fa2124137a 100644
--- a/mysql-test/t/variables_debug.test
+++ b/mysql-test/t/variables_debug.test
@@ -1,5 +1,7 @@
--source include/have_debug.inc
+SET @old_debug = @@GLOBAL.debug;
+
#
# Bug#34678 @@debug variable's incremental mode
#
@@ -20,3 +22,17 @@ SELECT @@session.debug, @@global.debug;
SET SESSION debug = '';
SELECT @@session.debug, @@global.debug;
+
+--echo #
+--echo # Bug #52629: memory leak from sys_var_thd_dbug in
+--echo # binlog.binlog_write_error
+--echo #
+
+SET GLOBAL debug='d,injecting_fault_writing';
+SELECT @@global.debug;
+SET GLOBAL debug='';
+SELECT @@global.debug;
+
+SET GLOBAL debug=@old_debug;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index d1a4d78e58f..4ef8b1898ae 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -3953,6 +3953,15 @@ ROW(1,1) >= ROW(1, (SELECT 1 FROM t1 WHERE f1 >= ANY ( SELECT '1' )));
DROP VIEW v1;
DROP TABLE t1;
+--echo #
+--echo # Bug#52120 create view cause Assertion failed: 0, file .\item_subselect.cc, line 817
+--echo #
+CREATE TABLE t1 (a CHAR(1) CHARSET latin1, b CHAR(1) CHARSET utf8);
+CREATE VIEW v1 AS SELECT 1 from t1
+WHERE t1.b <=> (SELECT a FROM t1 WHERE a < SOME(SELECT '1'));
+DROP VIEW v1;
+DROP TABLE t1;
+
--echo # -----------------------------------------------------------------
--echo # -- End of 5.1 tests.
--echo # -----------------------------------------------------------------
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index 2fbaac7fe72..4c93f5ffd57 100755
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -27,7 +27,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_
my_clock.c my_compress.c my_copy.c my_crc32.c my_create.c my_delete.c
my_div.c my_error.c my_file.c my_fopen.c my_fstream.c my_gethostbyname.c
my_gethwaddr.c my_getopt.c my_getsystime.c my_getwd.c my_handler.c my_init.c
- my_lib.c my_lock.c my_lockmem.c my_malloc.c my_messnc.c
+ my_lib.c my_lock.c my_lockmem.c my_malloc.c my_mess.c
my_mkdir.c my_mmap.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c
my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_sleep.c
my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index ad7f244e0fb..d5bffd874b2 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -34,7 +34,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
my_vle.c my_atomic.c lf_hash.c \
lf_dynarray.c lf_alloc-pin.c \
my_fopen.c my_fstream.c my_getsystime.c \
- my_error.c errors.c my_div.c my_messnc.c \
+ my_error.c errors.c my_div.c my_mess.c \
mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \
my_symlink.c my_symlink2.c \
mf_pack.c mf_unixpath.c mf_arr_appstr.c \
diff --git a/mysys/mf_loadpath.c b/mysys/mf_loadpath.c
index fbf6f7f5d57..07851ab6e92 100644
--- a/mysys/mf_loadpath.c
+++ b/mysys/mf_loadpath.c
@@ -34,7 +34,7 @@ char * my_load_path(char * to, const char *path,
if ((path[0] == FN_HOMELIB && path[1] == FN_LIBCHAR) ||
test_if_hard_path(path))
- (void) strmov(buff,path);
+ (void) strnmov(buff, path, FN_REFLEN);
else if ((is_cur=(path[0] == FN_CURLIB && path[1] == FN_LIBCHAR)) ||
(is_prefix(path,FN_PARENTDIR)) ||
! own_path_prefix)
@@ -42,13 +42,14 @@ char * my_load_path(char * to, const char *path,
if (is_cur)
is_cur=2; /* Remove current dir */
if (! my_getwd(buff,(uint) (FN_REFLEN-strlen(path)+is_cur),MYF(0)))
- (void) strcat(buff,path+is_cur);
+ (void) strncat(buff, path+is_cur, FN_REFLEN);
else
- (void) strmov(buff,path); /* Return org file name */
+ (void) strnmov(buff, path, FN_REFLEN); /* Return org file name */
}
else
- (void) strxmov(buff,own_path_prefix,path,NullS);
- strmov(to,buff);
+ (void) strxnmov(buff, FN_REFLEN, own_path_prefix, path, NullS);
+ strnmov(to, buff, FN_REFLEN);
+ to[FN_REFLEN-1]= '\0';
DBUG_PRINT("exit",("to: %s",to));
DBUG_RETURN(to);
} /* my_load_path */
diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c
index c13a5581b80..4f7cd90e8aa 100644
--- a/mysys/mf_pack.c
+++ b/mysys/mf_pack.c
@@ -311,6 +311,9 @@ size_t normalize_dirname(char *to, const char *from)
#endif
buff[length - 1] != FN_LIBCHAR && buff[length - 1] != '/')
{
+ /* we need reserve 2 bytes for the trailing slash and the zero */
+ if (length >= sizeof (buff) - 1)
+ length= sizeof (buff) - 2;
buff[length]= FN_LIBCHAR;
buff[length + 1]= '\0';
}
diff --git a/mysys/my_file.c b/mysys/my_file.c
index ec0c9c425ea..a31673b31bc 100644
--- a/mysys/my_file.c
+++ b/mysys/my_file.c
@@ -72,7 +72,7 @@ static uint set_max_open_files(uint max_file_limit)
}
#else
-static int set_max_open_files(uint max_file_limit)
+static uint set_max_open_files(uint max_file_limit)
{
/* We don't know the limit. Return best guess */
return min(max_file_limit, OS_FILE_LIMIT);
diff --git a/mysys/my_getwd.c b/mysys/my_getwd.c
index 6ef8d571492..4182ea9826f 100644
--- a/mysys/my_getwd.c
+++ b/mysys/my_getwd.c
@@ -50,16 +50,21 @@ int my_getwd(char * buf, size_t size, myf MyFlags)
DBUG_PRINT("my",("buf: 0x%lx size: %u MyFlags %d",
(long) buf, (uint) size, MyFlags));
+ if (size < 1)
+ DBUG_RETURN(-1);
+
if (curr_dir[0]) /* Current pos is saved here */
(void) strmake(buf,&curr_dir[0],size-1);
else
{
#if defined(HAVE_GETCWD)
+ if (size < 2)
+ DBUG_RETURN(-1);
if (!getcwd(buf,(uint) (size-2)) && MyFlags & MY_WME)
{
my_errno=errno;
my_error(EE_GETWD,MYF(ME_BELL+ME_WAITTANG),errno);
- return(-1);
+ DBUG_RETURN(-1);
}
#elif defined(HAVE_GETWD)
{
@@ -68,11 +73,13 @@ int my_getwd(char * buf, size_t size, myf MyFlags)
strmake(buf,pathname,size-1);
}
#elif defined(VMS)
+ if (size < 2)
+ DBUG_RETURN(-1);
if (!getcwd(buf,size-2,1) && MyFlags & MY_WME)
{
my_errno=errno;
my_error(EE_GETWD,MYF(ME_BELL+ME_WAITTANG),errno);
- return(-1);
+ DBUG_RETURN(-1);
}
intern_filename(buf,buf);
#else
diff --git a/mysys/my_init.c b/mysys/my_init.c
index 80f9a493bb0..f27f3f7b3e8 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -204,7 +204,7 @@ void my_end(int infoflag)
char ebuff[512];
my_snprintf(ebuff, sizeof(ebuff), EE(EE_OPEN_WARNING),
my_file_opened, my_stream_opened);
- my_message_no_curses(EE_OPEN_WARNING, ebuff, ME_BELL);
+ my_message_stderr(EE_OPEN_WARNING, ebuff, ME_BELL);
DBUG_PRINT("error", ("%s", ebuff));
my_print_open_files();
}
diff --git a/mysys/my_messnc.c b/mysys/my_mess.c
index e2dee3f6710..0ec97525ae8 100644
--- a/mysys/my_messnc.c
+++ b/mysys/my_mess.c
@@ -15,10 +15,10 @@
#include "mysys_priv.h"
-void my_message_no_curses(uint error __attribute__((unused)),
- const char *str, myf MyFlags)
+void my_message_stderr(uint error __attribute__((unused)),
+ const char *str, myf MyFlags)
{
- DBUG_ENTER("my_message_no_curses");
+ DBUG_ENTER("my_message_stderr");
DBUG_PRINT("enter",("message: %s",str));
(void) fflush(stdout);
if (MyFlags & ME_BELL)
diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c
index b6b7e7db857..3019e4bc5c1 100644
--- a/mysys/my_pthread.c
+++ b/mysys/my_pthread.c
@@ -492,11 +492,6 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex)
/* Some help functions */
-int pthread_no_free(void *not_used __attribute__((unused)))
-{
- return 0;
-}
-
int pthread_dummy(int ret)
{
return ret;
diff --git a/mysys/my_static.c b/mysys/my_static.c
index a86fe6c7ab7..ff5abba29d3 100644
--- a/mysys/my_static.c
+++ b/mysys/my_static.c
@@ -87,10 +87,10 @@ ulong my_time_to_wait_for_lock=2; /* In seconds */
char * NEAR globerrs[GLOBERRS]; /* my_error_messages is here */
#endif
void (*my_abort_hook)(int) = (void(*)(int)) exit;
-void (*error_handler_hook)(uint error,const char *str,myf MyFlags)=
- my_message_no_curses;
-void (*fatal_error_handler_hook)(uint error,const char *str,myf MyFlags)=
- my_message_no_curses;
+void (*error_handler_hook)(uint error, const char *str, myf MyFlags)=
+ my_message_stderr;
+void (*fatal_error_handler_hook)(uint error, const char *str, myf MyFlags)=
+ my_message_stderr;
static const char *proc_info_dummy(void *a __attribute__((unused)),
const char *b __attribute__((unused)),
@@ -123,7 +123,6 @@ my_bool NEAR my_disable_locking=0;
my_bool NEAR my_disable_async_io=0;
my_bool NEAR my_disable_flush_key_blocks=0;
my_bool NEAR my_disable_symlinks=0;
-my_bool NEAR mysys_uses_curses=0;
/*
Note that PSI_hook and PSI_server are unconditionally
diff --git a/plugin/daemon_example/daemon_example.cc b/plugin/daemon_example/daemon_example.cc
index 8f037e8babb..43138f0655f 100644
--- a/plugin/daemon_example/daemon_example.cc
+++ b/plugin/daemon_example/daemon_example.cc
@@ -13,13 +13,12 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+#include <my_global.h>
#include <sql_priv.h>
#include <stdlib.h>
#include <ctype.h>
-#include <time.h> // localtime_r
#include <mysql_version.h>
#include <mysql/plugin.h>
-#include <my_global.h>
#include <my_dir.h>
#include "my_pthread.h" // pthread_handler_t
#include "my_sys.h" // my_write, my_malloc
diff --git a/plugin/semisync/semisync_master.cc b/plugin/semisync/semisync_master.cc
index cdf01854442..40a0833b23f 100644
--- a/plugin/semisync/semisync_master.cc
+++ b/plugin/semisync/semisync_master.cc
@@ -147,7 +147,8 @@ int ActiveTranx::insert_tranx_node(const char *log_file_name,
}
/* insert the binlog position in the active transaction list. */
- strcpy(ins_node->log_name_, log_file_name);
+ strncpy(ins_node->log_name_, log_file_name, FN_REFLEN-1);
+ ins_node->log_name_[FN_REFLEN-1] = 0; /* make sure it ends properly */
ins_node->log_pos_ = log_file_pos;
if (!trx_front_)
@@ -1009,13 +1010,15 @@ int ReplSemiSyncMaster::writeTranxInBinlog(const char* log_file_name,
if (cmp > 0)
{
/* This is a larger position, let's update the maximum info. */
- strcpy(commit_file_name_, log_file_name);
+ strncpy(commit_file_name_, log_file_name, FN_REFLEN-1);
+ commit_file_name_[FN_REFLEN-1] = 0; /* make sure it ends properly */
commit_file_pos_ = log_file_pos;
}
}
else
{
- strcpy(commit_file_name_, log_file_name);
+ strncpy(commit_file_name_, log_file_name, FN_REFLEN-1);
+ commit_file_name_[FN_REFLEN-1] = 0; /* make sure it ends properly */
commit_file_pos_ = log_file_pos;
commit_file_name_inited_ = true;
}
@@ -1048,6 +1051,7 @@ int ReplSemiSyncMaster::readSlaveReply(NET *net, uint32 server_id,
const unsigned char *packet;
char log_file_name[FN_REFLEN];
my_off_t log_file_pos;
+ ulong log_file_len = 0;
ulong packet_len;
int result = -1;
@@ -1123,7 +1127,13 @@ int ReplSemiSyncMaster::readSlaveReply(NET *net, uint32 server_id,
}
log_file_pos = uint8korr(packet + REPLY_BINLOG_POS_OFFSET);
- strcpy(log_file_name, (const char*)packet + REPLY_BINLOG_NAME_OFFSET);
+ log_file_len = packet_len - REPLY_BINLOG_NAME_OFFSET;
+ if (log_file_len > FN_REFLEN)
+ {
+ sql_print_error("Read semi-sync reply binlog file length too large");
+ goto l_end;
+ }
+ strncpy(log_file_name, (const char*)packet + REPLY_BINLOG_NAME_OFFSET, log_file_len);
if (trc_level & kTraceDetail)
sql_print_information("%s: Got reply (%s, %lu)",
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
index 4514b5437b7..5d7f0760b82 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -199,6 +199,7 @@ parse_arguments() {
;;
--nice=*) niceness="$val" ;;
--open-files-limit=*) open_files="$val" ;;
+ --open_files_limit=*) open_files="$val" ;;
--skip-kill-mysqld*) KILL_MYSQLD=0 ;;
--syslog) want_syslog=1 ;;
--skip-syslog) want_syslog=0 ;;
@@ -545,10 +546,14 @@ then
if test -n "$open_files"
then
ulimit -n $open_files
- append_arg_to_args "--open-files-limit=$open_files"
fi
fi
+if test -n "$open_files"
+then
+ append_arg_to_args "--open-files-limit=$open_files"
+fi
+
safe_mysql_unix_port=${mysql_unix_port:-${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@}}
# Make sure that directory for $safe_mysql_unix_port exists
mysql_unix_port_dir=`dirname $safe_mysql_unix_port`
diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh
index 90f759739d0..aea7a657c9e 100644
--- a/scripts/mysqlhotcopy.sh
+++ b/scripts/mysqlhotcopy.sh
@@ -270,6 +270,14 @@ foreach my $rdb ( @db_desc ) {
my $db = $rdb->{src};
my @dbh_tables = get_list_of_tables( $db );
+ ## filter out certain system non-lockable tables.
+ ## keep in sync with mysqldump.
+ if ($db =~ m/^mysql$/i)
+ {
+ @dbh_tables = grep
+ { !/^(apply_status|schema|general_log|slow_log)$/ } @dbh_tables
+ }
+
## generate regex for tables/files
my $t_regex;
my $negated;
diff --git a/sql-common/client.c b/sql-common/client.c
index 173d8397bd9..bb7bd4d2633 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -2884,6 +2884,11 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
goto error;
}
+ /*
+ Using init_commands is not supported when connecting from within the
+ server.
+ */
+#ifndef MYSQL_SERVER
if (mysql->options.init_commands)
{
DYNAMIC_ARRAY *init_commands= mysql->options.init_commands;
@@ -2895,18 +2900,26 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
for (; ptr < end_command; ptr++)
{
- MYSQL_RES *res;
+ int status;
+
if (mysql_real_query(mysql,*ptr, (ulong) strlen(*ptr)))
goto error;
- if (mysql->fields)
- {
- if (!(res= cli_use_result(mysql)))
- goto error;
- mysql_free_result(res);
- }
+
+ do {
+ if (mysql->fields)
+ {
+ MYSQL_RES *res;
+ if (!(res= cli_use_result(mysql)))
+ goto error;
+ mysql_free_result(res);
+ }
+ if ((status= mysql_next_result(mysql)) > 0)
+ goto error;
+ } while (status == 0);
}
mysql->reconnect=reconnect;
}
+#endif
DBUG_PRINT("exit", ("Mysql handler: 0x%lx", (long) mysql));
reset_sigpipe(mysql);
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 357575c5b47..a0e157b7806 100755
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -92,7 +92,7 @@ TARGET_LINK_LIBRARIES(sql ${MYSQLD_STATIC_PLUGIN_LIBS}
IF(WIN32)
- SET(MYSQLD_SOURCE main.cc nt_servc.cc nt_servc.h message.rc)
+ SET(MYSQLD_SOURCE main.cc nt_servc.cc nt_servc.h message.rc)
ELSE()
SET(MYSQLD_SOURCE main.cc ${DTRACE_PROBES_ALL})
ENDIF()
diff --git a/sql/authors.h b/sql/authors.h
index 555fe2ae43a..5de2659f098 100644
--- a/sql/authors.h
+++ b/sql/authors.h
@@ -80,6 +80,7 @@ struct show_table_authors_st show_table_authors[]= {
{ "Eric Herman", "Amsterdam, Netherlands", "Bug fixing - federated" },
{ "Andrey Hristov", "Walldorf, Germany", "Event scheduler (5.1)" },
{ "Alexander (Alexi) Ivanov", "St. Petersburg, Russia", "Replication" },
+ { "Mattias Jonsson", "Uppsala, Sweden", "Partitioning" },
{ "Alexander (Salle) Keremidarski", "Sofia, Bulgaria",
"Bug fixing" },
{ "Mats Kindahl", "Storvreta, Sweden", "Replication" },
diff --git a/sql/events.cc b/sql/events.cc
index 96b86e6798f..a548bda53e2 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -276,7 +276,9 @@ create_query_string(THD *thd, String *buf)
/* Append definer */
append_definer(thd, buf, &(thd->lex->definer->user), &(thd->lex->definer->host));
/* Append the left part of thd->query after "DEFINER" part */
- if (buf->append(thd->lex->stmt_definition_begin))
+ if (buf->append(thd->lex->stmt_definition_begin,
+ thd->lex->stmt_definition_end -
+ thd->lex->stmt_definition_begin))
return 1;
return 0;
diff --git a/sql/field.cc b/sql/field.cc
index bd091f7eb57..ee7d91c1fb6 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -8464,14 +8464,20 @@ bool Field_num::eq_def(Field *field)
}
+/**
+ Check whether two numeric fields can be considered 'equal' for table
+ alteration purposes. Fields are equal if they are of the same type
+ and retain the same pack length.
+*/
+
uint Field_num::is_equal(Create_field *new_field)
{
return ((new_field->sql_type == real_type()) &&
- ((new_field->flags & UNSIGNED_FLAG) == (uint) (flags &
- UNSIGNED_FLAG)) &&
+ ((new_field->flags & UNSIGNED_FLAG) ==
+ (uint) (flags & UNSIGNED_FLAG)) &&
((new_field->flags & AUTO_INCREMENT_FLAG) ==
(uint) (flags & AUTO_INCREMENT_FLAG)) &&
- (new_field->length <= max_display_length()));
+ (new_field->pack_length == pack_length()));
}
@@ -9119,7 +9125,7 @@ void Create_field::create_length_to_internal_length(void)
void Create_field::init_for_tmp_table(enum_field_types sql_type_arg,
uint32 length_arg, uint32 decimals_arg,
bool maybe_null, bool is_unsigned,
- uint pack_length)
+ uint pack_length_arg)
{
DBUG_ENTER("Create_field::init_for_tmp_table");
@@ -9132,7 +9138,7 @@ void Create_field::init_for_tmp_table(enum_field_types sql_type_arg,
geom_type= Field::GEOM_GEOMETRY;
DBUG_PRINT("enter", ("sql_type: %d, length: %u, pack_length: %u",
- sql_type_arg, length_arg, pack_length));
+ sql_type_arg, length_arg, pack_length_arg));
/*
These pack flags are crafted to get it correctly through the
@@ -9196,8 +9202,8 @@ void Create_field::init_for_tmp_table(enum_field_types sql_type_arg,
case MYSQL_TYPE_GEOMETRY:
// If you are going to use the above types, you have to pass a
// pack_length as parameter. Assert that is really done.
- DBUG_ASSERT(pack_length != ~0U);
- pack_flag|= pack_length_to_packflag(pack_length);
+ DBUG_ASSERT(pack_length_arg != ~0U);
+ pack_flag|= pack_length_to_packflag(pack_length_arg);
break;
default:
/* Nothing */
diff --git a/sql/field.h b/sql/field.h
index d1fcc40ff5d..66b13d02b89 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -685,6 +685,10 @@ public:
int store_decimal(const my_decimal *);
int store(const char *to,uint length,CHARSET_INFO *cs)=0;
uint size_of() const { return sizeof(*this); }
+ uint repertoire(void) const
+ {
+ return my_charset_repertoire(field_charset);
+ }
CHARSET_INFO *charset(void) const { return field_charset; }
void set_charset(CHARSET_INFO *charset_arg) { field_charset= charset_arg; }
enum Derivation derivation(void) const { return field_derivation; }
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index e3be33c0f3c..299865e6114 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -123,13 +123,18 @@ set_field_to_null(Field *field)
return 0;
}
field->reset();
- if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN)
- {
+ switch (field->table->in_use->count_cuted_fields) {
+ case CHECK_FIELD_WARN:
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
+ /* fall through */
+ case CHECK_FIELD_IGNORE:
return 0;
+ case CHECK_FIELD_ERROR_FOR_NULL:
+ if (!field->table->in_use->no_errors)
+ my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
+ return -1;
}
- if (!field->table->in_use->no_errors)
- my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
+ DBUG_ASSERT(0); // impossible
return -1;
}
@@ -179,13 +184,18 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions)
field->table->auto_increment_field_not_null= FALSE;
return 0; // field is set in fill_record()
}
- if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN)
- {
+ switch (field->table->in_use->count_cuted_fields) {
+ case CHECK_FIELD_WARN:
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_BAD_NULL_ERROR, 1);
+ /* fall through */
+ case CHECK_FIELD_IGNORE:
return 0;
+ case CHECK_FIELD_ERROR_FOR_NULL:
+ if (!field->table->in_use->no_errors)
+ my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
+ return -1;
}
- if (!field->table->in_use->no_errors)
- my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
+ DBUG_ASSERT(0); // impossible
return -1;
}
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 86332f8c79c..2506e2fc8b3 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -61,6 +61,8 @@
#include "sql_plugin.h"
#include "table.h" /* HA_DATA_PARTITION */
+#include "debug_sync.h"
+
static const char *ha_par_ext= ".par";
#ifdef NOT_USED
static int free_share(PARTITION_SHARE * share);
@@ -693,6 +695,7 @@ int ha_partition::rename_partitions(const char *path)
DBUG_ASSERT(!strcmp(path, get_canonical_filename(m_file[0], path,
norm_name_buff)));
+ DEBUG_SYNC(ha_thd(), "before_rename_partitions");
if (temp_partitions)
{
/*
@@ -2686,6 +2689,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
DBUG_RETURN(0);
err_handler:
+ DEBUG_SYNC(ha_thd(), "partition_open_error");
while (file-- != m_file)
(*file)->close();
bitmap_free(&m_bulk_insert_started);
diff --git a/sql/handler.cc b/sql/handler.cc
index 8b56921a3a1..844c7305825 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -174,7 +174,7 @@ redo:
}
-plugin_ref ha_lock_engine(THD *thd, handlerton *hton)
+plugin_ref ha_lock_engine(THD *thd, const handlerton *hton)
{
if (hton)
{
@@ -642,9 +642,13 @@ static my_bool closecon_handlerton(THD *thd, plugin_ref plugin,
there's no need to rollback here as all transactions must
be rolled back already
*/
- if (hton->state == SHOW_OPTION_YES && hton->close_connection &&
- thd_get_ha_data(thd, hton))
- hton->close_connection(hton, thd);
+ if (hton->state == SHOW_OPTION_YES && thd_get_ha_data(thd, hton))
+ {
+ if (hton->close_connection)
+ hton->close_connection(hton, thd);
+ /* make sure ha_data is reset and ha_data_lock is released */
+ thd_set_ha_data(thd, hton, NULL);
+ }
return FALSE;
}
diff --git a/sql/handler.h b/sql/handler.h
index 1b5d5f8cb1f..ad26534d91d 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -2066,7 +2066,7 @@ extern ulong total_ha, total_ha_2pc;
/* lookups */
handlerton *ha_default_handlerton(THD *thd);
plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name);
-plugin_ref ha_lock_engine(THD *thd, handlerton *hton);
+plugin_ref ha_lock_engine(THD *thd, const handlerton *hton);
handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
handlerton *db_type);
diff --git a/sql/init.cc b/sql/init.cc
index c72787300b7..e43b12787ab 100644
--- a/sql/init.cc
+++ b/sql/init.cc
@@ -33,7 +33,7 @@ void unireg_init(ulong options)
{
DBUG_ENTER("unireg_init");
- MYSYS_PROGRAM_DONT_USE_CURSES();
+ error_handler_hook = my_message_stderr;
abort_loop=0;
my_disable_async_io=1; /* aioread is only in shared library */
diff --git a/sql/item.cc b/sql/item.cc
index 5fea7b9c075..c59a17a0ea3 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1,4 +1,4 @@
-/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2010 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
@@ -1816,7 +1816,16 @@ bool agg_item_set_converter(DTCollation &coll, const char *fname,
if (!(conv= (*arg)->safe_charset_converter(coll.collation)) &&
((*arg)->collation.repertoire == MY_REPERTOIRE_ASCII))
- conv= new Item_func_conv_charset(*arg, coll.collation, 1);
+ {
+ /*
+ We should disable const subselect item evaluation because
+ subselect transformation does not happen in view_prepare_mode
+ and thus val_...() methods can not be called for const items.
+ */
+ bool resolve_const= ((*arg)->type() == Item::SUBSELECT_ITEM &&
+ thd->lex->view_prepare_mode) ? FALSE : TRUE;
+ conv= new Item_func_conv_charset(*arg, coll.collation, resolve_const);
+ }
if (!conv)
{
@@ -3425,9 +3434,9 @@ Item_param::set_param_type_and_swap_value(Item_param *src)
bool
Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it)
{
- Item *value= *it;
+ Item *arg= *it;
- if (value->is_null())
+ if (arg->is_null())
{
set_null();
return FALSE;
@@ -3435,12 +3444,12 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it)
null_value= FALSE;
- switch (value->result_type()) {
+ switch (arg->result_type()) {
case STRING_RESULT:
{
char str_buffer[STRING_BUFFER_USUAL_SIZE];
String sv_buffer(str_buffer, sizeof(str_buffer), &my_charset_bin);
- String *sv= value->val_str(&sv_buffer);
+ String *sv= arg->val_str(&sv_buffer);
if (!sv)
return TRUE;
@@ -3457,19 +3466,19 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it)
}
case REAL_RESULT:
- set_double(value->val_real());
+ set_double(arg->val_real());
param_type= MYSQL_TYPE_DOUBLE;
break;
case INT_RESULT:
- set_int(value->val_int(), value->max_length);
+ set_int(arg->val_int(), arg->max_length);
param_type= MYSQL_TYPE_LONG;
break;
case DECIMAL_RESULT:
{
my_decimal dv_buf;
- my_decimal *dv= value->val_decimal(&dv_buf);
+ my_decimal *dv= arg->val_decimal(&dv_buf);
if (!dv)
return TRUE;
@@ -3489,8 +3498,8 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it)
return FALSE;
}
- item_result_type= value->result_type();
- item_type= value->type();
+ item_result_type= arg->result_type();
+ item_type= arg->type();
return FALSE;
}
@@ -3785,7 +3794,7 @@ void Item_copy_decimal::copy()
{
my_decimal *nr= item->val_decimal(&cached_value);
if (nr && nr != &cached_value)
- memcpy (&cached_value, nr, sizeof (my_decimal));
+ my_decimal2decimal (nr, &cached_value);
null_value= item->null_value;
}
@@ -5330,14 +5339,22 @@ int Item_field::save_in_field(Field *to, bool no_conversions)
if (result_field->is_null())
{
null_value=1;
- res= set_field_to_null_with_conversions(to, no_conversions);
+ return set_field_to_null_with_conversions(to, no_conversions);
}
- else
+ to->set_notnull();
+
+ /*
+ If we're setting the same field as the one we're reading from there's
+ nothing to do. This can happen in 'SET x = x' type of scenarios.
+ */
+ if (to == result_field)
{
- to->set_notnull();
- res= field_conv(to,result_field);
null_value=0;
+ return 0;
}
+
+ res= field_conv(to,result_field);
+ null_value=0;
return res;
}
@@ -5623,13 +5640,25 @@ inline uint char_val(char X)
X-'a'+10);
}
+Item_hex_string::Item_hex_string()
+{
+ hex_string_init("", 0);
+}
Item_hex_string::Item_hex_string(const char *str, uint str_length)
{
+ hex_string_init(str, str_length);
+}
+
+void Item_hex_string::hex_string_init(const char *str, uint str_length)
+{
max_length=(str_length+1)/2;
char *ptr=(char*) sql_alloc(max_length+1);
if (!ptr)
+ {
+ str_value.set("", 0, &my_charset_bin);
return;
+ }
str_value.set(ptr,max_length,&my_charset_bin);
char *end=ptr+max_length;
if (max_length*2 != str_length)
@@ -7402,7 +7431,7 @@ void Item_cache_int::store(Item *item, longlong val_arg)
String *Item_cache_int::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if (!has_value())
return NULL;
str->set(value, default_charset());
return str;
@@ -7412,7 +7441,7 @@ String *Item_cache_int::val_str(String *str)
my_decimal *Item_cache_int::val_decimal(my_decimal *decimal_val)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if (!has_value())
return NULL;
int2my_decimal(E_DEC_FATAL_ERROR, value, unsigned_flag, decimal_val);
return decimal_val;
@@ -7421,7 +7450,7 @@ my_decimal *Item_cache_int::val_decimal(my_decimal *decimal_val)
double Item_cache_int::val_real()
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if (!has_value())
return 0.0;
return (double) value;
}
@@ -7429,7 +7458,7 @@ double Item_cache_int::val_real()
longlong Item_cache_int::val_int()
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if (!has_value())
return 0;
return value;
}
@@ -7485,7 +7514,7 @@ String *Item_cache_datetime::val_str(String *str)
my_decimal *Item_cache_datetime::val_decimal(my_decimal *decimal_val)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value_int())
+ if (!has_value())
return NULL;
int2my_decimal(E_DEC_FATAL_ERROR, int_value, unsigned_flag, decimal_val);
return decimal_val;
@@ -7521,7 +7550,7 @@ bool Item_cache_real::cache_value()
double Item_cache_real::val_real()
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if (!has_value())
return 0.0;
return value;
}
@@ -7529,7 +7558,7 @@ double Item_cache_real::val_real()
longlong Item_cache_real::val_int()
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if (!has_value())
return 0;
return (longlong) rint(value);
}
@@ -7538,7 +7567,7 @@ longlong Item_cache_real::val_int()
String* Item_cache_real::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if (!has_value())
return NULL;
str->set_real(value, decimals, default_charset());
return str;
@@ -7548,7 +7577,7 @@ String* Item_cache_real::val_str(String *str)
my_decimal *Item_cache_real::val_decimal(my_decimal *decimal_val)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if (!has_value())
return NULL;
double2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val);
return decimal_val;
@@ -7570,7 +7599,7 @@ double Item_cache_decimal::val_real()
{
DBUG_ASSERT(fixed);
double res;
- if (!value_cached && !cache_value())
+ if (!has_value())
return 0.0;
my_decimal2double(E_DEC_FATAL_ERROR, &decimal_value, &res);
return res;
@@ -7580,7 +7609,7 @@ longlong Item_cache_decimal::val_int()
{
DBUG_ASSERT(fixed);
longlong res;
- if (!value_cached && !cache_value())
+ if (!has_value())
return 0;
my_decimal2int(E_DEC_FATAL_ERROR, &decimal_value, unsigned_flag, &res);
return res;
@@ -7589,7 +7618,7 @@ longlong Item_cache_decimal::val_int()
String* Item_cache_decimal::val_str(String *str)
{
DBUG_ASSERT(fixed);
- if (!value_cached && !cache_value())
+ if (!has_value())
return NULL;
my_decimal_round(E_DEC_FATAL_ERROR, &decimal_value, decimals, FALSE,
&decimal_value);
@@ -7600,7 +7629,7 @@ String* Item_cache_decimal::val_str(String *str)
my_decimal *Item_cache_decimal::val_decimal(my_decimal *val)
{
DBUG_ASSERT(fixed);
- if (!value_cached && !cache_value())
+ if (!has_value())
return NULL;
return &decimal_value;
}
@@ -7636,7 +7665,7 @@ double Item_cache_str::val_real()
DBUG_ASSERT(fixed == 1);
int err_not_used;
char *end_not_used;
- if (!value_cached && !cache_value())
+ if (!has_value())
return 0.0;
if (value)
return my_strntod(value->charset(), (char*) value->ptr(),
@@ -7649,7 +7678,7 @@ longlong Item_cache_str::val_int()
{
DBUG_ASSERT(fixed == 1);
int err;
- if (!value_cached && !cache_value())
+ if (!has_value())
return 0;
if (value)
return my_strntoll(value->charset(), value->ptr(),
@@ -7662,7 +7691,7 @@ longlong Item_cache_str::val_int()
String* Item_cache_str::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if (!has_value())
return 0;
return value;
}
@@ -7671,7 +7700,7 @@ String* Item_cache_str::val_str(String *str)
my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached && !cache_value())
+ if (!has_value())
return NULL;
if (value)
string2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val);
@@ -7683,7 +7712,7 @@ my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val)
int Item_cache_str::save_in_field(Field *field, bool no_conversions)
{
- if (!value_cached && !cache_value())
+ if (!has_value())
return 0;
int res= Item_cache::save_in_field(field, no_conversions);
return (is_varbinary && field->type() == MYSQL_TYPE_STRING &&
diff --git a/sql/item.h b/sql/item.h
index 11b4199da2c..e441a6ff261 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1181,6 +1181,10 @@ public:
collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII);
fix_char_length(max_char_length_arg);
}
+ /*
+ Return TRUE if the item points to a column of an outer-joined table.
+ */
+ virtual bool is_outer_field() const { DBUG_ASSERT(fixed); return FALSE; }
};
@@ -1694,6 +1698,11 @@ public:
int fix_outer_field(THD *thd, Field **field, Item **reference);
virtual Item *update_value_transformer(uchar *select_arg);
virtual void print(String *str, enum_query_type query_type);
+ bool is_outer_field() const
+ {
+ DBUG_ASSERT(fixed);
+ return field->table->pos_in_table_list->outer_join;
+ }
Field::geometry_type get_geometry_type() const
{
DBUG_ASSERT(field_type() == MYSQL_TYPE_GEOMETRY);
@@ -2302,7 +2311,7 @@ public:
class Item_hex_string: public Item_basic_constant
{
public:
- Item_hex_string() {}
+ Item_hex_string();
Item_hex_string(const char *str,uint str_length);
enum Type type() const { return VARBIN_ITEM; }
double val_real()
@@ -2322,6 +2331,8 @@ public:
bool eq(const Item *item, bool binary_cmp) const;
virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+private:
+ void hex_string_init(const char *str, uint str_length);
};
@@ -2504,7 +2515,13 @@ public:
DBUG_ASSERT(fixed);
return (*ref)->get_time(ltime);
}
- bool basic_const_item() { return (*ref)->basic_const_item(); }
+ virtual bool basic_const_item() const { return (*ref)->basic_const_item(); }
+ bool is_outer_field() const
+ {
+ DBUG_ASSERT(fixed);
+ DBUG_ASSERT(ref);
+ return (*ref)->is_outer_field();
+ }
};
@@ -3189,6 +3206,15 @@ public:
{
return this == item;
}
+ /**
+ Check if saved item has a non-NULL value.
+ Will cache value of saved item if not already done.
+ @return TRUE if cached value is non-NULL.
+ */
+ bool has_value()
+ {
+ return (value_cached || cache_value()) && !null_value;
+ }
virtual void store(Item *item);
virtual bool cache_value()= 0;
bool basic_const_item() const
@@ -3356,6 +3382,7 @@ public:
cmp_context= STRING_RESULT;
}
+ virtual void store(Item *item) { Item_cache::store(item); }
void store(Item *item, longlong val_arg);
double val_real();
longlong val_int();
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 19e8385539f..3c871bc0663 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -5466,7 +5466,21 @@ void Item_equal::update_const()
Item *item;
while ((item= it++))
{
- if (item->const_item())
+ if (item->const_item() &&
+ /*
+ Don't propagate constant status of outer-joined column.
+ Such a constant status here is a result of:
+ a) empty outer-joined table: in this case such a column has a
+ value of NULL; but at the same time other arguments of
+ Item_equal don't have to be NULLs and the value of the whole
+ multiple equivalence expression doesn't have to be NULL or FALSE
+ because of the outer join nature;
+ or
+ b) outer-joined table contains only 1 row: the result of
+ this column is equal to a row field value *or* NULL.
+ Both values are inacceptable as Item_equal constants.
+ */
+ !item->is_outer_field())
{
it.remove();
add(item);
@@ -5505,7 +5519,8 @@ void Item_equal::update_used_tables()
{
item->update_used_tables();
used_tables_cache|= item->used_tables();
- const_item_cache&= item->const_item();
+ /* see commentary at Item_equal::update_const() */
+ const_item_cache&= item->const_item() && !item->is_outer_field();
}
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index afd25688e79..a0b3f2c29a1 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -60,9 +60,9 @@ public:
/* Allow owner function to use string buffers. */
String value1, value2;
- Arg_comparator(): thd(0), a_cache(0), b_cache(0), set_null(TRUE),
+ Arg_comparator(): comparators(0), thd(0), a_cache(0), b_cache(0), set_null(TRUE),
get_value_a_func(0), get_value_b_func(0) {};
- Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), thd(0),
+ Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), comparators(0), thd(0),
a_cache(0), b_cache(0), set_null(TRUE),
get_value_a_func(0), get_value_b_func(0) {};
@@ -118,6 +118,11 @@ public:
return (owner->type() == Item::FUNC_ITEM &&
((Item_func*)owner)->functype() == Item_func::EQUAL_FUNC);
}
+ void cleanup()
+ {
+ delete [] comparators;
+ comparators= 0;
+ }
friend class Item_func;
};
@@ -371,6 +376,11 @@ public:
CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
uint decimal_precision() const { return 1; }
void top_level_item() { abort_on_null= TRUE; }
+ void cleanup()
+ {
+ Item_int_func::cleanup();
+ cmp.cleanup();
+ }
friend class Arg_comparator;
};
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index f2b34fe59ed..61febb01e93 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -512,7 +512,7 @@ String *Item_func_concat::val_str(String *str)
}
else if (str->alloced_length() >= res->length()+res2->length())
{
- if (str == res2)
+ if (str->ptr() == res2->ptr())
str->replace(0,0,*res);
else
{
@@ -3192,8 +3192,7 @@ String *Item_load_file::val_str(String *str)
MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
/* Read only allowed from within dir specified by secure_file_priv */
- if (opt_secure_file_priv &&
- strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
+ if (!is_secure_file_path(path))
goto err;
if (!mysql_file_stat(key_file_loadfile, path, &stat_info, MYF(0)))
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 7b7f8d3308a..2a34babae87 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -735,8 +735,9 @@ public:
String *val_str(String *);
void fix_length_and_dec()
{
+ ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 + 2;
+ max_length= (uint32) min(max_result_length, MAX_BLOB_WIDTH);
collation.set(args[0]->collation);
- max_length= args[0]->max_length * 2 + 2;
}
};
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index c341dd97460..10ef992594e 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -130,6 +130,21 @@ void Item_subselect::cleanup()
DBUG_VOID_RETURN;
}
+
+/*
+ We cannot use generic Item::safe_charset_converter() because
+ Subselect transformation does not happen in view_prepare_mode
+ and thus we can not evaluate val_...() for const items.
+*/
+
+Item *Item_subselect::safe_charset_converter(CHARSET_INFO *tocs)
+{
+ Item_func_conv_charset *conv=
+ new Item_func_conv_charset(this, tocs, thd->lex->view_prepare_mode ? 0 : 1);
+ return conv->safe ? conv : NULL;
+}
+
+
void Item_singlerow_subselect::cleanup()
{
DBUG_ENTER("Item_singlerow_subselect::cleanup");
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 04daab19adc..34b09ca6fdc 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -138,6 +138,7 @@ public:
virtual void reset_value_registration() {}
enum_parsing_place place() { return parsing_place; }
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
+ Item *safe_charset_converter(CHARSET_INFO *tocs);
/**
Get the SELECT_LEX structure associated with this Item.
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 4746a6057c6..917acb0e908 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -3411,7 +3411,7 @@ void Item_func_group_concat::print(String *str, enum_query_type query_type)
{
if (i)
str->append(',');
- (*order[i]->item)->print(str, query_type);
+ pargs[i + arg_count_field]->print(str, query_type);
if (order[i]->asc)
str->append(STRING_WITH_LEN(" ASC"));
else
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 5f2c4f166e6..c76f3102003 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -303,6 +303,8 @@ class st_select_lex;
class Item_sum :public Item_result_field
{
+ friend class Aggregator_distinct;
+
protected:
/**
Aggregator class instance. Not set initially. Allocated only after
diff --git a/sql/key.cc b/sql/key.cc
index d593850ca10..582334620ad 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -354,6 +354,16 @@ void key_unpack(String *to,TABLE *table,uint idx)
{
CHARSET_INFO *cs= field->charset();
field->val_str(&tmp);
+ /*
+ For BINARY(N) strip trailing zeroes to make
+ the error message nice-looking
+ */
+ if (field->binary() && field->type() == MYSQL_TYPE_STRING && tmp.length())
+ {
+ const char *tmp_end= tmp.ptr() + tmp.length();
+ while (tmp_end > tmp.ptr() && !*--tmp_end);
+ tmp.length(tmp_end - tmp.ptr() + 1);
+ }
if (cs->mbmaxlen > 1 &&
table->field[key_part->fieldnr - 1]->field_length !=
key_part->length)
diff --git a/sql/lock.cc b/sql/lock.cc
index 758ea6cf914..3f13f15454a 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -533,20 +533,6 @@ void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table)
}
}
-/* Downgrade all locks on a table to new WRITE level from WRITE_ONLY */
-
-void mysql_lock_downgrade_write(THD *thd, TABLE *table,
- thr_lock_type new_lock_type)
-{
- MYSQL_LOCK *locked;
- if ((locked = get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK)))
- {
- for (uint i=0; i < locked->lock_count; i++)
- thr_downgrade_write_lock(locked->locks[i], new_lock_type);
- my_free((uchar*) locked,MYF(0));
- }
-}
-
/** Abort all other threads waiting to get lock in table. */
diff --git a/sql/lock.h b/sql/lock.h
index 19b23f1f42b..f7c19913675 100644
--- a/sql/lock.h
+++ b/sql/lock.h
@@ -53,52 +53,22 @@ typedef struct st_mysql_lock MYSQL_LOCK;
MYSQL_OPEN_HAS_MDL_LOCK)
-#include "thr_lock.h" /* thr_lock_type */
-
-struct TABLE_LIST;
-class THD;
-struct TABLE;
-typedef struct st_mysql_lock MYSQL_LOCK;
-
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count, uint flags);
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count);
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table);
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock);
-void mysql_lock_downgrade_write(THD *thd, TABLE *table,
- thr_lock_type new_lock_type);
bool mysql_lock_abort_for_thread(THD *thd, TABLE *table);
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b);
TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
TABLE_LIST *haystack);
-bool lock_global_read_lock(THD *thd);
-void unlock_global_read_lock(THD *thd);
-bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
- bool is_not_commit);
-void start_waiting_global_read_lock(THD *thd);
-bool make_global_read_lock_block_commit(THD *thd);
-bool set_protect_against_global_read_lock(void);
-void unset_protect_against_global_read_lock(void);
-/* Lock based on stored routine name */
-bool lock_routine_name(THD *thd, bool is_function, const char *db,
- const char *name);
void broadcast_refresh(void);
-
/* Lock based on name */
-int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list);
-int lock_table_name(THD *thd, TABLE_LIST *table_list, bool check_in_use);
-void unlock_table_name(THD *thd, TABLE_LIST *table_list);
-bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list);
bool lock_table_names(THD *thd, TABLE_LIST *table_list);
void unlock_table_names(THD *thd);
-bool lock_table_names_exclusively(THD *thd, TABLE_LIST *table_list);
-bool is_table_name_exclusively_locked_by_this_thread(THD *thd,
- TABLE_LIST *table_list);
-bool is_table_name_exclusively_locked_by_this_thread(THD *thd, uchar *key,
- int key_length);
-void broadcast_refresh(void);
-
-
+/* Lock based on stored routine name */
+bool lock_routine_name(THD *thd, bool is_function, const char *db,
+ const char *name);
#endif /* LOCK_INCLUDED */
diff --git a/sql/log.cc b/sql/log.cc
index 6c0ab33e87a..fd17e04b212 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1528,11 +1528,6 @@ binlog_flush_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr,
cache_mngr->trx_cache.has_incident());
cache_mngr->reset_cache(&cache_mngr->trx_cache);
- /*
- We need to step the table map version after writing the
- transaction cache to disk.
- */
- mysql_bin_log.update_table_map_version();
statistic_increment(binlog_cache_use, &LOCK_status);
if (cache_log->disk_writes != 0)
{
@@ -1592,13 +1587,6 @@ binlog_truncate_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr, bool all)
else
cache_mngr->trx_cache.restore_prev_position();
- /*
- We need to step the table map version on a rollback to ensure that a new
- table map event is generated instead of the one that was written to the
- thrown-away transaction cache.
- */
- mysql_bin_log.update_table_map_version();
-
DBUG_ASSERT(thd->binlog_get_pending_rows_event(is_transactional) == NULL);
DBUG_RETURN(error);
}
@@ -1650,11 +1638,6 @@ binlog_flush_stmt_cache(THD *thd, binlog_cache_mngr *cache_mngr)
DBUG_RETURN(error);
cache_mngr->reset_cache(&cache_mngr->stmt_cache);
- /*
- We need to step the table map version after writing the
- transaction cache to disk.
- */
- mysql_bin_log.update_table_map_version();
statistic_increment(binlog_cache_use, &LOCK_status);
if (cache_log->disk_writes != 0)
{
@@ -1890,12 +1873,14 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv)
binlog_trans_log_savepos(thd, (my_off_t*) sv);
/* Write it to the binary log */
+ String log_query;
+ if (log_query.append(STRING_WITH_LEN("SAVEPOINT ")) ||
+ log_query.append(thd->lex->ident.str, thd->lex->ident.length))
+ DBUG_RETURN(1);
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
- int const error=
- thd->binlog_query(THD::STMT_QUERY_TYPE,
- thd->query(), thd->query_length(), TRUE, FALSE, FALSE,
- errcode);
- DBUG_RETURN(error);
+ Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(),
+ TRUE, FALSE, TRUE, errcode);
+ DBUG_RETURN(mysql_bin_log.write(&qinfo));
}
static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
@@ -1910,12 +1895,14 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
if (unlikely(trans_has_updated_non_trans_table(thd) ||
(thd->variables.option_bits & OPTION_KEEP_LOG)))
{
+ String log_query;
+ if (log_query.append(STRING_WITH_LEN("ROLLBACK TO ")) ||
+ log_query.append(thd->lex->ident.str, thd->lex->ident.length))
+ DBUG_RETURN(1);
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
- int error=
- thd->binlog_query(THD::STMT_QUERY_TYPE,
- thd->query(), thd->query_length(), TRUE, FALSE, FALSE,
- errcode);
- DBUG_RETURN(error);
+ Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(),
+ TRUE, FALSE, TRUE, errcode);
+ DBUG_RETURN(mysql_bin_log.write(&qinfo));
}
binlog_trans_log_truncate(thd, *(my_off_t*)sv);
DBUG_RETURN(0);
@@ -2658,7 +2645,7 @@ const char *MYSQL_LOG::generate_name(const char *log_name,
MYSQL_BIN_LOG::MYSQL_BIN_LOG(uint *sync_period)
:bytes_written(0), prepared_xids(0), file_id(1), open_count(1),
- need_start_event(TRUE), m_table_map_version(0),
+ need_start_event(TRUE),
sync_period_ptr(sync_period),
is_relay_log(0), signal_cnt(0),
description_event_for_exec(0), description_event_for_queue(0)
@@ -4443,7 +4430,6 @@ int THD::binlog_write_table_map(TABLE *table, bool is_transactional)
DBUG_RETURN(error);
binlog_table_maps++;
- table->s->table_map_version= mysql_bin_log.table_map_version();
DBUG_RETURN(0);
}
@@ -4585,21 +4571,6 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
DBUG_RETURN(1);
}
- /*
- We step the table map version if we are writing an event
- representing the end of a statement.
-
- In an ideal world, we could avoid stepping the table map version,
- since we could then reuse the table map that was written earlier
- in the cache. This does not work since STMT_END_F implies closing
- all table mappings on the slave side.
-
- TODO: Find a solution so that table maps does not have to be
- written several times within a transaction.
- */
- if (pending->get_flags(Rows_log_event::STMT_END_F))
- ++m_table_map_version;
-
delete pending;
}
@@ -4657,7 +4628,9 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
*/
const char *local_db= event_info->get_db();
if ((thd && !(thd->variables.option_bits & OPTION_BIN_LOG)) ||
- !binlog_filter->db_ok(local_db))
+ (thd->lex->sql_command != SQLCOM_ROLLBACK_TO_SAVEPOINT &&
+ thd->lex->sql_command != SQLCOM_SAVEPOINT &&
+ !binlog_filter->db_ok(local_db)))
DBUG_RETURN(0);
#endif /* HAVE_REPLICATION */
@@ -4786,9 +4759,6 @@ unlock:
}
}
- if (event_info->flags & LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F)
- ++m_table_map_version;
-
DBUG_RETURN(error);
}
diff --git a/sql/log.h b/sql/log.h
index 12e02969485..cd3faace598 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -299,8 +299,6 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
*/
bool no_auto_events;
- ulonglong m_table_map_version;
-
/* pointer to the sync period variable, for binlog this will be
sync_binlog_period, for relay log this will be
sync_relay_log_period
@@ -353,13 +351,6 @@ public:
void unlog(ulong cookie, my_xid xid);
int recover(IO_CACHE *log, Format_description_log_event *fdle);
#if !defined(MYSQL_CLIENT)
- bool is_table_mapped(TABLE *table) const
- {
- return table->s->table_map_version == table_map_version();
- }
-
- ulonglong table_map_version() const { return m_table_map_version; }
- void update_table_map_version() { ++m_table_map_version; }
int flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event,
bool is_transactional);
diff --git a/sql/log_event.cc b/sql/log_event.cc
index d5ae1c954ff..00015ea52fe 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -3189,10 +3189,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
::do_apply_event(), then the companion SET also have so
we don't need to reset_one_shot_variables().
*/
- if (!strncmp(query_arg, "BEGIN", q_len_arg) ||
- !strncmp(query_arg, "COMMIT", q_len_arg) ||
- !strncmp(query_arg, "ROLLBACK", q_len_arg) ||
- rpl_filter->db_ok(thd->db))
+ if (is_trans_keyword() || rpl_filter->db_ok(thd->db))
{
thd->set_time((time_t)when);
thd->set_query_and_id((char*)query_arg, q_len_arg, next_query_id());
@@ -3354,11 +3351,12 @@ compare_errors:
*/
actual_error= thd->is_error() ? thd->stmt_da->sql_errno() : 0;
DBUG_PRINT("info",("expected_error: %d sql_errno: %d",
- expected_error, actual_error));
+ expected_error, actual_error));
+
if ((expected_error && expected_error != actual_error &&
!concurrency_error_code(expected_error)) &&
- !ignored_error_code(actual_error) &&
- !ignored_error_code(expected_error))
+ !ignored_error_code(actual_error) &&
+ !ignored_error_code(expected_error))
{
rli->report(ERROR_LEVEL, 0,
"\
@@ -3376,9 +3374,9 @@ Default database: '%s'. Query: '%s'",
If we get the same error code as expected and it is not a concurrency
issue, or should be ignored.
*/
- else if ((expected_error == actual_error &&
+ else if ((expected_error == actual_error &&
!concurrency_error_code(expected_error)) ||
- ignored_error_code(actual_error))
+ ignored_error_code(actual_error))
{
DBUG_PRINT("info",("error ignored"));
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
@@ -3397,7 +3395,7 @@ Default database: '%s'. Query: '%s'",
If we expected a non-zero error code and get nothing and, it is a concurrency
issue or should be ignored.
*/
- else if (expected_error && !actual_error &&
+ else if (expected_error && !actual_error &&
(concurrency_error_code(expected_error) ||
ignored_error_code(expected_error)))
trans_rollback_stmt(thd);
@@ -3438,12 +3436,13 @@ Default database: '%s'. Query: '%s'",
*/
} /* End of if (db_ok(... */
- {/**
- The following failure injecion works in cooperation with tests
+ {
+ /**
+ The following failure injecion works in cooperation with tests
setting @@global.debug= 'd,stop_slave_middle_group'.
- The sql thread receives the killed status and will proceed
+ The sql thread receives the killed status and will proceed
to shutdown trying to finish incomplete events group.
- */
+ */
DBUG_EXECUTE_IF("stop_slave_middle_group",
if (strcmp("COMMIT", query) != 0 &&
strcmp("BEGIN", query) != 0)
@@ -3458,7 +3457,7 @@ end:
Probably we have set thd->query, thd->db, thd->catalog to point to places
in the data_buf of this event. Now the event is going to be deleted
probably, so data_buf will be freed, so the thd->... listed above will be
- pointers to freed memory.
+ pointers to freed memory.
So we must set them to 0, so that those bad pointers values are not later
used. Note that "cleanup" queries like automatic DROP TEMPORARY TABLE
don't suffer from these assignments to 0 as DROP TEMPORARY
@@ -3468,7 +3467,7 @@ end:
thd->set_db(NULL, 0); /* will free the current database */
thd->set_query(NULL, 0);
DBUG_PRINT("info", ("end: query= 0"));
- close_thread_tables(thd);
+ close_thread_tables(thd);
/*
As a disk space optimization, future masters will not log an event for
LAST_INSERT_ID() if that function returned 0 (and thus they will be able
@@ -3770,7 +3769,7 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
*/
if (post_header_len)
{
-#ifndef DBUG_OFF
+#ifndef DBUG_OFF
// Allows us to sanity-check that all events initialized their
// events (see the end of this 'if' block).
memset(post_header_len, 255, number_of_event_types*sizeof(uint8));
@@ -4624,9 +4623,9 @@ void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
for (i = 0; i < num_fields; i++)
{
if (i)
- my_b_printf(&cache, ",");
+ my_b_printf(&cache, ",");
my_b_printf(&cache, "%s", field);
-
+
field += field_lens[i] + 1;
}
my_b_printf(&cache, ")");
@@ -4796,9 +4795,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
thd->set_query(load_data_query, (uint) (end - load_data_query));
if (sql_ex.opt_flags & REPLACE_FLAG)
- {
- handle_dup= DUP_REPLACE;
- }
+ handle_dup= DUP_REPLACE;
else if (sql_ex.opt_flags & IGNORE_FLAG)
{
ignore= 1;
@@ -4807,14 +4804,14 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
else
{
/*
- When replication is running fine, if it was DUP_ERROR on the
+ When replication is running fine, if it was DUP_ERROR on the
master then we could choose IGNORE here, because if DUP_ERROR
suceeded on master, and data is identical on the master and slave,
then there should be no uniqueness errors on slave, so IGNORE is
the same as DUP_ERROR. But in the unlikely case of uniqueness errors
(because the data on the master and slave happen to be different
- (user error or bug), we want LOAD DATA to print an error message on
- the slave to discover the problem.
+ (user error or bug), we want LOAD DATA to print an error message on
+ the slave to discover the problem.
If reading from net (a 3.23 master), mysql_load() will change this
to IGNORE.
@@ -4846,7 +4843,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
if (sql_ex.empty_flags & FIELD_TERM_EMPTY)
- ex.field_term->length(0);
+ ex.field_term->length(0);
ex.skip_lines = skip_lines;
List<Item> field_list;
@@ -4855,12 +4852,10 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
thd->variables.pseudo_thread_id= thread_id;
if (net)
{
- // mysql_load will use thd->net to read the file
- thd->net.vio = net->vio;
- /*
- Make sure the client does not get confused about the packet sequence
- */
- thd->net.pkt_nr = net->pkt_nr;
+ // mysql_load will use thd->net to read the file
+ thd->net.vio = net->vio;
+ // Make sure the client does not get confused about the packet sequence
+ thd->net.pkt_nr = net->pkt_nr;
}
/*
It is safe to use tmp_list twice because we are not going to
@@ -4872,7 +4867,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
thd->is_slave_error= 1;
if (thd->cuted_fields)
{
- /* log_pos is the position of the LOAD event in the master log */
+ /* log_pos is the position of the LOAD event in the master log */
sql_print_warning("Slave: load data infile on table '%s' at "
"log position %s in log '%s' produced %ld "
"warning(s). Default database: '%s'",
@@ -5620,10 +5615,10 @@ User_var_log_event(const char* buf,
{
type= (Item_result) buf[UV_VAL_IS_NULL];
charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE);
- val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
- UV_CHARSET_NUMBER_SIZE);
+ val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
+ UV_CHARSET_NUMBER_SIZE);
val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
- UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
+ UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
/**
We need to check if this is from an old server
@@ -5707,9 +5702,9 @@ bool User_var_log_event::write(IO_CACHE* file)
return (write_header(file, event_length) ||
my_b_safe_write(file, (uchar*) buf, sizeof(buf)) ||
- my_b_safe_write(file, (uchar*) name, name_len) ||
- my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
- my_b_safe_write(file, pos, val_len) ||
+ my_b_safe_write(file, (uchar*) name, name_len) ||
+ my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
+ my_b_safe_write(file, pos, val_len) ||
my_b_safe_write(file, &flags, unsigned_len));
}
#endif
@@ -5983,7 +5978,7 @@ Slave_log_event::Slave_log_event(THD* thd_arg,
master_log_len = strlen(rli->group_master_log_name);
// on OOM, just do not initialize the structure and print the error
if ((mem_pool = (char*)my_malloc(get_data_size() + 1,
- MYF(MY_WME))))
+ MYF(MY_WME))))
{
master_host = mem_pool + SL_MASTER_HOST_OFFSET ;
memcpy(master_host, mi->host, master_host_len + 1);
@@ -5992,7 +5987,7 @@ Slave_log_event::Slave_log_event(THD* thd_arg,
master_port = mi->port;
master_pos = rli->group_master_log_pos;
DBUG_PRINT("info", ("master_log: %s pos: %lu", master_log,
- (ulong) master_pos));
+ (ulong) master_pos));
}
else
sql_print_error("Out of memory while recording slave event");
@@ -8941,11 +8936,28 @@ static bool record_compare(TABLE *table)
{
for (int i = 0 ; i < 2 ; ++i)
{
- saved_x[i]= table->record[i][0];
- saved_filler[i]= table->record[i][table->s->null_bytes - 1];
- table->record[i][0]|= 1U;
- table->record[i][table->s->null_bytes - 1]|=
- 256U - (1U << table->s->last_null_bit_pos);
+ /*
+ If we have an X bit then we need to take care of it.
+ */
+ if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
+ {
+ saved_x[i]= table->record[i][0];
+ table->record[i][0]|= 1U;
+ }
+
+ /*
+ If (last_null_bit_pos == 0 && null_bytes > 1), then:
+
+ X bit (if any) + N nullable fields + M Field_bit fields = 8 bits
+
+ Ie, the entire byte is used.
+ */
+ if (table->s->last_null_bit_pos > 0)
+ {
+ saved_filler[i]= table->record[i][table->s->null_bytes - 1];
+ table->record[i][table->s->null_bytes - 1]|=
+ 256U - (1U << table->s->last_null_bit_pos);
+ }
}
}
@@ -8985,8 +8997,11 @@ record_compare_exit:
{
for (int i = 0 ; i < 2 ; ++i)
{
- table->record[i][0]= saved_x[i];
- table->record[i][table->s->null_bytes - 1]= saved_filler[i];
+ if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
+ table->record[i][0]= saved_x[i];
+
+ if (table->s->last_null_bit_pos)
+ table->record[i][table->s->null_bytes - 1]= saved_filler[i];
}
}
diff --git a/sql/log_event.h b/sql/log_event.h
index e281fd6e206..bd95c74b6c5 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -469,10 +469,10 @@ struct sql_ex_info
#define LOG_EVENT_SUPPRESS_USE_F 0x8
/*
- The table map version internal to the log should be increased after
- the event has been written to the binary log.
+ Note: this is a place holder for the flag
+ LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F (0x10), which is not used any
+ more, please do not reused this value for other flags.
*/
-#define LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F 0x10
/**
@def LOG_EVENT_ARTIFICIAL_F
@@ -1746,6 +1746,28 @@ public: /* !!! Public in this patch to allow old usage */
const char *query_arg,
uint32 q_len_arg);
#endif /* HAVE_REPLICATION */
+ /*
+ If true, the event always be applied by slave SQL thread or be printed by
+ mysqlbinlog
+ */
+ bool is_trans_keyword()
+ {
+ /*
+ Before the patch for bug#50407, The 'SAVEPOINT and ROLLBACK TO'
+ queries input by user was written into log events directly.
+ So the keywords can be written in both upper case and lower case
+ together, strncasecmp is used to check both cases. they also could be
+ binlogged with comments in the front of these keywords. for examples:
+ / * bla bla * / SAVEPOINT a;
+ / * bla bla * / ROLLBACK TO a;
+ but we don't handle these cases and after the patch, both quiries are
+ binlogged in upper case with no comments.
+ */
+ return !strncmp(query, "BEGIN", q_len) ||
+ !strncmp(query, "COMMIT", q_len) ||
+ !strncasecmp(query, "SAVEPOINT", 9) ||
+ !strncasecmp(query, "ROLLBACK", 8);
+ }
};
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index f6c5b5d1023..76eda43aa48 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -314,12 +314,29 @@ static bool record_compare(TABLE *table)
if (table->s->null_bytes > 0)
{
for (int i = 0 ; i < 2 ; ++i)
- {
- saved_x[i]= table->record[i][0];
- saved_filler[i]= table->record[i][table->s->null_bytes - 1];
- table->record[i][0]|= 1U;
- table->record[i][table->s->null_bytes - 1]|=
- 256U - (1U << table->s->last_null_bit_pos);
+ {
+ /*
+ If we have an X bit then we need to take care of it.
+ */
+ if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
+ {
+ saved_x[i]= table->record[i][0];
+ table->record[i][0]|= 1U;
+ }
+
+ /*
+ If (last_null_bit_pos == 0 && null_bytes > 1), then:
+
+ X bit (if any) + N nullable fields + M Field_bit fields = 8 bits
+
+ Ie, the entire byte is used.
+ */
+ if (table->s->last_null_bit_pos > 0)
+ {
+ saved_filler[i]= table->record[i][table->s->null_bytes - 1];
+ table->record[i][table->s->null_bytes - 1]|=
+ 256U - (1U << table->s->last_null_bit_pos);
+ }
}
}
@@ -359,8 +376,11 @@ record_compare_exit:
{
for (int i = 0 ; i < 2 ; ++i)
{
- table->record[i][0]= saved_x[i];
- table->record[i][table->s->null_bytes - 1]= saved_filler[i];
+ if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
+ table->record[i][0]= saved_x[i];
+
+ if (table->s->last_null_bit_pos > 0)
+ table->record[i][table->s->null_bytes - 1]= saved_filler[i];
}
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 89b601d07f9..eb76132c080 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -400,6 +400,7 @@ ulonglong log_output_options;
my_bool opt_log_queries_not_using_indexes= 0;
bool opt_error_log= IF_WIN(1,0);
bool opt_disable_networking=0, opt_skip_show_db=0;
+bool opt_skip_name_resolve=0;
my_bool opt_character_set_client_handshake= 1;
bool server_id_supplied = 0;
bool opt_endinfo, using_udf_functions;
@@ -3600,7 +3601,6 @@ static int init_common_variables()
if (item_create_init())
return 1;
item_init();
- mysys_uses_curses=0;
#ifdef USE_REGEX
my_regex_init(&my_charset_latin1);
#endif
@@ -6209,9 +6209,6 @@ Can't be set to 1 if --log-slave-updates is used.",
#endif
{"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names.", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"skip-name-resolve", OPT_SKIP_RESOLVE,
- "Don't resolve hostnames. All hostnames are IP's or 'localhost'.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"skip-new", OPT_SKIP_NEW, "Don't use new, possibly wrong routines.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"skip-slave-start", 0,
@@ -6963,6 +6960,7 @@ static int mysql_init_variables(void)
opt_log= opt_slow_log= 0;
opt_bin_log= 0;
opt_disable_networking= opt_skip_show_db=0;
+ opt_skip_name_resolve= 0;
opt_ignore_builtin_innodb= 0;
opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= 0;
opt_tc_log_file= (char *)"tc.log"; // no hostname in tc_log file name !
@@ -7332,6 +7330,7 @@ mysqld_get_one_option(int optid,
opt_specialflag|= SPECIAL_NO_HOST_CACHE;
break;
case (int) OPT_SKIP_RESOLVE:
+ opt_skip_name_resolve= 1;
opt_specialflag|=SPECIAL_NO_RESOLVE;
break;
case (int) OPT_WANT_CORE:
@@ -7709,6 +7708,48 @@ fn_format_relative_to_data_home(char * to, const char *name,
}
+/**
+ Test a file path to determine if the path is compatible with the secure file
+ path restriction.
+
+ @param path null terminated character string
+
+ @return
+ @retval TRUE The path is secure
+ @retval FALSE The path isn't secure
+*/
+
+bool is_secure_file_path(char *path)
+{
+ char buff1[FN_REFLEN], buff2[FN_REFLEN];
+ /*
+ All paths are secure if opt_secure_file_path is 0
+ */
+ if (!opt_secure_file_priv)
+ return TRUE;
+
+ if (strlen(path) >= FN_REFLEN)
+ return FALSE;
+
+ if (my_realpath(buff1, path, 0))
+ {
+ /*
+ The supplied file path might have been a file and not a directory.
+ */
+ int length= (int)dirname_length(path);
+ if (length >= FN_REFLEN)
+ return FALSE;
+ memcpy(buff2, path, length);
+ buff2[length]= '\0';
+ if (length == 0 || my_realpath(buff1, buff2, 0))
+ return FALSE;
+ }
+ convert_dirname(buff2, buff1, NullS);
+ if (strncmp(opt_secure_file_priv, buff2, strlen(opt_secure_file_priv)))
+ return FALSE;
+ return TRUE;
+}
+
static int fix_paths(void)
{
char buff[FN_REFLEN],*pos;
@@ -7769,10 +7810,26 @@ static int fix_paths(void)
*/
if (opt_secure_file_priv)
{
- convert_dirname(buff, opt_secure_file_priv, NullS);
- x_free(opt_secure_file_priv);
- opt_secure_file_priv= my_strdup(buff, MYF(MY_FAE));
+ if (*opt_secure_file_priv == 0)
+ {
+ opt_secure_file_priv= 0;
+ }
+ else
+ {
+ if (strlen(opt_secure_file_priv) >= FN_REFLEN)
+ opt_secure_file_priv[FN_REFLEN-1]= '\0';
+ if (my_realpath(buff, opt_secure_file_priv, 0))
+ {
+ sql_print_warning("Failed to normalize the argument for --secure-file-priv.");
+ return 1;
+ }
+ char *secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE));
+ convert_dirname(secure_file_real_path, buff, NullS);
+ my_free(opt_secure_file_priv, MYF(0));
+ opt_secure_file_priv= secure_file_real_path;
+ }
}
+
return 0;
}
diff --git a/sql/mysqld.h b/sql/mysqld.h
index 842d74d063a..e14cd15ceb8 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -71,6 +71,7 @@ void unlink_thd(THD *thd);
bool one_thread_per_connection_end(THD *thd, bool put_in_cache);
void flush_thread_cache();
void refresh_status(THD *thd);
+bool is_secure_file_path(char *path);
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *system_charset_info;
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *files_charset_info ;
@@ -97,6 +98,7 @@ extern ulonglong log_output_options;
extern ulong log_backup_output_options;
extern my_bool opt_log_queries_not_using_indexes;
extern bool opt_disable_networking, opt_skip_show_db;
+extern bool opt_skip_name_resolve;
extern bool opt_ignore_builtin_innodb;
extern my_bool opt_character_set_client_handshake;
extern bool volatile abort_loop;
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index fc8655ea2e7..28ed4cbdbaf 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -133,6 +133,9 @@ my_bool my_net_init(NET *net, Vio* vio)
net->where_b = net->remain_in_buf=0;
net->last_errno=0;
net->unused= 0;
+#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
+ net->skip_big_packet= FALSE;
+#endif
if (vio != 0) /* If real connection */
{
@@ -967,6 +970,7 @@ my_real_read(NET *net, size_t *complen)
{
#if defined(MYSQL_SERVER) && !defined(NO_ALARM)
if (!net->compress &&
+ net->skip_big_packet &&
!my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff))
net->error= 3; /* Successfully skiped packet */
#endif
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index a46bfcf2d0e..5e985625c78 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -8717,8 +8717,6 @@ int QUICK_RANGE_SELECT::get_next()
{
int result;
KEY_MULTI_RANGE *mrange;
- key_range *start_key;
- key_range *end_key;
DBUG_ENTER("QUICK_RANGE_SELECT::get_next");
DBUG_ASSERT(multi_range_length && multi_range &&
(cur_range >= (QUICK_RANGE**) ranges.buffer) &&
@@ -8758,26 +8756,9 @@ int QUICK_RANGE_SELECT::get_next()
mrange_slot < mrange_end;
mrange_slot++)
{
- start_key= &mrange_slot->start_key;
- end_key= &mrange_slot->end_key;
last_range= *(cur_range++);
-
- start_key->key= (const uchar*) last_range->min_key;
- start_key->length= last_range->min_length;
- start_key->flag= ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
- (last_range->flag & EQ_RANGE) ?
- HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
- start_key->keypart_map= last_range->min_keypart_map;
- end_key->key= (const uchar*) last_range->max_key;
- end_key->length= last_range->max_length;
- /*
- We use HA_READ_AFTER_KEY here because if we are reading on a key
- prefix. We want to find all keys with this prefix.
- */
- end_key->flag= (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
- HA_READ_AFTER_KEY);
- end_key->keypart_map= last_range->max_keypart_map;
-
+ last_range->make_min_endpoint(&mrange_slot->start_key);
+ last_range->make_max_endpoint(&mrange_slot->end_key);
mrange_slot->range_flag= last_range->flag;
}
@@ -8801,49 +8782,52 @@ end:
/*
Get the next record with a different prefix.
- SYNOPSIS
- QUICK_RANGE_SELECT::get_next_prefix()
- prefix_length length of cur_prefix
- cur_prefix prefix of a key to be searched for
+ @param prefix_length length of cur_prefix
+ @param group_key_parts The number of key parts in the group prefix
+ @param cur_prefix prefix of a key to be searched for
- DESCRIPTION
- Each subsequent call to the method retrieves the first record that has a
- prefix with length prefix_length different from cur_prefix, such that the
- record with the new prefix is within the ranges described by
- this->ranges. The record found is stored into the buffer pointed by
- this->record.
- The method is useful for GROUP-BY queries with range conditions to
- discover the prefix of the next group that satisfies the range conditions.
+ Each subsequent call to the method retrieves the first record that has a
+ prefix with length prefix_length and which is different from cur_prefix,
+ such that the record with the new prefix is within the ranges described by
+ this->ranges. The record found is stored into the buffer pointed by
+ this->record. The method is useful for GROUP-BY queries with range
+ conditions to discover the prefix of the next group that satisfies the range
+ conditions.
+
+ @todo
- TODO
This method is a modified copy of QUICK_RANGE_SELECT::get_next(), so both
methods should be unified into a more general one to reduce code
duplication.
- RETURN
- 0 on success
- HA_ERR_END_OF_FILE if returned all keys
- other if some error occurred
+ @retval 0 on success
+ @retval HA_ERR_END_OF_FILE if returned all keys
+ @retval other if some error occurred
*/
int QUICK_RANGE_SELECT::get_next_prefix(uint prefix_length,
- key_part_map keypart_map,
+ uint group_key_parts,
uchar *cur_prefix)
{
DBUG_ENTER("QUICK_RANGE_SELECT::get_next_prefix");
+ const key_part_map keypart_map= make_prev_keypart_map(group_key_parts);
for (;;)
{
int result;
- key_range start_key, end_key;
if (last_range)
{
/* Read the next record in the same range with prefix after cur_prefix. */
- DBUG_ASSERT(cur_prefix != 0);
+ DBUG_ASSERT(cur_prefix != NULL);
result= file->index_read_map(record, cur_prefix, keypart_map,
HA_READ_AFTER_KEY);
- if (result || (file->compare_key(file->end_range) <= 0))
+ if (result || last_range->max_keypart_map == 0)
DBUG_RETURN(result);
+
+ key_range previous_endpoint;
+ last_range->make_max_endpoint(&previous_endpoint, prefix_length, keypart_map);
+ if (file->compare_key(&previous_endpoint) <= 0)
+ DBUG_RETURN(0);
}
uint count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
@@ -8855,21 +8839,9 @@ int QUICK_RANGE_SELECT::get_next_prefix(uint prefix_length,
}
last_range= *(cur_range++);
- start_key.key= (const uchar*) last_range->min_key;
- start_key.length= min(last_range->min_length, prefix_length);
- start_key.keypart_map= last_range->min_keypart_map & keypart_map;
- start_key.flag= ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
- (last_range->flag & EQ_RANGE) ?
- HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
- end_key.key= (const uchar*) last_range->max_key;
- end_key.length= min(last_range->max_length, prefix_length);
- end_key.keypart_map= last_range->max_keypart_map & keypart_map;
- /*
- We use READ_AFTER_KEY here because if we are reading on a key
- prefix we want to find all keys with this prefix
- */
- end_key.flag= (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
- HA_READ_AFTER_KEY);
+ key_range start_key, end_key;
+ last_range->make_min_endpoint(&start_key, prefix_length, keypart_map);
+ last_range->make_max_endpoint(&end_key, prefix_length, keypart_map);
result= file->read_range_first(last_range->min_keypart_map ? &start_key : 0,
last_range->max_keypart_map ? &end_key : 0,
@@ -8964,9 +8936,9 @@ bool QUICK_RANGE_SELECT::row_in_ranges()
}
/*
- This is a hack: we inherit from QUICK_SELECT so that we can use the
+ This is a hack: we inherit from QUICK_RANGE_SELECT so that we can use the
get_next() interface, but we have to hold a pointer to the original
- QUICK_SELECT because its data are used all over the place. What
+ QUICK_RANGE_SELECT because its data are used all over the place. What
should be done is to factor out the data that is needed into a base
class (QUICK_SELECT), and then have two subclasses (_ASC and _DESC)
which handle the ranges and implement the get_next() function. But
@@ -11159,7 +11131,8 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_prefix()
{
uchar *cur_prefix= seen_first_key ? group_prefix : NULL;
if ((result= quick_prefix_select->get_next_prefix(group_prefix_len,
- make_prev_keypart_map(group_key_parts), cur_prefix)))
+ group_key_parts,
+ cur_prefix)))
DBUG_RETURN(result);
seen_first_key= TRUE;
}
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 3b3b36f7689..85d59671b42 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -79,6 +79,85 @@ class QUICK_RANGE :public Sql_alloc {
dummy=0;
#endif
}
+
+ /**
+ Initalizes a key_range object for communication with storage engine.
+
+ This function facilitates communication with the Storage Engine API by
+ translating the minimum endpoint of the interval represented by this
+ QUICK_RANGE into an index range endpoint specifier for the engine.
+
+ @param Pointer to an uninitialized key_range C struct.
+
+ @param prefix_length The length of the search key prefix to be used for
+ lookup.
+
+ @param keypart_map A set (bitmap) of keyparts to be used.
+ */
+ void make_min_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_min_endpoint(kr);
+ kr->length= min(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+ /**
+ Initalizes a key_range object for communication with storage engine.
+
+ This function facilitates communication with the Storage Engine API by
+ translating the minimum endpoint of the interval represented by this
+ QUICK_RANGE into an index range endpoint specifier for the engine.
+
+ @param Pointer to an uninitialized key_range C struct.
+ */
+ void make_min_endpoint(key_range *kr) {
+ kr->key= (const uchar*)min_key;
+ kr->length= min_length;
+ kr->keypart_map= min_keypart_map;
+ kr->flag= ((flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
+ (flag & EQ_RANGE) ? HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
+ }
+
+ /**
+ Initalizes a key_range object for communication with storage engine.
+
+ This function facilitates communication with the Storage Engine API by
+ translating the maximum endpoint of the interval represented by this
+ QUICK_RANGE into an index range endpoint specifier for the engine.
+
+ @param Pointer to an uninitialized key_range C struct.
+
+ @param prefix_length The length of the search key prefix to be used for
+ lookup.
+
+ @param keypart_map A set (bitmap) of keyparts to be used.
+ */
+ void make_max_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_max_endpoint(kr);
+ kr->length= min(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+ /**
+ Initalizes a key_range object for communication with storage engine.
+
+ This function facilitates communication with the Storage Engine API by
+ translating the maximum endpoint of the interval represented by this
+ QUICK_RANGE into an index range endpoint specifier for the engine.
+
+ @param Pointer to an uninitialized key_range C struct.
+ */
+ void make_max_endpoint(key_range *kr) {
+ kr->key= (const uchar*)max_key;
+ kr->length= max_length;
+ kr->keypart_map= max_keypart_map;
+ /*
+ We use READ_AFTER_KEY here because if we are reading on a key
+ prefix we want to find all keys with this prefix
+ */
+ kr->flag= (flag & NEAR_MAX ? HA_READ_BEFORE_KEY : HA_READ_AFTER_KEY);
+ }
};
@@ -345,7 +424,7 @@ public:
int reset(void);
int get_next();
void range_end();
- int get_next_prefix(uint prefix_length, key_part_map keypart_map,
+ int get_next_prefix(uint prefix_length, uint group_key_parts,
uchar *cur_prefix);
bool reverse_sorted() { return 0; }
bool unique_key_range();
@@ -625,7 +704,7 @@ private:
uchar *record; /* Buffer where the next record is returned. */
uchar *tmp_record; /* Temporary storage for next_min(), next_max(). */
uchar *group_prefix; /* Key prefix consisting of the GROUP fields. */
- uint group_prefix_len; /* Length of the group prefix. */
+ const uint group_prefix_len; /* Length of the group prefix. */
uint group_key_parts; /* A number of keyparts in the group prefix */
uchar *last_prefix; /* Prefix of the last group for detecting EOF. */
bool have_min; /* Specify whether we are computing */
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index fd2040a4979..0c79c8dc797 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -90,6 +90,123 @@ static ulonglong get_exact_record_count(TABLE_LIST *tables)
/**
+ Use index to read MIN(field) value.
+
+ @param table Table object
+ @param ref Reference to the structure where we store the key value
+ @item_field Field used in MIN()
+ @range_fl Whether range endpoint is strict less than
+ @prefix_len Length of common key part for the range
+
+ @retval
+ 0 No errors
+ HA_ERR_... Otherwise
+*/
+
+static int get_index_min_value(TABLE *table, TABLE_REF *ref,
+ Item_field *item_field, uint range_fl,
+ uint prefix_len)
+{
+ int error;
+
+ if (!ref->key_length)
+ error= table->file->index_first(table->record[0]);
+ else
+ {
+ /*
+ Use index to replace MIN/MAX functions with their values
+ according to the following rules:
+
+ 1) Insert the minimum non-null values where the WHERE clause still
+ matches, or
+ 2) a NULL value if there are only NULL values for key_part_k.
+ 3) Fail, producing a row of nulls
+
+ Implementation: Read the smallest value using the search key. If
+ the interval is open, read the next value after the search
+ key. If read fails, and we're looking for a MIN() value for a
+ nullable column, test if there is an exact match for the key.
+ */
+ if (!(range_fl & NEAR_MIN))
+ /*
+ Closed interval: Either The MIN argument is non-nullable, or
+ we have a >= predicate for the MIN argument.
+ */
+ error= table->file->index_read_map(table->record[0],
+ ref->key_buff,
+ make_prev_keypart_map(ref->key_parts),
+ HA_READ_KEY_OR_NEXT);
+ else
+ {
+ /*
+ Open interval: There are two cases:
+ 1) We have only MIN() and the argument column is nullable, or
+ 2) there is a > predicate on it, nullability is irrelevant.
+ We need to scan the next bigger record first.
+ */
+ error= table->file->index_read_map(table->record[0],
+ ref->key_buff,
+ make_prev_keypart_map(ref->key_parts),
+ HA_READ_AFTER_KEY);
+ /*
+ If the found record is outside the group formed by the search
+ prefix, or there is no such record at all, check if all
+ records in that group have NULL in the MIN argument
+ column. If that is the case return that NULL.
+
+ Check if case 1 from above holds. If it does, we should read
+ the skipped tuple.
+ */
+ if (item_field->field->real_maybe_null() &&
+ ref->key_buff[prefix_len] == 1 &&
+ /*
+ Last keypart (i.e. the argument to MIN) is set to NULL by
+ find_key_for_maxmin only if all other keyparts are bound
+ to constants in a conjunction of equalities. Hence, we
+ can detect this by checking only if the last keypart is
+ NULL.
+ */
+ (error == HA_ERR_KEY_NOT_FOUND ||
+ key_cmp_if_same(table, ref->key_buff, ref->key, prefix_len)))
+ {
+ DBUG_ASSERT(item_field->field->real_maybe_null());
+ error= table->file->index_read_map(table->record[0],
+ ref->key_buff,
+ make_prev_keypart_map(ref->key_parts),
+ HA_READ_KEY_EXACT);
+ }
+ }
+ }
+ return error;
+}
+
+
+/**
+ Use index to read MAX(field) value.
+
+ @param table Table object
+ @param ref Reference to the structure where we store the key value
+ @range_fl Whether range endpoint is strict greater than
+
+ @retval
+ 0 No errors
+ HA_ERR_... Otherwise
+*/
+
+static int get_index_max_value(TABLE *table, TABLE_REF *ref, uint range_fl)
+{
+ return (ref->key_length ?
+ table->file->index_read_map(table->record[0], ref->key_buff,
+ make_prev_keypart_map(ref->key_parts),
+ range_fl & NEAR_MAX ?
+ HA_READ_BEFORE_KEY :
+ HA_READ_PREFIX_LAST_OR_PREV) :
+ table->file->index_last(table->record[0]));
+}
+
+
+
+/**
Substitutes constants for some COUNT(), MIN() and MAX() functions.
@param tables list of leaves of join table tree
@@ -220,9 +337,11 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
const_result= 0;
break;
case Item_sum::MIN_FUNC:
+ case Item_sum::MAX_FUNC:
{
+ int is_max= test(item_sum->sum_func() == Item_sum::MAX_FUNC);
/*
- If MIN(expr) is the first part of a key or if all previous
+ If MIN/MAX(expr) is the first part of a key or if all previous
parts of the key is found in the COND, then we can use
indexes to find the key.
*/
@@ -241,89 +360,26 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
Look for a partial key that can be used for optimization.
If we succeed, ref.key_length will contain the length of
this key, while prefix_len will contain the length of
- the beginning of this key without field used in MIN().
+ the beginning of this key without field used in MIN/MAX().
Type of range for the key part for this field will be
returned in range_fl.
*/
if (table->file->inited || (outer_tables & table->map) ||
- !find_key_for_maxmin(0, &ref, item_field->field, conds,
+ !find_key_for_maxmin(is_max, &ref, item_field->field, conds,
&range_fl, &prefix_len))
{
const_result= 0;
break;
}
- error= table->file->ha_index_init((uint) ref.key, 1);
+ table->file->ha_index_init((uint) ref.key, 1);
+
+ error= is_max ?
+ get_index_max_value(table, &ref, range_fl) :
+ get_index_min_value(table, &ref, item_field, range_fl,
+ prefix_len);
- if (!ref.key_length)
- error= table->file->index_first(table->record[0]);
- else
- {
- /*
- Use index to replace MIN/MAX functions with their values
- according to the following rules:
-
- 1) Insert the minimum non-null values where the WHERE clause still
- matches, or
- 2) a NULL value if there are only NULL values for key_part_k.
- 3) Fail, producing a row of nulls
-
- Implementation: Read the smallest value using the search key. If
- the interval is open, read the next value after the search
- key. If read fails, and we're looking for a MIN() value for a
- nullable column, test if there is an exact match for the key.
- */
- if (!(range_fl & NEAR_MIN))
- /*
- Closed interval: Either The MIN argument is non-nullable, or
- we have a >= predicate for the MIN argument.
- */
- error= table->file->index_read_map(table->record[0],
- ref.key_buff,
- make_prev_keypart_map(ref.key_parts),
- HA_READ_KEY_OR_NEXT);
- else
- {
- /*
- Open interval: There are two cases:
- 1) We have only MIN() and the argument column is nullable, or
- 2) there is a > predicate on it, nullability is irrelevant.
- We need to scan the next bigger record first.
- */
- error= table->file->index_read_map(table->record[0],
- ref.key_buff,
- make_prev_keypart_map(ref.key_parts),
- HA_READ_AFTER_KEY);
- /*
- If the found record is outside the group formed by the search
- prefix, or there is no such record at all, check if all
- records in that group have NULL in the MIN argument
- column. If that is the case return that NULL.
-
- Check if case 1 from above holds. If it does, we should read
- the skipped tuple.
- */
- if (item_field->field->real_maybe_null() &&
- ref.key_buff[prefix_len] == 1 &&
- /*
- Last keypart (i.e. the argument to MIN) is set to NULL by
- find_key_for_maxmin only if all other keyparts are bound
- to constants in a conjunction of equalities. Hence, we
- can detect this by checking only if the last keypart is
- NULL.
- */
- (error == HA_ERR_KEY_NOT_FOUND ||
- key_cmp_if_same(table, ref.key_buff, ref.key, prefix_len)))
- {
- DBUG_ASSERT(item_field->field->real_maybe_null());
- error= table->file->index_read_map(table->record[0],
- ref.key_buff,
- make_prev_keypart_map(ref.key_parts),
- HA_READ_KEY_EXACT);
- }
- }
- }
/* Verify that the read tuple indeed matches the search key */
- if (!error && reckey_in_range(0, &ref, item_field->field,
+ if (!error && reckey_in_range(is_max, &ref, item_field->field,
conds, range_fl, prefix_len))
error= HA_ERR_KEY_NOT_FOUND;
table->set_keyread(FALSE);
@@ -355,100 +411,18 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
item_sum->set_aggregator(item_sum->has_with_distinct() ?
Aggregator::DISTINCT_AGGREGATOR :
Aggregator::SIMPLE_AGGREGATOR);
- if (!count)
- {
- /* If count == 0, then we know that is_exact_count == TRUE. */
- ((Item_sum_min*) item_sum)->aggregator_clear(); /* Set to NULL. */
- }
- else
- ((Item_sum_min*) item_sum)->reset(); /* Set to the constant value. */
- ((Item_sum_min*) item_sum)->make_const();
- recalc_const_item= 1;
- break;
- }
- case Item_sum::MAX_FUNC:
- {
/*
- If MAX(expr) is the first part of a key or if all previous
- parts of the key is found in the COND, then we can use
- indexes to find the key.
+ If count == 0 (so is_exact_count == TRUE) and
+ there're no outer joins, set to NULL,
+ otherwise set to the constant value.
*/
- Item *expr=item_sum->get_arg(0);
- if (expr->real_item()->type() == Item::FIELD_ITEM)
- {
- uchar key_buff[MAX_KEY_LENGTH];
- TABLE_REF ref;
- uint range_fl, prefix_len;
-
- ref.key_buff= key_buff;
- Item_field *item_field= (Item_field*) (expr->real_item());
- TABLE *table= item_field->field->table;
-
- /*
- Look for a partial key that can be used for optimization.
- If we succeed, ref.key_length will contain the length of
- this key, while prefix_len will contain the length of
- the beginning of this key without field used in MAX().
- Type of range for the key part for this field will be
- returned in range_fl.
- */
- if (table->file->inited || (outer_tables & table->map) ||
- !find_key_for_maxmin(1, &ref, item_field->field, conds,
- &range_fl, &prefix_len))
- {
- const_result= 0;
- break;
- }
- error= table->file->ha_index_init((uint) ref.key, 1);
-
- if (!ref.key_length)
- error= table->file->index_last(table->record[0]);
- else
- error= table->file->index_read_map(table->record[0], key_buff,
- make_prev_keypart_map(ref.key_parts),
- range_fl & NEAR_MAX ?
- HA_READ_BEFORE_KEY :
- HA_READ_PREFIX_LAST_OR_PREV);
- if (!error && reckey_in_range(1, &ref, item_field->field,
- conds, range_fl, prefix_len))
- error= HA_ERR_KEY_NOT_FOUND;
- table->set_keyread(FALSE);
- table->file->ha_index_end();
- if (error)
- {
- if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
- return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE
- /* HA_ERR_LOCK_DEADLOCK or some other error */
- table->file->print_error(error, MYF(ME_FATALERROR));
- return(error);
- }
- removed_tables|= table->map;
- }
- else if (!expr->const_item() || !is_exact_count)
- {
- /*
- The optimization is not applicable in both cases:
- (a) 'expr' is a non-constant expression. Then we can't
- replace 'expr' by a constant.
- (b) 'expr' is a costant. According to ANSI, MIN/MAX must return
- NULL if the query does not return any rows. Thus, if we are not
- able to determine if the query returns any rows, we can't apply
- the optimization and replace MIN/MAX with a constant.
- */
- const_result= 0;
- break;
- }
- item_sum->set_aggregator(item_sum->has_with_distinct() ?
- Aggregator::DISTINCT_AGGREGATOR :
- Aggregator::SIMPLE_AGGREGATOR);
- if (!count)
+ if (!count && !outer_tables)
{
- /* If count != 1, then we know that is_exact_count == TRUE. */
- ((Item_sum_max*) item_sum)->aggregator_clear(); /* Set to NULL. */
+ item_sum->aggregator_clear();
}
else
- ((Item_sum_max*) item_sum)->reset(); /* Set to the constant value. */
- ((Item_sum_max*) item_sum)->make_const();
+ item_sum->reset();
+ item_sum->make_const();
recalc_const_item= 1;
break;
}
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index e505630d08f..a689d53d953 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006-2008 MySQL AB, Sun Microsystems Inc. 2008-2009
+/* Copyright (c) 2006, 2010 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
@@ -603,12 +603,12 @@ bool partition_info::check_engine_mix(handlerton *engine_type,
{
handlerton *old_engine_type= engine_type;
bool first= TRUE;
- uint num_parts= partitions.elements;
+ uint n_parts= partitions.elements;
DBUG_ENTER("partition_info::check_engine_mix");
DBUG_PRINT("info", ("in: engine_type = %s, table_engine_set = %u",
ha_resolve_storage_engine_name(engine_type),
table_engine_set));
- if (num_parts)
+ if (n_parts)
{
List_iterator<partition_element> part_it(partitions);
uint i= 0;
@@ -621,7 +621,7 @@ bool partition_info::check_engine_mix(handlerton *engine_type,
if (is_sub_partitioned() &&
part_elem->subpartitions.elements)
{
- uint num_subparts= part_elem->subpartitions.elements;
+ uint n_subparts= part_elem->subpartitions.elements;
uint j= 0;
List_iterator<partition_element> sub_it(part_elem->subpartitions);
do
@@ -633,7 +633,7 @@ bool partition_info::check_engine_mix(handlerton *engine_type,
if (check_engine_condition(sub_elem, table_engine_set,
&engine_type, &first))
goto error;
- } while (++j < num_subparts);
+ } while (++j < n_subparts);
/* ensure that the partition also has correct engine */
if (check_engine_condition(part_elem, table_engine_set,
&engine_type, &first))
@@ -642,7 +642,7 @@ bool partition_info::check_engine_mix(handlerton *engine_type,
else if (check_engine_condition(part_elem, table_engine_set,
&engine_type, &first))
goto error;
- } while (++i < num_parts);
+ } while (++i < n_parts);
}
DBUG_PRINT("info", ("engine_type = %s",
ha_resolve_storage_engine_name(engine_type)));
@@ -1199,7 +1199,7 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
part_elem->engine_type= default_engine_type;
}
if (check_table_name(part_elem->partition_name,
- strlen(part_elem->partition_name)))
+ strlen(part_elem->partition_name), FALSE))
{
my_error(ER_WRONG_PARTITION_NAME, MYF(0));
goto end;
@@ -1218,7 +1218,7 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
sub_elem= sub_it++;
warn_if_dir_in_part_elem(thd, sub_elem);
if (check_table_name(sub_elem->partition_name,
- strlen(sub_elem->partition_name)))
+ strlen(sub_elem->partition_name), FALSE))
{
my_error(ER_WRONG_PARTITION_NAME, MYF(0));
goto end;
@@ -1315,15 +1315,15 @@ end:
RETURN VALUES
*/
-void partition_info::print_no_partition_found(TABLE *table)
+void partition_info::print_no_partition_found(TABLE *table_arg)
{
char buf[100];
char *buf_ptr= (char*)&buf;
TABLE_LIST table_list;
bzero(&table_list, sizeof(table_list));
- table_list.db= table->s->db.str;
- table_list.table_name= table->s->table_name.str;
+ table_list.db= table_arg->s->db.str;
+ table_list.table_name= table_arg->s->table_name.str;
if (check_single_table_access(current_thd,
SELECT_ACL, &table_list, TRUE))
@@ -1337,13 +1337,13 @@ void partition_info::print_no_partition_found(TABLE *table)
buf_ptr= (char*)"from column_list";
else
{
- my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table_arg, table_arg->read_set);
if (part_expr->null_value)
buf_ptr= (char*)"NULL";
else
longlong2str(err_value, buf,
part_expr->unsigned_flag ? 10 : -10);
- dbug_tmp_restore_column_map(table->read_set, old_map);
+ dbug_tmp_restore_column_map(table_arg->read_set, old_map);
}
my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0), buf_ptr);
}
@@ -2003,7 +2003,7 @@ bool partition_info::fix_column_value_functions(THD *thd,
part_elem_value *val,
uint part_id)
{
- uint num_columns= part_field_list.elements;
+ uint n_columns= part_field_list.elements;
bool result= FALSE;
uint i;
part_column_list_val *col_val= val->col_val_array;
@@ -2013,7 +2013,7 @@ bool partition_info::fix_column_value_functions(THD *thd,
{
DBUG_RETURN(FALSE);
}
- for (i= 0; i < num_columns; col_val++, i++)
+ for (i= 0; i < n_columns; col_val++, i++)
{
Item *column_item= col_val->item_expression;
Field *field= part_field_array[i];
diff --git a/sql/protocol.cc b/sql/protocol.cc
index fd01e4a8885..eeb248012ab 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -1014,8 +1014,8 @@ bool Protocol_text::store(const char *from, size_t length,
{
CHARSET_INFO *tocs= this->thd->variables.character_set_results;
#ifndef DBUG_OFF
- DBUG_PRINT("info", ("Protocol_text::store field %u (%u): %*.s",
- field_pos, field_count, (int) length, from));
+ DBUG_PRINT("info", ("Protocol_text::store field %u (%u): %s", field_pos,
+ field_count, (length == 0? "" : from)));
DBUG_ASSERT(field_pos < field_count);
DBUG_ASSERT(field_types == 0 ||
field_types[field_pos] == MYSQL_TYPE_DECIMAL ||
diff --git a/sql/slave.cc b/sql/slave.cc
index e23763696df..6ebdea4a42a 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -3124,6 +3124,11 @@ pthread_handler_t handle_slave_sql(void *arg)
{
THD *thd; /* needs to be first for thread_stack */
char llbuff[22],llbuff1[22];
+ char saved_log_name[FN_REFLEN];
+ char saved_master_log_name[FN_REFLEN];
+ my_off_t saved_log_pos;
+ my_off_t saved_master_log_pos;
+ my_off_t saved_skip= 0;
Relay_log_info* rli = &((Master_info*)arg)->rli;
const char *errmsg;
@@ -3269,6 +3274,17 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
do not want to wait for next event in this case.
*/
mysql_mutex_lock(&rli->data_lock);
+ if (rli->slave_skip_counter)
+ {
+ char *pos;
+ pos= strmake(saved_log_name, rli->group_relay_log_name, FN_REFLEN - 1);
+ pos= '\0';
+ pos= strmake(saved_master_log_name, rli->group_master_log_name, FN_REFLEN - 1);
+ pos= '\0';
+ saved_log_pos= rli->group_relay_log_pos;
+ saved_master_log_pos= rli->group_master_log_pos;
+ saved_skip= rli->slave_skip_counter;
+ }
if (rli->until_condition != Relay_log_info::UNTIL_NONE &&
rli->is_until_satisfied(thd, NULL))
{
@@ -3287,6 +3303,21 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
thd_proc_info(thd, "Reading event from the relay log");
DBUG_ASSERT(rli->sql_thd == thd);
THD_CHECK_SENTRY(thd);
+
+ if (saved_skip && rli->slave_skip_counter == 0)
+ {
+ sql_print_information("'SQL_SLAVE_SKIP_COUNTER=%ld' executed at "
+ "relay_log_file='%s', relay_log_pos='%ld', master_log_name='%s', "
+ "master_log_pos='%ld' and new position at "
+ "relay_log_file='%s', relay_log_pos='%ld', master_log_name='%s', "
+ "master_log_pos='%ld' ",
+ (ulong) saved_skip, saved_log_name, (ulong) saved_log_pos,
+ saved_master_log_name, (ulong) saved_master_log_pos,
+ rli->group_relay_log_name, (ulong) rli->group_relay_log_pos,
+ rli->group_master_log_name, (ulong) rli->group_master_log_pos);
+ saved_skip= 0;
+ }
+
if (exec_relay_log_event(thd,rli))
{
DBUG_PRINT("info", ("exec_relay_log_event() failed"));
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 2e66aec91e5..9395146f18f 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -125,10 +125,10 @@ sp_get_item_value(THD *thd, Item *item, String *str)
case STRING_RESULT:
{
String *result= item->val_str(str);
-
+
if (!result)
return NULL;
-
+
{
char buf_holder[STRING_BUFFER_USUAL_SIZE];
String buf(buf_holder, sizeof(buf_holder), result->charset());
@@ -366,7 +366,7 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
Save original values and restore them after save.
*/
-
+
thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
thd->abort_on_warning=
thd->variables.sql_mode &
@@ -465,7 +465,7 @@ check_routine_name(LEX_STRING *ident)
{
if (!ident || !ident->str || !ident->str[0] ||
ident->str[ident->length-1] == ' ')
- {
+ {
my_error(ER_SP_WRONG_NAME, MYF(0), ident->str);
return TRUE;
}
@@ -502,7 +502,7 @@ sp_head::operator new(size_t size) throw()
DBUG_RETURN(sp);
}
-void
+void
sp_head::operator delete(void *ptr, size_t size) throw()
{
DBUG_ENTER("sp_head::operator delete");
@@ -718,7 +718,7 @@ create_typelib(MEM_ROOT *mem_root, Create_field *field_def, List<String> *src)
String *tmp= it++;
if (String::needs_conversion(tmp->length(), tmp->charset(),
- cs, &dummy))
+ cs, &dummy))
{
uint cnv_errs;
conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
@@ -747,21 +747,12 @@ create_typelib(MEM_ROOT *mem_root, Create_field *field_def, List<String> *src)
sp_head::~sp_head()
{
+ LEX *lex;
+ sp_instr *i;
DBUG_ENTER("sp_head::~sp_head");
- destroy();
- delete m_next_cached_sp;
- if (m_thd)
- restore_thd_mem_root(m_thd);
- DBUG_VOID_RETURN;
-}
-void
-sp_head::destroy()
-{
- sp_instr *i;
- LEX *lex;
- DBUG_ENTER("sp_head::destroy");
- DBUG_PRINT("info", ("name: %s", m_name.str));
+ /* sp_head::restore_thd_mem_root() must already have been called. */
+ DBUG_ASSERT(m_thd == NULL);
for (uint ip = 0 ; (i = get_instr(ip)) ; ip++)
delete i;
@@ -772,21 +763,22 @@ sp_head::destroy()
/*
If we have non-empty LEX stack then we just came out of parser with
error. Now we should delete all auxilary LEXes and restore original
- THD::lex (In this case sp_head::restore_thd_mem_root() was not called
- too, so m_thd points to the current thread context).
- It is safe to not update LEX::ptr because further query string parsing
- and execution will be stopped anyway.
+ THD::lex. It is safe to not update LEX::ptr because further query
+ string parsing and execution will be stopped anyway.
*/
- DBUG_ASSERT(m_lex.is_empty() || m_thd);
while ((lex= (LEX *)m_lex.pop()))
{
- lex_end(m_thd->lex);
- delete m_thd->lex;
- m_thd->lex= lex;
+ THD *thd= lex->thd;
+ lex_end(thd->lex);
+ delete thd->lex;
+ thd->lex= lex;
}
my_hash_free(&m_sptabs);
my_hash_free(&m_sroutines);
+
+ delete m_next_cached_sp;
+
DBUG_VOID_RETURN;
}
@@ -823,7 +815,7 @@ sp_head::create_result_field(uint field_max_length, const char *field_name,
if (field)
field->init(table);
-
+
DBUG_RETURN(field);
}
@@ -852,7 +844,7 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
Statements that have is_update_query(stmt) == FALSE (e.g. SELECTs) are not
written into binary log. Instead we catch function calls the statement
makes and write it into binary log separately (see #3).
-
+
2. PROCEDURE calls
CALL statements are not written into binary log. Instead
@@ -865,8 +857,8 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
This substitution is done in subst_spvars().
3. FUNCTION calls
-
- In sp_head::execute_function(), we check
+
+ In sp_head::execute_function(), we check
* If this function invocation is done from a statement that is written
into the binary log.
* If there were any attempts to write events to the binary log during
@@ -874,28 +866,28 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
If the answers are No and Yes, we write the function call into the binary
log as "SELECT spfunc(<param1value>, <param2value>, ...)"
-
-
+
+
4. Miscellaneous issues.
-
- 4.1 User variables.
+
+ 4.1 User variables.
When we call mysql_bin_log.write() for an SP statement, thd->user_var_events
- must hold set<{var_name, value}> pairs for all user variables used during
+ must hold set<{var_name, value}> pairs for all user variables used during
the statement execution.
This set is produced by tracking user variable reads during statement
- execution.
+ execution.
For SPs, this has the following implications:
- 1) thd->user_var_events may contain events from several SP statements and
- needs to be valid after exection of these statements was finished. In
+ 1) thd->user_var_events may contain events from several SP statements and
+ needs to be valid after exection of these statements was finished. In
order to achieve that, we
* Allocate user_var_events array elements on appropriate mem_root (grep
for user_var_events_alloc).
* Use is_query_in_union() to determine if user_var_event is created.
-
+
2) We need to empty thd->user_var_events after we have wrote a function
- call. This is currently done by making
+ call. This is currently done by making
reset_dynamic(&thd->user_var_events);
calls in several different places. (TODO cosider moving this into
mysql_bin_log.write() function)
@@ -914,7 +906,7 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
Replace thd->query{_length} with a string that one can write to
the binlog.
- The binlog-suitable string is produced by replacing references to SP local
+ The binlog-suitable string is produced by replacing references to SP local
variables with NAME_CONST('sp_var_name', value) calls.
@param thd Current thread.
@@ -951,11 +943,11 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
}
if (!sp_vars_uses.elements())
DBUG_RETURN(FALSE);
-
+
/* Sort SP var refs by their occurences in the query */
sp_vars_uses.sort(cmp_splocal_locations);
- /*
+ /*
Construct a statement string where SP local var refs are replaced
with "NAME_CONST(name, value)"
*/
@@ -963,7 +955,7 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
cur= query_str->str;
prev_pos= res= 0;
thd->query_name_consts= 0;
-
+
for (Item_splocal **splocal= sp_vars_uses.front();
splocal < sp_vars_uses.back(); splocal++)
{
@@ -973,13 +965,13 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
String str_value_holder(str_buffer, sizeof(str_buffer),
&my_charset_latin1);
String *str_value;
-
+
/* append the text between sp ref occurences */
res|= qbuf.append(cur + prev_pos, (*splocal)->pos_in_query - prev_pos);
prev_pos= (*splocal)->pos_in_query + (*splocal)->len_in_query;
-
+
res|= (*splocal)->fix_fields(thd, (Item **) splocal);
- if (res)
+ if (res)
break;
if ((*splocal)->limit_clause_param)
@@ -1006,7 +998,7 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
res|= qbuf.append(')');
if (res)
break;
-
+
thd->query_name_consts++;
}
res|= qbuf.append(cur + prev_pos, query_str->length - prev_pos);
@@ -1032,16 +1024,14 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
}
-/*
+/**
Return appropriate error about recursion limit reaching
- SYNOPSIS
- sp_head::recursion_level_error()
- thd Thread handle
+ @param thd Thread handle
- NOTE
- For functions and triggers we return error about prohibited recursion.
- For stored procedures we return about reaching recursion limit.
+ @remark For functions and triggers we return error about
+ prohibited recursion. For stored procedures we
+ return about reaching recursion limit.
*/
void sp_head::recursion_level_error(THD *thd)
@@ -1061,7 +1051,7 @@ void sp_head::recursion_level_error(THD *thd)
Execute the routine. The main instruction jump loop is there.
Assume the parameters already set.
@todo
- - Will write this SP statement into binlog separately
+ - Will write this SP statement into binlog separately
(TODO: consider changing the condition to "not inside event union")
@retval
@@ -1225,10 +1215,10 @@ sp_head::execute(THD *thd)
do
{
sp_instr *i;
- uint hip; // Handler ip
+ uint hip;
#if defined(ENABLED_PROFILING)
- /*
+ /*
Treat each "instr" of a routine as discrete unit that could be profiled.
Profiling only records information for segments of code that set the
source of the query, and almost all kinds of instructions in s-p do not.
@@ -1237,7 +1227,8 @@ sp_head::execute(THD *thd)
thd->profiling.start_new_query("continuing inside routine");
#endif
- i = get_instr(ip); // Returns NULL when we're done.
+ /* get_instr returns NULL when we're done. */
+ i = get_instr(ip);
if (i == NULL)
{
#if defined(ENABLED_PROFILING)
@@ -1248,10 +1239,13 @@ sp_head::execute(THD *thd)
DBUG_PRINT("execute", ("Instruction %u", ip));
- /* Don't change NOW() in FUNCTION or TRIGGER */
+ /*
+ Make current_time() et al work. But don't change NOW() in FUNCTION
+ or TRIGGER.
+ */
if (!thd->in_sub_stmt)
- thd->set_time(); // Make current_time() et al work
-
+ thd->set_time();
+
/*
We have to set thd->stmt_arena before executing the instruction
to store in the instruction free_list all new items, created
@@ -1259,10 +1253,10 @@ sp_head::execute(THD *thd)
items made during other permanent subquery transformations).
*/
thd->stmt_arena= i;
-
- /*
- Will write this SP statement into binlog separately
- (TODO: consider changing the condition to "not inside event union")
+
+ /*
+ Will write this SP statement into binlog separately.
+ TODO: consider changing the condition to "not inside event union".
*/
if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
thd->user_var_events_alloc= thd->mem_root;
@@ -1271,8 +1265,8 @@ sp_head::execute(THD *thd)
if (i->free_list)
cleanup_items(i->free_list);
-
- /*
+
+ /*
If we've set thd->user_var_events_alloc to mem_root of this SP
statement, clean all the events allocated in it.
*/
@@ -1284,7 +1278,7 @@ sp_head::execute(THD *thd)
/* we should cleanup free_list and memroot, used by instruction */
thd->cleanup_after_query();
- free_root(&execute_mem_root, MYF(0));
+ free_root(&execute_mem_root, MYF(0));
/*
Check if an exception has occurred and a handler has been found
@@ -1299,7 +1293,7 @@ sp_head::execute(THD *thd)
switch (ctx->found_handler(& hip, & handler_index)) {
case SP_HANDLER_NONE:
- break;
+ break;
case SP_HANDLER_CONTINUE:
thd->restore_active_arena(&execute_arena, &backup_arena);
thd->set_n_backup_active_arena(&execute_arena, &backup_arena);
@@ -1308,15 +1302,15 @@ sp_head::execute(THD *thd)
default:
if (ctx->end_partial_result_set)
thd->protocol->end_partial_result_set(thd);
- ip= hip;
- err_status= FALSE;
- ctx->clear_handler();
- ctx->enter_handler(hip, handler_index);
+ ip= hip;
+ err_status= FALSE;
+ ctx->clear_handler();
+ ctx->enter_handler(hip, handler_index);
thd->clear_error();
thd->is_fatal_error= 0;
- thd->killed= THD::NOT_KILLED;
+ thd->killed= THD::NOT_KILLED;
thd->mysys_var->abort= 0;
- continue;
+ continue;
}
ctx->end_partial_result_set= FALSE;
@@ -1359,7 +1353,7 @@ sp_head::execute(THD *thd)
done:
DBUG_PRINT("info", ("err_status: %d killed: %d is_slave_error: %d report_error: %d",
- err_status, thd->killed, thd->is_slave_error,
+ err_status, thd->killed, thd->is_slave_error,
thd->is_error()));
if (thd->killed)
@@ -1847,10 +1841,10 @@ err_with_cleanup:
/**
- Execute a procedure.
+ Execute a procedure.
The function does the following steps:
- - Set all parameters
+ - Set all parameters
- changes security context for SUID routines
- call sp_head::execute
- copy back values of INOUT and OUT parameters
@@ -1888,14 +1882,14 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
save_spcont= octx= thd->spcont;
if (! octx)
- { // Create a temporary old context
- if (!(octx= new sp_rcontext(m_pcont, NULL, octx)) ||
- octx->init(thd))
+ {
+ /* Create a temporary old context. */
+ if (!(octx= new sp_rcontext(m_pcont, NULL, octx)) || octx->init(thd))
{
delete octx; /* Delete octx if it was init() that failed. */
DBUG_RETURN(TRUE);
}
-
+
#ifndef DBUG_OFF
octx->sp= 0;
#endif
@@ -2155,7 +2149,7 @@ sp_head::restore_lex(THD *thd)
oldlex= (LEX *)m_lex.pop();
if (! oldlex)
- DBUG_RETURN(FALSE); // Nothing to restore
+ DBUG_RETURN(FALSE); // Nothing to restore
oldlex->trg_table_fields.push_back(&sublex->trg_table_fields);
@@ -2308,7 +2302,7 @@ sp_head::do_cont_backpatch()
void
sp_head::set_info(longlong created, longlong modified,
- st_sp_chistics *chistics, ulong sql_mode)
+ st_sp_chistics *chistics, ulong sql_mode)
{
m_created= created;
m_modified= modified;
@@ -2318,8 +2312,8 @@ sp_head::set_info(longlong created, longlong modified,
m_chistics->comment.str= 0;
else
m_chistics->comment.str= strmake_root(mem_root,
- m_chistics->comment.str,
- m_chistics->comment.length);
+ m_chistics->comment.str,
+ m_chistics->comment.length);
m_sql_mode= sql_mode;
}
@@ -2360,7 +2354,7 @@ sp_head::reset_thd_mem_root(THD *thd)
DBUG_PRINT("info", ("mem_root 0x%lx moved to thd mem root 0x%lx",
(ulong) &mem_root, (ulong) &thd->mem_root));
free_list= thd->free_list; // Keep the old list
- thd->free_list= NULL; // Start a new one
+ thd->free_list= NULL; // Start a new one
m_thd= thd;
DBUG_VOID_RETURN;
}
@@ -2369,13 +2363,13 @@ void
sp_head::restore_thd_mem_root(THD *thd)
{
DBUG_ENTER("sp_head::restore_thd_mem_root");
- Item *flist= free_list; // The old list
+ Item *flist= free_list; // The old list
set_query_arena(thd); // Get new free_list and mem_root
state= INITIALIZED_FOR_SP;
DBUG_PRINT("info", ("mem_root 0x%lx returned from thd mem root 0x%lx",
(ulong) &mem_root, (ulong) &thd->mem_root));
- thd->free_list= flist; // Restore the old one
+ thd->free_list= flist; // Restore the old one
thd->mem_root= m_thd_root;
m_thd= NULL;
DBUG_VOID_RETURN;
@@ -2385,10 +2379,10 @@ sp_head::restore_thd_mem_root(THD *thd)
/**
Check if a user has access right to a routine.
- @param thd Thread handler
- @param sp SP
- @param full_access Set to 1 if the user has SELECT right to the
- 'mysql.proc' able or is the owner of the routine
+ @param thd Thread handler
+ @param sp SP
+ @param full_access Set to 1 if the user has SELECT right to the
+ 'mysql.proc' able or is the owner of the routine
@retval
false ok
@retval
@@ -2517,8 +2511,6 @@ sp_head::show_create_routine(THD *thd, int type)
}
-
-
/**
Add instruction to SP.
@@ -2578,11 +2570,11 @@ void sp_head::optimize()
if (src != dst)
{
/* Move the instruction and update prev. jumps */
- sp_instr *ibp;
- List_iterator_fast<sp_instr> li(bp);
+ sp_instr *ibp;
+ List_iterator_fast<sp_instr> li(bp);
- set_dynamic(&m_instr, (uchar*)&i, dst);
- while ((ibp= li++))
+ set_dynamic(&m_instr, (uchar*)&i, dst);
+ while ((ibp= li++))
{
sp_instr_opt_meta *im= static_cast<sp_instr_opt_meta *>(ibp);
im->set_destination(src, dst);
@@ -2677,7 +2669,7 @@ sp_head::show_routine_code(THD *thd)
for (ip= 0; (i = get_instr(ip)) ; ip++)
{
- /*
+ /*
Consistency check. If these are different something went wrong
during optimization.
*/
@@ -2740,7 +2732,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
int res= 0;
DBUG_ENTER("reset_lex_and_exec_core");
- /*
+ /*
The flag is saved at the entry to the following substatement.
It's reset further in the common code part.
It's merged with the saved parent's value at the exit of this func.
@@ -2902,9 +2894,8 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
if (unlikely((thd->variables.option_bits & OPTION_LOG_OFF)==0))
general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
- if (query_cache_send_result_to_client(thd,
- thd->query(),
- thd->query_length()) <= 0)
+ if (query_cache_send_result_to_client(thd, thd->query(),
+ thd->query_length()) <= 0)
{
res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
@@ -3007,7 +2998,7 @@ sp_instr_set::exec_core(THD *thd, uint *nextp)
/* If this also failed, let's abort. */
sp_rcontext *spcont= thd->spcont;
-
+
thd->spcont= NULL; /* Avoid handlers */
my_error(ER_OUT_OF_RESOURCES, MYF(0));
spcont->clear_handler();
@@ -3051,6 +3042,7 @@ int
sp_instr_set_trigger_field::execute(THD *thd, uint *nextp)
{
DBUG_ENTER("sp_instr_set_trigger_field::execute");
+ thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
}
@@ -3110,7 +3102,7 @@ uint
sp_instr_jump::opt_mark(sp_head *sp, List<sp_instr> *leads)
{
m_dest= opt_shortcut_jump(sp, this);
- if (m_dest != m_ip+1) /* Jumping to following instruction? */
+ if (m_dest != m_ip+1) /* Jumping to following instruction? */
marked= 1;
m_optdest= sp->get_instr(m_dest);
return m_dest;
@@ -3140,9 +3132,9 @@ void
sp_instr_jump::opt_move(uint dst, List<sp_instr> *bp)
{
if (m_dest > m_ip)
- bp->push_back(this); // Forward
+ bp->push_back(this); // Forward
else if (m_optdest)
- m_dest= m_optdest->m_ip; // Backward
+ m_dest= m_optdest->m_ip; // Backward
m_ip= dst;
}
@@ -3415,7 +3407,7 @@ uint
sp_instr_hreturn::opt_mark(sp_head *sp, List<sp_instr> *leads)
{
marked= 1;
-
+
if (m_dest)
{
/*
@@ -3423,7 +3415,7 @@ sp_instr_hreturn::opt_mark(sp_head *sp, List<sp_instr> *leads)
*/
return m_dest;
}
-
+
/*
This is a CONTINUE handler; next instruction step will come from
the handler stack and not from opt_mark.
@@ -3740,14 +3732,14 @@ sp_instr_set_case_expr::exec_core(THD *thd, uint *nextp)
*/
Item *null_item= new Item_null();
-
+
if (!null_item ||
thd->spcont->set_case_expr(thd, m_case_expr_id, &null_item))
{
/* If this also failed, we have to abort. */
sp_rcontext *spcont= thd->spcont;
-
+
thd->spcont= NULL; /* Avoid handlers */
my_error(ER_OUT_OF_RESOURCES, MYF(0));
spcont->clear_handler();
@@ -3913,13 +3905,13 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
}
else
{
- if (!(tab= (SP_TABLE *)thd->calloc(sizeof(SP_TABLE))))
- return FALSE;
- if (lex_for_tmp_check->sql_command == SQLCOM_CREATE_TABLE &&
- lex_for_tmp_check->query_tables == table &&
- lex_for_tmp_check->create_info.options & HA_LEX_CREATE_TMP_TABLE)
+ if (!(tab= (SP_TABLE *)thd->calloc(sizeof(SP_TABLE))))
+ return FALSE;
+ if (lex_for_tmp_check->sql_command == SQLCOM_CREATE_TABLE &&
+ lex_for_tmp_check->query_tables == table &&
+ lex_for_tmp_check->create_info.options & HA_LEX_CREATE_TMP_TABLE)
{
- tab->temp= TRUE;
+ tab->temp= TRUE;
tab->qname.length= tlen - alen - 1;
}
else
@@ -3932,7 +3924,7 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
tab->lock_type= table->lock_type;
tab->lock_count= tab->query_lock_count= 1;
tab->trg_event_map= table->trg_event_map;
- if (my_hash_insert(&m_sptabs, (uchar *)tab))
+ if (my_hash_insert(&m_sptabs, (uchar *)tab))
return FALSE;
}
}
@@ -4039,8 +4031,8 @@ sp_head::add_used_tables_to_table_list(THD *thd,
TABLE_LIST *
sp_add_to_query_tables(THD *thd, LEX *lex,
- const char *db, const char *name,
- thr_lock_type locktype)
+ const char *db, const char *name,
+ thr_lock_type locktype)
{
TABLE_LIST *table;
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 165f88321a9..539a2da5f8c 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -305,10 +305,6 @@ public:
virtual ~sp_head();
- /// Free memory
- void
- destroy();
-
bool
execute_trigger(THD *thd,
const LEX_STRING *db_name,
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 55d83f49245..ec25e4cb68b 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -6261,21 +6261,21 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
mysql_mutex_unlock(&acl_cache->lock);
- int binlog_error=
+ if (result)
+ my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0));
+
+ result= result |
write_bin_log(thd, FALSE, thd->query(), thd->query_length());
mysql_rwlock_unlock(&LOCK_grant);
close_thread_tables(thd);
- /* error for writing binary log has already been reported */
- if (result && !binlog_error)
- my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0));
/* Restore the state of binlog format */
DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
if (save_binlog_row_based)
thd->set_current_stmt_binlog_format_row();
- DBUG_RETURN(result || binlog_error);
+ DBUG_RETURN(result);
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 28633365e28..1e537112d01 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1418,6 +1418,12 @@ void close_thread_tables(THD *thd)
table->s->table_name.str, (long) table));
#endif
+#if defined(ENABLED_DEBUG_SYNC)
+ /* debug_sync may not be initialized for some slave threads */
+ if (thd->debug_sync_control)
+ DEBUG_SYNC(thd, "before_close_thread_tables");
+#endif
+
/* Detach MERGE children after every statement. Even under LOCK TABLES. */
for (table= thd->open_tables; table; table= table->next)
{
@@ -5281,8 +5287,8 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables,
thd - thread handler
tables - list of tables for open
flags - bitmap of flags to modify how the tables will be open:
- MYSQL_OPEN_IGNORE_FLUSH - open table even if someone has
- done a flush or namelock on it.
+ MYSQL_LOCK_IGNORE_FLUSH - open table even if someone has
+ done a flush on it.
RETURN
FALSE - ok
@@ -8821,8 +8827,57 @@ bool is_equal(const LEX_STRING *a, const LEX_STRING *b)
/*
+ Unlock and close table before renaming and dropping partitions
+ SYNOPSIS
+ alter_close_tables()
+ lpt Struct carrying parameters
+ RETURN VALUES
+ 0
+*/
+
+static int alter_close_tables(ALTER_PARTITION_PARAM_TYPE *lpt)
+{
+ TABLE_SHARE *share= lpt->table->s;
+ THD *thd= lpt->thd;
+ TABLE *table;
+ DBUG_ENTER("alter_close_tables");
+ /*
+ We must keep LOCK_open while manipulating with thd->open_tables.
+ Another thread may be working on it.
+ */
+ mysql_mutex_lock(&LOCK_open);
+ /*
+ We can safely remove locks for all tables with the same name:
+ later they will all be closed anyway in
+ alter_partition_lock_handling().
+ */
+ for (table= thd->open_tables; table ; table= table->next)
+ {
+ if (!strcmp(table->s->table_name.str, share->table_name.str) &&
+ !strcmp(table->s->db.str, share->db.str))
+ {
+ mysql_lock_remove(thd, thd->lock, table);
+ table->file->close();
+ table->db_stat= 0; // Mark file closed
+ /*
+ Ensure that we won't end up with a crippled table instance
+ in the table cache if an error occurs before we reach
+ alter_partition_lock_handling() and the table is closed
+ by close_thread_tables() instead.
+ */
+ tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED,
+ table->s->db.str,
+ table->s->table_name.str);
+ }
+ }
+ mysql_mutex_unlock(&LOCK_open);
+ DBUG_RETURN(0);
+}
+
+
+/*
SYNOPSIS
- abort_and_upgrade_lock()
+ abort_and_upgrade_lock_and_close_table()
lpt Parameter passing struct
All parameters passed through the ALTER_PARTITION_PARAM_TYPE object
RETURN VALUE
@@ -8831,7 +8886,7 @@ bool is_equal(const LEX_STRING *a, const LEX_STRING *b)
Remember old lock level (for possible downgrade later on), abort all
waiting threads and ensure that all keeping locks currently are
completed such that we own the lock exclusively and no other interaction
- is ongoing.
+ is ongoing. Close the table and hold the name lock.
thd Thread object
table Table object
@@ -8840,12 +8895,14 @@ bool is_equal(const LEX_STRING *a, const LEX_STRING *b)
old_lock_level Old lock level
*/
-int abort_and_upgrade_lock(ALTER_PARTITION_PARAM_TYPE *lpt)
+int abort_and_upgrade_lock_and_close_table(ALTER_PARTITION_PARAM_TYPE *lpt)
{
- DBUG_ENTER("abort_and_upgrade_lock");
+ DBUG_ENTER("abort_and_upgrade_lock_and_close_table");
if (wait_while_table_is_used(lpt->thd, lpt->table, HA_EXTRA_FORCE_REOPEN))
DBUG_RETURN(1);
+ if (alter_close_tables(lpt))
+ DBUG_RETURN(1);
DBUG_RETURN(0);
}
diff --git a/sql/sql_base.h b/sql/sql_base.h
index 0c16151e43a..0fe70e4bc9d 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -217,7 +217,7 @@ TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
thr_lock_type lock_type, uint flags);
bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags);
bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags);
-int abort_and_upgrade_lock(ALTER_PARTITION_PARAM_TYPE *lpt);
+int abort_and_upgrade_lock_and_close_table(ALTER_PARTITION_PARAM_TYPE *lpt);
int decide_logging_format(THD *thd, TABLE_LIST *tables);
void free_io_cache(TABLE *entry);
void intern_close_table(TABLE *entry);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 789b01443f7..814ef27e574 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -305,6 +305,37 @@ void **thd_ha_data(const THD *thd, const struct handlerton *hton)
return (void **) &thd->ha_data[hton->slot].ha_ptr;
}
+
+/**
+ Provide a handler data getter to simplify coding
+*/
+extern "C"
+void *thd_get_ha_data(const THD *thd, const struct handlerton *hton)
+{
+ return *thd_ha_data(thd, hton);
+}
+
+
+/**
+ Provide a handler data setter to simplify coding
+ @see thd_set_ha_data() definition in plugin.h
+*/
+extern "C"
+void thd_set_ha_data(THD *thd, const struct handlerton *hton,
+ const void *ha_data)
+{
+ plugin_ref *lock= &thd->ha_data[hton->slot].lock;
+ if (ha_data && !*lock)
+ *lock= ha_lock_engine(NULL, (handlerton*) hton);
+ else if (!ha_data && *lock)
+ {
+ plugin_unlock(NULL, *lock);
+ *lock= NULL;
+ }
+ *thd_ha_data(thd, hton)= (void*) ha_data;
+}
+
+
extern "C"
long long thd_test_options(const THD *thd, long long test_options)
{
@@ -1884,8 +1915,7 @@ static File create_file(THD *thd, char *path, sql_exchange *exchange,
else
(void) fn_format(path, exchange->file_name, mysql_real_data_home, "", option);
- if (opt_secure_file_priv &&
- strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
+ if (!is_secure_file_path(path))
{
/* Write only allowed to dir or subdir specified by secure_file_priv */
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
@@ -2054,9 +2084,21 @@ bool select_export::send_data(List<Item> &items)
const char *from_end_pos;
const char *error_pos;
uint32 bytes;
- bytes= well_formed_copy_nchars(write_cs, cvt_buff, sizeof(cvt_buff),
+ uint64 estimated_bytes=
+ ((uint64) res->length() / res->charset()->mbminlen + 1) *
+ write_cs->mbmaxlen + 1;
+ set_if_smaller(estimated_bytes, UINT_MAX32);
+ if (cvt_str.realloc((uint32) estimated_bytes))
+ {
+ my_error(ER_OUTOFMEMORY, MYF(0), (uint32) estimated_bytes);
+ goto err;
+ }
+
+ bytes= well_formed_copy_nchars(write_cs, (char *) cvt_str.ptr(),
+ cvt_str.alloced_length(),
res->charset(), res->ptr(), res->length(),
- sizeof(cvt_buff),
+ UINT_MAX32, // copy all input chars,
+ // i.e. ignore nchars parameter
&well_formed_error_pos,
&cannot_convert_error_pos,
&from_end_pos);
@@ -2074,6 +2116,15 @@ bool select_export::send_data(List<Item> &items)
"string", printable_buff,
item->name, row_count);
}
+ else if (from_end_pos < res->ptr() + res->length())
+ {
+ /*
+ result is longer than UINT_MAX32 and doesn't fit into String
+ */
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ WARN_DATA_TRUNCATED, ER(WARN_DATA_TRUNCATED),
+ item->full_name(), row_count);
+ }
cvt_str.length(bytes);
res= &cvt_str;
}
@@ -3185,6 +3236,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
#endif
backup->option_bits= variables.option_bits;
+ backup->count_cuted_fields= count_cuted_fields;
backup->in_sub_stmt= in_sub_stmt;
backup->enable_slow_log= enable_slow_log;
backup->limit_found_rows= limit_found_rows;
@@ -3222,6 +3274,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
void THD::restore_sub_statement_state(Sub_statement_state *backup)
{
+ DBUG_ENTER("THD::restore_sub_statement_state");
#ifndef EMBEDDED_LIBRARY
/* BUG#33029, if we are replicating from a buggy master, restore
auto_inc_intervals_forced so that the top statement can use the
@@ -3248,6 +3301,7 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup)
/* ha_release_savepoint() never returns error. */
(void)ha_release_savepoint(this, sv);
}
+ count_cuted_fields= backup->count_cuted_fields;
transaction.savepoints= backup->savepoints;
variables.option_bits= backup->option_bits;
in_sub_stmt= backup->in_sub_stmt;
@@ -3277,6 +3331,7 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup)
*/
examined_row_count+= backup->examined_row_count;
cuted_fields+= backup->cuted_fields;
+ DBUG_VOID_RETURN;
}
@@ -4406,7 +4461,6 @@ int THD::binlog_flush_pending_rows_event(bool stmt_end, bool is_transactional)
if (stmt_end)
{
pending->set_flags(Rows_log_event::STMT_END_F);
- pending->flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
binlog_table_maps= 0;
}
@@ -4592,7 +4646,6 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
{
Query_log_event qinfo(this, query_arg, query_len, is_trans, direct,
suppress_use, errcode);
- qinfo.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
/*
Binlog table maps will be irrelevant after a Query_log_event
(they are just removed on the slave side) so after the query
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 916b79f8353..22143eb1498 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1094,6 +1094,7 @@ public:
bool enable_slow_log;
bool last_insert_id_used;
SAVEPOINT *savepoints;
+ enum enum_check_fields count_cuted_fields;
};
@@ -1469,7 +1470,11 @@ struct Ha_data
@sa trans_register_ha()
*/
Ha_trx_info ha_info[2];
-
+ /**
+ NULL: engine is not bound to this thread
+ non-NULL: engine is bound to this thread, engine shutdown forbidden
+ */
+ plugin_ref lock;
Ha_data() :ha_ptr(NULL) {}
};
@@ -2046,8 +2051,15 @@ public:
*/
ha_rows sent_row_count;
- /*
- number of rows we read, sent or not, including in create_sort_index()
+ /**
+ Number of rows read and/or evaluated for a statement. Used for
+ slow log reporting.
+
+ An examined row is defined as a row that is read and/or evaluated
+ according to a statement condition, including in
+ create_sort_index(). Rows may be counted more than once, e.g., a
+ statement including ORDER BY could possibly evaluate the row in
+ filesort() before reading it for e.g. update.
*/
ha_rows examined_row_count;
@@ -2107,8 +2119,6 @@ public:
char scramble[SCRAMBLE_LENGTH+1];
bool slave_thread, one_shot_set;
- bool locked, some_tables_deleted;
- bool last_cuted_field;
bool no_errors, password;
/**
Set to TRUE if execution of the current compound statement
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index e2d0977def7..c0081c13366 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -496,6 +496,13 @@ check_user(THD *thd, enum enum_server_command command,
}
my_ok(thd);
thd->password= test(passwd_len); // remember for error messages
+ /*
+ Allow the network layer to skip big packets. Although a malicious
+ authenticated session might use this to trick the server to read
+ big packets indefinitely, this is a previously established behavior
+ that needs to be preserved as to not break backwards compatibility.
+ */
+ thd->net.skip_big_packet= TRUE;
/* Ready to handle queries */
DBUG_RETURN(0);
}
diff --git a/sql/sql_const.h b/sql/sql_const.h
index 72f34ed6be8..dca66628ddb 100644
--- a/sql/sql_const.h
+++ b/sql/sql_const.h
@@ -136,7 +136,6 @@
#ifndef MYSQLD_NET_RETRY_COUNT
#define MYSQLD_NET_RETRY_COUNT 10 ///< Abort read after this many int.
#endif
-#define TEMP_POOL_SIZE 128
#define QUERY_ALLOC_BLOCK_SIZE 8192
#define QUERY_ALLOC_PREALLOC_SIZE 8192
@@ -146,11 +145,8 @@
#define ACL_ALLOC_BLOCK_SIZE 1024
#define UDF_ALLOC_BLOCK_SIZE 1024
#define TABLE_ALLOC_BLOCK_SIZE 1024
-#define BDB_LOG_ALLOC_BLOCK_SIZE 1024
#define WARN_ALLOC_BLOCK_SIZE 2048
#define WARN_ALLOC_PREALLOC_SIZE 1024
-#define PROFILE_ALLOC_BLOCK_SIZE 2048
-#define PROFILE_ALLOC_PREALLOC_SIZE 1024
/*
The following parameters is to decide when to use an extra cache to
@@ -194,8 +190,6 @@
*/
#define MATCHING_ROWS_IN_OTHER_TABLE 10
-#define RAID_BLOCK_SIZE 1024
-
#define MY_CHARSET_BIN_MB_MAXLEN 1
/** Don't pack string keys shorter than this (if PACK_KEYS=1 isn't used). */
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 10bdb8a22a6..2e86315d072 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -25,8 +25,7 @@
#include "sql_cache.h" // query_cache_*
#include "sql_base.h" // open_temprary_table
#include "sql_table.h" // build_table_filename
-#include "lock.h" // lock_and_wait_for_table_name,
- // unlock_table_name
+#include "lock.h" // unlock_table_name
#include "sql_view.h" // check_key_in_view, mysql_frm_type
#include "sql_parse.h" // mysql_init_select
#include "sql_acl.h" // *_ACL
@@ -262,6 +261,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
free_underlaid_joins(thd, &thd->lex->select_lex);
DBUG_RETURN(TRUE);
}
+ thd->examined_row_count+= examined_rows;
/*
Filesort has already found and selected the rows we want to delete,
so we don't need the where clause
@@ -279,7 +279,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
free_underlaid_joins(thd, select_lex);
DBUG_RETURN(TRUE);
}
- if (usable_index==MAX_KEY)
+ if (usable_index==MAX_KEY || (select && select->quick))
init_read_record(&info, thd, table, select, 1, 1, FALSE);
else
init_read_record_idx(&info, thd, table, 1, usable_index);
@@ -318,6 +318,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
while (!(error=info.read_record(&info)) && !thd->killed &&
! thd->is_error())
{
+ thd->examined_row_count++;
// thd->is_error() is tested to disallow delete row on error
if (!(select && select->skip_record())&& ! thd->is_error() )
{
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 1f9d69a798e..d40f0dcb410 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -3256,7 +3256,7 @@ bool select_insert::send_data(List<Item> &values)
thd->count_cuted_fields= CHECK_FIELD_WARN; // Calculate cuted fields
store_values(values);
- thd->count_cuted_fields= CHECK_FIELD_IGNORE;
+ thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
if (thd->is_error())
{
table->auto_increment_field_not_null= FALSE;
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 1795bc272f1..88cba22d115 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2218,6 +2218,7 @@ void LEX::cleanup_lex_after_parse_error(THD *thd)
*/
if (thd->lex->sphead)
{
+ thd->lex->sphead->restore_thd_mem_root(thd);
delete thd->lex->sphead;
thd->lex->sphead= NULL;
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 2ce6bdeed42..40bd3875793 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -2040,6 +2040,7 @@ struct LEX: public Query_tables_list
- CREATE TRIGGER (points to "TRIGGER");
- CREATE PROCEDURE (points to "PROCEDURE");
- CREATE FUNCTION (points to "FUNCTION" or "AGGREGATE");
+ - CREATE EVENT (points to "EVENT")
This pointer is required to add possibly omitted DEFINER-clause to the
DDL-statement before dumping it to the binlog.
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index ff9c16d229b..2c42f29ae71 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2000, 2010 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
@@ -397,16 +397,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
DBUG_ASSERT(FALSE);
#endif
}
- else if (opt_secure_file_priv)
+ else if (!is_secure_file_path(name))
{
- char secure_file_real_path[FN_REFLEN];
- (void) my_realpath(secure_file_real_path, opt_secure_file_priv, 0);
- if (strncmp(secure_file_real_path, name, strlen(secure_file_real_path)))
- {
- /* Read only allowed from within dir specified by secure_file_priv */
- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
- DBUG_RETURN(TRUE);
- }
+ /* Read only allowed from within dir specified by secure_file_priv */
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
+ DBUG_RETURN(TRUE);
}
}
@@ -572,7 +567,6 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
else
{
Delete_file_log_event d(thd, db, transactional_table);
- d.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
(void) mysql_bin_log.write(&d);
}
}
@@ -748,16 +742,13 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
strcpy(end, p);
end += pl;
- thd->set_query_inner(load_data_query, end - load_data_query);
-
Execute_load_query_log_event
- e(thd, thd->query(), thd->query_length(),
- (uint) ((char*) fname_start - (char*) thd->query() - 1),
- (uint) ((char*) fname_end - (char*) thd->query()),
+ e(thd, load_data_query, end-load_data_query,
+ (uint) ((char*) fname_start - load_data_query - 1),
+ (uint) ((char*) fname_end - load_data_query),
(duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
(ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
transactional_table, FALSE, FALSE, errcode);
- e.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
return mysql_bin_log.write(&e);
}
@@ -1717,7 +1708,7 @@ bool READ_INFO::find_start_of_fields()
/*
Clear taglist from tags with a specified level
*/
-int READ_INFO::clear_level(int level)
+int READ_INFO::clear_level(int level_arg)
{
DBUG_ENTER("READ_INFO::read_xml clear_level");
List_iterator<XML_TAG> xmlit(taglist);
@@ -1726,7 +1717,7 @@ int READ_INFO::clear_level(int level)
while ((tag= xmlit++))
{
- if(tag->level >= level)
+ if(tag->level >= level_arg)
{
xmlit.remove();
delete tag;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 2e47ce1e02a..ed4390a23cb 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1160,8 +1160,23 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
We have name + wildcard in packet, separated by endzero
*/
arg_end= strend(packet);
+ uint arg_length= arg_end - packet;
+
+ /* Check given table name length. */
+ if (arg_length >= packet_length || arg_length > NAME_LEN)
+ {
+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
+ break;
+ }
thd->convert_string(&conv_name, system_charset_info,
- packet, (uint) (arg_end - packet), thd->charset());
+ packet, arg_length, thd->charset());
+ if (check_table_name(conv_name.str, conv_name.length, FALSE))
+ {
+ /* this is OK due to convert_string() null-terminating the string */
+ my_error(ER_WRONG_TABLE_NAME, MYF(0), conv_name.str);
+ break;
+ }
+
table_list.alias= table_list.table_name= conv_name.str;
packet= arg_end + 1;
@@ -3238,7 +3253,7 @@ end_with_restore_list:
TODO: this is workaround. right way will be move invalidating in
the unlock procedure.
*/
- if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
+ if (!res && first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
thd->lock)
{
/* INSERT ... SELECT should invalidate only the very first table */
@@ -6042,7 +6057,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
DBUG_RETURN(0); // End of memory
alias_str= alias ? alias->str : table->table.str;
if (!test(table_options & TL_OPTION_ALIAS) &&
- check_table_name(table->table.str, table->table.length))
+ check_table_name(table->table.str, table->table.length, FALSE))
{
my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
DBUG_RETURN(0);
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index e6f9a10801b..fa9c698622b 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -6280,54 +6280,6 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)
sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE");
}
-/*
- Unlock and close table before renaming and dropping partitions
- SYNOPSIS
- alter_close_tables()
- lpt Struct carrying parameters
- RETURN VALUES
- 0
-*/
-
-static int alter_close_tables(ALTER_PARTITION_PARAM_TYPE *lpt)
-{
- TABLE_SHARE *share= lpt->table->s;
- THD *thd= lpt->thd;
- TABLE *table;
- DBUG_ENTER("alter_close_tables");
- /*
- We must keep LOCK_open while manipulating with thd->open_tables.
- Another thread may be working on it.
- */
- mysql_mutex_lock(&LOCK_open);
- /*
- We can safely remove locks for all tables with the same name:
- later they will all be closed anyway in
- alter_partition_lock_handling().
- */
- for (table= thd->open_tables; table ; table= table->next)
- {
- if (!strcmp(table->s->table_name.str, share->table_name.str) &&
- !strcmp(table->s->db.str, share->db.str))
- {
- mysql_lock_remove(thd, thd->lock, table);
- table->file->close();
- table->db_stat= 0; // Mark file closed
- /*
- Ensure that we won't end up with a crippled table instance
- in the table cache if an error occurs before we reach
- alter_partition_lock_handling() and the table is closed
- by close_thread_tables() instead.
- */
- tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED,
- table->s->db.str,
- table->s->table_name.str);
- }
- }
- mysql_mutex_unlock(&LOCK_open);
- DBUG_RETURN(0);
-}
-
/*
Handle errors for ALTER TABLE for partitioning
@@ -6626,9 +6578,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
write_log_drop_partition(lpt) ||
ERROR_INJECT_CRASH("crash_drop_partition_3") ||
(not_completed= FALSE) ||
- abort_and_upgrade_lock(lpt) ||
- ERROR_INJECT_CRASH("crash_drop_partition_4") ||
- alter_close_tables(lpt) ||
+ abort_and_upgrade_lock_and_close_table(lpt) ||
ERROR_INJECT_CRASH("crash_drop_partition_5") ||
((!thd->lex->no_write_to_binlog) &&
(write_bin_log(thd, FALSE,
@@ -6694,9 +6644,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_CRASH("crash_add_partition_2") ||
mysql_change_partitions(lpt) ||
ERROR_INJECT_CRASH("crash_add_partition_3") ||
- abort_and_upgrade_lock(lpt) ||
- ERROR_INJECT_CRASH("crash_add_partition_4") ||
- alter_close_tables(lpt) ||
+ abort_and_upgrade_lock_and_close_table(lpt) ||
ERROR_INJECT_CRASH("crash_add_partition_5") ||
((!thd->lex->no_write_to_binlog) &&
(write_bin_log(thd, FALSE,
@@ -6779,9 +6727,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
write_log_final_change_partition(lpt) ||
ERROR_INJECT_CRASH("crash_change_partition_4") ||
(not_completed= FALSE) ||
- abort_and_upgrade_lock(lpt) ||
- ERROR_INJECT_CRASH("crash_change_partition_5") ||
- alter_close_tables(lpt) ||
+ abort_and_upgrade_lock_and_close_table(lpt) ||
ERROR_INJECT_CRASH("crash_change_partition_6") ||
((!thd->lex->no_write_to_binlog) &&
(write_bin_log(thd, FALSE,
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 31e0cced207..0282053ce7e 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1755,6 +1755,12 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
struct st_plugin_int *tmp;
DBUG_ENTER("mysql_install_plugin");
+ if (opt_noacl)
+ {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables");
+ DBUG_RETURN(TRUE);
+ }
+
tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_WRITE);
if (check_table_access(thd, INSERT_ACL, &tables, FALSE, 1, FALSE))
DBUG_RETURN(TRUE);
@@ -1829,6 +1835,12 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
struct st_plugin_int *plugin;
DBUG_ENTER("mysql_uninstall_plugin");
+ if (opt_noacl)
+ {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables");
+ DBUG_RETURN(TRUE);
+ }
+
tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_WRITE);
if (check_table_access(thd, DELETE_ACL, &tables, FALSE, 1, FALSE))
diff --git a/sql/sql_priv.h b/sql/sql_priv.h
index 20893e0caa8..8601b10b9bf 100644
--- a/sql/sql_priv.h
+++ b/sql/sql_priv.h
@@ -187,10 +187,6 @@ extern char err_shared_dir[];
#define BINLOG_DUMP_NON_BLOCK 1
-/* sql_show.cc:show_log_files() */
-#define SHOW_LOG_STATUS_FREE "FREE"
-#define SHOW_LOG_STATUS_INUSE "IN USE"
-
/*
Some defines for exit codes for ::is_equal class functions.
*/
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 1ee770f70ef..787f9dcae2c 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1347,6 +1347,10 @@ bool change_master(THD* thd, Master_info* mi)
const char* errmsg= 0;
bool need_relay_log_purge= 1;
bool ret= FALSE;
+ char saved_host[HOSTNAME_LENGTH + 1];
+ uint saved_port;
+ char saved_log_name[FN_REFLEN];
+ my_off_t saved_log_pos;
DBUG_ENTER("change_master");
lock_slave_threads(mi);
@@ -1389,6 +1393,17 @@ bool change_master(THD* thd, Master_info* mi)
*/
/*
+ Before processing the command, save the previous state.
+ */
+ char *pos;
+ pos= strmake(saved_host, mi->host, HOSTNAME_LENGTH);
+ pos= '\0';
+ saved_port= mi->port;
+ pos= strmake(saved_log_name, mi->master_log_name, FN_REFLEN - 1);
+ pos= '\0';
+ saved_log_pos= mi->master_log_pos;
+
+ /*
If the user specified host or port without binlog or position,
reset binlog's name to FIRST and position to 4.
*/
@@ -1586,6 +1601,15 @@ bool change_master(THD* thd, Master_info* mi)
/* Clear the errors, for a clean start */
mi->rli.clear_error();
mi->rli.clear_until_condition();
+
+ sql_print_information("'CHANGE MASTER TO executed'. "
+ "Previous state master_host='%s', master_port='%u', master_log_file='%s', "
+ "master_log_pos='%ld'. "
+ "New state master_host='%s', master_port='%u', master_log_file='%s', "
+ "master_log_pos='%ld'.", saved_host, saved_port, saved_log_name,
+ (ulong) saved_log_pos, mi->host, mi->port, mi->master_log_name,
+ (ulong) mi->master_log_pos);
+
/*
If we don't write new coordinates to disk now, then old will remain in
relay-log.info until START SLAVE is issued; but if mysqld is shutdown
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index d126d0e4ec6..8112bbba267 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1126,9 +1126,8 @@ JOIN::optimize()
}
}
- if (conds &&!outer_join && const_table_map != found_const_table_map &&
- (select_options & SELECT_DESCRIBE) &&
- select_lex->master_unit() == &thd->lex->unit) // upper level SELECT
+ if (conds && const_table_map != found_const_table_map &&
+ (select_options & SELECT_DESCRIBE))
{
conds=new Item_int((longlong) 0,1); // Always false
}
@@ -1145,13 +1144,13 @@ JOIN::optimize()
elements may be lost during further having
condition transformation in JOIN::exec.
*/
- if (having && !having->with_sum_func)
+ if (having && const_table_map)
{
- COND *const_cond= make_cond_for_table(having, const_table_map, 0);
- DBUG_EXECUTE("where", print_where(const_cond, "const_having_cond",
- QT_ORDINARY););
- if (const_cond && !const_cond->val_int())
+ having->update_used_tables();
+ having= remove_eq_conds(thd, having, &having_value);
+ if (having_value == Item::COND_FALSE)
{
+ having= new Item_int((longlong) 0,1);
zero_result_cause= "Impossible HAVING noticed after reading const tables";
error= 0;
DBUG_RETURN(0);
@@ -3006,8 +3005,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
s->quick=select->quick;
s->needed_reg=select->needed_reg;
select->quick=0;
- if (records == 0 && s->table->reginfo.impossible_range &&
- (s->table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT))
+ if (records == 0 && s->table->reginfo.impossible_range)
{
/*
Impossible WHERE or ON expression
@@ -5162,6 +5160,11 @@ greedy_search(JOIN *join,
if (best_extension_by_limited_search(join, remaining_tables, idx, record_count,
read_time, search_depth, prune_level))
DBUG_RETURN(TRUE);
+ /*
+ 'best_read < DBL_MAX' means that optimizer managed to find
+ some plan and updated 'best_positions' array accordingly.
+ */
+ DBUG_ASSERT(join->best_read < DBL_MAX);
if (size_remain <= search_depth)
{
@@ -8942,8 +8945,14 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
we still make the inner tables dependent on the outer tables.
It would be enough to set dependency only on one outer table
for them. Yet this is really a rare case.
+ Note:
+ RAND_TABLE_BIT mask should not be counted as it
+ prevents update of inner table dependences.
+ For example it might happen if RAND() function
+ is used in JOIN ON clause.
*/
- if (!(prev_table->on_expr->used_tables() & ~prev_used_tables))
+ if (!((prev_table->on_expr->used_tables() & ~RAND_TABLE_BIT) &
+ ~prev_used_tables))
prev_table->dep_tables|= used_tables;
}
}
@@ -9199,6 +9208,46 @@ static bool check_interleaving_with_nj(JOIN_TAB *next_tab)
/**
Nested joins perspective: Remove the last table from the join order.
+ The algorithm is the reciprocal of check_interleaving_with_nj(), hence
+ parent join nest nodes are updated only when the last table in its child
+ node is removed. The ASCII graphic below will clarify.
+
+ %A table nesting such as <tt> t1 x [ ( t2 x t3 ) x ( t4 x t5 ) ] </tt>is
+ represented by the below join nest tree.
+
+ @verbatim
+ NJ1
+ _/ / \
+ _/ / NJ2
+ _/ / / \
+ / / / \
+ t1 x [ (t2 x t3) x (t4 x t5) ]
+ @endverbatim
+
+ At the point in time when check_interleaving_with_nj() adds the table t5 to
+ the query execution plan, QEP, it also directs the node named NJ2 to mark
+ the table as covered. NJ2 does so by incrementing its @c counter
+ member. Since all of NJ2's tables are now covered by the QEP, the algorithm
+ proceeds up the tree to NJ1, incrementing its counter as well. All join
+ nests are now completely covered by the QEP.
+
+ restore_prev_nj_state() does the above in reverse. As seen above, the node
+ NJ1 contains the nodes t2, t3, and NJ2. Its counter being equal to 3 means
+ that the plan covers t2, t3, and NJ2, @e and that the sub-plan (t4 x t5)
+ completely covers NJ2. The removal of t5 from the partial plan will first
+ decrement NJ2's counter to 1. It will then detect that NJ2 went from being
+ completely to partially covered, and hence the algorithm must continue
+ upwards to NJ1 and decrement its counter to 2. %A subsequent removal of t4
+ will however not influence NJ1 since it did not un-cover the last table in
+ NJ2.
+
+ SYNOPSIS
+ restore_prev_nj_state()
+ last join table to remove, it is assumed to be the last in current
+ partial join order.
+
+ DESCRIPTION
+
Remove the last table from the partial join order and update the nested
joins counters and join->cur_embedding_map. It is ok to call this
function for the first table in join order (for which
@@ -9212,19 +9261,20 @@ static void restore_prev_nj_state(JOIN_TAB *last)
{
TABLE_LIST *last_emb= last->table->pos_in_table_list->embedding;
JOIN *join= last->join;
- while (last_emb)
+ for (;last_emb != NULL; last_emb= last_emb->embedding)
{
- if (!(--last_emb->nested_join->counter))
- join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
- else if (last_emb->nested_join->join_list.elements-1 ==
- last_emb->nested_join->counter)
- {
- join->cur_embedding_map|= last_emb->nested_join->nj_map;
- break;
- }
- else
+ NESTED_JOIN *nest= last_emb->nested_join;
+ DBUG_ASSERT(nest->counter > 0);
+
+ bool was_fully_covered= nest->is_fully_covered();
+
+ if (--nest->counter == 0)
+ join->cur_embedding_map&= ~nest->nj_map;
+
+ if (!was_fully_covered)
break;
- last_emb= last_emb->embedding;
+
+ join->cur_embedding_map|= nest->nj_map;
}
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 00a507f0e47..dda434a557a 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -18,6 +18,7 @@
#include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */
#include "sql_priv.h"
+#include "debug_sync.h"
#include "unireg.h"
#include "sql_acl.h" // fill_schema_*_privileges
#include "sql_select.h" // For select_describe
@@ -49,7 +50,8 @@
#include "event_data_objects.h"
#endif
#include <my_dir.h>
-#include "lock.h" // MYSQL_LOCK_IGNORE_FLUSH
+#include "debug_sync.h"
+#include "lock.h" // MYSQL_OPEN_IGNORE_FLUSH
#define STR_OR_NIL(S) ((S) ? (S) : "<nil>")
@@ -1914,6 +1916,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
mysql_mutex_unlock(&mysys_var->mutex);
/* INFO */
+ /* Lock THD mutex that protects its data when looking at it. */
+ mysql_mutex_lock(&tmp->LOCK_thd_data);
if (tmp->query())
{
table->field[7]->store(tmp->query(),
@@ -1921,6 +1925,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
tmp->query_length()), cs);
table->field[7]->set_notnull();
}
+ mysql_mutex_unlock(&tmp->LOCK_thd_data);
if (schema_table_store_record(thd, table))
{
@@ -3292,12 +3297,17 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables,
goto end_share;
}
+ if (!open_table_from_share(thd, share, table_name->str, 0,
+ (EXTRA_RECORD | OPEN_FRM_FILE_ONLY),
+ thd->open_options, &tbl, FALSE))
{
tbl.s= share;
table_list.table= &tbl;
table_list.view= (LEX*) share->is_view;
res= schema_table->process_table(thd, &table_list, table,
res, db_name, table_name);
+ free_root(&tbl.mem_root, MYF(0));
+ my_free((char*) tbl.alias, MYF(MY_ALLOW_ZERO_PTR));
}
end_share:
@@ -3540,6 +3550,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
lex->sql_command= SQLCOM_SHOW_FIELDS;
show_table_list->i_s_requested_object=
schema_table->i_s_requested_object;
+ DEBUG_SYNC(thd, "before_open_in_get_all_tables");
res= open_normal_and_derived_tables(thd, show_table_list,
(MYSQL_OPEN_IGNORE_FLUSH |
MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL |
@@ -4024,7 +4035,6 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
CHARSET_INFO *cs= system_charset_info;
TABLE *show_table;
- TABLE_SHARE *show_table_share;
Field **ptr, *field, *timestamp_field;
int count;
DBUG_ENTER("get_schema_column_record");
@@ -4047,37 +4057,11 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
}
show_table= tables->table;
- show_table_share= show_table->s;
count= 0;
-
- if (tables->view || tables->schema_table)
- {
- ptr= show_table->field;
- timestamp_field= show_table->timestamp_field;
- show_table->use_all_columns(); // Required for default
- }
- else
- {
- ptr= show_table_share->field;
- timestamp_field= show_table_share->timestamp_field;
- /*
- read_set may be inited in case of
- temporary table
- */
- if (!show_table->read_set)
- {
- /* to satisfy 'field->val_str' ASSERTs */
- uchar *bitmaps;
- uint bitmap_size= show_table_share->column_bitmap_size;
- if (!(bitmaps= (uchar*) alloc_root(thd->mem_root, bitmap_size)))
- DBUG_RETURN(0);
- bitmap_init(&show_table->def_read_set,
- (my_bitmap_map*) bitmaps, show_table_share->fields, FALSE);
- bitmap_set_all(&show_table->def_read_set);
- show_table->read_set= &show_table->def_read_set;
- }
- bitmap_set_all(show_table->read_set);
- }
+ ptr= show_table->field;
+ timestamp_field= show_table->timestamp_field;
+ show_table->use_all_columns(); // Required for default
+ restore_record(show_table, s->default_values);
for (; (field= *ptr) ; ptr++)
{
@@ -4086,9 +4070,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
String type(tmp,sizeof(tmp), system_charset_info);
char *end;
- /* to satisfy 'field->val_str' ASSERTs */
- field->table= show_table;
- show_table->in_use= thd;
+ DEBUG_SYNC(thd, "get_schema_column");
if (wild && wild[0] &&
wild_case_compare(system_charset_info, field->field_name,wild))
@@ -4347,6 +4329,15 @@ int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond)
}
+static inline void copy_field_as_string(Field *to_field, Field *from_field)
+{
+ char buff[MAX_FIELD_WIDTH];
+ String tmp_str(buff, sizeof(buff), system_charset_info);
+ from_field->val_str(&tmp_str);
+ to_field->store(tmp_str.ptr(), tmp_str.length(), system_charset_info);
+}
+
+
/**
@brief Store record into I_S.PARAMETERS table
@@ -4513,18 +4504,26 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
const char *wild, bool full_access, const char *sp_user)
{
- String tmp_string;
- String sp_db, sp_name, definer;
MYSQL_TIME time;
LEX *lex= thd->lex;
CHARSET_INFO *cs= system_charset_info;
- get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_DB], &sp_db);
- get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_NAME], &sp_name);
- get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_DEFINER],&definer);
+ char sp_db_buff[NAME_LEN + 1], sp_name_buff[NAME_LEN + 1],
+ definer_buff[USERNAME_LENGTH + HOSTNAME_LENGTH + 2],
+ returns_buff[MAX_FIELD_WIDTH];
+
+ String sp_db(sp_db_buff, sizeof(sp_db_buff), cs);
+ String sp_name(sp_name_buff, sizeof(sp_name_buff), cs);
+ String definer(definer_buff, sizeof(definer_buff), cs);
+ String returns(returns_buff, sizeof(returns_buff), cs);
+
+ proc_table->field[MYSQL_PROC_FIELD_DB]->val_str(&sp_db);
+ proc_table->field[MYSQL_PROC_FIELD_NAME]->val_str(&sp_name);
+ proc_table->field[MYSQL_PROC_FIELD_DEFINER]->val_str(&definer);
+
if (!full_access)
- full_access= !strcmp(sp_user, definer.ptr());
- if (!full_access &&
- check_some_routine_access(thd, sp_db.ptr(), sp_name.ptr(),
+ full_access= !strcmp(sp_user, definer.c_ptr_safe());
+ if (!full_access &&
+ check_some_routine_access(thd, sp_db.c_ptr_safe(), sp_name.c_ptr_safe(),
proc_table->field[MYSQL_PROC_MYSQL_TYPE]->
val_int() == TYPE_ENUM_PROCEDURE))
return 0;
@@ -4538,32 +4537,30 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
(sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0)
{
restore_record(table, s->default_values);
- if (!wild || !wild[0] || !wild_compare(sp_name.ptr(), wild, 0))
+ if (!wild || !wild[0] || !wild_compare(sp_name.c_ptr_safe(), wild, 0))
{
int enum_idx= (int) proc_table->field[MYSQL_PROC_FIELD_ACCESS]->val_int();
table->field[3]->store(sp_name.ptr(), sp_name.length(), cs);
- get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME],
- &tmp_string);
- table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs);
+
+ copy_field_as_string(table->field[0],
+ proc_table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME]);
table->field[1]->store(STRING_WITH_LEN("def"), cs);
table->field[2]->store(sp_db.ptr(), sp_db.length(), cs);
- get_field(thd->mem_root, proc_table->field[MYSQL_PROC_MYSQL_TYPE],
- &tmp_string);
- table->field[4]->store(tmp_string.ptr(), tmp_string.length(), cs);
+ copy_field_as_string(table->field[4],
+ proc_table->field[MYSQL_PROC_MYSQL_TYPE]);
+
if (proc_table->field[MYSQL_PROC_MYSQL_TYPE]->val_int() ==
TYPE_ENUM_FUNCTION)
{
sp_head *sp;
bool free_sp_head;
- get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_RETURNS],
- &tmp_string);
-
+ proc_table->field[MYSQL_PROC_FIELD_RETURNS]->val_str(&returns);
sp= sp_load_for_information_schema(thd, proc_table, &sp_db, &sp_name,
(ulong) proc_table->
field[MYSQL_PROC_FIELD_SQL_MODE]->
val_int(),
TYPE_ENUM_FUNCTION,
- tmp_string.c_ptr_safe(),
+ returns.c_ptr_safe(),
"", &free_sp_head);
if (sp)
@@ -4594,24 +4591,19 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
if (full_access)
{
- get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_BODY_UTF8],
- &tmp_string);
- table->field[14]->store(tmp_string.ptr(), tmp_string.length(), cs);
+ copy_field_as_string(table->field[14],
+ proc_table->field[MYSQL_PROC_FIELD_BODY_UTF8]);
table->field[14]->set_notnull();
}
table->field[13]->store(STRING_WITH_LEN("SQL"), cs);
table->field[17]->store(STRING_WITH_LEN("SQL"), cs);
-
-
- get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_DETERMINISTIC],
- &tmp_string);
- table->field[18]->store(tmp_string.ptr(), tmp_string.length(), cs);
+ copy_field_as_string(table->field[18],
+ proc_table->field[MYSQL_PROC_FIELD_DETERMINISTIC]);
table->field[19]->store(sp_data_access_name[enum_idx].str,
sp_data_access_name[enum_idx].length , cs);
+ copy_field_as_string(table->field[21],
+ proc_table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]);
- get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_SECURITY_TYPE],
- &tmp_string);
- table->field[21]->store(tmp_string.ptr(), tmp_string.length(), cs);
bzero((char *)&time, sizeof(time));
((Field_timestamp *) proc_table->field[MYSQL_PROC_FIELD_CREATED])->
get_time(&time);
@@ -4620,29 +4612,20 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
((Field_timestamp *) proc_table->field[MYSQL_PROC_FIELD_MODIFIED])->
get_time(&time);
table->field[23]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ copy_field_as_string(table->field[24],
+ proc_table->field[MYSQL_PROC_FIELD_SQL_MODE]);
+ copy_field_as_string(table->field[25],
+ proc_table->field[MYSQL_PROC_FIELD_COMMENT]);
- get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_SQL_MODE],
- &tmp_string);
- table->field[24]->store(tmp_string.ptr(), tmp_string.length(), cs);
-
- get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_COMMENT],
- &tmp_string);
- table->field[25]->store(tmp_string.ptr(), tmp_string.length(), cs);
table->field[26]->store(definer.ptr(), definer.length(), cs);
-
- get_field(thd->mem_root,
- proc_table->field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT],
- &tmp_string);
- table->field[27]->store(tmp_string.ptr(), tmp_string.length(), cs);
-
- get_field(thd->mem_root,
- proc_table->field[ MYSQL_PROC_FIELD_COLLATION_CONNECTION],
- &tmp_string);
- table->field[28]->store(tmp_string.ptr(), tmp_string.length(), cs);
-
- get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_DB_COLLATION],
- &tmp_string);
- table->field[29]->store(tmp_string.ptr(), tmp_string.length(), cs);
+ copy_field_as_string(table->field[27],
+ proc_table->
+ field[MYSQL_PROC_FIELD_CHARACTER_SET_CLIENT]);
+ copy_field_as_string(table->field[28],
+ proc_table->
+ field[MYSQL_PROC_FIELD_COLLATION_CONNECTION]);
+ copy_field_as_string(table->field[29],
+ proc_table->field[MYSQL_PROC_FIELD_DB_COLLATION]);
return schema_table_store_record(thd, table);
}
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 9fbc06b7529..762eebba031 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -24,13 +24,6 @@
#include <m_string.h>
#include <m_ctype.h>
#include <mysql_com.h>
-/*
- The following extern declarations are ok as these are interface functions
- required by the string function
-*/
-
-extern uchar* sql_alloc(unsigned size);
-extern void sql_element_free(void *ptr);
#include "sql_string.h"
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index f8d99d87228..5052e29ac30 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -426,6 +426,25 @@ uint filename_to_tablename(const char *from, char *to, uint to_length)
/**
+ Check if given string begins with "#mysql50#" prefix
+
+ @param name string to check cut
+
+ @retval
+ FALSE no prefix found
+ @retval
+ TRUE prefix found
+*/
+
+bool check_mysql50_prefix(const char *name)
+{
+ return (name[0] == '#' &&
+ !strncmp(name, MYSQL50_TABLE_NAME_PREFIX,
+ MYSQL50_TABLE_NAME_PREFIX_LENGTH));
+}
+
+
+/**
Check if given string begins with "#mysql50#" prefix, cut it if so.
@param from string to check and cut
@@ -440,9 +459,7 @@ uint filename_to_tablename(const char *from, char *to, uint to_length)
uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length)
{
- if (from[0] == '#' &&
- !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
- MYSQL50_TABLE_NAME_PREFIX_LENGTH))
+ if (check_mysql50_prefix(from))
return (uint) (strmake(to, from + MYSQL50_TABLE_NAME_PREFIX_LENGTH,
to_length - 1) - to);
return 0;
@@ -469,7 +486,21 @@ uint tablename_to_filename(const char *from, char *to, uint to_length)
DBUG_PRINT("enter", ("from '%s'", from));
if ((length= check_n_cut_mysql50_prefix(from, to, to_length)))
+ {
+ /*
+ Check if the name supplied is a valid mysql 5.0 name and
+ make the name a zero length string if it's not.
+ Note that just returning zero length is not enough :
+ a lot of places don't check the return value and expect
+ a zero terminated string.
+ */
+ if (check_table_name(to, length, TRUE))
+ {
+ to[0]= 0;
+ length= 0;
+ }
DBUG_RETURN(length);
+ }
length= strconvert(system_charset_info, from,
&my_charset_filename, to, to_length, &errors);
if (check_if_legal_tablename(to) &&
@@ -6939,7 +6970,14 @@ view_err:
&index_add_buffer, &index_add_count,
&candidate_key_count))
goto err;
-
+
+ DBUG_EXECUTE_IF("alter_table_only_metadata_change", {
+ if (need_copy_table_res != ALTER_TABLE_METADATA_ONLY)
+ goto err; });
+ DBUG_EXECUTE_IF("alter_table_only_index_change", {
+ if (need_copy_table_res != ALTER_TABLE_INDEX_CHANGED)
+ goto err; });
+
if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
need_copy_table= need_copy_table_res;
}
diff --git a/sql/sql_table.h b/sql/sql_table.h
index 3114876f5ed..40b24605bd6 100644
--- a/sql/sql_table.h
+++ b/sql/sql_table.h
@@ -126,6 +126,7 @@ enum enum_explain_filename_mode
uint filename_to_tablename(const char *from, char *to, uint to_length);
uint tablename_to_filename(const char *from, char *to, uint to_length);
uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length);
+bool check_mysql50_prefix(const char *name);
uint build_table_filename(char *buff, size_t bufflen, const char *db,
const char *table, const char *ext, uint flags);
uint build_table_shadow_filename(char *buff, size_t bufflen,
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 300ca1098fb..9adfe896c73 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -436,6 +436,7 @@ int mysql_update(THD *thd,
{
goto err;
}
+ thd->examined_row_count+= examined_rows;
/*
Filesort has already found and selected the rows we want to update,
so we don't need the where clause
@@ -482,6 +483,7 @@ int mysql_update(THD *thd,
while (!(error=info.read_record(&info)) && !thd->killed)
{
+ thd->examined_row_count++;
if (!(select && select->skip_record()))
{
if (table->file->was_semi_consistent_read())
@@ -588,6 +590,7 @@ int mysql_update(THD *thd,
while (!(error=info.read_record(&info)) && !thd->killed)
{
+ thd->examined_row_count++;
if (!(select && select->skip_record()))
{
if (table->file->was_semi_consistent_read())
@@ -1336,6 +1339,16 @@ int multi_update::prepare(List<Item> &not_used_values,
{
table->read_set= &table->def_read_set;
bitmap_union(table->read_set, &table->tmp_set);
+ /*
+ If a timestamp field settable on UPDATE is present then to avoid wrong
+ update force the table handler to retrieve write-only fields to be able
+ to compare records and detect data change.
+ */
+ if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ &&
+ table->timestamp_field &&
+ (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
+ table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
+ bitmap_union(table->read_set, table->write_set);
}
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index aa336f3c072..9f20a4ccf71 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -6670,7 +6670,7 @@ alter_list_item:
{
MYSQL_YYABORT;
}
- if (check_table_name($3->table.str,$3->table.length) ||
+ if (check_table_name($3->table.str,$3->table.length, FALSE) ||
($3->db.str && check_db_name(&$3->db)))
{
my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str);
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index aeb9dda3a8b..5c1a44ba844 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -1595,6 +1595,13 @@ static Sys_var_mybool Sys_skip_networking(
READ_ONLY GLOBAL_VAR(opt_disable_networking), CMD_LINE(OPT_ARG),
DEFAULT(FALSE));
+static Sys_var_mybool Sys_skip_name_resolve(
+ "skip_name_resolve",
+ "Don't resolve hostnames. All hostnames are IP's or 'localhost'.",
+ READ_ONLY GLOBAL_VAR(opt_skip_name_resolve),
+ CMD_LINE(OPT_ARG, OPT_SKIP_RESOLVE),
+ DEFAULT(FALSE));
+
static Sys_var_mybool Sys_skip_show_database(
"skip_show_database", "Don't allow 'SHOW DATABASE' commands",
READ_ONLY GLOBAL_VAR(opt_skip_show_db), CMD_LINE(OPT_ARG),
diff --git a/sql/table.cc b/sql/table.cc
index 5ffe1cf17ae..b104c212593 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -311,13 +311,6 @@ TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
share->version= refresh_version;
/*
- This constant is used to mark that no table map version has been
- assigned. No arithmetic is done on the value: it will be
- overwritten with a value taken from MYSQL_BIN_LOG.
- */
- share->table_map_version= ~(ulonglong)0;
-
- /*
Since alloc_table_share() can be called without any locking (for
example, ha_create_table... functions), we do not assign a table
map id here. Instead we assign a value that is not used
@@ -383,11 +376,6 @@ void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
share->path.length= share->normalized_path.length= strlen(path);
share->frm_version= FRM_VER_TRUE_VARCHAR;
- /*
- Temporary tables are not replicated, but we set up these fields
- anyway to be able to catch errors.
- */
- share->table_map_version= ~(ulonglong)0;
share->cached_row_logging_check= -1;
/*
@@ -500,6 +488,26 @@ inline bool is_system_table_name(const char *name, uint length)
}
+/**
+ Check if a string contains path elements
+*/
+
+static inline bool has_disabled_path_chars(const char *str)
+{
+ for (; *str; str++)
+ switch (*str)
+ {
+ case FN_EXTCHAR:
+ case '/':
+ case '\\':
+ case '~':
+ case '@':
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
/*
Read table definition from a binary / text based .frm file
@@ -556,7 +564,8 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags)
This kind of tables must have been opened only by the
mysql_file_open() above.
*/
- if (strchr(share->table_name.str, '@') ||
+ if (has_disabled_path_chars(share->table_name.str) ||
+ has_disabled_path_chars(share->db.str) ||
!strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
!strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX,
@@ -2740,35 +2749,21 @@ bool check_db_name(LEX_STRING *org_name)
{
char *name= org_name->str;
uint name_length= org_name->length;
+ bool check_for_path_chars;
if (!name_length || name_length > NAME_LEN)
return 1;
+ if ((check_for_path_chars= check_mysql50_prefix(name)))
+ {
+ name+= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
+ name_length-= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
+ }
+
if (lower_case_table_names && name != any_db)
my_casedn_str(files_charset_info, name);
-#if defined(USE_MB) && defined(USE_MB_IDENT)
- if (use_mb(system_charset_info))
- {
- name_length= 0;
- bool last_char_is_space= TRUE;
- char *end= name + org_name->length;
- while (name < end)
- {
- int len;
- last_char_is_space= my_isspace(system_charset_info, *name);
- len= my_ismbchar(system_charset_info, name, end);
- if (!len)
- len= 1;
- name+= len;
- name_length++;
- }
- return (last_char_is_space || name_length > NAME_CHAR_LEN);
- }
- else
-#endif
- return ((org_name->str[org_name->length - 1] != ' ') ||
- (name_length > NAME_CHAR_LEN)); /* purecov: inspected */
+ return check_table_name(name, name_length, check_for_path_chars);
}
@@ -2778,8 +2773,7 @@ bool check_db_name(LEX_STRING *org_name)
returns 1 on error
*/
-
-bool check_table_name(const char *name, uint length)
+bool check_table_name(const char *name, uint length, bool check_for_path_chars)
{
uint name_length= 0; // name length in symbols
const char *end= name+length;
@@ -2807,6 +2801,9 @@ bool check_table_name(const char *name, uint length)
}
}
#endif
+ if (check_for_path_chars &&
+ (*name == '/' || *name == '\\' || *name == '~' || *name == FN_EXTCHAR))
+ return 1;
name++;
name_length++;
}
diff --git a/sql/table.h b/sql/table.h
index af357807add..87044ac769b 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -630,7 +630,6 @@ struct TABLE_SHARE
bool crashed;
bool is_view;
ulong table_map_id; /* for row-based replication */
- ulonglong table_map_version;
/*
Cache for row-based replication table share checks that does not
@@ -1913,7 +1912,11 @@ typedef struct st_nested_join
List<TABLE_LIST> join_list; /* list of elements in the nested join */
table_map used_tables; /* bitmap of tables in the nested join */
table_map not_null_tables; /* tables that rejects nulls */
- struct st_join_table *first_nested;/* the first nested table in the plan */
+ /**
+ Used for pointing out the first table in the plan being covered by this
+ join nest. It is used exclusively within make_outerjoin_info().
+ */
+ struct st_join_table *first_nested;
/*
Used to count tables in the nested join in 2 isolated places:
1. In make_outerjoin_info().
@@ -1923,6 +1926,15 @@ typedef struct st_nested_join
*/
uint counter;
nested_join_map nj_map; /* Bit used to identify this nested join*/
+ /**
+ True if this join nest node is completely covered by the query execution
+ plan. This means two things.
+
+ 1. All tables on its @c join_list are covered by the plan.
+
+ 2. All child join nest nodes are fully covered.
+ */
+ bool is_fully_covered() const { return join_list.elements == counter; }
} NESTED_JOIN;
@@ -2026,7 +2038,7 @@ void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form);
bool check_and_convert_db_name(LEX_STRING *db, bool preserve_lettercase);
bool check_db_name(LEX_STRING *db);
bool check_column_name(const char *name);
-bool check_table_name(const char *name, uint length);
+bool check_table_name(const char *name, uint length, bool check_for_path_chars);
int rename_file_ext(const char * from,const char * to,const char * ext);
char *get_field(MEM_ROOT *mem, Field *field);
bool get_field(MEM_ROOT *mem, Field *field, class String *res);
diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc
index 638f3bbb9f1..7696f28081d 100644
--- a/sql/thr_malloc.cc
+++ b/sql/thr_malloc.cc
@@ -109,10 +109,6 @@ void* sql_memdup(const void *ptr, size_t len)
return pos;
}
-void sql_element_free(void *ptr __attribute__((unused)))
-{} /* purecov: deadcode */
-
-
char *sql_strmake_with_convert(const char *str, size_t arg_length,
CHARSET_INFO *from_cs,
diff --git a/sql/thr_malloc.h b/sql/thr_malloc.h
index a655884b8b4..6b372a285a2 100644
--- a/sql/thr_malloc.h
+++ b/sql/thr_malloc.h
@@ -27,7 +27,6 @@ void *sql_calloc(size_t);
char *sql_strdup(const char *str);
char *sql_strmake(const char *str, size_t len);
void *sql_memdup(const void * ptr, size_t size);
-void sql_element_free(void *ptr);
char *sql_strmake_with_convert(const char *str, size_t arg_length,
CHARSET_INFO *from_cs,
size_t max_res_length,
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index e63ec33465e..2bcfc3ff672 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -1325,13 +1325,12 @@ end:
/*
This method repairs the meta file. It does this by walking the datafile and
- rewriting the meta file. Currently it does this by calling optimize with
- the extended flag.
+ rewriting the meta file. If EXTENDED repair is requested, we attempt to
+ recover as much data as possible.
*/
int ha_archive::repair(THD* thd, HA_CHECK_OPT* check_opt)
{
DBUG_ENTER("ha_archive::repair");
- check_opt->flags= T_EXTEND;
int rc= optimize(thd, check_opt);
if (rc)
@@ -1425,7 +1424,14 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
DBUG_PRINT("ha_archive", ("recovered %llu archive rows",
(unsigned long long)share->rows_recorded));
- if (rc && rc != HA_ERR_END_OF_FILE)
+ /*
+ If REPAIR ... EXTENDED is requested, try to recover as much data
+ from data file as possible. In this case if we failed to read a
+ record, we assume EOF. This allows massive data loss, but we can
+ hardly do more with broken zlib stream. And this is the only way
+ to restore at least what is still recoverable.
+ */
+ if (rc && rc != HA_ERR_END_OF_FILE && !(check_opt->flags & T_EXTEND))
goto error;
}
diff --git a/storage/myisam/CMakeLists.txt b/storage/myisam/CMakeLists.txt
index 4b7007055d8..b057a62a6dd 100755
--- a/storage/myisam/CMakeLists.txt
+++ b/storage/myisam/CMakeLists.txt
@@ -13,7 +13,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-SET(MYISAM_SOURCES ft_boolean_search.c ft_nlq_search.c ft_parser.c ft_static.c ft_stem.c
+SET(MYISAM_SOURCES ft_boolean_search.c ft_nlq_search.c ft_parser.c ft_static.c
ha_myisam.cc
ft_stopwords.c ft_update.c mi_cache.c mi_changed.c mi_check.c
mi_checksum.c mi_close.c mi_create.c mi_dbug.c mi_delete.c
@@ -23,7 +23,7 @@ SET(MYISAM_SOURCES ft_boolean_search.c ft_nlq_search.c ft_parser.c ft_static.c
mi_rfirst.c mi_rlast.c mi_rnext.c mi_rnext_same.c mi_rprev.c mi_rrnd.c
mi_rsame.c mi_rsamepos.c mi_scan.c mi_search.c mi_static.c mi_statrec.c
mi_unique.c mi_update.c mi_write.c rt_index.c rt_key.c rt_mbr.c
- rt_split.c sort.c sp_key.c ft_eval.h mi_extrafunc.h myisamdef.h
+ rt_split.c sort.c sp_key.c mi_extrafunc.h myisamdef.h
rt_index.h mi_rkey.c)
MYSQL_ADD_PLUGIN(myisam ${MYISAM_SOURCES}
diff --git a/storage/myisam/Makefile.am b/storage/myisam/Makefile.am
index d0f7f5b86dc..5c3370ac6c5 100644
--- a/storage/myisam/Makefile.am
+++ b/storage/myisam/Makefile.am
@@ -27,7 +27,7 @@ LDADD =
DEFS = @DEFS@
-EXTRA_DIST = mi_test_all.sh mi_test_all.res ft_stem.c CMakeLists.txt plug.in
+EXTRA_DIST = mi_test_all.sh mi_test_all.res CMakeLists.txt plug.in
pkgdata_DATA = mi_test_all mi_test_all.res
pkglib_LIBRARIES = libmyisam.a
@@ -47,10 +47,9 @@ myisampack_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
$(top_builddir)/mysys/libmysys.a \
$(top_builddir)/dbug/libdbug.a \
$(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
-noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 rt_test sp_test #ft_test1 ft_eval
+noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 rt_test sp_test
noinst_HEADERS = myisamdef.h rt_index.h rt_key.h rt_mbr.h sp_defs.h \
- fulltext.h ftdefs.h ft_test1.h ft_eval.h \
- ha_myisam.h mi_extrafunc.h
+ fulltext.h ftdefs.h ha_myisam.h mi_extrafunc.h
mi_test1_DEPENDENCIES= $(LIBRARIES)
mi_test1_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
$(top_builddir)/mysys/libmysys.a \
@@ -66,8 +65,6 @@ mi_test3_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
$(top_builddir)/mysys/libmysys.a \
$(top_builddir)/dbug/libdbug.a \
$(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
-#ft_test1_DEPENDENCIES= $(LIBRARIES)
-#ft_eval_DEPENDENCIES= $(LIBRARIES)
myisam_ftdump_DEPENDENCIES= $(LIBRARIES)
myisam_ftdump_LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
$(top_builddir)/mysys/libmysys.a \
diff --git a/storage/myisam/ft_eval.c b/storage/myisam/ft_eval.c
deleted file mode 100644
index f4faabe7919..00000000000
--- a/storage/myisam/ft_eval.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/* Copyright (C) 2000-2002 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Written by Sergei A. Golubchik, who has a shared copyright to this code
- added support for long options (my_getopt) 22.5.2002 by Jani Tolonen */
-
-#include "ftdefs.h"
-#include "ft_eval.h"
-#include <stdarg.h>
-#include <my_getopt.h>
-
-static void print_error(int exit_code, const char *fmt,...);
-static void get_options(int argc, char *argv[]);
-static int create_record(char *pos, FILE *file);
-static void usage();
-
-static struct my_option my_long_options[] =
-{
- {"", 's', "", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"", 'q', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"", 'S', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"", '#', "", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"", 'V', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"", '?', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"", 'h', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
-};
-
-int main(int argc, char *argv[])
-{
- MI_INFO *file;
- int i,j;
-
- MY_INIT(argv[0]);
- get_options(argc,argv);
- bzero((char*)recinfo,sizeof(recinfo));
-
- /* First define 2 columns */
- recinfo[0].type=FIELD_SKIP_ENDSPACE;
- recinfo[0].length=docid_length;
- recinfo[1].type=FIELD_BLOB;
- recinfo[1].length= 4+portable_sizeof_char_ptr;
-
- /* Define a key over the first column */
- keyinfo[0].seg=keyseg;
- keyinfo[0].keysegs=1;
- keyinfo[0].block_length= 0; /* Default block length */
- keyinfo[0].seg[0].type= HA_KEYTYPE_TEXT;
- keyinfo[0].seg[0].flag= HA_BLOB_PART;
- keyinfo[0].seg[0].start=recinfo[0].length;
- keyinfo[0].seg[0].length=key_length;
- keyinfo[0].seg[0].null_bit=0;
- keyinfo[0].seg[0].null_pos=0;
- keyinfo[0].seg[0].bit_start=4;
- keyinfo[0].seg[0].language=MY_CHARSET_CURRENT;
- keyinfo[0].flag = HA_FULLTEXT;
-
- if (!silent)
- printf("- Creating isam-file\n");
- if (mi_create(filename,1,keyinfo,2,recinfo,0,NULL,(MI_CREATE_INFO*) 0,0))
- goto err;
- if (!(file=mi_open(filename,2,0)))
- goto err;
- if (!silent)
- printf("Initializing stopwords\n");
- ft_init_stopwords(stopwordlist);
-
- if (!silent)
- printf("- Writing key:s\n");
-
- my_errno=0;
- i=0;
- while (create_record(record,df))
- {
- error=mi_write(file,record);
- if (error)
- printf("I= %2d mi_write: %d errno: %d\n",i,error,my_errno);
- i++;
- }
- fclose(df);
-
- if (mi_close(file)) goto err;
- if (!silent)
- printf("- Reopening file\n");
- if (!(file=mi_open(filename,2,0))) goto err;
- if (!silent)
- printf("- Reading rows with key\n");
- for (i=1;create_record(record,qf);i++)
- {
- FT_DOCLIST *result;
- double w;
- int t, err;
-
- result=ft_nlq_init_search(file,0,blob_record,(uint) strlen(blob_record),1);
- if (!result)
- {
- printf("Query %d failed with errno %3d\n",i,my_errno);
- goto err;
- }
- if (!silent)
- printf("Query %d. Found: %d.\n",i,result->ndocs);
- for (j=0;(err=ft_nlq_read_next(result, read_record))==0;j++)
- {
- t=uint2korr(read_record);
- w=ft_nlq_get_relevance(result);
- printf("%d %.*s %f\n",i,t,read_record+2,w);
- }
- if (err != HA_ERR_END_OF_FILE)
- {
- printf("ft_read_next %d failed with errno %3d\n",j,my_errno);
- goto err;
- }
- ft_nlq_close_search(result);
- }
-
- if (mi_close(file)) goto err;
- my_end(MY_CHECK_ERROR);
-
- return (0);
-
- err:
- printf("got error: %3d when using myisam-database\n",my_errno);
- return 1; /* skip warning */
-
-}
-
-
-static my_bool
-get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
- char *argument)
-{
- switch (optid) {
- case 's':
- if (stopwordlist && stopwordlist != ft_precompiled_stopwords)
- break;
- {
- FILE *f; char s[HA_FT_MAXLEN]; int i=0,n=SWL_INIT;
-
- if (!(stopwordlist=(const char**) malloc(n*sizeof(char *))))
- print_error(1,"malloc(%d)",n*sizeof(char *));
- if (!(f=fopen(argument,"r")))
- print_error(1,"fopen(%s)",argument);
- while (!feof(f))
- {
- if (!(fgets(s,HA_FT_MAXLEN,f)))
- print_error(1,"fgets(s,%d,%s)",HA_FT_MAXLEN,argument);
- if (!(stopwordlist[i++]=strdup(s)))
- print_error(1,"strdup(%s)",s);
- if (i >= n)
- {
- n+=SWL_PLUS;
- if (!(stopwordlist=(const char**) realloc((char*) stopwordlist,
- n*sizeof(char *))))
- print_error(1,"realloc(%d)",n*sizeof(char *));
- }
- }
- fclose(f);
- stopwordlist[i]=NULL;
- break;
- }
- case 'q': silent=1; break;
- case 'S': if (stopwordlist==ft_precompiled_stopwords) stopwordlist=NULL; break;
- case '#':
- DBUG_PUSH (argument);
- break;
- case 'V':
- case '?':
- case 'h':
- usage();
- exit(1);
- }
- return 0;
-}
-
-
-static void get_options(int argc, char *argv[])
-{
- int ho_error;
-
- if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
- exit(ho_error);
-
- if (!(d_file=argv[optind])) print_error(1,"No d_file");
- if (!(df=fopen(d_file,"r")))
- print_error(1,"fopen(%s)",d_file);
- if (!(q_file=argv[optind+1])) print_error(1,"No q_file");
- if (!(qf=fopen(q_file,"r")))
- print_error(1,"fopen(%s)",q_file);
- return;
-} /* get options */
-
-
-static int create_record(char *pos, FILE *file)
-{
- uint tmp; char *ptr;
-
- bzero((char *)pos,MAX_REC_LENGTH);
-
- /* column 1 - VARCHAR */
- if (!(fgets(pos+2,MAX_REC_LENGTH-32,file)))
- {
- if (feof(file))
- return 0;
- else
- print_error(1,"fgets(docid) - 1");
- }
- tmp=(uint) strlen(pos+2)-1;
- int2store(pos,tmp);
- pos+=recinfo[0].length;
-
- /* column 2 - BLOB */
-
- if (!(fgets(blob_record,MAX_BLOB_LENGTH,file)))
- print_error(1,"fgets(docid) - 2");
- tmp=(uint) strlen(blob_record);
- int4store(pos,tmp);
- ptr=blob_record;
- memcpy_fixed(pos+4,&ptr,sizeof(char*));
- return 1;
-}
-
-/* VARARGS */
-
-static void print_error(int exit_code, const char *fmt,...)
-{
- va_list args;
-
- va_start(args,fmt);
- fprintf(stderr,"%s: error: ",my_progname);
- (void) vfprintf(stderr, fmt, args);
- (void) fputc('\n',stderr);
- fflush(stderr);
- va_end(args);
- exit(exit_code);
-}
-
-
-static void usage()
-{
- printf("%s [options]\n", my_progname);
- my_print_help(my_long_options);
- my_print_variables(my_long_options);
-}
diff --git a/storage/myisam/ft_eval.h b/storage/myisam/ft_eval.h
deleted file mode 100644
index 9acc1a60d09..00000000000
--- a/storage/myisam/ft_eval.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & Sergei A. Golubchik
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
-
-const char **stopwordlist=ft_precompiled_stopwords;
-
-#define MAX_REC_LENGTH 128
-#define MAX_BLOB_LENGTH 60000
-char record[MAX_REC_LENGTH], read_record[MAX_REC_LENGTH+MAX_BLOB_LENGTH];
-char blob_record[MAX_BLOB_LENGTH+20*20];
-
-char *filename= (char*) "EVAL";
-
-int silent=0, error=0;
-
-uint key_length=MAX_BLOB_LENGTH,docid_length=32;
-char *d_file, *q_file;
-FILE *df,*qf;
-
-MI_COLUMNDEF recinfo[3];
-MI_KEYDEF keyinfo[2];
-HA_KEYSEG keyseg[10];
-
-#define SWL_INIT 500
-#define SWL_PLUS 50
-
-#define MAX_LINE_LENGTH 128
-char line[MAX_LINE_LENGTH];
diff --git a/storage/myisam/ft_stem.c b/storage/myisam/ft_stem.c
deleted file mode 100644
index dfc132fcfa9..00000000000
--- a/storage/myisam/ft_stem.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright (C) 2000 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
-
-/* mulitingual stem */
diff --git a/storage/myisam/ft_test1.c b/storage/myisam/ft_test1.c
deleted file mode 100644
index b37935a0d7a..00000000000
--- a/storage/myisam/ft_test1.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/* Copyright (C) 2000-2002, 2004 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Written by Sergei A. Golubchik, who has a shared copyright to this code
- added support for long options (my_getopt) 22.5.2002 by Jani Tolonen */
-
-#include "ftdefs.h"
-#include "ft_test1.h"
-#include <my_getopt.h>
-
-static int key_field=FIELD_VARCHAR,extra_field=FIELD_SKIP_ENDSPACE;
-static uint key_length=200,extra_length=50;
-static int key_type=HA_KEYTYPE_TEXT;
-static int verbose=0,silent=0,skip_update=0,
- no_keys=0,no_stopwords=0,no_search=0,no_fulltext=0;
-static int create_flag=0,error=0;
-
-#define MAX_REC_LENGTH 300
-static char record[MAX_REC_LENGTH],read_record[MAX_REC_LENGTH];
-
-static int run_test(const char *filename);
-static void get_options(int argc, char *argv[]);
-static void create_record(char *, int);
-static void usage();
-
-static struct my_option my_long_options[] =
-{
- {"", 'v', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"", '?', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"", 'h', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"", 'V', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"", 'v', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"", 's', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"", 'N', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"", 'S', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"", 'K', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"", 'F', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"", 'U', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"", '#', "", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
- { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
-};
-
-int main(int argc, char *argv[])
-{
- MY_INIT(argv[0]);
-
- get_options(argc,argv);
-
- exit(run_test("FT1"));
-}
-
-static MI_COLUMNDEF recinfo[3];
-static MI_KEYDEF keyinfo[2];
-static HA_KEYSEG keyseg[10];
-
-static int run_test(const char *filename)
-{
- MI_INFO *file;
- int i,j;
- my_off_t pos;
-
- bzero((char*) recinfo,sizeof(recinfo));
-
- /* First define 2 columns */
- recinfo[0].type=extra_field;
- recinfo[0].length= (extra_field == FIELD_BLOB ? 4 + portable_sizeof_char_ptr :
- extra_length);
- if (extra_field == FIELD_VARCHAR)
- recinfo[0].length+= HA_VARCHAR_PACKLENGTH(extra_length);
- recinfo[1].type=key_field;
- recinfo[1].length= (key_field == FIELD_BLOB ? 4+portable_sizeof_char_ptr :
- key_length);
- if (key_field == FIELD_VARCHAR)
- recinfo[1].length+= HA_VARCHAR_PACKLENGTH(key_length);
-
- /* Define a key over the first column */
- keyinfo[0].seg=keyseg;
- keyinfo[0].keysegs=1;
- keyinfo[0].block_length= 0; /* Default block length */
- keyinfo[0].seg[0].type= key_type;
- keyinfo[0].seg[0].flag= (key_field == FIELD_BLOB) ? HA_BLOB_PART:
- (key_field == FIELD_VARCHAR) ? HA_VAR_LENGTH_PART:0;
- keyinfo[0].seg[0].start=recinfo[0].length;
- keyinfo[0].seg[0].length=key_length;
- keyinfo[0].seg[0].null_bit= 0;
- keyinfo[0].seg[0].null_pos=0;
- keyinfo[0].seg[0].language= default_charset_info->number;
- keyinfo[0].flag = (no_fulltext?HA_PACK_KEY:HA_FULLTEXT);
-
- if (!silent)
- printf("- Creating isam-file\n");
- if (mi_create(filename,(no_keys?0:1),keyinfo,2,recinfo,0,NULL,
- (MI_CREATE_INFO*) 0, create_flag))
- goto err;
- if (!(file=mi_open(filename,2,0)))
- goto err;
-
- if (!silent)
- printf("- %s stopwords\n",no_stopwords?"Skipping":"Initializing");
- ft_init_stopwords(no_stopwords?NULL:ft_precompiled_stopwords);
-
- if (!silent)
- printf("- Writing key:s\n");
-
- my_errno=0;
- for (i=NUPD ; i<NDATAS; i++ )
- {
- create_record(record,i);
- error=mi_write(file,record);
- if (verbose || error)
- printf("I= %2d mi_write: %d errno: %d, record: %s\n",
- i,error,my_errno,data[i].f0);
- }
-
- if (!skip_update)
- {
- if (!silent)
- printf("- Updating rows\n");
-
- /* Read through all rows and update them */
- pos=(ha_rows) 0;
- i=0;
- while ((error=mi_rrnd(file,read_record,pos)) == 0)
- {
- create_record(record,NUPD-i-1);
- if (mi_update(file,read_record,record))
- {
- printf("Can't update row: %.*s, error: %d\n",
- keyinfo[0].seg[0].length,record,my_errno);
- }
- if(++i == NUPD) break;
- pos=HA_OFFSET_ERROR;
- }
- if (i != NUPD)
- printf("Found %d of %d rows\n", i,NUPD);
- }
-
- if (mi_close(file)) goto err;
- if(no_search) return 0;
- if (!silent)
- printf("- Reopening file\n");
- if (!(file=mi_open(filename,2,0))) goto err;
- if (!silent)
- printf("- Reading rows with key\n");
- for (i=0 ; i < NQUERIES ; i++)
- {
- FT_DOCLIST *result;
- result=ft_nlq_init_search(file,0,(char*) query[i],strlen(query[i]),1);
- if(!result)
- {
- printf("Query %d: `%s' failed with errno %3d\n",i,query[i],my_errno);
- continue;
- }
- printf("Query %d: `%s'. Found: %d. Top five documents:\n",
- i,query[i],result->ndocs);
- for (j=0;j<5;j++)
- {
- double w; int err;
- err= ft_nlq_read_next(result, read_record);
- if (err==HA_ERR_END_OF_FILE)
- {
- printf("No more matches!\n");
- break;
- }
- else if (err)
- {
- printf("ft_read_next %d failed with errno %3d\n",j,my_errno);
- break;
- }
- w=ft_nlq_get_relevance(result);
- if (key_field == FIELD_VARCHAR)
- {
- uint l;
- char *p;
- p=recinfo[0].length+read_record;
- l=uint2korr(p);
- printf("%10.7f: %.*s\n",w,(int) l,p+2);
- }
- else
- printf("%10.7f: %.*s\n",w,recinfo[1].length,
- recinfo[0].length+read_record);
- }
- ft_nlq_close_search(result);
- }
-
- if (mi_close(file)) goto err;
- my_end(MY_CHECK_ERROR);
-
- return (0);
-err:
- printf("got error: %3d when using myisam-database\n",my_errno);
- return 1; /* skip warning */
-}
-
-static char blob_key[MAX_REC_LENGTH];
-/* static char blob_record[MAX_REC_LENGTH+20*20]; */
-
-void create_record(char *pos, int n)
-{
- bzero((char*) pos,MAX_REC_LENGTH);
- if (recinfo[0].type == FIELD_BLOB)
- {
- uint tmp;
- char *ptr;
- strnmov(blob_key,data[n].f0,keyinfo[0].seg[0].length);
- tmp=strlen(blob_key);
- int4store(pos,tmp);
- ptr=blob_key;
- memcpy_fixed(pos+4,&ptr,sizeof(char*));
- pos+=recinfo[0].length;
- }
- else if (recinfo[0].type == FIELD_VARCHAR)
- {
- uint tmp;
- /* -1 is here because pack_length is stored in seg->length */
- uint pack_length= HA_VARCHAR_PACKLENGTH(keyinfo[0].seg[0].length-1);
- strnmov(pos+pack_length,data[n].f0,keyinfo[0].seg[0].length);
- tmp=strlen(pos+pack_length);
- if (pack_length == 1)
- *pos= (char) tmp;
- else
- int2store(pos,tmp);
- pos+=recinfo[0].length;
- }
- else
- {
- strnmov(pos,data[n].f0,keyinfo[0].seg[0].length);
- pos+=recinfo[0].length;
- }
- if (recinfo[1].type == FIELD_BLOB)
- {
- uint tmp;
- char *ptr;
- strnmov(blob_key,data[n].f2,keyinfo[0].seg[0].length);
- tmp=strlen(blob_key);
- int4store(pos,tmp);
- ptr=blob_key;
- memcpy_fixed(pos+4,&ptr,sizeof(char*));
- pos+=recinfo[1].length;
- }
- else if (recinfo[1].type == FIELD_VARCHAR)
- {
- uint tmp;
- /* -1 is here because pack_length is stored in seg->length */
- uint pack_length= HA_VARCHAR_PACKLENGTH(keyinfo[0].seg[0].length-1);
- strnmov(pos+pack_length,data[n].f2,keyinfo[0].seg[0].length);
- tmp=strlen(pos+1);
- if (pack_length == 1)
- *pos= (char) tmp;
- else
- int2store(pos,tmp);
- pos+=recinfo[1].length;
- }
- else
- {
- strnmov(pos,data[n].f2,keyinfo[0].seg[0].length);
- pos+=recinfo[1].length;
- }
-}
-
-
-static my_bool
-get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
- char *argument)
-{
- switch(optid) {
- case 'v': verbose=1; break;
- case 's': silent=1; break;
- case 'F': no_fulltext=1; no_search=1;
- case 'U': skip_update=1; break;
- case 'K': no_keys=no_search=1; break;
- case 'N': no_search=1; break;
- case 'S': no_stopwords=1; break;
- case '#':
- DBUG_PUSH (argument);
- break;
- case 'V':
- case '?':
- case 'h':
- usage();
- exit(1);
- }
- return 0;
-}
-
-/* Read options */
-
-static void get_options(int argc,char *argv[])
-{
- int ho_error;
-
- if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
- exit(ho_error);
- return;
-} /* get options */
-
-
-static void usage()
-{
- printf("%s [options]\n", my_progname);
- my_print_help(my_long_options);
- my_print_variables(my_long_options);
-}
diff --git a/storage/myisam/ft_test1.h b/storage/myisam/ft_test1.h
deleted file mode 100644
index 4b466818460..00000000000
--- a/storage/myisam/ft_test1.h
+++ /dev/null
@@ -1,420 +0,0 @@
-/* Copyright (C) 2000-2001 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
-
-#define NUPD 20
-#define NDATAS 389
-struct { const char *f0, *f2; } data[NDATAS] = {
- {"1", "General Information about MySQL"},
- {"1.1", "What is MySQL?"},
- {"1.2", "About this manual"},
- {"1.3", "History of MySQL"},
- {"1.4", "The main features of MySQL"},
- {"1.5", "General SQL information and tutorials"},
- {"1.6", "Useful MySQL-related links"},
- {"1.7", "What are stored procedures and triggers and so on?"},
- {"2", "MySQL mailing lists and how to ask questions/give error (bug) reports"},
- {"2.1", "Subscribing to/un-subscribing from the MySQL mailing list"},
- {"2.2", "Asking questions or reporting bugs"},
- {"2.3", "I think I have found a bug. What information do you need to help me?"},
- {"2.3.1", "MySQL keeps crashing"},
- {"2.4", "Guidelines for answering questions on the mailing list"},
- {"3", "Licensing or When do I have/want to pay for MySQL?"},
- {"3.1", "How much does MySQL cost?"},
- {"3.2", "How do I get commercial support?"},
- {"3.2.1", "Types of commercial support"},
- {"3.2.1.1", "Basic email support"},
- {"3.2.1.2", "Extended email support"},
-/*------------------------------- NUPD=20 -------------------------------*/
- {"3.2.1.3", "Asking: Login support"},
- {"3.2.1.4", "Extended login support"},
- {"3.3", "How do I pay for licenses/support?"},
- {"3.4", "Who do I contact when I want more information about licensing/support?"},
- {"3.5", "What Copyright does MySQL use?"},
- {"3.6", "When may I distribute MySQL commercially without a fee?"},
- {"3.7", "I want to sell a product that can be configured to use MySQL"},
- {"3.8", "I am running a commercial web server using MySQL"},
- {"3.9", "Do I need a license to sell commercial Perl/tcl/PHP/Web+ etc applications?"},
- {"3.10", "Possible future changes in the licensing"},
- {"4", "Compiling and installing MySQL"},
- {"4.1", "How do I get MySQL?"},
- {"4.2", "Which MySQL version should I use?"},
- {"4.3", "How/when will you release updates?"},
- {"4.4", "What operating systems does MySQL support?"},
- {"4.5", "Compiling MySQL from source code"},
- {"4.5.1", "Quick installation overview"},
- {"4.5.2", "Usual configure switches"},
- {"4.5.3", "Applying a patch"},
- {"4.6", "Problems compiling?"},
- {"4.7", "General compilation notes"},
- {"4.8", "MIT-pthreads notes (FreeBSD)"},
- {"4.9", "Perl installation comments"},
- {"4.10", "Special things to consider for some machine/OS combinations"},
- {"4.10.1", "Solaris notes"},
- {"4.10.2", "SunOS 4 notes"},
- {"4.10.3", "Linux notes for all versions"},
- {"4.10.3.1", "Linux-x86 notes"},
- {"4.10.3.2", "RedHat 5.0"},
- {"4.10.3.3", "RedHat 5.1"},
- {"4.10.3.4", "Linux-Sparc notes"},
- {"4.10.3.5", "Linux-Alpha notes"},
- {"4.10.3.6", "MkLinux notes"},
- {"4.10.4", "Alpha-DEC-Unix notes"},
- {"4.10.5", "Alpha-DEC-OSF1 notes"},
- {"4.10.6", "SGI-IRIX notes"},
- {"4.10.7", "FreeBSD notes"},
- {"4.10.7.1", "FreeBSD-3.0 notes"},
- {"4.10.8", "BSD/OS 2.# notes"},
- {"4.10.8.1", "BSD/OS 3.# notes"},
- {"4.10.9", "SCO notes"},
- {"4.10.10", "SCO Unixware 7.0 notes"},
- {"4.10.11", "IBM-AIX notes"},
- {"4.10.12", "HP-UX notes"},
- {"4.11", "TcX binaries"},
- {"4.12", "Win32 notes"},
- {"4.13", "Installation instructions for MySQL binary releases"},
- {"4.13.1", "How to get MySQL Perl support working"},
- {"4.13.2", "Linux notes"},
- {"4.13.3", "HP-UX notes"},
- {"4.13.4", "Linking client libraries"},
- {"4.14", "Problems running mysql_install_db"},
- {"4.15", "Problems starting MySQL"},
- {"4.16", "Automatic start/stop of MySQL"},
- {"4.17", "Option files"},
- {"5", "How standards-compatible is MySQL?"},
- {"5.1", "What extensions has MySQL to ANSI SQL92?"},
- {"5.2", "What functionality is missing in MySQL?"},
- {"5.2.1", "Sub-selects"},
- {"5.2.2", "SELECT INTO TABLE"},
- {"5.2.3", "Transactions"},
- {"5.2.4", "Triggers"},
- {"5.2.5", "Foreign Keys"},
- {"5.2.5.1", "Some reasons NOT to use FOREIGN KEYS"},
- {"5.2.6", "Views"},
- {"5.2.7", "-- as start of a comment"},
- {"5.3", "What standards does MySQL follow?"},
- {"5.4", "What functions exist only for compatibility?"},
- {"5.5", "Limitations of BLOB and TEXT types"},
- {"5.6", "How to cope without COMMIT-ROLLBACK"},
- {"6", "The MySQL access privilege system"},
- {"6.1", "What the privilege system does"},
- {"6.2", "Connecting to the MySQL server"},
- {"6.2.1", "Keeping your password secure"},
- {"6.3", "Privileges provided by MySQL"},
- {"6.4", "How the privilege system works"},
- {"6.5", "The privilege tables"},
- {"6.6", "Setting up the initial MySQL privileges"},
- {"6.7", "Adding new user privileges to MySQL"},
- {"6.8", "An example permission setup"},
- {"6.9", "Causes of Access denied errors"},
- {"6.10", "How to make MySQL secure against crackers"},
- {"7", "MySQL language reference"},
- {"7.1", "Literals: how to write strings and numbers"},
- {"7.1.1", "Strings"},
- {"7.1.2", "Numbers"},
- {"7.1.3", "NULL values"},
- {"7.1.4", "Database, table, index, column and alias names"},
- {"7.1.4.1", "Case sensitivity in names"},
- {"7.2", "Column types"},
- {"7.2.1", "Column type storage requirements"},
- {"7.2.5", "Numeric types"},
- {"7.2.6", "Date and time types"},
- {"7.2.6.1", "The DATE type"},
- {"7.2.6.2", "The TIME type"},
- {"7.2.6.3", "The DATETIME type"},
- {"7.2.6.4", "The TIMESTAMP type"},
- {"7.2.6.5", "The YEAR type"},
- {"7.2.6.6", "Miscellaneous date and time properties"},
- {"7.2.7", "String types"},
- {"7.2.7.1", "The CHAR and VARCHAR types"},
- {"7.2.7.2", "The BLOB and TEXT types"},
- {"7.2.7.3", "The ENUM type"},
- {"7.2.7.4", "The SET type"},
- {"7.2.8", "Choosing the right type for a column"},
- {"7.2.9", "Column indexes"},
- {"7.2.10", "Multiple-column indexes"},
- {"7.2.11", "Using column types from other database engines"},
- {"7.3", "Functions for use in SELECT and WHERE clauses"},
- {"7.3.1", "Grouping functions"},
- {"7.3.2", "Normal arithmetic operations"},
- {"7.3.3", "Bit functions"},
- {"7.3.4", "Logical operations"},
- {"7.3.5", "Comparison operators"},
- {"7.3.6", "String comparison functions"},
- {"7.3.7", "Control flow functions"},
- {"7.3.8", "Mathematical functions"},
- {"7.3.9", "String functions"},
- {"7.3.10", "Date and time functions"},
- {"7.3.11", "Miscellaneous functions"},
- {"7.3.12", "Functions for use with GROUP BY clauses"},
- {"7.4", "CREATE DATABASE syntax"},
- {"7.5", "DROP DATABASE syntax"},
- {"7.6", "CREATE TABLE syntax"},
- {"7.7", "ALTER TABLE syntax"},
- {"7.8", "OPTIMIZE TABLE syntax"},
- {"7.9", "DROP TABLE syntax"},
- {"7.10", "DELETE syntax"},
- {"7.11", "SELECT syntax"},
- {"7.12", "JOIN syntax"},
- {"7.13", "INSERT syntax"},
- {"7.14", "REPLACE syntax"},
- {"7.15", "LOAD DATA INFILE syntax"},
- {"7.16", "UPDATE syntax"},
- {"7.17", "USE syntax"},
- {"7.18", "SHOW syntax (Get information about tables, columns...)"},
- {"7.19", "EXPLAIN syntax (Get information about a SELECT)"},
- {"7.20", "DESCRIBE syntax (Get information about columns)"},
- {"7.21", "LOCK TABLES/UNLOCK TABLES syntax"},
- {"7.22", "SET OPTION syntax"},
- {"7.23", "GRANT syntax (Compatibility function)"},
- {"7.24", "CREATE INDEX syntax (Compatibility function)"},
- {"7.25", "DROP INDEX syntax (Compatibility function)"},
- {"7.26", "Comment syntax"},
- {"7.27", "CREATE FUNCTION/DROP FUNCTION syntax"},
- {"7.28", "Is MySQL picky about reserved words?"},
- {"8", "Example SQL queries"},
- {"8.1", "Queries from twin project"},
- {"8.1.1", "Find all non-distributed twins"},
- {"8.1.2", "Show a table on twin pair status"},
- {"9", "How safe/stable is MySQL?"},
- {"9.1", "How stable is MySQL?"},
- {"9.2", "Why are there is so many releases of MySQL?"},
- {"9.3", "Checking a table for errors"},
- {"9.4", "How to repair tables"},
- {"9.5", "Is there anything special to do when upgrading/downgrading MySQL?"},
- {"9.5.1", "Upgrading from a 3.21 version to 3.22"},
- {"9.5.2", "Upgrading from a 3.20 version to 3.21"},
- {"9.5.3", "Upgrading to another architecture"},
- {"9.6", "Year 2000 compliance"},
- {"10", "MySQL Server functions"},
- {"10.1", "What languages are supported by MySQL?"},
- {"10.1.1", "Character set used for data &#38; sorting"},
- {"10.2", "The update log"},
- {"10.3", "How big can MySQL tables be?"},
- {"11", "Getting maximum performance from MySQL"},
- {"11.1", "How does one change the size of MySQL buffers?"},
- {"11.2", "How compiling and linking affects the speed of MySQL"},
- {"11.3", "How does MySQL use memory?"},
- {"11.4", "How does MySQL use indexes?"},
- {"11.5", "What optimizations are done on WHERE clauses?"},
- {"11.6", "How does MySQL open &#38; close tables?"},
- {"11.6.0.1", "What are the drawbacks of creating possibly thousands of tables in a database?"},
- {"11.7", "How does MySQL lock tables?"},
- {"11.8", "How should I arrange my table to be as fast/small as possible?"},
- {"11.9", "What affects the speed of INSERT statements?"},
- {"11.10", "What affects the speed DELETE statements?"},
- {"11.11", "How do I get MySQL to run at full speed?"},
- {"11.12", "What are the different row formats? Or, when should VARCHAR/CHAR be used?"},
- {"11.13", "Why so many open tables?"},
- {"12", "MySQL benchmark suite"},
- {"13", "MySQL Utilites"},
- {"13.1", "Overview of the different MySQL programs"},
- {"13.2", "The MySQL table check, optimize and repair program"},
- {"13.2.1", "isamchk memory use"},
- {"13.2.2", "Getting low-level table information"},
- {"13.3", "The MySQL compressed read-only table generator"},
- {"14", "Adding new functions to MySQL"},
- {"15", "MySQL ODBC Support"},
- {"15.1", "Operating systems supported by MyODBC"},
- {"15.2", "How to report problems with MyODBC"},
- {"15.3", "Programs known to work with MyODBC"},
- {"15.4", "How to fill in the various fields in the ODBC administrator program"},
- {"15.5", "How to get the value of an AUTO_INCREMENT column in ODBC"},
- {"16", "Problems and common errors"},
- {"16.1", "Some common errors when using MySQL"},
- {"16.1.1", "MySQL server has gone away error"},
- {"16.1.2", "Can't connect to local MySQL server error"},
- {"16.1.3", "Out of memory error"},
- {"16.1.4", "Packet too large error"},
- {"16.1.5", "The table is full error"},
- {"16.1.6", "Commands out of sync error in client"},
- {"16.1.7", "Removing user error"},
- {"16.2", "How MySQL handles a full disk"},
- {"16.3", "How to run SQL commands from a text file"},
- {"16.4", "Where MySQL stores temporary files"},
- {"16.5", "Access denied error"},
- {"16.6", "How to run MySQL as a normal user"},
- {"16.7", "Problems with file permissions"},
- {"16.8", "File not found"},
- {"16.9", "Problems using DATE columns"},
- {"16.10", "Case sensitivity in searches"},
- {"16.11", "Problems with NULL values"},
- {"17", "Solving some common problems with MySQL"},
- {"17.1", "Database replication"},
- {"17.2", "Database backups"},
- {"18", "MySQL client tools and API's"},
- {"18.1", "MySQL C API"},
- {"18.2", "C API datatypes"},
- {"18.3", "C API function overview"},
- {"18.4", "C API function descriptions"},
- {"18.4.1", "mysql_affected_rows()"},
- {"18.4.2", "mysql_close()"},
- {"18.4.3", "mysql_connect()"},
- {"18.4.4", "mysql_create_db()"},
- {"18.4.5", "mysql_data_seek()"},
- {"18.4.6", "mysql_debug()"},
- {"18.4.7", "mysql_drop_db()"},
- {"18.4.8", "mysql_dump_debug_info()"},
- {"18.4.9", "mysql_eof()"},
- {"18.4.10", "mysql_errno()"},
- {"18.4.11", "mysql_error()"},
- {"18.4.12", "mysql_escape_string()"},
- {"18.4.13", "mysql_fetch_field()"},
- {"18.4.14", "mysql_fetch_fields()"},
- {"18.4.15", "mysql_fetch_field_direct()"},
- {"18.4.16", "mysql_fetch_lengths()"},
- {"18.4.17", "mysql_fetch_row()"},
- {"18.4.18", "mysql_field_seek()"},
- {"18.4.19", "mysql_field_tell()"},
- {"18.4.20", "mysql_free_result()"},
- {"18.4.21", "mysql_get_client_info()"},
- {"18.4.22", "mysql_get_host_info()"},
- {"18.4.23", "mysql_get_proto_info()"},
- {"18.4.24", "mysql_get_server_info()"},
- {"18.4.25", "mysql_info()"},
- {"18.4.26", "mysql_init()"},
- {"18.4.27", "mysql_insert_id()"},
- {"18.4.28", "mysql_kill()"},
- {"18.4.29", "mysql_list_dbs()"},
- {"18.4.30", "mysql_list_fields()"},
- {"18.4.31", "mysql_list_processes()"},
- {"18.4.32", "mysql_list_tables()"},
- {"18.4.33", "mysql_num_fields()"},
- {"18.4.34", "mysql_num_rows()"},
- {"18.4.35", "mysql_query()"},
- {"18.4.36", "mysql_real_connect()"},
- {"18.4.37", "mysql_real_query()"},
- {"18.4.38", "mysql_reload()"},
- {"18.4.39", "mysql_row_tell()"},
- {"18.4.40", "mysql_select_db()"},
- {"18.4.41", "mysql_shutdown()"},
- {"18.4.42", "mysql_stat()"},
- {"18.4.43", "mysql_store_result()"},
- {"18.4.44", "mysql_thread_id()"},
- {"18.4.45", "mysql_use_result()"},
- {"18.4.46", "Why is it that after mysql_query() returns success, mysql_store_result() sometimes returns NULL?"},
- {"18.4.47", "What results can I get from a query?"},
- {"18.4.48", "How can I get the unique ID for the last inserted row?"},
- {"18.4.49", "Problems linking with the C API"},
- {"18.4.50", "How to make a thread-safe client"},
- {"18.5", "MySQL Perl API's"},
- {"18.5.1", "DBI with DBD::mysql"},
- {"18.5.1.1", "The DBI interface"},
- {"18.5.1.2", "More DBI/DBD information"},
- {"18.6", "MySQL Java connectivity (JDBC)"},
- {"18.7", "MySQL PHP API's"},
- {"18.8", "MySQL C++ API's"},
- {"18.9", "MySQL Python API's"},
- {"18.10", "MySQL TCL API's"},
- {"19", "How MySQL compares to other databases"},
- {"19.1", "How MySQL compares to mSQL"},
- {"19.1.1", "How to convert mSQL tools for MySQL"},
- {"19.1.2", "How mSQL and MySQL client/server communications protocols differ"},
- {"19.1.3", "How mSQL 2.0 SQL syntax differs from MySQL"},
- {"19.2", "How MySQL compares to PostgreSQL"},
- {"A", "Some users of MySQL"},
- {"B", "Contributed programs"},
- {"C", "Contributors to MySQL"},
- {"D", "MySQL change history"},
- {"19.3", "Changes in release 3.22.x (Alpha version)"},
- {"19.3.1", "Changes in release 3.22.7"},
- {"19.3.2", "Changes in release 3.22.6"},
- {"19.3.3", "Changes in release 3.22.5"},
- {"19.3.4", "Changes in release 3.22.4"},
- {"19.3.5", "Changes in release 3.22.3"},
- {"19.3.6", "Changes in release 3.22.2"},
- {"19.3.7", "Changes in release 3.22.1"},
- {"19.3.8", "Changes in release 3.22.0"},
- {"19.4", "Changes in release 3.21.x"},
- {"19.4.1", "Changes in release 3.21.33"},
- {"19.4.2", "Changes in release 3.21.32"},
- {"19.4.3", "Changes in release 3.21.31"},
- {"19.4.4", "Changes in release 3.21.30"},
- {"19.4.5", "Changes in release 3.21.29"},
- {"19.4.6", "Changes in release 3.21.28"},
- {"19.4.7", "Changes in release 3.21.27"},
- {"19.4.8", "Changes in release 3.21.26"},
- {"19.4.9", "Changes in release 3.21.25"},
- {"19.4.10", "Changes in release 3.21.24"},
- {"19.4.11", "Changes in release 3.21.23"},
- {"19.4.12", "Changes in release 3.21.22"},
- {"19.4.13", "Changes in release 3.21.21a"},
- {"19.4.14", "Changes in release 3.21.21"},
- {"19.4.15", "Changes in release 3.21.20"},
- {"19.4.16", "Changes in release 3.21.19"},
- {"19.4.17", "Changes in release 3.21.18"},
- {"19.4.18", "Changes in release 3.21.17"},
- {"19.4.19", "Changes in release 3.21.16"},
- {"19.4.20", "Changes in release 3.21.15"},
- {"19.4.21", "Changes in release 3.21.14b"},
- {"19.4.22", "Changes in release 3.21.14a"},
- {"19.4.23", "Changes in release 3.21.13"},
- {"19.4.24", "Changes in release 3.21.12"},
- {"19.4.25", "Changes in release 3.21.11"},
- {"19.4.26", "Changes in release 3.21.10"},
- {"19.4.27", "Changes in release 3.21.9"},
- {"19.4.28", "Changes in release 3.21.8"},
- {"19.4.29", "Changes in release 3.21.7"},
- {"19.4.30", "Changes in release 3.21.6"},
- {"19.4.31", "Changes in release 3.21.5"},
- {"19.4.32", "Changes in release 3.21.4"},
- {"19.4.33", "Changes in release 3.21.3"},
- {"19.4.34", "Changes in release 3.21.2"},
- {"19.4.35", "Changes in release 3.21.0"},
- {"19.5", "Changes in release 3.20.x"},
- {"19.5.1", "Changes in release 3.20.18"},
- {"19.5.2", "Changes in release 3.20.17"},
- {"19.5.3", "Changes in release 3.20.16"},
- {"19.5.4", "Changes in release 3.20.15"},
- {"19.5.5", "Changes in release 3.20.14"},
- {"19.5.6", "Changes in release 3.20.13"},
- {"19.5.7", "Changes in release 3.20.11"},
- {"19.5.8", "Changes in release 3.20.10"},
- {"19.5.9", "Changes in release 3.20.9"},
- {"19.5.10", "Changes in release 3.20.8"},
- {"19.5.11", "Changes in release 3.20.7"},
- {"19.5.12", "Changes in release 3.20.6"},
- {"19.5.13", "Changes in release 3.20.3"},
- {"19.5.14", "Changes in release 3.20.0"},
- {"19.6", "Changes in release 3.19.x"},
- {"19.6.1", "Changes in release 3.19.5"},
- {"19.6.2", "Changes in release 3.19.4"},
- {"19.6.3", "Changes in release 3.19.3"},
- {"E", "Known errors and design deficiencies in MySQL"},
- {"F", "List of things we want to add to MySQL in the future (The TODO)"},
- {"19.7", "Things that must done in the real near future"},
- {"19.8", "Things that have to be done sometime"},
- {"19.9", "Some things we don't have any plans to do"},
- {"G", "Comments on porting to other systems"},
- {"19.10", "Debugging MySQL"},
- {"19.11", "Comments about RTS threads"},
- {"19.12", "What is the difference between different thread packages?"},
- {"H", "Description of MySQL regular expression syntax"},
- {"I", "What is Unireg?"},
- {"J", "The MySQL server license"},
- {"K", "The MySQL license for Microsoft operating systems"},
- {"*", "SQL command, type and function index"},
- {"*", "Concept Index"}
-};
-
-#define NQUERIES 5
-const char *query[NQUERIES]={
- "mysql information and manual",
- "upgrading from previous version",
- "column indexes",
- "against about after more right the with/without", /* stopwords test */
- "mysql license and copyright"
-};
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index a831335cbb9..e0e104a4878 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -79,7 +79,7 @@ static MYSQL_THDVAR_ULONG(repair_threads, PLUGIN_VAR_RQCMDARG,
static MYSQL_THDVAR_ULONG(sort_buffer_size, PLUGIN_VAR_RQCMDARG,
"The buffer that is allocated when sorting the index when doing "
"a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE", NULL, NULL,
- 8192*1024, 4, ULONG_MAX, 1);
+ 8192*1024, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), ULONG_MAX, 1);
static MYSQL_SYSVAR_BOOL(use_mmap, opt_myisam_use_mmap, PLUGIN_VAR_NOCMDARG,
"Use memory mapping for reading and writing MyISAM tables", NULL, NULL, FALSE);
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index 1cc521baf0e..0bcc022a0dc 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -2402,10 +2402,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
/*
fulltext indexes may have much more entries than the
number of rows in the table. We estimate the number here.
-
- Note, built-in parser is always nr. 0 - see ftparser_call_initializer()
*/
- if (sort_param.keyinfo->ftkey_nr == 0)
+ if (sort_param.keyinfo->parser == &ft_default_parser)
{
/*
for built-in parser the number of generated index entries
@@ -2422,8 +2420,9 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
so, we'll use all the sort memory and start from ~10 buffpeks.
(see _create_index_by_sort)
*/
- sort_info.max_records=
- 10*param->sort_buffer_length/sort_param.key_length;
+ sort_info.max_records= 10 *
+ max(param->sort_buffer_length, MIN_SORT_BUFFER) /
+ sort_param.key_length;
}
sort_param.key_read=sort_ft_key_read;
diff --git a/storage/myisam/mi_delete_all.c b/storage/myisam/mi_delete_all.c
index b8706069ced..7a2e24189e6 100644
--- a/storage/myisam/mi_delete_all.c
+++ b/storage/myisam/mi_delete_all.c
@@ -55,7 +55,7 @@ int mi_delete_all_rows(MI_INFO *info)
flush_key_blocks(share->key_cache, share->kfile, FLUSH_IGNORE_CHANGED);
#ifdef HAVE_MMAP
if (share->file_map)
- _mi_unmap_file(info);
+ mi_munmap_file(info);
#endif
if (mysql_file_chsize(info->dfile, 0, 0, MYF(MY_WME)) ||
mysql_file_chsize(share->kfile, share->base.keystart, 0, MYF(MY_WME)))
diff --git a/storage/myisam/mi_delete_table.c b/storage/myisam/mi_delete_table.c
index 28aee848665..58a60a760aa 100644
--- a/storage/myisam/mi_delete_table.c
+++ b/storage/myisam/mi_delete_table.c
@@ -58,13 +58,38 @@ int mi_delete_table(const char *name)
#endif /* USE_RAID */
fn_format(from,name,"",MI_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
- if (mysql_file_delete_with_symlink(mi_key_file_kfile, from, MYF(MY_WME)))
- DBUG_RETURN(my_errno);
+ if (my_is_symlink(from) && (*myisam_test_invalid_symlink)(from))
+ {
+ /*
+ Symlink is pointing to file in data directory.
+ Remove symlink, keep file.
+ */
+ if (mysql_file_delete(mi_key_file_kfile, from, MYF(MY_WME)))
+ DBUG_RETURN(my_errno);
+ }
+ else
+ {
+ if (mysql_file_delete_with_symlink(mi_key_file_kfile, from, MYF(MY_WME)))
+ DBUG_RETURN(my_errno);
+ }
fn_format(from,name,"",MI_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
#ifdef USE_RAID
if (raid_type)
DBUG_RETURN(my_raid_delete(from, raid_chunks, MYF(MY_WME)) ? my_errno : 0);
#endif
- DBUG_RETURN(mysql_file_delete_with_symlink(mi_key_file_dfile,
- from, MYF(MY_WME)) ? my_errno : 0);
+ if (my_is_symlink(from) && (*myisam_test_invalid_symlink)(from))
+ {
+ /*
+ Symlink is pointing to file in data directory.
+ Remove symlink, keep file.
+ */
+ if (mysql_file_delete(mi_key_file_dfile, from, MYF(MY_WME)))
+ DBUG_RETURN(my_errno);
+ }
+ else
+ {
+ if (mysql_file_delete_with_symlink(mi_key_file_dfile, from, MYF(MY_WME)))
+ DBUG_RETURN(my_errno);
+ }
+ DBUG_RETURN(0);
}
diff --git a/storage/myisam/mi_dynrec.c b/storage/myisam/mi_dynrec.c
index 3830763c673..02a8f21e3e2 100644
--- a/storage/myisam/mi_dynrec.c
+++ b/storage/myisam/mi_dynrec.c
@@ -97,6 +97,34 @@ my_bool mi_dynmap_file(MI_INFO *info, my_off_t size)
madvise((char*) info->s->file_map, size, MADV_RANDOM);
#endif
info->s->mmaped_length= size;
+ info->s->file_read= mi_mmap_pread;
+ info->s->file_write= mi_mmap_pwrite;
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Destroy mmaped area for MyISAM handler
+
+ SYNOPSIS
+ mi_munmap_file()
+ info MyISAM handler
+
+ RETURN
+ 0 ok
+ !0 error.
+*/
+
+int mi_munmap_file(MI_INFO *info)
+{
+ int ret;
+ DBUG_ENTER("mi_unmap_file");
+ if ((ret= my_munmap(info->s->file_map, info->s->mmaped_length)))
+ DBUG_RETURN(ret);
+ info->s->file_read= mi_nommap_pread;
+ info->s->file_write= mi_nommap_pwrite;
+ info->s->file_map= 0;
+ info->s->mmaped_length= 0;
DBUG_RETURN(0);
}
@@ -115,8 +143,7 @@ void mi_remap_file(MI_INFO *info, my_off_t size)
{
if (info->s->file_map)
{
- (void) (my_munmap((char*) info->s->file_map,
- (size_t) info->s->mmaped_length));
+ mi_munmap_file(info);
mi_dynmap_file(info, size);
}
}
diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c
index d8f4fc99c8e..baf8cb5e240 100644
--- a/storage/myisam/mi_extra.c
+++ b/storage/myisam/mi_extra.c
@@ -364,11 +364,6 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
DBUG_PRINT("warning",("mmap failed: errno: %d",errno));
error= my_errno= errno;
}
- else
- {
- share->file_read= mi_mmap_pread;
- share->file_write= mi_mmap_pwrite;
- }
}
mysql_mutex_unlock(&share->intern_lock);
#endif
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c
index ef5b442cd3a..1d877748b31 100644
--- a/storage/myisam/mi_open.c
+++ b/storage/myisam/mi_open.c
@@ -658,6 +658,9 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
mysql_mutex_unlock(&THR_LOCK_myisam);
+
+ bzero(info.buff, share->base.max_key_block_length * 2);
+
if (myisam_log_file >= 0)
{
intern_filename(name_buff,share->index_file_name);
diff --git a/storage/myisam/mi_page.c b/storage/myisam/mi_page.c
index 2cf3891807f..90e31e72532 100644
--- a/storage/myisam/mi_page.c
+++ b/storage/myisam/mi_page.c
@@ -86,13 +86,6 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if ((length=keyinfo->block_length) > IO_SIZE*2 &&
info->state->key_file_length != page+length)
length= ((mi_getint(buff)+IO_SIZE-1) & (uint) ~(IO_SIZE-1));
-#ifdef HAVE_purify
- {
- length=mi_getint(buff);
- bzero((uchar*) buff+length,keyinfo->block_length-length);
- length=keyinfo->block_length;
- }
-#endif
DBUG_RETURN((key_cache_write(info->s->key_cache,
info->s->kfile,page, level, (uchar*) buff,length,
(uint) keyinfo->block_length,
diff --git a/storage/myisam/mi_rnext.c b/storage/myisam/mi_rnext.c
index 6def5749043..e1a78a04e57 100644
--- a/storage/myisam/mi_rnext.c
+++ b/storage/myisam/mi_rnext.c
@@ -28,6 +28,7 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx)
{
int error,changed;
uint flag;
+ uint update_mask= HA_STATE_NEXT_FOUND;
DBUG_ENTER("mi_rnext");
if ((inx = _mi_check_index(info,inx)) < 0)
@@ -55,6 +56,20 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx)
info->s->state.key_root[inx]);
break;
}
+ /*
+ "search first" failed. This means we have no pivot for
+ "search next", or in other words MI_INFO::lastkey is
+ likely uninitialized.
+
+ Normally SQL layer would never request "search next" if
+ "search first" failed. But HANDLER may do anything.
+
+ As mi_rnext() without preceeding mi_rkey()/mi_rfirst()
+ equals to mi_rfirst(), we must restore original state
+ as if failing mi_rfirst() was not called.
+ */
+ if (error)
+ update_mask|= HA_STATE_PREV_FOUND;
}
else
{
@@ -100,7 +115,7 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx)
}
/* Don't clear if database-changed */
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
- info->update|= HA_STATE_NEXT_FOUND;
+ info->update|= update_mask;
if (error)
{
diff --git a/storage/myisam/mi_write.c b/storage/myisam/mi_write.c
index 4293d9b5269..5b46db111b3 100644
--- a/storage/myisam/mi_write.c
+++ b/storage/myisam/mi_write.c
@@ -825,7 +825,7 @@ static int _mi_balance_page(register MI_INFO *info, MI_KEYDEF *keyinfo,
(size_t) (length=new_left_length - left_length - k_length));
pos=buff+2+length;
memcpy((uchar*) father_key_pos,(uchar*) pos,(size_t) k_length);
- bmove((uchar*) buff+2,(uchar*) pos+k_length,new_right_length);
+ bmove((uchar*) buff + 2, (uchar*) pos + k_length, new_right_length - 2);
}
else
{ /* Move keys -> buff */
diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h
index a1142ff418a..d88ebdf5f12 100644
--- a/storage/myisam/myisamdef.h
+++ b/storage/myisam/myisamdef.h
@@ -767,6 +767,7 @@ int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *orn_name,
int mi_open_keyfile(MYISAM_SHARE *share);
void mi_setup_functions(register MYISAM_SHARE *share);
my_bool mi_dynmap_file(MI_INFO *info, my_off_t size);
+int mi_munmap_file(MI_INFO *info);
void mi_remap_file(MI_INFO *info, my_off_t size);
void _mi_report_crashed(MI_INFO *file, const char *message,
const char *sfile, uint sline);
diff --git a/storage/myisam/rt_index.c b/storage/myisam/rt_index.c
index 31241a83228..410badd3145 100644
--- a/storage/myisam/rt_index.c
+++ b/storage/myisam/rt_index.c
@@ -641,18 +641,12 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key,
}
case 1: /* root was split, grow a new root */
{
- uchar *new_root_buf;
+ uchar *new_root_buf= info->buff + info->s->base.max_key_block_length;
my_off_t new_root;
uchar *new_key;
uint nod_flag = info->s->base.key_reflength;
DBUG_PRINT("rtree", ("root was split, grow a new root"));
- if (!(new_root_buf = (uchar*)my_alloca((uint)keyinfo->block_length +
- MI_MAX_KEY_BUFF)))
- {
- my_errno = HA_ERR_OUT_OF_MEM;
- DBUG_RETURN(-1); /* purecov: inspected */
- }
mi_putint(new_root_buf, 2, nod_flag);
if ((new_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) ==
@@ -680,10 +674,8 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key,
DBUG_PRINT("rtree", ("new root page: %lu level: %d nod_flag: %u",
(ulong) new_root, 0, mi_test_if_nod(new_root_buf)));
- my_afree((uchar*)new_root_buf);
break;
err1:
- my_afree((uchar*)new_root_buf);
DBUG_RETURN(-1); /* purecov: inspected */
}
default:
diff --git a/storage/myisam/rt_split.c b/storage/myisam/rt_split.c
index ef988dbd048..88cf643faf9 100644
--- a/storage/myisam/rt_split.c
+++ b/storage/myisam/rt_split.c
@@ -258,7 +258,7 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key,
double *old_coord;
int n_dim;
uchar *source_cur, *cur1, *cur2;
- uchar *new_page;
+ uchar *new_page= info->buff;
int err_code= 0;
uint nod_flag= mi_test_if_nod(page);
uint full_length= key_length + (nod_flag ? nod_flag :
@@ -304,12 +304,7 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key,
goto split_err;
}
- if (!(new_page = (uchar*)my_alloca((uint)keyinfo->block_length)))
- {
- err_code= -1;
- goto split_err;
- }
-
+ info->buff_used= 1;
stop = task + (max_keys + 1);
cur1 = rt_PAGE_FIRST_KEY(page, nod_flag);
cur2 = rt_PAGE_FIRST_KEY(new_page, nod_flag);
@@ -345,8 +340,6 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key,
DFLT_INIT_HITS, new_page);
DBUG_PRINT("rtree", ("split new block: %lu", (ulong) *new_page_offs));
- my_afree((uchar*)new_page);
-
split_err:
my_afree((uchar*) coord_buf);
DBUG_RETURN(err_code);
diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c
index 3cb99867c6a..539630899f4 100644
--- a/storage/myisam/sort.c
+++ b/storage/myisam/sort.c
@@ -28,13 +28,11 @@
/* static variables */
-#undef MIN_SORT_MEMORY
#undef MYF_RW
#undef DISK_BUFFER_SIZE
#define MERGEBUFF 15
#define MERGEBUFF2 31
-#define MIN_SORT_MEMORY (4096-MALLOC_OVERHEAD)
#define MYF_RW MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL)
#define DISK_BUFFER_SIZE (IO_SIZE*16)
@@ -131,12 +129,12 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
sort_keys= (uchar **) NULL; error= 1;
maxbuffer=1;
- memavl=max(sortbuff_size,MIN_SORT_MEMORY);
+ memavl= max(sortbuff_size, MIN_SORT_BUFFER);
records= info->sort_info->max_records;
sort_length= info->key_length;
LINT_INIT(keys);
- while (memavl >= MIN_SORT_MEMORY)
+ while (memavl >= MIN_SORT_BUFFER)
{
if ((records < UINT_MAX32) &&
((my_off_t) (records + 1) *
@@ -171,10 +169,10 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
break;
}
old_memavl=memavl;
- if ((memavl=memavl/4*3) < MIN_SORT_MEMORY && old_memavl > MIN_SORT_MEMORY)
- memavl=MIN_SORT_MEMORY;
+ if ((memavl= memavl/4*3) < MIN_SORT_BUFFER && old_memavl > MIN_SORT_BUFFER)
+ memavl= MIN_SORT_BUFFER;
}
- if (memavl < MIN_SORT_MEMORY)
+ if (memavl < MIN_SORT_BUFFER)
{
mi_check_print_error(info->sort_info->param,"MyISAM sort buffer too small"); /* purecov: tested */
goto err; /* purecov: tested */
@@ -348,12 +346,12 @@ pthread_handler_t thr_find_all_keys(void *arg)
bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
sort_keys= (uchar **) NULL;
- memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY);
+ memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER);
idx= (uint)sort_param->sort_info->max_records;
sort_length= sort_param->key_length;
maxbuffer= 1;
- while (memavl >= MIN_SORT_MEMORY)
+ while (memavl >= MIN_SORT_BUFFER)
{
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
(my_off_t) memavl)
@@ -391,11 +389,11 @@ pthread_handler_t thr_find_all_keys(void *arg)
break;
}
old_memavl= memavl;
- if ((memavl= memavl/4*3) < MIN_SORT_MEMORY &&
- old_memavl > MIN_SORT_MEMORY)
- memavl= MIN_SORT_MEMORY;
+ if ((memavl= memavl / 4 * 3) < MIN_SORT_BUFFER &&
+ old_memavl > MIN_SORT_BUFFER)
+ memavl= MIN_SORT_BUFFER;
}
- if (memavl < MIN_SORT_MEMORY)
+ if (memavl < MIN_SORT_BUFFER)
{
mi_check_print_error(sort_param->sort_info->param,
"MyISAM sort buffer too small");
@@ -564,7 +562,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
if (!mergebuf)
{
length=param->sort_buffer_length;
- while (length >= MIN_SORT_MEMORY)
+ while (length >= MIN_SORT_BUFFER)
{
if ((mergebuf= my_malloc(length, MYF(0))))
break;
diff --git a/storage/myisammrg/myrg_queue.c b/storage/myisammrg/myrg_queue.c
index d2579053784..2c447083558 100644
--- a/storage/myisammrg/myrg_queue.c
+++ b/storage/myisammrg/myrg_queue.c
@@ -65,7 +65,17 @@ int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag)
}
}
else
- my_errno= error= HA_ERR_WRONG_INDEX;
+ {
+ /*
+ inx may be bigger than info->keys if there are no underlying tables
+ defined. In this case we should return empty result. As we check for
+ underlying tables conformance when we open a table, we may not enter
+ this branch with underlying table that has less keys than merge table
+ have.
+ */
+ DBUG_ASSERT(!info->tables);
+ error= my_errno= HA_ERR_END_OF_FILE;
+ }
return error;
}
diff --git a/strings/ChangeLog b/strings/ChangeLog
deleted file mode 100644
index 2d31f2946a1..00000000000
--- a/strings/ChangeLog
+++ /dev/null
@@ -1,38 +0,0 @@
-Thu May 20 13:45:15 1993 Michael Widenius (monty at bitch)
-
- * changed itoa() and ltoa() to use the same interface as microsoft:s
- and zortech:s libraryes.
-
-Sun Mar 24 00:30:34 1991 Michael Widenius (monty at LYNX)
-
- * Changed int2str to return BIG converted chars.
-
-Sun Feb 24 00:22:54 1991 Michael Widenius (monty at LYNX)
-
- * Added new function strcend(string,char). Its eqvialent to
- if (!(a=strchr(string,char)))
- a=strend(string);
-
-Tue Oct 16 18:53:19 1990 Michael Widenius (monty at LYNX)
-
- * Added define BAD_STRING_COMPILER to set define strmov()
- if compiler is very bad at stringoperations.
- * Changed to use cc on sun-systems instead of gcc.
-
-Sat Sep 29 18:42:31 1990 Michael Widenius (monty at LYNX)
-
- * Added my_atof for sparc system to get some speed.
-
-Sun Mar 11 16:35:59 1990 Monty (monty at monty)
-
- * strnmov() was changed to not fill to-string with null.
- * strmake() changed to point at closing null.
-
-Wed Feb 7 20:15:34 1990 David Axmark (davida at isil)
-
- * Made functon strinrstr that is reverse search.
-
-Fri Dec 2 03:37:59 1988 Monty (monty at monty)
-
- * Fixed bug in strcont; It didn't return first found character in
- set.
diff --git a/strings/bcopy-duff.c b/strings/bcopy-duff.c
deleted file mode 100644
index 215857715fd..00000000000
--- a/strings/bcopy-duff.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright (C) 2000 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#define IFACTOR 4
-
- void
-dcopy(char *chardest, char *charsrc, int size)
-{
- register int *src, *dest, intcount ;
- int startcharcpy, intoffset, numints2cpy, i ;
-
- numints2cpy = size >> 2 ;
- startcharcpy = numints2cpy << 2 ;
- intcount = numints2cpy & ~(IFACTOR-1) ;
- intoffset = numints2cpy - intcount ;
-
- src = (int *)(((int) charsrc) + intcount*sizeof(int*)) ;
- dest = (int *)(((int) chardest) + intcount*sizeof(int*)) ;
-
- /* copy the ints */
- switch(intoffset)
- do
- {
- case 0: dest[3] = src[3] ;
- case 3: dest[2] = src[2] ;
- case 2: dest[1] = src[1] ;
- case 1: dest[0] = src[0] ;
- intcount -= IFACTOR ;
- dest -= IFACTOR ;
- src -= IFACTOR ;
- } while (intcount >= 0) ;
-
- /* copy the chars left over by the int copy at the end */
- for(i=startcharcpy ; i<size ; i++)
- chardest[i] = charsrc[i] ;
-}
diff --git a/strings/bzero.c b/strings/bzero.c
deleted file mode 100644
index b720de65eed..00000000000
--- a/strings/bzero.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Copyright (C) 2000 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* File : bzero.c
- Author : Richard A. O'Keefe.
- Michael Widenius; ifdef MC68000
- Updated: 23 April 1984
- Defines: bzero()
-
- bzero(dst, len) moves "len" 0 bytes to "dst".
- Thus to clear a disc buffer to 0s do bzero(buffer, BUFSIZ).
-
- Note: the "b" routines are there to exploit certain VAX order codes,
- The asm code is presented for your interest and amusement.
-*/
-
-#ifndef BSD_FUNCS
-#include "strings.h"
-
-#ifdef bzero
-#undef bzero /* remove macro */
-#endif
-
-#if VaxAsm
-
-static void _bzero64 _A((char *dst,int len));
-
-void bzero(dst, len)
-char *dst;
-uint len;
-{
- while ((int) len >= 64*K)
- {
- _bzero64(dst, 64*K-1);
- dst += 64*K-1;
- len -= 64*K-1;
- }
- _bzero64(dst, len);
-}
-
-_bzero64(dst, len)
-char *dst;
-int len;
-{
- asm("movc5 $0,*4(ap),$0,8(ap),*4(ap)");
-}
-
-#else
-
-#if defined(MC68000) && defined(DS90)
-
-void bzero(dst, len)
-char *dst;
-uint len;
-{
- bfill(dst,len,0); /* This is very optimized ! */
-} /* bzero */
-
-#else
-
-void bzero(dst, len)
-register char *dst;
-register uint len;
-{
- while (len-- != 0) *dst++ = 0;
-} /* bzero */
-
-#endif
-#endif
-#endif /* BSD_FUNCS */
diff --git a/strings/macros.asm b/strings/macros.asm
deleted file mode 100644
index 1eedcfbb15f..00000000000
--- a/strings/macros.asm
+++ /dev/null
@@ -1,147 +0,0 @@
-; Copyright (C) 2000 MySQL AB
-;
-; This library is free software; you can redistribute it and/or
-; modify it under the terms of the GNU Library General Public
-; License as published by the Free Software Foundation; version 2
-; of the License.
-;
-; This library 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
-; Library General Public License for more details.
-;
-; You should have received a copy of the GNU Library General Public
-; License along with this library; if not, write to the Free
-; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-; MA 02111-1307, USA
-
-; Some useful macros
-
- .386P
- .387
-
-_FLAT equ 0 ;FLAT memory model
-_STDCALL equ 0 ;default to _stdcall
-I386 equ 1
-
-begcode macro module
- if _FLAT
-_TEXT segment dword use32 public 'CODE'
- assume CS:FLAT,DS:FLAT,SS:FLAT
- else
-_TEXT segment dword public 'CODE'
- assume CS:_TEXT
- endif
- endm
-
-endcode macro module
-_TEXT ENDS
- endm
-
-begdata macro
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Set up segments for data
-; Regular initialized data goes in _DATA
-
-_DATA segment dword public 'DATA'
-_DATA ends
-
-;Function pointers to constructors
-XIB segment dword public 'DATA'
-XIB ends
-XI segment dword public 'DATA'
-XI ends
-XIE segment dword public 'DATA'
-XIE ends
-
-;Function pointers to destructors
-XCB segment dword public 'DATA'
-XCB ends
-XC segment dword public 'DATA'
-XC ends
-XCE segment dword public 'DATA'
-XCE ends
-
-;Constant data, such as switch tables, go here.
-
-CONST segment dword public 'CONST'
-CONST ends
-
-;Segment for uninitialized data. This is set to 0 by the startup code/OS,
-;so it does not consume room in the executable file.
-
-_BSS segment dword public 'BSS'
-_BSS ends
-
-HUGE_BSS segment dword public 'HUGE_BSS'
-HUGE_BSS ends
-
-EEND segment dword public 'ENDBSS'
-EEND ends
-
-STACK segment para stack 'STACK'
-STACK ends
-DGROUP group _DATA,XIB,XI,XIE,XCB,XC,XCE,CONST,_BSS,EEND,STACK
-
-_DATA segment
- if _FLAT
- assume DS:FLAT
- else
- assume DS:DGROUP
- endif
- endm
-
-enddata macro
-_DATA ends
- endm
-
-P equ 8 ; Offset of start of parameters on the stack frame
- ; From EBP assuming EBP was pushed.
-PS equ 4 ; Offset of start of parameters on the stack frame
- ; From ESP assuming EBP was NOT pushed.
-ESeqDS equ 0
-FSeqDS equ 0
-GSeqDS equ 0
-SSeqDS equ 1
-SIZEPTR equ 4 ; Size of a pointer
-LPTR equ 0
-SPTR equ 1
-LCODE equ 0
-
-func macro name
-_&name proc near
- ifndef name
-name equ _&name
- endif
- endm
-
-callm macro name
- call _&name
- endm
-
-;Macros to replace public, extrn, and endp for C-callable assembly routines,
-; and to define labels: c_label defines labels,
-; c_public replaces public, c_extrn replaces extrn, and c_endp replaces endp
-
-c_name macro name
- name equ _&name
- endm
-
-c_label macro name
-_&name:
- endm
-
-c_endp macro name
-_&name ENDP
- endm
-
-clr macro list ;clear a register
- irp reg,<list>
- xor reg,reg
- endm
- endm
-
-jmps macro lbl
- jmp short lbl
- endm
diff --git a/strings/memcmp.c b/strings/memcmp.c
deleted file mode 100644
index 9471353f751..00000000000
--- a/strings/memcmp.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright (C) 2000 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* memcmp(lhs, rhs, len)
- compares the two memory areas lhs[0..len-1] ?? rhs[0..len-1]. It
- returns an integer less than, equal to, or greater than 0 according
- as lhs[-] is lexicographically less than, equal to, or greater than
- rhs[-]. Note that this is not at all the same as bcmp, which tells
- you *where* the difference is but not what.
-
- Note: suppose we have int x, y; then memcmp(&x, &y, sizeof x) need
- not bear any relation to x-y. This is because byte order is machine
- dependent, and also, some machines have integer representations that
- are shorter than a machine word and two equal integers might have
- different values in the spare bits. On a ones complement machine,
- -0 == 0, but the bit patterns are different.
-*/
-
-#include "strings.h"
-
-#if !defined(HAVE_MEMCPY)
-
-int memcmp(lhs, rhs, len)
- register char *lhs, *rhs;
- register int len;
-{
- while (--len >= 0)
- if (*lhs++ != *rhs++) return (uchar) lhs[-1] - (uchar) rhs[-1];
- return 0;
-}
-
-#endif
diff --git a/strings/memcpy.c b/strings/memcpy.c
deleted file mode 100644
index f32d346e3ec..00000000000
--- a/strings/memcpy.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Copyright (C) 2000 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/*
- memcpy(dst, src, len)
- moves len bytes from src to dst. The result is dst. This is not
- the same as strncpy or strnmov, while move a maximum of len bytes
- and stop early if they hit a NUL character. This moves len bytes
- exactly, no more, no less. See also bcopy() and bmove() which do
- not return a value but otherwise do the same job.
-*/
-
-#include "strings.h"
-
-char *memcpy(char *dst, register char *src, register int len)
-{
- register char *d;
-
- for (d = dst; --len >= 0; *d++ = *src++) ;
- return dst;
-}
diff --git a/strings/memset.c b/strings/memset.c
deleted file mode 100644
index e07dc4ead85..00000000000
--- a/strings/memset.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright (C) 2000 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* File : memset.c
- Author : Richard A. O'Keefe.
- Updated: 25 May 1984
- Defines: memset()
-
- memset(dst, chr, len)
- fills the memory area dst[0..len-1] with len bytes all equal to chr.
- The result is dst. See also bfill(), which has no return value and
- puts the last two arguments the other way around.
-
- Note: the VAX assembly code version can only handle 0 <= len < 2^16.
- It is presented for your interest and amusement.
-*/
-
-#include "strings.h"
-
-#if VaxAsm
-
-char *memset(char *dst,int chr, int len)
-{
- asm("movc5 $0,*4(ap),8(ap),12(ap),*4(ap)");
- return dst;
-}
-
-#else ~VaxAsm
-
-char *memset(char *dst, register pchar chr, register int len)
-{
- register char *d;
-
- for (d = dst; --len >= 0; *d++ = chr) ;
- return dst;
-}
-
-#endif VaxAsm
diff --git a/strings/ptr_cmp.asm b/strings/ptr_cmp.asm
deleted file mode 100644
index b2a020d8a37..00000000000
--- a/strings/ptr_cmp.asm
+++ /dev/null
@@ -1,180 +0,0 @@
-; Copyright (C) 2000 MySQL AB
-;
-; This library is free software; you can redistribute it and/or
-; modify it under the terms of the GNU Library General Public
-; License as published by the Free Software Foundation; version 2
-; of the License.
-;
-; This library 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
-; Library General Public License for more details.
-;
-; You should have received a copy of the GNU Library General Public
-; License along with this library; if not, write to the Free
-; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-; MA 02111-1307, USA
-
- TITLE Optimized cmp of pointer to strings of unsigned chars
-
-ifndef M_I386
- .8087
- DOSSEG
- .MODEL LARGE
- .DATA
-compare_length dw 0
- .CODE STRINGS
-
- PUBLIC _get_ptr_compare
-_get_ptr_compare PROC
- mov bx,sp
- mov cx,ss:[BX+4]
- mov compare_length,cx
- mov dx,seg strings:_ptr_cmp
- mov ax,offset _ptr_cmp_0
- jcxz @F
- mov ax,offset _ptr_cmp_1
- dec cx
- jz @F
- mov ax,offset _ptr_cmp
-@@: ret
-_get_ptr_compare ENDP
-
-_ptr_cmp_0 PROC
- mov AX,0 ; Emptyt strings are always equal
- ret
-_ptr_cmp_0 ENDP
-
-
-_ptr_cmp_1 PROC
- mov bx,sp
- mov dx,si ; Save si and ds
- mov cx,ds
- lds si,DWORD PTR ss:[bx+4] ; s1
- lds si,DWORD PTR ds:[si]
- mov al,ds:[si]
- xor ah,ah
- lds si,DWORD PTR ss:[bx+8] ; s2
- lds si,DWORD PTR ds:[si]
- mov bl,ds:[si]
- mov bh,ah
- sub ax,bx
- mov ds,cx ; restore si and ds
- mov si,dx
- ret
-_ptr_cmp_1 ENDP
-
-_ptr_cmp PROC
- mov bx,bp ; Save bp
- mov dx,di ; Save di
- mov bp,sp
- push ds
- push si
- mov cx,compare_length ; Length of memory-area
- lds si,DWORD PTR [bp+4] ; s1
- lds si,DWORD PTR ds:[si]
- les di,DWORD PTR [bp+8] ; s2
- les di,DWORD PTR es:[di]
-; cld ; Work uppward
- xor ax,ax
- repe cmpsb ; Compare strings
- je @F ; Strings are equal
- sbb ax,ax
- cmc
- adc ax,0
-
-@@: pop si
- pop ds
- mov di,dx
- mov bp,bx
- ret
-_ptr_cmp ENDP
-
-else
-
-include macros.asm
-
-fix_es MACRO fix_cld ; Load ES if neaded
- ife ESeqDS
- mov ax,ds
- mov es,ax
- endif
- ifnb <fix_cld>
- cld
- endif
- ENDM
-
- begdata
-compare_length dd 0 ; Length of strings
- enddata
-
- begcode get_ptr_compare
- public _get_ptr_compare
-_get_ptr_compare proc near
- mov ecx,P-SIZEPTR[esp]
- mov compare_length,ecx
- mov eax,offset _TEXT:_ptr_cmp_0
- jecxz @F
- mov eax,offset _TEXT:_ptr_cmp_1
- dec ecx
- jz @F
- mov eax,offset _TEXT:_ptr_cmp
-@@: ret
-_get_ptr_compare endp
- endcode _get_ptr_compare
-
-
- begcode ptr_cmp_0
-_ptr_cmp_0 PROC
- mov EAX,0 ; Emptyt strings are always equal
- ret
-_ptr_cmp_0 ENDP
- endcode ptr_cmp_0
-
-
- begcode ptr_cmp_1
-_ptr_cmp_1 proc near
- mov edx,esi ; Save esi
- mov esi,P-SIZEPTR[esp] ; *s1
- mov esi,[esi]
- movzx eax,[esi]
- mov esi,P[esp] ; *s2
- mov esi,[esi]
- movzx ecx,[esi]
- sub eax,ecx
- mov esi,edx ; Restore esi
- ret
-_ptr_cmp_1 ENDP
- endcode ptr_cmp_1
-
-
- begcode ptr_cmp
-_ptr_cmp proc near
- fix_es 1
- push ebp
- mov ebp,esp
- mov edx,edi ; Save esi
- push esi
- mov esi,P[ebp] ; *s1
- mov esi,[esi]
- mov edi,P+SIZEPTR[ebp] ; *s2
- mov edi,[edi]
- mov ecx,compare_length ; Length of memory-area
- xor eax,eax
- repe cmpsb ; Compare strings
- je @F ; Strings are equal
-
- sbb eax,eax
- cmc
- adc eax,0
-
-@@: pop esi
- mov edi,edx
- pop ebp
- ret
-_ptr_cmp ENDP
- endcode ptr_cmp
-
-endif
-
- END
diff --git a/strings/strcat.c b/strings/strcat.c
deleted file mode 100644
index e69369c357f..00000000000
--- a/strings/strcat.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright (C) 2000 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* File : strcat.c
- Author : Richard A. O'Keefe.
- Updated: 10 April 1984
- Defines: strcat()
-
- strcat(s, t) concatenates t on the end of s. There had better be
- enough room in the space s points to; strcat has no way to tell.
- Note that strcat has to search for the end of s, so if you are doing
- a lot of concatenating it may be better to use strmov, e.g.
- strmov(strmov(strmov(strmov(s,a),b),c),d)
- rather than
- strcat(strcat(strcat(strcpy(s,a),b),c),d).
- strcat returns the old value of s.
-*/
-
-#include "strings.h"
-
-char *strcat(register char *s, register const char *t)
-{
- char *save;
-
- for (save = s; *s++; ) ;
- for (--s; *s++ = *t++; ) ;
- return save;
- }
diff --git a/strings/strchr.c b/strings/strchr.c
deleted file mode 100644
index 5ffe386c718..00000000000
--- a/strings/strchr.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright (C) 2000 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* File : strchr.c
- Author : Richard A. O'Keefe.
- Michael Widenius: ifdef MC68000
- Updated: 20 April 1984
- Defines: strchr(), index()
-
- strchr(s, c) returns a pointer to the first place in s where c
- occurs, or NullS if c does not occur in s. This function is called
- index in V7 and 4.?bsd systems; while not ideal the name is clearer
- than strchr, so index remains in strings.h as a macro. NB: strchr
- looks for single characters, not for sets or strings. To find the
- NUL character which closes s, use strchr(s, '\0') or strend(s). The
- parameter 'c' is declared 'int' so it will go in a register; if your
- C compiler is happy with register _char_ change it to that.
-*/
-
-#include "strings.h"
-
-#if defined(MC68000) && defined(DS90)
-
-char* strchr(char *s, pchar c)
-{
-asm(" movl 4(a7),a0 ");
-asm(" movl 8(a7),d1 ");
-asm(".L2: movb (a0)+,d0 ");
-asm(" cmpb d0,d1 ");
-asm(" beq .L1 ");
-asm(" tstb d0 ");
-asm(" bne .L2 ");
-asm(" moveq #0,d0 ");
-asm(" rts ");
-asm(".L1: movl a0,d0 ");
-asm(" subql #1,d0 ");
-}
-#else
-
-char *strchr(register const char *s, register pchar c)
-{
- for (;;)
- {
- if (*s == (char) c) return (char*) s;
- if (!*s++) return NullS;
- }
-}
-
-#endif
diff --git a/strings/strcmp.c b/strings/strcmp.c
deleted file mode 100644
index 54bbe92279b..00000000000
--- a/strings/strcmp.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright (C) 2000 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* File : strcmp.c
- Author : Richard A. O'Keefe.
- Updated: 10 April 1984
- Defines: strcmp()
-
- strcmp(s, t) returns > 0, = 0, or < 0 when s > t, s = t, or s < t
- according to the ordinary lexicographical order. To test for
- equality, the macro streql(s,t) is clearer than !strcmp(s,t). Note
- that if the string contains characters outside the range 0..127 the
- result is machine-dependent; PDP-11s and VAXen use signed bytes,
- some other machines use unsigned bytes.
-*/
-
-#include "strings.h"
-
-int strcmp(register const char *s, register const char *t)
-{
- while (*s == *t++) if (!*s++) return 0;
- return s[0]-t[-1];
-}
diff --git a/strings/strings.asm b/strings/strings.asm
deleted file mode 100644
index 2224025cc72..00000000000
--- a/strings/strings.asm
+++ /dev/null
@@ -1,1060 +0,0 @@
-; Copyright (C) 2000, 2003 MySQL AB
-;
-; This library is free software; you can redistribute it and/or
-; modify it under the terms of the GNU Library General Public
-; License as published by the Free Software Foundation; version 2
-; of the License.
-;
-; This library 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
-; Library General Public License for more details.
-;
-; You should have received a copy of the GNU Library General Public
-; License along with this library; if not, write to the Free
-; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-; MA 02111-1307, USA
-
-; Note that if you don't have a macro assembler (like MASM) to compile
-; this file, you can instead compile all *.c files in the string
-; directory.
-
- TITLE Stringfunctions that we use often at MSDOS / Intel 8086
-
-ifndef M_I386
- .8087
- DOSSEG
- .MODEL LARGE
- .CODE
-
- ;
- ; Some macros
- ;
-
-q_movs MACRO ; as rep movsb but quicker
- shr cx,1
- rep movsw ; Move 2 bytes at a time
- adc cx,cx
- rep movsb ; Move last byte if any
- ENDM
-
-q_stos MACRO ; as rep stosb but quicker
- mov ah,al ; For word store
- shr cx,1
- rep stosw ; Move 2 bytes at a time
- adc cx,cx
- rep stosb ; Move last byte if any
- ENDM
-
-ifndef ZTC ; If not using ZORTECH compiler
- ;
- ; Compare memory
- ; Args: s1,s2,length
- ;
-
- PUBLIC _bcmp
-_bcmp PROC
- mov bx,bp ; Save bp
- mov dx,di ; Save di
- mov bp,sp
- push ds
- push si
- les di,DWORD PTR [bp+8] ; s2
- lds si,DWORD PTR [bp+4] ; s1
- mov cx,WORD PTR [bp+12] ; Length of memory-area
- jcxz @F ; Length = 0, return same
-; cld ; Work uppward
- repe cmpsb ; Compare strings
- jz @F ; Match found
- inc cx ; return matchpoint +1
-@@: mov ax,cx ; Return 0 if match, else pos from end
- pop si
- pop ds
- mov di,dx
- mov bp,bx
- ret
-_bcmp ENDP
-
- ;
- ; Find a char in a string
- ; Arg: str,char
- ; Ret: pointer to found char or NullS
- ;
-
-ifdef better_stringfunctions ; Breaks window linkage (broken linking)
-
- PUBLIC _strchr
-_strchr PROC
- mov bx,bp ; Save bp and di
- mov dx,di
- mov bp,sp
- les di,DWORD PTR [bp+4] ; str
- mov ah,BYTE PTR [bp+8] ; search
- xor al,al ; for scasb to find end
-
-@@: cmp ah,es:[di]
- jz @F ; Found char
- scasb
- jnz @B ; Not end
- xor di,di ; Not found
- mov es,di
-@@: mov ax,di
- mov di,dx ; Restore
- mov dx,es ; Seg adr
- mov bp,bx ; Restore
- ret
-_strchr ENDP
-
- ;
- ; Find length of string
- ; arg: str
- ; ret: length
- ;
-
- PUBLIC _strlen
-_strlen PROC
- mov bx,sp
- mov dx,di
- les di,DWORD PTR ss:[bx+4] ; Str
- xor al,al ; Find end of string
- mov cx,-1
-; cld
- repne scasb ; Find strend or length
- inc cx ; Calc strlength
- not cx
- mov ax,cx
- mov di,dx ; Restore register
- ret
-_strlen ENDP
-
-endif
-
- ;
- ; Move a string
- ; arg: dst,src
- ; ret: end-null of to
- ;
-
- PUBLIC _strmov
-_strmov PROC
- mov bx,bp
- mov cx,si
- mov bp,sp
- push ds
- push di
- les di,DWORD PTR [bp+4] ; dst
- lds si,DWORD PTR [bp+8] ; src
-; cld
-@@: mov al,ds:[si]
- movsb ; move arg
- and al,al
- jnz @B ; Not last
- lea ax,WORD PTR [di-1] ; Set DX:AX to point at last null
- mov dx,es
- pop di
- pop ds
- mov si,cx
- mov bp,bx
- ret
-_strmov ENDP
-
- ;
- ; Fill a area of memory with a walue
- ; Args: to,length,fillchar
- ;
-
- PUBLIC _bfill
-_bfill PROC
- mov bx,sp ; Get args through BX
- mov al,BYTE PTR ss:[bx+10] ; Fill
-bfill_10:
- mov dx,di ; Save di
- les di,DWORD PTR ss:[bx+4] ; Memory pointer
- mov cx,WORD PTR ss:[bx+8] ; Length
-; cld
- q_stos
- mov di,dx
- ret
-_bfill ENDP
-
- ;
- ; Fill a area with null
- ; Args: to,length
-
- PUBLIC _bzero
-_bzero PROC
- mov bx,sp ; Get args through BX
- mov al,0 ; Fill with null
- jmp short bfill_10
-_bzero ENDP
-
-endif ; ZTC
-
- ;
- ; Move a memory area
- ; Args: to,from,length
- ;
-
- PUBLIC _bmove
-_bmove PROC
- mov bx,bp
- mov dx,di
- mov ax,si
- mov bp,sp
- push ds
- lds si,DWORD PTR [bp+8] ; from
- les di,DWORD PTR [bp+4] ; to
- mov cx,WORD PTR [bp+12] ; Length of memory-area
-; cld ; Work uppward
- rep movsb ; Not q_movs because overlap ?
- pop ds
- mov si,ax
- mov di,dx
- mov bp,bx
- ret
-_bmove ENDP
-
- ;
- ; Move a alligned, not overlapped, by (long) divided memory area
- ; Args: to,from,length
- ;
-
- PUBLIC _bmove_align
-_bmove_align PROC
- mov bx,bp
- mov dx,di
- mov ax,si
- mov bp,sp
- push ds
- lds si,DWORD PTR [bp+8] ; from
- les di,DWORD PTR [bp+4] ; to
- mov cx,WORD PTR [bp+12] ; Length of memory-area
-; cld ; Work uppward
- inc cx ; fix if not divisible with word
- shr cx,1
- rep movsw ; Move 2 bytes at a time
- pop ds
- mov si,ax
- mov di,dx
- mov bp,bx
- ret
-_bmove_align ENDP
-
- ;
- ; Move a string from higher to lower
- ; Arg from+1,to+1,length
- ;
-
- PUBLIC _bmove_upp
-_bmove_upp PROC
- mov bx,bp
- mov dx,di
- mov ax,si
- mov bp,sp
- push ds
- lds si,DWORD PTR [bp+8] ; from
- les di,DWORD PTR [bp+4] ; to
- mov cx,WORD PTR [bp+12] ; Length of memory-area
- dec di ; Don't move last arg
- dec si
- std ; Work downward
- rep movsb ; Not q_movs because overlap ?
- cld ; C compilator want cld
- pop ds
- mov si,ax
- mov di,dx
- mov bp,bx
- ret
-_bmove_upp ENDP
-
- ;
- ; Append fillchars to string
- ; Args: dest,len,fill
- ;
-
- PUBLIC _strappend
-_strappend PROC
- mov bx,bp
- mov dx,di
- mov bp,sp
- les di,DWORD PTR [bp+4] ; Memory pointer
- mov cx,WORD PTR [bp+8] ; Length
- sub al,al ; Find end of string
-; cld
- repne scasb
- jnz sa_99 ; String to long, shorten it
- mov al,BYTE PTR [bp+10] ; Fillchar
- dec di ; Point at end null
- inc cx ; rep made one dec for null-char
- q_stos ; Store al in string
-sa_99: mov BYTE PTR es:[di],0 ; End of string
- mov di,dx
- mov bp,bx
- ret
-_strappend ENDP
-
- ;
- ; Find if string contains any char in another string
- ; Arg: str,set
- ; Ret: Pointer to first found char in str
- ;
-
- PUBLIC _strcont
-_strcont PROC
- mov bx,bp ; Save bp and di in regs
- mov dx,di
- mov bp,sp
- push ds
- push si
- lds si,DWORD PTR [bp+4] ; str
- les di,DWORD PTR [bp+8] ; Set
- mov cx,di ; Save for loop
- xor ah,ah ; For endtest
- jmp sc_60
-
-sc_10: scasb
- jz sc_fo ; Found char
-sc_20: cmp ah,es:[di] ; Test if null
- jnz sc_10 ; Not end of set yet
- inc si ; Next char in str
- mov di,cx ; es:di = Set
-sc_60: mov al,ds:[si] ; Test if this char exist
- and al,al
- jnz sc_20 ; Not end of string
- sub si,si ; Return Null
- mov ds,si
-sc_fo: mov ax,si ; Char found here
- mov di,dx ; Restore
- mov dx,ds ; Seg of found char
- pop si
- pop ds
- mov bp,bx
- ret
-_strcont ENDP
-
- ;
- ; Found end of string
- ; Arg: str
- ; ret: Pointer to end null
- ;
-
- PUBLIC _strend
-_strend PROC
- mov bx,sp
- mov dx,di ; Save
- les di,DWORD PTR ss:[bx+4] ; str
- mov cx,-1
- sub al,al ; Find end of string
-; cld
- repne scasb
- lea ax,WORD PTR [di-1] ; Endpos i DX:AX
- mov di,dx ; Restore
- mov dx,es
- ret
-_strend ENDP
-
- ;
- ; Make a string with len fill-chars and endnull
- ; Args: dest,len,fill
- ; Ret: dest+len
- ;
-
- PUBLIC _strfill
-_strfill PROC
- mov bx,bp ; Save sp
- mov bp,sp
- push di
- les di,DWORD PTR [bp+4] ; Memory pointer
- mov cx,WORD PTR [bp+8] ; Length
- mov al,BYTE PTR [bp+10] ; Fill
-; cld
- q_stos
- mov BYTE PTR es:[di],0 ; End NULL
- mov ax,di ; End i DX:AX
- mov dx,es
- pop di
- mov bp,bx
- ret
-_strfill ENDP
-
- ;
- ; Find a char in or end of a string
- ; Arg: str,char
- ; Ret: pointer to found char or NullS
- ;
-
- PUBLIC _strcend
-_strcend PROC
- mov bx,bp ; Save bp and di
- mov dx,di
- mov bp,sp
- les di,DWORD PTR [bp+4] ; str
- mov ah,BYTE PTR [bp+8] ; search
- xor al,al ; for scasb to find end
-
-@@: cmp ah,es:[di]
- jz @F ; Found char
- scasb
- jnz @B ; Not end
- dec di ; Not found, point at end of string
-@@: mov ax,di
- mov di,dx ; Restore
- mov dx,es ; Seg adr
- mov bp,bx ; Restore
- ret
-_strcend ENDP
-
- ;
- ; Test if string has a given suffix
- ;
-
-PUBLIC _is_prefix
-_is_prefix PROC
- mov dx,di ; Save di
- mov bx,sp ; Arguments through bx
- push ds
- push si
- les di,DWORD PTR ss:[bx+8] ; s2
- lds si,DWORD PTR ss:[bx+4] ; s1
- mov ax,1 ; Ok and zero-test
-; cld ; Work uppward
-@@: cmp ah,es:[di]
- jz suf_ok ; End of string; found suffix
- cmpsb ; Compare strings
- jz @B ; Same, possible prefix
- xor ax,ax ; Not suffix
-suf_ok: pop si
- pop ds
- mov di,dx
- ret
-_is_prefix ENDP
-
- ;
- ; Find a substring in string
- ; Arg: str,search
- ;
-
- PUBLIC _strstr
-_strstr PROC
- mov bx,bp
- mov bp,sp
- push ds
- push di
- push si
- lds si,DWORD PTR [bp+4] ; str
- les di,DWORD PTR [bp+8] ; search
- mov cx,di
- inc cx ; CX = search+1
- mov ah,es:[di] ; AH = First char in search
- jmp sf_10
-
-sf_00: mov si,dx ; si = Current str-pos
-sf_10: mov al,ds:[si] ; Test if this char exist
- and al,al
- jz sf_90 ; End of string, didn't find search
- inc si
- cmp al,ah
- jnz sf_10 ; Didn't find first char, continue
- mov dx,si ; Save str-pos in DX
- mov di,cx
-sf_20: cmp BYTE PTR es:[di],0
- jz sf_fo ; Found substring
- cmpsb
- jz sf_20 ; Char ok
- jmp sf_00 ; Next str-pos
-
-sf_90: sub dx,dx ; Return Null
- mov ds,dx
- inc dx ; Because of following dec
-sf_fo: mov ax,dx ; Char found here
- dec ax ; Pointed one after
- mov dx,ds
- pop si
- pop di ; End
- pop ds
- mov bp,bx
- ret
-_strstr ENDP
-
- ;
- ; Find a substring in string, return index
- ; Arg: str,search
- ;
-
- PUBLIC _strinstr
-_strinstr PROC
- push bp
- mov bp,sp
- push di
- les di,DWORD PTR [bp+10] ; search
- push es
- push di
- les di,DWORD PTR [bp+6] ; str
- push es
- push di
- call _strstr
- mov cx,ax
- or cx,dx
- jz si_99
- sub ax,di ; Pos from start
- inc ax ; And first pos = 1
-si_99: add sp,8
- pop di
- pop bp
- ret
-_strinstr ENDP
-
- ;
- ; Make a string of len length from another string
- ; Arg: dst,src,length
- ; ret: end of dst
- ;
-
- PUBLIC _strmake
-_strmake PROC
- mov bx,bp
- mov bp,sp
- push ds
- push di
- push si
- les di,DWORD PTR [bp+4] ; dst
- lds si,DWORD PTR [bp+8] ; src
- mov cx,WORD PTR [bp+12] ; Length of memory-area
- xor al,al ; For test of end-null
- jcxz sm_90 ; Nothing to move, put zero at end.
-; cld ; Work uppward
-
-@@: cmp al,ds:[si] ; Next char to move
- movsb ; move arg
- jz sm_99 ; last char, we are ready
- loop @B ; Continue moving
-sm_90: mov BYTE PTR es:[di],al ; Set end pos
- inc di ; Fix that di points at end null
-sm_99: dec di ; di points now at end null
- mov ax,di ; Ret value in DX:AX
- mov dx,es
- pop si
- pop di
- pop ds
- mov bp,bx
- ret
-_strmake ENDP
-
- ;
- ; Find length of string with maxlength
- ; arg: str,maxlength
- ; ret: length
- ;
-
- PUBLIC _strnlen
-_strnlen PROC
- mov bx,bp
- mov bp,sp
- push di
- les di,DWORD PTR [bp+4] ; Str
- mov cx,WORD PTR [bp+8] ; length
- mov dx,di ; Save str to calc length
- jcxz sn_10 ; Length = 0
- xor al,al ; Find end of string
-; cld
- repne scasb ; Find strend or length
- jnz sn_10
- dec di ; DI points at last null
-sn_10: mov ax,di
- sub ax,dx ; Ax = length
- pop di
- mov bp,bx
- ret
-_strnlen ENDP
-
- ;
- ; Move a string with max len chars
- ; arg: dst,src,len
- ; ret: pos to first null or dst+len
-
- PUBLIC _strnmov
-_strnmov PROC
- mov bx,bp
- mov bp,sp
- push ds
- push di
- push si
- les di,DWORD PTR [bp+4] ; dst
- lds si,DWORD PTR [bp+8] ; src
- mov cx,WORD PTR [bp+12] ; length
- jcxz snm_99 ; Nothing to do
- xor al,al ; For test of end-null
-; cld
-
-@@: cmp al,ds:[si] ; Next char to move
- movsb ; move arg
- jz snm_20 ; last char, fill with null
- loop @B ; Continue moving
- inc di ; Point two after last
-snm_20: dec di ; Point at first null (or last+1)
-snm_99: mov ax,di ; Pointer at last char
- mov dx,es ; To-segment
- pop si
- pop di
- pop ds
- mov bp,bx ; Restore
- ret
-_strnmov ENDP
-
-else ; M_I386
-
-include macros.asm
-
-q_stos MACRO ; as rep stosb but quicker, Uses edx
- mov ah,al ;(2) Set up a 32 bit pattern.
- mov edx,eax ;(2)
- shl edx,16 ;(3)
- or eax,edx ;(2) EAX has the 32 bit pattern.
-
- mov edx,ecx ;(2) Save the count of bytes.
- shr ecx,2 ;(2) Number of dwords.
- rep stosd ;(5 + 5n)
- mov cl,3 ;(2)
- and ecx,edx ;(2) Fill in the remaining odd bytes.
- rep stosb ; Move last bytes if any
- ENDM
-
-fix_es MACRO fix_cld ; Load ES if neaded
- ife ESeqDS
- mov ax,ds
- mov es,ax
- endif
- ifnb <fix_cld>
- cld
- endif
- ENDM
-
- ;
- ; Move a memory area
- ; Args: to,from,length
- ; Acts as one byte was moved a-time from dst to source.
- ;
-
- begcode bmove
- public _bmove
-_bmove proc near
- fix_es 1
- mov edx,edi
- mov eax,esi
- mov edi,P-SIZEPTR[esp] ;p1
- mov esi,P[esp] ;p2
- mov ecx,P+SIZEPTR[esp]
- rep movsb ; Not q_movs because overlap ?
- mov esi,eax
- mov edi,edx
- ret
-_bmove ENDP
- endcode bmove
-
- ;
- ; Move a alligned, not overlapped, by (long) divided memory area
- ; Args: to,from,length
- ;
-
- begcode bmove_align
- public _bmove_align
-_bmove_align proc near
- fix_es 1
- mov edx,edi
- mov eax,esi
- mov edi,P-SIZEPTR[esp] ;to
- mov esi,P[esp] ;from
- mov ecx,P+SIZEPTR[esp] ;length
- add cx,3 ;fix if not divisible with long
- shr cx,2
- rep movsd
- mov esi,eax
- mov edi,edx
- ret
-_bmove_align ENDP
- endcode bmove_align
-
- ;
- ; Move a string from higher to lower
- ; Arg from+1,to+1,length
- ;
-
- begcode bmove_upp
- public _bmove_upp
-_bmove_upp proc near
- fix_es
- std ; Work downward
- mov edx,edi
- mov eax,esi
- mov edi,P-SIZEPTR[esp] ;p1
- mov esi,P[esp] ;p2
- mov ecx,P+SIZEPTR[esp]
- dec edi ; Don't move last arg
- dec esi
- rep movsb ; One byte a time because overlap !
- cld ; C compilator wants cld
- mov esi,eax
- mov edi,edx
- ret
-_bmove_upp ENDP
- endcode bmove_upp
-
- ;
- ; Append fillchars to string
- ; Args: dest,len,fill
- ;
-
- begcode strappend
- public _strappend
-_strappend proc near
- push ebp
- mov ebp,esp
- fix_es 1
- push edi
- mov edi,P[ebp] ; Memory pointer
- mov ecx,P+SIZEPTR[ebp] ; Length
- clr eax ; Find end of string
- repne scasb
- jnz sa_99 ; String to long, shorten it
- movzx eax,byte ptr P+(2*SIZEPTR)[ebp] ; Fillchar
- dec edi ; Point at end null
- inc ecx ; rep made one dec for null-char
- q_stos ; Store al in string
-sa_99: mov BYTE PTR [edi],0 ; End of string
- pop edi
- pop ebp
- ret
-_strappend ENDP
- endcode strappend
-
- ;
- ; Find if string contains any char in another string
- ; Arg: str,set
- ; Ret: Pointer to first found char in str
- ;
-
- begcode strcont
- PUBLIC _strcont
-_strcont proc near
- push ebp
- mov ebp,esp
- fix_es 1
- mov edx,edi
- push esi
- mov esi,P[ebp] ; str
- mov ecx,P+SIZEPTR[ebp] ; Set
- clr ah ; For endtest
- jmps sc_60
-
-sc_10: scasb
- jz sc_fo ; Found char
-sc_20: cmp ah,[edi] ; Test if null
- jnz sc_10 ; Not end of set yet
- inc esi ; Next char in str
-sc_60: mov edi,ecx ; edi = Set
- mov al,[esi] ; Test if this char exist
- and al,al
- jnz sc_20 ; Not end of string
- clr esi ; Return Null
-sc_fo: mov eax,esi ; Char found here
- mov edi,edx ; Restore
- pop esi
- pop ebp
- ret
-_strcont ENDP
- endcode strcont
-
- ;
- ; Found end of string
- ; Arg: str
- ; ret: Pointer to end null
- ;
-
- begcode strend
- public _strend
-_strend proc near
- fix_es 1
- mov edx,edi ; Save
- mov edi,P-SIZEPTR[esp] ; str
- clr eax ; Find end of string
- mov ecx,eax
- dec ecx ; ECX = -1
- repne scasb
- mov eax,edi
- dec eax
- mov edi,edx ; Restore
- ret
-_strend endp
- endcode strend
-
- ;
- ; Make a string with len fill-chars and endnull
- ; Args: dest,len,fill
- ; Ret: dest+len
- ;
-
- begcode strfill
- public _strfill
-_strfill proc near
- push ebp
- mov ebp,esp
- fix_es 1
- push edi
- mov edi,P[ebp] ; Memory pointer
- mov ecx,P+SIZEPTR[ebp] ; Length
- movzx eax,byte ptr P+(2*SIZEPTR)[ebp] ; Fill
- q_stos
- mov BYTE PTR [edi],0 ; End NULL
- mov eax,edi ; End i DX:AX
- pop edi
- pop ebp
- ret
-_strfill endp
- endcode strfill
-
- ;
- ; Find a char in or end of a string
- ; Arg: str,char
- ; Ret: pointer to found char or NullS
- ;
-
- begcode strcend
- public _strcend
-_strcend proc near
- push ebp
- mov ebp,esp
- fix_es 1
- mov edx,edi
- mov edi,P[ebp] ; str
- mov ah,P+SIZEPTR[ebp] ; search
- clr al ; for scasb to find end
-
-@@: cmp ah,[edi]
- jz @F ; Found char
- scasb
- jnz @B ; Not end
- dec edi ; Not found, point at end of string
-@@: mov eax,edi
- mov edi,edx ; Restore
- pop ebp
- ret
-_strcend ENDP
- endcode strcend
-
- ;
- ; Test if string has a given suffix
- ;
-
- begcode is_prefix
- public _is_prefix
-_is_prefix proc near
- fix_es 1
- mov edx,edi ; Save edi
- mov eax,esi ; Save esi
- mov esi,P[esp] ; get suffix
- mov edi,P-SIZEPTR[esp] ; s1
- push eax ; push esi
- mov eax,1 ; Ok and zero-test
-@@: cmp ah,[esi]
- jz suf_ok ; End of string; found suffix
- cmpsb ; Compare strings
- jz @B ; Same, possible prefix
- xor eax,eax ; Not suffix
-suf_ok: pop esi
- mov edi,edx
- ret
-_is_prefix endp
- endcode _is_prefix
-
- ;
- ; Find a substring in string
- ; Arg: str,search
- ;
-
- begcode strstr
- public _strstr
-_strstr proc near
- push ebp
- mov ebp,esp
- fix_es 1
- push EDI
- push ESI
- mov esi,P[ebp] ; str
- mov edi,P+SIZEPTR[ebp] ; search
- mov ecx,edi
- inc ecx ; ECX = search+1
- mov ah,[edi] ; AH = First char in search
- jmps sf_10
-
-sf_00: mov esi,edx ; si = Current str-pos
-sf_10: mov al,[esi] ; Test if this char exist
- and al,al
- jz sf_90 ; End of string, didn't find search
- inc esi
- cmp al,ah
- jnz sf_10 ; Didn't find first char, continue
- mov edx,esi ; Save str-pos in EDX
- mov edi,ecx
-sf_20: cmp BYTE PTR [edi],0
- jz sf_fo ; Found substring
- cmpsb
- jz sf_20 ; Char ok
- jmps sf_00 ; Next str-pos
-
-sf_90: mov edx,1 ; Return Null
-sf_fo: mov eax,edx ; Char found here
- dec eax ; Pointed one after
- pop ESI
- pop EDI
- pop ebp
- ret
-_strstr endp
- endcode strstr
-
- ;
- ; Find a substring in string, return index
- ; Arg: str,search
- ;
-
- begcode strinstr
- public _strinstr
-_strinstr proc near
- push ebp
- mov ebp,esp
- push P+SIZEPTR[ebp] ; search
- push P[ebp] ; str
- call _strstr
- add esp,SIZEPTR*2
- or eax,eax
- jz si_99 ; Not found, return NULL
- sub eax,P[ebp] ; Pos from start
- inc eax ; And first pos = 1
-si_99: pop ebp
- ret
-_strinstr endp
- endcode strinstr
-
- ;
- ; Make a string of len length from another string
- ; Arg: dst,src,length
- ; ret: end of dst
- ;
-
- begcode strmake
- public _strmake
-_strmake proc near
- push ebp
- mov ebp,esp
- fix_es 1
- push EDI
- push ESI
- mov edi,P[ebp] ; dst
- mov esi,P+SIZEPTR[ebp] ; src
- mov ecx,P+SIZEPTR*2[ebp] ; Length of memory-area
- clr al ; For test of end-null
- jcxz sm_90 ; Nothing to move, put zero at end.
-
-@@: cmp al,[esi] ; Next char to move
- movsb ; move arg
- jz sm_99 ; last char, we are ready
- loop @B ; Continue moving
-sm_90: mov BYTE PTR [edi],al ; Set end pos
- inc edi ; Fix that di points at end null
-sm_99: dec edi ; di points now at end null
- mov eax,edi ; Ret value in DX:AX
- pop ESI
- pop EDI
- pop ebp
- ret
-_strmake ENDP
- endcode strmake
-
- ;
- ; Find length of string with maxlength
- ; arg: str,maxlength
- ; ret: length
- ;
-
- begcode strnlen
- public _strnlen
-_strnlen proc near
- push ebp
- mov ebp,esp
- fix_es 1
- push edi
- mov edi,P[ebp] ; Str
- mov ecx,P+SIZEPTR[ebp] ; length
- mov edx,edi ; Save str to calc length
- jcxz sn_10 ; Length = 0
- clr al ; Find end of string
- repne scasb ; Find strend or length
- jnz sn_10
- dec edi ; DI points at last null
-sn_10: mov eax,edi
- sub eax,edx ; Ax = length
- pop edi
- pop ebp
- ret
-_strnlen ENDP
- endcode strnlen
-
- ;
- ; Move a string with max len chars
- ; arg: dst,src,len
- ; ret: pos to first null or dst+len
-
- begcode strnmov
- public _strnmov
-_strnmov PROC near
- push ebp
- mov ebp,esp
- fix_es 1
- push EDI
- push ESI
- mov edi,P[ebp] ; dst
- mov esi,P+SIZEPTR[ebp] ; src
- mov ecx,P+(SIZEPTR*2)[ebp] ; length
- jcxz snm_99 ; Nothing to do
- clr al ; For test of end-null
-
-@@: cmp al,[esi] ; Next char to move
- movsb ; move arg
- jz snm_20 ; last char, fill with null
- loop @B ; Continue moving
- inc edi ; Point two after last
-snm_20: dec edi ; Point at first null (or last+1)
-snm_99: mov eax,edi ; Pointer at last char
- pop ESI
- pop EDI
- pop ebp
- ret
-_strnmov ENDP
- endcode strnmov
-
-;
-; Zortech has this one in standard library
-;
-
- begcode strmov
- public _strmov
-_strmov proc near
- mov ecx,esi ; Save old esi and edi
- mov edx,edi
- mov esi,P[esp] ; get source pointer (s2)
- mov edi,P-SIZEPTR[esp] ; EDI -> s1
- fix_es 1
-@@: mov al,[esi]
- movsb ; move arg
- and al,al
- jnz @B ; Not last
- mov eax,edi
- dec eax
- mov esi,ecx ; Restore args
- mov edi,edx
- ret
-_strmov endp
- endcode strmov
-
-endif ; M_I386
-
- END
diff --git a/strings/strlen.c b/strings/strlen.c
deleted file mode 100644
index 1469dd096ee..00000000000
--- a/strings/strlen.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright (C) 2000 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* File : strlen.c
- Author : Richard A. O'Keefe. / Monty
- Michael Widenius; ifdef MC68000
- Updated: 1986-11-30
- Defines: strlen()
-
- strlen(s) returns the number of characters in s, that is, the number
- of non-NUL characters found before the closing NULEosCh. Note: some
- non-standard C compilers for 32-bit machines take int to be 16 bits,
- either put up with short strings or change int to long throughout
- this package. Better yet, BOYCOTT such shoddy compilers.
- Beware: the asm version works only if strlen(s) < 65536.
-*/
-
-#include "strings.h"
-
-#if VaxAsm
-
-size_t strlen(char *s)
-{
- asm("locc $0,$65535,*4(ap)");
- asm("subl3 r0,$65535,r0");
-}
-
-#else
-#if defined(MC68000) && defined(DS90)
-
-size_t strlen(char *s)
-{
-asm(" movl 4(a7),a0 ");
-asm(" movl a0,a1 ");
-asm(".L4: tstb (a0)+ ");
-asm(" jne .L4 ");
-asm(" movl a0,d0 ");
-asm(" subl a1,d0 ");
-asm(" subql #1,d0 ");
-}
-#else
-
-size_t strlen(register char *s)
-{
- register char *startpos;
-
- startpos = s;
- while (*s++);
- return ((size_t) (s-startpos-1));
-}
-
-#endif
-#endif
diff --git a/strings/strrchr.c b/strings/strrchr.c
deleted file mode 100644
index cdb0479ef90..00000000000
--- a/strings/strrchr.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (C) 2000 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* File : strrchr.c
- Author : Richard A. O'Keefe.
- Updated: 10 April 1984
- Defines: strrchr(), rindex()
-
- strrchr(s, c) returns a pointer to the last place in s where c
- occurs, or NullS if c does not occur in s. This function is called
- rindex in V7 and 4.?bsd systems; while not ideal the name is clearer
- than strrchr, so rindex remains in strings.h as a macro. NB:
- strrchr looks for single characters, not for sets or strings. The
- parameter 'c' is declared 'int' so it will go in a register; if your
- C compiler is happy with register char change it to that.
-*/
-
-#include "strings.h"
-
-char *strrchr(register const char *s, register pchar c)
-{
- reg3 char *t;
-
- t = NullS;
- do if (*s == (char) c) t = (char*) s; while (*s++);
- return (char*) t;
-}
diff --git a/strings/strxmov.asm b/strings/strxmov.asm
deleted file mode 100644
index ad5d0dd3db0..00000000000
--- a/strings/strxmov.asm
+++ /dev/null
@@ -1,103 +0,0 @@
-; Copyright (C) 2000 MySQL AB
-;
-; This library is free software; you can redistribute it and/or
-; modify it under the terms of the GNU Library General Public
-; License as published by the Free Software Foundation; version 2
-; of the License.
-;
-; This library 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
-; Library General Public License for more details.
-;
-; You should have received a copy of the GNU Library General Public
-; License along with this library; if not, write to the Free
-; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-; MA 02111-1307, USA
-
- TITLE Optimized strxmov for MSDOS / Intel 8086
-
-ifndef M_I386
- .8087
- DOSSEG
- .MODEL LARGE
- .CODE
-
- PUBLIC _strxmov
-_strxmov PROC
- mov bx,sp
- add bx,4
- push si
- push di
- mov cx,ds ; Save ds
-ASSUME DS: NOTHING
-ASSUME ES: NOTHING
- les di,DWORD PTR ss:[bx] ; dst
- jmp next_str
-
-start_str:
- mov al,ds:[si]
- movsb ; move arg
- and al,al
- jnz start_str ; Not last
- dec di
-
-next_str:
- add bx,4
- lds si,DWORD PTR ss:[bx]
- mov ax,ds
- or ax,si
- jnz start_str
-
- mov byte ptr es:[di],0 ; Force end null (if no source)
- mov ds,cx
- mov ax,di ; Return ptr to last 0
- mov dx,es
- pop di
- pop si
- ret
-_strxmov ENDP
-
-else
-
-include macros.asm
-
- begcode strxmov
- public _strxmov
-
-_strxmov PROC near
-ASSUME DS: NOTHING
-ASSUME ES: NOTHING
- push EBP
- mov EBP,ESP
- mov EDX,EBX ; Save EBX
- mov ECX,ESI ; Save ESI
- push EDI
- mov EDI,8[EBP] ; Get destination
- lea EBX,8[EBP] ; Get adress to first source - 4
- xor al,al
- jmp next_str
-
-start_str: movsb
- cmp AL,[EDI-1]
- jne start_str
- dec EDI ; Don't copy last null
-
-next_str: add EBX,4
- mov ESI,[EBX]
- or ESI,ESI
- jne start_str
- mov byte ptr [EDI],0 ; Force last null
-
- mov EAX,EDI ; Return ptr to null
- pop EDI
- mov ESI,ECX
- mov EBX,EDX
- pop EBP
- ret
-_strxmov endp
- endcode strxmov
-
-endif
-
- END
diff --git a/strings/udiv.c b/strings/udiv.c
deleted file mode 100644
index 81ac01ee9c3..00000000000
--- a/strings/udiv.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (C) 2000 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Do udiv and urem if machine dosn't have it */
-
-#include <my_global.h>
-#include <math.h>
-
-unsigned long udiv(long unsigned int a, long unsigned int b)
-{
- if (a < INT_MAX32 && b < INT_MAX32)
- return (unsigned long) ((long) a / (long) b);
- if (!(b & 1))
- return (unsigned long) ((long) (a >> 1) / (long) (b >> 1));
-
- return (unsigned long) floor(((double) a / (double) b));
-}
-
-unsigned long urem(long unsigned int a, long unsigned int b)
-{
- if (a < INT_MAX32 && b < INT_MAX32)
- return (unsigned long) ((long) a % (long) b);
- return a-udiv(a,b)*b;
-}
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index 657dd3fbbdf..4ea34f13ce9 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -121,43 +121,62 @@
%define distro_specific 0
%endif
%if %{distro_specific}
- %if %(test -f /etc/redhat-release && echo 1 || echo 0)
- %define elver %(rpm -qf --qf '%%{version}\\n' /etc/redhat-release | sed -e 's/^\\([0-9]*\\).*/\\1/g')
+ %if %(test -f /etc/enterprise-release && echo 1 || echo 0)
+ %define elver %(rpm -qf --qf '%%{version}\\n' /etc/enterprise-release | sed -e 's/^\\([0-9]*\\).*/\\1/g')
%if "%elver" == "4"
- %define distro_description Enterprise Linux 4
+ %define distro_description Oracle Enterprise Linux 4
%define distro_releasetag el4
%define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel
%define distro_requires chkconfig coreutils grep procps shadow-utils
%else
%if "%elver" == "5"
- %define distro_description Enterprise Linux 5
+ %define distro_description Oracle Enterprise Linux 5
%define distro_releasetag el5
%define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel
%define distro_requires chkconfig coreutils grep procps shadow-utils
%else
- %{error:Enterprise Linux %{elver} is unsupported}
+ %{error:Oracle Enterprise Linux %{elver} 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)
- %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
+ %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" == "4"
+ %define distro_description Red Hat Enterprise Linux 4
+ %define distro_releasetag rhel4
+ %define distro_buildreq gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel
+ %define distro_requires chkconfig coreutils grep procps shadow-utils
%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
+ %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
%else
- %{error:SuSE %{susever} is unsupported}
+ %{error:Red Hat Enterprise Linux %{rhelver} is unsupported}
%endif
%endif
%else
- %{error:Unsupported distribution}
+ %if %(test -f /etc/SuSE-release && echo 1 || echo 0)
+ %define susever %(rpm -qf --qf '%%{version}\\n' /etc/SuSE-release)
+ %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
@@ -396,8 +415,9 @@ mkdir debug
-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
+ # XXX: MYSQL_UNIX_ADDR should be in cmake/* but mysql_version is included
+ # XXX: before install_layout so we can't just set it based on
+ # XXX: INSTALL_LAYOUT=RPM
${CMAKE} ../%{src_dir} -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM \
-DCMAKE_BUILD_TYPE=Debug \
-DMYSQL_UNIX_ADDR="/var/lib/mysql/mysql.sock" \
@@ -410,8 +430,9 @@ mkdir debug
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
+ # XXX: MYSQL_UNIX_ADDR should be in cmake/* but mysql_version is included
+ # XXX: before install_layout so we can't just set it based on
+ # XXX: INSTALL_LAYOUT=RPM
${CMAKE} ../%{src_dir} -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DMYSQL_UNIX_ADDR="/var/lib/mysql/mysql.sock" \
@@ -468,8 +489,10 @@ install -d $RBR%{_sbindir}
mv -v $RBR/%{_libdir}/*.a $RBR/%{_libdir}/mysql/
# Install logrotate and autostart
-install -m 644 $MBD/release/support-files/mysql-log-rotate $RBR%{_sysconfdir}/logrotate.d/mysql
-install -m 755 $MBD/release/support-files/mysql.server $RBR%{_sysconfdir}/init.d/mysql
+install -m 644 $MBD/release/support-files/mysql-log-rotate \
+ $RBR%{_sysconfdir}/logrotate.d/mysql
+install -m 755 $MBD/release/support-files/mysql.server \
+ $RBR%{_sysconfdir}/init.d/mysql
# Create a symlink "rcmysql", pointing to the init.script. SuSE users
# will appreciate that, as all services usually offer this.
@@ -487,7 +510,8 @@ install -m 600 $MBD/%{src_dir}/support-files/RHEL4-SElinux/mysql.{fc,te} \
# Even though this is a shared library, put it under /usr/lib*/mysql, so it
# doesn't conflict with possible shared lib by the same name in /usr/lib*. See
# `mysql_config --variable=pkglibdir` and mysqld_safe for how this is used.
-install -m 644 "%{malloc_lib_source}" "$RBR%{_libdir}/mysql/%{malloc_lib_target}"
+install -m 644 "%{malloc_lib_source}" \
+ "$RBR%{_libdir}/mysql/%{malloc_lib_target}"
%endif
# Remove man pages we explicitly do not want to package, avoids 'unpackaged
@@ -511,15 +535,19 @@ if [ $? -eq 0 -a -n "$installed" ]; then
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'`
+ 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" != "$myoldvendor" -a "$vendor" != "$myvendor_2" -a "$vendor" != "$myvendor" ]; then
+ if [ "$vendor" != "$myoldvendor" \
+ -a "$vendor" != "$myvendor_2" \
+ -a "$vendor" != "$myvendor" ]; then
error_text="$error_text
The current MySQL server package is provided by a different
vendor ($vendor) than $myoldvendor, $myvendor_2, or $myvendor.
@@ -569,9 +597,9 @@ fi
# Shut down a previously installed server first
if [ -x %{_sysconfdir}/init.d/mysql ] ; then
- %{_sysconfdir}/init.d/mysql stop > /dev/null 2>&1
- echo "Giving mysqld 5 seconds to exit nicely"
- sleep 5
+ %{_sysconfdir}/init.d/mysql stop > /dev/null 2>&1
+ echo "Giving mysqld 5 seconds to exit nicely"
+ sleep 5
fi
%post -n MySQL-server%{product_suffix}
@@ -589,10 +617,10 @@ if [ ! -d $mysql_datadir/test ] ; then mkdir $mysql_datadir/test; fi
# ----------------------------------------------------------------------
# use insserv for older SuSE Linux versions
if [ -x /sbin/insserv ] ; then
- /sbin/insserv %{_sysconfdir}/init.d/mysql
+ /sbin/insserv %{_sysconfdir}/init.d/mysql
# use chkconfig on Enterprise Linux and newer SuSE releases
elif [ -x /sbin/chkconfig ] ; then
- /sbin/chkconfig --add mysql
+ /sbin/chkconfig --add mysql
fi
# ----------------------------------------------------------------------
@@ -600,8 +628,10 @@ fi
# exists.
# ----------------------------------------------------------------------
groupadd -r %{mysqld_group} 2> /dev/null || true
-useradd -M -r -d $mysql_datadir -s /bin/bash -c "MySQL server" -g %{mysqld_group} %{mysqld_user} 2> /dev/null || true
-# The user may already exist, make sure it has the proper group nevertheless (BUG#12823)
+useradd -M -r -d $mysql_datadir -s /bin/bash -c "MySQL server" \
+ -g %{mysqld_group} %{mysqld_user} 2> /dev/null || true
+# The user may already exist, make sure it has the proper group nevertheless
+# (BUG#12823)
usermod -g %{mysqld_group} %{mysqld_user} 2> /dev/null || true
# ----------------------------------------------------------------------
@@ -630,32 +660,66 @@ chown -R %{mysqld_user}:%{mysqld_group} $mysql_datadir
# ----------------------------------------------------------------------
chmod -R og-rw $mysql_datadir/mysql
+# ----------------------------------------------------------------------
+# install SELinux files - but don't override existing ones
+# ----------------------------------------------------------------------
+SETARGETDIR=/etc/selinux/targeted/src/policy
+SEDOMPROG=$SETARGETDIR/domains/program
+SECONPROG=$SETARGETDIR/file_contexts/program
+if [ -f /etc/redhat-release ] \
+ && (grep -q "Red Hat Enterprise Linux .. release 4" /etc/redhat-release \
+ || grep -q "CentOS release 4" /etc/redhat-release) ; then
+ echo
+ echo
+ echo 'Notes regarding SELinux on this platform:'
+ echo '========================================='
+ echo
+ echo 'The default policy might cause server startup to fail because it is'
+ echo 'not allowed to access critical files. In this case, please update'
+ echo 'your installation.'
+ echo
+ echo 'The default policy might also cause inavailability of SSL related'
+ echo 'features because the server is not allowed to access /dev/random'
+ echo 'and /dev/urandom. If this is a problem, please do the following:'
+ echo
+ echo ' 1) install selinux-policy-targeted-sources from your OS vendor'
+ echo ' 2) add the following two lines to '$SEDOMPROG/mysqld.te':'
+ echo ' allow mysqld_t random_device_t:chr_file read;'
+ echo ' allow mysqld_t urandom_device_t:chr_file read;'
+ echo ' 3) cd to '$SETARGETDIR' and issue the following command:'
+ echo ' make load'
+ echo
+ echo
+fi
+
+if [ -x sbin/restorecon ] ; then
+ sbin/restorecon -R var/lib/mysql
+fi
+
# Restart in the same way that mysqld will be started normally.
-%{_sysconfdir}/init.d/mysql start
+if [ -x %{_sysconfdir}/init.d/mysql ] ; then
+ %{_sysconfdir}/init.d/mysql start
+ echo "Giving mysqld 2 seconds to start"
+ sleep 2
+fi
# Allow mysqld_safe to start mysqld and print a message before we exit
sleep 2
-#echo "Thank you for installing the MySQL Community Server! For Production
-#systems, we recommend MySQL Enterprise, which contains enterprise-ready
-#software, intelligent advisory services, and full production support with
-#scheduled service packs and more. Visit www.mysql.com/enterprise for more
-#information."
-
%preun -n MySQL-server%{product_suffix}
if [ $1 = 0 ] ; then
- # Stop MySQL before uninstalling it
- if [ -x %{_sysconfdir}/init.d/mysql ] ; then
- %{_sysconfdir}/init.d/mysql stop > /dev/null
- # Remove autostart of MySQL
- # For older SuSE Linux versions
- if [ -x /sbin/insserv ] ; then
- /sbin/insserv -r %{_sysconfdir}/init.d/mysql
- # use chkconfig on Enterprise Linux and newer SuSE releases
- elif [ -x /sbin/chkconfig ] ; then
- /sbin/chkconfig --del mysql
- fi
- fi
+ # Stop MySQL before uninstalling it
+ if [ -x %{_sysconfdir}/init.d/mysql ] ; then
+ %{_sysconfdir}/init.d/mysql stop > /dev/null
+ # Remove autostart of MySQL
+ # For older SuSE Linux versions
+ if [ -x /sbin/insserv ] ; then
+ /sbin/insserv -r %{_sysconfdir}/init.d/mysql
+ # use chkconfig on Enterprise Linux and newer SuSE releases
+ elif [ -x /sbin/chkconfig ] ; then
+ /sbin/chkconfig --del mysql
+ fi
+ fi
fi
# We do not remove the mysql user since it may still own a lot of
@@ -665,7 +729,8 @@ fi
# Clean up the BuildRoot after build is done
# ----------------------------------------------------------------------
%clean
-[ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT;
+[ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] \
+ && rm -rf $RPM_BUILD_ROOT;
##############################################################################
# Files section
@@ -846,6 +911,10 @@ fi
# merging BK trees)
##############################################################################
%changelog
+* Tue Jun 1 2010 Jonathan Perkin <jonathan.perkin@oracle.com>
+
+- Implement SELinux checks from distribution-specific spec file.
+
* Wed May 12 2010 Jonathan Perkin <jonathan.perkin@oracle.com>
- Large number of changes to build using CMake
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 8112a2a3c0d..b518b617535 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -18935,6 +18935,131 @@ static void test_bug44495()
DBUG_VOID_RETURN;
}
+static void test_bug53371()
+{
+ int rc;
+ MYSQL_RES *result;
+
+ myheader("test_bug53371");
+
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP DATABASE IF EXISTS bug53371");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
+
+ rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
+ myquery(rc);
+ rc= mysql_query(mysql, "CREATE DATABASE bug53371");
+ myquery(rc);
+ rc= mysql_query(mysql, "GRANT SELECT ON bug53371.* to 'testbug'@localhost");
+ myquery(rc);
+
+ rc= mysql_change_user(mysql, "testbug", NULL, "bug53371");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "SHOW COLUMNS FROM client_test_db.t1");
+ DIE_UNLESS(rc);
+ DIE_UNLESS(mysql_errno(mysql) == 1142);
+
+ result= mysql_list_fields(mysql, "../client_test_db/t1", NULL);
+ DIE_IF(result);
+
+ result= mysql_list_fields(mysql, "#mysql50#/../client_test_db/t1", NULL);
+ DIE_IF(result);
+
+ rc= mysql_change_user(mysql, opt_user, opt_password, current_db);
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP TABLE t1");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP DATABASE bug53371");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
+ myquery(rc);
+}
+
+
+
+/**
+ Bug#42373: libmysql can mess a connection at connect
+*/
+static void test_bug42373()
+{
+ int rc;
+ MYSQL con;
+ MYSQL_STMT *stmt;
+
+ DBUG_ENTER("test_bug42373");
+ myheader("test_42373");
+
+ rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "CREATE PROCEDURE p1()"
+ " BEGIN"
+ " SELECT 1;"
+ " INSERT INTO t1 VALUES (2);"
+ "END;");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
+ myquery(rc);
+
+ /* Try with a stored procedure. */
+ DIE_UNLESS(mysql_client_init(&con));
+
+ mysql_options(&con, MYSQL_INIT_COMMAND, "CALL p1()");
+
+ DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
+ current_db, opt_port, opt_unix_socket,
+ CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS));
+
+ stmt= mysql_simple_prepare(&con, "SELECT a FROM t1");
+ check_stmt(stmt);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ rc= my_process_stmt_result(stmt);
+ DIE_UNLESS(rc == 1);
+
+ mysql_stmt_close(stmt);
+
+ /* Now try with a multi-statement. */
+ DIE_UNLESS(mysql_client_init(&con));
+
+ mysql_options(&con, MYSQL_INIT_COMMAND,
+ "SELECT 3; INSERT INTO t1 VALUES (4)");
+
+ DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
+ current_db, opt_port, opt_unix_socket,
+ CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS));
+
+ stmt= mysql_simple_prepare(&con, "SELECT a FROM t1");
+ check_stmt(stmt);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ rc= my_process_stmt_result(stmt);
+ DIE_UNLESS(rc == 2);
+
+ mysql_stmt_close(stmt);
+ mysql_close(&con);
+
+ rc= mysql_query(mysql, "DROP TABLE t1");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "DROP PROCEDURE p1");
+ myquery(rc);
+
+ DBUG_VOID_RETURN;
+}
+
+
/*
Bug#49972: Crash in prepared statements.
@@ -19353,6 +19478,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug30472", test_bug30472 },
{ "test_bug20023", test_bug20023 },
{ "test_bug45010", test_bug45010 },
+ { "test_bug53371", test_bug53371 },
{ "test_bug31418", test_bug31418 },
{ "test_bug31669", test_bug31669 },
{ "test_bug28386", test_bug28386 },
@@ -19374,6 +19500,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug41078", test_bug41078 },
{ "test_bug44495", test_bug44495 },
{ "test_bug49972", test_bug49972 },
+ { "test_bug42373", test_bug42373 },
{ 0, 0 }
};