summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xBUILD/compile-solaris-amd6463
-rw-r--r--BUILD/compile-solaris-amd64-debug10
-rw-r--r--BUILD/compile-solaris-amd64-forte52
-rw-r--r--BUILD/compile-solaris-amd64-forte-debug54
-rwxr-xr-xBitKeeper/triggers/post-commit.innodb.pl22
-rwxr-xr-xBitKeeper/triggers/post-incoming.innodb.pl30
-rwxr-xr-xBitKeeper/triggers/pre-commit.innodb.pl21
-rw-r--r--BitKeeper/triggers/triggers-lib.pl360
-rwxr-xr-xclient/CMakeLists.txt3
-rw-r--r--client/Makefile.am3
-rw-r--r--client/mysql.cc749
-rw-r--r--client/mysqlbinlog.cc31
-rw-r--r--client/mysqlcheck.c19
-rw-r--r--client/mysqldump.c1
-rw-r--r--client/mysqltest.c137
-rw-r--r--cmd-line-utils/readline/bind.c2
-rw-r--r--cmd-line-utils/readline/callback.c2
-rw-r--r--cmd-line-utils/readline/compat.c2
-rw-r--r--cmd-line-utils/readline/complete.c2
-rw-r--r--cmd-line-utils/readline/display.c2
-rw-r--r--cmd-line-utils/readline/funmap.c2
-rw-r--r--cmd-line-utils/readline/histexpand.c2
-rw-r--r--cmd-line-utils/readline/histfile.c2
-rw-r--r--cmd-line-utils/readline/history.c2
-rw-r--r--cmd-line-utils/readline/histsearch.c2
-rw-r--r--cmd-line-utils/readline/input.c2
-rw-r--r--cmd-line-utils/readline/isearch.c2
-rw-r--r--cmd-line-utils/readline/keymaps.c2
-rw-r--r--cmd-line-utils/readline/kill.c2
-rw-r--r--cmd-line-utils/readline/macro.c2
-rw-r--r--cmd-line-utils/readline/mbutil.c2
-rw-r--r--cmd-line-utils/readline/misc.c2
-rw-r--r--cmd-line-utils/readline/nls.c2
-rw-r--r--cmd-line-utils/readline/parens.c2
-rw-r--r--cmd-line-utils/readline/readline.c2
-rw-r--r--cmd-line-utils/readline/rldefs.h2
-rw-r--r--cmd-line-utils/readline/rltty.c2
-rw-r--r--cmd-line-utils/readline/rlwinsize.h2
-rw-r--r--cmd-line-utils/readline/savestring.c2
-rw-r--r--cmd-line-utils/readline/search.c2
-rw-r--r--cmd-line-utils/readline/shell.c2
-rw-r--r--cmd-line-utils/readline/signals.c2
-rw-r--r--cmd-line-utils/readline/tcap.h2
-rw-r--r--cmd-line-utils/readline/terminal.c2
-rw-r--r--cmd-line-utils/readline/text.c2
-rw-r--r--cmd-line-utils/readline/tilde.c2
-rw-r--r--cmd-line-utils/readline/undo.c2
-rw-r--r--cmd-line-utils/readline/util.c2
-rw-r--r--cmd-line-utils/readline/vi_mode.c2
-rw-r--r--cmd-line-utils/readline/xmalloc.c2
-rw-r--r--configure.in6
-rwxr-xr-xextra/CMakeLists.txt3
-rw-r--r--extra/resolveip.c28
-rw-r--r--extra/yassl/src/handshake.cpp5
-rw-r--r--extra/yassl/src/template_instnt.cpp1
-rw-r--r--extra/yassl/src/yassl_imp.cpp11
-rw-r--r--include/my_sys.h6
-rw-r--r--mysql-test/include/have_local_infile.inc4
-rw-r--r--mysql-test/include/ndb_wait_connected.inc26
-rw-r--r--mysql-test/include/show_binlog_events2.inc5
-rwxr-xr-xmysql-test/mysql-test-run.pl5
-rw-r--r--mysql-test/r/bdb.result1
-rw-r--r--mysql-test/r/bdb_notembedded.result6
-rw-r--r--mysql-test/r/binlog.result15
-rw-r--r--mysql-test/r/binlog_innodb.result16
-rw-r--r--mysql-test/r/binlog_start_comment.result15
-rw-r--r--mysql-test/r/blackhole.result4
-rw-r--r--mysql-test/r/compare.result38
-rw-r--r--mysql-test/r/ctype_cp932_binlog.result6
-rw-r--r--mysql-test/r/ctype_ucs_binlog.result3
-rw-r--r--mysql-test/r/func_gconcat.result15
-rw-r--r--mysql-test/r/func_misc.result19
-rw-r--r--mysql-test/r/func_time.result23
-rw-r--r--mysql-test/r/grant3.result17
-rw-r--r--mysql-test/r/have_local_infile.require2
-rw-r--r--mysql-test/r/heap.result1
-rw-r--r--mysql-test/r/innodb.result1
-rw-r--r--mysql-test/r/innodb_mysql.result6
-rw-r--r--mysql-test/r/limit.result9
-rw-r--r--mysql-test/r/mix_innodb_myisam_binlog.result87
-rw-r--r--mysql-test/r/multi_update.result4
-rw-r--r--mysql-test/r/myisam.result1
-rw-r--r--mysql-test/r/mysqlbinlog.result108
-rw-r--r--mysql-test/r/mysqlbinlog2.result339
-rw-r--r--mysql-test/r/mysqlcheck.result11
-rw-r--r--mysql-test/r/mysqldump-no-binlog.result1
-rw-r--r--mysql-test/r/mysqltest.result3
-rw-r--r--mysql-test/r/ndb_alter_table2.result19
-rw-r--r--mysql-test/r/ndb_auto_increment.result6
-rw-r--r--mysql-test/r/ndb_bug31477.result98
-rw-r--r--mysql-test/r/ndb_condition_pushdown.result6
-rw-r--r--mysql-test/r/ndb_restore.result50
-rw-r--r--mysql-test/r/null_key.result18
-rw-r--r--mysql-test/r/order_by.result12
-rw-r--r--mysql-test/r/ps.result198
-rw-r--r--mysql-test/r/range.result13
-rw-r--r--mysql-test/r/row.result9
-rw-r--r--mysql-test/r/rpl_charset.result69
-rw-r--r--mysql-test/r/rpl_drop_view.result27
-rw-r--r--mysql-test/r/rpl_grant.result4
-rw-r--r--mysql-test/r/rpl_loaddata_map.result26
-rw-r--r--mysql-test/r/rpl_server_id.result34
-rw-r--r--mysql-test/r/rpl_slave_skip.result104
-rw-r--r--mysql-test/r/rpl_timezone.result18
-rw-r--r--mysql-test/r/rpl_transaction.result95
-rw-r--r--mysql-test/r/rpl_user.result45
-rw-r--r--mysql-test/r/rpl_user_variables.result16
-rw-r--r--mysql-test/r/select.result27
-rw-r--r--mysql-test/r/sp-code.result109
-rw-r--r--mysql-test/r/sp-error.result48
-rw-r--r--mysql-test/r/sp.result68
-rw-r--r--mysql-test/r/sp_trans_log.result1
-rw-r--r--mysql-test/r/strict.result2
-rw-r--r--mysql-test/r/subselect.result128
-rw-r--r--mysql-test/r/symlink.result77
-rw-r--r--mysql-test/r/tablelock.result9
-rw-r--r--mysql-test/r/type_binary.result1
-rw-r--r--mysql-test/r/type_set.result8
-rw-r--r--mysql-test/r/user_var-binlog.result6
-rw-r--r--mysql-test/r/variables-big.result14
-rw-r--r--mysql-test/r/variables.result2
-rw-r--r--mysql-test/r/view.result45
-rw-r--r--mysql-test/r/view_grant.result1
-rw-r--r--mysql-test/r/warnings.result38
-rw-r--r--mysql-test/std_data/bug30435_10k_items.txt10000
-rw-r--r--mysql-test/std_data/bug30435_5k.txt5000
-rw-r--r--mysql-test/t/binlog.test17
-rw-r--r--mysql-test/t/binlog_innodb.test25
-rw-r--r--mysql-test/t/binlog_start_comment.test24
-rw-r--r--mysql-test/t/blackhole.test1
-rw-r--r--mysql-test/t/compare.test31
-rw-r--r--mysql-test/t/func_gconcat.test17
-rw-r--r--mysql-test/t/func_misc.test18
-rw-r--r--mysql-test/t/func_time.test27
-rw-r--r--mysql-test/t/grant3.test26
-rw-r--r--mysql-test/t/innodb_mysql.test14
-rw-r--r--mysql-test/t/limit.test17
-rw-r--r--mysql-test/t/mix_innodb_myisam_binlog.test3
-rw-r--r--mysql-test/t/mysqlbinlog.test12
-rw-r--r--mysql-test/t/mysqlcheck.test18
-rw-r--r--mysql-test/t/mysqldump-no-binlog-master.opt1
-rw-r--r--mysql-test/t/mysqldump-no-binlog.test6
-rw-r--r--mysql-test/t/mysqltest.test41
-rw-r--r--mysql-test/t/ndb_alter_table2.test31
-rw-r--r--mysql-test/t/ndb_autodiscover.test1
-rw-r--r--mysql-test/t/ndb_autodiscover3.test9
-rw-r--r--mysql-test/t/ndb_bug31477.test109
-rw-r--r--mysql-test/t/ndb_condition_pushdown.test751
-rw-r--r--mysql-test/t/ndb_restore.test25
-rw-r--r--mysql-test/t/null_key.test23
-rw-r--r--mysql-test/t/order_by.test12
-rw-r--r--mysql-test/t/ps.test159
-rw-r--r--mysql-test/t/range.test16
-rw-r--r--mysql-test/t/row.test13
-rw-r--r--mysql-test/t/rpl_drop_view.test31
-rw-r--r--mysql-test/t/rpl_loaddata_map-master.opt1
-rw-r--r--mysql-test/t/rpl_loaddata_map-slave.opt1
-rw-r--r--mysql-test/t/rpl_loaddata_map.test52
-rw-r--r--mysql-test/t/rpl_server_id.test29
-rw-r--r--mysql-test/t/rpl_slave_skip.test169
-rw-r--r--mysql-test/t/rpl_sp.test2
-rw-r--r--mysql-test/t/rpl_transaction-master.opt1
-rw-r--r--mysql-test/t/rpl_transaction-slave.opt1
-rw-r--r--mysql-test/t/rpl_transaction.test107
-rw-r--r--mysql-test/t/rpl_user.test62
-rw-r--r--mysql-test/t/rpl_user_variables.test17
-rw-r--r--mysql-test/t/select.test29
-rw-r--r--mysql-test/t/sp-code.test77
-rw-r--r--mysql-test/t/sp-error.test63
-rw-r--r--mysql-test/t/sp.test94
-rw-r--r--mysql-test/t/subselect.test124
-rw-r--r--mysql-test/t/symlink.test104
-rw-r--r--mysql-test/t/tablelock.test13
-rw-r--r--mysql-test/t/type_set.test20
-rw-r--r--mysql-test/t/variables.test2
-rw-r--r--mysql-test/t/view.test70
-rw-r--r--mysql-test/t/view_grant.test1
-rw-r--r--mysql-test/t/warnings.test33
-rw-r--r--mysys/my_create.c20
-rw-r--r--ndb/include/kernel/ndb_limits.h11
-rw-r--r--ndb/include/mgmapi/ndb_logevent.h8
-rw-r--r--ndb/include/ndbapi/Ndb.hpp18
-rw-r--r--ndb/include/ndbapi/ndbapi_limits.h3
-rw-r--r--ndb/include/util/Bitmask.hpp10
-rw-r--r--ndb/src/common/debugger/SignalLoggerManager.cpp2
-rw-r--r--ndb/src/common/debugger/signaldata/ScanTab.cpp2
-rw-r--r--ndb/src/common/transporter/TCP_Transporter.cpp22
-rw-r--r--ndb/src/common/util/Bitmask.cpp353
-rw-r--r--ndb/src/common/util/NdbOut.cpp2
-rw-r--r--ndb/src/kernel/blocks/backup/Backup.cpp14
-rw-r--r--ndb/src/kernel/blocks/backup/Backup.hpp2
-rw-r--r--ndb/src/kernel/blocks/dbtup/Dbtup.hpp26
-rw-r--r--ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp8
-rw-r--r--ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp96
-rw-r--r--ndb/src/kernel/blocks/dbtup/DbtupStoredProcDef.cpp16
-rw-r--r--ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp9
-rw-r--r--ndb/src/kernel/vm/DLHashTable.hpp22
-rw-r--r--ndb/src/kernel/vm/DLHashTable2.hpp22
-rw-r--r--ndb/src/kernel/vm/pc.hpp6
-rw-r--r--ndb/src/mgmapi/ndb_logevent.cpp2
-rw-r--r--ndb/src/mgmclient/CommandInterpreter.cpp17
-rw-r--r--ndb/src/mgmsrv/ConfigInfo.cpp12
-rw-r--r--ndb/src/ndbapi/DictCache.cpp1
-rw-r--r--ndb/src/ndbapi/DictCache.hpp1
-rw-r--r--ndb/src/ndbapi/Ndb.cpp131
-rw-r--r--ndb/src/ndbapi/NdbDictionaryImpl.cpp19
-rw-r--r--ndb/src/ndbapi/ndberror.c1
-rw-r--r--ndb/test/ndbapi/testBitfield.cpp407
-rw-r--r--ndb/test/ndbapi/testInterpreter.cpp89
-rw-r--r--ndb/test/ndbapi/testOIBasic.cpp2952
-rw-r--r--ndb/test/run-test/daily-basic-tests.txt8
-rw-r--r--ndb/tools/waiter.cpp127
-rwxr-xr-xscripts/CMakeLists.txt41
-rw-r--r--scripts/Makefile.am3
-rw-r--r--scripts/make_binary_distribution.sh10
-rwxr-xr-xscripts/make_win_bin_dist37
-rw-r--r--scripts/mysql_config.pl.in285
-rw-r--r--scripts/mysql_config.sh15
-rw-r--r--scripts/mysql_convert_table_format.sh2
-rw-r--r--scripts/mysql_explain_log.sh9
-rw-r--r--scripts/mysql_install_db.pl.in612
-rwxr-xr-xscripts/mysql_secure_installation.pl.in352
-rw-r--r--scripts/mysql_tableinfo.sh2
-rw-r--r--scripts/mysqld_multi.sh2
-rw-r--r--scripts/mysqldumpslow.sh2
-rw-r--r--scripts/mysqlhotcopy.sh101
-rwxr-xr-xsql/CMakeLists.txt2
-rw-r--r--sql/field.cc80
-rw-r--r--sql/field.h2
-rw-r--r--sql/filesort.cc10
-rw-r--r--sql/ha_innodb.cc4
-rw-r--r--sql/ha_ndbcluster.cc10
-rw-r--r--sql/ha_ndbcluster_cond.cc9
-rw-r--r--sql/ha_ndbcluster_cond.h1
-rw-r--r--sql/handler.cc12
-rw-r--r--sql/item.cc144
-rw-r--r--sql/item.h91
-rw-r--r--sql/item_cmpfunc.cc5
-rw-r--r--sql/item_func.cc4
-rw-r--r--sql/item_func.h5
-rw-r--r--sql/item_sum.cc3
-rw-r--r--sql/log.cc100
-rw-r--r--sql/log_event.cc7
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/mysqld.cc245
-rw-r--r--sql/set_var.cc27
-rw-r--r--sql/slave.cc16
-rw-r--r--sql/slave.h4
-rw-r--r--sql/sp.cc6
-rw-r--r--sql/sp_head.cc6
-rw-r--r--sql/sp_head.h5
-rw-r--r--sql/sp_rcontext.cc76
-rw-r--r--sql/sp_rcontext.h40
-rw-r--r--sql/sql_acl.cc28
-rw-r--r--sql/sql_base.cc8
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_cursor.cc98
-rw-r--r--sql/sql_insert.cc3
-rw-r--r--sql/sql_parse.cc80
-rw-r--r--sql/sql_prepare.cc39
-rw-r--r--sql/sql_repl.cc75
-rw-r--r--sql/sql_select.cc43
-rw-r--r--sql/sql_string.cc4
-rw-r--r--sql/sql_view.cc274
-rw-r--r--sql/sql_view.h3
-rw-r--r--sql/sql_yacc.yy124
-rw-r--r--sql/stacktrace.c275
-rw-r--r--sql/stacktrace.h23
-rw-r--r--support-files/mysql.spec.sh74
-rw-r--r--tests/mysql_client_test.c184
-rw-r--r--vio/viossl.c35
271 files changed, 25893 insertions, 3784 deletions
diff --git a/BUILD/compile-solaris-amd64 b/BUILD/compile-solaris-amd64
index f128fb12973..9204170b908 100755
--- a/BUILD/compile-solaris-amd64
+++ b/BUILD/compile-solaris-amd64
@@ -1,55 +1,10 @@
-#!/usr/bin/bash
-
-function _find_mysql_root () (
- while [ "x$PWD" != "x/" ]; do
- # Check if some directories are present
- if [ -d BUILD -a -d sql -a -d mysys ]; then
- echo "$PWD"
- return 0
- fi
- cd ..
- done
- return 1
-)
-
-make -k clean || true
-/bin/rm -f */.deps/*.P config.cache
-
+#! /bin/sh
path=`dirname $0`
-. "$path/autorun.sh"
-
-warning_flags="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused"
-compiler_flags="-g -O3 -fno-omit-frame-pointer"
-
-export CC CXX CFLAGS CXXFLAGS LDFLAGS LIBS
-CC="gcc"
-CXX="gcc"
-CFLAGS="$warning_flags $compiler_flags"
-CXXFLAGS=""
-LDFLAGS="-O3 -g -static-libgcc"
-LIBS=-lmtmalloc
-root=$(_find_mysql_root)
-
-$root/configure \
- --prefix=/usr/local/mysql \
- --localstatedir=/usr/local/mysql/data \
- --libexecdir=/usr/local/mysql/bin \
- --with-extra-charsets=complex \
- --enable-thread-safe-client \
- --enable-local-infile \
- --with-zlib-dir=bundled \
- --with-big-tables \
- --with-readline \
- --with-archive-storage-engine \
- --with-named-curses=-lcurses \
- --with-big-tables \
- --with-innodb \
- --with-berkeley-db \
- --with-example-storage-engine \
- --with-blackhole-storage-engine \
- --with-ndbcluster \
- --with-federated-storage-engine \
- --with-csv-storage-engine \
- --with-ssl \
- --with-embedded-server \
- --disable-shared
+. "$path/SETUP.sh"
+amd64_cflags="-m64 -mtune=athlon64"
+extra_flags="$amd64_cflags $max_cflags"
+c_warnings="$c_warnings"
+cxx_warnings="$cxx_warnings"
+extra_configs="$amd64_configs $debug_configs $max_configs --enable-thread-safe-client"
+
+. "$path/FINISH.sh"
diff --git a/BUILD/compile-solaris-amd64-debug b/BUILD/compile-solaris-amd64-debug
new file mode 100644
index 00000000000..ad1c298907f
--- /dev/null
+++ b/BUILD/compile-solaris-amd64-debug
@@ -0,0 +1,10 @@
+#! /bin/sh
+path=`dirname $0`
+. "$path/SETUP.sh"
+amd64_cflags="-m64 -mtune=athlon64"
+extra_flags="$amd64_cflags $debug_cflags $max_cflags"
+c_warnings="$c_warnings $debug_extra_warnings"
+cxx_warnings="$cxx_warnings $debug_extra_warnings"
+extra_configs="$amd64_configs $debug_configs $max_configs --enable-thread-safe-client"
+
+. "$path/FINISH.sh"
diff --git a/BUILD/compile-solaris-amd64-forte b/BUILD/compile-solaris-amd64-forte
new file mode 100644
index 00000000000..63aceb16c04
--- /dev/null
+++ b/BUILD/compile-solaris-amd64-forte
@@ -0,0 +1,52 @@
+#! /bin/sh
+
+gmake -k clean || true
+/bin/rm -f */.deps/*.P config.cache
+
+path=`dirname $0`
+. "$path/autorun.sh"
+
+# For "optimal" code for this computer add -fast to EXTRA
+# To compile 64 bit, add -xarch=v9 to EXTRA_64_BIT
+
+EXTRA_64_BIT="-xarch=amd64"
+EXTRA="-fast"
+
+#
+# The following should not need to be touched
+#
+
+export CC CXX CFLAGS CXXFLAGS
+STD="-g -mt -D_FORTEC_ $EXTRA $EXTRA_64_BIT"
+ASFLAGS="$EXTRA_64_BIT"
+CC=cc-5.0
+CFLAGS="-Xa -xstrconst $STD"
+CXX=CC
+CXXFLAGS="-noex $STD"
+./configure \
+ --prefix=/usr/local/mysql \
+ --localstatedir=/usr/local/mysql/data \
+ --libexecdir=/usr/local/mysql/bin \
+ --with-extra-charsets=complex \
+ --enable-thread-safe-client \
+ --enable-local-infile \
+ --with-zlib-dir=bundled \
+ --with-big-tables \
+ --with-readline \
+ --with-archive-storage-engine \
+ --with-named-curses=-lcurses \
+ --with-big-tables \
+ --with-innodb \
+ --with-example-storage-engine \
+ --with-blackhole-storage-engine \
+ --with-federated-storage-engine \
+ --with-csv-storage-engine \
+ --with-ssl \
+ --enable-assembler
+
+# Not including:
+# --with-ndbcluster
+# --with-berkeley-db
+
+gmake -j4
+test $? = 0 && make test
diff --git a/BUILD/compile-solaris-amd64-forte-debug b/BUILD/compile-solaris-amd64-forte-debug
new file mode 100644
index 00000000000..8e3ade9b429
--- /dev/null
+++ b/BUILD/compile-solaris-amd64-forte-debug
@@ -0,0 +1,54 @@
+#! /bin/sh
+
+gmake -k clean || true
+/bin/rm -f */.deps/*.P config.cache
+
+path=`dirname $0`
+. "$path/autorun.sh"
+
+# To compile 64 bit, add -xarch=amd64 to EXTRA_64_BIT
+EXTRA_64_BIT="-xarch=amd64"
+
+# For "optimal" code for this computer add -fast to EXTRA. Note that
+# this causes problem with debugging the program since -fast implies
+# -xO5.
+EXTRA=""
+
+#
+# The following should not need to be touched
+#
+
+export CC CXX CFLAGS CXXFLAGS
+STD="-g -mt -D_FORTEC_ $EXTRA $EXTRA_64_BIT $debug_cflags"
+ASFLAGS="$EXTRA_64_BIT"
+CC=cc-5.0
+CFLAGS="-Xa -xstrconst $STD"
+CXX=CC
+CXXFLAGS="-noex $STD"
+./configure \
+ --prefix=/usr/local/mysql \
+ --localstatedir=/usr/local/mysql/data \
+ --libexecdir=/usr/local/mysql/bin \
+ --with-extra-charsets=complex \
+ --enable-thread-safe-client \
+ --enable-local-infile \
+ --with-zlib-dir=bundled \
+ --with-big-tables \
+ --with-readline \
+ --with-archive-storage-engine \
+ --with-named-curses=-lcurses \
+ --with-big-tables \
+ --with-innodb \
+ --with-example-storage-engine \
+ --with-blackhole-storage-engine \
+ --with-federated-storage-engine \
+ --with-csv-storage-engine \
+ --with-ssl \
+ --with-debug \
+ --enable-assembler
+
+# Not including:
+# --with-ndbcluster
+# --with-berkeley-db
+
+gmake -j4
diff --git a/BitKeeper/triggers/post-commit.innodb.pl b/BitKeeper/triggers/post-commit.innodb.pl
new file mode 100755
index 00000000000..44d98b04838
--- /dev/null
+++ b/BitKeeper/triggers/post-commit.innodb.pl
@@ -0,0 +1,22 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+
+use FindBin;
+require "$FindBin::Bin/triggers-lib.pl";
+
+# Don't run unless commit was successful
+check_status() || exit 0;
+
+my $cset = latest_cset();
+
+# Read most recent ChangeSet's changed files. Send merge changes along, since
+# they'll need to be incorporated in InnoDB's source tree eventually.
+my $changes = innodb_get_changes('cset', $cset, 'yes')
+ or exit 0;
+
+innodb_send_changes_email($cset, $changes)
+ or exit 1;
+
+exit 0;
diff --git a/BitKeeper/triggers/post-incoming.innodb.pl b/BitKeeper/triggers/post-incoming.innodb.pl
new file mode 100755
index 00000000000..4b100d88037
--- /dev/null
+++ b/BitKeeper/triggers/post-incoming.innodb.pl
@@ -0,0 +1,30 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+
+use FindBin;
+require "$FindBin::Bin/triggers-lib.pl";
+
+# Don't run unless push/pull was successful
+check_status() or exit 0;
+
+# Don't run if push/pull is in local clones
+exit 0 if repository_type() eq 'local';
+
+# For each pushed ChangeSet, check it for InnoDB files and send
+# diff of entire ChangeSet to InnoDB developers if such changes
+# exist.
+
+my $error = 0;
+
+foreach my $cset (read_bk_csetlist())
+{
+ my $changes = innodb_get_changes('cset', $cset, 'yes')
+ or next;
+
+ innodb_send_changes_email($cset, $changes)
+ or $error = 1;
+}
+
+exit ($error == 0 ? 0 : 1);
diff --git a/BitKeeper/triggers/pre-commit.innodb.pl b/BitKeeper/triggers/pre-commit.innodb.pl
new file mode 100755
index 00000000000..6e2b65113b0
--- /dev/null
+++ b/BitKeeper/triggers/pre-commit.innodb.pl
@@ -0,0 +1,21 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+
+use FindBin;
+require "$FindBin::Bin/triggers-lib.pl";
+
+die "$0: Script error: \$BK_PENDING is not set in pre-commit trigger\n"
+ unless defined $ENV{BK_PENDING};
+
+# Read changed files from $BK_PENDING directly. Do not bother user about
+# merge changes; they don't have any choice, the merge must be done.
+my $changes = innodb_get_changes('file', $ENV{BK_PENDING}, undef)
+ or exit 0;
+
+innodb_inform_and_query_user($changes)
+ or exit 1; # Abort commit
+
+# OK, continue with commit
+exit 0;
diff --git a/BitKeeper/triggers/triggers-lib.pl b/BitKeeper/triggers/triggers-lib.pl
new file mode 100644
index 00000000000..1c5f7a85726
--- /dev/null
+++ b/BitKeeper/triggers/triggers-lib.pl
@@ -0,0 +1,360 @@
+# To use this convenience library in a trigger, simply require it at
+# at the top of the script. For example:
+#
+# #! /usr/bin/perl
+#
+# use FindBin;
+# require "$FindBin::Bin/triggers-lib.pl";
+#
+# FindBin is needed, because sometimes a trigger is called from the
+# RESYNC directory, and the trigger dir is ../BitKeeper/triggers
+
+use strict;
+use warnings;
+
+use Carp;
+use FindBin;
+
+
+my $mysql_version = "5.0";
+
+# These addresses must be kept current in all MySQL versions.
+# See the wiki page InnoDBandOracle.
+#my @innodb_to_email = ('dev_innodb_ww@oracle.com');
+#my @innodb_cc_email = ('dev-innodb@mysql.com');
+# FIXME: Keep this for testing; remove it once it's been used for a
+# week or two.
+my @innodb_to_email = ('tim@mysql.com');
+my @innodb_cc_email = ();
+
+# This is for MySQL <= 5.0. Regex which defines the InnoDB files
+# which should generally not be touched by MySQL developers.
+my $innodb_files_description = <<EOF;
+ innobase/*
+ mysql-test/t/innodb* (except mysql-test/t/innodb_mysql*)
+ mysql-test/r/innodb* (except mysql-test/r/innodb_mysql*)
+ sql/ha_innodb*
+EOF
+my $innodb_files_regex = qr{
+ ^
+ (
+ # Case 1: innobase/*
+ innobase/
+ |
+ # Case 2: mysql-test/[tr]/innodb* (except innodb_mysql*)
+ mysql-test/(t|r)/SCCS/s.innodb
+ # The mysql-test/[tr]/innodb_mysql* are OK to edit
+ (?!_mysql)
+ |
+ # Case 3: sql/ha_innodb*
+ sql/SCCS/s.ha_innodb
+ )
+}x;
+
+
+# See 'bk help log', and the format of, e.g., $BK_PENDING.
+# Important: this already contains the terminating newline!
+my $file_rev_dspec = ':SFILE:|:REV:\n';
+
+my $bktmp = "$FindBin::Bin/../tmp";
+
+my $sendmail;
+foreach ('/usr/sbin/sendmail', 'sendmail') {
+ $sendmail = $_;
+ last if -x $sendmail;
+}
+my $from = $ENV{REAL_EMAIL} || $ENV{USER} . '@mysql.com';
+
+
+# close_or_warn
+# $fh file handle to be closed
+# $description description of the file handle
+# RETURN Return value of close($fh)
+#
+# Print a nice warning message if close() isn't successful. See
+# perldoc perlvar and perldoc -f close for details.
+
+sub close_or_warn (*$)
+{
+ my ($fh, $description) = @_;
+
+ my $status = close $fh;
+ if (not $status) {
+ warn "$0: error on close of '$description': ",
+ ($! ? "$!" : "exit status " . ($? >> 8)), "\n";
+ }
+
+ return $status;
+}
+
+
+# check_status
+# $warn If true, warn about bad status
+# RETURN TRUE, if $BK_STATUS is "OK"; FALSE otherwise
+#
+# Also checks the undocumented $BK_COMMIT env variable
+
+sub check_status
+{
+ my ($warn) = @_;
+
+ my $status = (grep { defined $_ }
+ $ENV{BK_STATUS}, $ENV{BK_COMMIT}, '<undef>')[0];
+
+ unless ($status eq 'OK')
+ {
+ warn "Bad BK_STATUS '$status'\n" if $warn;
+ return undef;
+ }
+
+ return 1;
+}
+
+
+# repository_location
+#
+# RETURN ('HOST', 'ROOT') for the repository being modified
+
+sub repository_location
+{
+ if ($ENV{BK_SIDE} eq 'client') {
+ return ($ENV{BK_HOST}, $ENV{BK_ROOT});
+ } else {
+ return ($ENV{BKD_HOST}, $ENV{BKD_ROOT});
+ }
+}
+
+
+# repository_type
+# RETURN:
+# 'main' for repo on bk-internal with post-incoming.bugdb trigger
+# 'team' for repo on bk-internal with post-incoming.queuepush.pl trigger
+# 'local' otherwise
+#
+# This definition may need to be modified if the host name or triggers change.
+
+sub repository_type
+{
+ my ($host, $root) = repository_location();
+
+ return 'local'
+ unless uc($host) eq 'BK-INTERNAL.MYSQL.COM'
+ and -e "$root/BitKeeper/triggers/post-incoming.queuepush.pl";
+
+ return 'main' if -e "$root/BitKeeper/triggers/post-incoming.bugdb";
+
+ return 'team';
+}
+
+
+# latest_cset
+# RETURN Key for most recent ChangeSet
+
+sub latest_cset {
+ chomp(my $retval = `bk changes -r+ -k`);
+ return $retval;
+}
+
+
+# read_bk_csetlist
+# RETURN list of cset keys from $BK_CSETLIST file
+sub read_bk_csetlist
+{
+ die "$0: script error: \$BK_CSETLIST not set\n"
+ unless defined $ENV{BK_CSETLIST};
+
+ open CSETS, '<', $ENV{BK_CSETLIST}
+ or die "$0: can't read \$BK_CSETLIST='$ENV{BK_CSETLIST}': $!\n";
+ chomp(my @csets = <CSETS>);
+ close_or_warn(CSETS, "\$BK_CSETLIST='$ENV{BK_CSETLIST}'");
+
+ return @csets;
+}
+
+
+# innodb_get_changes
+# $type 'file' or 'cset'
+# $value file name (e.g., $BK_PENDING) or ChangeSet key
+# $want_merge_changes flag; if false, merge changes will be ignored
+# RETURN A string describing the InnoDB changes, or undef if no changes
+#
+# The return value does *not* include ChangeSet comments, only per-file
+# comments.
+
+sub innodb_get_changes
+{
+ my ($type, $value, $want_merge_changes) = @_;
+
+ if ($type eq 'file')
+ {
+ open CHANGES, '<', $value
+ or die "$0: can't read '$value': $!\n";
+ }
+ elsif ($type eq 'cset')
+ {
+ open CHANGES, '-|', "bk changes -r'$value' -v -d'$file_rev_dspec'"
+ or die "$0: can't exec 'bk changes': $!\n";
+ }
+ else
+ {
+ croak "$0: script error: invalid type '$type'";
+ }
+
+ my @changes = grep { /$innodb_files_regex/ } <CHANGES>;
+
+ close_or_warn(CHANGES, "($type, '$value')");
+
+ return undef unless @changes;
+
+
+ # Set up a pipeline of 'bk log' commands to weed out unwanted deltas. We
+ # never want deltas which contain no actual changes. We may not want deltas
+ # which are merges.
+
+ my @filters;
+
+ # This tests if :LI: (lines inserted) or :LD: (lines deleted) is
+ # non-zero. That is, did this delta change the file contents?
+ push @filters,
+ "bk log -d'"
+ . "\$if(:LI: -gt 0){$file_rev_dspec}"
+ . "\$if(:LI: -eq 0){\$if(:LD: -gt 0){$file_rev_dspec}}"
+ . "' -";
+
+ push @filters, "bk log -d'\$unless(:MERGE:){$file_rev_dspec}' -"
+ unless $want_merge_changes;
+
+ my $tmpname = "$bktmp/ibchanges.txt";
+ my $pipeline = join(' | ', @filters) . " > $tmpname";
+ open TMP, '|-', $pipeline
+ or die "$0: can't exec [[$pipeline]]: $!\n";
+
+ print TMP @changes;
+ close_or_warn(TMP, "| $pipeline");
+
+ # Use bk log to describe the changes
+ open LOG, "bk log - < $tmpname |"
+ or die "$0: can't exec 'bk log - < $tmpname': $!\n";
+ my @log = <LOG>;
+ close_or_warn(LOG, "bk log - < $tmpname |");
+
+ unlink $tmpname;
+
+ return undef unless @log;
+
+ return join('', @log);
+}
+
+
+# Ask user if they really want to commit.
+# RETURN TRUE = YES, commit; FALSE = NO, do not commit
+
+sub innodb_inform_and_query_user
+{
+ my ($description) = @_;
+
+ my $tmpname = "$bktmp/ibquery.txt";
+
+ open MESSAGE, "> $tmpname"
+ or die "$0: can't write message to '$tmpname': $!";
+
+ print MESSAGE <<EOF;
+This ChangeSet modifies some files which should normally be changed by
+InnoDB developers only. In general, MySQL developers should not change:
+
+$innodb_files_description
+The following InnoDB files were modified:
+=========================================================
+$description
+=========================================================
+
+If you understand this, you may Commit these changes. The changes
+will be sent to the InnoDB developers at @{[join ', ', @innodb_to_email]},
+CC @{[join ', ', @innodb_cc_email]}.
+EOF
+
+ close_or_warn(MESSAGE, "$tmpname");
+
+ my $status = system('bk', 'prompt', '-w',
+ '-yCommit these changes', '-nDo not Commit', "-f$tmpname");
+
+ unlink $tmpname;
+
+ return ($status == 0 ? 1 : undef);
+}
+
+
+# innodb_send_changes_email
+# $cset The ChangeSet key
+# $description A (maybe brief) description of the changes
+# RETURN TRUE = Success, e-mail sent; FALSE = Failure
+#
+# Sends a complete diff of changes in $cset by e-mail.
+
+sub innodb_send_changes_email
+{
+ my ($cset, $description) = @_;
+
+ # FIXME: Much of this is duplicated in the 'post-commit' Bourne shell
+ # trigger
+
+ my $cset_short = `bk changes -r'$cset' -d':P:::I:'`;
+ my $cset_key = `bk changes -r'$cset' -d':KEY:'`;
+
+ my ($host, $bk_root) = repository_location();
+ my $type = repository_type();
+ (my $treename = $bk_root) =~ s,^.*/,,;
+
+ print "Nofifying InnoDB developers at ",
+ (join ', ', @innodb_to_email, @innodb_cc_email), "\n";
+
+ open SENDMAIL, '|-', "$sendmail -t"
+ or die "Can't exec '$sendmail -t': $!\n";
+
+ my @headers;
+ push @headers, "List-ID: <bk.innodb-$mysql_version>";
+ push @headers, "From: $from";
+ push @headers, "To: " . (join ', ', @innodb_to_email);
+ push @headers, "Cc: " . (join ', ', @innodb_cc_email) if @innodb_cc_email;
+ push @headers,
+ "Subject: InnoDB changes in $type $mysql_version tree ($cset_short)";
+ push @headers, "X-CSetKey: <$cset_key>";
+
+ print SENDMAIL map { "$_\n" } @headers, '';
+
+ if ($type eq 'main')
+ {
+ print SENDMAIL <<EOF;
+Changes pushed to $treename by $ENV{USER} affect the following
+files. These changes are in a $mysql_version main tree. They
+will be available publicly within 24 hours.
+EOF
+ }
+ elsif ($type eq 'team')
+ {
+ print SENDMAIL <<EOF;
+Changes added to $treename by $ENV{USER} affect the
+following files. These changes are in a $mysql_version team tree.
+EOF
+ }
+ else
+ {
+ print SENDMAIL <<EOF;
+A local commit by $ENV{USER} affects the following files. These
+changes are in a clone of a $mysql_version tree.
+EOF
+ }
+ print SENDMAIL "\n";
+ print SENDMAIL qx(bk changes -r'$cset');
+ print SENDMAIL "$description";
+ print SENDMAIL "The complete ChangeSet diffs follow.\n\n";
+ print SENDMAIL qx(bk rset -r'$cset' -ah | bk gnupatch -h -dup -T);
+
+ close_or_warn(SENDMAIL, "$sendmail -t")
+ or return undef;
+
+ return 1;
+}
+
+
+1;
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index 89675138750..a419da5eabf 100755
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -32,7 +32,8 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c)
TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32)
-ADD_EXECUTABLE(mysqltest mysqltest.c ../mysys/my_getsystime.c ../mysys/my_copy.c)
+ADD_EXECUTABLE(mysqltest mysqltest.c ../mysys/my_getsystime.c
+ ../mysys/my_copy.c ../mysys/my_mkdir.c)
TARGET_LINK_LIBRARIES(mysqltest mysqlclient_notls regex wsock32)
ADD_EXECUTABLE(mysqlcheck mysqlcheck.c)
diff --git a/client/Makefile.am b/client/Makefile.am
index c7663c7da82..672bb2e0c47 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -34,7 +34,8 @@ mysqladmin_SOURCES = mysqladmin.cc
mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS)
mysqltest_SOURCES= mysqltest.c \
$(top_srcdir)/mysys/my_getsystime.c \
- $(top_srcdir)/mysys/my_copy.c
+ $(top_srcdir)/mysys/my_copy.c \
+ $(top_srcdir)/mysys/my_mkdir.c
mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD)
mysqlbinlog_SOURCES = mysqlbinlog.cc \
diff --git a/client/mysql.cc b/client/mysql.cc
index af28dce2cdd..483b1829ec0 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright (C) 2000-2008 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
@@ -283,13 +283,6 @@ static COMMANDS commands[] = {
/* Get bash-like expansion for some commands */
{ "create table", 0, 0, 0, ""},
{ "create database", 0, 0, 0, ""},
- { "drop", 0, 0, 0, ""},
- { "select", 0, 0, 0, ""},
- { "insert", 0, 0, 0, ""},
- { "replace", 0, 0, 0, ""},
- { "update", 0, 0, 0, ""},
- { "delete", 0, 0, 0, ""},
- { "explain", 0, 0, 0, ""},
{ "show databases", 0, 0, 0, ""},
{ "show fields from", 0, 0, 0, ""},
{ "show keys from", 0, 0, 0, ""},
@@ -299,6 +292,718 @@ static COMMANDS commands[] = {
{ "set option", 0, 0, 0, ""},
{ "lock tables", 0, 0, 0, ""},
{ "unlock tables", 0, 0, 0, ""},
+ /* generated 2006-12-28. Refresh occasionally from lexer. */
+ { "ACTION", 0, 0, 0, ""},
+ { "ADD", 0, 0, 0, ""},
+ { "AFTER", 0, 0, 0, ""},
+ { "AGAINST", 0, 0, 0, ""},
+ { "AGGREGATE", 0, 0, 0, ""},
+ { "ALL", 0, 0, 0, ""},
+ { "ALGORITHM", 0, 0, 0, ""},
+ { "ALTER", 0, 0, 0, ""},
+ { "ANALYZE", 0, 0, 0, ""},
+ { "AND", 0, 0, 0, ""},
+ { "ANY", 0, 0, 0, ""},
+ { "AS", 0, 0, 0, ""},
+ { "ASC", 0, 0, 0, ""},
+ { "ASCII", 0, 0, 0, ""},
+ { "ASENSITIVE", 0, 0, 0, ""},
+ { "AUTO_INCREMENT", 0, 0, 0, ""},
+ { "AVG", 0, 0, 0, ""},
+ { "AVG_ROW_LENGTH", 0, 0, 0, ""},
+ { "BACKUP", 0, 0, 0, ""},
+ { "BDB", 0, 0, 0, ""},
+ { "BEFORE", 0, 0, 0, ""},
+ { "BEGIN", 0, 0, 0, ""},
+ { "BERKELEYDB", 0, 0, 0, ""},
+ { "BETWEEN", 0, 0, 0, ""},
+ { "BIGINT", 0, 0, 0, ""},
+ { "BINARY", 0, 0, 0, ""},
+ { "BINLOG", 0, 0, 0, ""},
+ { "BIT", 0, 0, 0, ""},
+ { "BLOB", 0, 0, 0, ""},
+ { "BOOL", 0, 0, 0, ""},
+ { "BOOLEAN", 0, 0, 0, ""},
+ { "BOTH", 0, 0, 0, ""},
+ { "BTREE", 0, 0, 0, ""},
+ { "BY", 0, 0, 0, ""},
+ { "BYTE", 0, 0, 0, ""},
+ { "CACHE", 0, 0, 0, ""},
+ { "CALL", 0, 0, 0, ""},
+ { "CASCADE", 0, 0, 0, ""},
+ { "CASCADED", 0, 0, 0, ""},
+ { "CASE", 0, 0, 0, ""},
+ { "CHAIN", 0, 0, 0, ""},
+ { "CHANGE", 0, 0, 0, ""},
+ { "CHANGED", 0, 0, 0, ""},
+ { "CHAR", 0, 0, 0, ""},
+ { "CHARACTER", 0, 0, 0, ""},
+ { "CHARSET", 0, 0, 0, ""},
+ { "CHECK", 0, 0, 0, ""},
+ { "CHECKSUM", 0, 0, 0, ""},
+ { "CIPHER", 0, 0, 0, ""},
+ { "CLIENT", 0, 0, 0, ""},
+ { "CLOSE", 0, 0, 0, ""},
+ { "CODE", 0, 0, 0, ""},
+ { "COLLATE", 0, 0, 0, ""},
+ { "COLLATION", 0, 0, 0, ""},
+ { "COLUMN", 0, 0, 0, ""},
+ { "COLUMNS", 0, 0, 0, ""},
+ { "COMMENT", 0, 0, 0, ""},
+ { "COMMIT", 0, 0, 0, ""},
+ { "COMMITTED", 0, 0, 0, ""},
+ { "COMPACT", 0, 0, 0, ""},
+ { "COMPRESSED", 0, 0, 0, ""},
+ { "CONCURRENT", 0, 0, 0, ""},
+ { "CONDITION", 0, 0, 0, ""},
+ { "CONNECTION", 0, 0, 0, ""},
+ { "CONSISTENT", 0, 0, 0, ""},
+ { "CONSTRAINT", 0, 0, 0, ""},
+ { "CONTAINS", 0, 0, 0, ""},
+ { "CONTINUE", 0, 0, 0, ""},
+ { "CONVERT", 0, 0, 0, ""},
+ { "CREATE", 0, 0, 0, ""},
+ { "CROSS", 0, 0, 0, ""},
+ { "CUBE", 0, 0, 0, ""},
+ { "CURRENT_DATE", 0, 0, 0, ""},
+ { "CURRENT_TIME", 0, 0, 0, ""},
+ { "CURRENT_TIMESTAMP", 0, 0, 0, ""},
+ { "CURRENT_USER", 0, 0, 0, ""},
+ { "CURSOR", 0, 0, 0, ""},
+ { "DATA", 0, 0, 0, ""},
+ { "DATABASE", 0, 0, 0, ""},
+ { "DATABASES", 0, 0, 0, ""},
+ { "DATE", 0, 0, 0, ""},
+ { "DATETIME", 0, 0, 0, ""},
+ { "DAY", 0, 0, 0, ""},
+ { "DAY_HOUR", 0, 0, 0, ""},
+ { "DAY_MICROSECOND", 0, 0, 0, ""},
+ { "DAY_MINUTE", 0, 0, 0, ""},
+ { "DAY_SECOND", 0, 0, 0, ""},
+ { "DEALLOCATE", 0, 0, 0, ""},
+ { "DEC", 0, 0, 0, ""},
+ { "DECIMAL", 0, 0, 0, ""},
+ { "DECLARE", 0, 0, 0, ""},
+ { "DEFAULT", 0, 0, 0, ""},
+ { "DEFINER", 0, 0, 0, ""},
+ { "DELAYED", 0, 0, 0, ""},
+ { "DELAY_KEY_WRITE", 0, 0, 0, ""},
+ { "DELETE", 0, 0, 0, ""},
+ { "DESC", 0, 0, 0, ""},
+ { "DESCRIBE", 0, 0, 0, ""},
+ { "DES_KEY_FILE", 0, 0, 0, ""},
+ { "DETERMINISTIC", 0, 0, 0, ""},
+ { "DIRECTORY", 0, 0, 0, ""},
+ { "DISABLE", 0, 0, 0, ""},
+ { "DISCARD", 0, 0, 0, ""},
+ { "DISTINCT", 0, 0, 0, ""},
+ { "DISTINCTROW", 0, 0, 0, ""},
+ { "DIV", 0, 0, 0, ""},
+ { "DO", 0, 0, 0, ""},
+ { "DOUBLE", 0, 0, 0, ""},
+ { "DROP", 0, 0, 0, ""},
+ { "DUAL", 0, 0, 0, ""},
+ { "DUMPFILE", 0, 0, 0, ""},
+ { "DUPLICATE", 0, 0, 0, ""},
+ { "DYNAMIC", 0, 0, 0, ""},
+ { "EACH", 0, 0, 0, ""},
+ { "ELSE", 0, 0, 0, ""},
+ { "ELSEIF", 0, 0, 0, ""},
+ { "ENABLE", 0, 0, 0, ""},
+ { "ENCLOSED", 0, 0, 0, ""},
+ { "END", 0, 0, 0, ""},
+ { "ENGINE", 0, 0, 0, ""},
+ { "ENGINES", 0, 0, 0, ""},
+ { "ENUM", 0, 0, 0, ""},
+ { "ERRORS", 0, 0, 0, ""},
+ { "ESCAPE", 0, 0, 0, ""},
+ { "ESCAPED", 0, 0, 0, ""},
+ { "EVENTS", 0, 0, 0, ""},
+ { "EXECUTE", 0, 0, 0, ""},
+ { "EXISTS", 0, 0, 0, ""},
+ { "EXIT", 0, 0, 0, ""},
+ { "EXPANSION", 0, 0, 0, ""},
+ { "EXPLAIN", 0, 0, 0, ""},
+ { "EXTENDED", 0, 0, 0, ""},
+ { "FALSE", 0, 0, 0, ""},
+ { "FAST", 0, 0, 0, ""},
+ { "FETCH", 0, 0, 0, ""},
+ { "FIELDS", 0, 0, 0, ""},
+ { "FILE", 0, 0, 0, ""},
+ { "FIRST", 0, 0, 0, ""},
+ { "FIXED", 0, 0, 0, ""},
+ { "FLOAT", 0, 0, 0, ""},
+ { "FLOAT4", 0, 0, 0, ""},
+ { "FLOAT8", 0, 0, 0, ""},
+ { "FLUSH", 0, 0, 0, ""},
+ { "FOR", 0, 0, 0, ""},
+ { "FORCE", 0, 0, 0, ""},
+ { "FOREIGN", 0, 0, 0, ""},
+ { "FOUND", 0, 0, 0, ""},
+ { "FRAC_SECOND", 0, 0, 0, ""},
+ { "FROM", 0, 0, 0, ""},
+ { "FULL", 0, 0, 0, ""},
+ { "FULLTEXT", 0, 0, 0, ""},
+ { "FUNCTION", 0, 0, 0, ""},
+ { "GEOMETRY", 0, 0, 0, ""},
+ { "GEOMETRYCOLLECTION", 0, 0, 0, ""},
+ { "GET_FORMAT", 0, 0, 0, ""},
+ { "GLOBAL", 0, 0, 0, ""},
+ { "GRANT", 0, 0, 0, ""},
+ { "GRANTS", 0, 0, 0, ""},
+ { "GROUP", 0, 0, 0, ""},
+ { "HANDLER", 0, 0, 0, ""},
+ { "HASH", 0, 0, 0, ""},
+ { "HAVING", 0, 0, 0, ""},
+ { "HELP", 0, 0, 0, ""},
+ { "HIGH_PRIORITY", 0, 0, 0, ""},
+ { "HOSTS", 0, 0, 0, ""},
+ { "HOUR", 0, 0, 0, ""},
+ { "HOUR_MICROSECOND", 0, 0, 0, ""},
+ { "HOUR_MINUTE", 0, 0, 0, ""},
+ { "HOUR_SECOND", 0, 0, 0, ""},
+ { "IDENTIFIED", 0, 0, 0, ""},
+ { "IF", 0, 0, 0, ""},
+ { "IGNORE", 0, 0, 0, ""},
+ { "IMPORT", 0, 0, 0, ""},
+ { "IN", 0, 0, 0, ""},
+ { "INDEX", 0, 0, 0, ""},
+ { "INDEXES", 0, 0, 0, ""},
+ { "INFILE", 0, 0, 0, ""},
+ { "INNER", 0, 0, 0, ""},
+ { "INNOBASE", 0, 0, 0, ""},
+ { "INNODB", 0, 0, 0, ""},
+ { "INOUT", 0, 0, 0, ""},
+ { "INSENSITIVE", 0, 0, 0, ""},
+ { "INSERT", 0, 0, 0, ""},
+ { "INSERT_METHOD", 0, 0, 0, ""},
+ { "INT", 0, 0, 0, ""},
+ { "INT1", 0, 0, 0, ""},
+ { "INT2", 0, 0, 0, ""},
+ { "INT3", 0, 0, 0, ""},
+ { "INT4", 0, 0, 0, ""},
+ { "INT8", 0, 0, 0, ""},
+ { "INTEGER", 0, 0, 0, ""},
+ { "INTERVAL", 0, 0, 0, ""},
+ { "INTO", 0, 0, 0, ""},
+ { "IO_THREAD", 0, 0, 0, ""},
+ { "IS", 0, 0, 0, ""},
+ { "ISOLATION", 0, 0, 0, ""},
+ { "ISSUER", 0, 0, 0, ""},
+ { "ITERATE", 0, 0, 0, ""},
+ { "INVOKER", 0, 0, 0, ""},
+ { "JOIN", 0, 0, 0, ""},
+ { "KEY", 0, 0, 0, ""},
+ { "KEYS", 0, 0, 0, ""},
+ { "KILL", 0, 0, 0, ""},
+ { "LANGUAGE", 0, 0, 0, ""},
+ { "LAST", 0, 0, 0, ""},
+ { "LEADING", 0, 0, 0, ""},
+ { "LEAVE", 0, 0, 0, ""},
+ { "LEAVES", 0, 0, 0, ""},
+ { "LEFT", 0, 0, 0, ""},
+ { "LEVEL", 0, 0, 0, ""},
+ { "LIKE", 0, 0, 0, ""},
+ { "LIMIT", 0, 0, 0, ""},
+ { "LINES", 0, 0, 0, ""},
+ { "LINESTRING", 0, 0, 0, ""},
+ { "LOAD", 0, 0, 0, ""},
+ { "LOCAL", 0, 0, 0, ""},
+ { "LOCALTIME", 0, 0, 0, ""},
+ { "LOCALTIMESTAMP", 0, 0, 0, ""},
+ { "LOCK", 0, 0, 0, ""},
+ { "LOCKS", 0, 0, 0, ""},
+ { "LOGS", 0, 0, 0, ""},
+ { "LONG", 0, 0, 0, ""},
+ { "LONGBLOB", 0, 0, 0, ""},
+ { "LONGTEXT", 0, 0, 0, ""},
+ { "LOOP", 0, 0, 0, ""},
+ { "LOW_PRIORITY", 0, 0, 0, ""},
+ { "MASTER", 0, 0, 0, ""},
+ { "MASTER_CONNECT_RETRY", 0, 0, 0, ""},
+ { "MASTER_HOST", 0, 0, 0, ""},
+ { "MASTER_LOG_FILE", 0, 0, 0, ""},
+ { "MASTER_LOG_POS", 0, 0, 0, ""},
+ { "MASTER_PASSWORD", 0, 0, 0, ""},
+ { "MASTER_PORT", 0, 0, 0, ""},
+ { "MASTER_SERVER_ID", 0, 0, 0, ""},
+ { "MASTER_SSL", 0, 0, 0, ""},
+ { "MASTER_SSL_CA", 0, 0, 0, ""},
+ { "MASTER_SSL_CAPATH", 0, 0, 0, ""},
+ { "MASTER_SSL_CERT", 0, 0, 0, ""},
+ { "MASTER_SSL_CIPHER", 0, 0, 0, ""},
+ { "MASTER_SSL_KEY", 0, 0, 0, ""},
+ { "MASTER_USER", 0, 0, 0, ""},
+ { "MATCH", 0, 0, 0, ""},
+ { "MAX_CONNECTIONS_PER_HOUR", 0, 0, 0, ""},
+ { "MAX_QUERIES_PER_HOUR", 0, 0, 0, ""},
+ { "MAX_ROWS", 0, 0, 0, ""},
+ { "MAX_UPDATES_PER_HOUR", 0, 0, 0, ""},
+ { "MAX_USER_CONNECTIONS", 0, 0, 0, ""},
+ { "MEDIUM", 0, 0, 0, ""},
+ { "MEDIUMBLOB", 0, 0, 0, ""},
+ { "MEDIUMINT", 0, 0, 0, ""},
+ { "MEDIUMTEXT", 0, 0, 0, ""},
+ { "MERGE", 0, 0, 0, ""},
+ { "MICROSECOND", 0, 0, 0, ""},
+ { "MIDDLEINT", 0, 0, 0, ""},
+ { "MIGRATE", 0, 0, 0, ""},
+ { "MINUTE", 0, 0, 0, ""},
+ { "MINUTE_MICROSECOND", 0, 0, 0, ""},
+ { "MINUTE_SECOND", 0, 0, 0, ""},
+ { "MIN_ROWS", 0, 0, 0, ""},
+ { "MOD", 0, 0, 0, ""},
+ { "MODE", 0, 0, 0, ""},
+ { "MODIFIES", 0, 0, 0, ""},
+ { "MODIFY", 0, 0, 0, ""},
+ { "MONTH", 0, 0, 0, ""},
+ { "MULTILINESTRING", 0, 0, 0, ""},
+ { "MULTIPOINT", 0, 0, 0, ""},
+ { "MULTIPOLYGON", 0, 0, 0, ""},
+ { "MUTEX", 0, 0, 0, ""},
+ { "NAME", 0, 0, 0, ""},
+ { "NAMES", 0, 0, 0, ""},
+ { "NATIONAL", 0, 0, 0, ""},
+ { "NATURAL", 0, 0, 0, ""},
+ { "NDB", 0, 0, 0, ""},
+ { "NDBCLUSTER", 0, 0, 0, ""},
+ { "NCHAR", 0, 0, 0, ""},
+ { "NEW", 0, 0, 0, ""},
+ { "NEXT", 0, 0, 0, ""},
+ { "NO", 0, 0, 0, ""},
+ { "NONE", 0, 0, 0, ""},
+ { "NOT", 0, 0, 0, ""},
+ { "NO_WRITE_TO_BINLOG", 0, 0, 0, ""},
+ { "NULL", 0, 0, 0, ""},
+ { "NUMERIC", 0, 0, 0, ""},
+ { "NVARCHAR", 0, 0, 0, ""},
+ { "OFFSET", 0, 0, 0, ""},
+ { "OLD_PASSWORD", 0, 0, 0, ""},
+ { "ON", 0, 0, 0, ""},
+ { "ONE", 0, 0, 0, ""},
+ { "ONE_SHOT", 0, 0, 0, ""},
+ { "OPEN", 0, 0, 0, ""},
+ { "OPTIMIZE", 0, 0, 0, ""},
+ { "OPTION", 0, 0, 0, ""},
+ { "OPTIONALLY", 0, 0, 0, ""},
+ { "OR", 0, 0, 0, ""},
+ { "ORDER", 0, 0, 0, ""},
+ { "OUT", 0, 0, 0, ""},
+ { "OUTER", 0, 0, 0, ""},
+ { "OUTFILE", 0, 0, 0, ""},
+ { "PACK_KEYS", 0, 0, 0, ""},
+ { "PARTIAL", 0, 0, 0, ""},
+ { "PASSWORD", 0, 0, 0, ""},
+ { "PHASE", 0, 0, 0, ""},
+ { "POINT", 0, 0, 0, ""},
+ { "POLYGON", 0, 0, 0, ""},
+ { "PRECISION", 0, 0, 0, ""},
+ { "PREPARE", 0, 0, 0, ""},
+ { "PREV", 0, 0, 0, ""},
+ { "PRIMARY", 0, 0, 0, ""},
+ { "PRIVILEGES", 0, 0, 0, ""},
+ { "PROCEDURE", 0, 0, 0, ""},
+ { "PROCESS", 0, 0, 0, ""},
+ { "PROCESSLIST", 0, 0, 0, ""},
+ { "PURGE", 0, 0, 0, ""},
+ { "QUARTER", 0, 0, 0, ""},
+ { "QUERY", 0, 0, 0, ""},
+ { "QUICK", 0, 0, 0, ""},
+ { "RAID0", 0, 0, 0, ""},
+ { "RAID_CHUNKS", 0, 0, 0, ""},
+ { "RAID_CHUNKSIZE", 0, 0, 0, ""},
+ { "RAID_TYPE", 0, 0, 0, ""},
+ { "READ", 0, 0, 0, ""},
+ { "READS", 0, 0, 0, ""},
+ { "REAL", 0, 0, 0, ""},
+ { "RECOVER", 0, 0, 0, ""},
+ { "REDUNDANT", 0, 0, 0, ""},
+ { "REFERENCES", 0, 0, 0, ""},
+ { "REGEXP", 0, 0, 0, ""},
+ { "RELAY_LOG_FILE", 0, 0, 0, ""},
+ { "RELAY_LOG_POS", 0, 0, 0, ""},
+ { "RELAY_THREAD", 0, 0, 0, ""},
+ { "RELEASE", 0, 0, 0, ""},
+ { "RELOAD", 0, 0, 0, ""},
+ { "RENAME", 0, 0, 0, ""},
+ { "REPAIR", 0, 0, 0, ""},
+ { "REPEATABLE", 0, 0, 0, ""},
+ { "REPLACE", 0, 0, 0, ""},
+ { "REPLICATION", 0, 0, 0, ""},
+ { "REPEAT", 0, 0, 0, ""},
+ { "REQUIRE", 0, 0, 0, ""},
+ { "RESET", 0, 0, 0, ""},
+ { "RESTORE", 0, 0, 0, ""},
+ { "RESTRICT", 0, 0, 0, ""},
+ { "RESUME", 0, 0, 0, ""},
+ { "RETURN", 0, 0, 0, ""},
+ { "RETURNS", 0, 0, 0, ""},
+ { "REVOKE", 0, 0, 0, ""},
+ { "RIGHT", 0, 0, 0, ""},
+ { "RLIKE", 0, 0, 0, ""},
+ { "ROLLBACK", 0, 0, 0, ""},
+ { "ROLLUP", 0, 0, 0, ""},
+ { "ROUTINE", 0, 0, 0, ""},
+ { "ROW", 0, 0, 0, ""},
+ { "ROWS", 0, 0, 0, ""},
+ { "ROW_FORMAT", 0, 0, 0, ""},
+ { "RTREE", 0, 0, 0, ""},
+ { "SAVEPOINT", 0, 0, 0, ""},
+ { "SCHEMA", 0, 0, 0, ""},
+ { "SCHEMAS", 0, 0, 0, ""},
+ { "SECOND", 0, 0, 0, ""},
+ { "SECOND_MICROSECOND", 0, 0, 0, ""},
+ { "SECURITY", 0, 0, 0, ""},
+ { "SELECT", 0, 0, 0, ""},
+ { "SENSITIVE", 0, 0, 0, ""},
+ { "SEPARATOR", 0, 0, 0, ""},
+ { "SERIAL", 0, 0, 0, ""},
+ { "SERIALIZABLE", 0, 0, 0, ""},
+ { "SESSION", 0, 0, 0, ""},
+ { "SET", 0, 0, 0, ""},
+ { "SHARE", 0, 0, 0, ""},
+ { "SHOW", 0, 0, 0, ""},
+ { "SHUTDOWN", 0, 0, 0, ""},
+ { "SIGNED", 0, 0, 0, ""},
+ { "SIMPLE", 0, 0, 0, ""},
+ { "SLAVE", 0, 0, 0, ""},
+ { "SNAPSHOT", 0, 0, 0, ""},
+ { "SMALLINT", 0, 0, 0, ""},
+ { "SOME", 0, 0, 0, ""},
+ { "SONAME", 0, 0, 0, ""},
+ { "SOUNDS", 0, 0, 0, ""},
+ { "SPATIAL", 0, 0, 0, ""},
+ { "SPECIFIC", 0, 0, 0, ""},
+ { "SQL", 0, 0, 0, ""},
+ { "SQLEXCEPTION", 0, 0, 0, ""},
+ { "SQLSTATE", 0, 0, 0, ""},
+ { "SQLWARNING", 0, 0, 0, ""},
+ { "SQL_BIG_RESULT", 0, 0, 0, ""},
+ { "SQL_BUFFER_RESULT", 0, 0, 0, ""},
+ { "SQL_CACHE", 0, 0, 0, ""},
+ { "SQL_CALC_FOUND_ROWS", 0, 0, 0, ""},
+ { "SQL_NO_CACHE", 0, 0, 0, ""},
+ { "SQL_SMALL_RESULT", 0, 0, 0, ""},
+ { "SQL_THREAD", 0, 0, 0, ""},
+ { "SQL_TSI_FRAC_SECOND", 0, 0, 0, ""},
+ { "SQL_TSI_SECOND", 0, 0, 0, ""},
+ { "SQL_TSI_MINUTE", 0, 0, 0, ""},
+ { "SQL_TSI_HOUR", 0, 0, 0, ""},
+ { "SQL_TSI_DAY", 0, 0, 0, ""},
+ { "SQL_TSI_WEEK", 0, 0, 0, ""},
+ { "SQL_TSI_MONTH", 0, 0, 0, ""},
+ { "SQL_TSI_QUARTER", 0, 0, 0, ""},
+ { "SQL_TSI_YEAR", 0, 0, 0, ""},
+ { "SSL", 0, 0, 0, ""},
+ { "START", 0, 0, 0, ""},
+ { "STARTING", 0, 0, 0, ""},
+ { "STATUS", 0, 0, 0, ""},
+ { "STOP", 0, 0, 0, ""},
+ { "STORAGE", 0, 0, 0, ""},
+ { "STRAIGHT_JOIN", 0, 0, 0, ""},
+ { "STRING", 0, 0, 0, ""},
+ { "STRIPED", 0, 0, 0, ""},
+ { "SUBJECT", 0, 0, 0, ""},
+ { "SUPER", 0, 0, 0, ""},
+ { "SUSPEND", 0, 0, 0, ""},
+ { "TABLE", 0, 0, 0, ""},
+ { "TABLES", 0, 0, 0, ""},
+ { "TABLESPACE", 0, 0, 0, ""},
+ { "TEMPORARY", 0, 0, 0, ""},
+ { "TEMPTABLE", 0, 0, 0, ""},
+ { "TERMINATED", 0, 0, 0, ""},
+ { "TEXT", 0, 0, 0, ""},
+ { "THEN", 0, 0, 0, ""},
+ { "TIME", 0, 0, 0, ""},
+ { "TIMESTAMP", 0, 0, 0, ""},
+ { "TIMESTAMPADD", 0, 0, 0, ""},
+ { "TIMESTAMPDIFF", 0, 0, 0, ""},
+ { "TINYBLOB", 0, 0, 0, ""},
+ { "TINYINT", 0, 0, 0, ""},
+ { "TINYTEXT", 0, 0, 0, ""},
+ { "TO", 0, 0, 0, ""},
+ { "TRAILING", 0, 0, 0, ""},
+ { "TRANSACTION", 0, 0, 0, ""},
+ { "TRIGGER", 0, 0, 0, ""},
+ { "TRIGGERS", 0, 0, 0, ""},
+ { "TRUE", 0, 0, 0, ""},
+ { "TRUNCATE", 0, 0, 0, ""},
+ { "TYPE", 0, 0, 0, ""},
+ { "TYPES", 0, 0, 0, ""},
+ { "UNCOMMITTED", 0, 0, 0, ""},
+ { "UNDEFINED", 0, 0, 0, ""},
+ { "UNDO", 0, 0, 0, ""},
+ { "UNICODE", 0, 0, 0, ""},
+ { "UNION", 0, 0, 0, ""},
+ { "UNIQUE", 0, 0, 0, ""},
+ { "UNKNOWN", 0, 0, 0, ""},
+ { "UNLOCK", 0, 0, 0, ""},
+ { "UNSIGNED", 0, 0, 0, ""},
+ { "UNTIL", 0, 0, 0, ""},
+ { "UPDATE", 0, 0, 0, ""},
+ { "UPGRADE", 0, 0, 0, ""},
+ { "USAGE", 0, 0, 0, ""},
+ { "USE", 0, 0, 0, ""},
+ { "USER", 0, 0, 0, ""},
+ { "USER_RESOURCES", 0, 0, 0, ""},
+ { "USE_FRM", 0, 0, 0, ""},
+ { "USING", 0, 0, 0, ""},
+ { "UTC_DATE", 0, 0, 0, ""},
+ { "UTC_TIME", 0, 0, 0, ""},
+ { "UTC_TIMESTAMP", 0, 0, 0, ""},
+ { "VALUE", 0, 0, 0, ""},
+ { "VALUES", 0, 0, 0, ""},
+ { "VARBINARY", 0, 0, 0, ""},
+ { "VARCHAR", 0, 0, 0, ""},
+ { "VARCHARACTER", 0, 0, 0, ""},
+ { "VARIABLES", 0, 0, 0, ""},
+ { "VARYING", 0, 0, 0, ""},
+ { "WARNINGS", 0, 0, 0, ""},
+ { "WEEK", 0, 0, 0, ""},
+ { "WHEN", 0, 0, 0, ""},
+ { "WHERE", 0, 0, 0, ""},
+ { "WHILE", 0, 0, 0, ""},
+ { "VIEW", 0, 0, 0, ""},
+ { "WITH", 0, 0, 0, ""},
+ { "WORK", 0, 0, 0, ""},
+ { "WRITE", 0, 0, 0, ""},
+ { "X509", 0, 0, 0, ""},
+ { "XOR", 0, 0, 0, ""},
+ { "XA", 0, 0, 0, ""},
+ { "YEAR", 0, 0, 0, ""},
+ { "YEAR_MONTH", 0, 0, 0, ""},
+ { "ZEROFILL", 0, 0, 0, ""},
+ { "ABS", 0, 0, 0, ""},
+ { "ACOS", 0, 0, 0, ""},
+ { "ADDDATE", 0, 0, 0, ""},
+ { "ADDTIME", 0, 0, 0, ""},
+ { "AES_ENCRYPT", 0, 0, 0, ""},
+ { "AES_DECRYPT", 0, 0, 0, ""},
+ { "AREA", 0, 0, 0, ""},
+ { "ASIN", 0, 0, 0, ""},
+ { "ASBINARY", 0, 0, 0, ""},
+ { "ASTEXT", 0, 0, 0, ""},
+ { "ASWKB", 0, 0, 0, ""},
+ { "ASWKT", 0, 0, 0, ""},
+ { "ATAN", 0, 0, 0, ""},
+ { "ATAN2", 0, 0, 0, ""},
+ { "BENCHMARK", 0, 0, 0, ""},
+ { "BIN", 0, 0, 0, ""},
+ { "BIT_COUNT", 0, 0, 0, ""},
+ { "BIT_OR", 0, 0, 0, ""},
+ { "BIT_AND", 0, 0, 0, ""},
+ { "BIT_XOR", 0, 0, 0, ""},
+ { "CAST", 0, 0, 0, ""},
+ { "CEIL", 0, 0, 0, ""},
+ { "CEILING", 0, 0, 0, ""},
+ { "BIT_LENGTH", 0, 0, 0, ""},
+ { "CENTROID", 0, 0, 0, ""},
+ { "CHAR_LENGTH", 0, 0, 0, ""},
+ { "CHARACTER_LENGTH", 0, 0, 0, ""},
+ { "COALESCE", 0, 0, 0, ""},
+ { "COERCIBILITY", 0, 0, 0, ""},
+ { "COMPRESS", 0, 0, 0, ""},
+ { "CONCAT", 0, 0, 0, ""},
+ { "CONCAT_WS", 0, 0, 0, ""},
+ { "CONNECTION_ID", 0, 0, 0, ""},
+ { "CONV", 0, 0, 0, ""},
+ { "CONVERT_TZ", 0, 0, 0, ""},
+ { "COUNT", 0, 0, 0, ""},
+ { "COS", 0, 0, 0, ""},
+ { "COT", 0, 0, 0, ""},
+ { "CRC32", 0, 0, 0, ""},
+ { "CROSSES", 0, 0, 0, ""},
+ { "CURDATE", 0, 0, 0, ""},
+ { "CURTIME", 0, 0, 0, ""},
+ { "DATE_ADD", 0, 0, 0, ""},
+ { "DATEDIFF", 0, 0, 0, ""},
+ { "DATE_FORMAT", 0, 0, 0, ""},
+ { "DATE_SUB", 0, 0, 0, ""},
+ { "DAYNAME", 0, 0, 0, ""},
+ { "DAYOFMONTH", 0, 0, 0, ""},
+ { "DAYOFWEEK", 0, 0, 0, ""},
+ { "DAYOFYEAR", 0, 0, 0, ""},
+ { "DECODE", 0, 0, 0, ""},
+ { "DEGREES", 0, 0, 0, ""},
+ { "DES_ENCRYPT", 0, 0, 0, ""},
+ { "DES_DECRYPT", 0, 0, 0, ""},
+ { "DIMENSION", 0, 0, 0, ""},
+ { "DISJOINT", 0, 0, 0, ""},
+ { "ELT", 0, 0, 0, ""},
+ { "ENCODE", 0, 0, 0, ""},
+ { "ENCRYPT", 0, 0, 0, ""},
+ { "ENDPOINT", 0, 0, 0, ""},
+ { "ENVELOPE", 0, 0, 0, ""},
+ { "EQUALS", 0, 0, 0, ""},
+ { "EXTERIORRING", 0, 0, 0, ""},
+ { "EXTRACT", 0, 0, 0, ""},
+ { "EXP", 0, 0, 0, ""},
+ { "EXPORT_SET", 0, 0, 0, ""},
+ { "FIELD", 0, 0, 0, ""},
+ { "FIND_IN_SET", 0, 0, 0, ""},
+ { "FLOOR", 0, 0, 0, ""},
+ { "FORMAT", 0, 0, 0, ""},
+ { "FOUND_ROWS", 0, 0, 0, ""},
+ { "FROM_DAYS", 0, 0, 0, ""},
+ { "FROM_UNIXTIME", 0, 0, 0, ""},
+ { "GET_LOCK", 0, 0, 0, ""},
+ { "GEOMETRYN", 0, 0, 0, ""},
+ { "GEOMETRYTYPE", 0, 0, 0, ""},
+ { "GEOMCOLLFROMTEXT", 0, 0, 0, ""},
+ { "GEOMCOLLFROMWKB", 0, 0, 0, ""},
+ { "GEOMETRYCOLLECTIONFROMTEXT", 0, 0, 0, ""},
+ { "GEOMETRYCOLLECTIONFROMWKB", 0, 0, 0, ""},
+ { "GEOMETRYFROMTEXT", 0, 0, 0, ""},
+ { "GEOMETRYFROMWKB", 0, 0, 0, ""},
+ { "GEOMFROMTEXT", 0, 0, 0, ""},
+ { "GEOMFROMWKB", 0, 0, 0, ""},
+ { "GLENGTH", 0, 0, 0, ""},
+ { "GREATEST", 0, 0, 0, ""},
+ { "GROUP_CONCAT", 0, 0, 0, ""},
+ { "GROUP_UNIQUE_USERS", 0, 0, 0, ""},
+ { "HEX", 0, 0, 0, ""},
+ { "IFNULL", 0, 0, 0, ""},
+ { "INET_ATON", 0, 0, 0, ""},
+ { "INET_NTOA", 0, 0, 0, ""},
+ { "INSTR", 0, 0, 0, ""},
+ { "INTERIORRINGN", 0, 0, 0, ""},
+ { "INTERSECTS", 0, 0, 0, ""},
+ { "ISCLOSED", 0, 0, 0, ""},
+ { "ISEMPTY", 0, 0, 0, ""},
+ { "ISNULL", 0, 0, 0, ""},
+ { "IS_FREE_LOCK", 0, 0, 0, ""},
+ { "IS_USED_LOCK", 0, 0, 0, ""},
+ { "LAST_INSERT_ID", 0, 0, 0, ""},
+ { "ISSIMPLE", 0, 0, 0, ""},
+ { "LAST_DAY", 0, 0, 0, ""},
+ { "LCASE", 0, 0, 0, ""},
+ { "LEAST", 0, 0, 0, ""},
+ { "LENGTH", 0, 0, 0, ""},
+ { "LN", 0, 0, 0, ""},
+ { "LINEFROMTEXT", 0, 0, 0, ""},
+ { "LINEFROMWKB", 0, 0, 0, ""},
+ { "LINESTRINGFROMTEXT", 0, 0, 0, ""},
+ { "LINESTRINGFROMWKB", 0, 0, 0, ""},
+ { "LOAD_FILE", 0, 0, 0, ""},
+ { "LOCATE", 0, 0, 0, ""},
+ { "LOG", 0, 0, 0, ""},
+ { "LOG2", 0, 0, 0, ""},
+ { "LOG10", 0, 0, 0, ""},
+ { "LOWER", 0, 0, 0, ""},
+ { "LPAD", 0, 0, 0, ""},
+ { "LTRIM", 0, 0, 0, ""},
+ { "MAKE_SET", 0, 0, 0, ""},
+ { "MAKEDATE", 0, 0, 0, ""},
+ { "MAKETIME", 0, 0, 0, ""},
+ { "MASTER_POS_WAIT", 0, 0, 0, ""},
+ { "MAX", 0, 0, 0, ""},
+ { "MBRCONTAINS", 0, 0, 0, ""},
+ { "MBRDISJOINT", 0, 0, 0, ""},
+ { "MBREQUAL", 0, 0, 0, ""},
+ { "MBRINTERSECTS", 0, 0, 0, ""},
+ { "MBROVERLAPS", 0, 0, 0, ""},
+ { "MBRTOUCHES", 0, 0, 0, ""},
+ { "MBRWITHIN", 0, 0, 0, ""},
+ { "MD5", 0, 0, 0, ""},
+ { "MID", 0, 0, 0, ""},
+ { "MIN", 0, 0, 0, ""},
+ { "MLINEFROMTEXT", 0, 0, 0, ""},
+ { "MLINEFROMWKB", 0, 0, 0, ""},
+ { "MPOINTFROMTEXT", 0, 0, 0, ""},
+ { "MPOINTFROMWKB", 0, 0, 0, ""},
+ { "MPOLYFROMTEXT", 0, 0, 0, ""},
+ { "MPOLYFROMWKB", 0, 0, 0, ""},
+ { "MONTHNAME", 0, 0, 0, ""},
+ { "MULTILINESTRINGFROMTEXT", 0, 0, 0, ""},
+ { "MULTILINESTRINGFROMWKB", 0, 0, 0, ""},
+ { "MULTIPOINTFROMTEXT", 0, 0, 0, ""},
+ { "MULTIPOINTFROMWKB", 0, 0, 0, ""},
+ { "MULTIPOLYGONFROMTEXT", 0, 0, 0, ""},
+ { "MULTIPOLYGONFROMWKB", 0, 0, 0, ""},
+ { "NAME_CONST", 0, 0, 0, ""},
+ { "NOW", 0, 0, 0, ""},
+ { "NULLIF", 0, 0, 0, ""},
+ { "NUMGEOMETRIES", 0, 0, 0, ""},
+ { "NUMINTERIORRINGS", 0, 0, 0, ""},
+ { "NUMPOINTS", 0, 0, 0, ""},
+ { "OCTET_LENGTH", 0, 0, 0, ""},
+ { "OCT", 0, 0, 0, ""},
+ { "ORD", 0, 0, 0, ""},
+ { "OVERLAPS", 0, 0, 0, ""},
+ { "PERIOD_ADD", 0, 0, 0, ""},
+ { "PERIOD_DIFF", 0, 0, 0, ""},
+ { "PI", 0, 0, 0, ""},
+ { "POINTFROMTEXT", 0, 0, 0, ""},
+ { "POINTFROMWKB", 0, 0, 0, ""},
+ { "POINTN", 0, 0, 0, ""},
+ { "POLYFROMTEXT", 0, 0, 0, ""},
+ { "POLYFROMWKB", 0, 0, 0, ""},
+ { "POLYGONFROMTEXT", 0, 0, 0, ""},
+ { "POLYGONFROMWKB", 0, 0, 0, ""},
+ { "POSITION", 0, 0, 0, ""},
+ { "POW", 0, 0, 0, ""},
+ { "POWER", 0, 0, 0, ""},
+ { "QUOTE", 0, 0, 0, ""},
+ { "RADIANS", 0, 0, 0, ""},
+ { "RAND", 0, 0, 0, ""},
+ { "RELEASE_LOCK", 0, 0, 0, ""},
+ { "REVERSE", 0, 0, 0, ""},
+ { "ROUND", 0, 0, 0, ""},
+ { "ROW_COUNT", 0, 0, 0, ""},
+ { "RPAD", 0, 0, 0, ""},
+ { "RTRIM", 0, 0, 0, ""},
+ { "SEC_TO_TIME", 0, 0, 0, ""},
+ { "SESSION_USER", 0, 0, 0, ""},
+ { "SUBDATE", 0, 0, 0, ""},
+ { "SIGN", 0, 0, 0, ""},
+ { "SIN", 0, 0, 0, ""},
+ { "SHA", 0, 0, 0, ""},
+ { "SHA1", 0, 0, 0, ""},
+ { "SLEEP", 0, 0, 0, ""},
+ { "SOUNDEX", 0, 0, 0, ""},
+ { "SPACE", 0, 0, 0, ""},
+ { "SQRT", 0, 0, 0, ""},
+ { "SRID", 0, 0, 0, ""},
+ { "STARTPOINT", 0, 0, 0, ""},
+ { "STD", 0, 0, 0, ""},
+ { "STDDEV", 0, 0, 0, ""},
+ { "STDDEV_POP", 0, 0, 0, ""},
+ { "STDDEV_SAMP", 0, 0, 0, ""},
+ { "STR_TO_DATE", 0, 0, 0, ""},
+ { "STRCMP", 0, 0, 0, ""},
+ { "SUBSTR", 0, 0, 0, ""},
+ { "SUBSTRING", 0, 0, 0, ""},
+ { "SUBSTRING_INDEX", 0, 0, 0, ""},
+ { "SUBTIME", 0, 0, 0, ""},
+ { "SUM", 0, 0, 0, ""},
+ { "SYSDATE", 0, 0, 0, ""},
+ { "SYSTEM_USER", 0, 0, 0, ""},
+ { "TAN", 0, 0, 0, ""},
+ { "TIME_FORMAT", 0, 0, 0, ""},
+ { "TIME_TO_SEC", 0, 0, 0, ""},
+ { "TIMEDIFF", 0, 0, 0, ""},
+ { "TO_DAYS", 0, 0, 0, ""},
+ { "TOUCHES", 0, 0, 0, ""},
+ { "TRIM", 0, 0, 0, ""},
+ { "UCASE", 0, 0, 0, ""},
+ { "UNCOMPRESS", 0, 0, 0, ""},
+ { "UNCOMPRESSED_LENGTH", 0, 0, 0, ""},
+ { "UNHEX", 0, 0, 0, ""},
+ { "UNIQUE_USERS", 0, 0, 0, ""},
+ { "UNIX_TIMESTAMP", 0, 0, 0, ""},
+ { "UPPER", 0, 0, 0, ""},
+ { "UUID", 0, 0, 0, ""},
+ { "VARIANCE", 0, 0, 0, ""},
+ { "VAR_POP", 0, 0, 0, ""},
+ { "VAR_SAMP", 0, 0, 0, ""},
+ { "VERSION", 0, 0, 0, ""},
+ { "WEEKDAY", 0, 0, 0, ""},
+ { "WEEKOFYEAR", 0, 0, 0, ""},
+ { "WITHIN", 0, 0, 0, ""},
+ { "X", 0, 0, 0, ""},
+ { "Y", 0, 0, 0, ""},
+ { "YEARWEEK", 0, 0, 0, ""},
+ /* end sentinel */
{ (char *)NULL, 0, 0, 0, ""}
};
@@ -795,7 +1500,7 @@ static void usage(int version)
if (version)
return;
printf("\
-Copyright (C) 2002 MySQL AB\n\
+Copyright (C) 2000-2008 MySQL AB\n\
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
and you are welcome to modify and redistribute it under the GPL license\n");
printf("Usage: %s [OPTIONS] [database]\n", my_progname);
@@ -1750,12 +2455,6 @@ static void build_completion_hash(bool rehash, bool write_info)
if (status.batch || quick || !current_db)
DBUG_VOID_RETURN; // We don't need completion in batches
-
- /* hash SQL commands */
- while (cmd->name) {
- add_word(&ht,(char*) cmd->name);
- cmd++;
- }
if (!rehash)
DBUG_VOID_RETURN;
@@ -1765,6 +2464,12 @@ static void build_completion_hash(bool rehash, bool write_info)
completion_hash_clean(&ht);
free_root(&hash_mem_root,MYF(0));
+ /* hash this file's known subset of SQL commands */
+ while (cmd->name) {
+ add_word(&ht,(char*) cmd->name);
+ cmd++;
+ }
+
/* hash MySQL functions (to be implemented) */
/* hash all database names */
@@ -2146,7 +2851,8 @@ com_charset(String *buffer __attribute__((unused)), char *line)
static int
com_go(String *buffer,char *line __attribute__((unused)))
{
- char buff[200], time_buff[32], *pos;
+ char buff[200]; /* about 110 chars used so far */
+ char time_buff[52+3+1]; /* time max + space&parens + NUL */
MYSQL_RES *result;
ulong timer, warnings;
uint error= 0;
@@ -2212,6 +2918,8 @@ com_go(String *buffer,char *line __attribute__((unused)))
do
{
+ char *pos;
+
if (quick)
{
if (!(result=mysql_use_result(&mysql)) && mysql_field_count(&mysql))
@@ -2233,7 +2941,9 @@ com_go(String *buffer,char *line __attribute__((unused)))
if (verbose >= 3 || !opt_silent)
mysql_end_timer(timer,time_buff);
else
- time_buff[0]=0;
+ time_buff[0]= '\0';
+
+ /* Every branch must truncate buff . */
if (result)
{
if (!mysql_num_rows(result) && ! quick && !info_flag)
@@ -3792,6 +4502,11 @@ static ulong start_timer(void)
}
+/**
+ Write as many as 52+1 bytes to buff, in the form of a legible duration of time.
+
+ len("4294967296 days, 23 hours, 59 minutes, 60.00 seconds") -> 52
+*/
static void nice_time(double sec,char *buff,bool part_second)
{
ulong tmp;
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 3d06a21c243..b4086b59c01 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -465,6 +465,31 @@ Create_file event for file_id: %u\n",ae->file_id);
Load_log_processor load_processor;
+/**
+ Replace windows-style backslashes by forward slashes so it can be
+ consumed by the mysql client, which requires Unix path.
+
+ @todo This is only useful under windows, so may be ifdef'ed out on
+ other systems. /Sven
+
+ @todo If a Create_file_log_event contains a filename with a
+ backslash (valid under unix), then we have problems under windows.
+ /Sven
+
+ @param[in,out] fname Filename to modify. The filename is modified
+ in-place.
+*/
+static void convert_path_to_forward_slashes(char *fname)
+{
+ while (*fname)
+ {
+ if (*fname == '\\')
+ *fname= '/';
+ fname++;
+ }
+}
+
+
static bool check_database(const char *log_dbname)
{
return one_database &&
@@ -582,6 +607,11 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
*/
if (ce)
{
+ /*
+ We must not convert earlier, since the file is used by
+ my_open() in Load_log_processor::append().
+ */
+ convert_path_to_forward_slashes((char*) ce->fname);
ce->print(result_file, print_event_info, TRUE);
my_free((char*)ce->fname,MYF(MY_WME));
delete ce;
@@ -622,6 +652,7 @@ Create_file event for file_id: %u\n",exv->file_id);
if (fname)
{
+ convert_path_to_forward_slashes(fname);
exlq->print(result_file, print_event_info, fname);
my_free(fname, MYF(MY_WME));
}
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index 3b504eb50b0..473e172adf9 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -483,14 +483,17 @@ static int process_all_tables_in_db(char *database)
{
MYSQL_RES *res;
MYSQL_ROW row;
+ uint num_columns;
LINT_INIT(res);
if (use_db(database))
return 1;
- if (mysql_query(sock, "SHOW TABLE STATUS") ||
+ if (mysql_query(sock, "SHOW /*!50002 FULL*/ TABLES") ||
!((res= mysql_store_result(sock))))
return 1;
+ num_columns= mysql_num_fields(res);
+
if (opt_all_in_1)
{
/*
@@ -513,12 +516,11 @@ static int process_all_tables_in_db(char *database)
}
for (end = tables + 1; (row = mysql_fetch_row(res)) ;)
{
- /* Skip tables with an engine of NULL (probably a view). */
- if (row[1])
- {
- end= fix_table_name(end, row[0]);
- *end++= ',';
- }
+ if ((num_columns == 2) && (strcmp(row[1], "VIEW") == 0))
+ continue;
+
+ end= fix_table_name(end, row[0]);
+ *end++= ',';
}
*--end = 0;
if (tot_length)
@@ -531,6 +533,9 @@ static int process_all_tables_in_db(char *database)
/* Skip tables with an engine of NULL (probably a view). */
if (row[1])
{
+ if ((num_columns == 2) && (strcmp(row[1], "VIEW") == 0))
+ continue;
+
handle_request_for_tables(row[0], fixed_name_length(row[0]));
}
}
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 980013d539a..e8129a6fd73 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -3285,6 +3285,7 @@ static int do_show_master_status(MYSQL *mysql_con)
my_printf_error(0, "Error: Binlogging on server not active",
MYF(0));
mysql_free_result(master);
+ maybe_exit(EX_MYSQLERR);
return 1;
}
mysql_free_result(master);
diff --git a/client/mysqltest.c b/client/mysqltest.c
index 88575c26bc6..05c9ced3848 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -51,6 +51,10 @@
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
+#ifdef __WIN__
+#include <direct.h>
+#endif
+
#ifndef WEXITSTATUS
# ifdef __WIN__
@@ -277,7 +281,7 @@ enum enum_commands {
Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST,
Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP,
Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES,
- Q_SEND_QUIT,
+ Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR,
Q_UNKNOWN, /* Unknown command. */
Q_COMMENT, /* Comments, ignored. */
@@ -366,6 +370,10 @@ const char *command_names[]=
"cat_file",
"diff_files",
"send_quit",
+ "change_user",
+ "mkdir",
+ "rmdir",
+
0
};
@@ -2742,6 +2750,67 @@ void do_file_exist(struct st_command *command)
/*
+ SYNOPSIS
+ do_mkdir
+ command called command
+
+ DESCRIPTION
+ mkdir <dir_name>
+ Create the directory <dir_name>
+*/
+
+void do_mkdir(struct st_command *command)
+{
+ int error;
+ static DYNAMIC_STRING ds_dirname;
+ const struct command_arg mkdir_args[] = {
+ "dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to create"
+ };
+ DBUG_ENTER("do_mkdir");
+
+ check_command_args(command, command->first_argument,
+ mkdir_args, sizeof(mkdir_args)/sizeof(struct command_arg),
+ ' ');
+
+ DBUG_PRINT("info", ("creating directory: %s", ds_dirname.str));
+ error= my_mkdir(ds_dirname.str, 0777, MYF(0)) != 0;
+ handle_command_error(command, error);
+ dynstr_free(&ds_dirname);
+ DBUG_VOID_RETURN;
+}
+
+/*
+ SYNOPSIS
+ do_rmdir
+ command called command
+
+ DESCRIPTION
+ rmdir <dir_name>
+ Remove the empty directory <dir_name>
+*/
+
+void do_rmdir(struct st_command *command)
+{
+ int error;
+ static DYNAMIC_STRING ds_dirname;
+ const struct command_arg rmdir_args[] = {
+ "dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to remove"
+ };
+ DBUG_ENTER("do_rmdir");
+
+ check_command_args(command, command->first_argument,
+ rmdir_args, sizeof(rmdir_args)/sizeof(struct command_arg),
+ ' ');
+
+ DBUG_PRINT("info", ("removing directory: %s", ds_dirname.str));
+ error= rmdir(ds_dirname.str) != 0;
+ handle_command_error(command, error);
+ dynstr_free(&ds_dirname);
+ DBUG_VOID_RETURN;
+}
+
+
+/*
Read characters from line buffer or file. This is needed to allow
my_ungetc() to buffer MAX_DELIMITER_LENGTH characters for a file
@@ -3048,6 +3117,69 @@ void do_send_quit(struct st_command *command)
/*
SYNOPSIS
+ do_change_user
+ command called command
+
+ DESCRIPTION
+ change_user [<user>], [<passwd>], [<db>]
+ <user> - user to change to
+ <passwd> - user password
+ <db> - default database
+
+ Changes the user and causes the database specified by db to become
+ the default (current) database for the the current connection.
+
+*/
+
+void do_change_user(struct st_command *command)
+{
+ MYSQL *mysql = &cur_con->mysql;
+ /* static keyword to make the NetWare compiler happy. */
+ static DYNAMIC_STRING ds_user, ds_passwd, ds_db;
+ const struct command_arg change_user_args[] = {
+ { "user", ARG_STRING, FALSE, &ds_user, "User to connect as" },
+ { "password", ARG_STRING, FALSE, &ds_passwd, "Password used when connecting" },
+ { "database", ARG_STRING, FALSE, &ds_db, "Database to select after connect" },
+ };
+
+ DBUG_ENTER("do_change_user");
+
+ check_command_args(command, command->first_argument,
+ change_user_args,
+ sizeof(change_user_args)/sizeof(struct command_arg),
+ ',');
+
+ if (cur_con->stmt)
+ {
+ mysql_stmt_close(cur_con->stmt);
+ cur_con->stmt= NULL;
+ }
+
+ if (!ds_user.length)
+ dynstr_set(&ds_user, mysql->user);
+
+ if (!ds_passwd.length)
+ dynstr_set(&ds_passwd, mysql->passwd);
+
+ if (!ds_db.length)
+ dynstr_set(&ds_db, mysql->db);
+
+ DBUG_PRINT("info",("connection: '%s' user: '%s' password: '%s' database: '%s'",
+ cur_con->name, ds_user.str, ds_passwd.str, ds_db.str));
+
+ if (mysql_change_user(mysql, ds_user.str, ds_passwd.str, ds_db.str))
+ die("change user failed: %s", mysql_error(mysql));
+
+ dynstr_free(&ds_user);
+ dynstr_free(&ds_passwd);
+ dynstr_free(&ds_db);
+
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ SYNOPSIS
do_perl
command command handle
@@ -6847,11 +6979,14 @@ int main(int argc, char **argv)
case Q_ECHO: do_echo(command); command_executed++; break;
case Q_SYSTEM: do_system(command); break;
case Q_REMOVE_FILE: do_remove_file(command); break;
+ case Q_MKDIR: do_mkdir(command); break;
+ case Q_RMDIR: do_rmdir(command); break;
case Q_FILE_EXIST: do_file_exist(command); break;
case Q_WRITE_FILE: do_write_file(command); break;
case Q_APPEND_FILE: do_append_file(command); break;
case Q_DIFF_FILES: do_diff_files(command); break;
case Q_SEND_QUIT: do_send_quit(command); break;
+ case Q_CHANGE_USER: do_change_user(command); break;
case Q_CAT_FILE: do_cat_file(command); break;
case Q_COPY_FILE: do_copy_file(command); break;
case Q_CHMOD_FILE: do_chmod_file(command); break;
diff --git a/cmd-line-utils/readline/bind.c b/cmd-line-utils/readline/bind.c
index 08c906bfcc3..baed1dfad49 100644
--- a/cmd-line-utils/readline/bind.c
+++ b/cmd-line-utils/readline/bind.c
@@ -27,7 +27,7 @@
#endif
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <stdio.h>
diff --git a/cmd-line-utils/readline/callback.c b/cmd-line-utils/readline/callback.c
index ada04d8593b..2f7e4b78057 100644
--- a/cmd-line-utils/readline/callback.c
+++ b/cmd-line-utils/readline/callback.c
@@ -22,7 +22,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include "rlconf.h"
diff --git a/cmd-line-utils/readline/compat.c b/cmd-line-utils/readline/compat.c
index a66d210fd2e..3949bf6a16b 100644
--- a/cmd-line-utils/readline/compat.c
+++ b/cmd-line-utils/readline/compat.c
@@ -22,7 +22,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <stdio.h>
diff --git a/cmd-line-utils/readline/complete.c b/cmd-line-utils/readline/complete.c
index 73f834a68a7..d0c9e772f0f 100644
--- a/cmd-line-utils/readline/complete.c
+++ b/cmd-line-utils/readline/complete.c
@@ -22,7 +22,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <sys/types.h>
diff --git a/cmd-line-utils/readline/display.c b/cmd-line-utils/readline/display.c
index 47ff0615974..6f63faa9738 100644
--- a/cmd-line-utils/readline/display.c
+++ b/cmd-line-utils/readline/display.c
@@ -22,7 +22,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <sys/types.h>
diff --git a/cmd-line-utils/readline/funmap.c b/cmd-line-utils/readline/funmap.c
index 9c760cc3475..2d2a35ed0c8 100644
--- a/cmd-line-utils/readline/funmap.c
+++ b/cmd-line-utils/readline/funmap.c
@@ -22,7 +22,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#if !defined (BUFSIZ)
diff --git a/cmd-line-utils/readline/histexpand.c b/cmd-line-utils/readline/histexpand.c
index f46c0b2a45d..45377fc3b5e 100644
--- a/cmd-line-utils/readline/histexpand.c
+++ b/cmd-line-utils/readline/histexpand.c
@@ -23,7 +23,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <stdio.h>
diff --git a/cmd-line-utils/readline/histfile.c b/cmd-line-utils/readline/histfile.c
index 2f051a32563..d98293d933c 100644
--- a/cmd-line-utils/readline/histfile.c
+++ b/cmd-line-utils/readline/histfile.c
@@ -31,7 +31,7 @@
#endif
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <stdio.h>
diff --git a/cmd-line-utils/readline/history.c b/cmd-line-utils/readline/history.c
index 1ccf4db786c..5cd5788d1da 100644
--- a/cmd-line-utils/readline/history.c
+++ b/cmd-line-utils/readline/history.c
@@ -26,7 +26,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <stdio.h>
diff --git a/cmd-line-utils/readline/histsearch.c b/cmd-line-utils/readline/histsearch.c
index 1cc5875a4b4..b71965135cc 100644
--- a/cmd-line-utils/readline/histsearch.c
+++ b/cmd-line-utils/readline/histsearch.c
@@ -23,7 +23,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <stdio.h>
diff --git a/cmd-line-utils/readline/input.c b/cmd-line-utils/readline/input.c
index da5d771c481..62c0443d890 100644
--- a/cmd-line-utils/readline/input.c
+++ b/cmd-line-utils/readline/input.c
@@ -26,7 +26,7 @@
#endif
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <sys/types.h>
diff --git a/cmd-line-utils/readline/isearch.c b/cmd-line-utils/readline/isearch.c
index 9f67bfc0801..8060adb97cd 100644
--- a/cmd-line-utils/readline/isearch.c
+++ b/cmd-line-utils/readline/isearch.c
@@ -27,7 +27,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <sys/types.h>
diff --git a/cmd-line-utils/readline/keymaps.c b/cmd-line-utils/readline/keymaps.c
index 70d0cc08d3f..562c22d7558 100644
--- a/cmd-line-utils/readline/keymaps.c
+++ b/cmd-line-utils/readline/keymaps.c
@@ -21,7 +21,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#if defined (HAVE_STDLIB_H)
diff --git a/cmd-line-utils/readline/kill.c b/cmd-line-utils/readline/kill.c
index 031ddf47c5b..42c53948689 100644
--- a/cmd-line-utils/readline/kill.c
+++ b/cmd-line-utils/readline/kill.c
@@ -22,7 +22,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <sys/types.h>
diff --git a/cmd-line-utils/readline/macro.c b/cmd-line-utils/readline/macro.c
index 00cd58d628c..3473f705335 100644
--- a/cmd-line-utils/readline/macro.c
+++ b/cmd-line-utils/readline/macro.c
@@ -22,7 +22,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <sys/types.h>
diff --git a/cmd-line-utils/readline/mbutil.c b/cmd-line-utils/readline/mbutil.c
index 17dde53ed7b..e21708fb748 100644
--- a/cmd-line-utils/readline/mbutil.c
+++ b/cmd-line-utils/readline/mbutil.c
@@ -22,7 +22,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <sys/types.h>
diff --git a/cmd-line-utils/readline/misc.c b/cmd-line-utils/readline/misc.c
index 94ecb25900a..e0e6893c60e 100644
--- a/cmd-line-utils/readline/misc.c
+++ b/cmd-line-utils/readline/misc.c
@@ -22,7 +22,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#if defined (HAVE_UNISTD_H)
diff --git a/cmd-line-utils/readline/nls.c b/cmd-line-utils/readline/nls.c
index bcee87561aa..6ec685ed9ea 100644
--- a/cmd-line-utils/readline/nls.c
+++ b/cmd-line-utils/readline/nls.c
@@ -22,7 +22,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <sys/types.h>
diff --git a/cmd-line-utils/readline/parens.c b/cmd-line-utils/readline/parens.c
index 737f7675e93..fe1578ed3e2 100644
--- a/cmd-line-utils/readline/parens.c
+++ b/cmd-line-utils/readline/parens.c
@@ -28,7 +28,7 @@
#include "rlconf.h"
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <stdio.h>
diff --git a/cmd-line-utils/readline/readline.c b/cmd-line-utils/readline/readline.c
index c2b74006b05..8c3cad52d36 100644
--- a/cmd-line-utils/readline/readline.c
+++ b/cmd-line-utils/readline/readline.c
@@ -23,7 +23,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <sys/types.h>
diff --git a/cmd-line-utils/readline/rldefs.h b/cmd-line-utils/readline/rldefs.h
index 0f6c87446dd..dcdfc49fbbc 100644
--- a/cmd-line-utils/readline/rldefs.h
+++ b/cmd-line-utils/readline/rldefs.h
@@ -27,7 +27,7 @@
#define _RLDEFS_H_
#if defined (HAVE_CONFIG_H)
-# include "config.h"
+# include "config_readline.h"
#endif
#include "rlstdc.h"
diff --git a/cmd-line-utils/readline/rltty.c b/cmd-line-utils/readline/rltty.c
index 0a570f85840..b5bc5d367a5 100644
--- a/cmd-line-utils/readline/rltty.c
+++ b/cmd-line-utils/readline/rltty.c
@@ -23,7 +23,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <sys/types.h>
diff --git a/cmd-line-utils/readline/rlwinsize.h b/cmd-line-utils/readline/rlwinsize.h
index 7838154d023..60729b0f549 100644
--- a/cmd-line-utils/readline/rlwinsize.h
+++ b/cmd-line-utils/readline/rlwinsize.h
@@ -26,7 +26,7 @@
#define _RLWINSIZE_H_
#if defined (HAVE_CONFIG_H)
-# include "config.h"
+# include "config_readline.h"
#endif
/* Try to find the definitions of `struct winsize' and TIOGCWINSZ */
diff --git a/cmd-line-utils/readline/savestring.c b/cmd-line-utils/readline/savestring.c
index 820428d8881..d42bcadf5d7 100644
--- a/cmd-line-utils/readline/savestring.c
+++ b/cmd-line-utils/readline/savestring.c
@@ -21,7 +21,7 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
-#include <config.h>
+#include "config_readline.h"
#ifdef HAVE_STRING_H
# include <string.h>
#endif
diff --git a/cmd-line-utils/readline/search.c b/cmd-line-utils/readline/search.c
index 33cc4fc1e73..cfa5db1dc17 100644
--- a/cmd-line-utils/readline/search.c
+++ b/cmd-line-utils/readline/search.c
@@ -23,7 +23,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <sys/types.h>
diff --git a/cmd-line-utils/readline/shell.c b/cmd-line-utils/readline/shell.c
index 346f8113d43..5d084476bed 100644
--- a/cmd-line-utils/readline/shell.c
+++ b/cmd-line-utils/readline/shell.c
@@ -23,7 +23,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <sys/types.h>
diff --git a/cmd-line-utils/readline/signals.c b/cmd-line-utils/readline/signals.c
index 54f2a642846..65c2ff308f6 100644
--- a/cmd-line-utils/readline/signals.c
+++ b/cmd-line-utils/readline/signals.c
@@ -22,7 +22,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <stdio.h> /* Just for NULL. Yuck. */
diff --git a/cmd-line-utils/readline/tcap.h b/cmd-line-utils/readline/tcap.h
index 58ab894d93e..04252e72f2d 100644
--- a/cmd-line-utils/readline/tcap.h
+++ b/cmd-line-utils/readline/tcap.h
@@ -25,7 +25,7 @@
#define _RLTCAP_H_
#if defined (HAVE_CONFIG_H)
-# include "config.h"
+# include "config_readline.h"
#endif
#if defined (HAVE_TERMCAP_H)
diff --git a/cmd-line-utils/readline/terminal.c b/cmd-line-utils/readline/terminal.c
index 547f6f5dfe5..a630bc02e05 100644
--- a/cmd-line-utils/readline/terminal.c
+++ b/cmd-line-utils/readline/terminal.c
@@ -22,7 +22,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <sys/types.h>
diff --git a/cmd-line-utils/readline/text.c b/cmd-line-utils/readline/text.c
index 399a48c5f1e..b26afeda525 100644
--- a/cmd-line-utils/readline/text.c
+++ b/cmd-line-utils/readline/text.c
@@ -22,7 +22,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#if defined (HAVE_UNISTD_H)
diff --git a/cmd-line-utils/readline/tilde.c b/cmd-line-utils/readline/tilde.c
index 1b76c9f2404..d50f7a0ffa4 100644
--- a/cmd-line-utils/readline/tilde.c
+++ b/cmd-line-utils/readline/tilde.c
@@ -20,7 +20,7 @@
Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#if defined (HAVE_UNISTD_H)
diff --git a/cmd-line-utils/readline/undo.c b/cmd-line-utils/readline/undo.c
index 9d9bd25ba8f..5699193b14c 100644
--- a/cmd-line-utils/readline/undo.c
+++ b/cmd-line-utils/readline/undo.c
@@ -23,7 +23,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <sys/types.h>
diff --git a/cmd-line-utils/readline/util.c b/cmd-line-utils/readline/util.c
index e44ef64349d..935c9c927c2 100644
--- a/cmd-line-utils/readline/util.c
+++ b/cmd-line-utils/readline/util.c
@@ -22,7 +22,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <sys/types.h>
diff --git a/cmd-line-utils/readline/vi_mode.c b/cmd-line-utils/readline/vi_mode.c
index d0b7e330adc..25213cb762f 100644
--- a/cmd-line-utils/readline/vi_mode.c
+++ b/cmd-line-utils/readline/vi_mode.c
@@ -32,7 +32,7 @@
#if defined (VI_MODE)
#if defined (HAVE_CONFIG_H)
-# include <config.h>
+# include "config_readline.h"
#endif
#include <sys/types.h>
diff --git a/cmd-line-utils/readline/xmalloc.c b/cmd-line-utils/readline/xmalloc.c
index 8985d340d39..cf52da351a8 100644
--- a/cmd-line-utils/readline/xmalloc.c
+++ b/cmd-line-utils/readline/xmalloc.c
@@ -21,7 +21,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
-#include <config.h>
+#include "config_readline.h"
#endif
#include <stdio.h>
diff --git a/configure.in b/configure.in
index 63d3976aa3c..2ee722b4905 100644
--- a/configure.in
+++ b/configure.in
@@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
# remember to also change ndb version below and update version.c in ndb
-AM_INIT_AUTOMAKE(mysql, 5.0.56)
+AM_INIT_AUTOMAKE(mysql, 5.0.60)
AM_CONFIG_HEADER([include/config.h:config.h.in])
PROTOCOL_VERSION=10
@@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0
# ndb version
NDB_VERSION_MAJOR=5
NDB_VERSION_MINOR=0
-NDB_VERSION_BUILD=56
+NDB_VERSION_BUILD=60
NDB_VERSION_STATUS=""
# Set all version vars based on $VERSION. How do we do this more elegant ?
@@ -838,6 +838,8 @@ AC_CHECK_FUNC(p2open, , AC_CHECK_LIB(gen, p2open))
AC_CHECK_FUNC(bind, , AC_CHECK_LIB(bind, bind))
# Check if crypt() exists in libc or libcrypt, sets LIBS if needed
AC_SEARCH_LIBS(crypt, crypt, AC_DEFINE(HAVE_CRYPT, 1, [crypt]))
+# See if we need a library for address lookup.
+AC_SEARCH_LIBS(inet_aton, [socket nsl resolv])
# For the sched_yield() function on Solaris
AC_CHECK_FUNC(sched_yield, , AC_CHECK_LIB(posix4, sched_yield))
diff --git a/extra/CMakeLists.txt b/extra/CMakeLists.txt
index a909bc93820..c1477e41a81 100755
--- a/extra/CMakeLists.txt
+++ b/extra/CMakeLists.txt
@@ -44,6 +44,9 @@ TARGET_LINK_LIBRARIES(my_print_defaults strings mysys debug dbug taocrypt wsock3
ADD_EXECUTABLE(perror perror.c)
TARGET_LINK_LIBRARIES(perror strings mysys debug dbug wsock32)
+ADD_EXECUTABLE(resolveip resolveip.c)
+TARGET_LINK_LIBRARIES(resolveip strings mysys debug dbug wsock32)
+
ADD_EXECUTABLE(replace replace.c)
TARGET_LINK_LIBRARIES(replace strings mysys debug dbug wsock32)
diff --git a/extra/resolveip.c b/extra/resolveip.c
index 1061cafe380..aedc2cc3418 100644
--- a/extra/resolveip.c
+++ b/extra/resolveip.c
@@ -21,13 +21,15 @@
#include <m_ctype.h>
#include <my_sys.h>
#include <m_string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#ifndef HAVE_BROKEN_NETINET_INCLUDES
-#include <netinet/in.h>
+#ifndef WIN32
+# include <sys/types.h>
+# include <sys/socket.h>
+# ifndef HAVE_BROKEN_NETINET_INCLUDES
+# include <netinet/in.h>
+# endif
+# include <arpa/inet.h>
+# include <netdb.h>
#endif
-#include <arpa/inet.h>
-#include <netdb.h>
#include <my_net.h>
#include <my_getopt.h>
@@ -116,11 +118,21 @@ int main(int argc, char **argv)
while (argc--)
{
+#ifndef WIN32
+ struct in_addr addr;
+#endif
ip = *argv++;
- if (my_isdigit(&my_charset_latin1,ip[0]))
+ /* Not compatible with IPv6! Probably should use getnameinfo(). */
+#ifdef WIN32
+ taddr = inet_addr(ip);
+ if(taddr != INADDR_NONE)
+ {
+#else
+ if (inet_aton(ip, &addr) != 0)
{
- taddr = inet_addr(ip);
+ taddr= addr.s_addr;
+#endif
if (taddr == htonl(INADDR_BROADCAST))
{
puts("Broadcast");
diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp
index 1d5a95820bb..262b5cb3b8b 100644
--- a/extra/yassl/src/handshake.cpp
+++ b/extra/yassl/src/handshake.cpp
@@ -527,6 +527,11 @@ void ProcessOldClientHello(input_buffer& input, SSL& ssl)
input.read(len, sizeof(len));
uint16 randomLen;
ato16(len, randomLen);
+ if (ch.suite_len_ > MAX_SUITE_SZ || sessionLen > ID_LEN ||
+ randomLen > RAN_LEN) {
+ ssl.SetError(bad_input);
+ return;
+ }
int j = 0;
for (uint16 i = 0; i < ch.suite_len_; i += 3) {
diff --git a/extra/yassl/src/template_instnt.cpp b/extra/yassl/src/template_instnt.cpp
index f82f7924359..fe3a251b865 100644
--- a/extra/yassl/src/template_instnt.cpp
+++ b/extra/yassl/src/template_instnt.cpp
@@ -101,6 +101,7 @@ template void ysArrayDelete<unsigned char>(unsigned char*);
template void ysArrayDelete<char>(char*);
template int min<int>(int, int);
+template uint16 min<uint16>(uint16, uint16);
template unsigned int min<unsigned int>(unsigned int, unsigned int);
template unsigned long min<unsigned long>(unsigned long, unsigned long);
}
diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp
index 0bc95f64abc..b43d9c27355 100644
--- a/extra/yassl/src/yassl_imp.cpp
+++ b/extra/yassl/src/yassl_imp.cpp
@@ -621,6 +621,10 @@ void HandShakeHeader::Process(input_buffer& input, SSL& ssl)
}
uint len = c24to32(length_);
+ if (len > input.get_remaining()) {
+ ssl.SetError(bad_input);
+ return;
+ }
hashHandShake(ssl, input, len);
hs->set_length(len);
@@ -1391,10 +1395,15 @@ input_buffer& operator>>(input_buffer& input, ClientHello& hello)
// Suites
byte tmp[2];
+ uint16 len;
tmp[0] = input[AUTO];
tmp[1] = input[AUTO];
- ato16(tmp, hello.suite_len_);
+ ato16(tmp, len);
+
+ hello.suite_len_ = min(len, static_cast<uint16>(MAX_SUITE_SZ));
input.read(hello.cipher_suites_, hello.suite_len_);
+ if (len > hello.suite_len_) // ignore extra suites
+ input.set_current(input.get_current() + len - hello.suite_len_);
// Compression
hello.comp_len_ = input[AUTO];
diff --git a/include/my_sys.h b/include/my_sys.h
index f72aef13989..d656326e968 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -530,6 +530,12 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *);
#define my_b_tell(info) ((info)->pos_in_file + \
(uint) (*(info)->current_pos - (info)->request_pos))
+#define my_b_get_buffer_start(info) (info)->request_pos
+#define my_b_get_bytes_in_buffer(info) (char*) (info)->read_end - \
+ (char*) my_b_get_buffer_start(info)
+#define my_b_get_pos_in_file(info) (info)->pos_in_file
+
+
/* tell write offset in the SEQ_APPEND cache */
my_off_t my_b_append_tell(IO_CACHE* info);
my_off_t my_b_safe_tell(IO_CACHE* info); /* picks the correct tell() */
diff --git a/mysql-test/include/have_local_infile.inc b/mysql-test/include/have_local_infile.inc
new file mode 100644
index 00000000000..4a1362c6e30
--- /dev/null
+++ b/mysql-test/include/have_local_infile.inc
@@ -0,0 +1,4 @@
+--require r/have_local_infile.require
+disable_query_log;
+show variables like 'local_infile';
+enable_query_log;
diff --git a/mysql-test/include/ndb_wait_connected.inc b/mysql-test/include/ndb_wait_connected.inc
new file mode 100644
index 00000000000..cfea94db1f1
--- /dev/null
+++ b/mysql-test/include/ndb_wait_connected.inc
@@ -0,0 +1,26 @@
+# Check that mysqld has reconnected to ndbd after
+# restart of ndbd
+#
+--disable_query_log
+--disable_result_log
+let $mysql_errno= 1;
+let $counter= 600;
+while ($mysql_errno)
+{
+ --error 0,157
+ CREATE TABLE ndb_wait_connected (a int primary key);
+ if ($mysql_errno)
+ {
+ if (!$counter)
+ {
+ die Failed waiting for mysqld to reconnect to ndbd;
+ }
+ dec $counter;
+ --sleep 0.1
+ }
+}
+DROP TABLE ndb_wait_connected;
+--enable_query_log
+--enable_result_log
+
+
diff --git a/mysql-test/include/show_binlog_events2.inc b/mysql-test/include/show_binlog_events2.inc
new file mode 100644
index 00000000000..fa244c5a5a3
--- /dev/null
+++ b/mysql-test/include/show_binlog_events2.inc
@@ -0,0 +1,5 @@
+--let $binlog_start=98
+--replace_result $binlog_start <binlog_start>
+--replace_column 2 # 5 #
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
+--eval show binlog events from $binlog_start
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 29c5648090c..7c4677b8274 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -3765,12 +3765,11 @@ sub mysqld_arguments ($$$$) {
# When mysqld is run by a root user(euid is 0), it will fail
- # to start unless we specify what user to run as. If not running
- # as root it will be ignored, see BUG#30630
+ # to start unless we specify what user to run as, see BUG#30630
my $euid= $>;
if (!$glob_win32 and $euid == 0 and
grep(/^--user/, @$extra_opt, @opt_extra_mysqld_opt) == 0) {
- mtr_add_arg($args, "%s--user=root");
+ mtr_add_arg($args, "%s--user=root", $prefix);
}
if ( $opt_valgrind_mysqld )
diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result
index 3356d23053f..fefeeb405c5 100644
--- a/mysql-test/r/bdb.result
+++ b/mysql-test/r/bdb.result
@@ -1325,6 +1325,7 @@ set @a=repeat(' ',20);
insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a));
Warnings:
Note 1265 Data truncated for column 'v' at row 1
+Note 1265 Data truncated for column 'c' at row 1
select concat('*',v,'*',c,'*',t,'*') from t1;
concat('*',v,'*',c,'*',t,'*')
*+ *+*+ *
diff --git a/mysql-test/r/bdb_notembedded.result b/mysql-test/r/bdb_notembedded.result
index 14cb5fad915..2367e0d3fda 100644
--- a/mysql-test/r/bdb_notembedded.result
+++ b/mysql-test/r/bdb_notembedded.result
@@ -24,12 +24,18 @@ show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4
f n Query 1 n use `test`; create table bug16206 (a int) engine= bdb
+f n Query 1 n use `test`; BEGIN
f n Query 1 n use `test`; insert into bug16206 values(0)
+f n Query 1 n use `test`; COMMIT
+f n Query 1 n use `test`; BEGIN
f n Query 1 n use `test`; insert into bug16206 values(1)
+f n Query 1 n use `test`; COMMIT
f n Query 1 n use `test`; BEGIN
f n Query 1 n use `test`; insert into bug16206 values(2)
f n Query 1 n use `test`; COMMIT
+f n Query 1 n use `test`; BEGIN
f n Query 1 n use `test`; insert into bug16206 values(3)
+f n Query 1 n use `test`; COMMIT
drop table bug16206;
set autocommit=0;
End of 5.0 tests
diff --git a/mysql-test/r/binlog.result b/mysql-test/r/binlog.result
index 0a199c87545..e6c5e3222de 100644
--- a/mysql-test/r/binlog.result
+++ b/mysql-test/r/binlog.result
@@ -567,4 +567,19 @@ master-bin.000001 36585 Rotate 1 36629 master-bin.000002;pos=4
drop table t1;
set global binlog_cache_size=@bcs;
set session autocommit = @ac;
+drop table if exists t1;
+reset master;
+create table t1 (a bigint unsigned, b bigint(20) unsigned);
+prepare stmt from "insert into t1 values (?,?)";
+set @a= 9999999999999999;
+set @b= 14632475938453979136;
+execute stmt using @a, @b;
+deallocate prepare stmt;
+drop table t1;
+show binlog events from 0;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 4 Format_desc 1 98 Server version, Binlog ver: 4
+master-bin.000001 98 Query 1 219 use `test`; create table t1 (a bigint unsigned, b bigint(20) unsigned)
+master-bin.000001 219 Query 1 343 use `test`; insert into t1 values (9999999999999999,14632475938453979136)
+master-bin.000001 343 Query 1 419 use `test`; drop table t1
End of 5.0 tests
diff --git a/mysql-test/r/binlog_innodb.result b/mysql-test/r/binlog_innodb.result
index 93414a13ba1..18b4b7c1c93 100644
--- a/mysql-test/r/binlog_innodb.result
+++ b/mysql-test/r/binlog_innodb.result
@@ -21,3 +21,19 @@ show status like "binlog_cache_disk_use";
Variable_name Value
Binlog_cache_disk_use 1
drop table t1;
+CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=MyISAM;
+CREATE TABLE t2 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
+CREATE FUNCTION bug23333()
+RETURNS int(11)
+DETERMINISTIC
+BEGIN
+INSERT INTO t1 VALUES (NULL);
+SELECT COUNT(*) FROM t1 INTO @a;
+RETURN @a;
+END|
+INSERT INTO t2 VALUES (2),(10+bug23333());
+SHOW MASTER STATUS;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+# 184136
+DROP FUNCTION bug23333;
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/binlog_start_comment.result b/mysql-test/r/binlog_start_comment.result
new file mode 100644
index 00000000000..162968195f2
--- /dev/null
+++ b/mysql-test/r/binlog_start_comment.result
@@ -0,0 +1,15 @@
+reset master;
+drop table if exists t1,t2;
+create table t1 (word varchar(20)) -- create table t1;
+create table t2 (word varchar(20)) -- create table t2;
+load data infile '../std_data_ln/words.dat' into table t1 -- load data to t1;
+insert into t2 values ("Ada");
+flush logs;
+select * from t2;
+word
+Ada
+flush logs;
+select * from t2;
+word
+Ada
+drop table t1,t2;
diff --git a/mysql-test/r/blackhole.result b/mysql-test/r/blackhole.result
index 5ab4931b53b..a4b780f9db5 100644
--- a/mysql-test/r/blackhole.result
+++ b/mysql-test/r/blackhole.result
@@ -115,8 +115,8 @@ master-bin.000001 # Query 1 # use `test`; insert into t1 values(1)
master-bin.000001 # Query 1 # use `test`; insert ignore into t1 values(1)
master-bin.000001 # Query 1 # use `test`; replace into t1 values(100)
master-bin.000001 # Query 1 # use `test`; create table t2 (a varchar(200)) engine=blackhole
-master-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581
-master-bin.000001 # Execute_load_query 1 # use `test`; load data infile '../std_data_ln/words.dat' into table t2 ;file_id=1
+master-bin.000001 # Begin_load_query 1 # ;file_id=#;block_len=581
+master-bin.000001 # Execute_load_query 1 # use `test`; load data infile '../std_data_ln/words.dat' into table t2 ;file_id=#
master-bin.000001 # Query 1 # use `test`; alter table t1 add b int
master-bin.000001 # Query 1 # use `test`; alter table t1 drop b
master-bin.000001 # Query 1 # use `test`; create table t3 like t1
diff --git a/mysql-test/r/compare.result b/mysql-test/r/compare.result
index c141b255716..c9ef41e0582 100644
--- a/mysql-test/r/compare.result
+++ b/mysql-test/r/compare.result
@@ -53,3 +53,41 @@ a b
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: ''
drop table if exists t1;
+CREATE TABLE t1 (b int(2) zerofill, c int(2) zerofill);
+INSERT INTO t1 (b,c) VALUES (1,2), (1,1), (2,2);
+SELECT CONCAT(b,c), CONCAT(b,c) = '0101' FROM t1;
+CONCAT(b,c) CONCAT(b,c) = '0101'
+0102 0
+0101 1
+0202 0
+EXPLAIN EXTENDED SELECT b,c FROM t1 WHERE b = 1 AND CONCAT(b,c) = '0101';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`b` = 1) and (concat(_binary'01',`test`.`t1`.`c`) = _latin1'0101'))
+SELECT b,c FROM t1 WHERE b = 1 AND CONCAT(b,c) = '0101';
+b c
+01 01
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (1),(2);
+SELECT a,
+(SELECT COUNT(*) FROM t1
+WHERE b = t2.a AND CONCAT(b,c) = CONCAT('0',t2.a,'01')) x
+FROM t2 ORDER BY a;
+a x
+1 1
+2 0
+EXPLAIN EXTENDED
+SELECT a,
+(SELECT COUNT(*) FROM t1
+WHERE b = t2.a AND CONCAT(b,c) = CONCAT('0',t2.a,'01')) x
+FROM t2 ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using filesort
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
+Warnings:
+Note 1276 Field or reference 'test.t2.a' of SELECT #2 was resolved in SELECT #1
+Note 1276 Field or reference 'test.t2.a' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t2`.`a` AS `a`,(select count(0) AS `COUNT(*)` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t2`.`a`) and (concat(`test`.`t1`.`b`,`test`.`t1`.`c`) = concat(_latin1'0',`test`.`t2`.`a`,_latin1'01')))) AS `x` from `test`.`t2` order by `test`.`t2`.`a`
+DROP TABLE t1,t2;
+End of 5.0 tests
diff --git a/mysql-test/r/ctype_cp932_binlog.result b/mysql-test/r/ctype_cp932_binlog.result
index 3385cd20ec4..0b4ca93a0dd 100644
--- a/mysql-test/r/ctype_cp932_binlog.result
+++ b/mysql-test/r/ctype_cp932_binlog.result
@@ -40,6 +40,6 @@ IN ind DECIMAL(10,2))
BEGIN
INSERT INTO t4 VALUES (ins1, ins2, ind);
END
-master-bin.000001 776 Query 1 995 use `test`; INSERT INTO t4 VALUES ( NAME_CONST('ins1',_latin1 0x466F6F2773206120426172), NAME_CONST('ins2',_cp932 0xED40ED41ED42), NAME_CONST('ind',47.93))
-master-bin.000001 995 Query 1 1084 use `test`; DROP PROCEDURE bug18293
-master-bin.000001 1084 Query 1 1163 use `test`; DROP TABLE t4
+master-bin.000001 776 Query 1 987 use `test`; INSERT INTO t4 VALUES ( NAME_CONST('ins1',_latin1 0x466F6F2773206120426172), NAME_CONST('ins2',_cp932 0xED40ED41ED42), NAME_CONST('ind',47.93))
+master-bin.000001 987 Query 1 1076 use `test`; DROP PROCEDURE bug18293
+master-bin.000001 1076 Query 1 1155 use `test`; DROP TABLE t4
diff --git a/mysql-test/r/ctype_ucs_binlog.result b/mysql-test/r/ctype_ucs_binlog.result
index 2657bf60c04..721a1ae51b7 100644
--- a/mysql-test/r/ctype_ucs_binlog.result
+++ b/mysql-test/r/ctype_ucs_binlog.result
@@ -18,7 +18,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t2 values (@v)/*!*/;
+insert into t2 values (@v)
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result
index 19b5f03de6b..77d11831842 100644
--- a/mysql-test/r/func_gconcat.result
+++ b/mysql-test/r/func_gconcat.result
@@ -931,4 +931,19 @@ SELECT GROUP_CONCAT(DISTINCT b, a ORDER BY b) FROM t1;
GROUP_CONCAT(DISTINCT b, a ORDER BY b)
11,22,32
DROP TABLE t1, t2, t3;
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (),();
+SELECT s1.d1 FROM
+(
+SELECT
+t1.a as d1,
+GROUP_CONCAT(DISTINCT t1.a) AS d2
+FROM
+t1 AS t1,
+t1 AS t2
+GROUP BY 1
+) AS s1;
+d1
+NULL
+DROP TABLE t1;
End of 5.0 tests
diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result
index 4f6b6d3a0d8..cccdd391497 100644
--- a/mysql-test/r/func_misc.result
+++ b/mysql-test/r/func_misc.result
@@ -207,6 +207,25 @@ test
SELECT NAME_CONST('test', 'test');
test
test
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2),(3);
+SELECT NAME_CONST('flag',1) * MAX(a) FROM t1;
+NAME_CONST('flag',1) * MAX(a)
+3
+SELECT NAME_CONST('flag',1.5) * MAX(a) FROM t1;
+NAME_CONST('flag',1.5) * MAX(a)
+4.5
+SELECT NAME_CONST('flag',-1) * MAX(a) FROM t1;
+NAME_CONST('flag',-1) * MAX(a)
+-3
+SELECT NAME_CONST('flag',-1.5) * MAX(a) FROM t1;
+NAME_CONST('flag',-1.5) * MAX(a)
+-4.5
+SELECT NAME_CONST('flag', SQRT(4)) * MAX(a) FROM t1;
+ERROR HY000: Incorrect arguments to NAME_CONST
+SELECT NAME_CONST('flag',-SQRT(4)) * MAX(a) FROM t1;
+ERROR HY000: Incorrect arguments to NAME_CONST
+DROP TABLE t1;
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (5), (2);
SELECT NAME_CONST(x,2) FROM (SELECT a x FROM t1) t;
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index f25f9ed9e0a..d397947d7ca 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -666,6 +666,8 @@ timestampadd(SQL_TSI_SECOND, 1, date)
select timestampadd(SQL_TSI_FRAC_SECOND, 1, date) from t1;
timestampadd(SQL_TSI_FRAC_SECOND, 1, date)
2003-01-02 00:00:00.000001
+Warnings:
+Warning 1287 'FRAC_SECOND' is deprecated; use 'MICROSECOND' instead
select timestampdiff(MONTH, '2001-02-01', '2001-05-01') as a;
a
3
@@ -699,6 +701,8 @@ a
select timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a;
a
7689538999999
+Warnings:
+Warning 1287 'FRAC_SECOND' is deprecated; use 'MICROSECOND' instead
select timestampdiff(SQL_TSI_DAY, '1986-02-01', '1986-03-01') as a1,
timestampdiff(SQL_TSI_DAY, '1900-02-01', '1900-03-01') as a2,
timestampdiff(SQL_TSI_DAY, '1996-02-01', '1996-03-01') as a3,
@@ -1069,6 +1073,7 @@ timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
+Warning 1287 'FRAC_SECOND' is deprecated; use 'MICROSECOND' instead
Note 1003 select timestampdiff(WEEK,_latin1'2001-02-01',_latin1'2001-05-01') AS `a1`,timestampdiff(SECOND_FRAC,_latin1'2001-02-01 12:59:59.120000',_latin1'2001-05-01 12:58:58.119999') AS `a2`
select last_day('2005-00-00');
last_day('2005-00-00')
@@ -1285,4 +1290,22 @@ DATE_ADD(20071108, INTERVAL 1 DAY)
select LAST_DAY('2007-12-06 08:59:19.05') - INTERVAL 1 SECOND;
LAST_DAY('2007-12-06 08:59:19.05') - INTERVAL 1 SECOND
2007-12-30 23:59:59
+SELECT TIMESTAMPADD(FRAC_SECOND, 1, '2008-02-18');
+TIMESTAMPADD(FRAC_SECOND, 1, '2008-02-18')
+2008-02-18 00:00:00.000001
+Warnings:
+Warning 1287 'FRAC_SECOND' is deprecated; use 'MICROSECOND' instead
+SELECT TIMESTAMPDIFF(FRAC_SECOND, '2008-02-17', '2008-02-18');
+TIMESTAMPDIFF(FRAC_SECOND, '2008-02-17', '2008-02-18')
+86400000000
+Warnings:
+Warning 1287 'FRAC_SECOND' is deprecated; use 'MICROSECOND' instead
+SELECT DATE_ADD('2008-02-18', INTERVAL 1 FRAC_SECOND);
+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 'FRAC_SECOND)' at line 1
+SELECT DATE_SUB('2008-02-18', INTERVAL 1 FRAC_SECOND);
+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 'FRAC_SECOND)' at line 1
+SELECT '2008-02-18' + INTERVAL 1 FRAC_SECOND;
+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 'FRAC_SECOND' at line 1
+SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND;
+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 'FRAC_SECOND' at line 1
End of 5.0 tests
diff --git a/mysql-test/r/grant3.result b/mysql-test/r/grant3.result
index cc7f46855b2..f38848111ad 100644
--- a/mysql-test/r/grant3.result
+++ b/mysql-test/r/grant3.result
@@ -138,3 +138,20 @@ SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by
user host db select_priv
DROP USER CUser2@localhost;
DROP USER CUser2@LOCALHOST;
+CREATE DATABASE mysqltest_1;
+CREATE TABLE mysqltest_1.t1 (a INT);
+CREATE USER 'mysqltest1'@'%';
+GRANT SELECT, UPDATE ON `mysqltest_1`.* TO 'mysqltest1'@'%';
+REVOKE SELECT ON `mysqltest_1`.* FROM 'mysqltest1'@'%';
+GRANT SELECT, UPDATE ON `mysqltest\_1`.* TO 'mysqltest1'@'%';
+FLUSH PRIVILEGES;
+SHOW GRANTS;
+Grants for mysqltest1@%
+GRANT USAGE ON *.* TO 'mysqltest1'@'%'
+GRANT SELECT, UPDATE ON `mysqltest\_1`.* TO 'mysqltest1'@'%'
+GRANT UPDATE ON `mysqltest_1`.* TO 'mysqltest1'@'%'
+SELECT * FROM mysqltest_1.t1;
+a
+DROP USER 'mysqltest1'@'%';
+DROP DATABASE mysqltest_1;
+End of 5.0 tests
diff --git a/mysql-test/r/have_local_infile.require b/mysql-test/r/have_local_infile.require
new file mode 100644
index 00000000000..124540f7b77
--- /dev/null
+++ b/mysql-test/r/have_local_infile.require
@@ -0,0 +1,2 @@
+Variable_name Value
+local_infile ON
diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result
index 906c431b834..adfcc00174f 100644
--- a/mysql-test/r/heap.result
+++ b/mysql-test/r/heap.result
@@ -256,6 +256,7 @@ set @a=repeat(' ',20);
insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a));
Warnings:
Note 1265 Data truncated for column 'v' at row 1
+Note 1265 Data truncated for column 'c' at row 1
select concat('*',v,'*',c,'*',t,'*') from t1;
concat('*',v,'*',c,'*',t,'*')
*+ *+*+ *
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 854712fdb1d..774e0bd167b 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1901,6 +1901,7 @@ set @a=repeat(' ',20);
insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a));
Warnings:
Note 1265 Data truncated for column 'v' at row 1
+Note 1265 Data truncated for column 'c' at row 1
select concat('*',v,'*',c,'*',t,'*') from t1;
concat('*',v,'*',c,'*',t,'*')
*+ *+*+ *
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index 2ab463e7f85..b487cfd9a4b 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -1240,4 +1240,10 @@ t1 CREATE TABLE `t1` (
UNIQUE KEY `aa` (`a`(1))
) ENGINE=InnoDB DEFAULT CHARSET=latin1
drop table t1;
+set @my_innodb_autoextend_increment=@@global.innodb_autoextend_increment;
+set global innodb_autoextend_increment=8;
+set global innodb_autoextend_increment=@my_innodb_autoextend_increment;
+set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
+set global innodb_commit_concurrency=0;
+set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
End of 5.0 tests
diff --git a/mysql-test/r/limit.result b/mysql-test/r/limit.result
index 01d7d7ca218..2acf74162a4 100644
--- a/mysql-test/r/limit.result
+++ b/mysql-test/r/limit.result
@@ -94,6 +94,9 @@ drop table t1;
prepare s from "select 1 limit ?";
set @a='qwe';
execute s using @a;
+1
+set @a=-1;
+execute s using @a;
ERROR HY000: Incorrect arguments to EXECUTE
prepare s from "select 1 limit 1, ?";
execute s using @a;
@@ -101,4 +104,10 @@ ERROR HY000: Incorrect arguments to EXECUTE
prepare s from "select 1 limit ?, ?";
execute s using @a, @a;
ERROR HY000: Incorrect arguments to EXECUTE
+set @a=14632475938453979136;
+execute s using @a, @a;
+1
+set @a=-14632475938453979136;
+execute s using @a, @a;
+ERROR HY000: Incorrect arguments to EXECUTE
End of 5.0 tests
diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result
index 89ee82e9655..e1968ac7ef8 100644
--- a/mysql-test/r/mix_innodb_myisam_binlog.result
+++ b/mysql-test/r/mix_innodb_myisam_binlog.result
@@ -100,9 +100,10 @@ insert into t1 values(9);
insert into t2 select * from t1;
show binlog events from 98;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 # use `test`; insert into t1 values(9)
-master-bin.000001 185 Xid 1 # COMMIT /* XID */
-master-bin.000001 212 Query 1 # use `test`; insert into t2 select * from t1
+master-bin.000001 98 Query 1 # use `test`; BEGIN
+master-bin.000001 166 Query 1 # use `test`; insert into t1 values(9)
+master-bin.000001 253 Xid 1 # COMMIT /* XID */
+master-bin.000001 280 Query 1 # use `test`; insert into t2 select * from t1
delete from t1;
delete from t2;
reset master;
@@ -111,19 +112,21 @@ begin;
insert into t2 select * from t1;
show binlog events from 98;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 # use `test`; insert into t1 values(10)
-master-bin.000001 186 Xid 1 # COMMIT /* XID */
-master-bin.000001 213 Query 1 # use `test`; insert into t2 select * from t1
+master-bin.000001 98 Query 1 # use `test`; BEGIN
+master-bin.000001 166 Query 1 # use `test`; insert into t1 values(10)
+master-bin.000001 254 Xid 1 # COMMIT /* XID */
+master-bin.000001 281 Query 1 # use `test`; insert into t2 select * from t1
insert into t1 values(11);
commit;
show binlog events from 98;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 # use `test`; insert into t1 values(10)
-master-bin.000001 186 Xid 1 # COMMIT /* XID */
-master-bin.000001 213 Query 1 # use `test`; insert into t2 select * from t1
-master-bin.000001 307 Query 1 # use `test`; BEGIN
-master-bin.000001 375 Query 1 # use `test`; insert into t1 values(11)
-master-bin.000001 463 Xid 1 # COMMIT /* XID */
+master-bin.000001 98 Query 1 # use `test`; BEGIN
+master-bin.000001 166 Query 1 # use `test`; insert into t1 values(10)
+master-bin.000001 254 Xid 1 # COMMIT /* XID */
+master-bin.000001 281 Query 1 # use `test`; insert into t2 select * from t1
+master-bin.000001 375 Query 1 # use `test`; BEGIN
+master-bin.000001 443 Query 1 # use `test`; insert into t1 values(11)
+master-bin.000001 531 Xid 1 # COMMIT /* XID */
alter table t2 engine=INNODB;
delete from t1;
delete from t2;
@@ -235,25 +238,29 @@ master-bin.000001 98 Query 1 # use `test`; BEGIN
master-bin.000001 166 Query 1 # use `test`; insert into t1 values(16)
master-bin.000001 254 Query 1 # use `test`; insert into t1 values(18)
master-bin.000001 342 Xid 1 # COMMIT /* XID */
-master-bin.000001 369 Query 1 # use `test`; delete from t1
-master-bin.000001 446 Xid 1 # COMMIT /* XID */
-master-bin.000001 473 Query 1 # use `test`; delete from t2
-master-bin.000001 550 Xid 1 # COMMIT /* XID */
-master-bin.000001 577 Query 1 # use `test`; alter table t2 type=MyISAM
-master-bin.000001 666 Query 1 # use `test`; insert into t1 values (1)
-master-bin.000001 754 Xid 1 # COMMIT /* XID */
-master-bin.000001 781 Query 1 # use `test`; insert into t2 values (20)
-master-bin.000001 870 Query 1 # use `test`; drop table t1,t2
-master-bin.000001 949 Query 1 # use `test`; create temporary table ti (a int) engine=innodb
-master-bin.000001 1059 Query 1 # use `test`; insert into ti values(1)
-master-bin.000001 1146 Xid 1 # COMMIT /* XID */
-master-bin.000001 1173 Query 1 # use `test`; create temporary table t1 (a int) engine=myisam
-master-bin.000001 1283 Query 1 # use `test`; insert t1 values (1)
-master-bin.000001 1366 Query 1 # use `test`; create table t0 (n int)
-master-bin.000001 1452 Query 1 # use `test`; insert t0 select * from t1
-master-bin.000001 1541 Query 1 # use `test`; insert into t0 select GET_LOCK("lock1",null)
-master-bin.000001 1648 Query 1 # use `test`; create table t2 (n int) engine=innodb
-master-bin.000001 1748 Query 1 # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `test`.`t1`,`test`.`ti`
+master-bin.000001 369 Query 1 # use `test`; BEGIN
+master-bin.000001 437 Query 1 # use `test`; delete from t1
+master-bin.000001 514 Xid 1 # COMMIT /* XID */
+master-bin.000001 541 Query 1 # use `test`; BEGIN
+master-bin.000001 609 Query 1 # use `test`; delete from t2
+master-bin.000001 686 Xid 1 # COMMIT /* XID */
+master-bin.000001 713 Query 1 # use `test`; alter table t2 type=MyISAM
+master-bin.000001 802 Query 1 # use `test`; BEGIN
+master-bin.000001 870 Query 1 # use `test`; insert into t1 values (1)
+master-bin.000001 958 Xid 1 # COMMIT /* XID */
+master-bin.000001 985 Query 1 # use `test`; insert into t2 values (20)
+master-bin.000001 1074 Query 1 # use `test`; drop table t1,t2
+master-bin.000001 1153 Query 1 # use `test`; create temporary table ti (a int) engine=innodb
+master-bin.000001 1263 Query 1 # use `test`; BEGIN
+master-bin.000001 1331 Query 1 # use `test`; insert into ti values(1)
+master-bin.000001 1418 Xid 1 # COMMIT /* XID */
+master-bin.000001 1445 Query 1 # use `test`; create temporary table t1 (a int) engine=myisam
+master-bin.000001 1555 Query 1 # use `test`; insert t1 values (1)
+master-bin.000001 1638 Query 1 # use `test`; create table t0 (n int)
+master-bin.000001 1724 Query 1 # use `test`; insert t0 select * from t1
+master-bin.000001 1813 Query 1 # use `test`; insert into t0 select GET_LOCK("lock1",null)
+master-bin.000001 1920 Query 1 # use `test`; create table t2 (n int) engine=innodb
+master-bin.000001 2020 Query 1 # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `test`.`t1`,`test`.`ti`
do release_lock("lock1");
drop table t0,t2;
reset master;
@@ -275,9 +282,11 @@ is not null;
is not null
1
select
-@a like "%#%error_code=0%ROLLBACK/*!*/;%ROLLBACK /* added by mysqlbinlog */;%",
+@a like "%#%error_code=0%ROLLBACK\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" OR
+@a like "%#%error_code=0%ROLLBACK\r\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%",
@a not like "%#%error_code=%error_code=%";
-@a like "%#%error_code=0%ROLLBACK/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" @a not like "%#%error_code=%error_code=%"
+@a like "%#%error_code=0%ROLLBACK\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" OR
+@a like "%#%error_code=0%ROLLBACK\r\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" @a not like "%#%error_code=%error_code=%"
1 1
drop table t1, t2;
create temporary table tt (a int unique);
@@ -402,7 +411,7 @@ insert into t2 values (bug27417(1));
ERROR 23000: Duplicate entry '1' for key 1
show master status /* the offset must denote there is the query */;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000001 267
+master-bin.000001 335
select count(*) from t1 /* must be 1 */;
count(*)
1
@@ -414,7 +423,7 @@ insert into t2 select bug27417(1) union select bug27417(2);
ERROR 23000: Duplicate entry '2' for key 1
show master status /* the offset must denote there is the query */;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000001 290
+master-bin.000001 358
select count(*) from t1 /* must be 2 */;
count(*)
2
@@ -438,7 +447,7 @@ UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */;
ERROR 23000: Duplicate entry '2' for key 1
show master status /* the offset must denote there is the query */;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000001 301
+master-bin.000001 369
select count(*) from t1 /* must be 4 */;
count(*)
4
@@ -466,7 +475,7 @@ delete from t2;
ERROR 23000: Duplicate entry '1' for key 1
show master status /* the offset must denote there is the query */;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000001 246
+master-bin.000001 314
select count(*) from t1 /* must be 1 */;
count(*)
1
@@ -483,7 +492,7 @@ delete t2.* from t2,t5 where t2.a=t5.a + 1;
ERROR 23000: Duplicate entry '1' for key 1
show master status /* the offset must denote there is the query */;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000001 274
+master-bin.000001 342
select count(*) from t1 /* must be 1 */;
count(*)
1
@@ -501,7 +510,7 @@ count(*)
2
show master status /* the offset must denote there is the query */;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000001 376
+master-bin.000001 444
drop trigger trg_del_t2;
drop table t1,t2,t3,t4,t5;
drop function bug27417;
diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result
index d95036090a5..8a0eacd9eeb 100644
--- a/mysql-test/r/multi_update.result
+++ b/mysql-test/r/multi_update.result
@@ -545,7 +545,7 @@ a b
4 4
show master status /* there must be the UPDATE query event */;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000001 260
+master-bin.000001 328
delete from t1;
delete from t2;
insert into t1 values (1,2),(3,4),(4,4);
@@ -555,7 +555,7 @@ UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a;
ERROR 23000: Duplicate entry '4' for key 1
show master status /* there must be the UPDATE query event */;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000001 275
+master-bin.000001 343
drop table t1, t2;
drop table if exists t1, t2, t3;
CREATE TABLE t1 (a int, PRIMARY KEY (a));
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index 33f64d600bb..24c1cecfb4f 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -1104,6 +1104,7 @@ set @a=repeat(' ',20);
insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a));
Warnings:
Note 1265 Data truncated for column 'v' at row 1
+Note 1265 Data truncated for column 'c' at row 1
select concat('*',v,'*',c,'*',t,'*') from t1;
concat('*',v,'*',c,'*',t,'*')
*+ *+*+ *
diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result
index 9f001c293de..469250a6fa2 100644
--- a/mysql-test/r/mysqlbinlog.result
+++ b/mysql-test/r/mysqlbinlog.result
@@ -23,24 +23,33 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-drop table if exists t1,t2,t3,t4,t5,t03,t04/*!*/;
+drop table if exists t1,t2,t3,t4,t5,t03,t04
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-create table t1 (word varchar(20))/*!*/;
+create table t1 (word varchar(20))
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-create table t2 (id int auto_increment not null primary key)/*!*/;
+create table t2 (id int auto_increment not null primary key)
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-insert into t1 values ("abirvalg")/*!*/;
+insert into t1 values ("abirvalg")
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-insert into t2 values ()/*!*/;
+insert into t2 values ()
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-1-0' INTO table t1/*!*/;
+load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-2-0' INTO table t1/*!*/;
+load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-3-0' INTO table t1/*!*/;
+load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-4-0' INTO table t1/*!*/;
+load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -56,7 +65,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values ("Alas")/*!*/;
+insert into t1 values ("Alas")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -83,7 +93,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values ("Alas")/*!*/;
+insert into t1 values ("Alas")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -100,24 +111,33 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-drop table if exists t1,t2,t3,t4,t5,t03,t04/*!*/;
+drop table if exists t1,t2,t3,t4,t5,t03,t04
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-create table t1 (word varchar(20))/*!*/;
+create table t1 (word varchar(20))
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-create table t2 (id int auto_increment not null primary key)/*!*/;
+create table t2 (id int auto_increment not null primary key)
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-insert into t1 values ("abirvalg")/*!*/;
+insert into t1 values ("abirvalg")
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-insert into t2 values ()/*!*/;
+insert into t2 values ()
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-1-2' INTO table t1/*!*/;
+load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-2-2' INTO table t1/*!*/;
+load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-3-2' INTO table t1/*!*/;
+load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-4-2' INTO table t1/*!*/;
+load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -133,7 +153,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values ("Alas")/*!*/;
+insert into t1 values ("Alas")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -160,7 +181,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values ("Alas")/*!*/;
+insert into t1 values ("Alas")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -173,9 +195,11 @@ DELIMITER /*!*/;
ROLLBACK/*!*/;
use test/*!*/;
SET TIMESTAMP=1108844556/*!*/;
-BEGIN/*!*/;
+BEGIN
+/*!*/;
SET TIMESTAMP=1108844555/*!*/;
-insert t1 values (1)/*!*/;
+insert t1 values (1)
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -185,9 +209,11 @@ ROLLBACK /* added by mysqlbinlog */;
DELIMITER /*!*/;
use test/*!*/;
SET TIMESTAMP=1108844556/*!*/;
-BEGIN/*!*/;
+BEGIN
+/*!*/;
SET TIMESTAMP=1108844555/*!*/;
-insert t1 values (1)/*!*/;
+insert t1 values (1)
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -245,7 +271,8 @@ SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.
CREATE DEFINER=`root`@`localhost` procedure p1()
begin
select 1;
-end/*!*/;
+end
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -287,27 +314,36 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-create table t1 (a varchar(64) character set utf8)/*!*/;
+create table t1 (a varchar(64) character set utf8)
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-6-0' INTO table t1/*!*/;
+load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.collation_database=7/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-7-0' INTO table t1/*!*/;
+load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-8-0' INTO table t1/*!*/;
+load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-9-0' INTO table t1/*!*/;
+load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.collation_database=7/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-a-0' INTO table t1/*!*/;
+load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-a-0' INTO table t1
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-b-0' INTO table t1/*!*/;
+load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-b-0' INTO table t1
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-c-0' INTO table t1 character set koi8r/*!*/;
+load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-c-0' INTO table t1 character set koi8r
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-drop table t1/*!*/;
+drop table t1
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
diff --git a/mysql-test/r/mysqlbinlog2.result b/mysql-test/r/mysqlbinlog2.result
index 03b0e16d32a..f4755338da3 100644
--- a/mysql-test/r/mysqlbinlog2.result
+++ b/mysql-test/r/mysqlbinlog2.result
@@ -25,22 +25,28 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-create table t1 (a int auto_increment not null primary key, b char(3))/*!*/;
+create table t1 (a int auto_increment not null primary key, b char(3))
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
SET INSERT_ID=3/*!*/;
SET TIMESTAMP=1579609944/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -58,19 +64,24 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
SET INSERT_ID=3/*!*/;
SET TIMESTAMP=1579609944/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -87,10 +98,12 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -107,16 +120,20 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-create table t1 (a int auto_increment not null primary key, b char(3))/*!*/;
+create table t1 (a int auto_increment not null primary key, b char(3))
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
SET INSERT_ID=3/*!*/;
SET TIMESTAMP=1579609944/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -133,7 +150,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
DELIMITER ;
# End of log file
@@ -152,13 +170,16 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -175,13 +196,16 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-create table t1 (a int auto_increment not null primary key, b char(3))/*!*/;
+create table t1 (a int auto_increment not null primary key, b char(3))
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -198,22 +222,28 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-create table t1 (a int auto_increment not null primary key, b char(3))/*!*/;
+create table t1 (a int auto_increment not null primary key, b char(3))
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
SET INSERT_ID=3/*!*/;
SET TIMESTAMP=1579609944/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
DELIMITER /*!*/;
SET INSERT_ID=6/*!*/;
@@ -223,7 +253,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "f")/*!*/;
+insert into t1 values(null, "f")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -241,19 +272,24 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
SET INSERT_ID=3/*!*/;
SET TIMESTAMP=1579609944/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
DELIMITER /*!*/;
SET INSERT_ID=6/*!*/;
@@ -263,7 +299,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "f")/*!*/;
+insert into t1 values(null, "f")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -280,10 +317,12 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
DELIMITER /*!*/;
SET INSERT_ID=6/*!*/;
@@ -293,7 +332,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "f")/*!*/;
+insert into t1 values(null, "f")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -310,22 +350,28 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-create table t1 (a int auto_increment not null primary key, b char(3))/*!*/;
+create table t1 (a int auto_increment not null primary key, b char(3))
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
SET INSERT_ID=3/*!*/;
SET TIMESTAMP=1579609944/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
DELIMITER /*!*/;
SET INSERT_ID=6/*!*/;
@@ -346,13 +392,16 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
DELIMITER /*!*/;
SET INSERT_ID=6/*!*/;
@@ -362,7 +411,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "f")/*!*/;
+insert into t1 values(null, "f")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -379,13 +429,16 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-create table t1 (a int auto_increment not null primary key, b char(3))/*!*/;
+create table t1 (a int auto_increment not null primary key, b char(3))
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -402,22 +455,28 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-create table t1 (a int auto_increment not null primary key, b char(3))/*!*/;
+create table t1 (a int auto_increment not null primary key, b char(3))
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
SET INSERT_ID=3/*!*/;
SET TIMESTAMP=1579609944/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -435,19 +494,24 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
SET INSERT_ID=3/*!*/;
SET TIMESTAMP=1579609944/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -464,10 +528,12 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -484,16 +550,20 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-create table t1 (a int auto_increment not null primary key, b char(3))/*!*/;
+create table t1 (a int auto_increment not null primary key, b char(3))
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
SET INSERT_ID=3/*!*/;
SET TIMESTAMP=1579609944/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -510,7 +580,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
DELIMITER ;
# End of log file
@@ -529,13 +600,16 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -552,13 +626,16 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-create table t1 (a int auto_increment not null primary key, b char(3))/*!*/;
+create table t1 (a int auto_increment not null primary key, b char(3))
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -575,22 +652,28 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-create table t1 (a int auto_increment not null primary key, b char(3))/*!*/;
+create table t1 (a int auto_increment not null primary key, b char(3))
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
SET INSERT_ID=3/*!*/;
SET TIMESTAMP=1579609944/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
DELIMITER /*!*/;
SET INSERT_ID=6/*!*/;
@@ -600,7 +683,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "f")/*!*/;
+insert into t1 values(null, "f")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -618,19 +702,24 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
SET INSERT_ID=3/*!*/;
SET TIMESTAMP=1579609944/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
DELIMITER /*!*/;
SET INSERT_ID=6/*!*/;
@@ -640,7 +729,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "f")/*!*/;
+insert into t1 values(null, "f")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -657,10 +747,12 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
DELIMITER /*!*/;
SET INSERT_ID=6/*!*/;
@@ -670,7 +762,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "f")/*!*/;
+insert into t1 values(null, "f")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -687,22 +780,28 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-create table t1 (a int auto_increment not null primary key, b char(3))/*!*/;
+create table t1 (a int auto_increment not null primary key, b char(3))
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
SET INSERT_ID=3/*!*/;
SET TIMESTAMP=1579609944/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
DELIMITER /*!*/;
SET INSERT_ID=6/*!*/;
@@ -723,13 +822,16 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
DELIMITER ;
DELIMITER /*!*/;
SET INSERT_ID=6/*!*/;
@@ -739,7 +841,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-insert into t1 values(null, "f")/*!*/;
+insert into t1 values(null, "f")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -756,13 +859,16 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-create table t1 (a int auto_increment not null primary key, b char(3))/*!*/;
+create table t1 (a int auto_increment not null primary key, b char(3))
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
@@ -779,25 +885,32 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-create table t1 (a int auto_increment not null primary key, b char(3))/*!*/;
+create table t1 (a int auto_increment not null primary key, b char(3))
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "a")/*!*/;
+insert into t1 values(null, "a")
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1579609942/*!*/;
-insert into t1 values(null, "b")/*!*/;
+insert into t1 values(null, "b")
+/*!*/;
SET INSERT_ID=3/*!*/;
SET TIMESTAMP=1579609944/*!*/;
-insert into t1 values(null, "c")/*!*/;
+insert into t1 values(null, "c")
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "d")/*!*/;
+insert into t1 values(null, "d")
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1579609946/*!*/;
-insert into t1 values(null, "e")/*!*/;
+insert into t1 values(null, "e")
+/*!*/;
SET INSERT_ID=6/*!*/;
SET TIMESTAMP=1579609943/*!*/;
-insert into t1 values(null, "f")/*!*/;
+insert into t1 values(null, "f")
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result
index f8a28009c42..8d7a2d41649 100644
--- a/mysql-test/r/mysqlcheck.result
+++ b/mysql-test/r/mysqlcheck.result
@@ -46,4 +46,15 @@ create table `t 1`(a int);
test.t 1 OK
test.t`1 OK
drop table `t``1`, `t 1`;
+create database d_bug25347;
+use d_bug25347;
+create table t_bug25347 (a int);
+create view v_bug25347 as select * from t_bug25347;
+flush tables;
+removing and creating
+d_bug25347.t_bug25347 OK
+drop view v_bug25347;
+drop table t_bug25347;
+drop database d_bug25347;
+use test;
End of 5.0 tests
diff --git a/mysql-test/r/mysqldump-no-binlog.result b/mysql-test/r/mysqldump-no-binlog.result
new file mode 100644
index 00000000000..78bc19b7cba
--- /dev/null
+++ b/mysql-test/r/mysqldump-no-binlog.result
@@ -0,0 +1 @@
+mysqldump: Error: Binlogging on server not active
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index d03e21b1bb0..a7df1a523cf 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -722,4 +722,7 @@ a int(11) YES NULL
b varchar(255) YES NULL
c datetime YES NULL
drop table t1;
+mysqltest: At line 1: change user failed: Unknown database 'inexistent'
+mysqltest: At line 1: change user failed: Access denied for user 'inexistent'@'localhost' (using password: NO)
+mysqltest: At line 1: change user failed: Access denied for user 'root'@'localhost' (using password: YES)
End of tests
diff --git a/mysql-test/r/ndb_alter_table2.result b/mysql-test/r/ndb_alter_table2.result
index 399578dc97b..886c300d53d 100644
--- a/mysql-test/r/ndb_alter_table2.result
+++ b/mysql-test/r/ndb_alter_table2.result
@@ -40,3 +40,22 @@ a b c
select * from t1;
a b c
drop table t1;
+DROP TABLE IF EXISTS truncate_test;
+CREATE TABLE truncate_test (
+i INT PRIMARY KEY,
+a INT,
+b VARCHAR(11),
+UNIQUE KEY (a)
+) ENGINE = NDB;
+INSERT INTO truncate_test VALUES (1, 1, 'test') ON DUPLICATE KEY UPDATE b = 'new';
+INSERT INTO truncate_test VALUES (1, 1, 'test') ON DUPLICATE KEY UPDATE b = 'new';
+TRUNCATE truncate_test;
+INSERT INTO truncate_test VALUES (1, 1, 'test') ON DUPLICATE KEY UPDATE b = 'new';
+SELECT * FROM truncate_test;
+i a b
+1 1 test
+INSERT INTO truncate_test VALUES (1, 1, 'test') ON DUPLICATE KEY UPDATE b = 'new';
+SELECT * FROM truncate_test;
+i a b
+1 1 new
+DROP TABLE truncate_test;
diff --git a/mysql-test/r/ndb_auto_increment.result b/mysql-test/r/ndb_auto_increment.result
index b7c9fa8e2b5..f8ef5af2770 100644
--- a/mysql-test/r/ndb_auto_increment.result
+++ b/mysql-test/r/ndb_auto_increment.result
@@ -421,10 +421,10 @@ select * from t1 order by a;
a
1
20
-21
33
34
35
+65
insert into t1 values (100);
insert into t1 values (NULL);
insert into t1 values (NULL);
@@ -432,11 +432,11 @@ select * from t1 order by a;
a
1
20
-21
-22
33
34
35
+65
+66
100
101
set auto_increment_offset = @old_auto_increment_offset;
diff --git a/mysql-test/r/ndb_bug31477.result b/mysql-test/r/ndb_bug31477.result
new file mode 100644
index 00000000000..002a928b485
--- /dev/null
+++ b/mysql-test/r/ndb_bug31477.result
@@ -0,0 +1,98 @@
+drop table if exists t1;
+create table t1(a int primary key, b int, c int, unique(b)) engine = ndb;
+insert into t1 values (2,2,2);
+insert into t1 values (3,3,3);
+insert into t1 values (4,4,4);
+begin;
+insert into t1 values (1,1,1);
+begin;
+update t1 set c = 2 where b = 1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+rollback;
+rollback;
+drop table t1;
+create table t1(a int primary key, b int, c int, key(b)) engine = ndb;
+insert into t1 values (2,2,2);
+insert into t1 values (3,3,3);
+insert into t1 values (4,4,4);
+begin;
+insert into t1 values (1,1,1);
+begin;
+update t1 set c = 2 where b = 1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+rollback;
+rollback;
+drop table t1;
+--con1
+create table t1(a int primary key, b int, c int, key(b)) engine = ndb;
+insert into t1 values (1,1,1);
+insert into t1 values (2,2,2);
+insert into t1 values (3,3,3);
+insert into t1 values (4,4,4);
+begin;
+update t1 set c = 10 where a = 1;
+update t1 set c = 20 where a = 1;
+update t1 set c = 30 where a = 1;
+--con1 c=30
+select * from t1 where b >= 1 order by b;
+a b c
+1 1 30
+2 2 2
+3 3 3
+4 4 4
+--con2 c=1
+select * from t1 where b >= 1 order by b;
+a b c
+1 1 1
+2 2 2
+3 3 3
+4 4 4
+--con1
+delete from t1 where a = 1;
+--con1 c=none
+select * from t1 where b >= 1 order by b;
+a b c
+2 2 2
+3 3 3
+4 4 4
+--con2 c=1
+select * from t1 where b >= 1 order by b;
+a b c
+1 1 1
+2 2 2
+3 3 3
+4 4 4
+--con1
+commit;
+--con1 c=none
+select * from t1 where b >= 1 order by b;
+a b c
+2 2 2
+3 3 3
+4 4 4
+--con2 c=none
+select * from t1 where b >= 1 order by b;
+a b c
+2 2 2
+3 3 3
+4 4 4
+--con1
+begin;
+insert into t1 values (1,1,1);
+update t1 set c = 10 where a = 1;
+update t1 set c = 20 where a = 1;
+update t1 set c = 30 where a = 1;
+--con1 c=30
+select * from t1 where b >= 1 order by b;
+a b c
+1 1 30
+2 2 2
+3 3 3
+4 4 4
+--con2 c=none
+select * from t1 where b >= 1 order by b;
+a b c
+2 2 2
+3 3 3
+4 4 4
+drop table t1;
diff --git a/mysql-test/r/ndb_condition_pushdown.result b/mysql-test/r/ndb_condition_pushdown.result
index d49c0cd983e..b211b9079d0 100644
--- a/mysql-test/r/ndb_condition_pushdown.result
+++ b/mysql-test/r/ndb_condition_pushdown.result
@@ -1904,6 +1904,12 @@ a b d
10 1 4369
20 2 8738
50 5 21845
+-- big filter just below limit
+a b d
+10 1 4369
+20 2 8738
+50 5 21845
+-- big filter just above limit
a b d
10 1 4369
20 2 8738
diff --git a/mysql-test/r/ndb_restore.result b/mysql-test/r/ndb_restore.result
index 9faac2df0a4..c48333f6ea8 100644
--- a/mysql-test/r/ndb_restore.result
+++ b/mysql-test/r/ndb_restore.result
@@ -266,21 +266,41 @@ a
2000
3000
10000
-show table status like 't1_c';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-X X X X X X X X X X 3001 X X X X X X X
-show table status like 't2_c';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-X X X X X X X X X X 501 X X X X X X X
-show table status like 't4_c';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-X X X X X X X X X X 290000001 X X X X X X X
-show table status like 't7_c';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-X X X X X X X X X X 29 X X X X X X X
-show table status like 't10_c';
-Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-X X X X X X X X X X 10001 X X X X X X X
+select max(capgoaledatta) from t1_c;
+max(capgoaledatta)
+3000
+select auto_increment from information_schema.tables
+where table_name = 't1_c';
+auto_increment
+3001
+select max(capgotod) from t2_c;
+max(capgotod)
+500
+select auto_increment from information_schema.tables
+where table_name = 't2_c';
+auto_increment
+501
+select max(capfa) from t4_c;
+max(capfa)
+290000000
+select auto_increment from information_schema.tables
+where table_name = 't4_c';
+auto_increment
+290000001
+select max(dardtestard) from t7_c;
+max(dardtestard)
+28
+select auto_increment from information_schema.tables
+where table_name = 't7_c';
+auto_increment
+29
+select max(a) from t10_c;
+max(a)
+10000
+select auto_increment from information_schema.tables
+where table_name = 't10_c';
+auto_increment
+10001
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9, t10;
drop table if exists t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c, t10_c;
520093696,<the_backup_id>
diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result
index 8a440284c53..58c587fe588 100644
--- a/mysql-test/r/null_key.result
+++ b/mysql-test/r/null_key.result
@@ -429,3 +429,21 @@ Handler_read_prev 0
Handler_read_rnd 0
Handler_read_rnd_next 5
DROP TABLE t1,t2,t3,t4;
+CREATE TABLE t1 (
+a int(11) default NULL,
+b int(11) default NULL,
+KEY a (a,b)
+);
+INSERT INTO t1 VALUES (0,10),(0,11),(0,12);
+CREATE TABLE t2 (
+a int(11) default NULL,
+b int(11) default NULL,
+KEY a (a)
+);
+INSERT INTO t2 VALUES (3,NULL),(3,11),(3,12);
+SELECT * FROM t2 inner join t1 WHERE ( t1.a = 0 OR t1.a IS NULL) AND t2.a = 3 AND t2.b = t1.b;
+a b a b
+3 11 0 11
+3 12 0 12
+drop table t1, t2;
+End of 5.0 tests
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index eedc2fa476b..9f6a1b3932c 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -1064,3 +1064,15 @@ a b
10 00:00:10
0 00:00:00
DROP TABLE t1;
+#
+# Bug#31590: Wrong error message on sort buffer being too small.
+#
+create table t1(a int, b tinytext);
+insert into t1 values (1,2),(3,2);
+set session sort_buffer_size= 30000;
+Warnings:
+Warning 1292 Truncated incorrect sort_buffer_size value: '30000'
+set session max_sort_length= 2180;
+select * from t1 order by b;
+ERROR HY001: Out of sort memory; increase server sort buffer size
+drop table t1;
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index f547654bed1..9aef58d5702 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -1693,4 +1693,202 @@ t1 CREATE TABLE `t1` (
`?` decimal(2,1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
+drop table if exists t1;
+create table t1 (a bigint unsigned, b bigint(20) unsigned);
+prepare stmt from "insert into t1 values (?,?)";
+set @a= 9999999999999999;
+set @b= 14632475938453979136;
+insert into t1 values (@a, @b);
+select * from t1 where a = @a and b = @b;
+a b
+9999999999999999 14632475938453979136
+execute stmt using @a, @b;
+select * from t1 where a = @a and b = @b;
+a b
+9999999999999999 14632475938453979136
+9999999999999999 14632475938453979136
+deallocate prepare stmt;
+drop table t1;
+drop view if exists v1;
+drop table if exists t1;
+create table t1 (a int, b int);
+insert into t1 values (1,1), (2,2), (3,3);
+insert into t1 values (3,1), (1,2), (2,3);
+prepare stmt from "create view v1 as select * from t1";
+execute stmt;
+drop table t1;
+create table t1 (a int, b int);
+drop view v1;
+execute stmt;
+show create view v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b` from `t1`
+drop view v1;
+prepare stmt from "create view v1 (c,d) as select a,b from t1";
+execute stmt;
+show create view v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `c`,`t1`.`b` AS `d` from `t1`
+select * from v1;
+c d
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `c`,`t1`.`b` AS `d` from `t1`
+select * from v1;
+c d
+drop view v1;
+prepare stmt from "create view v1 (c) as select b+1 from t1";
+execute stmt;
+show create view v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select (`t1`.`b` + 1) AS `c` from `t1`
+select * from v1;
+c
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select (`t1`.`b` + 1) AS `c` from `t1`
+select * from v1;
+c
+drop view v1;
+prepare stmt from "create view v1 (c,d,e,f) as select a,b,a in (select a+2 from t1), a = all (select a from t1) from t1";
+execute stmt;
+show create view v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `c`,`t1`.`b` AS `d`,`t1`.`a` in (select (`t1`.`a` + 2) AS `a+2` from `t1`) AS `e`,`t1`.`a` = all (select `t1`.`a` AS `a` from `t1`) AS `f` from `t1`
+select * from v1;
+c d e f
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `c`,`t1`.`b` AS `d`,`t1`.`a` in (select (`t1`.`a` + 2) AS `a+2` from `t1`) AS `e`,`t1`.`a` = all (select `t1`.`a` AS `a` from `t1`) AS `f` from `t1`
+select * from v1;
+c d e f
+drop view v1;
+prepare stmt from "create or replace view v1 as select 1";
+execute stmt;
+show create view v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1`
+select * from v1;
+1
+1
+execute stmt;
+show create view v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1`
+deallocate prepare stmt;
+show create view v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1`
+select * from v1;
+1
+1
+drop view v1;
+prepare stmt from "create view v1 as select 1, 1";
+execute stmt;
+show create view v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1`,1 AS `My_exp_1`
+select * from v1;
+1 My_exp_1
+1 1
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1`,1 AS `My_exp_1`
+select * from v1;
+1 My_exp_1
+1 1
+drop view v1;
+prepare stmt from "create view v1 (x) as select a from t1 where a > 1";
+execute stmt;
+show create view v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `x` from `t1` where (`t1`.`a` > 1)
+select * from v1;
+x
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `x` from `t1` where (`t1`.`a` > 1)
+select * from v1;
+x
+drop view v1;
+prepare stmt from "create view v1 as select * from `t1` `b`";
+execute stmt;
+show create view v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `b`.`a` AS `a`,`b`.`b` AS `b` from `t1` `b`
+select * from v1;
+a b
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `b`.`a` AS `a`,`b`.`b` AS `b` from `t1` `b`
+select * from v1;
+a b
+drop view v1;
+prepare stmt from "create view v1 (a,b,c) as select * from t1";
+execute stmt;
+ERROR HY000: View's SELECT and view's field list have different column counts
+execute stmt;
+ERROR HY000: View's SELECT and view's field list have different column counts
+deallocate prepare stmt;
+drop table t1;
+create temporary table t1 (a int, b int);
+prepare stmt from "create view v1 as select * from t1";
+execute stmt;
+ERROR HY000: View's SELECT refers to a temporary table 't1'
+execute stmt;
+ERROR HY000: View's SELECT refers to a temporary table 't1'
+deallocate prepare stmt;
+drop table t1;
+prepare stmt from "create view v1 as select * from t1";
+ERROR 42S02: Table 'test.t1' doesn't exist
+prepare stmt from "create view v1 as select * from `t1` `b`";
+ERROR 42S02: Table 'test.t1' doesn't exist
+prepare stmt from "select ?";
+set @arg= 123456789.987654321;
+select @arg;
+@arg
+123456789.987654321
+execute stmt using @arg;
+?
+123456789.987654321
+set @arg= "string";
+select @arg;
+@arg
+string
+execute stmt using @arg;
+?
+string
+set @arg= 123456;
+select @arg;
+@arg
+123456
+execute stmt using @arg;
+?
+123456
+set @arg= cast(-12345.54321 as decimal(20, 10));
+select @arg;
+@arg
+-12345.5432100000
+execute stmt using @arg;
+?
+-12345.5432100000
+deallocate prepare stmt;
End of 5.0 tests.
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index f666030465e..0c4c332395a 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -1153,6 +1153,19 @@ explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= '
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range dateval dateval 4 NULL 2 Using where
drop table t1;
+CREATE TABLE t1 (
+a varchar(32), index (a)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_bin;
+INSERT INTO t1 VALUES
+('B'), ('A'), ('A'), ('C'), ('B'), ('A'), ('A');
+SELECT a FROM t1 WHERE a='b' OR a='B';
+a
+B
+B
+EXPLAIN SELECT a FROM t1 WHERE a='b' OR a='B';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 35 NULL 3 Using where; Using index
+DROP TABLE t1;
CREATE TABLE t1 (f1 TINYINT(11) UNSIGNED NOT NULL, PRIMARY KEY (f1));
INSERT INTO t1 VALUES (127),(254),(0),(1),(255);
SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 < 256;
diff --git a/mysql-test/r/row.result b/mysql-test/r/row.result
index 702e66fea62..98c79d4bc00 100644
--- a/mysql-test/r/row.result
+++ b/mysql-test/r/row.result
@@ -434,3 +434,12 @@ SELECT @x;
@x
99
DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1,1);
+SELECT ROW(a, 1) IN (SELECT SUM(b), 1) FROM t1 GROUP BY a;
+ROW(a, 1) IN (SELECT SUM(b), 1)
+1
+SELECT ROW(a, 1) IN (SELECT SUM(b), 3) FROM t1 GROUP BY a;
+ROW(a, 1) IN (SELECT SUM(b), 3)
+0
+DROP TABLE t1;
diff --git a/mysql-test/r/rpl_charset.result b/mysql-test/r/rpl_charset.result
index 4b6d9f44a2b..c77818d34ee 100644
--- a/mysql-test/r/rpl_charset.result
+++ b/mysql-test/r/rpl_charset.result
@@ -183,78 +183,101 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-drop database if exists mysqltest2/*!*/;
+drop database if exists mysqltest2
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-drop database if exists mysqltest3/*!*/;
+drop database if exists mysqltest3
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-create database mysqltest2 character set latin2/*!*/;
+create database mysqltest2 character set latin2
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=30/*!*/;
-create database mysqltest3/*!*/;
+create database mysqltest3
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=64/*!*/;
-drop database mysqltest3/*!*/;
+drop database mysqltest3
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-create database mysqltest3/*!*/;
+create database mysqltest3
+/*!*/;
use mysqltest2/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-create table t1 (a int auto_increment primary key, b varchar(100))/*!*/;
+create table t1 (a int auto_increment primary key, b varchar(100))
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1000000000/*!*/;
/*!\C cp850 *//*!*/;
SET @@session.character_set_client=4,@@session.collation_connection=27,@@session.collation_server=64/*!*/;
-insert into t1 (b) values(@@character_set_server)/*!*/;
+insert into t1 (b) values(@@character_set_server)
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-insert into t1 (b) values(@@collation_server)/*!*/;
+insert into t1 (b) values(@@collation_server)
+/*!*/;
SET INSERT_ID=3/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-insert into t1 (b) values(@@character_set_client)/*!*/;
+insert into t1 (b) values(@@character_set_client)
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-insert into t1 (b) values(@@character_set_connection)/*!*/;
+insert into t1 (b) values(@@character_set_connection)
+/*!*/;
SET INSERT_ID=5/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-insert into t1 (b) values(@@collation_connection)/*!*/;
+insert into t1 (b) values(@@collation_connection)
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=5,@@session.collation_server=64/*!*/;
-truncate table t1/*!*/;
+truncate table t1
+/*!*/;
SET INSERT_ID=1/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-insert into t1 (b) values(@@collation_connection)/*!*/;
+insert into t1 (b) values(@@collation_connection)
+/*!*/;
SET INSERT_ID=2/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-insert into t1 (b) values(LEAST("Müller","Muffler"))/*!*/;
+insert into t1 (b) values(LEAST("Müller","Muffler"))
+/*!*/;
SET INSERT_ID=3/*!*/;
SET TIMESTAMP=1000000000/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=31,@@session.collation_server=64/*!*/;
-insert into t1 (b) values(@@collation_connection)/*!*/;
+insert into t1 (b) values(@@collation_connection)
+/*!*/;
SET INSERT_ID=4/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-insert into t1 (b) values(LEAST("Müller","Muffler"))/*!*/;
+insert into t1 (b) values(LEAST("Müller","Muffler"))
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-truncate table t1/*!*/;
+truncate table t1
+/*!*/;
SET INSERT_ID=1/*!*/;
SET @`a`:=_cp850 0x4DFC6C6C6572 COLLATE `cp850_general_ci`/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-insert into t1 (b) values(collation(@a))/*!*/;
+insert into t1 (b) values(collation(@a))
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-drop database mysqltest2/*!*/;
+drop database mysqltest2
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-drop database mysqltest3/*!*/;
+drop database mysqltest3
+/*!*/;
use test/*!*/;
SET TIMESTAMP=1000000000/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=30/*!*/;
-CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))/*!*/;
+CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))
+/*!*/;
SET TIMESTAMP=1000000000/*!*/;
/*!\C koi8r *//*!*/;
SET @@session.character_set_client=7,@@session.collation_connection=51,@@session.collation_server=30/*!*/;
-INSERT INTO t1 (c1, c2) VALUES ('îÕ, ÚÁ ÒÙÂÁÌËÕ','îÕ, ÚÁ ÒÙÂÁÌËÕ')/*!*/;
+INSERT INTO t1 (c1, c2) VALUES ('îÕ, ÚÁ ÒÙÂÁÌËÕ','îÕ, ÚÁ ÒÙÂÁÌËÕ')
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
diff --git a/mysql-test/r/rpl_drop_view.result b/mysql-test/r/rpl_drop_view.result
new file mode 100644
index 00000000000..ef625464881
--- /dev/null
+++ b/mysql-test/r/rpl_drop_view.result
@@ -0,0 +1,27 @@
+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;
+drop table if exists t1, t2;
+drop view if exists v1, v2, v3, not_exist_view;
+create table t1 (a int);
+create table t2 (b int);
+create table t3 (c int);
+create view v1 as select * from t1;
+create view v2 as select * from t2;
+create view v3 as select * from t3;
+drop view not_exist_view;
+ERROR 42S02: Unknown table 'not_exist_view'
+drop view v1, not_exist_view;
+ERROR 42S02: Unknown table 'not_exist_view'
+select * from v1;
+ERROR 42S02: Table 'test.v1' doesn't exist
+drop view v2, v3;
+select * from v1;
+ERROR 42S02: Table 'test.v1' doesn't exist
+select * from v2;
+ERROR 42S02: Table 'test.v2' doesn't exist
+select * from v3;
+ERROR 42S02: Table 'test.v3' doesn't exist
diff --git a/mysql-test/r/rpl_grant.result b/mysql-test/r/rpl_grant.result
index 4d7ad298ce4..17bceb339c8 100644
--- a/mysql-test/r/rpl_grant.result
+++ b/mysql-test/r/rpl_grant.result
@@ -48,7 +48,7 @@ Master_User root
Master_Port MASTER_PORT
Connect_Retry 1
Master_Log_File master-bin.000001
-Read_Master_Log_Pos 609
+Read_Master_Log_Pos 515
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
@@ -63,7 +63,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0
Last_Error
Skip_Counter 0
-Exec_Master_Log_Pos 609
+Exec_Master_Log_Pos 515
Relay_Log_Space #
Until_Condition None
Until_Log_File
diff --git a/mysql-test/r/rpl_loaddata_map.result b/mysql-test/r/rpl_loaddata_map.result
new file mode 100644
index 00000000000..c2159adef6a
--- /dev/null
+++ b/mysql-test/r/rpl_loaddata_map.result
@@ -0,0 +1,26 @@
+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 t2 (id int not null primary key auto_increment);
+select @@session.read_buffer_size - @@session.max_allowed_packet > 0 ;
+@@session.read_buffer_size - @@session.max_allowed_packet > 0
+1
+load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2;
+select count(*) from t2 /* 5 000 */;
+count(*)
+5000
+show binlog events in 'master-bin.000002' from 98;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000002 98 Query 1 # use `test`; create table t2 (id int not null primary key auto_increment)
+master-bin.000002 221 Begin_load_query 1 # ;file_id=#;block_len=8192
+master-bin.000002 8436 Append_block 1 # ;file_id=#;block_len=8192
+master-bin.000002 16651 Append_block 1 # ;file_id=#;block_len=7509
+master-bin.000002 24183 Execute_load_query 1 # use `test`; load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2 ;file_id=#
+select count(*) from t2 /* 5 000 */;
+count(*)
+5000
+drop table t1, t2;
+end of the tests
diff --git a/mysql-test/r/rpl_server_id.result b/mysql-test/r/rpl_server_id.result
new file mode 100644
index 00000000000..1e74394c122
--- /dev/null
+++ b/mysql-test/r/rpl_server_id.result
@@ -0,0 +1,34 @@
+set global server_id=1;
+reset master;
+drop table if exists t1,t2,t3;
+create table t1 (a int);
+select @@server_id;
+@@server_id
+1
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; drop table if exists t1,t2,t3
+master-bin.000001 # Query 1 # use `test`; create table t1 (a int)
+set global server_id=2;
+create table t2 (b int);
+select @@server_id;
+@@server_id
+2
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; drop table if exists t1,t2,t3
+master-bin.000001 # Query 1 # use `test`; create table t1 (a int)
+master-bin.000001 # Query 2 # use `test`; create table t2 (b int)
+set global server_id=3;
+create table t3 (c int);
+select @@server_id;
+@@server_id
+3
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; drop table if exists t1,t2,t3
+master-bin.000001 # Query 1 # use `test`; create table t1 (a int)
+master-bin.000001 # Query 2 # use `test`; create table t2 (b int)
+master-bin.000001 # Query 3 # use `test`; create table t3 (c int)
+set global server_id=1;
+drop table t1,t2,t3;
diff --git a/mysql-test/r/rpl_slave_skip.result b/mysql-test/r/rpl_slave_skip.result
index a59ac3eb884..0e06e0951b3 100644
--- a/mysql-test/r/rpl_slave_skip.result
+++ b/mysql-test/r/rpl_slave_skip.result
@@ -5,8 +5,10 @@ reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
**** On Master ****
-CREATE TABLE t1 (a INT, b SET('master','slave')) ENGINE=INNODB;
-CREATE TABLE t2 (a INT, b SET('master','slave')) ENGINE=MYISAM;
+CREATE TABLE t1 (a INT, b SET('master','slave')) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT, b SET('master','slave')) ENGINE=MyISAM;
+CREATE TABLE t3 (a CHAR(20), b SET('master','slave')) ENGINE=InnoDB;
+CREATE TABLE t4 (a CHAR(20), b SET('master','slave')) ENGINE=MyISAM;
==== Skipping normal transactions ====
**** On Slave ****
STOP SLAVE;
@@ -139,6 +141,102 @@ a b
SELECT * FROM t2 ORDER BY a;
a b
5 master,slave
+==== Skipping first event of a LOAD DATA for a transactional table ====
+**** On Slave ****
+STOP SLAVE;
+**** On Master ****
+SET AUTOCOMMIT=1;
+LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t3(a) SET b = 'master';
+INSERT INTO t3 VALUES ('Go Rin No Sho', 'master,slave');
+SELECT COUNT(*) FROM t3;
+COUNT(*)
+71
+**** On Slave ****
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+-- Should only contain records marked 'master,slave'
+SELECT * FROM t3 ORDER BY a;
+a b
+Go Rin No Sho master,slave
+**** On Master ****
+DELETE FROM t3;
+==== Skipping first event of a LOAD DATA for a non-transactional table ====
+**** On Slave ****
+STOP SLAVE;
+**** On Master ****
+SET AUTOCOMMIT=1;
+LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t4(a) SET b = 'master';
+INSERT INTO t4 VALUES ('Go Rin No Sho', 'master,slave');
+SELECT COUNT(*) FROM t4;
+COUNT(*)
+71
+**** On Slave ****
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+-- Should only contain records marked 'master,slave'
+SELECT * FROM t4 ORDER BY a;
+a b
+Go Rin No Sho master,slave
+**** On Master ****
+DELETE FROM t4;
+==== Try with a big file so that we get an append_block event as well
+**** On Slave ****
+STOP SLAVE;
+**** On Master ****
+SET AUTOCOMMIT=1;
+SET SQL_LOG_BIN=0;
+LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t4(a) SET b = 'master';
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+SELECT a FROM t4 INTO OUTFILE 'rpl_slave_skip_words.dat';
+SET SQL_LOG_BIN=1;
+LOAD DATA INFILE 'rpl_slave_skip_words.dat' INTO TABLE t4(a) SET b = 'master';
+INSERT INTO t4 VALUES ('Go Rin No Sho', 'master,slave');
+SELECT COUNT(*) FROM t4;
+COUNT(*)
+286721
+**** On Slave ****
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+-- Should only contain records marked 'master,slave'
+SELECT * FROM t4 ORDER BY a;
+a b
+Go Rin No Sho master,slave
+**** On Master ****
+DELETE FROM t4;
+**** On Master ****
+CREATE TABLE t5 (a int, b int, c SET('master','slave'), PRIMARY KEY (a,b)) ENGINE=MyISAM;
+LOAD DATA INFILE '../std_data_ln/loaddata5.dat' INTO TABLE t5 FIELDS TERMINATED BY '' ENCLOSED BY '' (a,b) SET c='master,slave';
+**** On Slave ****
+STOP SLAVE;
+**** On Master ****
+LOAD DATA INFILE '../std_data_ln/loaddata5.dat' INTO TABLE t5 FIELDS TERMINATED BY '' ENCLOSED BY '' (a,b) SET c='';
+ERROR 23000: Duplicate entry '1-2' for key 1
+INSERT INTO t5 VALUES (42, 42, 'master,slave');
+SELECT * FROM t5;
+a b c
+1 2 master,slave
+3 4 master,slave
+5 6 master,slave
+42 42 master,slave
+**** On Slave ****
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+SELECT * FROM t5;
+a b c
+1 2 master,slave
+3 4 master,slave
+5 6 master,slave
+42 42 master,slave
==== Cleanup ====
**** On Master ****
-DROP TABLE t1, t2;
+DROP TABLE t1, t2, t3, t4, t5;
diff --git a/mysql-test/r/rpl_timezone.result b/mysql-test/r/rpl_timezone.result
index 7a18a26afd3..7a5d09ea6a7 100644
--- a/mysql-test/r/rpl_timezone.result
+++ b/mysql-test/r/rpl_timezone.result
@@ -52,20 +52,26 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-create table t1 (t timestamp)/*!*/;
+create table t1 (t timestamp)
+/*!*/;
SET TIMESTAMP=100000000/*!*/;
-create table t2 (t char(32))/*!*/;
+create table t2 (t char(32))
+/*!*/;
SET TIMESTAMP=100000000/*!*/;
SET @@session.time_zone='Europe/Moscow'/*!*/;
-insert into t1 values ('20050101000000'), ('20050611093902')/*!*/;
+insert into t1 values ('20050101000000'), ('20050611093902')
+/*!*/;
SET TIMESTAMP=100000000/*!*/;
SET @@session.time_zone='UTC'/*!*/;
-insert into t1 values ('20040101000000'), ('20040611093902')/*!*/;
+insert into t1 values ('20040101000000'), ('20040611093902')
+/*!*/;
SET TIMESTAMP=100000000/*!*/;
-delete from t1/*!*/;
+delete from t1
+/*!*/;
SET TIMESTAMP=100000000/*!*/;
SET @@session.time_zone='Europe/Moscow'/*!*/;
-insert into t1 values ('20040101000000'), ('20040611093902')/*!*/;
+insert into t1 values ('20040101000000'), ('20040611093902')
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
diff --git a/mysql-test/r/rpl_transaction.result b/mysql-test/r/rpl_transaction.result
new file mode 100644
index 00000000000..9ea0c8f7afd
--- /dev/null
+++ b/mysql-test/r/rpl_transaction.result
@@ -0,0 +1,95 @@
+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 tmyisam (a int) ENGINE = MYISAM;
+CREATE TABLE tinnodb (a int) ENGINE = INNODB;
+SHOW CREATE TABLE tmyisam;
+Table Create Table
+tmyisam CREATE TABLE `tmyisam` (
+ `a` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SHOW CREATE TABLE tinnodb;
+Table Create Table
+tinnodb CREATE TABLE `tinnodb` (
+ `a` int(11) default NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+==== Test 1: Non-XA Engines ====
+--- on master ---
+SET AUTOCOMMIT = 1;
+INSERT INTO tmyisam VALUES (1);
+BEGIN;
+INSERT INTO tmyisam VALUES (2);
+INSERT INTO tmyisam VALUES (3);
+COMMIT;
+BEGIN;
+INSERT INTO tmyisam VALUES (5);
+INSERT INTO tmyisam VALUES (6);
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+SELECT * FROM tmyisam ORDER BY a;
+a
+1
+2
+3
+5
+6
+--- on slave ---
+SELECT * FROM tmyisam ORDER BY a;
+a
+1
+2
+3
+5
+6
+==== Test 2: Master crash before writing XID event on XA engine ====
+--- on master ---
+INSERT INTO tinnodb VALUES (1);
+SELECT * FROM tinnodb ORDER BY a;
+a
+1
+--- on slave ---
+STOP SLAVE;
+SHOW SLAVE STATUS;
+Slave_IO_State
+Master_Host 127.0.0.1
+Master_User root
+Master_Port #
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos #
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running No
+Slave_SQL_Running No
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table #
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos #
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
+SELECT * FROM tinnodb ORDER BY a;
+a
+DROP TABLE tmyisam;
+DROP TABLE tinnodb;
+DROP TABLE tmyisam;
+DROP TABLE tinnodb;
diff --git a/mysql-test/r/rpl_user.result b/mysql-test/r/rpl_user.result
new file mode 100644
index 00000000000..25e0f310f55
--- /dev/null
+++ b/mysql-test/r/rpl_user.result
@@ -0,0 +1,45 @@
+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;
+set sql_log_bin=0;
+delete from mysql.user where Host='fakehost';
+set sql_log_bin=1;
+set sql_log_bin=0;
+delete from mysql.user where Host='fakehost';
+set sql_log_bin=1;
+create user 'foo'@'fakehost';
+create user 'foo'@'fakehost', 'bar'@'fakehost';
+ERROR HY000: Operation CREATE USER failed for 'foo'@'fakehost'
+create user 'foo'@'fakehost', 'bar'@'fakehost';
+ERROR HY000: Operation CREATE USER failed for 'foo'@'fakehost','bar'@'fakehost'
+select Host,User from mysql.user where Host='fakehost';
+Host User
+fakehost bar
+fakehost foo
+rename user 'foo'@'fakehost' to 'foofoo'@'fakehost';
+rename user 'not_exist_user1'@'fakehost' to 'foobar'@'fakehost', 'bar'@'fakehost' to 'barbar'@'fakehost';
+ERROR HY000: Operation RENAME USER failed for 'not_exist_user1'@'fakehost'
+rename user 'not_exist_user1'@'fakehost' to 'foobar'@'fakehost', 'not_exist_user2'@'fakehost' to 'barfoo'@'fakehost';
+ERROR HY000: Operation RENAME USER failed for 'not_exist_user1'@'fakehost','not_exist_user2'@'fakehost'
+select Host,User from mysql.user where Host='fakehost';
+Host User
+fakehost barbar
+fakehost foofoo
+drop user 'foofoo'@'fakehost';
+drop user 'not_exist_user1'@'fakehost', 'barbar'@'fakehost';
+ERROR HY000: Operation DROP USER failed for 'not_exist_user1'@'fakehost'
+drop user 'not_exist_user1'@'fakehost', 'not_exist_user2'@'fakehost';
+ERROR HY000: Operation DROP USER failed for 'not_exist_user1'@'fakehost','not_exist_user2'@'fakehost'
+select Host,User from mysql.user where Host='fakehost';
+Host User
+show binlog events from 98;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 98 Query 1 # use `test`; create user 'foo'@'fakehost'
+master-bin.000001 189 Query 1 # use `test`; create user 'foo'@'fakehost', 'bar'@'fakehost'
+master-bin.000001 298 Query 1 # use `test`; rename user 'foo'@'fakehost' to 'foofoo'@'fakehost'
+master-bin.000001 412 Query 1 # use `test`; rename user 'not_exist_user1'@'fakehost' to 'foobar'@'fakehost', 'bar'@'fakehost' to 'barbar'@'fakehost'
+master-bin.000001 579 Query 1 # use `test`; drop user 'foofoo'@'fakehost'
+master-bin.000001 671 Query 1 # use `test`; drop user 'not_exist_user1'@'fakehost', 'barbar'@'fakehost'
diff --git a/mysql-test/r/rpl_user_variables.result b/mysql-test/r/rpl_user_variables.result
index 26ac2b26aaa..b8032a9c362 100644
--- a/mysql-test/r/rpl_user_variables.result
+++ b/mysql-test/r/rpl_user_variables.result
@@ -290,6 +290,22 @@ select * from t1;
a b
2 1
drop table t1;
+create table t1(a int);
+insert into t1 values (1),(2);
+prepare s1 from 'insert into t1 select a from t1 limit ?';
+set @x='1.1';
+execute s1 using @x;
+select * from t1;
+a
+1
+2
+1
+select * from t1;
+a
+1
+2
+1
+drop table t1;
End of 5.0 tests.
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 3ca84bcf34b..c2cd2129a32 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -4328,4 +4328,31 @@ SELECT * FROM t1 WHERE c1 > NULL + 1;
c1
DROP TABLE t1;
+CREATE TABLE t1 (a VARCHAR(10) NOT NULL PRIMARY KEY);
+INSERT INTO t1 (a) VALUES ('foo0'), ('bar0'), ('baz0');
+SELECT * FROM t1 WHERE a IN (CONCAT('foo', 0), 'bar');
+a
+foo0
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT, c INT, KEY(a));
+INSERT INTO t1 VALUES (1, 1), (2, 2);
+INSERT INTO t2 VALUES (1, 1), (1, 2), (1, 3), (1, 4), (1, 5),
+(2, 1), (2, 2), (2, 3), (2, 4), (2, 5),
+(3, 1), (3, 2), (3, 3), (3, 4), (3, 5),
+(4, 1), (4, 2), (4, 3), (4, 4), (4, 5);
+FLUSH STATUS;
+SELECT DISTINCT b FROM t1 LEFT JOIN t2 USING(a) WHERE c <= 3;
+b
+1
+2
+SHOW STATUS LIKE 'Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 2
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 6
+DROP TABLE t1, t2;
End of 5.0 tests
diff --git a/mysql-test/r/sp-code.result b/mysql-test/r/sp-code.result
index 219f3c9b37a..855cabc25d8 100644
--- a/mysql-test/r/sp-code.result
+++ b/mysql-test/r/sp-code.result
@@ -733,4 +733,113 @@ optimizer: keep hreturn
drop table t1;
drop procedure proc_26977_broken;
drop procedure proc_26977_works;
+drop procedure if exists proc_33618_h;
+drop procedure if exists proc_33618_c;
+create procedure proc_33618_h(num int)
+begin
+declare count1 int default '0';
+declare vb varchar(30);
+declare last_row int;
+while(num>=1) do
+set num=num-1;
+begin
+declare cur1 cursor for select `a` from t_33618;
+declare continue handler for not found set last_row = 1;
+set last_row:=0;
+open cur1;
+rep1:
+repeat
+begin
+declare exit handler for 1062 begin end;
+fetch cur1 into vb;
+if (last_row = 1) then
+## should generate a hpop instruction here
+leave rep1;
+end if;
+end;
+until last_row=1
+end repeat;
+close cur1;
+end;
+end while;
+end//
+create procedure proc_33618_c(num int)
+begin
+declare count1 int default '0';
+declare vb varchar(30);
+declare last_row int;
+while(num>=1) do
+set num=num-1;
+begin
+declare cur1 cursor for select `a` from t_33618;
+declare continue handler for not found set last_row = 1;
+set last_row:=0;
+open cur1;
+rep1:
+repeat
+begin
+declare cur2 cursor for select `b` from t_33618;
+fetch cur1 into vb;
+if (last_row = 1) then
+## should generate a cpop instruction here
+leave rep1;
+end if;
+end;
+until last_row=1
+end repeat;
+close cur1;
+end;
+end while;
+end//
+show procedure code proc_33618_h;
+Pos Instruction
+0 set count1@1 _latin1'0'
+1 set vb@2 NULL
+2 set last_row@3 NULL
+3 jump_if_not 24(24) (num@0 >= 1)
+4 set num@0 (num@0 - 1)
+5 cpush cur1@0
+6 hpush_jump 9 4 CONTINUE
+7 set last_row@3 1
+8 hreturn 4
+9 set last_row@3 0
+10 copen cur1@0
+11 hpush_jump 13 4 EXIT
+12 hreturn 0 17
+13 cfetch cur1@0 vb@2
+14 jump_if_not 17(17) (last_row@3 = 1)
+15 hpop 1
+16 jump 19
+17 hpop 1
+18 jump_if_not 11(19) (last_row@3 = 1)
+19 cclose cur1@0
+20 hpop 1
+21 cpop 1
+22 jump 3
+show procedure code proc_33618_c;
+Pos Instruction
+0 set count1@1 _latin1'0'
+1 set vb@2 NULL
+2 set last_row@3 NULL
+3 jump_if_not 23(23) (num@0 >= 1)
+4 set num@0 (num@0 - 1)
+5 cpush cur1@0
+6 hpush_jump 9 4 CONTINUE
+7 set last_row@3 1
+8 hreturn 4
+9 set last_row@3 0
+10 copen cur1@0
+11 cpush cur2@1
+12 cfetch cur1@0 vb@2
+13 jump_if_not 16(16) (last_row@3 = 1)
+14 cpop 1
+15 jump 18
+16 cpop 1
+17 jump_if_not 11(18) (last_row@3 = 1)
+18 cclose cur1@0
+19 hpop 1
+20 cpop 1
+21 jump 3
+drop procedure proc_33618_h;
+drop procedure proc_33618_c;
End of 5.0 tests.
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index b4bcfbdc7f7..0fc0adc89ad 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -1465,3 +1465,51 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
SELECT ..inexistent();
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 '.inexistent()' at line 1
USE test;
+drop procedure if exists proc_33983_a;
+drop procedure if exists proc_33983_b;
+drop procedure if exists proc_33983_c;
+drop procedure if exists proc_33983_d;
+create procedure proc_33983_a()
+begin
+label1:
+begin
+label2:
+begin
+select 1;
+end label1;
+end;
+end|
+ERROR 42000: End-label label1 without match
+create procedure proc_33983_b()
+begin
+label1:
+repeat
+label2:
+repeat
+select 1;
+until FALSE end repeat label1;
+until FALSE end repeat;
+end|
+ERROR 42000: End-label label1 without match
+create procedure proc_33983_c()
+begin
+label1:
+while TRUE do
+label2:
+while TRUE do
+select 1;
+end while label1;
+end while;
+end|
+ERROR 42000: End-label label1 without match
+create procedure proc_33983_d()
+begin
+label1:
+loop
+label2:
+loop
+select 1;
+end loop label1;
+end loop;
+end|
+ERROR 42000: End-label label1 without match
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 061bbafd9a1..562102f0ea7 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -6578,6 +6578,74 @@ DROP PROCEDURE db28318_a.t1;
DROP PROCEDURE db28318_b.t2;
DROP DATABASE db28318_a;
DROP DATABASE db28318_b;
+USE test;
+DROP TABLE IF EXISTS t1;
+DROP PROCEDURE IF EXISTS bug29770;
+CREATE TABLE t1(a int);
+CREATE PROCEDURE bug29770()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '42S22' SET @state:= 'run';
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @exception:= 'run';
+SELECT x FROM t1;
+END|
+CALL bug29770();
+SELECT @state, @exception;
+@state @exception
+run NULL
+DROP TABLE t1;
+DROP PROCEDURE bug29770;
+use test;
+drop table if exists t_33618;
+drop procedure if exists proc_33618;
+create table t_33618 (`a` int, unique(`a`), `b` varchar(30)) engine=myisam;
+insert into t_33618 (`a`,`b`) values (1,'1'),(2,'2');
+create procedure proc_33618(num int)
+begin
+declare count1 int default '0';
+declare vb varchar(30);
+declare last_row int;
+while(num>=1) do
+set num=num-1;
+begin
+declare cur1 cursor for select `a` from t_33618;
+declare continue handler for not found set last_row = 1;
+set last_row:=0;
+open cur1;
+rep1:
+repeat
+begin
+declare exit handler for 1062 begin end;
+fetch cur1 into vb;
+if (last_row = 1) then
+leave rep1;
+end if;
+end;
+until last_row=1
+end repeat;
+close cur1;
+end;
+end while;
+end//
+call proc_33618(20);
+drop table t_33618;
+drop procedure proc_33618;
+#
+# Bug#30787: Stored function ignores user defined alias.
+#
+use test;
+drop function if exists func30787;
+create table t1(f1 int);
+insert into t1 values(1),(2);
+create function func30787(p1 int) returns int
+begin
+return p1;
+end |
+select (select func30787(f1)) as ttt from t1;
+ttt
+1
+2
+drop function func30787;
+drop table t1;
# ------------------------------------------------------------------
# -- End of 5.0 tests
# ------------------------------------------------------------------
diff --git a/mysql-test/r/sp_trans_log.result b/mysql-test/r/sp_trans_log.result
index 9b644798079..eb0770cb0a1 100644
--- a/mysql-test/r/sp_trans_log.result
+++ b/mysql-test/r/sp_trans_log.result
@@ -16,6 +16,7 @@ show binlog events from 98 /* with fixes for #23333 will show there are 2 querie
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # #
master-bin.000001 # Query 1 # #
+master-bin.000001 # Query 1 # #
select count(*),@a from t1 /* must be 1,1 */|
count(*) @a
1 1
diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result
index 34869862a63..0a714635f70 100644
--- a/mysql-test/r/strict.result
+++ b/mysql-test/r/strict.result
@@ -934,6 +934,8 @@ NULL NULL
DROP TABLE t1;
CREATE TABLE t1 (col1 CHAR(5), col2 VARCHAR(6));
INSERT INTO t1 VALUES ('hello', 'hello'),('he', 'he'),('hello ', 'hello ');
+Warnings:
+Note 1265 Data truncated for column 'col1' at row 3
INSERT INTO t1 (col1) VALUES ('hellobob');
ERROR 22001: Data too long for column 'col1' at row 1
INSERT INTO t1 (col2) VALUES ('hellobob');
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 527c45671f4..2de2589fc92 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -4147,103 +4147,37 @@ DROP TABLE t1,t2;
create table t1(a int,b int,key(a),key(b));
insert into t1(a,b) values (1,2),(2,1),(2,3),(3,4),(5,4),(5,5),
(6,7),(7,4),(5,3);
-select sum(a),a from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1
-)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1)
-group by a;
-sum(a) a
-select sum(a),a from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1)
-group by a;
-ERROR HY000: Thread stack overrun detected
-explain select sum(a),a from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1
-)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1)
-group by a;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index a a 5 NULL 9 Using where; Using index
-2 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort
-3 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort
-4 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort
-5 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort
-6 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort
-7 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort
-8 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort
-9 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort
-10 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort
-11 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort
-12 SUBQUERY t1 range a a 5 NULL 1 Using where; Using temporary; Using filesort
-13 SUBQUERY t1 index NULL a 5 NULL 9 Using index
-explain select sum(a),a from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
-select sum(a) from t1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1
-)group by b limit 1)group by b limit 1)group by b limit 1)
-group by a;
-ERROR HY000: Thread stack overrun detected
+5
+4
+3
+2
+1
+26
+25
+24
+23
+22
+21
+20
+19
+18
+17
+16
+15
+14
+13
+12
+11
+10
+9
+8
+7
+6
+5
+4
+3
+2
+1
drop table t1;
CREATE TABLE t1 (a1 INT, a2 INT);
CREATE TABLE t2 (b1 INT, b2 INT);
diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result
index 833adbeb851..689aa724935 100644
--- a/mysql-test/r/symlink.result
+++ b/mysql-test/r/symlink.result
@@ -100,23 +100,15 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
CREATE TABLE t1(a INT)
-DATA DIRECTORY='TEST_DIR/master-data/mysql'
-INDEX DIRECTORY='TEST_DIR/master-data/mysql';
-RENAME TABLE t1 TO user;
-ERROR HY000: Can't create/write to file 'TEST_DIR/master-data/mysql/user.MYI' (Errcode: 17)
-DROP TABLE t1;
-show create table t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `i` int(11) default NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-drop table t1;
-show create table t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `i` int(11) default NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-drop table t1;
+DATA DIRECTORY='TEST_DIR/tmp'
+INDEX DIRECTORY='TEST_DIR/tmp';
+ERROR HY000: Can't create/write to file 'TEST_DIR/tmp/t1.MYI' (Errcode: 17)
+CREATE TABLE t2(a INT)
+DATA DIRECTORY='TEST_DIR/tmp'
+INDEX DIRECTORY='TEST_DIR/tmp';
+RENAME TABLE t2 TO t1;
+ERROR HY000: Can't create/write to file 'TEST_DIR/tmp/t1.MYI' (Errcode: 17)
+DROP TABLE t2;
show create table t1;
Table Create Table
t1 CREATE TEMPORARY TABLE `t1` (
@@ -138,27 +130,38 @@ select * from t1;
a
42
drop table t1;
+execute stmt;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c` char(10) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/'
+drop table t1;
+execute stmt;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c` char(10) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/'
+drop table t1;
+deallocate prepare stmt;
+CREATE TABLE t1(a INT)
+DATA DIRECTORY='TEST_DIR/var/master-data/test';
+Got one of the listed errors
+CREATE TABLE t1(a INT)
+DATA DIRECTORY='TEST_DIR/var/master-data/';
+Got one of the listed errors
+CREATE TABLE t1(a INT)
+INDEX DIRECTORY='TEST_DIR/var/master-data';
+Got one of the listed errors
+CREATE TABLE t1(a INT)
+INDEX DIRECTORY='TEST_DIR/var/master-data_var';
+Got one of the listed errors
End of 4.1 tests
-CREATE DATABASE db1;
-CREATE DATABASE db2;
-USE db2;
-INSERT INTO db2.t1 VALUES (1);
-SELECT * FROM db2.t1;
-b
-1
-RESET QUERY CACHE;
-USE db1;
SET SESSION keep_files_on_create = TRUE;
CREATE TABLE t1 (a INT) ENGINE MYISAM;
-ERROR HY000: Can't create/write to file './db1/t1.MYD' (Errcode: 17)
-CREATE TABLE t3 (a INT) Engine=MyISAM;
-INSERT INTO t3 VALUES (1),(2),(3);
-TRUNCATE TABLE t3;
-SELECT * from t3;
-a
-SET SESSION keep_files_on_create = DEFAULT;
-DROP TABLE db2.t1, db1.t3;
-DROP DATABASE db1;
-DROP DATABASE db2;
-USE test;
+ERROR HY000: Can't create/write to file './test/t1.MYD' (Errcode: 17)
+SET SESSION keep_files_on_create = FALSE;
+CREATE TABLE t1 (a INT) ENGINE MYISAM;
+DROP TABLE t1;
End of 5.0 tests
diff --git a/mysql-test/r/tablelock.result b/mysql-test/r/tablelock.result
index 2ffd8f928a9..6923ad40916 100644
--- a/mysql-test/r/tablelock.result
+++ b/mysql-test/r/tablelock.result
@@ -46,3 +46,12 @@ CREATE TABLE t2 (a int);
lock tables t1 write,t1 as b write, t2 write, t2 as c read;
drop table t2,t1;
unlock tables;
+create temporary table t1(f1 int);
+lock tables t1 write;
+insert into t1 values (1);
+show columns from t1;
+Field Type Null Key Default Extra
+f1 int(11) YES NULL
+insert into t1 values(2);
+drop table t1;
+unlock tables;
diff --git a/mysql-test/r/type_binary.result b/mysql-test/r/type_binary.result
index debf4ff8fb8..aaa46ab415e 100644
--- a/mysql-test/r/type_binary.result
+++ b/mysql-test/r/type_binary.result
@@ -125,6 +125,7 @@ create table t1 (c char(2), vc varchar(2));
insert into t1 values(0x4120, 0x4120);
insert into t1 values(0x412020, 0x412020);
Warnings:
+Note 1265 Data truncated for column 'c' at row 1
Note 1265 Data truncated for column 'vc' at row 1
drop table t1;
set @old_sql_mode= @@sql_mode, sql_mode= 'traditional';
diff --git a/mysql-test/r/type_set.result b/mysql-test/r/type_set.result
index 03de20baef2..9829d4951c9 100644
--- a/mysql-test/r/type_set.result
+++ b/mysql-test/r/type_set.result
@@ -85,3 +85,11 @@ t1 CREATE TABLE `t1` (
`f1` set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','1') default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
+CREATE TABLE t1(c set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64'));
+INSERT INTO t1 VALUES(7);
+INSERT INTO t1 VALUES(9223372036854775808);
+SELECT * FROM t1;
+c
+1,2,3
+64
+DROP TABLE t1;
diff --git a/mysql-test/r/user_var-binlog.result b/mysql-test/r/user_var-binlog.result
index 2b37a4b1d9a..b8df68b8f28 100644
--- a/mysql-test/r/user_var-binlog.result
+++ b/mysql-test/r/user_var-binlog.result
@@ -24,11 +24,13 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
-INSERT INTO t1 VALUES(@`a b`)/*!*/;
+INSERT INTO t1 VALUES(@`a b`)
+/*!*/;
SET @`var1`:=_latin1 0x273B616161 COLLATE `latin1_swedish_ci`/*!*/;
SET @`var2`:=_binary 0x61 COLLATE `binary`/*!*/;
SET TIMESTAMP=10000/*!*/;
-insert into t1 values (@var1),(@var2)/*!*/;
+insert into t1 values (@var1),(@var2)
+/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
diff --git a/mysql-test/r/variables-big.result b/mysql-test/r/variables-big.result
index d7906869276..c441f27d82d 100644
--- a/mysql-test/r/variables-big.result
+++ b/mysql-test/r/variables-big.result
@@ -1,20 +1,24 @@
set session transaction_prealloc_size=1024*1024*1024*1;
show processlist;
Id User Host db Command Time State Info
-1 root localhost test Query 0 NULL show processlist
+6 root localhost test Query 0 NULL show processlist
set session transaction_prealloc_size=1024*1024*1024*2;
show processlist;
Id User Host db Command Time State Info
-1 root localhost test Query 2 NULL show processlist
+6 root localhost test Query 1 NULL show processlist
set session transaction_prealloc_size=1024*1024*1024*3;
show processlist;
Id User Host db Command Time State Info
-1 root localhost test Query 0 NULL show processlist
+6 root localhost test Query 0 NULL show processlist
set session transaction_prealloc_size=1024*1024*1024*4;
+Warnings:
+Warning 1292 Truncated incorrect transaction_prealloc_size value: '4294967296'
show processlist;
Id User Host db Command Time State Info
-1 root localhost test Query 0 NULL show processlist
+6 root localhost test Query 0 NULL show processlist
set session transaction_prealloc_size=1024*1024*1024*5;
+Warnings:
+Warning 1292 Truncated incorrect transaction_prealloc_size value: '5368709120'
show processlist;
Id User Host db Command Time State Info
-1 root localhost test Query 0 NULL show processlist
+6 root localhost test Query 0 NULL show processlist
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index 9c360ef4ab3..376a8ffa38e 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -182,7 +182,7 @@ show global variables like 'myisam_max_sort_file_size';
Variable_name Value
myisam_max_sort_file_size 1048576
set GLOBAL myisam_max_sort_file_size=default;
-show variables like 'myisam_max_sort_file_size';
+show global variables like 'myisam_max_sort_file_size';
Variable_name Value
myisam_max_sort_file_size FILE_SIZE
set global net_retry_count=10, session net_retry_count=10;
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index fb36304e562..520bf9426b8 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -3618,4 +3618,47 @@ ERROR HY000: Field of view 'test.v1' underlying table doesn't have a default val
set @@sql_mode=@old_mode;
drop view v1;
drop table t1;
-End of 5.0 tests.
+create table t1 (a int, key(a));
+create table t2 (c int);
+create view v1 as select a b from t1;
+create view v2 as select 1 a from t2, v1 where c in
+(select 1 from t1 where b = a);
+insert into t1 values (1), (1);
+insert into t2 values (1), (1);
+prepare stmt from "select * from v2 where a = 1";
+execute stmt;
+a
+1
+1
+1
+1
+drop view v1, v2;
+drop table t1, t2;
+CREATE TABLE t1 (a INT);
+CREATE VIEW v1 AS SELECT p.a AS a FROM t1 p, t1 q;
+INSERT INTO t1 VALUES (1), (1);
+SELECT MAX(a), COUNT(DISTINCT a) FROM v1 GROUP BY a;
+MAX(a) COUNT(DISTINCT a)
+1 1
+DROP VIEW v1;
+DROP TABLE t1;
+# -----------------------------------------------------------------
+# -- Bug#34337: Server crash when Altering a view using a table name.
+# -----------------------------------------------------------------
+
+DROP TABLE IF EXISTS t1;
+
+CREATE TABLE t1(c1 INT);
+
+SELECT * FROM t1;
+c1
+ALTER ALGORITHM=TEMPTABLE SQL SECURITY INVOKER VIEW t1 (c2) AS SELECT (1);
+ERROR HY000: 'test.t1' is not VIEW
+
+DROP TABLE t1;
+
+# -- End of test case for Bug#34337.
+
+# -----------------------------------------------------------------
+# -- End of 5.0 tests.
+# -----------------------------------------------------------------
diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result
index eef61c65fb8..53ad8642ba4 100644
--- a/mysql-test/r/view_grant.result
+++ b/mysql-test/r/view_grant.result
@@ -467,6 +467,7 @@ use test;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost;
drop database mysqltest;
drop view if exists v1;
+drop table if exists t1;
create table t1 as select * from mysql.user where user='';
delete from mysql.user where user='';
flush privileges;
diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result
index 9ce1f9c825d..e74f92205aa 100644
--- a/mysql-test/r/warnings.result
+++ b/mysql-test/r/warnings.result
@@ -298,4 +298,42 @@ DROP TABLE t3;
DROP PROCEDURE sp1;
DROP PROCEDURE sp2;
DROP PROCEDURE sp3;
+create table t1 (c_char char(255), c_varchar varchar(255), c_tinytext tinytext);
+create table t2 (c_tinyblob tinyblob);
+set @c = repeat(' ', 256);
+set @q = repeat('q', 256);
+set sql_mode = '';
+insert into t1 values(@c, @c, @c);
+Warnings:
+Note 1265 Data truncated for column 'c_char' at row 1
+Note 1265 Data truncated for column 'c_varchar' at row 1
+Note 1265 Data truncated for column 'c_tinytext' at row 1
+insert into t2 values(@c);
+Warnings:
+Warning 1265 Data truncated for column 'c_tinyblob' at row 1
+insert into t1 values(@q, @q, @q);
+Warnings:
+Warning 1265 Data truncated for column 'c_char' at row 1
+Warning 1265 Data truncated for column 'c_varchar' at row 1
+Warning 1265 Data truncated for column 'c_tinytext' at row 1
+insert into t2 values(@q);
+Warnings:
+Warning 1265 Data truncated for column 'c_tinyblob' at row 1
+set sql_mode = 'traditional';
+insert into t1 values(@c, @c, @c);
+Warnings:
+Note 1265 Data truncated for column 'c_char' at row 1
+Note 1265 Data truncated for column 'c_varchar' at row 1
+Note 1265 Data truncated for column 'c_tinytext' at row 1
+insert into t2 values(@c);
+ERROR 22001: Data too long for column 'c_tinyblob' at row 1
+insert into t1 values(@q, NULL, NULL);
+ERROR 22001: Data too long for column 'c_char' at row 1
+insert into t1 values(NULL, @q, NULL);
+ERROR 22001: Data too long for column 'c_varchar' at row 1
+insert into t1 values(NULL, NULL, @q);
+ERROR 22001: Data too long for column 'c_tinytext' at row 1
+insert into t2 values(@q);
+ERROR 22001: Data too long for column 'c_tinyblob' at row 1
+drop table t1, t2;
End of 5.0 tests
diff --git a/mysql-test/std_data/bug30435_10k_items.txt b/mysql-test/std_data/bug30435_10k_items.txt
new file mode 100644
index 00000000000..9812045fd89
--- /dev/null
+++ b/mysql-test/std_data/bug30435_10k_items.txt
@@ -0,0 +1,10000 @@
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+2180
+2181
+2182
+2183
+2184
+2185
+2186
+2187
+2188
+2189
+2190
+2191
+2192
+2193
+2194
+2195
+2196
+2197
+2198
+2199
+2200
+2201
+2202
+2203
+2204
+2205
+2206
+2207
+2208
+2209
+2210
+2211
+2212
+2213
+2214
+2215
+2216
+2217
+2218
+2219
+2220
+2221
+2222
+2223
+2224
+2225
+2226
+2227
+2228
+2229
+2230
+2231
+2232
+2233
+2234
+2235
+2236
+2237
+2238
+2239
+2240
+2241
+2242
+2243
+2244
+2245
+2246
+2247
+2248
+2249
+2250
+2251
+2252
+2253
+2254
+2255
+2256
+2257
+2258
+2259
+2260
+2261
+2262
+2263
+2264
+2265
+2266
+2267
+2268
+2269
+2270
+2271
+2272
+2273
+2274
+2275
+2276
+2277
+2278
+2279
+2280
+2281
+2282
+2283
+2284
+2285
+2286
+2287
+2288
+2289
+2290
+2291
+2292
+2293
+2294
+2295
+2296
+2297
+2298
+2299
+2300
+2301
+2302
+2303
+2304
+2305
+2306
+2307
+2308
+2309
+2310
+2311
+2312
+2313
+2314
+2315
+2316
+2317
+2318
+2319
+2320
+2321
+2322
+2323
+2324
+2325
+2326
+2327
+2328
+2329
+2330
+2331
+2332
+2333
+2334
+2335
+2336
+2337
+2338
+2339
+2340
+2341
+2342
+2343
+2344
+2345
+2346
+2347
+2348
+2349
+2350
+2351
+2352
+2353
+2354
+2355
+2356
+2357
+2358
+2359
+2360
+2361
+2362
+2363
+2364
+2365
+2366
+2367
+2368
+2369
+2370
+2371
+2372
+2373
+2374
+2375
+2376
+2377
+2378
+2379
+2380
+2381
+2382
+2383
+2384
+2385
+2386
+2387
+2388
+2389
+2390
+2391
+2392
+2393
+2394
+2395
+2396
+2397
+2398
+2399
+2400
+2401
+2402
+2403
+2404
+2405
+2406
+2407
+2408
+2409
+2410
+2411
+2412
+2413
+2414
+2415
+2416
+2417
+2418
+2419
+2420
+2421
+2422
+2423
+2424
+2425
+2426
+2427
+2428
+2429
+2430
+2431
+2432
+2433
+2434
+2435
+2436
+2437
+2438
+2439
+2440
+2441
+2442
+2443
+2444
+2445
+2446
+2447
+2448
+2449
+2450
+2451
+2452
+2453
+2454
+2455
+2456
+2457
+2458
+2459
+2460
+2461
+2462
+2463
+2464
+2465
+2466
+2467
+2468
+2469
+2470
+2471
+2472
+2473
+2474
+2475
+2476
+2477
+2478
+2479
+2480
+2481
+2482
+2483
+2484
+2485
+2486
+2487
+2488
+2489
+2490
+2491
+2492
+2493
+2494
+2495
+2496
+2497
+2498
+2499
+2500
+2501
+2502
+2503
+2504
+2505
+2506
+2507
+2508
+2509
+2510
+2511
+2512
+2513
+2514
+2515
+2516
+2517
+2518
+2519
+2520
+2521
+2522
+2523
+2524
+2525
+2526
+2527
+2528
+2529
+2530
+2531
+2532
+2533
+2534
+2535
+2536
+2537
+2538
+2539
+2540
+2541
+2542
+2543
+2544
+2545
+2546
+2547
+2548
+2549
+2550
+2551
+2552
+2553
+2554
+2555
+2556
+2557
+2558
+2559
+2560
+2561
+2562
+2563
+2564
+2565
+2566
+2567
+2568
+2569
+2570
+2571
+2572
+2573
+2574
+2575
+2576
+2577
+2578
+2579
+2580
+2581
+2582
+2583
+2584
+2585
+2586
+2587
+2588
+2589
+2590
+2591
+2592
+2593
+2594
+2595
+2596
+2597
+2598
+2599
+2600
+2601
+2602
+2603
+2604
+2605
+2606
+2607
+2608
+2609
+2610
+2611
+2612
+2613
+2614
+2615
+2616
+2617
+2618
+2619
+2620
+2621
+2622
+2623
+2624
+2625
+2626
+2627
+2628
+2629
+2630
+2631
+2632
+2633
+2634
+2635
+2636
+2637
+2638
+2639
+2640
+2641
+2642
+2643
+2644
+2645
+2646
+2647
+2648
+2649
+2650
+2651
+2652
+2653
+2654
+2655
+2656
+2657
+2658
+2659
+2660
+2661
+2662
+2663
+2664
+2665
+2666
+2667
+2668
+2669
+2670
+2671
+2672
+2673
+2674
+2675
+2676
+2677
+2678
+2679
+2680
+2681
+2682
+2683
+2684
+2685
+2686
+2687
+2688
+2689
+2690
+2691
+2692
+2693
+2694
+2695
+2696
+2697
+2698
+2699
+2700
+2701
+2702
+2703
+2704
+2705
+2706
+2707
+2708
+2709
+2710
+2711
+2712
+2713
+2714
+2715
+2716
+2717
+2718
+2719
+2720
+2721
+2722
+2723
+2724
+2725
+2726
+2727
+2728
+2729
+2730
+2731
+2732
+2733
+2734
+2735
+2736
+2737
+2738
+2739
+2740
+2741
+2742
+2743
+2744
+2745
+2746
+2747
+2748
+2749
+2750
+2751
+2752
+2753
+2754
+2755
+2756
+2757
+2758
+2759
+2760
+2761
+2762
+2763
+2764
+2765
+2766
+2767
+2768
+2769
+2770
+2771
+2772
+2773
+2774
+2775
+2776
+2777
+2778
+2779
+2780
+2781
+2782
+2783
+2784
+2785
+2786
+2787
+2788
+2789
+2790
+2791
+2792
+2793
+2794
+2795
+2796
+2797
+2798
+2799
+2800
+2801
+2802
+2803
+2804
+2805
+2806
+2807
+2808
+2809
+2810
+2811
+2812
+2813
+2814
+2815
+2816
+2817
+2818
+2819
+2820
+2821
+2822
+2823
+2824
+2825
+2826
+2827
+2828
+2829
+2830
+2831
+2832
+2833
+2834
+2835
+2836
+2837
+2838
+2839
+2840
+2841
+2842
+2843
+2844
+2845
+2846
+2847
+2848
+2849
+2850
+2851
+2852
+2853
+2854
+2855
+2856
+2857
+2858
+2859
+2860
+2861
+2862
+2863
+2864
+2865
+2866
+2867
+2868
+2869
+2870
+2871
+2872
+2873
+2874
+2875
+2876
+2877
+2878
+2879
+2880
+2881
+2882
+2883
+2884
+2885
+2886
+2887
+2888
+2889
+2890
+2891
+2892
+2893
+2894
+2895
+2896
+2897
+2898
+2899
+2900
+2901
+2902
+2903
+2904
+2905
+2906
+2907
+2908
+2909
+2910
+2911
+2912
+2913
+2914
+2915
+2916
+2917
+2918
+2919
+2920
+2921
+2922
+2923
+2924
+2925
+2926
+2927
+2928
+2929
+2930
+2931
+2932
+2933
+2934
+2935
+2936
+2937
+2938
+2939
+2940
+2941
+2942
+2943
+2944
+2945
+2946
+2947
+2948
+2949
+2950
+2951
+2952
+2953
+2954
+2955
+2956
+2957
+2958
+2959
+2960
+2961
+2962
+2963
+2964
+2965
+2966
+2967
+2968
+2969
+2970
+2971
+2972
+2973
+2974
+2975
+2976
+2977
+2978
+2979
+2980
+2981
+2982
+2983
+2984
+2985
+2986
+2987
+2988
+2989
+2990
+2991
+2992
+2993
+2994
+2995
+2996
+2997
+2998
+2999
+3000
+3001
+3002
+3003
+3004
+3005
+3006
+3007
+3008
+3009
+3010
+3011
+3012
+3013
+3014
+3015
+3016
+3017
+3018
+3019
+3020
+3021
+3022
+3023
+3024
+3025
+3026
+3027
+3028
+3029
+3030
+3031
+3032
+3033
+3034
+3035
+3036
+3037
+3038
+3039
+3040
+3041
+3042
+3043
+3044
+3045
+3046
+3047
+3048
+3049
+3050
+3051
+3052
+3053
+3054
+3055
+3056
+3057
+3058
+3059
+3060
+3061
+3062
+3063
+3064
+3065
+3066
+3067
+3068
+3069
+3070
+3071
+3072
+3073
+3074
+3075
+3076
+3077
+3078
+3079
+3080
+3081
+3082
+3083
+3084
+3085
+3086
+3087
+3088
+3089
+3090
+3091
+3092
+3093
+3094
+3095
+3096
+3097
+3098
+3099
+3100
+3101
+3102
+3103
+3104
+3105
+3106
+3107
+3108
+3109
+3110
+3111
+3112
+3113
+3114
+3115
+3116
+3117
+3118
+3119
+3120
+3121
+3122
+3123
+3124
+3125
+3126
+3127
+3128
+3129
+3130
+3131
+3132
+3133
+3134
+3135
+3136
+3137
+3138
+3139
+3140
+3141
+3142
+3143
+3144
+3145
+3146
+3147
+3148
+3149
+3150
+3151
+3152
+3153
+3154
+3155
+3156
+3157
+3158
+3159
+3160
+3161
+3162
+3163
+3164
+3165
+3166
+3167
+3168
+3169
+3170
+3171
+3172
+3173
+3174
+3175
+3176
+3177
+3178
+3179
+3180
+3181
+3182
+3183
+3184
+3185
+3186
+3187
+3188
+3189
+3190
+3191
+3192
+3193
+3194
+3195
+3196
+3197
+3198
+3199
+3200
+3201
+3202
+3203
+3204
+3205
+3206
+3207
+3208
+3209
+3210
+3211
+3212
+3213
+3214
+3215
+3216
+3217
+3218
+3219
+3220
+3221
+3222
+3223
+3224
+3225
+3226
+3227
+3228
+3229
+3230
+3231
+3232
+3233
+3234
+3235
+3236
+3237
+3238
+3239
+3240
+3241
+3242
+3243
+3244
+3245
+3246
+3247
+3248
+3249
+3250
+3251
+3252
+3253
+3254
+3255
+3256
+3257
+3258
+3259
+3260
+3261
+3262
+3263
+3264
+3265
+3266
+3267
+3268
+3269
+3270
+3271
+3272
+3273
+3274
+3275
+3276
+3277
+3278
+3279
+3280
+3281
+3282
+3283
+3284
+3285
+3286
+3287
+3288
+3289
+3290
+3291
+3292
+3293
+3294
+3295
+3296
+3297
+3298
+3299
+3300
+3301
+3302
+3303
+3304
+3305
+3306
+3307
+3308
+3309
+3310
+3311
+3312
+3313
+3314
+3315
+3316
+3317
+3318
+3319
+3320
+3321
+3322
+3323
+3324
+3325
+3326
+3327
+3328
+3329
+3330
+3331
+3332
+3333
+3334
+3335
+3336
+3337
+3338
+3339
+3340
+3341
+3342
+3343
+3344
+3345
+3346
+3347
+3348
+3349
+3350
+3351
+3352
+3353
+3354
+3355
+3356
+3357
+3358
+3359
+3360
+3361
+3362
+3363
+3364
+3365
+3366
+3367
+3368
+3369
+3370
+3371
+3372
+3373
+3374
+3375
+3376
+3377
+3378
+3379
+3380
+3381
+3382
+3383
+3384
+3385
+3386
+3387
+3388
+3389
+3390
+3391
+3392
+3393
+3394
+3395
+3396
+3397
+3398
+3399
+3400
+3401
+3402
+3403
+3404
+3405
+3406
+3407
+3408
+3409
+3410
+3411
+3412
+3413
+3414
+3415
+3416
+3417
+3418
+3419
+3420
+3421
+3422
+3423
+3424
+3425
+3426
+3427
+3428
+3429
+3430
+3431
+3432
+3433
+3434
+3435
+3436
+3437
+3438
+3439
+3440
+3441
+3442
+3443
+3444
+3445
+3446
+3447
+3448
+3449
+3450
+3451
+3452
+3453
+3454
+3455
+3456
+3457
+3458
+3459
+3460
+3461
+3462
+3463
+3464
+3465
+3466
+3467
+3468
+3469
+3470
+3471
+3472
+3473
+3474
+3475
+3476
+3477
+3478
+3479
+3480
+3481
+3482
+3483
+3484
+3485
+3486
+3487
+3488
+3489
+3490
+3491
+3492
+3493
+3494
+3495
+3496
+3497
+3498
+3499
+3500
+3501
+3502
+3503
+3504
+3505
+3506
+3507
+3508
+3509
+3510
+3511
+3512
+3513
+3514
+3515
+3516
+3517
+3518
+3519
+3520
+3521
+3522
+3523
+3524
+3525
+3526
+3527
+3528
+3529
+3530
+3531
+3532
+3533
+3534
+3535
+3536
+3537
+3538
+3539
+3540
+3541
+3542
+3543
+3544
+3545
+3546
+3547
+3548
+3549
+3550
+3551
+3552
+3553
+3554
+3555
+3556
+3557
+3558
+3559
+3560
+3561
+3562
+3563
+3564
+3565
+3566
+3567
+3568
+3569
+3570
+3571
+3572
+3573
+3574
+3575
+3576
+3577
+3578
+3579
+3580
+3581
+3582
+3583
+3584
+3585
+3586
+3587
+3588
+3589
+3590
+3591
+3592
+3593
+3594
+3595
+3596
+3597
+3598
+3599
+3600
+3601
+3602
+3603
+3604
+3605
+3606
+3607
+3608
+3609
+3610
+3611
+3612
+3613
+3614
+3615
+3616
+3617
+3618
+3619
+3620
+3621
+3622
+3623
+3624
+3625
+3626
+3627
+3628
+3629
+3630
+3631
+3632
+3633
+3634
+3635
+3636
+3637
+3638
+3639
+3640
+3641
+3642
+3643
+3644
+3645
+3646
+3647
+3648
+3649
+3650
+3651
+3652
+3653
+3654
+3655
+3656
+3657
+3658
+3659
+3660
+3661
+3662
+3663
+3664
+3665
+3666
+3667
+3668
+3669
+3670
+3671
+3672
+3673
+3674
+3675
+3676
+3677
+3678
+3679
+3680
+3681
+3682
+3683
+3684
+3685
+3686
+3687
+3688
+3689
+3690
+3691
+3692
+3693
+3694
+3695
+3696
+3697
+3698
+3699
+3700
+3701
+3702
+3703
+3704
+3705
+3706
+3707
+3708
+3709
+3710
+3711
+3712
+3713
+3714
+3715
+3716
+3717
+3718
+3719
+3720
+3721
+3722
+3723
+3724
+3725
+3726
+3727
+3728
+3729
+3730
+3731
+3732
+3733
+3734
+3735
+3736
+3737
+3738
+3739
+3740
+3741
+3742
+3743
+3744
+3745
+3746
+3747
+3748
+3749
+3750
+3751
+3752
+3753
+3754
+3755
+3756
+3757
+3758
+3759
+3760
+3761
+3762
+3763
+3764
+3765
+3766
+3767
+3768
+3769
+3770
+3771
+3772
+3773
+3774
+3775
+3776
+3777
+3778
+3779
+3780
+3781
+3782
+3783
+3784
+3785
+3786
+3787
+3788
+3789
+3790
+3791
+3792
+3793
+3794
+3795
+3796
+3797
+3798
+3799
+3800
+3801
+3802
+3803
+3804
+3805
+3806
+3807
+3808
+3809
+3810
+3811
+3812
+3813
+3814
+3815
+3816
+3817
+3818
+3819
+3820
+3821
+3822
+3823
+3824
+3825
+3826
+3827
+3828
+3829
+3830
+3831
+3832
+3833
+3834
+3835
+3836
+3837
+3838
+3839
+3840
+3841
+3842
+3843
+3844
+3845
+3846
+3847
+3848
+3849
+3850
+3851
+3852
+3853
+3854
+3855
+3856
+3857
+3858
+3859
+3860
+3861
+3862
+3863
+3864
+3865
+3866
+3867
+3868
+3869
+3870
+3871
+3872
+3873
+3874
+3875
+3876
+3877
+3878
+3879
+3880
+3881
+3882
+3883
+3884
+3885
+3886
+3887
+3888
+3889
+3890
+3891
+3892
+3893
+3894
+3895
+3896
+3897
+3898
+3899
+3900
+3901
+3902
+3903
+3904
+3905
+3906
+3907
+3908
+3909
+3910
+3911
+3912
+3913
+3914
+3915
+3916
+3917
+3918
+3919
+3920
+3921
+3922
+3923
+3924
+3925
+3926
+3927
+3928
+3929
+3930
+3931
+3932
+3933
+3934
+3935
+3936
+3937
+3938
+3939
+3940
+3941
+3942
+3943
+3944
+3945
+3946
+3947
+3948
+3949
+3950
+3951
+3952
+3953
+3954
+3955
+3956
+3957
+3958
+3959
+3960
+3961
+3962
+3963
+3964
+3965
+3966
+3967
+3968
+3969
+3970
+3971
+3972
+3973
+3974
+3975
+3976
+3977
+3978
+3979
+3980
+3981
+3982
+3983
+3984
+3985
+3986
+3987
+3988
+3989
+3990
+3991
+3992
+3993
+3994
+3995
+3996
+3997
+3998
+3999
+4000
+4001
+4002
+4003
+4004
+4005
+4006
+4007
+4008
+4009
+4010
+4011
+4012
+4013
+4014
+4015
+4016
+4017
+4018
+4019
+4020
+4021
+4022
+4023
+4024
+4025
+4026
+4027
+4028
+4029
+4030
+4031
+4032
+4033
+4034
+4035
+4036
+4037
+4038
+4039
+4040
+4041
+4042
+4043
+4044
+4045
+4046
+4047
+4048
+4049
+4050
+4051
+4052
+4053
+4054
+4055
+4056
+4057
+4058
+4059
+4060
+4061
+4062
+4063
+4064
+4065
+4066
+4067
+4068
+4069
+4070
+4071
+4072
+4073
+4074
+4075
+4076
+4077
+4078
+4079
+4080
+4081
+4082
+4083
+4084
+4085
+4086
+4087
+4088
+4089
+4090
+4091
+4092
+4093
+4094
+4095
+4096
+4097
+4098
+4099
+4100
+4101
+4102
+4103
+4104
+4105
+4106
+4107
+4108
+4109
+4110
+4111
+4112
+4113
+4114
+4115
+4116
+4117
+4118
+4119
+4120
+4121
+4122
+4123
+4124
+4125
+4126
+4127
+4128
+4129
+4130
+4131
+4132
+4133
+4134
+4135
+4136
+4137
+4138
+4139
+4140
+4141
+4142
+4143
+4144
+4145
+4146
+4147
+4148
+4149
+4150
+4151
+4152
+4153
+4154
+4155
+4156
+4157
+4158
+4159
+4160
+4161
+4162
+4163
+4164
+4165
+4166
+4167
+4168
+4169
+4170
+4171
+4172
+4173
+4174
+4175
+4176
+4177
+4178
+4179
+4180
+4181
+4182
+4183
+4184
+4185
+4186
+4187
+4188
+4189
+4190
+4191
+4192
+4193
+4194
+4195
+4196
+4197
+4198
+4199
+4200
+4201
+4202
+4203
+4204
+4205
+4206
+4207
+4208
+4209
+4210
+4211
+4212
+4213
+4214
+4215
+4216
+4217
+4218
+4219
+4220
+4221
+4222
+4223
+4224
+4225
+4226
+4227
+4228
+4229
+4230
+4231
+4232
+4233
+4234
+4235
+4236
+4237
+4238
+4239
+4240
+4241
+4242
+4243
+4244
+4245
+4246
+4247
+4248
+4249
+4250
+4251
+4252
+4253
+4254
+4255
+4256
+4257
+4258
+4259
+4260
+4261
+4262
+4263
+4264
+4265
+4266
+4267
+4268
+4269
+4270
+4271
+4272
+4273
+4274
+4275
+4276
+4277
+4278
+4279
+4280
+4281
+4282
+4283
+4284
+4285
+4286
+4287
+4288
+4289
+4290
+4291
+4292
+4293
+4294
+4295
+4296
+4297
+4298
+4299
+4300
+4301
+4302
+4303
+4304
+4305
+4306
+4307
+4308
+4309
+4310
+4311
+4312
+4313
+4314
+4315
+4316
+4317
+4318
+4319
+4320
+4321
+4322
+4323
+4324
+4325
+4326
+4327
+4328
+4329
+4330
+4331
+4332
+4333
+4334
+4335
+4336
+4337
+4338
+4339
+4340
+4341
+4342
+4343
+4344
+4345
+4346
+4347
+4348
+4349
+4350
+4351
+4352
+4353
+4354
+4355
+4356
+4357
+4358
+4359
+4360
+4361
+4362
+4363
+4364
+4365
+4366
+4367
+4368
+4369
+4370
+4371
+4372
+4373
+4374
+4375
+4376
+4377
+4378
+4379
+4380
+4381
+4382
+4383
+4384
+4385
+4386
+4387
+4388
+4389
+4390
+4391
+4392
+4393
+4394
+4395
+4396
+4397
+4398
+4399
+4400
+4401
+4402
+4403
+4404
+4405
+4406
+4407
+4408
+4409
+4410
+4411
+4412
+4413
+4414
+4415
+4416
+4417
+4418
+4419
+4420
+4421
+4422
+4423
+4424
+4425
+4426
+4427
+4428
+4429
+4430
+4431
+4432
+4433
+4434
+4435
+4436
+4437
+4438
+4439
+4440
+4441
+4442
+4443
+4444
+4445
+4446
+4447
+4448
+4449
+4450
+4451
+4452
+4453
+4454
+4455
+4456
+4457
+4458
+4459
+4460
+4461
+4462
+4463
+4464
+4465
+4466
+4467
+4468
+4469
+4470
+4471
+4472
+4473
+4474
+4475
+4476
+4477
+4478
+4479
+4480
+4481
+4482
+4483
+4484
+4485
+4486
+4487
+4488
+4489
+4490
+4491
+4492
+4493
+4494
+4495
+4496
+4497
+4498
+4499
+4500
+4501
+4502
+4503
+4504
+4505
+4506
+4507
+4508
+4509
+4510
+4511
+4512
+4513
+4514
+4515
+4516
+4517
+4518
+4519
+4520
+4521
+4522
+4523
+4524
+4525
+4526
+4527
+4528
+4529
+4530
+4531
+4532
+4533
+4534
+4535
+4536
+4537
+4538
+4539
+4540
+4541
+4542
+4543
+4544
+4545
+4546
+4547
+4548
+4549
+4550
+4551
+4552
+4553
+4554
+4555
+4556
+4557
+4558
+4559
+4560
+4561
+4562
+4563
+4564
+4565
+4566
+4567
+4568
+4569
+4570
+4571
+4572
+4573
+4574
+4575
+4576
+4577
+4578
+4579
+4580
+4581
+4582
+4583
+4584
+4585
+4586
+4587
+4588
+4589
+4590
+4591
+4592
+4593
+4594
+4595
+4596
+4597
+4598
+4599
+4600
+4601
+4602
+4603
+4604
+4605
+4606
+4607
+4608
+4609
+4610
+4611
+4612
+4613
+4614
+4615
+4616
+4617
+4618
+4619
+4620
+4621
+4622
+4623
+4624
+4625
+4626
+4627
+4628
+4629
+4630
+4631
+4632
+4633
+4634
+4635
+4636
+4637
+4638
+4639
+4640
+4641
+4642
+4643
+4644
+4645
+4646
+4647
+4648
+4649
+4650
+4651
+4652
+4653
+4654
+4655
+4656
+4657
+4658
+4659
+4660
+4661
+4662
+4663
+4664
+4665
+4666
+4667
+4668
+4669
+4670
+4671
+4672
+4673
+4674
+4675
+4676
+4677
+4678
+4679
+4680
+4681
+4682
+4683
+4684
+4685
+4686
+4687
+4688
+4689
+4690
+4691
+4692
+4693
+4694
+4695
+4696
+4697
+4698
+4699
+4700
+4701
+4702
+4703
+4704
+4705
+4706
+4707
+4708
+4709
+4710
+4711
+4712
+4713
+4714
+4715
+4716
+4717
+4718
+4719
+4720
+4721
+4722
+4723
+4724
+4725
+4726
+4727
+4728
+4729
+4730
+4731
+4732
+4733
+4734
+4735
+4736
+4737
+4738
+4739
+4740
+4741
+4742
+4743
+4744
+4745
+4746
+4747
+4748
+4749
+4750
+4751
+4752
+4753
+4754
+4755
+4756
+4757
+4758
+4759
+4760
+4761
+4762
+4763
+4764
+4765
+4766
+4767
+4768
+4769
+4770
+4771
+4772
+4773
+4774
+4775
+4776
+4777
+4778
+4779
+4780
+4781
+4782
+4783
+4784
+4785
+4786
+4787
+4788
+4789
+4790
+4791
+4792
+4793
+4794
+4795
+4796
+4797
+4798
+4799
+4800
+4801
+4802
+4803
+4804
+4805
+4806
+4807
+4808
+4809
+4810
+4811
+4812
+4813
+4814
+4815
+4816
+4817
+4818
+4819
+4820
+4821
+4822
+4823
+4824
+4825
+4826
+4827
+4828
+4829
+4830
+4831
+4832
+4833
+4834
+4835
+4836
+4837
+4838
+4839
+4840
+4841
+4842
+4843
+4844
+4845
+4846
+4847
+4848
+4849
+4850
+4851
+4852
+4853
+4854
+4855
+4856
+4857
+4858
+4859
+4860
+4861
+4862
+4863
+4864
+4865
+4866
+4867
+4868
+4869
+4870
+4871
+4872
+4873
+4874
+4875
+4876
+4877
+4878
+4879
+4880
+4881
+4882
+4883
+4884
+4885
+4886
+4887
+4888
+4889
+4890
+4891
+4892
+4893
+4894
+4895
+4896
+4897
+4898
+4899
+4900
+4901
+4902
+4903
+4904
+4905
+4906
+4907
+4908
+4909
+4910
+4911
+4912
+4913
+4914
+4915
+4916
+4917
+4918
+4919
+4920
+4921
+4922
+4923
+4924
+4925
+4926
+4927
+4928
+4929
+4930
+4931
+4932
+4933
+4934
+4935
+4936
+4937
+4938
+4939
+4940
+4941
+4942
+4943
+4944
+4945
+4946
+4947
+4948
+4949
+4950
+4951
+4952
+4953
+4954
+4955
+4956
+4957
+4958
+4959
+4960
+4961
+4962
+4963
+4964
+4965
+4966
+4967
+4968
+4969
+4970
+4971
+4972
+4973
+4974
+4975
+4976
+4977
+4978
+4979
+4980
+4981
+4982
+4983
+4984
+4985
+4986
+4987
+4988
+4989
+4990
+4991
+4992
+4993
+4994
+4995
+4996
+4997
+4998
+4999
+5000
+5001
+5002
+5003
+5004
+5005
+5006
+5007
+5008
+5009
+5010
+5011
+5012
+5013
+5014
+5015
+5016
+5017
+5018
+5019
+5020
+5021
+5022
+5023
+5024
+5025
+5026
+5027
+5028
+5029
+5030
+5031
+5032
+5033
+5034
+5035
+5036
+5037
+5038
+5039
+5040
+5041
+5042
+5043
+5044
+5045
+5046
+5047
+5048
+5049
+5050
+5051
+5052
+5053
+5054
+5055
+5056
+5057
+5058
+5059
+5060
+5061
+5062
+5063
+5064
+5065
+5066
+5067
+5068
+5069
+5070
+5071
+5072
+5073
+5074
+5075
+5076
+5077
+5078
+5079
+5080
+5081
+5082
+5083
+5084
+5085
+5086
+5087
+5088
+5089
+5090
+5091
+5092
+5093
+5094
+5095
+5096
+5097
+5098
+5099
+5100
+5101
+5102
+5103
+5104
+5105
+5106
+5107
+5108
+5109
+5110
+5111
+5112
+5113
+5114
+5115
+5116
+5117
+5118
+5119
+5120
+5121
+5122
+5123
+5124
+5125
+5126
+5127
+5128
+5129
+5130
+5131
+5132
+5133
+5134
+5135
+5136
+5137
+5138
+5139
+5140
+5141
+5142
+5143
+5144
+5145
+5146
+5147
+5148
+5149
+5150
+5151
+5152
+5153
+5154
+5155
+5156
+5157
+5158
+5159
+5160
+5161
+5162
+5163
+5164
+5165
+5166
+5167
+5168
+5169
+5170
+5171
+5172
+5173
+5174
+5175
+5176
+5177
+5178
+5179
+5180
+5181
+5182
+5183
+5184
+5185
+5186
+5187
+5188
+5189
+5190
+5191
+5192
+5193
+5194
+5195
+5196
+5197
+5198
+5199
+5200
+5201
+5202
+5203
+5204
+5205
+5206
+5207
+5208
+5209
+5210
+5211
+5212
+5213
+5214
+5215
+5216
+5217
+5218
+5219
+5220
+5221
+5222
+5223
+5224
+5225
+5226
+5227
+5228
+5229
+5230
+5231
+5232
+5233
+5234
+5235
+5236
+5237
+5238
+5239
+5240
+5241
+5242
+5243
+5244
+5245
+5246
+5247
+5248
+5249
+5250
+5251
+5252
+5253
+5254
+5255
+5256
+5257
+5258
+5259
+5260
+5261
+5262
+5263
+5264
+5265
+5266
+5267
+5268
+5269
+5270
+5271
+5272
+5273
+5274
+5275
+5276
+5277
+5278
+5279
+5280
+5281
+5282
+5283
+5284
+5285
+5286
+5287
+5288
+5289
+5290
+5291
+5292
+5293
+5294
+5295
+5296
+5297
+5298
+5299
+5300
+5301
+5302
+5303
+5304
+5305
+5306
+5307
+5308
+5309
+5310
+5311
+5312
+5313
+5314
+5315
+5316
+5317
+5318
+5319
+5320
+5321
+5322
+5323
+5324
+5325
+5326
+5327
+5328
+5329
+5330
+5331
+5332
+5333
+5334
+5335
+5336
+5337
+5338
+5339
+5340
+5341
+5342
+5343
+5344
+5345
+5346
+5347
+5348
+5349
+5350
+5351
+5352
+5353
+5354
+5355
+5356
+5357
+5358
+5359
+5360
+5361
+5362
+5363
+5364
+5365
+5366
+5367
+5368
+5369
+5370
+5371
+5372
+5373
+5374
+5375
+5376
+5377
+5378
+5379
+5380
+5381
+5382
+5383
+5384
+5385
+5386
+5387
+5388
+5389
+5390
+5391
+5392
+5393
+5394
+5395
+5396
+5397
+5398
+5399
+5400
+5401
+5402
+5403
+5404
+5405
+5406
+5407
+5408
+5409
+5410
+5411
+5412
+5413
+5414
+5415
+5416
+5417
+5418
+5419
+5420
+5421
+5422
+5423
+5424
+5425
+5426
+5427
+5428
+5429
+5430
+5431
+5432
+5433
+5434
+5435
+5436
+5437
+5438
+5439
+5440
+5441
+5442
+5443
+5444
+5445
+5446
+5447
+5448
+5449
+5450
+5451
+5452
+5453
+5454
+5455
+5456
+5457
+5458
+5459
+5460
+5461
+5462
+5463
+5464
+5465
+5466
+5467
+5468
+5469
+5470
+5471
+5472
+5473
+5474
+5475
+5476
+5477
+5478
+5479
+5480
+5481
+5482
+5483
+5484
+5485
+5486
+5487
+5488
+5489
+5490
+5491
+5492
+5493
+5494
+5495
+5496
+5497
+5498
+5499
+5500
+5501
+5502
+5503
+5504
+5505
+5506
+5507
+5508
+5509
+5510
+5511
+5512
+5513
+5514
+5515
+5516
+5517
+5518
+5519
+5520
+5521
+5522
+5523
+5524
+5525
+5526
+5527
+5528
+5529
+5530
+5531
+5532
+5533
+5534
+5535
+5536
+5537
+5538
+5539
+5540
+5541
+5542
+5543
+5544
+5545
+5546
+5547
+5548
+5549
+5550
+5551
+5552
+5553
+5554
+5555
+5556
+5557
+5558
+5559
+5560
+5561
+5562
+5563
+5564
+5565
+5566
+5567
+5568
+5569
+5570
+5571
+5572
+5573
+5574
+5575
+5576
+5577
+5578
+5579
+5580
+5581
+5582
+5583
+5584
+5585
+5586
+5587
+5588
+5589
+5590
+5591
+5592
+5593
+5594
+5595
+5596
+5597
+5598
+5599
+5600
+5601
+5602
+5603
+5604
+5605
+5606
+5607
+5608
+5609
+5610
+5611
+5612
+5613
+5614
+5615
+5616
+5617
+5618
+5619
+5620
+5621
+5622
+5623
+5624
+5625
+5626
+5627
+5628
+5629
+5630
+5631
+5632
+5633
+5634
+5635
+5636
+5637
+5638
+5639
+5640
+5641
+5642
+5643
+5644
+5645
+5646
+5647
+5648
+5649
+5650
+5651
+5652
+5653
+5654
+5655
+5656
+5657
+5658
+5659
+5660
+5661
+5662
+5663
+5664
+5665
+5666
+5667
+5668
+5669
+5670
+5671
+5672
+5673
+5674
+5675
+5676
+5677
+5678
+5679
+5680
+5681
+5682
+5683
+5684
+5685
+5686
+5687
+5688
+5689
+5690
+5691
+5692
+5693
+5694
+5695
+5696
+5697
+5698
+5699
+5700
+5701
+5702
+5703
+5704
+5705
+5706
+5707
+5708
+5709
+5710
+5711
+5712
+5713
+5714
+5715
+5716
+5717
+5718
+5719
+5720
+5721
+5722
+5723
+5724
+5725
+5726
+5727
+5728
+5729
+5730
+5731
+5732
+5733
+5734
+5735
+5736
+5737
+5738
+5739
+5740
+5741
+5742
+5743
+5744
+5745
+5746
+5747
+5748
+5749
+5750
+5751
+5752
+5753
+5754
+5755
+5756
+5757
+5758
+5759
+5760
+5761
+5762
+5763
+5764
+5765
+5766
+5767
+5768
+5769
+5770
+5771
+5772
+5773
+5774
+5775
+5776
+5777
+5778
+5779
+5780
+5781
+5782
+5783
+5784
+5785
+5786
+5787
+5788
+5789
+5790
+5791
+5792
+5793
+5794
+5795
+5796
+5797
+5798
+5799
+5800
+5801
+5802
+5803
+5804
+5805
+5806
+5807
+5808
+5809
+5810
+5811
+5812
+5813
+5814
+5815
+5816
+5817
+5818
+5819
+5820
+5821
+5822
+5823
+5824
+5825
+5826
+5827
+5828
+5829
+5830
+5831
+5832
+5833
+5834
+5835
+5836
+5837
+5838
+5839
+5840
+5841
+5842
+5843
+5844
+5845
+5846
+5847
+5848
+5849
+5850
+5851
+5852
+5853
+5854
+5855
+5856
+5857
+5858
+5859
+5860
+5861
+5862
+5863
+5864
+5865
+5866
+5867
+5868
+5869
+5870
+5871
+5872
+5873
+5874
+5875
+5876
+5877
+5878
+5879
+5880
+5881
+5882
+5883
+5884
+5885
+5886
+5887
+5888
+5889
+5890
+5891
+5892
+5893
+5894
+5895
+5896
+5897
+5898
+5899
+5900
+5901
+5902
+5903
+5904
+5905
+5906
+5907
+5908
+5909
+5910
+5911
+5912
+5913
+5914
+5915
+5916
+5917
+5918
+5919
+5920
+5921
+5922
+5923
+5924
+5925
+5926
+5927
+5928
+5929
+5930
+5931
+5932
+5933
+5934
+5935
+5936
+5937
+5938
+5939
+5940
+5941
+5942
+5943
+5944
+5945
+5946
+5947
+5948
+5949
+5950
+5951
+5952
+5953
+5954
+5955
+5956
+5957
+5958
+5959
+5960
+5961
+5962
+5963
+5964
+5965
+5966
+5967
+5968
+5969
+5970
+5971
+5972
+5973
+5974
+5975
+5976
+5977
+5978
+5979
+5980
+5981
+5982
+5983
+5984
+5985
+5986
+5987
+5988
+5989
+5990
+5991
+5992
+5993
+5994
+5995
+5996
+5997
+5998
+5999
+6000
+6001
+6002
+6003
+6004
+6005
+6006
+6007
+6008
+6009
+6010
+6011
+6012
+6013
+6014
+6015
+6016
+6017
+6018
+6019
+6020
+6021
+6022
+6023
+6024
+6025
+6026
+6027
+6028
+6029
+6030
+6031
+6032
+6033
+6034
+6035
+6036
+6037
+6038
+6039
+6040
+6041
+6042
+6043
+6044
+6045
+6046
+6047
+6048
+6049
+6050
+6051
+6052
+6053
+6054
+6055
+6056
+6057
+6058
+6059
+6060
+6061
+6062
+6063
+6064
+6065
+6066
+6067
+6068
+6069
+6070
+6071
+6072
+6073
+6074
+6075
+6076
+6077
+6078
+6079
+6080
+6081
+6082
+6083
+6084
+6085
+6086
+6087
+6088
+6089
+6090
+6091
+6092
+6093
+6094
+6095
+6096
+6097
+6098
+6099
+6100
+6101
+6102
+6103
+6104
+6105
+6106
+6107
+6108
+6109
+6110
+6111
+6112
+6113
+6114
+6115
+6116
+6117
+6118
+6119
+6120
+6121
+6122
+6123
+6124
+6125
+6126
+6127
+6128
+6129
+6130
+6131
+6132
+6133
+6134
+6135
+6136
+6137
+6138
+6139
+6140
+6141
+6142
+6143
+6144
+6145
+6146
+6147
+6148
+6149
+6150
+6151
+6152
+6153
+6154
+6155
+6156
+6157
+6158
+6159
+6160
+6161
+6162
+6163
+6164
+6165
+6166
+6167
+6168
+6169
+6170
+6171
+6172
+6173
+6174
+6175
+6176
+6177
+6178
+6179
+6180
+6181
+6182
+6183
+6184
+6185
+6186
+6187
+6188
+6189
+6190
+6191
+6192
+6193
+6194
+6195
+6196
+6197
+6198
+6199
+6200
+6201
+6202
+6203
+6204
+6205
+6206
+6207
+6208
+6209
+6210
+6211
+6212
+6213
+6214
+6215
+6216
+6217
+6218
+6219
+6220
+6221
+6222
+6223
+6224
+6225
+6226
+6227
+6228
+6229
+6230
+6231
+6232
+6233
+6234
+6235
+6236
+6237
+6238
+6239
+6240
+6241
+6242
+6243
+6244
+6245
+6246
+6247
+6248
+6249
+6250
+6251
+6252
+6253
+6254
+6255
+6256
+6257
+6258
+6259
+6260
+6261
+6262
+6263
+6264
+6265
+6266
+6267
+6268
+6269
+6270
+6271
+6272
+6273
+6274
+6275
+6276
+6277
+6278
+6279
+6280
+6281
+6282
+6283
+6284
+6285
+6286
+6287
+6288
+6289
+6290
+6291
+6292
+6293
+6294
+6295
+6296
+6297
+6298
+6299
+6300
+6301
+6302
+6303
+6304
+6305
+6306
+6307
+6308
+6309
+6310
+6311
+6312
+6313
+6314
+6315
+6316
+6317
+6318
+6319
+6320
+6321
+6322
+6323
+6324
+6325
+6326
+6327
+6328
+6329
+6330
+6331
+6332
+6333
+6334
+6335
+6336
+6337
+6338
+6339
+6340
+6341
+6342
+6343
+6344
+6345
+6346
+6347
+6348
+6349
+6350
+6351
+6352
+6353
+6354
+6355
+6356
+6357
+6358
+6359
+6360
+6361
+6362
+6363
+6364
+6365
+6366
+6367
+6368
+6369
+6370
+6371
+6372
+6373
+6374
+6375
+6376
+6377
+6378
+6379
+6380
+6381
+6382
+6383
+6384
+6385
+6386
+6387
+6388
+6389
+6390
+6391
+6392
+6393
+6394
+6395
+6396
+6397
+6398
+6399
+6400
+6401
+6402
+6403
+6404
+6405
+6406
+6407
+6408
+6409
+6410
+6411
+6412
+6413
+6414
+6415
+6416
+6417
+6418
+6419
+6420
+6421
+6422
+6423
+6424
+6425
+6426
+6427
+6428
+6429
+6430
+6431
+6432
+6433
+6434
+6435
+6436
+6437
+6438
+6439
+6440
+6441
+6442
+6443
+6444
+6445
+6446
+6447
+6448
+6449
+6450
+6451
+6452
+6453
+6454
+6455
+6456
+6457
+6458
+6459
+6460
+6461
+6462
+6463
+6464
+6465
+6466
+6467
+6468
+6469
+6470
+6471
+6472
+6473
+6474
+6475
+6476
+6477
+6478
+6479
+6480
+6481
+6482
+6483
+6484
+6485
+6486
+6487
+6488
+6489
+6490
+6491
+6492
+6493
+6494
+6495
+6496
+6497
+6498
+6499
+6500
+6501
+6502
+6503
+6504
+6505
+6506
+6507
+6508
+6509
+6510
+6511
+6512
+6513
+6514
+6515
+6516
+6517
+6518
+6519
+6520
+6521
+6522
+6523
+6524
+6525
+6526
+6527
+6528
+6529
+6530
+6531
+6532
+6533
+6534
+6535
+6536
+6537
+6538
+6539
+6540
+6541
+6542
+6543
+6544
+6545
+6546
+6547
+6548
+6549
+6550
+6551
+6552
+6553
+6554
+6555
+6556
+6557
+6558
+6559
+6560
+6561
+6562
+6563
+6564
+6565
+6566
+6567
+6568
+6569
+6570
+6571
+6572
+6573
+6574
+6575
+6576
+6577
+6578
+6579
+6580
+6581
+6582
+6583
+6584
+6585
+6586
+6587
+6588
+6589
+6590
+6591
+6592
+6593
+6594
+6595
+6596
+6597
+6598
+6599
+6600
+6601
+6602
+6603
+6604
+6605
+6606
+6607
+6608
+6609
+6610
+6611
+6612
+6613
+6614
+6615
+6616
+6617
+6618
+6619
+6620
+6621
+6622
+6623
+6624
+6625
+6626
+6627
+6628
+6629
+6630
+6631
+6632
+6633
+6634
+6635
+6636
+6637
+6638
+6639
+6640
+6641
+6642
+6643
+6644
+6645
+6646
+6647
+6648
+6649
+6650
+6651
+6652
+6653
+6654
+6655
+6656
+6657
+6658
+6659
+6660
+6661
+6662
+6663
+6664
+6665
+6666
+6667
+6668
+6669
+6670
+6671
+6672
+6673
+6674
+6675
+6676
+6677
+6678
+6679
+6680
+6681
+6682
+6683
+6684
+6685
+6686
+6687
+6688
+6689
+6690
+6691
+6692
+6693
+6694
+6695
+6696
+6697
+6698
+6699
+6700
+6701
+6702
+6703
+6704
+6705
+6706
+6707
+6708
+6709
+6710
+6711
+6712
+6713
+6714
+6715
+6716
+6717
+6718
+6719
+6720
+6721
+6722
+6723
+6724
+6725
+6726
+6727
+6728
+6729
+6730
+6731
+6732
+6733
+6734
+6735
+6736
+6737
+6738
+6739
+6740
+6741
+6742
+6743
+6744
+6745
+6746
+6747
+6748
+6749
+6750
+6751
+6752
+6753
+6754
+6755
+6756
+6757
+6758
+6759
+6760
+6761
+6762
+6763
+6764
+6765
+6766
+6767
+6768
+6769
+6770
+6771
+6772
+6773
+6774
+6775
+6776
+6777
+6778
+6779
+6780
+6781
+6782
+6783
+6784
+6785
+6786
+6787
+6788
+6789
+6790
+6791
+6792
+6793
+6794
+6795
+6796
+6797
+6798
+6799
+6800
+6801
+6802
+6803
+6804
+6805
+6806
+6807
+6808
+6809
+6810
+6811
+6812
+6813
+6814
+6815
+6816
+6817
+6818
+6819
+6820
+6821
+6822
+6823
+6824
+6825
+6826
+6827
+6828
+6829
+6830
+6831
+6832
+6833
+6834
+6835
+6836
+6837
+6838
+6839
+6840
+6841
+6842
+6843
+6844
+6845
+6846
+6847
+6848
+6849
+6850
+6851
+6852
+6853
+6854
+6855
+6856
+6857
+6858
+6859
+6860
+6861
+6862
+6863
+6864
+6865
+6866
+6867
+6868
+6869
+6870
+6871
+6872
+6873
+6874
+6875
+6876
+6877
+6878
+6879
+6880
+6881
+6882
+6883
+6884
+6885
+6886
+6887
+6888
+6889
+6890
+6891
+6892
+6893
+6894
+6895
+6896
+6897
+6898
+6899
+6900
+6901
+6902
+6903
+6904
+6905
+6906
+6907
+6908
+6909
+6910
+6911
+6912
+6913
+6914
+6915
+6916
+6917
+6918
+6919
+6920
+6921
+6922
+6923
+6924
+6925
+6926
+6927
+6928
+6929
+6930
+6931
+6932
+6933
+6934
+6935
+6936
+6937
+6938
+6939
+6940
+6941
+6942
+6943
+6944
+6945
+6946
+6947
+6948
+6949
+6950
+6951
+6952
+6953
+6954
+6955
+6956
+6957
+6958
+6959
+6960
+6961
+6962
+6963
+6964
+6965
+6966
+6967
+6968
+6969
+6970
+6971
+6972
+6973
+6974
+6975
+6976
+6977
+6978
+6979
+6980
+6981
+6982
+6983
+6984
+6985
+6986
+6987
+6988
+6989
+6990
+6991
+6992
+6993
+6994
+6995
+6996
+6997
+6998
+6999
+7000
+7001
+7002
+7003
+7004
+7005
+7006
+7007
+7008
+7009
+7010
+7011
+7012
+7013
+7014
+7015
+7016
+7017
+7018
+7019
+7020
+7021
+7022
+7023
+7024
+7025
+7026
+7027
+7028
+7029
+7030
+7031
+7032
+7033
+7034
+7035
+7036
+7037
+7038
+7039
+7040
+7041
+7042
+7043
+7044
+7045
+7046
+7047
+7048
+7049
+7050
+7051
+7052
+7053
+7054
+7055
+7056
+7057
+7058
+7059
+7060
+7061
+7062
+7063
+7064
+7065
+7066
+7067
+7068
+7069
+7070
+7071
+7072
+7073
+7074
+7075
+7076
+7077
+7078
+7079
+7080
+7081
+7082
+7083
+7084
+7085
+7086
+7087
+7088
+7089
+7090
+7091
+7092
+7093
+7094
+7095
+7096
+7097
+7098
+7099
+7100
+7101
+7102
+7103
+7104
+7105
+7106
+7107
+7108
+7109
+7110
+7111
+7112
+7113
+7114
+7115
+7116
+7117
+7118
+7119
+7120
+7121
+7122
+7123
+7124
+7125
+7126
+7127
+7128
+7129
+7130
+7131
+7132
+7133
+7134
+7135
+7136
+7137
+7138
+7139
+7140
+7141
+7142
+7143
+7144
+7145
+7146
+7147
+7148
+7149
+7150
+7151
+7152
+7153
+7154
+7155
+7156
+7157
+7158
+7159
+7160
+7161
+7162
+7163
+7164
+7165
+7166
+7167
+7168
+7169
+7170
+7171
+7172
+7173
+7174
+7175
+7176
+7177
+7178
+7179
+7180
+7181
+7182
+7183
+7184
+7185
+7186
+7187
+7188
+7189
+7190
+7191
+7192
+7193
+7194
+7195
+7196
+7197
+7198
+7199
+7200
+7201
+7202
+7203
+7204
+7205
+7206
+7207
+7208
+7209
+7210
+7211
+7212
+7213
+7214
+7215
+7216
+7217
+7218
+7219
+7220
+7221
+7222
+7223
+7224
+7225
+7226
+7227
+7228
+7229
+7230
+7231
+7232
+7233
+7234
+7235
+7236
+7237
+7238
+7239
+7240
+7241
+7242
+7243
+7244
+7245
+7246
+7247
+7248
+7249
+7250
+7251
+7252
+7253
+7254
+7255
+7256
+7257
+7258
+7259
+7260
+7261
+7262
+7263
+7264
+7265
+7266
+7267
+7268
+7269
+7270
+7271
+7272
+7273
+7274
+7275
+7276
+7277
+7278
+7279
+7280
+7281
+7282
+7283
+7284
+7285
+7286
+7287
+7288
+7289
+7290
+7291
+7292
+7293
+7294
+7295
+7296
+7297
+7298
+7299
+7300
+7301
+7302
+7303
+7304
+7305
+7306
+7307
+7308
+7309
+7310
+7311
+7312
+7313
+7314
+7315
+7316
+7317
+7318
+7319
+7320
+7321
+7322
+7323
+7324
+7325
+7326
+7327
+7328
+7329
+7330
+7331
+7332
+7333
+7334
+7335
+7336
+7337
+7338
+7339
+7340
+7341
+7342
+7343
+7344
+7345
+7346
+7347
+7348
+7349
+7350
+7351
+7352
+7353
+7354
+7355
+7356
+7357
+7358
+7359
+7360
+7361
+7362
+7363
+7364
+7365
+7366
+7367
+7368
+7369
+7370
+7371
+7372
+7373
+7374
+7375
+7376
+7377
+7378
+7379
+7380
+7381
+7382
+7383
+7384
+7385
+7386
+7387
+7388
+7389
+7390
+7391
+7392
+7393
+7394
+7395
+7396
+7397
+7398
+7399
+7400
+7401
+7402
+7403
+7404
+7405
+7406
+7407
+7408
+7409
+7410
+7411
+7412
+7413
+7414
+7415
+7416
+7417
+7418
+7419
+7420
+7421
+7422
+7423
+7424
+7425
+7426
+7427
+7428
+7429
+7430
+7431
+7432
+7433
+7434
+7435
+7436
+7437
+7438
+7439
+7440
+7441
+7442
+7443
+7444
+7445
+7446
+7447
+7448
+7449
+7450
+7451
+7452
+7453
+7454
+7455
+7456
+7457
+7458
+7459
+7460
+7461
+7462
+7463
+7464
+7465
+7466
+7467
+7468
+7469
+7470
+7471
+7472
+7473
+7474
+7475
+7476
+7477
+7478
+7479
+7480
+7481
+7482
+7483
+7484
+7485
+7486
+7487
+7488
+7489
+7490
+7491
+7492
+7493
+7494
+7495
+7496
+7497
+7498
+7499
+7500
+7501
+7502
+7503
+7504
+7505
+7506
+7507
+7508
+7509
+7510
+7511
+7512
+7513
+7514
+7515
+7516
+7517
+7518
+7519
+7520
+7521
+7522
+7523
+7524
+7525
+7526
+7527
+7528
+7529
+7530
+7531
+7532
+7533
+7534
+7535
+7536
+7537
+7538
+7539
+7540
+7541
+7542
+7543
+7544
+7545
+7546
+7547
+7548
+7549
+7550
+7551
+7552
+7553
+7554
+7555
+7556
+7557
+7558
+7559
+7560
+7561
+7562
+7563
+7564
+7565
+7566
+7567
+7568
+7569
+7570
+7571
+7572
+7573
+7574
+7575
+7576
+7577
+7578
+7579
+7580
+7581
+7582
+7583
+7584
+7585
+7586
+7587
+7588
+7589
+7590
+7591
+7592
+7593
+7594
+7595
+7596
+7597
+7598
+7599
+7600
+7601
+7602
+7603
+7604
+7605
+7606
+7607
+7608
+7609
+7610
+7611
+7612
+7613
+7614
+7615
+7616
+7617
+7618
+7619
+7620
+7621
+7622
+7623
+7624
+7625
+7626
+7627
+7628
+7629
+7630
+7631
+7632
+7633
+7634
+7635
+7636
+7637
+7638
+7639
+7640
+7641
+7642
+7643
+7644
+7645
+7646
+7647
+7648
+7649
+7650
+7651
+7652
+7653
+7654
+7655
+7656
+7657
+7658
+7659
+7660
+7661
+7662
+7663
+7664
+7665
+7666
+7667
+7668
+7669
+7670
+7671
+7672
+7673
+7674
+7675
+7676
+7677
+7678
+7679
+7680
+7681
+7682
+7683
+7684
+7685
+7686
+7687
+7688
+7689
+7690
+7691
+7692
+7693
+7694
+7695
+7696
+7697
+7698
+7699
+7700
+7701
+7702
+7703
+7704
+7705
+7706
+7707
+7708
+7709
+7710
+7711
+7712
+7713
+7714
+7715
+7716
+7717
+7718
+7719
+7720
+7721
+7722
+7723
+7724
+7725
+7726
+7727
+7728
+7729
+7730
+7731
+7732
+7733
+7734
+7735
+7736
+7737
+7738
+7739
+7740
+7741
+7742
+7743
+7744
+7745
+7746
+7747
+7748
+7749
+7750
+7751
+7752
+7753
+7754
+7755
+7756
+7757
+7758
+7759
+7760
+7761
+7762
+7763
+7764
+7765
+7766
+7767
+7768
+7769
+7770
+7771
+7772
+7773
+7774
+7775
+7776
+7777
+7778
+7779
+7780
+7781
+7782
+7783
+7784
+7785
+7786
+7787
+7788
+7789
+7790
+7791
+7792
+7793
+7794
+7795
+7796
+7797
+7798
+7799
+7800
+7801
+7802
+7803
+7804
+7805
+7806
+7807
+7808
+7809
+7810
+7811
+7812
+7813
+7814
+7815
+7816
+7817
+7818
+7819
+7820
+7821
+7822
+7823
+7824
+7825
+7826
+7827
+7828
+7829
+7830
+7831
+7832
+7833
+7834
+7835
+7836
+7837
+7838
+7839
+7840
+7841
+7842
+7843
+7844
+7845
+7846
+7847
+7848
+7849
+7850
+7851
+7852
+7853
+7854
+7855
+7856
+7857
+7858
+7859
+7860
+7861
+7862
+7863
+7864
+7865
+7866
+7867
+7868
+7869
+7870
+7871
+7872
+7873
+7874
+7875
+7876
+7877
+7878
+7879
+7880
+7881
+7882
+7883
+7884
+7885
+7886
+7887
+7888
+7889
+7890
+7891
+7892
+7893
+7894
+7895
+7896
+7897
+7898
+7899
+7900
+7901
+7902
+7903
+7904
+7905
+7906
+7907
+7908
+7909
+7910
+7911
+7912
+7913
+7914
+7915
+7916
+7917
+7918
+7919
+7920
+7921
+7922
+7923
+7924
+7925
+7926
+7927
+7928
+7929
+7930
+7931
+7932
+7933
+7934
+7935
+7936
+7937
+7938
+7939
+7940
+7941
+7942
+7943
+7944
+7945
+7946
+7947
+7948
+7949
+7950
+7951
+7952
+7953
+7954
+7955
+7956
+7957
+7958
+7959
+7960
+7961
+7962
+7963
+7964
+7965
+7966
+7967
+7968
+7969
+7970
+7971
+7972
+7973
+7974
+7975
+7976
+7977
+7978
+7979
+7980
+7981
+7982
+7983
+7984
+7985
+7986
+7987
+7988
+7989
+7990
+7991
+7992
+7993
+7994
+7995
+7996
+7997
+7998
+7999
+8000
+8001
+8002
+8003
+8004
+8005
+8006
+8007
+8008
+8009
+8010
+8011
+8012
+8013
+8014
+8015
+8016
+8017
+8018
+8019
+8020
+8021
+8022
+8023
+8024
+8025
+8026
+8027
+8028
+8029
+8030
+8031
+8032
+8033
+8034
+8035
+8036
+8037
+8038
+8039
+8040
+8041
+8042
+8043
+8044
+8045
+8046
+8047
+8048
+8049
+8050
+8051
+8052
+8053
+8054
+8055
+8056
+8057
+8058
+8059
+8060
+8061
+8062
+8063
+8064
+8065
+8066
+8067
+8068
+8069
+8070
+8071
+8072
+8073
+8074
+8075
+8076
+8077
+8078
+8079
+8080
+8081
+8082
+8083
+8084
+8085
+8086
+8087
+8088
+8089
+8090
+8091
+8092
+8093
+8094
+8095
+8096
+8097
+8098
+8099
+8100
+8101
+8102
+8103
+8104
+8105
+8106
+8107
+8108
+8109
+8110
+8111
+8112
+8113
+8114
+8115
+8116
+8117
+8118
+8119
+8120
+8121
+8122
+8123
+8124
+8125
+8126
+8127
+8128
+8129
+8130
+8131
+8132
+8133
+8134
+8135
+8136
+8137
+8138
+8139
+8140
+8141
+8142
+8143
+8144
+8145
+8146
+8147
+8148
+8149
+8150
+8151
+8152
+8153
+8154
+8155
+8156
+8157
+8158
+8159
+8160
+8161
+8162
+8163
+8164
+8165
+8166
+8167
+8168
+8169
+8170
+8171
+8172
+8173
+8174
+8175
+8176
+8177
+8178
+8179
+8180
+8181
+8182
+8183
+8184
+8185
+8186
+8187
+8188
+8189
+8190
+8191
+8192
+8193
+8194
+8195
+8196
+8197
+8198
+8199
+8200
+8201
+8202
+8203
+8204
+8205
+8206
+8207
+8208
+8209
+8210
+8211
+8212
+8213
+8214
+8215
+8216
+8217
+8218
+8219
+8220
+8221
+8222
+8223
+8224
+8225
+8226
+8227
+8228
+8229
+8230
+8231
+8232
+8233
+8234
+8235
+8236
+8237
+8238
+8239
+8240
+8241
+8242
+8243
+8244
+8245
+8246
+8247
+8248
+8249
+8250
+8251
+8252
+8253
+8254
+8255
+8256
+8257
+8258
+8259
+8260
+8261
+8262
+8263
+8264
+8265
+8266
+8267
+8268
+8269
+8270
+8271
+8272
+8273
+8274
+8275
+8276
+8277
+8278
+8279
+8280
+8281
+8282
+8283
+8284
+8285
+8286
+8287
+8288
+8289
+8290
+8291
+8292
+8293
+8294
+8295
+8296
+8297
+8298
+8299
+8300
+8301
+8302
+8303
+8304
+8305
+8306
+8307
+8308
+8309
+8310
+8311
+8312
+8313
+8314
+8315
+8316
+8317
+8318
+8319
+8320
+8321
+8322
+8323
+8324
+8325
+8326
+8327
+8328
+8329
+8330
+8331
+8332
+8333
+8334
+8335
+8336
+8337
+8338
+8339
+8340
+8341
+8342
+8343
+8344
+8345
+8346
+8347
+8348
+8349
+8350
+8351
+8352
+8353
+8354
+8355
+8356
+8357
+8358
+8359
+8360
+8361
+8362
+8363
+8364
+8365
+8366
+8367
+8368
+8369
+8370
+8371
+8372
+8373
+8374
+8375
+8376
+8377
+8378
+8379
+8380
+8381
+8382
+8383
+8384
+8385
+8386
+8387
+8388
+8389
+8390
+8391
+8392
+8393
+8394
+8395
+8396
+8397
+8398
+8399
+8400
+8401
+8402
+8403
+8404
+8405
+8406
+8407
+8408
+8409
+8410
+8411
+8412
+8413
+8414
+8415
+8416
+8417
+8418
+8419
+8420
+8421
+8422
+8423
+8424
+8425
+8426
+8427
+8428
+8429
+8430
+8431
+8432
+8433
+8434
+8435
+8436
+8437
+8438
+8439
+8440
+8441
+8442
+8443
+8444
+8445
+8446
+8447
+8448
+8449
+8450
+8451
+8452
+8453
+8454
+8455
+8456
+8457
+8458
+8459
+8460
+8461
+8462
+8463
+8464
+8465
+8466
+8467
+8468
+8469
+8470
+8471
+8472
+8473
+8474
+8475
+8476
+8477
+8478
+8479
+8480
+8481
+8482
+8483
+8484
+8485
+8486
+8487
+8488
+8489
+8490
+8491
+8492
+8493
+8494
+8495
+8496
+8497
+8498
+8499
+8500
+8501
+8502
+8503
+8504
+8505
+8506
+8507
+8508
+8509
+8510
+8511
+8512
+8513
+8514
+8515
+8516
+8517
+8518
+8519
+8520
+8521
+8522
+8523
+8524
+8525
+8526
+8527
+8528
+8529
+8530
+8531
+8532
+8533
+8534
+8535
+8536
+8537
+8538
+8539
+8540
+8541
+8542
+8543
+8544
+8545
+8546
+8547
+8548
+8549
+8550
+8551
+8552
+8553
+8554
+8555
+8556
+8557
+8558
+8559
+8560
+8561
+8562
+8563
+8564
+8565
+8566
+8567
+8568
+8569
+8570
+8571
+8572
+8573
+8574
+8575
+8576
+8577
+8578
+8579
+8580
+8581
+8582
+8583
+8584
+8585
+8586
+8587
+8588
+8589
+8590
+8591
+8592
+8593
+8594
+8595
+8596
+8597
+8598
+8599
+8600
+8601
+8602
+8603
+8604
+8605
+8606
+8607
+8608
+8609
+8610
+8611
+8612
+8613
+8614
+8615
+8616
+8617
+8618
+8619
+8620
+8621
+8622
+8623
+8624
+8625
+8626
+8627
+8628
+8629
+8630
+8631
+8632
+8633
+8634
+8635
+8636
+8637
+8638
+8639
+8640
+8641
+8642
+8643
+8644
+8645
+8646
+8647
+8648
+8649
+8650
+8651
+8652
+8653
+8654
+8655
+8656
+8657
+8658
+8659
+8660
+8661
+8662
+8663
+8664
+8665
+8666
+8667
+8668
+8669
+8670
+8671
+8672
+8673
+8674
+8675
+8676
+8677
+8678
+8679
+8680
+8681
+8682
+8683
+8684
+8685
+8686
+8687
+8688
+8689
+8690
+8691
+8692
+8693
+8694
+8695
+8696
+8697
+8698
+8699
+8700
+8701
+8702
+8703
+8704
+8705
+8706
+8707
+8708
+8709
+8710
+8711
+8712
+8713
+8714
+8715
+8716
+8717
+8718
+8719
+8720
+8721
+8722
+8723
+8724
+8725
+8726
+8727
+8728
+8729
+8730
+8731
+8732
+8733
+8734
+8735
+8736
+8737
+8738
+8739
+8740
+8741
+8742
+8743
+8744
+8745
+8746
+8747
+8748
+8749
+8750
+8751
+8752
+8753
+8754
+8755
+8756
+8757
+8758
+8759
+8760
+8761
+8762
+8763
+8764
+8765
+8766
+8767
+8768
+8769
+8770
+8771
+8772
+8773
+8774
+8775
+8776
+8777
+8778
+8779
+8780
+8781
+8782
+8783
+8784
+8785
+8786
+8787
+8788
+8789
+8790
+8791
+8792
+8793
+8794
+8795
+8796
+8797
+8798
+8799
+8800
+8801
+8802
+8803
+8804
+8805
+8806
+8807
+8808
+8809
+8810
+8811
+8812
+8813
+8814
+8815
+8816
+8817
+8818
+8819
+8820
+8821
+8822
+8823
+8824
+8825
+8826
+8827
+8828
+8829
+8830
+8831
+8832
+8833
+8834
+8835
+8836
+8837
+8838
+8839
+8840
+8841
+8842
+8843
+8844
+8845
+8846
+8847
+8848
+8849
+8850
+8851
+8852
+8853
+8854
+8855
+8856
+8857
+8858
+8859
+8860
+8861
+8862
+8863
+8864
+8865
+8866
+8867
+8868
+8869
+8870
+8871
+8872
+8873
+8874
+8875
+8876
+8877
+8878
+8879
+8880
+8881
+8882
+8883
+8884
+8885
+8886
+8887
+8888
+8889
+8890
+8891
+8892
+8893
+8894
+8895
+8896
+8897
+8898
+8899
+8900
+8901
+8902
+8903
+8904
+8905
+8906
+8907
+8908
+8909
+8910
+8911
+8912
+8913
+8914
+8915
+8916
+8917
+8918
+8919
+8920
+8921
+8922
+8923
+8924
+8925
+8926
+8927
+8928
+8929
+8930
+8931
+8932
+8933
+8934
+8935
+8936
+8937
+8938
+8939
+8940
+8941
+8942
+8943
+8944
+8945
+8946
+8947
+8948
+8949
+8950
+8951
+8952
+8953
+8954
+8955
+8956
+8957
+8958
+8959
+8960
+8961
+8962
+8963
+8964
+8965
+8966
+8967
+8968
+8969
+8970
+8971
+8972
+8973
+8974
+8975
+8976
+8977
+8978
+8979
+8980
+8981
+8982
+8983
+8984
+8985
+8986
+8987
+8988
+8989
+8990
+8991
+8992
+8993
+8994
+8995
+8996
+8997
+8998
+8999
+9000
+9001
+9002
+9003
+9004
+9005
+9006
+9007
+9008
+9009
+9010
+9011
+9012
+9013
+9014
+9015
+9016
+9017
+9018
+9019
+9020
+9021
+9022
+9023
+9024
+9025
+9026
+9027
+9028
+9029
+9030
+9031
+9032
+9033
+9034
+9035
+9036
+9037
+9038
+9039
+9040
+9041
+9042
+9043
+9044
+9045
+9046
+9047
+9048
+9049
+9050
+9051
+9052
+9053
+9054
+9055
+9056
+9057
+9058
+9059
+9060
+9061
+9062
+9063
+9064
+9065
+9066
+9067
+9068
+9069
+9070
+9071
+9072
+9073
+9074
+9075
+9076
+9077
+9078
+9079
+9080
+9081
+9082
+9083
+9084
+9085
+9086
+9087
+9088
+9089
+9090
+9091
+9092
+9093
+9094
+9095
+9096
+9097
+9098
+9099
+9100
+9101
+9102
+9103
+9104
+9105
+9106
+9107
+9108
+9109
+9110
+9111
+9112
+9113
+9114
+9115
+9116
+9117
+9118
+9119
+9120
+9121
+9122
+9123
+9124
+9125
+9126
+9127
+9128
+9129
+9130
+9131
+9132
+9133
+9134
+9135
+9136
+9137
+9138
+9139
+9140
+9141
+9142
+9143
+9144
+9145
+9146
+9147
+9148
+9149
+9150
+9151
+9152
+9153
+9154
+9155
+9156
+9157
+9158
+9159
+9160
+9161
+9162
+9163
+9164
+9165
+9166
+9167
+9168
+9169
+9170
+9171
+9172
+9173
+9174
+9175
+9176
+9177
+9178
+9179
+9180
+9181
+9182
+9183
+9184
+9185
+9186
+9187
+9188
+9189
+9190
+9191
+9192
+9193
+9194
+9195
+9196
+9197
+9198
+9199
+9200
+9201
+9202
+9203
+9204
+9205
+9206
+9207
+9208
+9209
+9210
+9211
+9212
+9213
+9214
+9215
+9216
+9217
+9218
+9219
+9220
+9221
+9222
+9223
+9224
+9225
+9226
+9227
+9228
+9229
+9230
+9231
+9232
+9233
+9234
+9235
+9236
+9237
+9238
+9239
+9240
+9241
+9242
+9243
+9244
+9245
+9246
+9247
+9248
+9249
+9250
+9251
+9252
+9253
+9254
+9255
+9256
+9257
+9258
+9259
+9260
+9261
+9262
+9263
+9264
+9265
+9266
+9267
+9268
+9269
+9270
+9271
+9272
+9273
+9274
+9275
+9276
+9277
+9278
+9279
+9280
+9281
+9282
+9283
+9284
+9285
+9286
+9287
+9288
+9289
+9290
+9291
+9292
+9293
+9294
+9295
+9296
+9297
+9298
+9299
+9300
+9301
+9302
+9303
+9304
+9305
+9306
+9307
+9308
+9309
+9310
+9311
+9312
+9313
+9314
+9315
+9316
+9317
+9318
+9319
+9320
+9321
+9322
+9323
+9324
+9325
+9326
+9327
+9328
+9329
+9330
+9331
+9332
+9333
+9334
+9335
+9336
+9337
+9338
+9339
+9340
+9341
+9342
+9343
+9344
+9345
+9346
+9347
+9348
+9349
+9350
+9351
+9352
+9353
+9354
+9355
+9356
+9357
+9358
+9359
+9360
+9361
+9362
+9363
+9364
+9365
+9366
+9367
+9368
+9369
+9370
+9371
+9372
+9373
+9374
+9375
+9376
+9377
+9378
+9379
+9380
+9381
+9382
+9383
+9384
+9385
+9386
+9387
+9388
+9389
+9390
+9391
+9392
+9393
+9394
+9395
+9396
+9397
+9398
+9399
+9400
+9401
+9402
+9403
+9404
+9405
+9406
+9407
+9408
+9409
+9410
+9411
+9412
+9413
+9414
+9415
+9416
+9417
+9418
+9419
+9420
+9421
+9422
+9423
+9424
+9425
+9426
+9427
+9428
+9429
+9430
+9431
+9432
+9433
+9434
+9435
+9436
+9437
+9438
+9439
+9440
+9441
+9442
+9443
+9444
+9445
+9446
+9447
+9448
+9449
+9450
+9451
+9452
+9453
+9454
+9455
+9456
+9457
+9458
+9459
+9460
+9461
+9462
+9463
+9464
+9465
+9466
+9467
+9468
+9469
+9470
+9471
+9472
+9473
+9474
+9475
+9476
+9477
+9478
+9479
+9480
+9481
+9482
+9483
+9484
+9485
+9486
+9487
+9488
+9489
+9490
+9491
+9492
+9493
+9494
+9495
+9496
+9497
+9498
+9499
+9500
+9501
+9502
+9503
+9504
+9505
+9506
+9507
+9508
+9509
+9510
+9511
+9512
+9513
+9514
+9515
+9516
+9517
+9518
+9519
+9520
+9521
+9522
+9523
+9524
+9525
+9526
+9527
+9528
+9529
+9530
+9531
+9532
+9533
+9534
+9535
+9536
+9537
+9538
+9539
+9540
+9541
+9542
+9543
+9544
+9545
+9546
+9547
+9548
+9549
+9550
+9551
+9552
+9553
+9554
+9555
+9556
+9557
+9558
+9559
+9560
+9561
+9562
+9563
+9564
+9565
+9566
+9567
+9568
+9569
+9570
+9571
+9572
+9573
+9574
+9575
+9576
+9577
+9578
+9579
+9580
+9581
+9582
+9583
+9584
+9585
+9586
+9587
+9588
+9589
+9590
+9591
+9592
+9593
+9594
+9595
+9596
+9597
+9598
+9599
+9600
+9601
+9602
+9603
+9604
+9605
+9606
+9607
+9608
+9609
+9610
+9611
+9612
+9613
+9614
+9615
+9616
+9617
+9618
+9619
+9620
+9621
+9622
+9623
+9624
+9625
+9626
+9627
+9628
+9629
+9630
+9631
+9632
+9633
+9634
+9635
+9636
+9637
+9638
+9639
+9640
+9641
+9642
+9643
+9644
+9645
+9646
+9647
+9648
+9649
+9650
+9651
+9652
+9653
+9654
+9655
+9656
+9657
+9658
+9659
+9660
+9661
+9662
+9663
+9664
+9665
+9666
+9667
+9668
+9669
+9670
+9671
+9672
+9673
+9674
+9675
+9676
+9677
+9678
+9679
+9680
+9681
+9682
+9683
+9684
+9685
+9686
+9687
+9688
+9689
+9690
+9691
+9692
+9693
+9694
+9695
+9696
+9697
+9698
+9699
+9700
+9701
+9702
+9703
+9704
+9705
+9706
+9707
+9708
+9709
+9710
+9711
+9712
+9713
+9714
+9715
+9716
+9717
+9718
+9719
+9720
+9721
+9722
+9723
+9724
+9725
+9726
+9727
+9728
+9729
+9730
+9731
+9732
+9733
+9734
+9735
+9736
+9737
+9738
+9739
+9740
+9741
+9742
+9743
+9744
+9745
+9746
+9747
+9748
+9749
+9750
+9751
+9752
+9753
+9754
+9755
+9756
+9757
+9758
+9759
+9760
+9761
+9762
+9763
+9764
+9765
+9766
+9767
+9768
+9769
+9770
+9771
+9772
+9773
+9774
+9775
+9776
+9777
+9778
+9779
+9780
+9781
+9782
+9783
+9784
+9785
+9786
+9787
+9788
+9789
+9790
+9791
+9792
+9793
+9794
+9795
+9796
+9797
+9798
+9799
+9800
+9801
+9802
+9803
+9804
+9805
+9806
+9807
+9808
+9809
+9810
+9811
+9812
+9813
+9814
+9815
+9816
+9817
+9818
+9819
+9820
+9821
+9822
+9823
+9824
+9825
+9826
+9827
+9828
+9829
+9830
+9831
+9832
+9833
+9834
+9835
+9836
+9837
+9838
+9839
+9840
+9841
+9842
+9843
+9844
+9845
+9846
+9847
+9848
+9849
+9850
+9851
+9852
+9853
+9854
+9855
+9856
+9857
+9858
+9859
+9860
+9861
+9862
+9863
+9864
+9865
+9866
+9867
+9868
+9869
+9870
+9871
+9872
+9873
+9874
+9875
+9876
+9877
+9878
+9879
+9880
+9881
+9882
+9883
+9884
+9885
+9886
+9887
+9888
+9889
+9890
+9891
+9892
+9893
+9894
+9895
+9896
+9897
+9898
+9899
+9900
+9901
+9902
+9903
+9904
+9905
+9906
+9907
+9908
+9909
+9910
+9911
+9912
+9913
+9914
+9915
+9916
+9917
+9918
+9919
+9920
+9921
+9922
+9923
+9924
+9925
+9926
+9927
+9928
+9929
+9930
+9931
+9932
+9933
+9934
+9935
+9936
+9937
+9938
+9939
+9940
+9941
+9942
+9943
+9944
+9945
+9946
+9947
+9948
+9949
+9950
+9951
+9952
+9953
+9954
+9955
+9956
+9957
+9958
+9959
+9960
+9961
+9962
+9963
+9964
+9965
+9966
+9967
+9968
+9969
+9970
+9971
+9972
+9973
+9974
+9975
+9976
+9977
+9978
+9979
+9980
+9981
+9982
+9983
+9984
+9985
+9986
+9987
+9988
+9989
+9990
+9991
+9992
+9993
+9994
+9995
+9996
+9997
+9998
+9999
+10000
diff --git a/mysql-test/std_data/bug30435_5k.txt b/mysql-test/std_data/bug30435_5k.txt
new file mode 100644
index 00000000000..7d1714969fc
--- /dev/null
+++ b/mysql-test/std_data/bug30435_5k.txt
@@ -0,0 +1,5000 @@
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+2180
+2181
+2182
+2183
+2184
+2185
+2186
+2187
+2188
+2189
+2190
+2191
+2192
+2193
+2194
+2195
+2196
+2197
+2198
+2199
+2200
+2201
+2202
+2203
+2204
+2205
+2206
+2207
+2208
+2209
+2210
+2211
+2212
+2213
+2214
+2215
+2216
+2217
+2218
+2219
+2220
+2221
+2222
+2223
+2224
+2225
+2226
+2227
+2228
+2229
+2230
+2231
+2232
+2233
+2234
+2235
+2236
+2237
+2238
+2239
+2240
+2241
+2242
+2243
+2244
+2245
+2246
+2247
+2248
+2249
+2250
+2251
+2252
+2253
+2254
+2255
+2256
+2257
+2258
+2259
+2260
+2261
+2262
+2263
+2264
+2265
+2266
+2267
+2268
+2269
+2270
+2271
+2272
+2273
+2274
+2275
+2276
+2277
+2278
+2279
+2280
+2281
+2282
+2283
+2284
+2285
+2286
+2287
+2288
+2289
+2290
+2291
+2292
+2293
+2294
+2295
+2296
+2297
+2298
+2299
+2300
+2301
+2302
+2303
+2304
+2305
+2306
+2307
+2308
+2309
+2310
+2311
+2312
+2313
+2314
+2315
+2316
+2317
+2318
+2319
+2320
+2321
+2322
+2323
+2324
+2325
+2326
+2327
+2328
+2329
+2330
+2331
+2332
+2333
+2334
+2335
+2336
+2337
+2338
+2339
+2340
+2341
+2342
+2343
+2344
+2345
+2346
+2347
+2348
+2349
+2350
+2351
+2352
+2353
+2354
+2355
+2356
+2357
+2358
+2359
+2360
+2361
+2362
+2363
+2364
+2365
+2366
+2367
+2368
+2369
+2370
+2371
+2372
+2373
+2374
+2375
+2376
+2377
+2378
+2379
+2380
+2381
+2382
+2383
+2384
+2385
+2386
+2387
+2388
+2389
+2390
+2391
+2392
+2393
+2394
+2395
+2396
+2397
+2398
+2399
+2400
+2401
+2402
+2403
+2404
+2405
+2406
+2407
+2408
+2409
+2410
+2411
+2412
+2413
+2414
+2415
+2416
+2417
+2418
+2419
+2420
+2421
+2422
+2423
+2424
+2425
+2426
+2427
+2428
+2429
+2430
+2431
+2432
+2433
+2434
+2435
+2436
+2437
+2438
+2439
+2440
+2441
+2442
+2443
+2444
+2445
+2446
+2447
+2448
+2449
+2450
+2451
+2452
+2453
+2454
+2455
+2456
+2457
+2458
+2459
+2460
+2461
+2462
+2463
+2464
+2465
+2466
+2467
+2468
+2469
+2470
+2471
+2472
+2473
+2474
+2475
+2476
+2477
+2478
+2479
+2480
+2481
+2482
+2483
+2484
+2485
+2486
+2487
+2488
+2489
+2490
+2491
+2492
+2493
+2494
+2495
+2496
+2497
+2498
+2499
+2500
+2501
+2502
+2503
+2504
+2505
+2506
+2507
+2508
+2509
+2510
+2511
+2512
+2513
+2514
+2515
+2516
+2517
+2518
+2519
+2520
+2521
+2522
+2523
+2524
+2525
+2526
+2527
+2528
+2529
+2530
+2531
+2532
+2533
+2534
+2535
+2536
+2537
+2538
+2539
+2540
+2541
+2542
+2543
+2544
+2545
+2546
+2547
+2548
+2549
+2550
+2551
+2552
+2553
+2554
+2555
+2556
+2557
+2558
+2559
+2560
+2561
+2562
+2563
+2564
+2565
+2566
+2567
+2568
+2569
+2570
+2571
+2572
+2573
+2574
+2575
+2576
+2577
+2578
+2579
+2580
+2581
+2582
+2583
+2584
+2585
+2586
+2587
+2588
+2589
+2590
+2591
+2592
+2593
+2594
+2595
+2596
+2597
+2598
+2599
+2600
+2601
+2602
+2603
+2604
+2605
+2606
+2607
+2608
+2609
+2610
+2611
+2612
+2613
+2614
+2615
+2616
+2617
+2618
+2619
+2620
+2621
+2622
+2623
+2624
+2625
+2626
+2627
+2628
+2629
+2630
+2631
+2632
+2633
+2634
+2635
+2636
+2637
+2638
+2639
+2640
+2641
+2642
+2643
+2644
+2645
+2646
+2647
+2648
+2649
+2650
+2651
+2652
+2653
+2654
+2655
+2656
+2657
+2658
+2659
+2660
+2661
+2662
+2663
+2664
+2665
+2666
+2667
+2668
+2669
+2670
+2671
+2672
+2673
+2674
+2675
+2676
+2677
+2678
+2679
+2680
+2681
+2682
+2683
+2684
+2685
+2686
+2687
+2688
+2689
+2690
+2691
+2692
+2693
+2694
+2695
+2696
+2697
+2698
+2699
+2700
+2701
+2702
+2703
+2704
+2705
+2706
+2707
+2708
+2709
+2710
+2711
+2712
+2713
+2714
+2715
+2716
+2717
+2718
+2719
+2720
+2721
+2722
+2723
+2724
+2725
+2726
+2727
+2728
+2729
+2730
+2731
+2732
+2733
+2734
+2735
+2736
+2737
+2738
+2739
+2740
+2741
+2742
+2743
+2744
+2745
+2746
+2747
+2748
+2749
+2750
+2751
+2752
+2753
+2754
+2755
+2756
+2757
+2758
+2759
+2760
+2761
+2762
+2763
+2764
+2765
+2766
+2767
+2768
+2769
+2770
+2771
+2772
+2773
+2774
+2775
+2776
+2777
+2778
+2779
+2780
+2781
+2782
+2783
+2784
+2785
+2786
+2787
+2788
+2789
+2790
+2791
+2792
+2793
+2794
+2795
+2796
+2797
+2798
+2799
+2800
+2801
+2802
+2803
+2804
+2805
+2806
+2807
+2808
+2809
+2810
+2811
+2812
+2813
+2814
+2815
+2816
+2817
+2818
+2819
+2820
+2821
+2822
+2823
+2824
+2825
+2826
+2827
+2828
+2829
+2830
+2831
+2832
+2833
+2834
+2835
+2836
+2837
+2838
+2839
+2840
+2841
+2842
+2843
+2844
+2845
+2846
+2847
+2848
+2849
+2850
+2851
+2852
+2853
+2854
+2855
+2856
+2857
+2858
+2859
+2860
+2861
+2862
+2863
+2864
+2865
+2866
+2867
+2868
+2869
+2870
+2871
+2872
+2873
+2874
+2875
+2876
+2877
+2878
+2879
+2880
+2881
+2882
+2883
+2884
+2885
+2886
+2887
+2888
+2889
+2890
+2891
+2892
+2893
+2894
+2895
+2896
+2897
+2898
+2899
+2900
+2901
+2902
+2903
+2904
+2905
+2906
+2907
+2908
+2909
+2910
+2911
+2912
+2913
+2914
+2915
+2916
+2917
+2918
+2919
+2920
+2921
+2922
+2923
+2924
+2925
+2926
+2927
+2928
+2929
+2930
+2931
+2932
+2933
+2934
+2935
+2936
+2937
+2938
+2939
+2940
+2941
+2942
+2943
+2944
+2945
+2946
+2947
+2948
+2949
+2950
+2951
+2952
+2953
+2954
+2955
+2956
+2957
+2958
+2959
+2960
+2961
+2962
+2963
+2964
+2965
+2966
+2967
+2968
+2969
+2970
+2971
+2972
+2973
+2974
+2975
+2976
+2977
+2978
+2979
+2980
+2981
+2982
+2983
+2984
+2985
+2986
+2987
+2988
+2989
+2990
+2991
+2992
+2993
+2994
+2995
+2996
+2997
+2998
+2999
+3000
+3001
+3002
+3003
+3004
+3005
+3006
+3007
+3008
+3009
+3010
+3011
+3012
+3013
+3014
+3015
+3016
+3017
+3018
+3019
+3020
+3021
+3022
+3023
+3024
+3025
+3026
+3027
+3028
+3029
+3030
+3031
+3032
+3033
+3034
+3035
+3036
+3037
+3038
+3039
+3040
+3041
+3042
+3043
+3044
+3045
+3046
+3047
+3048
+3049
+3050
+3051
+3052
+3053
+3054
+3055
+3056
+3057
+3058
+3059
+3060
+3061
+3062
+3063
+3064
+3065
+3066
+3067
+3068
+3069
+3070
+3071
+3072
+3073
+3074
+3075
+3076
+3077
+3078
+3079
+3080
+3081
+3082
+3083
+3084
+3085
+3086
+3087
+3088
+3089
+3090
+3091
+3092
+3093
+3094
+3095
+3096
+3097
+3098
+3099
+3100
+3101
+3102
+3103
+3104
+3105
+3106
+3107
+3108
+3109
+3110
+3111
+3112
+3113
+3114
+3115
+3116
+3117
+3118
+3119
+3120
+3121
+3122
+3123
+3124
+3125
+3126
+3127
+3128
+3129
+3130
+3131
+3132
+3133
+3134
+3135
+3136
+3137
+3138
+3139
+3140
+3141
+3142
+3143
+3144
+3145
+3146
+3147
+3148
+3149
+3150
+3151
+3152
+3153
+3154
+3155
+3156
+3157
+3158
+3159
+3160
+3161
+3162
+3163
+3164
+3165
+3166
+3167
+3168
+3169
+3170
+3171
+3172
+3173
+3174
+3175
+3176
+3177
+3178
+3179
+3180
+3181
+3182
+3183
+3184
+3185
+3186
+3187
+3188
+3189
+3190
+3191
+3192
+3193
+3194
+3195
+3196
+3197
+3198
+3199
+3200
+3201
+3202
+3203
+3204
+3205
+3206
+3207
+3208
+3209
+3210
+3211
+3212
+3213
+3214
+3215
+3216
+3217
+3218
+3219
+3220
+3221
+3222
+3223
+3224
+3225
+3226
+3227
+3228
+3229
+3230
+3231
+3232
+3233
+3234
+3235
+3236
+3237
+3238
+3239
+3240
+3241
+3242
+3243
+3244
+3245
+3246
+3247
+3248
+3249
+3250
+3251
+3252
+3253
+3254
+3255
+3256
+3257
+3258
+3259
+3260
+3261
+3262
+3263
+3264
+3265
+3266
+3267
+3268
+3269
+3270
+3271
+3272
+3273
+3274
+3275
+3276
+3277
+3278
+3279
+3280
+3281
+3282
+3283
+3284
+3285
+3286
+3287
+3288
+3289
+3290
+3291
+3292
+3293
+3294
+3295
+3296
+3297
+3298
+3299
+3300
+3301
+3302
+3303
+3304
+3305
+3306
+3307
+3308
+3309
+3310
+3311
+3312
+3313
+3314
+3315
+3316
+3317
+3318
+3319
+3320
+3321
+3322
+3323
+3324
+3325
+3326
+3327
+3328
+3329
+3330
+3331
+3332
+3333
+3334
+3335
+3336
+3337
+3338
+3339
+3340
+3341
+3342
+3343
+3344
+3345
+3346
+3347
+3348
+3349
+3350
+3351
+3352
+3353
+3354
+3355
+3356
+3357
+3358
+3359
+3360
+3361
+3362
+3363
+3364
+3365
+3366
+3367
+3368
+3369
+3370
+3371
+3372
+3373
+3374
+3375
+3376
+3377
+3378
+3379
+3380
+3381
+3382
+3383
+3384
+3385
+3386
+3387
+3388
+3389
+3390
+3391
+3392
+3393
+3394
+3395
+3396
+3397
+3398
+3399
+3400
+3401
+3402
+3403
+3404
+3405
+3406
+3407
+3408
+3409
+3410
+3411
+3412
+3413
+3414
+3415
+3416
+3417
+3418
+3419
+3420
+3421
+3422
+3423
+3424
+3425
+3426
+3427
+3428
+3429
+3430
+3431
+3432
+3433
+3434
+3435
+3436
+3437
+3438
+3439
+3440
+3441
+3442
+3443
+3444
+3445
+3446
+3447
+3448
+3449
+3450
+3451
+3452
+3453
+3454
+3455
+3456
+3457
+3458
+3459
+3460
+3461
+3462
+3463
+3464
+3465
+3466
+3467
+3468
+3469
+3470
+3471
+3472
+3473
+3474
+3475
+3476
+3477
+3478
+3479
+3480
+3481
+3482
+3483
+3484
+3485
+3486
+3487
+3488
+3489
+3490
+3491
+3492
+3493
+3494
+3495
+3496
+3497
+3498
+3499
+3500
+3501
+3502
+3503
+3504
+3505
+3506
+3507
+3508
+3509
+3510
+3511
+3512
+3513
+3514
+3515
+3516
+3517
+3518
+3519
+3520
+3521
+3522
+3523
+3524
+3525
+3526
+3527
+3528
+3529
+3530
+3531
+3532
+3533
+3534
+3535
+3536
+3537
+3538
+3539
+3540
+3541
+3542
+3543
+3544
+3545
+3546
+3547
+3548
+3549
+3550
+3551
+3552
+3553
+3554
+3555
+3556
+3557
+3558
+3559
+3560
+3561
+3562
+3563
+3564
+3565
+3566
+3567
+3568
+3569
+3570
+3571
+3572
+3573
+3574
+3575
+3576
+3577
+3578
+3579
+3580
+3581
+3582
+3583
+3584
+3585
+3586
+3587
+3588
+3589
+3590
+3591
+3592
+3593
+3594
+3595
+3596
+3597
+3598
+3599
+3600
+3601
+3602
+3603
+3604
+3605
+3606
+3607
+3608
+3609
+3610
+3611
+3612
+3613
+3614
+3615
+3616
+3617
+3618
+3619
+3620
+3621
+3622
+3623
+3624
+3625
+3626
+3627
+3628
+3629
+3630
+3631
+3632
+3633
+3634
+3635
+3636
+3637
+3638
+3639
+3640
+3641
+3642
+3643
+3644
+3645
+3646
+3647
+3648
+3649
+3650
+3651
+3652
+3653
+3654
+3655
+3656
+3657
+3658
+3659
+3660
+3661
+3662
+3663
+3664
+3665
+3666
+3667
+3668
+3669
+3670
+3671
+3672
+3673
+3674
+3675
+3676
+3677
+3678
+3679
+3680
+3681
+3682
+3683
+3684
+3685
+3686
+3687
+3688
+3689
+3690
+3691
+3692
+3693
+3694
+3695
+3696
+3697
+3698
+3699
+3700
+3701
+3702
+3703
+3704
+3705
+3706
+3707
+3708
+3709
+3710
+3711
+3712
+3713
+3714
+3715
+3716
+3717
+3718
+3719
+3720
+3721
+3722
+3723
+3724
+3725
+3726
+3727
+3728
+3729
+3730
+3731
+3732
+3733
+3734
+3735
+3736
+3737
+3738
+3739
+3740
+3741
+3742
+3743
+3744
+3745
+3746
+3747
+3748
+3749
+3750
+3751
+3752
+3753
+3754
+3755
+3756
+3757
+3758
+3759
+3760
+3761
+3762
+3763
+3764
+3765
+3766
+3767
+3768
+3769
+3770
+3771
+3772
+3773
+3774
+3775
+3776
+3777
+3778
+3779
+3780
+3781
+3782
+3783
+3784
+3785
+3786
+3787
+3788
+3789
+3790
+3791
+3792
+3793
+3794
+3795
+3796
+3797
+3798
+3799
+3800
+3801
+3802
+3803
+3804
+3805
+3806
+3807
+3808
+3809
+3810
+3811
+3812
+3813
+3814
+3815
+3816
+3817
+3818
+3819
+3820
+3821
+3822
+3823
+3824
+3825
+3826
+3827
+3828
+3829
+3830
+3831
+3832
+3833
+3834
+3835
+3836
+3837
+3838
+3839
+3840
+3841
+3842
+3843
+3844
+3845
+3846
+3847
+3848
+3849
+3850
+3851
+3852
+3853
+3854
+3855
+3856
+3857
+3858
+3859
+3860
+3861
+3862
+3863
+3864
+3865
+3866
+3867
+3868
+3869
+3870
+3871
+3872
+3873
+3874
+3875
+3876
+3877
+3878
+3879
+3880
+3881
+3882
+3883
+3884
+3885
+3886
+3887
+3888
+3889
+3890
+3891
+3892
+3893
+3894
+3895
+3896
+3897
+3898
+3899
+3900
+3901
+3902
+3903
+3904
+3905
+3906
+3907
+3908
+3909
+3910
+3911
+3912
+3913
+3914
+3915
+3916
+3917
+3918
+3919
+3920
+3921
+3922
+3923
+3924
+3925
+3926
+3927
+3928
+3929
+3930
+3931
+3932
+3933
+3934
+3935
+3936
+3937
+3938
+3939
+3940
+3941
+3942
+3943
+3944
+3945
+3946
+3947
+3948
+3949
+3950
+3951
+3952
+3953
+3954
+3955
+3956
+3957
+3958
+3959
+3960
+3961
+3962
+3963
+3964
+3965
+3966
+3967
+3968
+3969
+3970
+3971
+3972
+3973
+3974
+3975
+3976
+3977
+3978
+3979
+3980
+3981
+3982
+3983
+3984
+3985
+3986
+3987
+3988
+3989
+3990
+3991
+3992
+3993
+3994
+3995
+3996
+3997
+3998
+3999
+4000
+4001
+4002
+4003
+4004
+4005
+4006
+4007
+4008
+4009
+4010
+4011
+4012
+4013
+4014
+4015
+4016
+4017
+4018
+4019
+4020
+4021
+4022
+4023
+4024
+4025
+4026
+4027
+4028
+4029
+4030
+4031
+4032
+4033
+4034
+4035
+4036
+4037
+4038
+4039
+4040
+4041
+4042
+4043
+4044
+4045
+4046
+4047
+4048
+4049
+4050
+4051
+4052
+4053
+4054
+4055
+4056
+4057
+4058
+4059
+4060
+4061
+4062
+4063
+4064
+4065
+4066
+4067
+4068
+4069
+4070
+4071
+4072
+4073
+4074
+4075
+4076
+4077
+4078
+4079
+4080
+4081
+4082
+4083
+4084
+4085
+4086
+4087
+4088
+4089
+4090
+4091
+4092
+4093
+4094
+4095
+4096
+4097
+4098
+4099
+4100
+4101
+4102
+4103
+4104
+4105
+4106
+4107
+4108
+4109
+4110
+4111
+4112
+4113
+4114
+4115
+4116
+4117
+4118
+4119
+4120
+4121
+4122
+4123
+4124
+4125
+4126
+4127
+4128
+4129
+4130
+4131
+4132
+4133
+4134
+4135
+4136
+4137
+4138
+4139
+4140
+4141
+4142
+4143
+4144
+4145
+4146
+4147
+4148
+4149
+4150
+4151
+4152
+4153
+4154
+4155
+4156
+4157
+4158
+4159
+4160
+4161
+4162
+4163
+4164
+4165
+4166
+4167
+4168
+4169
+4170
+4171
+4172
+4173
+4174
+4175
+4176
+4177
+4178
+4179
+4180
+4181
+4182
+4183
+4184
+4185
+4186
+4187
+4188
+4189
+4190
+4191
+4192
+4193
+4194
+4195
+4196
+4197
+4198
+4199
+4200
+4201
+4202
+4203
+4204
+4205
+4206
+4207
+4208
+4209
+4210
+4211
+4212
+4213
+4214
+4215
+4216
+4217
+4218
+4219
+4220
+4221
+4222
+4223
+4224
+4225
+4226
+4227
+4228
+4229
+4230
+4231
+4232
+4233
+4234
+4235
+4236
+4237
+4238
+4239
+4240
+4241
+4242
+4243
+4244
+4245
+4246
+4247
+4248
+4249
+4250
+4251
+4252
+4253
+4254
+4255
+4256
+4257
+4258
+4259
+4260
+4261
+4262
+4263
+4264
+4265
+4266
+4267
+4268
+4269
+4270
+4271
+4272
+4273
+4274
+4275
+4276
+4277
+4278
+4279
+4280
+4281
+4282
+4283
+4284
+4285
+4286
+4287
+4288
+4289
+4290
+4291
+4292
+4293
+4294
+4295
+4296
+4297
+4298
+4299
+4300
+4301
+4302
+4303
+4304
+4305
+4306
+4307
+4308
+4309
+4310
+4311
+4312
+4313
+4314
+4315
+4316
+4317
+4318
+4319
+4320
+4321
+4322
+4323
+4324
+4325
+4326
+4327
+4328
+4329
+4330
+4331
+4332
+4333
+4334
+4335
+4336
+4337
+4338
+4339
+4340
+4341
+4342
+4343
+4344
+4345
+4346
+4347
+4348
+4349
+4350
+4351
+4352
+4353
+4354
+4355
+4356
+4357
+4358
+4359
+4360
+4361
+4362
+4363
+4364
+4365
+4366
+4367
+4368
+4369
+4370
+4371
+4372
+4373
+4374
+4375
+4376
+4377
+4378
+4379
+4380
+4381
+4382
+4383
+4384
+4385
+4386
+4387
+4388
+4389
+4390
+4391
+4392
+4393
+4394
+4395
+4396
+4397
+4398
+4399
+4400
+4401
+4402
+4403
+4404
+4405
+4406
+4407
+4408
+4409
+4410
+4411
+4412
+4413
+4414
+4415
+4416
+4417
+4418
+4419
+4420
+4421
+4422
+4423
+4424
+4425
+4426
+4427
+4428
+4429
+4430
+4431
+4432
+4433
+4434
+4435
+4436
+4437
+4438
+4439
+4440
+4441
+4442
+4443
+4444
+4445
+4446
+4447
+4448
+4449
+4450
+4451
+4452
+4453
+4454
+4455
+4456
+4457
+4458
+4459
+4460
+4461
+4462
+4463
+4464
+4465
+4466
+4467
+4468
+4469
+4470
+4471
+4472
+4473
+4474
+4475
+4476
+4477
+4478
+4479
+4480
+4481
+4482
+4483
+4484
+4485
+4486
+4487
+4488
+4489
+4490
+4491
+4492
+4493
+4494
+4495
+4496
+4497
+4498
+4499
+4500
+4501
+4502
+4503
+4504
+4505
+4506
+4507
+4508
+4509
+4510
+4511
+4512
+4513
+4514
+4515
+4516
+4517
+4518
+4519
+4520
+4521
+4522
+4523
+4524
+4525
+4526
+4527
+4528
+4529
+4530
+4531
+4532
+4533
+4534
+4535
+4536
+4537
+4538
+4539
+4540
+4541
+4542
+4543
+4544
+4545
+4546
+4547
+4548
+4549
+4550
+4551
+4552
+4553
+4554
+4555
+4556
+4557
+4558
+4559
+4560
+4561
+4562
+4563
+4564
+4565
+4566
+4567
+4568
+4569
+4570
+4571
+4572
+4573
+4574
+4575
+4576
+4577
+4578
+4579
+4580
+4581
+4582
+4583
+4584
+4585
+4586
+4587
+4588
+4589
+4590
+4591
+4592
+4593
+4594
+4595
+4596
+4597
+4598
+4599
+4600
+4601
+4602
+4603
+4604
+4605
+4606
+4607
+4608
+4609
+4610
+4611
+4612
+4613
+4614
+4615
+4616
+4617
+4618
+4619
+4620
+4621
+4622
+4623
+4624
+4625
+4626
+4627
+4628
+4629
+4630
+4631
+4632
+4633
+4634
+4635
+4636
+4637
+4638
+4639
+4640
+4641
+4642
+4643
+4644
+4645
+4646
+4647
+4648
+4649
+4650
+4651
+4652
+4653
+4654
+4655
+4656
+4657
+4658
+4659
+4660
+4661
+4662
+4663
+4664
+4665
+4666
+4667
+4668
+4669
+4670
+4671
+4672
+4673
+4674
+4675
+4676
+4677
+4678
+4679
+4680
+4681
+4682
+4683
+4684
+4685
+4686
+4687
+4688
+4689
+4690
+4691
+4692
+4693
+4694
+4695
+4696
+4697
+4698
+4699
+4700
+4701
+4702
+4703
+4704
+4705
+4706
+4707
+4708
+4709
+4710
+4711
+4712
+4713
+4714
+4715
+4716
+4717
+4718
+4719
+4720
+4721
+4722
+4723
+4724
+4725
+4726
+4727
+4728
+4729
+4730
+4731
+4732
+4733
+4734
+4735
+4736
+4737
+4738
+4739
+4740
+4741
+4742
+4743
+4744
+4745
+4746
+4747
+4748
+4749
+4750
+4751
+4752
+4753
+4754
+4755
+4756
+4757
+4758
+4759
+4760
+4761
+4762
+4763
+4764
+4765
+4766
+4767
+4768
+4769
+4770
+4771
+4772
+4773
+4774
+4775
+4776
+4777
+4778
+4779
+4780
+4781
+4782
+4783
+4784
+4785
+4786
+4787
+4788
+4789
+4790
+4791
+4792
+4793
+4794
+4795
+4796
+4797
+4798
+4799
+4800
+4801
+4802
+4803
+4804
+4805
+4806
+4807
+4808
+4809
+4810
+4811
+4812
+4813
+4814
+4815
+4816
+4817
+4818
+4819
+4820
+4821
+4822
+4823
+4824
+4825
+4826
+4827
+4828
+4829
+4830
+4831
+4832
+4833
+4834
+4835
+4836
+4837
+4838
+4839
+4840
+4841
+4842
+4843
+4844
+4845
+4846
+4847
+4848
+4849
+4850
+4851
+4852
+4853
+4854
+4855
+4856
+4857
+4858
+4859
+4860
+4861
+4862
+4863
+4864
+4865
+4866
+4867
+4868
+4869
+4870
+4871
+4872
+4873
+4874
+4875
+4876
+4877
+4878
+4879
+4880
+4881
+4882
+4883
+4884
+4885
+4886
+4887
+4888
+4889
+4890
+4891
+4892
+4893
+4894
+4895
+4896
+4897
+4898
+4899
+4900
+4901
+4902
+4903
+4904
+4905
+4906
+4907
+4908
+4909
+4910
+4911
+4912
+4913
+4914
+4915
+4916
+4917
+4918
+4919
+4920
+4921
+4922
+4923
+4924
+4925
+4926
+4927
+4928
+4929
+4930
+4931
+4932
+4933
+4934
+4935
+4936
+4937
+4938
+4939
+4940
+4941
+4942
+4943
+4944
+4945
+4946
+4947
+4948
+4949
+4950
+4951
+4952
+4953
+4954
+4955
+4956
+4957
+4958
+4959
+4960
+4961
+4962
+4963
+4964
+4965
+4966
+4967
+4968
+4969
+4970
+4971
+4972
+4973
+4974
+4975
+4976
+4977
+4978
+4979
+4980
+4981
+4982
+4983
+4984
+4985
+4986
+4987
+4988
+4989
+4990
+4991
+4992
+4993
+4994
+4995
+4996
+4997
+4998
+4999
+5000
diff --git a/mysql-test/t/binlog.test b/mysql-test/t/binlog.test
index 5d1399925c3..b35c81b3b18 100644
--- a/mysql-test/t/binlog.test
+++ b/mysql-test/t/binlog.test
@@ -106,4 +106,21 @@ drop table t1;
set global binlog_cache_size=@bcs;
set session autocommit = @ac;
+#
+# Bug#33798: prepared statements improperly handle large unsigned ints
+#
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+reset master;
+create table t1 (a bigint unsigned, b bigint(20) unsigned);
+prepare stmt from "insert into t1 values (?,?)";
+set @a= 9999999999999999;
+set @b= 14632475938453979136;
+execute stmt using @a, @b;
+deallocate prepare stmt;
+drop table t1;
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/
+show binlog events from 0;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/binlog_innodb.test b/mysql-test/t/binlog_innodb.test
index 2da7b2b0895..47b09719ef5 100644
--- a/mysql-test/t/binlog_innodb.test
+++ b/mysql-test/t/binlog_innodb.test
@@ -37,3 +37,28 @@ show status like "binlog_cache_disk_use";
drop table t1;
+#
+# Bug #30604: different flagging of time_zone_used in normal and ps-protocol
+#
+
+CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=MyISAM;
+CREATE TABLE t2 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
+
+DELIMITER |;
+# the function does not deal with time objects
+CREATE FUNCTION bug23333()
+RETURNS int(11)
+DETERMINISTIC
+BEGIN
+ INSERT INTO t1 VALUES (NULL);
+ SELECT COUNT(*) FROM t1 INTO @a;
+ RETURN @a;
+END|
+
+DELIMITER ;|
+
+INSERT INTO t2 VALUES (2),(10+bug23333());
+--replace_column 1 #
+SHOW MASTER STATUS;
+DROP FUNCTION bug23333;
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/binlog_start_comment.test b/mysql-test/t/binlog_start_comment.test
new file mode 100644
index 00000000000..84889167cd2
--- /dev/null
+++ b/mysql-test/t/binlog_start_comment.test
@@ -0,0 +1,24 @@
+# Test case for bug#32205 Replaying statements from mysqlbinlog fails
+# with a syntax error, replicates fine
+
+source include/have_log_bin.inc;
+source include/have_local_infile.inc;
+
+reset master;
+--disable_warnings
+drop table if exists t1,t2;
+--enable_warnings
+create table t1 (word varchar(20)) -- create table t1;
+create table t2 (word varchar(20)) -- create table t2;
+load data infile '../std_data_ln/words.dat' into table t1 -- load data to t1;
+insert into t2 values ("Ada");
+flush logs;
+select * from t2;
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_start_comment.binlog
+--exec $MYSQL --local-infile=1 < $MYSQLTEST_VARDIR/tmp/binlog_start_comment.binlog
+flush logs;
+select * from t2;
+
+# clean up
+drop table t1,t2;
+#--system rm $MYSQLTEST_VARDIR/tmp/binlog_start_comment.binlog
diff --git a/mysql-test/t/blackhole.test b/mysql-test/t/blackhole.test
index d8ffdeb8312..ba77b7b7f6a 100644
--- a/mysql-test/t/blackhole.test
+++ b/mysql-test/t/blackhole.test
@@ -128,6 +128,7 @@ select * from t3;
let $VERSION=`select version()`;
--replace_result $VERSION VERSION
--replace_column 2 # 5 #
+--replace_regex /file_id=[0-9]+/file_id=#/
show binlog events;
drop table t1,t2,t3;
diff --git a/mysql-test/t/compare.test b/mysql-test/t/compare.test
index 337035a8095..8863ed825c2 100644
--- a/mysql-test/t/compare.test
+++ b/mysql-test/t/compare.test
@@ -46,3 +46,34 @@ insert into t1 values (0x01,0x01);
select * from t1 where a=b;
select * from t1 where a=b and b=0x01;
drop table if exists t1;
+
+#
+# Bug #31887: DML Select statement not returning same results when executed
+# in version 5
+#
+
+CREATE TABLE t1 (b int(2) zerofill, c int(2) zerofill);
+INSERT INTO t1 (b,c) VALUES (1,2), (1,1), (2,2);
+
+SELECT CONCAT(b,c), CONCAT(b,c) = '0101' FROM t1;
+
+EXPLAIN EXTENDED SELECT b,c FROM t1 WHERE b = 1 AND CONCAT(b,c) = '0101';
+SELECT b,c FROM t1 WHERE b = 1 AND CONCAT(b,c) = '0101';
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (1),(2);
+
+SELECT a,
+ (SELECT COUNT(*) FROM t1
+ WHERE b = t2.a AND CONCAT(b,c) = CONCAT('0',t2.a,'01')) x
+FROM t2 ORDER BY a;
+
+EXPLAIN EXTENDED
+SELECT a,
+ (SELECT COUNT(*) FROM t1
+ WHERE b = t2.a AND CONCAT(b,c) = CONCAT('0',t2.a,'01')) x
+FROM t2 ORDER BY a;
+
+DROP TABLE t1,t2;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test
index 84c286e516b..87632fbdbb8 100644
--- a/mysql-test/t/func_gconcat.test
+++ b/mysql-test/t/func_gconcat.test
@@ -640,4 +640,21 @@ SELECT GROUP_CONCAT(DISTINCT b, a ORDER BY b) FROM t1;
DROP TABLE t1, t2, t3;
+#
+# Bug #34747: crash in debug assertion check after derived table
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (),();
+SELECT s1.d1 FROM
+(
+ SELECT
+ t1.a as d1,
+ GROUP_CONCAT(DISTINCT t1.a) AS d2
+ FROM
+ t1 AS t1,
+ t1 AS t2
+ GROUP BY 1
+) AS s1;
+DROP TABLE t1;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test
index ccb59df5677..17c147f7193 100644
--- a/mysql-test/t/func_misc.test
+++ b/mysql-test/t/func_misc.test
@@ -205,6 +205,24 @@ SELECT NAME_CONST('test', -1.0);
SELECT NAME_CONST('test', 'test');
#
+# Bug #34749: Server crash when using NAME_CONST() with an aggregate function
+#
+
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2),(3);
+# NAME_CONST() + aggregate.
+SELECT NAME_CONST('flag',1) * MAX(a) FROM t1;
+SELECT NAME_CONST('flag',1.5) * MAX(a) FROM t1;
+# Now, wrap the INT_ITEM in Item_func_neg and watch the pretty explosions
+SELECT NAME_CONST('flag',-1) * MAX(a) FROM t1;
+SELECT NAME_CONST('flag',-1.5) * MAX(a) FROM t1;
+--error ER_WRONG_ARGUMENTS
+SELECT NAME_CONST('flag', SQRT(4)) * MAX(a) FROM t1;
+--error ER_WRONG_ARGUMENTS
+SELECT NAME_CONST('flag',-SQRT(4)) * MAX(a) FROM t1;
+DROP TABLE t1;
+
+#
# Bug #27545: erroneous usage of NAME_CONST with a name as the first parameter
# resolved against a column name of a derived table hangs the client
#
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index b0f47e0ad56..ef22adb4251 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -336,7 +336,7 @@ select date_add(date,INTERVAL "1" QUARTER) from t1;
select timestampadd(MINUTE, 1, date) from t1;
select timestampadd(WEEK, 1, date) from t1;
select timestampadd(SQL_TSI_SECOND, 1, date) from t1;
-# Prepared statements doesn't support FRAC_SECOND yet
+# mysqltest.c discards an expected 'deprecated' warning on prepare stage
--disable_ps_protocol
select timestampadd(SQL_TSI_FRAC_SECOND, 1, date) from t1;
--enable_ps_protocol
@@ -351,7 +351,10 @@ select timestampdiff(SQL_TSI_HOUR, '2001-02-01', '2001-05-01') as a;
select timestampdiff(SQL_TSI_DAY, '2001-02-01', '2001-05-01') as a;
select timestampdiff(SQL_TSI_MINUTE, '2001-02-01 12:59:59', '2001-05-01 12:58:59') as a;
select timestampdiff(SQL_TSI_SECOND, '2001-02-01 12:59:59', '2001-05-01 12:58:58') as a;
+# mysqltest.c discards an expected 'deprecated' warning on prepare stage
+--disable_ps_protocol
select timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a;
+--enable_ps_protocol
select timestampdiff(SQL_TSI_DAY, '1986-02-01', '1986-03-01') as a1,
timestampdiff(SQL_TSI_DAY, '1900-02-01', '1900-03-01') as a2,
@@ -804,4 +807,26 @@ select DATE_ADD(20071108, INTERVAL 1 DAY);
select LAST_DAY('2007-12-06 08:59:19.05') - INTERVAL 1 SECOND;
+#
+# Bug#33834: FRAC_SECOND: Applicability not clear in documentation
+#
+# Show that he use of FRAC_SECOND, for anything other than
+# TIMESTAMPADD / TIMESTAMPDIFF, is a server error.
+
+# mysqltest.c discards an expected 'deprecated' warning on prepare stage
+--disable_ps_protocol
+SELECT TIMESTAMPADD(FRAC_SECOND, 1, '2008-02-18');
+SELECT TIMESTAMPDIFF(FRAC_SECOND, '2008-02-17', '2008-02-18');
+--enable_ps_protocol
+
+--error ER_PARSE_ERROR
+SELECT DATE_ADD('2008-02-18', INTERVAL 1 FRAC_SECOND);
+--error ER_PARSE_ERROR
+SELECT DATE_SUB('2008-02-18', INTERVAL 1 FRAC_SECOND);
+
+--error ER_PARSE_ERROR
+SELECT '2008-02-18' + INTERVAL 1 FRAC_SECOND;
+--error ER_PARSE_ERROR
+SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/grant3.test b/mysql-test/t/grant3.test
index fac577ef0ff..8eceb851c29 100644
--- a/mysql-test/t/grant3.test
+++ b/mysql-test/t/grant3.test
@@ -134,3 +134,29 @@ SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by
DROP USER CUser2@localhost;
DROP USER CUser2@LOCALHOST;
+
+
+#
+# Bug#31194: Privilege ordering does not order properly for wildcard values
+#
+
+CREATE DATABASE mysqltest_1;
+CREATE TABLE mysqltest_1.t1 (a INT);
+CREATE USER 'mysqltest1'@'%';
+GRANT SELECT, UPDATE ON `mysqltest_1`.* TO 'mysqltest1'@'%';
+REVOKE SELECT ON `mysqltest_1`.* FROM 'mysqltest1'@'%';
+GRANT SELECT, UPDATE ON `mysqltest\_1`.* TO 'mysqltest1'@'%';
+FLUSH PRIVILEGES;
+
+connect (conn1,localhost,mysqltest1,,);
+connection conn1;
+SHOW GRANTS;
+SELECT * FROM mysqltest_1.t1;
+disconnect conn1;
+
+connection default;
+DROP USER 'mysqltest1'@'%';
+DROP DATABASE mysqltest_1;
+
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test
index 020295684b0..59ee7c274bb 100644
--- a/mysql-test/t/innodb_mysql.test
+++ b/mysql-test/t/innodb_mysql.test
@@ -982,4 +982,18 @@ desc t1;
show create table t1;
drop table t1;
+
+#
+# Bug #34223: Assertion failed: (optp->var_type & 127) == 8,
+# file .\my_getopt.c, line 830
+#
+
+set @my_innodb_autoextend_increment=@@global.innodb_autoextend_increment;
+set global innodb_autoextend_increment=8;
+set global innodb_autoextend_increment=@my_innodb_autoextend_increment;
+
+set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
+set global innodb_commit_concurrency=0;
+set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/limit.test b/mysql-test/t/limit.test
index 286c04785ff..9cccca1adc3 100644
--- a/mysql-test/t/limit.test
+++ b/mysql-test/t/limit.test
@@ -76,15 +76,22 @@ drop table t1;
# Bug #28464: a string argument to 'limit ?' PS
#
-prepare s from "select 1 limit ?";
-set @a='qwe';
---error 1210
+prepare s from "select 1 limit ?";
+set @a='qwe';
+execute s using @a;
+set @a=-1;
+--error ER_WRONG_ARGUMENTS
execute s using @a;
prepare s from "select 1 limit 1, ?";
---error 1210
+--error ER_WRONG_ARGUMENTS
execute s using @a;
prepare s from "select 1 limit ?, ?";
---error 1210
+--error ER_WRONG_ARGUMENTS
+execute s using @a, @a;
+set @a=14632475938453979136;
+execute s using @a, @a;
+set @a=-14632475938453979136;
+--error ER_WRONG_ARGUMENTS
execute s using @a, @a;
--echo End of 5.0 tests
diff --git a/mysql-test/t/mix_innodb_myisam_binlog.test b/mysql-test/t/mix_innodb_myisam_binlog.test
index e0ce802254a..8ab639661b8 100644
--- a/mysql-test/t/mix_innodb_myisam_binlog.test
+++ b/mysql-test/t/mix_innodb_myisam_binlog.test
@@ -262,7 +262,8 @@ eval select
is not null;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
eval select
-@a like "%#%error_code=0%ROLLBACK/*!*/;%ROLLBACK /* added by mysqlbinlog */;%",
+@a like "%#%error_code=0%ROLLBACK\\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" OR
+@a like "%#%error_code=0%ROLLBACK\\r\\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%",
@a not like "%#%error_code=%error_code=%";
drop table t1, t2;
diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test
index c83fe94f2eb..5b4a43c8fe8 100644
--- a/mysql-test/t/mysqlbinlog.test
+++ b/mysql-test/t/mysqlbinlog.test
@@ -41,6 +41,7 @@ select "--- Local --" as "";
#
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLTEST_VARDIR/log/master-bin.000001
# this should not fail but shouldn't produce any working statements
@@ -48,6 +49,7 @@ select "--- Local --" as "";
select "--- Broken LOAD DATA --" as "";
--enable_query_log
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLTEST_VARDIR/log/master-bin.000002 2> /dev/null
# this should show almost nothing
@@ -55,6 +57,7 @@ select "--- Broken LOAD DATA --" as "";
select "--- --database --" as "";
--enable_query_log
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --database=nottest $MYSQLTEST_VARDIR/log/master-bin.000001 2> /dev/null
# this test for position option
@@ -62,6 +65,7 @@ select "--- --database --" as "";
select "--- --position --" as "";
--enable_query_log
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --position=231 $MYSQLTEST_VARDIR/log/master-bin.000002
# These are tests for remote binlog.
@@ -73,6 +77,7 @@ select "--- Remote --" as "";
# This is broken now
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
# This is broken too
@@ -80,6 +85,7 @@ select "--- Remote --" as "";
select "--- Broken LOAD DATA --" as "";
--enable_query_log
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 2> /dev/null
# And this too ! (altough it is documented)
@@ -87,6 +93,7 @@ select "--- Broken LOAD DATA --" as "";
select "--- --database --" as "";
--enable_query_log
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --database=nottest master-bin.000001 2> /dev/null
# Strangely but this works
@@ -94,6 +101,7 @@ select "--- --database --" as "";
select "--- --position --" as "";
--enable_query_log
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --position=231 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
# Bug#7853 (mysqlbinlog does not accept input from stdin)
@@ -101,9 +109,11 @@ select "--- --position --" as "";
select "--- reading stdin --" as "";
--enable_query_log
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form - < $MYSQL_TEST_DIR/std_data/trunc_binlog.000001
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --position=79 - < $MYSQL_TEST_DIR/std_data/trunc_binlog.000001
drop table t1,t2;
@@ -166,6 +176,7 @@ call p1();
drop procedure p1;
--error 1305
call p1();
+--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form $MYSQLTEST_VARDIR/log/master-bin.000007
--exec $MYSQL_BINLOG --short-form $MYSQLTEST_VARDIR/log/master-bin.000007 | $MYSQL
call p1();
@@ -201,6 +212,7 @@ select hex(a) from t1;
drop table t1;
flush logs;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLTEST_VARDIR/log/master-bin.000009
#
diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test
index 04e7b6b4bdb..8d5e1a1c4c5 100644
--- a/mysql-test/t/mysqlcheck.test
+++ b/mysql-test/t/mysqlcheck.test
@@ -40,4 +40,22 @@ create table `t 1`(a int);
--exec $MYSQL_CHECK --databases test
drop table `t``1`, `t 1`;
+#
+# Bug#25347: mysqlcheck -A -r doesn't repair table marked as crashed
+#
+create database d_bug25347;
+use d_bug25347;
+create table t_bug25347 (a int);
+create view v_bug25347 as select * from t_bug25347;
+flush tables;
+--echo removing and creating
+--remove_file $MYSQLTEST_VARDIR/master-data/d_bug25347/t_bug25347.MYI
+--write_file $MYSQLTEST_VARDIR/master-data/d_bug25347/t_bug25347.MYI
+EOF
+--exec $MYSQL_CHECK --repair --databases --use-frm d_bug25347
+drop view v_bug25347;
+drop table t_bug25347;
+drop database d_bug25347;
+use test;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/mysqldump-no-binlog-master.opt b/mysql-test/t/mysqldump-no-binlog-master.opt
new file mode 100644
index 00000000000..789275fa25e
--- /dev/null
+++ b/mysql-test/t/mysqldump-no-binlog-master.opt
@@ -0,0 +1 @@
+--skip-log-bin
diff --git a/mysql-test/t/mysqldump-no-binlog.test b/mysql-test/t/mysqldump-no-binlog.test
new file mode 100644
index 00000000000..434b2931792
--- /dev/null
+++ b/mysql-test/t/mysqldump-no-binlog.test
@@ -0,0 +1,6 @@
+# Embedded server doesn't support external clients
+--source include/not_embedded.inc
+
+--replace_regex /MASTER_LOG_POS=[0-9]+/XX/
+--error 2
+--exec $MYSQL_DUMP --compact --master-data=2 test 2>&1
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index ec188af0244..5856bfff036 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -2083,5 +2083,46 @@ eval $show_statement;
drop table t1;
+# ----------------------------------------------------------------------------
+# Test change_user command
+# ----------------------------------------------------------------------------
+
+--error 1
+--exec echo "--change_user root,,inexistent" | $MYSQL_TEST 2>&1
+
+--error 1
+--exec echo "--change_user inexistent,,test" | $MYSQL_TEST 2>&1
+
+--error 1
+--exec echo "--change_user root,inexistent,test" | $MYSQL_TEST 2>&1
+
+--change_user
+--change_user root
+--change_user root,,
+--change_user root,,test
+
+# ----------------------------------------------------------------------------
+# Test mkdir and rmdir command
+# ----------------------------------------------------------------------------
+
+mkdir $MYSQLTEST_VARDIR/tmp/testdir;
+rmdir $MYSQLTEST_VARDIR/tmp/testdir;
+
+# Directory already exist
+mkdir $MYSQLTEST_VARDIR/tmp/testdir;
+--error 1
+mkdir $MYSQLTEST_VARDIR/tmp/testdir;
+
+# Remove dir with file inside
+write_file $MYSQLTEST_VARDIR/tmp/testdir/file1.txt;
+hello
+EOF
+--error 1
+rmdir $MYSQLTEST_VARDIR/tmp/testdir;
+
+remove_file $MYSQLTEST_VARDIR/tmp/testdir/file1.txt;
+rmdir $MYSQLTEST_VARDIR/tmp/testdir;
+
+
--echo End of tests
diff --git a/mysql-test/t/ndb_alter_table2.test b/mysql-test/t/ndb_alter_table2.test
index 3861fcc6c9d..99c201f7370 100644
--- a/mysql-test/t/ndb_alter_table2.test
+++ b/mysql-test/t/ndb_alter_table2.test
@@ -81,3 +81,34 @@ select * from t1;
select * from t1;
drop table t1;
+
+#For BUG#29851 TRUNCATE causes error 4350 from cluster in INSERT... ON DUPLICATE KEY UPDATE
+
+connection con1;
+
+--disable_warnings
+DROP TABLE IF EXISTS truncate_test;
+--enable_warnings
+
+CREATE TABLE truncate_test (
+ i INT PRIMARY KEY,
+ a INT,
+ b VARCHAR(11),
+ UNIQUE KEY (a)
+) ENGINE = NDB;
+
+INSERT INTO truncate_test VALUES (1, 1, 'test') ON DUPLICATE KEY UPDATE b = 'new';
+INSERT INTO truncate_test VALUES (1, 1, 'test') ON DUPLICATE KEY UPDATE b = 'new';
+
+connection con2;
+TRUNCATE truncate_test;
+
+connection con1;
+INSERT INTO truncate_test VALUES (1, 1, 'test') ON DUPLICATE KEY UPDATE b = 'new';
+SELECT * FROM truncate_test;
+
+connection con2;
+INSERT INTO truncate_test VALUES (1, 1, 'test') ON DUPLICATE KEY UPDATE b = 'new';
+SELECT * FROM truncate_test;
+
+DROP TABLE truncate_test;
diff --git a/mysql-test/t/ndb_autodiscover.test b/mysql-test/t/ndb_autodiscover.test
index 6eb039c2df2..049dcd9755e 100644
--- a/mysql-test/t/ndb_autodiscover.test
+++ b/mysql-test/t/ndb_autodiscover.test
@@ -491,6 +491,7 @@ select * from t1;
select * from t1;
--exec $NDB_MGM --no-defaults -e "all start" > /dev/null
--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults > /dev/null
+--source include/ndb_wait_connected.inc
use test;
drop database test_only_ndb_tables;
diff --git a/mysql-test/t/ndb_autodiscover3.test b/mysql-test/t/ndb_autodiscover3.test
index 259da6e3501..4a20e7dd430 100644
--- a/mysql-test/t/ndb_autodiscover3.test
+++ b/mysql-test/t/ndb_autodiscover3.test
@@ -25,6 +25,13 @@ insert into t1 values (1);
--exec $NDB_MGM --no-defaults -e "all restart" >> $NDB_TOOLS_OUTPUT
--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults -c $connect_str >> $NDB_TOOLS_OUTPUT
+# Create separate connection and use that for detecting
+# when mysqld has reconnected to ndbd
+connect (ndb_wait_con,127.0.0.1,root,,test,$MASTER_MYPORT,);
+--source include/ndb_wait_connected.inc
+disconnect ndb_wait_con;
+connection server1;
+
--error 1297
insert into t1 values (2);
--error 1296
@@ -44,6 +51,7 @@ select * from t2 order by a limit 3;
--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults -c $connect_str >> $NDB_TOOLS_OUTPUT
--connection server2
+--source include/ndb_wait_connected.inc
create table t2 (a int key) engine=ndbcluster;
insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
select * from t2 order by a limit 3;
@@ -58,6 +66,7 @@ select * from t2 order by a limit 3;
--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults -c $connect_str >> $NDB_TOOLS_OUTPUT
--connection server1
+--source include/ndb_wait_connected.inc
show tables;
create table t2 (a int key) engine=ndbcluster;
insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
diff --git a/mysql-test/t/ndb_bug31477.test b/mysql-test/t/ndb_bug31477.test
new file mode 100644
index 00000000000..41c519e56fd
--- /dev/null
+++ b/mysql-test/t/ndb_bug31477.test
@@ -0,0 +1,109 @@
+--source include/have_ndb.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+# setup
+
+connect (con1,localhost,root,,test);
+connect (con2,localhost,root,,test);
+
+# unique index
+connection con1;
+create table t1(a int primary key, b int, c int, unique(b)) engine = ndb;
+insert into t1 values (2,2,2);
+insert into t1 values (3,3,3);
+insert into t1 values (4,4,4);
+
+begin;
+insert into t1 values (1,1,1);
+
+connection con2;
+begin;
+--error 1205
+update t1 set c = 2 where b = 1;
+rollback;
+
+connection con1;
+rollback;
+drop table t1;
+# ordered index
+
+connection con1;
+create table t1(a int primary key, b int, c int, key(b)) engine = ndb;
+insert into t1 values (2,2,2);
+insert into t1 values (3,3,3);
+insert into t1 values (4,4,4);
+
+begin;
+insert into t1 values (1,1,1);
+
+connection con2;
+begin;
+--error 1205
+update t1 set c = 2 where b = 1;
+rollback;
+
+connection con1;
+rollback;
+drop table t1;
+
+# multiple versions
+
+--echo --con1
+connection con1;
+create table t1(a int primary key, b int, c int, key(b)) engine = ndb;
+insert into t1 values (1,1,1);
+insert into t1 values (2,2,2);
+insert into t1 values (3,3,3);
+insert into t1 values (4,4,4);
+
+begin;
+update t1 set c = 10 where a = 1;
+update t1 set c = 20 where a = 1;
+update t1 set c = 30 where a = 1;
+
+--echo --con1 c=30
+select * from t1 where b >= 1 order by b;
+--echo --con2 c=1
+connection con2;
+select * from t1 where b >= 1 order by b;
+
+--echo --con1
+connection con1;
+delete from t1 where a = 1;
+
+--echo --con1 c=none
+select * from t1 where b >= 1 order by b;
+--echo --con2 c=1
+connection con2;
+select * from t1 where b >= 1 order by b;
+
+--echo --con1
+connection con1;
+commit;
+
+--echo --con1 c=none
+select * from t1 where b >= 1 order by b;
+--echo --con2 c=none
+connection con2;
+select * from t1 where b >= 1 order by b;
+
+--echo --con1
+connection con1;
+begin;
+insert into t1 values (1,1,1);
+update t1 set c = 10 where a = 1;
+update t1 set c = 20 where a = 1;
+update t1 set c = 30 where a = 1;
+
+--echo --con1 c=30
+select * from t1 where b >= 1 order by b;
+--echo --con2 c=none
+connection con2;
+select * from t1 where b >= 1 order by b;
+
+# this fails with "no such table" via con2 ???
+connection con1;
+drop table t1;
diff --git a/mysql-test/t/ndb_condition_pushdown.test b/mysql-test/t/ndb_condition_pushdown.test
index b5b7e41fb21..ebfd9c7231a 100644
--- a/mysql-test/t/ndb_condition_pushdown.test
+++ b/mysql-test/t/ndb_condition_pushdown.test
@@ -1719,6 +1719,7 @@ set engine_condition_pushdown = 1;
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
# bug#29390 (scan filter is too large, discarded)
+# bug#34107 (previous limit was too large for TUP)
drop table t1;
@@ -1737,9 +1738,11 @@ select a,b,d from t1
where b in (0,1,2,5)
order by b;
+--echo -- big filter just below limit
--disable_query_log
select a,b,d from t1
where b in (
+0,1,2,5,0,1,2,5,0,1,
0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
@@ -1870,745 +1873,15 @@ select a,b,d from t1
0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
-0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
+0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2)
+ order by b;
+--enable_query_log
+
+--echo -- big filter just above limit
+--disable_query_log
+select a,b,d from t1
+ where b in (
+0,1,2,5,0,1,2,5,0,1,2,
0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,5,0,1,2,
diff --git a/mysql-test/t/ndb_restore.test b/mysql-test/t/ndb_restore.test
index 266a0c7fbc1..940b53adbe1 100644
--- a/mysql-test/t/ndb_restore.test
+++ b/mysql-test/t/ndb_restore.test
@@ -231,16 +231,21 @@ select count(*)
select * from t10_c order by a;
# Bug #27775 cont'd
# - auto inc info should be correct
---replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X
-show table status like 't1_c';
---replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X
-show table status like 't2_c';
---replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X
-show table status like 't4_c';
---replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X
-show table status like 't7_c';
---replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X
-show table status like 't10_c';
+select max(capgoaledatta) from t1_c;
+select auto_increment from information_schema.tables
+where table_name = 't1_c';
+select max(capgotod) from t2_c;
+select auto_increment from information_schema.tables
+where table_name = 't2_c';
+select max(capfa) from t4_c;
+select auto_increment from information_schema.tables
+where table_name = 't4_c';
+select max(dardtestard) from t7_c;
+select auto_increment from information_schema.tables
+where table_name = 't7_c';
+select max(a) from t10_c;
+select auto_increment from information_schema.tables
+where table_name = 't10_c';
--disable_warnings
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9, t10;
diff --git a/mysql-test/t/null_key.test b/mysql-test/t/null_key.test
index e15aec01d2a..1400c643203 100644
--- a/mysql-test/t/null_key.test
+++ b/mysql-test/t/null_key.test
@@ -240,3 +240,26 @@ SHOW STATUS LIKE "handler_read%";
DROP TABLE t1,t2,t3,t4;
# End of 4.1 tests
+
+#
+# BUG#34945 "ref_or_null queries that are null_rejecting and have a null value crash mysql"
+#
+CREATE TABLE t1 (
+ a int(11) default NULL,
+ b int(11) default NULL,
+ KEY a (a,b)
+);
+INSERT INTO t1 VALUES (0,10),(0,11),(0,12);
+
+CREATE TABLE t2 (
+ a int(11) default NULL,
+ b int(11) default NULL,
+ KEY a (a)
+);
+INSERT INTO t2 VALUES (3,NULL),(3,11),(3,12);
+
+SELECT * FROM t2 inner join t1 WHERE ( t1.a = 0 OR t1.a IS NULL) AND t2.a = 3 AND t2.b = t1.b;
+
+drop table t1, t2;
+-- echo End of 5.0 tests
+
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index 29a290c7fbf..9a55c27df99 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -726,3 +726,15 @@ SELECT a, b FROM t1 ORDER BY b DESC;
SELECT a, b FROM t1 ORDER BY SEC_TO_TIME(a) DESC;
DROP TABLE t1;
+
+--echo #
+--echo # Bug#31590: Wrong error message on sort buffer being too small.
+--echo #
+create table t1(a int, b tinytext);
+insert into t1 values (1,2),(3,2);
+set session sort_buffer_size= 30000;
+set session max_sort_length= 2180;
+--error 1038
+select * from t1 order by b;
+drop table t1;
+
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index c1505ffd645..6c3f98f6a1a 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -1807,4 +1807,163 @@ execute stmt using @a;
show create table t1;
drop table t1;
+#
+# Bug#33798: prepared statements improperly handle large unsigned ints
+#
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a bigint unsigned, b bigint(20) unsigned);
+prepare stmt from "insert into t1 values (?,?)";
+set @a= 9999999999999999;
+set @b= 14632475938453979136;
+insert into t1 values (@a, @b);
+select * from t1 where a = @a and b = @b;
+execute stmt using @a, @b;
+select * from t1 where a = @a and b = @b;
+deallocate prepare stmt;
+drop table t1;
+
+#
+# Bug#32890 Crash after repeated create and drop of tables and views
+#
+
+--disable_warnings
+drop view if exists v1;
+drop table if exists t1;
+--enable_warnings
+
+create table t1 (a int, b int);
+insert into t1 values (1,1), (2,2), (3,3);
+insert into t1 values (3,1), (1,2), (2,3);
+
+prepare stmt from "create view v1 as select * from t1";
+execute stmt;
+drop table t1;
+create table t1 (a int, b int);
+drop view v1;
+execute stmt;
+show create view v1;
+drop view v1;
+
+prepare stmt from "create view v1 (c,d) as select a,b from t1";
+execute stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+
+prepare stmt from "create view v1 (c) as select b+1 from t1";
+execute stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+
+prepare stmt from "create view v1 (c,d,e,f) as select a,b,a in (select a+2 from t1), a = all (select a from t1) from t1";
+execute stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+
+prepare stmt from "create or replace view v1 as select 1";
+execute stmt;
+show create view v1;
+select * from v1;
+execute stmt;
+show create view v1;
+deallocate prepare stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+
+prepare stmt from "create view v1 as select 1, 1";
+execute stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+
+prepare stmt from "create view v1 (x) as select a from t1 where a > 1";
+execute stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+
+prepare stmt from "create view v1 as select * from `t1` `b`";
+execute stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+
+prepare stmt from "create view v1 (a,b,c) as select * from t1";
+--error ER_VIEW_WRONG_LIST
+execute stmt;
+--error ER_VIEW_WRONG_LIST
+execute stmt;
+deallocate prepare stmt;
+
+drop table t1;
+create temporary table t1 (a int, b int);
+
+prepare stmt from "create view v1 as select * from t1";
+--error ER_VIEW_SELECT_TMPTABLE
+execute stmt;
+--error ER_VIEW_SELECT_TMPTABLE
+execute stmt;
+deallocate prepare stmt;
+
+drop table t1;
+
+--error ER_NO_SUCH_TABLE
+prepare stmt from "create view v1 as select * from t1";
+--error ER_NO_SUCH_TABLE
+prepare stmt from "create view v1 as select * from `t1` `b`";
+
+#
+# Bug#33851: Passing UNSIGNED param to EXECUTE returns ERROR 1210
+#
+
+prepare stmt from "select ?";
+set @arg= 123456789.987654321;
+select @arg;
+execute stmt using @arg;
+set @arg= "string";
+select @arg;
+execute stmt using @arg;
+set @arg= 123456;
+select @arg;
+execute stmt using @arg;
+set @arg= cast(-12345.54321 as decimal(20, 10));
+select @arg;
+execute stmt using @arg;
+deallocate prepare stmt;
+
--echo End of 5.0 tests.
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index 95e0d31ff8f..cdbedb1f848 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -955,6 +955,22 @@ explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= '
drop table t1;
+#
+# Bug #33833: different or-ed predicates were erroneously merged into one that
+# resulted in ref access instead of range access and a wrong result set
+#
+
+CREATE TABLE t1 (
+ a varchar(32), index (a)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_bin;
+
+INSERT INTO t1 VALUES
+ ('B'), ('A'), ('A'), ('C'), ('B'), ('A'), ('A');
+
+SELECT a FROM t1 WHERE a='b' OR a='B';
+EXPLAIN SELECT a FROM t1 WHERE a='b' OR a='B';
+
+DROP TABLE t1;
#
# Bug #34731: highest possible value for INT erroneously filtered by WHERE
diff --git a/mysql-test/t/row.test b/mysql-test/t/row.test
index 20d044306a6..1601f7afd0e 100644
--- a/mysql-test/t/row.test
+++ b/mysql-test/t/row.test
@@ -224,3 +224,16 @@ SET @x:= (SELECT h FROM t1 WHERE (a,b,c,d,e,f,g)=(1,2,3,4,5,6,7));
SELECT @x;
DROP TABLE t1;
+
+#
+# Bug #34620: item_row.cc:50: Item_row::illegal_method_call(const char*):
+# Assertion `0' failed
+#
+
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1,1);
+
+SELECT ROW(a, 1) IN (SELECT SUM(b), 1) FROM t1 GROUP BY a;
+SELECT ROW(a, 1) IN (SELECT SUM(b), 3) FROM t1 GROUP BY a;
+
+DROP TABLE t1;
diff --git a/mysql-test/t/rpl_drop_view.test b/mysql-test/t/rpl_drop_view.test
new file mode 100644
index 00000000000..8d826b8214d
--- /dev/null
+++ b/mysql-test/t/rpl_drop_view.test
@@ -0,0 +1,31 @@
+# test case for bug#30998
+# Drop View breaks replication if view does not exist
+#
+
+source include/master-slave.inc;
+--disable_warnings
+drop table if exists t1, t2;
+drop view if exists v1, v2, v3, not_exist_view;
+--enable_warnings
+create table t1 (a int);
+create table t2 (b int);
+create table t3 (c int);
+create view v1 as select * from t1;
+create view v2 as select * from t2;
+create view v3 as select * from t3;
+--error 1051
+drop view not_exist_view;
+--error 1051
+drop view v1, not_exist_view;
+--error 1146
+select * from v1;
+drop view v2, v3;
+save_master_pos;
+connection slave;
+sync_with_master;
+--error 1146
+select * from v1;
+--error 1146
+select * from v2;
+--error 1146
+select * from v3;
diff --git a/mysql-test/t/rpl_loaddata_map-master.opt b/mysql-test/t/rpl_loaddata_map-master.opt
new file mode 100644
index 00000000000..f3c797b19c8
--- /dev/null
+++ b/mysql-test/t/rpl_loaddata_map-master.opt
@@ -0,0 +1 @@
+--read_buffer_size=9K --max_allowed_packet=8K
diff --git a/mysql-test/t/rpl_loaddata_map-slave.opt b/mysql-test/t/rpl_loaddata_map-slave.opt
new file mode 100644
index 00000000000..95f55bcf7d8
--- /dev/null
+++ b/mysql-test/t/rpl_loaddata_map-slave.opt
@@ -0,0 +1 @@
+--max_allowed_packet=8K
diff --git a/mysql-test/t/rpl_loaddata_map.test b/mysql-test/t/rpl_loaddata_map.test
new file mode 100644
index 00000000000..0a2883bfcca
--- /dev/null
+++ b/mysql-test/t/rpl_loaddata_map.test
@@ -0,0 +1,52 @@
+#
+# check replication of load data with the server parameters subjected to
+# read_buffer_size > max_allowed_packet
+#
+# BUG#30435 loading large LOAD DATA INFILE breaks slave with
+# read_buffer_size set on master
+# BUG#33413 show binlog events fails if binlog has event size of close
+# to max_allowed_packet
+
+source include/master-slave.inc;
+source include/have_innodb.inc;
+
+--disable_query_log
+let $rows= 5000;
+create table t1 (id int not null primary key auto_increment);
+
+while($rows)
+{
+ eval insert into t1 values (null);
+ dec $rows;
+}
+eval select * into outfile '$MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' from t1;
+flush logs;
+--enable_query_log
+
+connection master;
+create table t2 (id int not null primary key auto_increment);
+
+select @@session.read_buffer_size - @@session.max_allowed_packet > 0 ;
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval load data infile '$MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2;
+select count(*) from t2 /* 5 000 */;
+
+# the binglog will show fragmented Append_block events
+--let $binlog_start=98
+--replace_column 5 #
+--replace_regex /\/\* xid=.* \*\//\/* XID *\// /file_id=[0-9]+/file_id=#/
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--eval show binlog events in 'master-bin.000002' from $binlog_start
+
+
+sync_slave_with_master;
+#connection slave;
+select count(*) from t2 /* 5 000 */;
+
+connection master;
+drop table t1, t2;
+sync_slave_with_master;
+remove_file $MYSQLTEST_VARDIR/tmp/bug30435_5k.txt;
+
+--echo end of the tests
diff --git a/mysql-test/t/rpl_server_id.test b/mysql-test/t/rpl_server_id.test
new file mode 100644
index 00000000000..6e98ec6ee6d
--- /dev/null
+++ b/mysql-test/t/rpl_server_id.test
@@ -0,0 +1,29 @@
+# Test for BUG#28908 Replication: set global server_id is not setting the session server_id
+
+-- source include/have_log_bin.inc
+
+let $saved_server_id=`select @@server_id`;
+set global server_id=1;
+reset master;
+
+-- disable_warnings
+drop table if exists t1,t2,t3;
+-- enable_warnings
+
+create table t1 (a int);
+select @@server_id;
+source include/show_binlog_events2.inc;
+
+set global server_id=2;
+create table t2 (b int);
+select @@server_id;
+source include/show_binlog_events2.inc;
+
+set global server_id=3;
+create table t3 (c int);
+select @@server_id;
+source include/show_binlog_events2.inc;
+
+# cleanup
+eval set global server_id=$saved_server_id;
+drop table t1,t2,t3;
diff --git a/mysql-test/t/rpl_slave_skip.test b/mysql-test/t/rpl_slave_skip.test
index 04aafc51129..71e951aceea 100644
--- a/mysql-test/t/rpl_slave_skip.test
+++ b/mysql-test/t/rpl_slave_skip.test
@@ -13,8 +13,10 @@ source include/master-slave.inc;
# it back to get the non-transactional change into the table.
--echo **** On Master ****
-CREATE TABLE t1 (a INT, b SET('master','slave')) ENGINE=INNODB;
-CREATE TABLE t2 (a INT, b SET('master','slave')) ENGINE=MYISAM;
+CREATE TABLE t1 (a INT, b SET('master','slave')) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT, b SET('master','slave')) ENGINE=MyISAM;
+CREATE TABLE t3 (a CHAR(20), b SET('master','slave')) ENGINE=InnoDB;
+CREATE TABLE t4 (a CHAR(20), b SET('master','slave')) ENGINE=MyISAM;
--echo ==== Skipping normal transactions ====
@@ -195,9 +197,170 @@ sync_with_master;
SELECT * FROM t1 ORDER BY a;
SELECT * FROM t2 ORDER BY a;
+--echo ==== Skipping first event of a LOAD DATA for a transactional table ====
+
+--echo **** On Slave ****
+connection slave;
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+
+--echo **** On Master ****
+connection master;
+SET AUTOCOMMIT=1;
+
+LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t3(a) SET b = 'master';
+INSERT INTO t3 VALUES ('Go Rin No Sho', 'master,slave');
+
+save_master_pos;
+
+SELECT COUNT(*) FROM t3;
+
+# This will skip a begin event and the first INSERT of the
+# transaction, and it should keep skipping until it has reached the
+# transaction terminator.
+
+--echo **** On Slave ****
+connection slave;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+sync_with_master;
+--echo -- Should only contain records marked 'master,slave'
+SELECT * FROM t3 ORDER BY a;
+
+--echo **** On Master ****
+connection master;
+DELETE FROM t3;
+sync_slave_with_master;
+
+--echo ==== Skipping first event of a LOAD DATA for a non-transactional table ====
+
+--echo **** On Slave ****
+connection slave;
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+
+--echo **** On Master ****
+connection master;
+SET AUTOCOMMIT=1;
+
+LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t4(a) SET b = 'master';
+INSERT INTO t4 VALUES ('Go Rin No Sho', 'master,slave');
+
+save_master_pos;
+
+SELECT COUNT(*) FROM t4;
+
+# This will skip a begin event and the first INSERT of the
+# transaction, and it should keep skipping until it has reached the
+# transaction terminator.
+
+--echo **** On Slave ****
+connection slave;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+sync_with_master;
+--echo -- Should only contain records marked 'master,slave'
+SELECT * FROM t4 ORDER BY a;
+
+--echo **** On Master ****
+connection master;
+DELETE FROM t4;
+sync_slave_with_master;
+
+--echo ==== Try with a big file so that we get an append_block event as well
+
+--echo **** On Slave ****
+connection slave;
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+
+--echo **** On Master ****
+connection master;
+SET AUTOCOMMIT=1;
+
+# This contain about 70 words, so we double it a few times to get more than 128 KiB
+SET SQL_LOG_BIN=0;
+LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t4(a) SET b = 'master';
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+SELECT a FROM t4 INTO OUTFILE 'rpl_slave_skip_words.dat';
+SET SQL_LOG_BIN=1;
+
+# Start the real job
+LOAD DATA INFILE 'rpl_slave_skip_words.dat' INTO TABLE t4(a) SET b = 'master';
+INSERT INTO t4 VALUES ('Go Rin No Sho', 'master,slave');
+
+#SHOW BINLOG EVENTS;
+
+save_master_pos;
+
+SELECT COUNT(*) FROM t4;
+
+# This will skip a begin event and the first INSERT of the
+# transaction, and it should keep skipping until it has reached the
+# transaction terminator.
+
+--echo **** On Slave ****
+connection slave;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+sync_with_master;
+--echo -- Should only contain records marked 'master,slave'
+SELECT * FROM t4 ORDER BY a;
+
+--echo **** On Master ****
+connection master;
+DELETE FROM t4;
+sync_slave_with_master;
+
+# Test to generate a Delete_file log event, and see that it works as well.
+--echo **** On Master ****
+connection master;
+CREATE TABLE t5 (a int, b int, c SET('master','slave'), PRIMARY KEY (a,b)) ENGINE=MyISAM;
+LOAD DATA INFILE '../std_data_ln/loaddata5.dat' INTO TABLE t5 FIELDS TERMINATED BY '' ENCLOSED BY '' (a,b) SET c='master,slave';
+
+--echo **** On Slave ****
+sync_slave_with_master;
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+
+--echo **** On Master ****
+connection master;
+error ER_DUP_ENTRY;
+LOAD DATA INFILE '../std_data_ln/loaddata5.dat' INTO TABLE t5 FIELDS TERMINATED BY '' ENCLOSED BY '' (a,b) SET c='';
+INSERT INTO t5 VALUES (42, 42, 'master,slave');
+save_master_pos;
+
+#SHOW BINLOG EVENTS;
+
+SELECT * FROM t5;
+
+--echo **** On Slave ****
+connection slave;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+
+sync_with_master;
+SELECT * FROM t5;
+
+connection slave;
+
--echo ==== Cleanup ====
--echo **** On Master ****
connection master;
-DROP TABLE t1, t2;
+DROP TABLE t1, t2, t3, t4, t5;
sync_slave_with_master;
diff --git a/mysql-test/t/rpl_sp.test b/mysql-test/t/rpl_sp.test
index fc17c5615ef..f7cd8907e34 100644
--- a/mysql-test/t/rpl_sp.test
+++ b/mysql-test/t/rpl_sp.test
@@ -560,7 +560,6 @@ set @a:= mysqltest2.f1();
sync_slave_with_master;
connection master;
-
# Final inspection which verifies how all statements of this test file
# were written to the binary log.
--replace_column 2 # 5 #
@@ -577,3 +576,4 @@ set global log_bin_trust_function_creators=0;
# Clean up
drop database mysqltest;
drop database mysqltest2;
+sync_slave_with_master;
diff --git a/mysql-test/t/rpl_transaction-master.opt b/mysql-test/t/rpl_transaction-master.opt
new file mode 100644
index 00000000000..5411960b4aa
--- /dev/null
+++ b/mysql-test/t/rpl_transaction-master.opt
@@ -0,0 +1 @@
+--innodb --debug=d,do_not_write_xid
diff --git a/mysql-test/t/rpl_transaction-slave.opt b/mysql-test/t/rpl_transaction-slave.opt
new file mode 100644
index 00000000000..627becdbfb5
--- /dev/null
+++ b/mysql-test/t/rpl_transaction-slave.opt
@@ -0,0 +1 @@
+--innodb
diff --git a/mysql-test/t/rpl_transaction.test b/mysql-test/t/rpl_transaction.test
new file mode 100644
index 00000000000..07ba2ea8281
--- /dev/null
+++ b/mysql-test/t/rpl_transaction.test
@@ -0,0 +1,107 @@
+# Tests that transactions are replicated correctly, with various
+# combinations of non-transactional and transactional non-XA tables.
+# Also tests that an XA transaction where the master crashes just
+# before writing the XID log event is executed correctly. See below
+# for implementation details.
+
+# Note: this test should not exist in 5.1 or higher. It has been
+# replaced by rpl_ndb_transaction.test, which tests a superset of what
+# this test tests.
+
+source include/have_innodb.inc;
+source include/have_debug.inc;
+source include/master-slave.inc;
+
+
+CREATE TABLE tmyisam (a int) ENGINE = MYISAM;
+CREATE TABLE tinnodb (a int) ENGINE = INNODB;
+
+SHOW CREATE TABLE tmyisam;
+SHOW CREATE TABLE tinnodb;
+
+
+--echo ==== Test 1: Non-XA Engines ====
+# Test that everything works fine with non-XA engines. We just try
+# all ways to do transactions involving ndb and/or myisam, with
+# rollback or commit.
+
+--echo --- on master ---
+
+SET AUTOCOMMIT = 1;
+
+INSERT INTO tmyisam VALUES (1);
+
+BEGIN;
+INSERT INTO tmyisam VALUES (2);
+INSERT INTO tmyisam VALUES (3);
+COMMIT;
+
+BEGIN;
+INSERT INTO tmyisam VALUES (5);
+INSERT INTO tmyisam VALUES (6);
+--warning 1196
+ROLLBACK;
+
+SELECT * FROM tmyisam ORDER BY a;
+
+--echo --- on slave ---
+--sync_slave_with_master
+SELECT * FROM tmyisam ORDER BY a;
+
+
+--echo ==== Test 2: Master crash before writing XID event on XA engine ====
+# We now want to test the following scenario, to verify that BUG#26395
+# has been fixed:
+
+# "master and slave have a transactional table that uses XA. Master
+# has AUTOCOMMIT on and executes a statement (in this case an
+# INSERT). Master crashes just before writing the XID event."
+
+# In this scenario, master will roll back, so slave should not execute
+# the statement, and slave should roll back later when master is
+# restarted.
+
+# However, we the master to be alive so that we are sure it replicates
+# the statement to the slave. So in the test case, we must therefore
+# not crash the master. Instead, we fake the crash by just not writing
+# the XID event to the binlog. This is done by the
+# --debug=d,do_not_write_xid flag in the .opt file.
+
+# So, unlike if the master had crashed, the master *will* execute the
+# statement. But the slave should not execute it. Hence, after the
+# first test is executed, the expected result on master is a table
+# with one row, and on slave a table with no rows.
+
+# To simulate the slave correctly, we wait until everything up to the
+# XID is replicated. We cannot sync_slave_with_master, because that
+# would wait for the transaction to end. Instead, we wait for
+# "sufficiently long time". Then we stop the slave.
+
+# Note: since this puts the master binlog in an inconsistent state,
+# this should be the last test of the file.
+
+--echo --- on master ---
+--connection master
+
+INSERT INTO tinnodb VALUES (1);
+SELECT * FROM tinnodb ORDER BY a;
+
+--echo --- on slave ---
+--connection slave
+--sleep 3
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+--replace_column 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 #
+query_vertical SHOW SLAVE STATUS;
+# the following statement should show that nothing has been replicated
+SELECT * FROM tinnodb ORDER BY a;
+
+
+# clean up
+connection master;
+DROP TABLE tmyisam;
+DROP TABLE tinnodb;
+
+connection slave;
+DROP TABLE tmyisam;
+DROP TABLE tinnodb;
diff --git a/mysql-test/t/rpl_user.test b/mysql-test/t/rpl_user.test
new file mode 100644
index 00000000000..a0aeeac62c2
--- /dev/null
+++ b/mysql-test/t/rpl_user.test
@@ -0,0 +1,62 @@
+# BUG#33862 completely failed DROP USER statement gets replicated
+
+--source include/master-slave.inc
+
+#
+# remove all users will be used in the test
+#
+connection master;
+set sql_log_bin=0;
+delete from mysql.user where Host='fakehost';
+set sql_log_bin=1;
+
+connection slave;
+set sql_log_bin=0;
+delete from mysql.user where Host='fakehost';
+set sql_log_bin=1;
+
+
+#
+# Test create user
+#
+connection master;
+create user 'foo'@'fakehost';
+--error ER_CANNOT_USER
+create user 'foo'@'fakehost', 'bar'@'fakehost';
+--error ER_CANNOT_USER
+create user 'foo'@'fakehost', 'bar'@'fakehost';
+
+sync_slave_with_master;
+select Host,User from mysql.user where Host='fakehost';
+
+#
+# Test rename user
+#
+connection master;
+rename user 'foo'@'fakehost' to 'foofoo'@'fakehost';
+--error ER_CANNOT_USER
+rename user 'not_exist_user1'@'fakehost' to 'foobar'@'fakehost', 'bar'@'fakehost' to 'barbar'@'fakehost';
+--error ER_CANNOT_USER
+rename user 'not_exist_user1'@'fakehost' to 'foobar'@'fakehost', 'not_exist_user2'@'fakehost' to 'barfoo'@'fakehost';
+
+sync_slave_with_master;
+select Host,User from mysql.user where Host='fakehost';
+
+#
+# Test drop user
+#
+connection master;
+drop user 'foofoo'@'fakehost';
+--error ER_CANNOT_USER
+drop user 'not_exist_user1'@'fakehost', 'barbar'@'fakehost';
+--error ER_CANNOT_USER
+drop user 'not_exist_user1'@'fakehost', 'not_exist_user2'@'fakehost';
+
+sync_slave_with_master;
+select Host,User from mysql.user where Host='fakehost';
+
+#
+# show the binlog events on the master
+#
+connection master;
+source include/show_binlog_events.inc;
diff --git a/mysql-test/t/rpl_user_variables.test b/mysql-test/t/rpl_user_variables.test
index 8f8f0accbd1..70b708be258 100644
--- a/mysql-test/t/rpl_user_variables.test
+++ b/mysql-test/t/rpl_user_variables.test
@@ -337,6 +337,23 @@ select * from t1;
connection master;
drop table t1;
+#
+# Bug#33851: Passing UNSIGNED param to EXECUTE returns ERROR 1210
+#
+
+connection master;
+create table t1(a int);
+insert into t1 values (1),(2);
+prepare s1 from 'insert into t1 select a from t1 limit ?';
+set @x='1.1';
+execute s1 using @x;
+select * from t1;
+sync_slave_with_master;
+connection slave;
+select * from t1;
+connection master;
+drop table t1;
+
--echo End of 5.0 tests.
# This test uses a stored function that uses user-defined variables to return data
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index c48f2771aa8..1ee87957643 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -3672,4 +3672,33 @@ DROP TABLE t1;
--echo
+###########################################################################
+
+#
+# Bug #33764: Wrong result with IN(), CONCAT() and implicit type conversion
+#
+
+CREATE TABLE t1 (a VARCHAR(10) NOT NULL PRIMARY KEY);
+INSERT INTO t1 (a) VALUES ('foo0'), ('bar0'), ('baz0');
+SELECT * FROM t1 WHERE a IN (CONCAT('foo', 0), 'bar');
+DROP TABLE t1;
+
+#
+# Bug #32942 now() - interval '7200' second is NOT pre-calculated, causing "full table scan"
+#
+
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT, c INT, KEY(a));
+
+INSERT INTO t1 VALUES (1, 1), (2, 2);
+INSERT INTO t2 VALUES (1, 1), (1, 2), (1, 3), (1, 4), (1, 5),
+ (2, 1), (2, 2), (2, 3), (2, 4), (2, 5),
+ (3, 1), (3, 2), (3, 3), (3, 4), (3, 5),
+ (4, 1), (4, 2), (4, 3), (4, 4), (4, 5);
+
+FLUSH STATUS;
+SELECT DISTINCT b FROM t1 LEFT JOIN t2 USING(a) WHERE c <= 3;
+SHOW STATUS LIKE 'Handler_read%';
+DROP TABLE t1, t2;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/sp-code.test b/mysql-test/t/sp-code.test
index 10755f2bf8a..751282c895a 100644
--- a/mysql-test/t/sp-code.test
+++ b/mysql-test/t/sp-code.test
@@ -520,5 +520,82 @@ drop table t1;
drop procedure proc_26977_broken;
drop procedure proc_26977_works;
+#
+# Bug#33618 Crash in sp_rcontext
+#
+
+--disable_warnings
+drop procedure if exists proc_33618_h;
+drop procedure if exists proc_33618_c;
+--enable_warnings
+
+delimiter //;
+
+create procedure proc_33618_h(num int)
+begin
+ declare count1 int default '0';
+ declare vb varchar(30);
+ declare last_row int;
+
+ while(num>=1) do
+ set num=num-1;
+ begin
+ declare cur1 cursor for select `a` from t_33618;
+ declare continue handler for not found set last_row = 1;
+ set last_row:=0;
+ open cur1;
+ rep1:
+ repeat
+ begin
+ declare exit handler for 1062 begin end;
+ fetch cur1 into vb;
+ if (last_row = 1) then
+ ## should generate a hpop instruction here
+ leave rep1;
+ end if;
+ end;
+ until last_row=1
+ end repeat;
+ close cur1;
+ end;
+ end while;
+end//
+
+create procedure proc_33618_c(num int)
+begin
+ declare count1 int default '0';
+ declare vb varchar(30);
+ declare last_row int;
+
+ while(num>=1) do
+ set num=num-1;
+ begin
+ declare cur1 cursor for select `a` from t_33618;
+ declare continue handler for not found set last_row = 1;
+ set last_row:=0;
+ open cur1;
+ rep1:
+ repeat
+ begin
+ declare cur2 cursor for select `b` from t_33618;
+ fetch cur1 into vb;
+ if (last_row = 1) then
+ ## should generate a cpop instruction here
+ leave rep1;
+ end if;
+ end;
+ until last_row=1
+ end repeat;
+ close cur1;
+ end;
+ end while;
+end//
+delimiter ;//
+
+show procedure code proc_33618_h;
+show procedure code proc_33618_c;
+
+drop procedure proc_33618_h;
+drop procedure proc_33618_c;
--echo End of 5.0 tests.
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index 8133a2271a1..c9b2b1dbd0e 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -2113,6 +2113,69 @@ SELECT ..inexistent();
USE test;
#
+# Bug#33983 (Stored Procedures: wrong end <label> syntax is accepted)
+#
+
+--disable_warnings
+drop procedure if exists proc_33983_a;
+drop procedure if exists proc_33983_b;
+drop procedure if exists proc_33983_c;
+drop procedure if exists proc_33983_d;
+--enable_warnings
+
+delimiter |;
+
+--error ER_SP_LABEL_MISMATCH
+create procedure proc_33983_a()
+begin
+ label1:
+ begin
+ label2:
+ begin
+ select 1;
+ end label1;
+ end;
+end|
+
+--error ER_SP_LABEL_MISMATCH
+create procedure proc_33983_b()
+begin
+ label1:
+ repeat
+ label2:
+ repeat
+ select 1;
+ until FALSE end repeat label1;
+ until FALSE end repeat;
+end|
+
+--error ER_SP_LABEL_MISMATCH
+create procedure proc_33983_c()
+begin
+ label1:
+ while TRUE do
+ label2:
+ while TRUE do
+ select 1;
+ end while label1;
+ end while;
+end|
+
+--error ER_SP_LABEL_MISMATCH
+create procedure proc_33983_d()
+begin
+ label1:
+ loop
+ label2:
+ loop
+ select 1;
+ end loop label1;
+ end loop;
+end|
+
+delimiter ;|
+
+#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 785e7e3793c..48ef51e09aa 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -7698,6 +7698,100 @@ DROP PROCEDURE db28318_a.t1;
DROP PROCEDURE db28318_b.t2;
DROP DATABASE db28318_a;
DROP DATABASE db28318_b;
+USE test;
+
+#
+# Bug#29770 Two handlers are allowed to catch an error in an stored procedure.
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP PROCEDURE IF EXISTS bug29770;
+--enable_warnings
+
+CREATE TABLE t1(a int);
+delimiter |;
+CREATE PROCEDURE bug29770()
+BEGIN
+ DECLARE CONTINUE HANDLER FOR SQLSTATE '42S22' SET @state:= 'run';
+ DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @exception:= 'run';
+ SELECT x FROM t1;
+END|
+delimiter ;|
+CALL bug29770();
+SELECT @state, @exception;
+DROP TABLE t1;
+DROP PROCEDURE bug29770;
+
+#
+# Bug#33618 Crash in sp_rcontext
+#
+
+use test;
+
+--disable_warnings
+drop table if exists t_33618;
+drop procedure if exists proc_33618;
+--enable_warnings
+
+create table t_33618 (`a` int, unique(`a`), `b` varchar(30)) engine=myisam;
+insert into t_33618 (`a`,`b`) values (1,'1'),(2,'2');
+
+delimiter //;
+
+create procedure proc_33618(num int)
+begin
+ declare count1 int default '0';
+ declare vb varchar(30);
+ declare last_row int;
+
+ while(num>=1) do
+ set num=num-1;
+ begin
+ declare cur1 cursor for select `a` from t_33618;
+ declare continue handler for not found set last_row = 1;
+ set last_row:=0;
+ open cur1;
+ rep1:
+ repeat
+ begin
+ declare exit handler for 1062 begin end;
+ fetch cur1 into vb;
+ if (last_row = 1) then
+ leave rep1;
+ end if;
+ end;
+ until last_row=1
+ end repeat;
+ close cur1;
+ end;
+ end while;
+end//
+
+delimiter ;//
+
+call proc_33618(20);
+
+drop table t_33618;
+drop procedure proc_33618;
+--echo #
+--echo # Bug#30787: Stored function ignores user defined alias.
+--echo #
+use test;
+--disable_warnings
+drop function if exists func30787;
+--enable_warnings
+create table t1(f1 int);
+insert into t1 values(1),(2);
+delimiter |;
+create function func30787(p1 int) returns int
+begin
+ return p1;
+end |
+delimiter ;|
+select (select func30787(f1)) as ttt from t1;
+drop function func30787;
+drop table t1;
--echo # ------------------------------------------------------------------
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 326d80f84c1..c5edd5414e3 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -3006,92 +3006,44 @@ DROP TABLE t1,t2;
create table t1(a int,b int,key(a),key(b));
insert into t1(a,b) values (1,2),(2,1),(2,3),(3,4),(5,4),(5,5),
(6,7),(7,4),(5,3);
-# test for the stack overflow bug
-select sum(a),a from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1
- )group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1)
-group by a;
---replace_regex /overrun.*$/overrun detected/
---error 1436
-select sum(a),a from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1)
-group by a;
-# test for the memory consumption & subquery slowness bug
-explain select sum(a),a from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1
- )group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1)
-group by a;
---replace_regex /overrun.*$/overrun detected/
---error 1436
-explain select sum(a),a from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
- select sum(a) from t1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1
- )group by b limit 1)group by b limit 1)group by b limit 1)
-group by a;
+
+let $nesting= 26;
+let $should_work_nesting= 5;
+let $start= select sum(a),a from t1 where a> ( select sum(a) from t1 ;
+let $end= )group by a ;
+let $start_app= where a> ( select sum(a) from t1 ;
+let $end_pre= )group by b limit 1 ;
+
+--disable_result_log
+--disable_query_log
+# At least 4 level nesting should work without errors
+while ($should_work_nesting)
+{
+--echo $should_work_nesting
+ eval $start $end;
+ eval explain $start $end;
+ let $start= $start
+ $start_app;
+ let $end= $end_pre
+ $end;
+ dec $should_work_nesting;
+}
+# Other may fail with the 'stack overrun error'
+while ($nesting)
+{
+--echo $nesting
+--error 0,1436
+ eval $start $end;
+--error 0,1436
+ eval explain $start $end;
+ let $start= $start
+ $start_app;
+ let $end= $end_pre
+ $end;
+ dec $nesting;
+}
+--enable_result_log
+--enable_query_log
drop table t1;
#
diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test
index 7eaeaa00c0a..10d8f355c98 100644
--- a/mysql-test/t/symlink.test
+++ b/mysql-test/t/symlink.test
@@ -127,29 +127,22 @@ drop table t1;
#
# BUG#32111 - Security Breach via DATA/INDEX DIRECORY and RENAME TABLE
#
+--write_file $MYSQLTEST_VARDIR/tmp/t1.MYI
+EOF
--replace_result $MYSQLTEST_VARDIR TEST_DIR
+--error 1
eval CREATE TABLE t1(a INT)
-DATA DIRECTORY='$MYSQLTEST_VARDIR/master-data/mysql'
-INDEX DIRECTORY='$MYSQLTEST_VARDIR/master-data/mysql';
+DATA DIRECTORY='$MYSQLTEST_VARDIR/tmp'
+INDEX DIRECTORY='$MYSQLTEST_VARDIR/tmp';
+--replace_result $MYSQLTEST_VARDIR TEST_DIR
+eval CREATE TABLE t2(a INT)
+DATA DIRECTORY='$MYSQLTEST_VARDIR/tmp'
+INDEX DIRECTORY='$MYSQLTEST_VARDIR/tmp';
--replace_result $MYSQLTEST_VARDIR TEST_DIR
--error 1
-RENAME TABLE t1 TO user;
-DROP TABLE t1;
-
-#
-# Test specifying DATA DIRECTORY that is the same as what would normally
-# have been chosen. (Bug #8707)
-#
-disable_query_log;
-eval create table t1 (i int) data directory = "$MYSQLTEST_VARDIR/master-data/test/";
-enable_query_log;
-show create table t1;
-drop table t1;
-disable_query_log;
-eval create table t1 (i int) index directory = "$MYSQLTEST_VARDIR/master-data/test/";
-enable_query_log;
-show create table t1;
-drop table t1;
+RENAME TABLE t2 TO t1;
+DROP TABLE t2;
+--remove_file $MYSQLTEST_VARDIR/tmp/t1.MYI
#
# Bug#8706 - temporary table with data directory option fails
@@ -188,44 +181,61 @@ connection default;
select * from t1;
drop table t1;
---echo End of 4.1 tests
-
#
-# Bug #29325: create table overwrites .MYD file of other table (datadir)
+# CREATE TABLE with DATA DIRECTORY option
#
-
-CREATE DATABASE db1;
-CREATE DATABASE db2;
-
-USE db2;
+# Protect ourselves from data left in tmp/ by a previos possibly failed
+# test
+--system rm -f $MYSQLTEST_VARDIR/tmp/t1.*
--disable_query_log
-eval CREATE TABLE t1 (b INT) ENGINE MYISAM
-DATA DIRECTORY = '$MYSQLTEST_VARDIR/master-data/db1/';
+eval prepare stmt from "create table t1 (c char(10)) data directory='$MYSQLTEST_VARDIR/tmp'";
--enable_query_log
+execute stmt;
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+show create table t1;
+drop table t1;
+execute stmt;
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+show create table t1;
+drop table t1;
+deallocate prepare stmt;
-INSERT INTO db2.t1 VALUES (1);
-SELECT * FROM db2.t1;
-RESET QUERY CACHE;
+#
+# Bug#32167 another privilege bypass with DATA/INDEX DIRECORY
+#
+--replace_result $MYSQL_TEST_DIR TEST_DIR
+--error 1,1210
+eval CREATE TABLE t1(a INT)
+DATA DIRECTORY='$MYSQL_TEST_DIR/var/master-data/test';
+--replace_result $MYSQL_TEST_DIR TEST_DIR
+--error 1,1210
+eval CREATE TABLE t1(a INT)
+DATA DIRECTORY='$MYSQL_TEST_DIR/var/master-data/';
+--replace_result $MYSQL_TEST_DIR TEST_DIR
+--error 1,1210
+eval CREATE TABLE t1(a INT)
+INDEX DIRECTORY='$MYSQL_TEST_DIR/var/master-data';
+--replace_result $MYSQL_TEST_DIR TEST_DIR
+--error 1,1210
+eval CREATE TABLE t1(a INT)
+INDEX DIRECTORY='$MYSQL_TEST_DIR/var/master-data_var';
-USE db1;
+--echo End of 4.1 tests
-#no warning from create table
+#
+# Bug #29325: create table overwrites .MYD file of other table (datadir)
+#
SET SESSION keep_files_on_create = TRUE;
+--write_file $MYSQLTEST_VARDIR/master-data/test/t1.MYD
+EOF
--disable_abort_on_error
+--error 1
CREATE TABLE t1 (a INT) ENGINE MYISAM;
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/test/t1.MYD;
--enable_abort_on_error
-
-CREATE TABLE t3 (a INT) Engine=MyISAM;
-INSERT INTO t3 VALUES (1),(2),(3);
-TRUNCATE TABLE t3;
-SELECT * from t3;
-
-SET SESSION keep_files_on_create = DEFAULT;
-
-DROP TABLE db2.t1, db1.t3;
-DROP DATABASE db1;
-DROP DATABASE db2;
-USE test;
-
+SET SESSION keep_files_on_create = FALSE;
+CREATE TABLE t1 (a INT) ENGINE MYISAM;
+DROP TABLE t1;
--echo End of 5.0 tests
diff --git a/mysql-test/t/tablelock.test b/mysql-test/t/tablelock.test
index 95533903b45..5ac93f09ac1 100644
--- a/mysql-test/t/tablelock.test
+++ b/mysql-test/t/tablelock.test
@@ -49,3 +49,16 @@ drop table t2,t1;
unlock tables;
# End of 4.1 tests
+
+#
+# Bug#23588 SHOW COLUMNS on a temporary table causes locking issues
+#
+create temporary table t1(f1 int);
+lock tables t1 write;
+insert into t1 values (1);
+show columns from t1;
+insert into t1 values(2);
+drop table t1;
+unlock tables;
+
+# End of 5.0 tests
diff --git a/mysql-test/t/type_set.test b/mysql-test/t/type_set.test
index b1c816f3371..c7f8c59de28 100644
--- a/mysql-test/t/type_set.test
+++ b/mysql-test/t/type_set.test
@@ -56,3 +56,23 @@ set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17',
'50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','1'));
show create table t1;
drop table t1;
+
+#
+# Bug#15409: Columns with SET datatype with 64-element sets
+# may not be updated with integers
+#
+
+let $i=64;
+let $s='$i';
+dec $i;
+while ($i) {
+ let $s='$i',$s;
+ dec $i;
+}
+--eval CREATE TABLE t1(c set($s))
+INSERT INTO t1 VALUES(7);
+INSERT INTO t1 VALUES(9223372036854775808);
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--# echo End of 5.0 tests
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index c86e7dfa7f3..1748b63ceb9 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -127,7 +127,7 @@ set GLOBAL myisam_max_sort_file_size=2000000;
show global variables like 'myisam_max_sort_file_size';
set GLOBAL myisam_max_sort_file_size=default;
--replace_result 9223372036853727232 FILE_SIZE 2146435072 FILE_SIZE
-show variables like 'myisam_max_sort_file_size';
+show global variables like 'myisam_max_sort_file_size';
set global net_retry_count=10, session net_retry_count=10;
set global net_buffer_length=1024, net_write_timeout=200, net_read_timeout=300;
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 340a34db5a1..23e64b0546f 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -3470,5 +3470,73 @@ insert into v1 values(1);
set @@sql_mode=@old_mode;
drop view v1;
drop table t1;
---echo End of 5.0 tests.
+#
+# Bug #33389: Selecting from a view into a table from within SP or trigger
+# crashes server
+#
+
+create table t1 (a int, key(a));
+create table t2 (c int);
+
+create view v1 as select a b from t1;
+create view v2 as select 1 a from t2, v1 where c in
+ (select 1 from t1 where b = a);
+
+insert into t1 values (1), (1);
+insert into t2 values (1), (1);
+
+prepare stmt from "select * from v2 where a = 1";
+execute stmt;
+
+drop view v1, v2;
+drop table t1, t2;
+
+#
+# Bug #33049: Assert while running test-as3ap test(mysql-bench suite)
+#
+
+CREATE TABLE t1 (a INT);
+CREATE VIEW v1 AS SELECT p.a AS a FROM t1 p, t1 q;
+
+INSERT INTO t1 VALUES (1), (1);
+SELECT MAX(a), COUNT(DISTINCT a) FROM v1 GROUP BY a;
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+###########################################################################
+
+--echo # -----------------------------------------------------------------
+--echo # -- Bug#34337: Server crash when Altering a view using a table name.
+--echo # -----------------------------------------------------------------
+--echo
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo
+
+CREATE TABLE t1(c1 INT);
+
+--echo
+
+SELECT * FROM t1;
+
+--error ER_WRONG_OBJECT
+ALTER ALGORITHM=TEMPTABLE SQL SECURITY INVOKER VIEW t1 (c2) AS SELECT (1);
+
+--echo
+
+DROP TABLE t1;
+
+--echo
+--echo # -- End of test case for Bug#34337.
+--echo
+
+###########################################################################
+
+--echo # -----------------------------------------------------------------
+--echo # -- End of 5.0 tests.
+--echo # -----------------------------------------------------------------
diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test
index 7f9eb4e1cff..be9daacec4f 100644
--- a/mysql-test/t/view_grant.test
+++ b/mysql-test/t/view_grant.test
@@ -608,6 +608,7 @@ drop database mysqltest;
#
--disable_warnings
drop view if exists v1;
+drop table if exists t1;
--enable_warnings
# Backup anonymous users and remove them. (They get in the way of
diff --git a/mysql-test/t/warnings.test b/mysql-test/t/warnings.test
index 5e9d25aa09b..c42dd22024c 100644
--- a/mysql-test/t/warnings.test
+++ b/mysql-test/t/warnings.test
@@ -212,4 +212,37 @@ DROP PROCEDURE sp1;
DROP PROCEDURE sp2;
DROP PROCEDURE sp3;
+
+#
+# Bug#30059: End-space truncation warnings are inconsistent or incorrect
+#
+
+create table t1 (c_char char(255), c_varchar varchar(255), c_tinytext tinytext);
+create table t2 (c_tinyblob tinyblob); # not affected by bug, for regression testing
+set @c = repeat(' ', 256);
+set @q = repeat('q', 256);
+
+set sql_mode = '';
+
+insert into t1 values(@c, @c, @c);
+insert into t2 values(@c);
+insert into t1 values(@q, @q, @q);
+insert into t2 values(@q);
+
+set sql_mode = 'traditional';
+
+insert into t1 values(@c, @c, @c);
+--error 1406
+insert into t2 values(@c);
+--error 1406
+insert into t1 values(@q, NULL, NULL);
+--error 1406
+insert into t1 values(NULL, @q, NULL);
+--error 1406
+insert into t1 values(NULL, NULL, @q);
+--error 1406
+insert into t2 values(@q);
+
+drop table t1, t2;
+
--echo End of 5.0 tests
diff --git a/mysys/my_create.c b/mysys/my_create.c
index d612926c1a5..c535ae73a0a 100644
--- a/mysys/my_create.c
+++ b/mysys/my_create.c
@@ -35,7 +35,7 @@
File my_create(const char *FileName, int CreateFlags, int access_flags,
myf MyFlags)
{
- int fd;
+ int fd, rc;
DBUG_ENTER("my_create");
DBUG_PRINT("my",("Name: '%s' CreateFlags: %d AccessFlags: %d MyFlags: %d",
FileName, CreateFlags, access_flags, MyFlags));
@@ -60,6 +60,20 @@ File my_create(const char *FileName, int CreateFlags, int access_flags,
fd = open(FileName, access_flags);
#endif
- DBUG_RETURN(my_register_filename(fd, FileName, FILE_BY_CREATE,
- EE_CANTCREATEFILE, MyFlags));
+ rc= my_register_filename(fd, FileName, FILE_BY_CREATE,
+ EE_CANTCREATEFILE, MyFlags);
+ /*
+ my_register_filename() may fail on some platforms even if the call to
+ *open() above succeeds. In this case, don't leave the stale file because
+ callers assume the file to not exist if my_create() fails, so they don't
+ do any cleanups.
+ */
+ if (unlikely(fd >= 0 && rc < 0))
+ {
+ int tmp= my_errno;
+ my_delete(FileName, MyFlags);
+ my_errno= tmp;
+ }
+
+ DBUG_RETURN(rc);
} /* my_create */
diff --git a/ndb/include/kernel/ndb_limits.h b/ndb/include/kernel/ndb_limits.h
index c82288c762a..82fd0bd5d51 100644
--- a/ndb/include/kernel/ndb_limits.h
+++ b/ndb/include/kernel/ndb_limits.h
@@ -27,6 +27,17 @@
#define MAX_NDB_NODES 49
#define MAX_NODES 64
+/**************************************************************************
+ * IT SHOULD BE (MAX_NDB_NODES - 1).
+ * WHEN MAX_NDB_NODE IS CHANGED, IT SHOULD BE CHANGED ALSO
+ **************************************************************************/
+#define MAX_DATA_NODE_ID 48
+/**************************************************************************
+ * IT SHOULD BE (MAX_NODES - 1).
+ * WHEN MAX_NODES IS CHANGED, IT SHOULD BE CHANGED ALSO
+ **************************************************************************/
+#define MAX_NODES_ID 63
+
/**
* MAX_API_NODES = MAX_NODES - No of NDB Nodes in use
*/
diff --git a/ndb/include/mgmapi/ndb_logevent.h b/ndb/include/mgmapi/ndb_logevent.h
index 76e4c31baa2..389004da06b 100644
--- a/ndb/include/mgmapi/ndb_logevent.h
+++ b/ndb/include/mgmapi/ndb_logevent.h
@@ -551,7 +551,13 @@ extern "C" {
/** Log event specific data for for corresponding NDB_LE_ log event */
struct {
int gth;
- unsigned page_size_kb;
+ /* union is for compatibility backward.
+ * page_size_kb member variable should be removed in the future
+ */
+ union {
+ unsigned page_size_kb;
+ unsigned page_size_bytes;
+ };
unsigned pages_used;
unsigned pages_total;
unsigned block;
diff --git a/ndb/include/ndbapi/Ndb.hpp b/ndb/include/ndbapi/Ndb.hpp
index 5f0da6ea83d..42f6302861c 100644
--- a/ndb/include/ndbapi/Ndb.hpp
+++ b/ndb/include/ndbapi/Ndb.hpp
@@ -1386,22 +1386,22 @@ public:
*
* @param cacheSize number of values to cache in this Ndb object
*
- * @return 0 or -1 on error, and tupleId in out parameter
+ * @return 0 or -1 on error, and autoValue in out parameter
*/
int getAutoIncrementValue(const char* aTableName,
- Uint64 & tupleId, Uint32 cacheSize,
+ Uint64 & autoValue, Uint32 cacheSize,
Uint64 step = 1, Uint64 start = 1);
int getAutoIncrementValue(const NdbDictionary::Table * aTable,
- Uint64 & tupleId, Uint32 cacheSize,
+ Uint64 & autoValue, Uint32 cacheSize,
Uint64 step = 1, Uint64 start = 1);
int readAutoIncrementValue(const char* aTableName,
- Uint64 & tupleId);
+ Uint64 & autoValue);
int readAutoIncrementValue(const NdbDictionary::Table * aTable,
- Uint64 & tupleId);
+ Uint64 & autoValue);
int setAutoIncrementValue(const char* aTableName,
- Uint64 tupleId, bool increase);
+ Uint64 autoValue, bool modify);
int setAutoIncrementValue(const NdbDictionary::Table * aTable,
- Uint64 tupleId, bool increase);
+ Uint64 autoValue, bool modify);
private:
int getTupleIdFromNdb(Ndb_local_table_info* info,
Uint64 & tupleId, Uint32 cacheSize,
@@ -1409,7 +1409,9 @@ private:
int readTupleIdFromNdb(Ndb_local_table_info* info,
Uint64 & tupleId);
int setTupleIdInNdb(Ndb_local_table_info* info,
- Uint64 tupleId, bool increase);
+ Uint64 tupleId, bool modify);
+ int checkTupleIdInNdb(Ndb_local_table_info* info,
+ Uint64 tupleId);
int opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op);
public:
diff --git a/ndb/include/ndbapi/ndbapi_limits.h b/ndb/include/ndbapi/ndbapi_limits.h
index e283913d059..98551866edc 100644
--- a/ndb/include/ndbapi/ndbapi_limits.h
+++ b/ndb/include/ndbapi/ndbapi_limits.h
@@ -26,6 +26,7 @@
#define NDB_MAX_TUPLE_SIZE (NDB_MAX_TUPLE_SIZE_IN_WORDS*4)
#define NDB_MAX_ACTIVE_EVENTS 100
-#define NDB_MAX_SCANFILTER_SIZE_IN_WORDS 50000
+/* TUP ZATTR_BUFFER_SIZE 16384 (minus 1) minus place for getValue()s */
+#define NDB_MAX_SCANFILTER_SIZE_IN_WORDS (16384 - 1 - 1024)
#endif
diff --git a/ndb/include/util/Bitmask.hpp b/ndb/include/util/Bitmask.hpp
index 3b3fe721cca..0383841a666 100644
--- a/ndb/include/util/Bitmask.hpp
+++ b/ndb/include/util/Bitmask.hpp
@@ -126,6 +126,7 @@ public:
/**
* setField - Set bitfield at given position and length (max 32 bits)
+ * Note : length == 0 not supported.
*/
static void setField(unsigned size, Uint32 data[],
unsigned pos, unsigned len, Uint32 val);
@@ -133,6 +134,7 @@ public:
/**
* getField - Get bitfield at given position and length
+ * Note : length == 0 not supported.
*/
static void getField(unsigned size, const Uint32 data[],
unsigned pos, unsigned len, Uint32 dst[]);
@@ -814,7 +816,10 @@ BitmaskImpl::getField(unsigned size, const Uint32 src[],
unsigned pos, unsigned len, Uint32 dst[])
{
assert(pos + len <= (size << 5));
-
+ assert (len != 0);
+ if (len == 0)
+ return;
+
src += (pos >> 5);
Uint32 offset = pos & 31;
* dst = (* src >> offset) & (len >= 32 ? ~0 : (1 << len) - 1);
@@ -833,6 +838,9 @@ BitmaskImpl::setField(unsigned size, Uint32 dst[],
unsigned pos, unsigned len, const Uint32 src[])
{
assert(pos + len <= (size << 5));
+ assert(len != 0);
+ if (len == 0)
+ return;
dst += (pos >> 5);
Uint32 offset = pos & 31;
diff --git a/ndb/src/common/debugger/SignalLoggerManager.cpp b/ndb/src/common/debugger/SignalLoggerManager.cpp
index 471bea64f64..48cacb6bc1a 100644
--- a/ndb/src/common/debugger/SignalLoggerManager.cpp
+++ b/ndb/src/common/debugger/SignalLoggerManager.cpp
@@ -129,7 +129,7 @@ SignalLoggerManager::log(LogMode logMode, const char * params)
const int count = getParameter(blocks, "BLOCK=", params);
int cnt = 0;
- if((count == 1 && blocks[0] == "ALL") ||
+ if((count == 1 && !strcmp(blocks[0], "ALL")) ||
count == 0){
for (int number = 0; number < NO_OF_BLOCKS; ++number){
diff --git a/ndb/src/common/debugger/signaldata/ScanTab.cpp b/ndb/src/common/debugger/signaldata/ScanTab.cpp
index 39589542800..db9bbb52eab 100644
--- a/ndb/src/common/debugger/signaldata/ScanTab.cpp
+++ b/ndb/src/common/debugger/signaldata/ScanTab.cpp
@@ -69,7 +69,7 @@ printSCANTABCONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 recei
sig->transId1, sig->transId2);
fprintf(output, " requestInfo: Eod: %d OpCount: %d\n",
- (requestInfo & ScanTabConf::EndOfData == ScanTabConf::EndOfData),
+ (requestInfo & ScanTabConf::EndOfData) == ScanTabConf::EndOfData,
(requestInfo & (~ScanTabConf::EndOfData)));
size_t op_count= requestInfo & (~ScanTabConf::EndOfData);
if(op_count){
diff --git a/ndb/src/common/transporter/TCP_Transporter.cpp b/ndb/src/common/transporter/TCP_Transporter.cpp
index c8095defd86..ea9e0944915 100644
--- a/ndb/src/common/transporter/TCP_Transporter.cpp
+++ b/ndb/src/common/transporter/TCP_Transporter.cpp
@@ -337,22 +337,32 @@ TCP_Transporter::doSend() {
// Empty the SendBuffers
- const char * const sendPtr = m_sendBuffer.sendPtr;
- const Uint32 sizeToSend = m_sendBuffer.sendDataSize;
- if (sizeToSend > 0){
+ bool sent_any = true;
+ while (m_sendBuffer.dataSize > 0)
+ {
+ const char * const sendPtr = m_sendBuffer.sendPtr;
+ const Uint32 sizeToSend = m_sendBuffer.sendDataSize;
const int nBytesSent = inet_send(theSocket, sendPtr, sizeToSend, 0);
- if (nBytesSent > 0) {
+ if (nBytesSent > 0)
+ {
+ sent_any = true;
m_sendBuffer.bytesSent(nBytesSent);
sendCount ++;
sendSize += nBytesSent;
- if(sendCount == reportFreq){
+ if(sendCount == reportFreq)
+ {
reportSendLen(get_callback_obj(), remoteNodeId, sendCount, sendSize);
sendCount = 0;
sendSize = 0;
}
- } else {
+ }
+ else
+ {
+ if (nBytesSent < 0 && InetErrno == EAGAIN && sent_any)
+ break;
+
// Send failed
#if defined DEBUG_TRANSPORTER
ndbout_c("Send Failure(disconnect==%d) to node = %d nBytesSent = %d "
diff --git a/ndb/src/common/util/Bitmask.cpp b/ndb/src/common/util/Bitmask.cpp
index 4b90e5a01f4..22919fe585a 100644
--- a/ndb/src/common/util/Bitmask.cpp
+++ b/ndb/src/common/util/Bitmask.cpp
@@ -16,34 +16,63 @@
#include <Bitmask.hpp>
#include <NdbOut.hpp>
-#ifndef __TEST_BITMASK__
-
void
BitmaskImpl::getFieldImpl(const Uint32 src[],
unsigned shiftL, unsigned len, Uint32 dst[])
{
+ /* Copy whole words of src to dst, shifting src left
+ * by shiftL. Undefined bits of the last written dst word
+ * should be zeroed.
+ */
assert(shiftL < 32);
unsigned shiftR = 32 - shiftL;
unsigned undefined = shiftL ? ~0 : 0;
+ /* Merge first word with previously set bits if there's a shift */
* dst = shiftL ? * dst : 0;
-
- while(len >= 32)
- {
- * dst++ |= (* src) << shiftL;
- * dst = ((* src++) >> shiftR) & undefined;
- len -= 32;
- }
-
- if(len < shiftR)
+
+ /* Treat the zero-shift case separately to avoid
+ * trampling or reading past the end of src
+ */
+ if (shiftL == 0)
{
- * dst |= ((* src) & ((1 << len) - 1)) << shiftL;
+ while(len >= 32)
+ {
+ * dst++ = * src++;
+ len -=32;
+ }
+
+ if (len != 0)
+ {
+ /* Last word has some bits set */
+ Uint32 mask= ((1 << len) -1); // 0000111
+ * dst = (* src) & mask;
+ }
}
- else
+ else // shiftL !=0, need to build each word from two words shifted
{
- * dst++ |= ((* src) << shiftL);
- * dst = ((* src) >> shiftR) & ((1 << (len - shiftR)) - 1) & undefined;
+ while(len >= 32)
+ {
+ * dst++ |= (* src) << shiftL;
+ * dst = ((* src++) >> shiftR) & undefined;
+ len -= 32;
+ }
+
+ /* Have space for shiftR more bits in the current dst word
+ * is that enough?
+ */
+ if(len <= shiftR)
+ {
+ /* Fit the remaining bits in the current dst word */
+ * dst |= ((* src) & ((1 << len) - 1)) << shiftL;
+ }
+ else
+ {
+ /* Need to write to two dst words */
+ * dst++ |= ((* src) << shiftL);
+ * dst = ((* src) >> shiftR) & ((1 << (len - shiftR)) - 1) & undefined;
+ }
}
}
@@ -66,301 +95,23 @@ BitmaskImpl::setFieldImpl(Uint32 dst[],
len -= 32;
}
+ /* Copy last bits */
Uint32 mask = ((1 << len) -1);
* dst = (* dst & ~mask);
- if(len < shiftR)
+ if(len <= shiftR)
{
+ /* Remaining bits fit in current word */
* dst |= ((* src++) >> shiftL) & mask;
}
else
{
+ /* Remaining bits update 2 words */
* dst |= ((* src++) >> shiftL);
* dst |= ((* src) & ((1 << (len - shiftR)) - 1)) << shiftR ;
}
}
-#else
-
-static
-void print(const Uint32 src[], Uint32 len, Uint32 pos = 0)
-{
- printf("b'");
- for(unsigned i = 0; i<len; i++)
- {
- if(BitmaskImpl::get((pos + len + 31) >> 5, src, i+pos))
- printf("1");
- else
- printf("0");
- if((i & 31) == 31)
- printf(" ");
- }
-}
-
-#define DEBUG 0
-#include <Vector.hpp>
-static void do_test(int bitmask_size);
-
-int
-main(int argc, char** argv)
-{
- int loops = argc > 1 ? atoi(argv[1]) : 1000;
- int max_size = argc > 2 ? atoi(argv[2]) : 1000;
-
-
- for(int i = 0; i<loops; i++)
- do_test(1 + (rand() % max_size));
-}
-
-struct Alloc
-{
- Uint32 pos;
- Uint32 size;
- Vector<Uint32> data;
-};
-
-static void require(bool b)
-{
- if(!b) abort();
-}
-
-static
-bool cmp(const Uint32 b1[], const Uint32 b2[], Uint32 len)
-{
- Uint32 sz32 = (len + 31) >> 5;
- for(int i = 0; i<len; i++)
- {
- if(BitmaskImpl::get(sz32, b1, i) ^ BitmaskImpl::get(sz32, b2, i))
- return false;
- }
- return true;
-}
-
-
-static int val_pos = 0;
-static int val[] = { 384, 241, 32,
- 1,1,1,1, 0,0,0,0, 1,1,1,1, 0,0,0,0,
- 241 };
-
-static int lrand()
-{
-#if 0
- return val[val_pos++];
-#else
- return rand();
-#endif
-}
-
-static
-void rand(Uint32 dst[], Uint32 len)
-{
- for(int i = 0; i<len; i++)
- BitmaskImpl::set((len + 31) >> 5, dst, i, (lrand() % 1000) > 500);
-}
-
-static
-void simple(int pos, int size)
-{
- ndbout_c("simple pos: %d size: %d", pos, size);
- Vector<Uint32> _mask;
- Vector<Uint32> _src;
- Vector<Uint32> _dst;
- Uint32 sz32 = (size + pos + 32) >> 5;
- const Uint32 sz = 4 * sz32;
-
- Uint32 zero = 0;
- _mask.fill(sz32+1, zero);
- _src.fill(sz32+1, zero);
- _dst.fill(sz32+1, zero);
-
- Uint32 * src = _src.getBase();
- Uint32 * dst = _dst.getBase();
- Uint32 * mask = _mask.getBase();
-
- memset(src, 0x0, sz);
- memset(dst, 0x0, sz);
- memset(mask, 0xFF, sz);
- rand(src, size);
- BitmaskImpl::setField(sz32, mask, pos, size, src);
- BitmaskImpl::getField(sz32, mask, pos, size, dst);
- printf("src: "); print(src, size+31); printf("\n");
- printf("msk: "); print(mask, (sz32 << 5) + 31); printf("\n");
- printf("dst: "); print(dst, size+31); printf("\n");
- require(cmp(src, dst, size+31));
-};
-
-static
-void simple2(int size, int loops)
-{
- ndbout_c("simple2 %d - ", size);
- Vector<Uint32> _mask;
- Vector<Uint32> _src;
- Vector<Uint32> _dst;
-
- Uint32 sz32 = (size + 32) >> 5;
- Uint32 sz = sz32 << 2;
-
- Uint32 zero = 0;
- _mask.fill(sz32+1, zero);
- _src.fill(sz32+1, zero);
- _dst.fill(sz32+1, zero);
-
- Uint32 * src = _src.getBase();
- Uint32 * dst = _dst.getBase();
- Uint32 * mask = _mask.getBase();
-
- Vector<Uint32> save;
- for(int i = 0; i<loops; i++)
- {
- memset(mask, 0xFF, sz);
- memset(dst, 0xFF, sz);
- int len;
- int pos = 0;
- while(pos+1 < size)
- {
- memset(src, 0xFF, sz);
- while(!(len = rand() % (size - pos)));
- BitmaskImpl::setField(sz32, mask, pos, len, src);
- if(memcmp(dst, mask, sz))
- {
- ndbout_c("pos: %d len: %d", pos, len);
- print(mask, size);
- abort();
- }
- printf("[ %d %d ]", pos, len);
- save.push_back(pos);
- save.push_back(len);
- pos += len;
- }
-
- for(int j = 0; j<save.size(); )
- {
- pos = save[j++];
- len = save[j++];
- memset(src, 0xFF, sz);
- BitmaskImpl::getField(sz32, mask, pos, len, src);
- if(memcmp(dst, src, sz))
- {
- ndbout_c("pos: %d len: %d", pos, len);
- printf("src: "); print(src, size); printf("\n");
- printf("dst: "); print(dst, size); printf("\n");
- printf("msk: "); print(mask, size); printf("\n");
- abort();
- }
- }
- ndbout_c("");
- }
-}
-
-static void
-do_test(int bitmask_size)
-{
-#if 1
- simple(rand() % 33, (rand() % 63)+1);
-//#else
- Vector<Alloc> alloc_list;
- bitmask_size = (bitmask_size + 31) & ~31;
- Uint32 sz32 = (bitmask_size >> 5);
- Vector<Uint32> alloc_mask;
- Vector<Uint32> test_mask;
-
- ndbout_c("Testing bitmask of size %d", bitmask_size);
- Uint32 zero = 0;
- alloc_mask.fill(sz32, zero);
- test_mask.fill(sz32, zero);
-
- for(int i = 0; i<5000; i++)
- {
- Vector<Uint32> tmp;
- tmp.fill(sz32, zero);
-
- int pos = lrand() % (bitmask_size - 1);
- int free = 0;
- if(BitmaskImpl::get(sz32, alloc_mask.getBase(), pos))
- {
- // Bit was allocated
- // 1) Look up allocation
- // 2) Check data
- // 3) free it
- size_t j;
- int min, max;
- for(j = 0; j<alloc_list.size(); j++)
- {
- min = alloc_list[j].pos;
- max = min + alloc_list[j].size;
- if(pos >= min && pos < max)
- {
- break;
- }
- }
- require(pos >= min && pos < max);
- BitmaskImpl::getField(sz32, test_mask.getBase(), min, max-min,
- tmp.getBase());
- if(DEBUG)
- {
- printf("freeing [ %d %d ]", min, max);
- printf("- mask: ");
- print(tmp.getBase(), max - min);
-
- printf(" save: ");
- size_t k;
- Alloc& a = alloc_list[j];
- for(k = 0; k<a.data.size(); k++)
- printf("%.8x ", a.data[k]);
- printf("\n");
- }
- int bytes = (max - min + 7) >> 3;
- if(!cmp(tmp.getBase(), alloc_list[j].data.getBase(), max - min))
- {
- abort();
- }
- while(min < max)
- BitmaskImpl::clear(sz32, alloc_mask.getBase(), min++);
- alloc_list.erase(j);
- }
- else
- {
- Vector<Uint32> tmp;
- tmp.fill(sz32, zero);
-
- // Bit was free
- // 1) Check how much space is avaiable
- // 2) Create new allocation of lrandom size
- // 3) Fill data with lrandom data
- // 4) Update alloc mask
- while(pos+free < bitmask_size &&
- !BitmaskImpl::get(sz32, alloc_mask.getBase(), pos+free))
- free++;
-
- Uint32 sz =
- (free <= 64 && ((lrand() % 100) > 80)) ? free : (lrand() % free);
- sz = sz ? sz : 1;
- sz = pos + sz == bitmask_size ? sz - 1 : sz;
- Alloc a;
- a.pos = pos;
- a.size = sz;
- a.data.fill(((sz+31)>> 5)-1, zero);
- if(DEBUG)
- printf("pos %d -> alloc [ %d %d ]", pos, pos, pos+sz);
- for(size_t j = 0; j<sz; j++)
- {
- BitmaskImpl::set(sz32, alloc_mask.getBase(), pos+j);
- if((lrand() % 1000) > 500)
- BitmaskImpl::set((sz + 31) >> 5, a.data.getBase(), j);
- }
- if(DEBUG)
- {
- printf("- mask: ");
- print(a.data.getBase(), sz);
- printf("\n");
- }
- BitmaskImpl::setField(sz32, test_mask.getBase(), pos, sz,
- a.data.getBase());
- alloc_list.push_back(a);
- }
- }
-#endif
-}
-
-template class Vector<Alloc>;
-template class Vector<Uint32>;
-#endif
+/* Bitmask testcase code moved from here to
+ * storage/ndb/test/ndbapi/testBitfield.cpp
+ * to get coverage from automated testing
+ */
diff --git a/ndb/src/common/util/NdbOut.cpp b/ndb/src/common/util/NdbOut.cpp
index 7ca7c91e266..61de2be7572 100644
--- a/ndb/src/common/util/NdbOut.cpp
+++ b/ndb/src/common/util/NdbOut.cpp
@@ -29,7 +29,7 @@ static const char * fms[] = {
"%d", "0x%08x", // Int32
"%u", "0x%08x", // Uint32
"%lld", "0x%016llx", // Int64
- "%llu", "0x%016llx" // Uint64
+ "%llu", "0x%016llx", // Uint64
"%llu", "0x%016llx" // UintPtr
};
diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp
index 70721bfca56..52ab11b8388 100644
--- a/ndb/src/kernel/blocks/backup/Backup.cpp
+++ b/ndb/src/kernel/blocks/backup/Backup.cpp
@@ -374,16 +374,18 @@ Backup::execCONTINUEB(Signal* signal)
ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
FsBuffer & buf = filePtr.p->operation.dataBuffer;
- if(buf.getFreeSize() + buf.getMinRead() < buf.getUsableSize()) {
+ if(buf.getFreeSize() < buf.getMaxWrite()) {
jam();
TablePtr tabPtr LINT_SET_PTR;
c_tablePool.getPtr(tabPtr, Tdata2);
- DEBUG_OUT("Backup - Buffer full - " << buf.getFreeSize()
- << " + " << buf.getMinRead()
- << " < " << buf.getUsableSize()
- << " - tableId = " << tabPtr.p->tableId);
-
+ DEBUG_OUT("Backup - Buffer full - "
+ << buf.getFreeSize()
+ << " < " << buf.getMaxWrite()
+ << " (sz: " << buf.getUsableSize()
+ << " getMinRead: " << buf.getMinRead()
+ << ") - tableId = " << tabPtr.p->tableId);
+
signal->theData[0] = BackupContinueB::BUFFER_FULL_META;
signal->theData[1] = Tdata1;
signal->theData[2] = Tdata2;
diff --git a/ndb/src/kernel/blocks/backup/Backup.hpp b/ndb/src/kernel/blocks/backup/Backup.hpp
index 8b0c27727b0..e67d8f09f0e 100644
--- a/ndb/src/kernel/blocks/backup/Backup.hpp
+++ b/ndb/src/kernel/blocks/backup/Backup.hpp
@@ -518,7 +518,7 @@ public:
Uint32 m_diskless;
STATIC_CONST(NO_OF_PAGES_META_FILE =
- (MAX_WORDS_META_FILE + BACKUP_WORDS_PER_PAGE - 1) /
+ (2*MAX_WORDS_META_FILE + BACKUP_WORDS_PER_PAGE - 1) /
BACKUP_WORDS_PER_PAGE);
/**
diff --git a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
index 6fe0eefcdb5..829156ef15a 100644
--- a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
+++ b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
@@ -198,6 +198,7 @@
#define ZUNSUPPORTED_BRANCH 892
#define ZSTORED_SEIZE_ATTRINBUFREC_ERROR 873 // Part of Scan
+#define ZSTORED_TOO_MUCH_ATTRINFO_ERROR 874
#define ZREAD_ONLY_CONSTRAINT_VIOLATION 893
#define ZVAR_SIZED_NOT_SUPPORTED 894
@@ -1085,7 +1086,7 @@ public:
/*
* TUX checks if tuple is visible to scan.
*/
- bool tuxQueryTh(Uint32 fragPtrI, Uint32 tupAddr, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, Uint32 savePointId);
+ bool tuxQueryTh(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, bool dirty, Uint32 savePointId);
private:
BLOCK_DEFINES(Dbtup);
@@ -1942,6 +1943,8 @@ private:
bool getPageThroughSavePoint(Operationrec* const regOperPtr,
Operationrec* const leaderOpPtr);
+ bool find_savepoint(OperationrecPtr& loopOpPtr, Uint32 savepointId);
+
Uint32 calculateChecksum(Page* const pagePtr, Uint32 tupHeadOffset, Uint32 tupHeadSize);
void setChecksum(Page* const pagePtr, Uint32 tupHeadOffset, Uint32 tupHeadSize);
@@ -2171,7 +2174,8 @@ private:
Operationrec* regOperPtr,
Uint32 lenAttrInfo);
void storedSeizeAttrinbufrecErrorLab(Signal* signal,
- Operationrec* regOperPtr);
+ Operationrec* regOperPtr,
+ Uint32 errorCode);
bool storedProcedureAttrInfo(Signal* signal,
Operationrec* regOperPtr,
Uint32 length,
@@ -2467,4 +2471,22 @@ bool Dbtup::isPageUndoLogged(Fragrecord* const regFragPtr,
return false;
}//Dbtup::isUndoLoggingNeeded()
+inline
+bool Dbtup::find_savepoint(OperationrecPtr& loopOpPtr, Uint32 savepointId)
+{
+ while (true) {
+ if (savepointId > loopOpPtr.p->savePointId) {
+ jam();
+ return true;
+ }
+ // note 5.0 has reversed next/prev pointers
+ loopOpPtr.i = loopOpPtr.p->nextActiveOp;
+ if (loopOpPtr.i == RNIL) {
+ break;
+ }
+ ptrCheckGuard(loopOpPtr, cnoOfOprec, operationrec);
+ }
+ return false;
+}
+
#endif
diff --git a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
index 298fb183bc3..9ab4fb34827 100644
--- a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
+++ b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
@@ -77,6 +77,14 @@ void Dbtup::copyAttrinfo(Signal* signal,
RbufLen = copyAttrBufPtr.p->attrbuf[ZBUF_DATA_LEN];
Rnext = copyAttrBufPtr.p->attrbuf[ZBUF_NEXT];
Rfirst = cfirstfreeAttrbufrec;
+ /*
+ * ATTRINFO comes from 2 mutually exclusive places:
+ * 1) TUPKEYREQ (also interpreted part)
+ * 2) STORED_PROCREQ before scan start
+ * Assert here that both have a check for overflow.
+ * The "<" instead of "<=" is intentional.
+ */
+ ndbrequire(RinBufIndex + RbufLen < ZATTR_BUFFER_SIZE);
MEMCOPY_NO_WORDS(&inBuffer[RinBufIndex],
&copyAttrBufPtr.p->attrbuf[0],
RbufLen);
diff --git a/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp b/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp
index 964d8578217..c03ca35bc6a 100644
--- a/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp
+++ b/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp
@@ -246,8 +246,18 @@ Dbtup::accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIn
return ret;
}
+/*
+ * TUX index contains all tuple versions. A scan in TUX has scanned
+ * one of them and asks if it can be returned as scan result. This
+ * depends on trans id, dirty read flag, and savepoint within trans.
+ *
+ * Previously this faked a ZREAD operation and used getPage().
+ * In TUP getPage() is run after ACC locking, but TUX comes here
+ * before ACC access. Instead of modifying getPage() it is more
+ * clear to do the full check here.
+ */
bool
-Dbtup::tuxQueryTh(Uint32 fragPtrI, Uint32 tupAddr, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, Uint32 savePointId)
+Dbtup::tuxQueryTh(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, bool dirty, Uint32 savePointId)
{
ljamEntry();
FragrecordPtr fragPtr;
@@ -256,33 +266,73 @@ Dbtup::tuxQueryTh(Uint32 fragPtrI, Uint32 tupAddr, Uint32 tupVersion, Uint32 tra
TablerecPtr tablePtr;
tablePtr.i = fragPtr.p->fragTableId;
ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
- // get page
PagePtr pagePtr;
- Uint32 fragPageId = tupAddr >> MAX_TUPLES_BITS;
- Uint32 pageIndex = tupAddr & ((1 << MAX_TUPLES_BITS ) - 1);
- // use temp op rec
- Operationrec tempOp;
- tempOp.fragPageId = fragPageId;
- tempOp.pageIndex = pageIndex;
- tempOp.transid1 = transId1;
- tempOp.transid2 = transId2;
- tempOp.savePointId = savePointId;
- tempOp.optype = ZREAD;
- tempOp.dirtyOp = 1;
- if (getPage(pagePtr, &tempOp, fragPtr.p, tablePtr.p)) {
- /*
- * We use the normal getPage which will return the tuple to be used
- * for this transaction and savepoint id. If its tuple version
- * equals the requested then we have a visible tuple otherwise not.
- */
+ pagePtr.i = pageId;
+ ptrCheckGuard(pagePtr, cnoOfPage, page);
+
+ OperationrecPtr currOpPtr;
+ currOpPtr.i = pagePtr.p->pageWord[pageOffset];
+ if (currOpPtr.i == RNIL) {
+ ljam();
+ // tuple has no operation, any scan can see it
+ return true;
+ }
+ ptrCheckGuard(currOpPtr, cnoOfOprec, operationrec);
+
+ const bool sameTrans =
+ transId1 == currOpPtr.p->transid1 &&
+ transId2 == currOpPtr.p->transid2;
+
+ bool res = false;
+ OperationrecPtr loopOpPtr = currOpPtr;
+
+ if (!sameTrans) {
ljam();
- Uint32 read_tupVersion = pagePtr.p->pageWord[tempOp.pageOffset + 1];
- if (read_tupVersion == tupVersion) {
+ if (!dirty) {
ljam();
- return true;
+ if (currOpPtr.p->prevActiveOp == RNIL) {
+ ljam();
+ // last op - TUX makes ACC lock request in same timeslice
+ res = true;
+ }
+ }
+ else {
+ // loop to first op (returns false)
+ find_savepoint(loopOpPtr, 0);
+ const Uint32 op_type = loopOpPtr.p->optype;
+
+ if (op_type != ZINSERT) {
+ ljam();
+ // read committed version from the page
+ const Uint32 origVersion = pagePtr.p->pageWord[pageOffset + 1];
+ if (origVersion == tupVersion) {
+ ljam();
+ res = true;
+ }
+ }
}
}
- return false;
+ else {
+ ljam();
+ // for own trans, ignore dirty flag
+
+ if (find_savepoint(loopOpPtr, savePointId)) {
+ ljam();
+ const Uint32 op_type = loopOpPtr.p->optype;
+
+ if (op_type != ZDELETE) {
+ ljam();
+ // check if this op has produced the scanned version
+ Uint32 loopVersion = loopOpPtr.p->tupVersion;
+ if (loopVersion == tupVersion) {
+ ljam();
+ res = true;
+ }
+ }
+ }
+ }
+
+ return res;
}
// ordered index build
diff --git a/ndb/src/kernel/blocks/dbtup/DbtupStoredProcDef.cpp b/ndb/src/kernel/blocks/dbtup/DbtupStoredProcDef.cpp
index 37fcd3df317..f4215b6da7d 100644
--- a/ndb/src/kernel/blocks/dbtup/DbtupStoredProcDef.cpp
+++ b/ndb/src/kernel/blocks/dbtup/DbtupStoredProcDef.cpp
@@ -108,6 +108,11 @@ void Dbtup::scanProcedure(Signal* signal,
regOperPtr->attrinbufLen = lenAttrInfo;
regOperPtr->currentAttrinbufLen = 0;
regOperPtr->pageOffset = storedPtr.i;
+ if (lenAttrInfo >= ZATTR_BUFFER_SIZE) { // yes ">="
+ jam();
+ // send REF and change state to ignore the ATTRINFO to come
+ storedSeizeAttrinbufrecErrorLab(signal, regOperPtr, ZSTORED_TOO_MUCH_ATTRINFO_ERROR);
+ }
}//Dbtup::scanProcedure()
void Dbtup::copyProcedure(Signal* signal,
@@ -146,7 +151,7 @@ bool Dbtup::storedProcedureAttrInfo(Signal* signal,
Uint32 RnoFree = cnoFreeAttrbufrec;
if (ERROR_INSERTED(4004) && !copyProcedure) {
CLEAR_ERROR_INSERT_VALUE;
- storedSeizeAttrinbufrecErrorLab(signal, regOperPtr);
+ storedSeizeAttrinbufrecErrorLab(signal, regOperPtr, ZSTORED_SEIZE_ATTRINBUFREC_ERROR);
return false;
}//if
regOperPtr->currentAttrinbufLen += length;
@@ -162,7 +167,7 @@ bool Dbtup::storedProcedureAttrInfo(Signal* signal,
regAttrPtr.p->attrbuf[ZBUF_NEXT] = RNIL;
} else {
ljam();
- storedSeizeAttrinbufrecErrorLab(signal, regOperPtr);
+ storedSeizeAttrinbufrecErrorLab(signal, regOperPtr, ZSTORED_SEIZE_ATTRINBUFREC_ERROR);
return false;
}//if
if (regOperPtr->firstAttrinbufrec == RNIL) {
@@ -190,7 +195,7 @@ bool Dbtup::storedProcedureAttrInfo(Signal* signal,
}//if
if (ERROR_INSERTED(4005) && !copyProcedure) {
CLEAR_ERROR_INSERT_VALUE;
- storedSeizeAttrinbufrecErrorLab(signal, regOperPtr);
+ storedSeizeAttrinbufrecErrorLab(signal, regOperPtr, ZSTORED_SEIZE_ATTRINBUFREC_ERROR);
return false;
}//if
@@ -211,7 +216,8 @@ bool Dbtup::storedProcedureAttrInfo(Signal* signal,
}//Dbtup::storedProcedureAttrInfo()
void Dbtup::storedSeizeAttrinbufrecErrorLab(Signal* signal,
- Operationrec* regOperPtr)
+ Operationrec* regOperPtr,
+ Uint32 errorCode)
{
StoredProcPtr storedPtr;
c_storedProcPool.getPtr(storedPtr, (Uint32)regOperPtr->pageOffset);
@@ -222,7 +228,7 @@ void Dbtup::storedSeizeAttrinbufrecErrorLab(Signal* signal,
regOperPtr->lastAttrinbufrec = RNIL;
regOperPtr->transstate = ERROR_WAIT_STORED_PROCREQ;
signal->theData[0] = regOperPtr->userpointer;
- signal->theData[1] = ZSTORED_SEIZE_ATTRINBUFREC_ERROR;
+ signal->theData[1] = errorCode;
signal->theData[2] = regOperPtr->pageOffset;
sendSignal(regOperPtr->userblockref, GSN_STORED_PROCREF, signal, 3, JBB);
}//Dbtup::storedSeizeAttrinbufrecErrorLab()
diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp
index 7eae1486d43..f72b1db1cc5 100644
--- a/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp
+++ b/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp
@@ -216,7 +216,8 @@ Dbtux::execTUX_BOUND_INFO(Signal* signal)
// fill in any gap
while (maxAttrId[j] <= attrId) {
jam();
- BoundInfo& b = boundInfo[j][maxAttrId[j]++];
+ BoundInfo& b = boundInfo[j][maxAttrId[j]];
+ maxAttrId[j]++;
b.type2 = -1;
}
BoundInfo& b = boundInfo[j][attrId];
@@ -984,7 +985,8 @@ Dbtux::scanVisible(ScanOpPtr scanPtr, TreeEnt ent)
const Frag& frag = *c_fragPool.getPtr(scan.m_fragPtrI);
Uint32 fragBit = ent.m_fragBit;
Uint32 tableFragPtrI = frag.m_tupTableFragPtrI[fragBit];
- Uint32 tupAddr = getTupAddr(frag, ent);
+ Uint32 pageId = ent.m_tupLoc.getPageId();
+ Uint32 pageOffset = ent.m_tupLoc.getPageOffset();
Uint32 tupVersion = ent.m_tupVersion;
// check for same tuple twice in row
if (scan.m_scanEnt.m_tupLoc == ent.m_tupLoc &&
@@ -994,8 +996,9 @@ Dbtux::scanVisible(ScanOpPtr scanPtr, TreeEnt ent)
}
Uint32 transId1 = scan.m_transId1;
Uint32 transId2 = scan.m_transId2;
+ bool dirty = scan.m_readCommitted;
Uint32 savePointId = scan.m_savePointId;
- bool ret = c_tup->tuxQueryTh(tableFragPtrI, tupAddr, tupVersion, transId1, transId2, savePointId);
+ bool ret = c_tup->tuxQueryTh(tableFragPtrI, pageId, pageOffset, tupVersion, transId1, transId2, dirty, savePointId);
jamEntry();
return ret;
}
diff --git a/ndb/src/kernel/vm/DLHashTable.hpp b/ndb/src/kernel/vm/DLHashTable.hpp
index acf53944b07..cc6802db2bc 100644
--- a/ndb/src/kernel/vm/DLHashTable.hpp
+++ b/ndb/src/kernel/vm/DLHashTable.hpp
@@ -45,8 +45,8 @@ public:
/**
* Seize element from pool - return i
*
- * Note must be either added using <b>add</b> or released
- * using <b>release</b>
+ * Note *must* be added using <b>add</b> (even before hash.release)
+ * or be released using pool
*/
bool seize(Ptr<T> &);
@@ -374,7 +374,14 @@ DLHashTable<T>::remove(Ptr<T> & ptr){
prevP->nextHash = next;
} else {
const Uint32 hv = ptr.p->hashValue() & mask;
- hashValues[hv] = next;
+ if (hashValues[hv] == ptr.i)
+ {
+ hashValues[hv] = next;
+ }
+ else
+ {
+ // Will add assert in 5.1
+ }
}
if(next != RNIL){
@@ -395,7 +402,14 @@ DLHashTable<T>::release(Ptr<T> & ptr){
prevP->nextHash = next;
} else {
const Uint32 hv = ptr.p->hashValue() & mask;
- hashValues[hv] = next;
+ if (hashValues[hv] == ptr.i)
+ {
+ hashValues[hv] = next;
+ }
+ else
+ {
+ // Will add assert in 5.1
+ }
}
if(next != RNIL){
diff --git a/ndb/src/kernel/vm/DLHashTable2.hpp b/ndb/src/kernel/vm/DLHashTable2.hpp
index ad03e8ed3ba..20515af8cf6 100644
--- a/ndb/src/kernel/vm/DLHashTable2.hpp
+++ b/ndb/src/kernel/vm/DLHashTable2.hpp
@@ -43,8 +43,8 @@ public:
/**
* Seize element from pool - return i
*
- * Note must be either added using <b>add</b> or released
- * using <b>release</b>
+ * Note *must* be added using <b>add</b> (even before hash.release)
+ * or be released using pool
*/
bool seize(Ptr<T> &);
@@ -375,7 +375,14 @@ DLHashTable2<T, U>::remove(Ptr<T> & ptr){
prevP->nextHash = next;
} else {
const Uint32 hv = ptr.p->hashValue() & mask;
- hashValues[hv] = next;
+ if (hashValues[hv] == ptr.i)
+ {
+ hashValues[hv] = next;
+ }
+ else
+ {
+ // Will add assert in 5.1
+ }
}
if(next != RNIL){
@@ -396,7 +403,14 @@ DLHashTable2<T, U>::release(Ptr<T> & ptr){
prevP->nextHash = next;
} else {
const Uint32 hv = ptr.p->hashValue() & mask;
- hashValues[hv] = next;
+ if (hashValues[hv] == ptr.i)
+ {
+ hashValues[hv] = next;
+ }
+ else
+ {
+ // Will add assert in 5.1
+ }
}
if(next != RNIL){
diff --git a/ndb/src/kernel/vm/pc.hpp b/ndb/src/kernel/vm/pc.hpp
index 269719c44d0..ed592620a2e 100644
--- a/ndb/src/kernel/vm/pc.hpp
+++ b/ndb/src/kernel/vm/pc.hpp
@@ -49,7 +49,7 @@
theEmulatedJamBlockNumber = number(); \
Uint32 tEmulatedJamIndex = theEmulatedJamIndex; \
*(Uint32*)(theEmulatedJam + tEmulatedJamIndex) = \
- ((theEmulatedJamBlockNumber << 20) | line); \
+ ((theEmulatedJamBlockNumber << 20) | (line)); \
theEmulatedJamIndex = (tEmulatedJamIndex + 4) & JAM_MASK; }
#else
@@ -72,7 +72,7 @@
theEmulatedJamBlockNumber = number(); \
Uint32 tEmulatedJamIndex = theEmulatedJamIndex; \
*(Uint32*)((UintPtr)theEmulatedJam + (Uint32)tEmulatedJamIndex) = \
- ((theEmulatedJamBlockNumber << 20) | line); \
+ ((theEmulatedJamBlockNumber << 20) | (line)); \
theEmulatedJamIndex = (tEmulatedJamIndex + 4) & JAM_MASK; }
#endif
@@ -232,7 +232,7 @@
#define MEMCOPY_PAGE(to, from, page_size_in_bytes) \
memcpy((void*)(to), (void*)(from), (size_t)(page_size_in_bytes));
#define MEMCOPY_NO_WORDS(to, from, no_of_words) \
- memcpy((to), (void*)(from), (size_t)(no_of_words << 2));
+ memcpy((to), (void*)(from), (size_t)((no_of_words) << 2));
template <class T>
struct Ptr {
diff --git a/ndb/src/mgmapi/ndb_logevent.cpp b/ndb/src/mgmapi/ndb_logevent.cpp
index 3885bb79536..f0b7c26cf78 100644
--- a/ndb/src/mgmapi/ndb_logevent.cpp
+++ b/ndb/src/mgmapi/ndb_logevent.cpp
@@ -256,7 +256,7 @@ struct Ndb_logevent_body_row ndb_logevent_body[]= {
ROW( ReceiveBytesStatistic, "mean_received_bytes", 2, mean_received_bytes),
ROW( MemoryUsage, "gth", 1, gth),
- ROW( MemoryUsage, "page_size_kb", 2, page_size_kb),
+ ROW( MemoryUsage, "page_size_bytes", 2, page_size_bytes),
ROW( MemoryUsage, "pages_used", 3, pages_used),
ROW( MemoryUsage, "pages_total", 4, pages_total),
ROW( MemoryUsage, "block", 5, block),
diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp
index 1036461d404..b72f7b12f9b 100644
--- a/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -921,10 +921,14 @@ event_thread_run(void* p)
{
do_event_thread= 1;
do {
- if (ndb_logevent_get_next(log_handle, &log_event, 2000) <= 0)
- continue;
- Guard g(printmutex);
- printLogEvent(&log_event);
+ int res= ndb_logevent_get_next(log_handle, &log_event, 2000);
+ if (res > 0)
+ {
+ Guard g(printmutex);
+ printLogEvent(&log_event);
+ }
+ else if (res < 0)
+ break;
} while(do_event_thread);
ndb_mgm_destroy_logevent_handle(&log_handle);
}
@@ -2722,8 +2726,9 @@ CommandInterpreter::executeStartBackup(char* parameters, bool interactive)
{
int count = 0;
int retry = 0;
+ int res;
do {
- if (ndb_logevent_get_next(log_handle, &log_event, 60000) > 0)
+ if ((res= ndb_logevent_get_next(log_handle, &log_event, 60000)) > 0)
{
int print = 0;
switch (log_event.type) {
@@ -2753,7 +2758,7 @@ CommandInterpreter::executeStartBackup(char* parameters, bool interactive)
{
retry++;
}
- } while(count < 2 && retry < 3);
+ } while(res >= 0 && count < 2 && retry < 3);
if (retry >= 3)
ndbout << "get backup event failed for " << retry << " times" << endl;
diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp
index 3600dfdeab3..2a22fc72183 100644
--- a/ndb/src/mgmsrv/ConfigInfo.cpp
+++ b/ndb/src/mgmsrv/ConfigInfo.cpp
@@ -398,7 +398,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
ConfigInfo::CI_INT,
MANDATORY,
"1",
- STR_VALUE(MAX_NODES) },
+ STR_VALUE(MAX_DATA_NODE_ID) },
{
CFG_NODE_ID,
@@ -410,7 +410,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
ConfigInfo::CI_INT,
MANDATORY,
"1",
- STR_VALUE(MAX_NODES) },
+ STR_VALUE(MAX_DATA_NODE_ID) },
{
KEY_INTERNAL,
@@ -1261,7 +1261,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
ConfigInfo::CI_INT,
MANDATORY,
"1",
- STR_VALUE(MAX_NODES) },
+ STR_VALUE(MAX_NODES_ID) },
{
CFG_NODE_ID,
@@ -1273,7 +1273,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
ConfigInfo::CI_INT,
MANDATORY,
"1",
- STR_VALUE(MAX_NODES) },
+ STR_VALUE(MAX_NODES_ID) },
{
KEY_INTERNAL,
@@ -1404,7 +1404,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
ConfigInfo::CI_INT,
MANDATORY,
"1",
- STR_VALUE(MAX_NODES) },
+ STR_VALUE(MAX_NODES_ID) },
{
CFG_NODE_ID,
@@ -1416,7 +1416,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
ConfigInfo::CI_INT,
MANDATORY,
"1",
- STR_VALUE(MAX_NODES) },
+ STR_VALUE(MAX_NODES_ID) },
{
CFG_LOG_DESTINATION,
diff --git a/ndb/src/ndbapi/DictCache.cpp b/ndb/src/ndbapi/DictCache.cpp
index 6a815067233..9234b6b5219 100644
--- a/ndb/src/ndbapi/DictCache.cpp
+++ b/ndb/src/ndbapi/DictCache.cpp
@@ -46,6 +46,7 @@ Ndb_local_table_info::Ndb_local_table_info(NdbTableImpl *table_impl)
m_table_impl= table_impl;
m_first_tuple_id = ~(Uint64)0;
m_last_tuple_id = ~(Uint64)0;
+ m_highest_seen = 0;
}
Ndb_local_table_info::~Ndb_local_table_info()
diff --git a/ndb/src/ndbapi/DictCache.hpp b/ndb/src/ndbapi/DictCache.hpp
index db90a07d487..6ada55cc05e 100644
--- a/ndb/src/ndbapi/DictCache.hpp
+++ b/ndb/src/ndbapi/DictCache.hpp
@@ -36,6 +36,7 @@ public:
// range of cached tuple ids per thread
Uint64 m_first_tuple_id;
Uint64 m_last_tuple_id;
+ Uint64 m_highest_seen;
Uint64 m_local_data[1]; // Must be last member. Used to access extra space.
private:
diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp
index dcdee3d4ea1..c784f557b4c 100644
--- a/ndb/src/ndbapi/Ndb.cpp
+++ b/ndb/src/ndbapi/Ndb.cpp
@@ -767,8 +767,8 @@ Ndb::getNodeId()
}
/****************************************************************************
-Uint64 getAutoIncrementValue( const char* aTableName,
- Uint64 & tupleId,
+int getAutoIncrementValue( const char* aTableName,
+ Uint64 & autoValue,
Uint32 cacheSize,
Uint64 step,
Uint64 start);
@@ -779,6 +779,7 @@ Parameters: aTableName (IN) : The table name.
step (IN) : Specifies the step between the
autoincrement values.
start (IN) : Start value for first value
+Returns: 0 if succesful, -1 if error encountered
Remark: Returns a new autoincrement value to the application.
The autoincrement values can be increased by steps
(default 1) and a number of values can be prefetched
@@ -892,9 +893,18 @@ Ndb::getTupleIdFromNdb(Ndb_local_table_info* info,
DBUG_RETURN(0);
}
+/****************************************************************************
+int readAutoIncrementValue( const char* aTableName,
+ Uint64 & autoValue);
+
+Parameters: aTableName (IN) : The table name.
+ autoValue (OUT) : The current autoincrement value
+Returns: 0 if succesful, -1 if error encountered
+Remark: Returns the current autoincrement value to the application.
+****************************************************************************/
int
Ndb::readAutoIncrementValue(const char* aTableName,
- Uint64 & tupleId)
+ Uint64 & autoValue)
{
DBUG_ENTER("Ndb::readAutoIncrementValue");
BaseString internal_tabname(internalize_table_name(aTableName));
@@ -905,15 +915,15 @@ Ndb::readAutoIncrementValue(const char* aTableName,
theError.code = theDictionary->getNdbError().code;
DBUG_RETURN(-1);
}
- if (readTupleIdFromNdb(info, tupleId) == -1)
+ if (readTupleIdFromNdb(info, autoValue) == -1)
DBUG_RETURN(-1);
- DBUG_PRINT("info", ("value %lu", (ulong)tupleId));
+ DBUG_PRINT("info", ("value %lu", (ulong)autoValue));
DBUG_RETURN(0);
}
int
Ndb::readAutoIncrementValue(const NdbDictionary::Table * aTable,
- Uint64 & tupleId)
+ Uint64 & autoValue)
{
DBUG_ENTER("Ndb::readAutoIncrementValue");
assert(aTable != 0);
@@ -926,9 +936,9 @@ Ndb::readAutoIncrementValue(const NdbDictionary::Table * aTable,
theError.code = theDictionary->getNdbError().code;
DBUG_RETURN(-1);
}
- if (readTupleIdFromNdb(info, tupleId) == -1)
+ if (readTupleIdFromNdb(info, autoValue) == -1)
DBUG_RETURN(-1);
- DBUG_PRINT("info", ("value %lu", (ulong)tupleId));
+ DBUG_PRINT("info", ("value %lu", (ulong)autoValue));
DBUG_RETURN(0);
}
@@ -956,9 +966,20 @@ Ndb::readTupleIdFromNdb(Ndb_local_table_info* info,
DBUG_RETURN(0);
}
+/****************************************************************************
+int setAutoIncrementValue( const char* aTableName,
+ Uint64 autoValue,
+ bool modify);
+
+Parameters: aTableName (IN) : The table name.
+ autoValue (IN) : The new autoincrement value
+ modify (IN) : Modify existing value (not initialization)
+Returns: 0 if succesful, -1 if error encountered
+Remark: Sets a new autoincrement value for the application.
+****************************************************************************/
int
Ndb::setAutoIncrementValue(const char* aTableName,
- Uint64 tupleId, bool increase)
+ Uint64 autoValue, bool modify)
{
DBUG_ENTER("Ndb::setAutoIncrementValue");
BaseString internal_tabname(internalize_table_name(aTableName));
@@ -969,14 +990,14 @@ Ndb::setAutoIncrementValue(const char* aTableName,
theError.code = theDictionary->getNdbError().code;
DBUG_RETURN(-1);
}
- if (setTupleIdInNdb(info, tupleId, increase) == -1)
+ if (setTupleIdInNdb(info, autoValue, modify) == -1)
DBUG_RETURN(-1);
DBUG_RETURN(0);
}
int
Ndb::setAutoIncrementValue(const NdbDictionary::Table * aTable,
- Uint64 tupleId, bool increase)
+ Uint64 autoValue, bool modify)
{
DBUG_ENTER("Ndb::setAutoIncrementValue");
assert(aTable != 0);
@@ -989,38 +1010,42 @@ Ndb::setAutoIncrementValue(const NdbDictionary::Table * aTable,
theError.code = theDictionary->getNdbError().code;
DBUG_RETURN(-1);
}
- if (setTupleIdInNdb(info, tupleId, increase) == -1)
+ if (setTupleIdInNdb(info, autoValue, modify) == -1)
DBUG_RETURN(-1);
DBUG_RETURN(0);
}
int
Ndb::setTupleIdInNdb(Ndb_local_table_info* info,
- Uint64 tupleId, bool increase)
+ Uint64 tupleId, bool modify)
{
DBUG_ENTER("Ndb::setTupleIdInNdb");
- if (increase)
+ if (modify)
{
- if (info->m_first_tuple_id != info->m_last_tuple_id)
+ if (checkTupleIdInNdb(info, tupleId))
{
- assert(info->m_first_tuple_id < info->m_last_tuple_id);
- if (tupleId <= info->m_first_tuple_id + 1)
- DBUG_RETURN(0);
- if (tupleId <= info->m_last_tuple_id)
+ if (info->m_first_tuple_id != info->m_last_tuple_id)
{
- info->m_first_tuple_id = tupleId - 1;
- DBUG_PRINT("info",
- ("Setting next auto increment cached value to %lu",
- (ulong)tupleId));
- DBUG_RETURN(0);
+ assert(info->m_first_tuple_id < info->m_last_tuple_id);
+ if (tupleId <= info->m_first_tuple_id + 1)
+ DBUG_RETURN(0);
+ if (tupleId <= info->m_last_tuple_id)
+ {
+ info->m_first_tuple_id = tupleId - 1;
+ DBUG_PRINT("info",
+ ("Setting next auto increment cached value to %lu",
+ (ulong)tupleId));
+ DBUG_RETURN(0);
+ }
}
+ /*
+ * if tupleId <= NEXTID, do nothing. otherwise update NEXTID to
+ * tupleId and set cached range to first = last = tupleId - 1.
+ */
+ Uint64 opValue = tupleId;
+ if (opTupleIdOnNdb(info, opValue, 2) == -1)
+ DBUG_RETURN(-1);
}
- /*
- * if tupleId <= NEXTID, do nothing. otherwise update NEXTID to
- * tupleId and set cached range to first = last = tupleId - 1.
- */
- if (opTupleIdOnNdb(info, tupleId, 2) == -1)
- DBUG_RETURN(-1);
}
else
{
@@ -1034,6 +1059,32 @@ Ndb::setTupleIdInNdb(Ndb_local_table_info* info,
}
int
+Ndb::checkTupleIdInNdb(Ndb_local_table_info* info, Uint64 tupleId)
+{
+ DBUG_ENTER("Ndb::checkTupleIdIndNdb");
+ if ((info->m_first_tuple_id != ~(Uint64)0) &&
+ (info->m_first_tuple_id > tupleId))
+ {
+ /*
+ * If we have ever cached a value in this object and this cached
+ * value is larger than the value we're trying to set then we
+ * need not check with the real value in the SYSTAB_0 table.
+ */
+ DBUG_RETURN(0);
+ }
+ if (info->m_highest_seen > tupleId)
+ {
+ /*
+ * Although we've never cached any higher value we have read
+ * a higher value and again it isn't necessary to change the
+ * auto increment value.
+ */
+ DBUG_RETURN(0);
+ }
+ DBUG_RETURN(1);
+}
+
+int
Ndb::opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op)
{
DBUG_ENTER("Ndb::opTupleIdOnNdb");
@@ -1094,6 +1145,7 @@ Ndb::opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op)
info->m_first_tuple_id = ~(Uint64)0;
info->m_last_tuple_id = ~(Uint64)0;
+ info->m_highest_seen = 0;
break;
case 2:
tOperation->interpretedUpdateTuple();
@@ -1103,19 +1155,18 @@ Ndb::opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op)
// compare NEXTID >= opValue
tOperation->branch_le(2, 1, 0);
tOperation->write_attr("NEXTID", 1);
- tOperation->interpret_exit_ok();
tOperation->def_label(0);
- tOperation->interpret_exit_nok(9999);
-
+ tOperation->interpret_exit_ok();
+ tRecAttrResult = tOperation->getValue("NEXTID");
if (tConnection->execute( Commit ) == -1)
{
- if (tConnection->theError.code != 9999)
- goto error_handler;
+ goto error_handler;
}
else
{
+ info->m_highest_seen = tRecAttrResult->u_64_value();
DBUG_PRINT("info",
- ("Setting next auto increment value (db) to %lu",
+ ("Setting auto increment value (db) to %lu",
(ulong)opValue));
info->m_first_tuple_id = info->m_last_tuple_id = opValue - 1;
}
@@ -1126,7 +1177,7 @@ Ndb::opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op)
tRecAttrResult = tOperation->getValue("NEXTID");
if (tConnection->execute( Commit ) == -1 )
goto error_handler;
- opValue = tRecAttrResult->u_64_value(); // out
+ info->m_highest_seen = opValue = tRecAttrResult->u_64_value(); // out
break;
default:
goto error_handler;
@@ -1415,11 +1466,7 @@ Ndb::printState(const char* fmt, ...)
NdbMutex_Lock(ndb_print_state_mutex);
bool dups = false;
unsigned i;
- ndbout << buf << " ndb=" << hex << this << dec;
-#ifndef NDB_WIN32
- ndbout << " thread=" << (int)pthread_self();
-#endif
- ndbout << endl;
+ ndbout << buf << " ndb=" << hex << (void*)this << endl;
for (unsigned n = 0; n < MAX_NDB_NODES; n++) {
NdbTransaction* con = theConnectionArray[n];
if (con != 0) {
diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp
index bf0c02714db..ecbf527c9ae 100644
--- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp
+++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp
@@ -35,6 +35,7 @@
#include "NdbBlobImpl.hpp"
#include <AttributeHeader.hpp>
#include <my_sys.h>
+#include <NdbSleep.h>
#define DEBUG_PRINT 0
#define INCOMPATIBLE_VERSION -2
@@ -886,7 +887,23 @@ NdbDictInterface::dictSignal(NdbApiSignal* signal,
{
DBUG_ENTER("NdbDictInterface::dictSignal");
DBUG_PRINT("enter", ("useMasterNodeId: %d", useMasterNodeId));
- for(Uint32 i = 0; i<RETRIES; i++){
+
+ int sleep = 50;
+ int mod = 5;
+
+ for(Uint32 i = 0; i<RETRIES; i++)
+ {
+ if (i > 0)
+ NdbSleep_MilliSleep(sleep + 10 * (rand() % mod));
+ if (i == RETRIES / 2)
+ {
+ mod = 10;
+ }
+ if (i == 3*RETRIES/4)
+ {
+ sleep = 100;
+ }
+
//if (useMasterNodeId == 0)
m_buffer.clear();
diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c
index 4c60e384e6c..27b640489f6 100644
--- a/ndb/src/ndbapi/ndberror.c
+++ b/ndb/src/ndbapi/ndberror.c
@@ -291,6 +291,7 @@ ErrorBundle ErrorCodes[] = {
{ 242, AE, "Zero concurrency in scan"},
{ 244, AE, "Too high concurrency in scan"},
{ 269, AE, "No condition and attributes to read in scan"},
+ { 874, AE, "Too much attrinfo (e.g. scan filter) for scan in tuple manager" },
{ 4600, AE, "Transaction is already started"},
{ 4601, AE, "Transaction is not started"},
{ 4602, AE, "You must call getNdbOperation before executeScan" },
diff --git a/ndb/test/ndbapi/testBitfield.cpp b/ndb/test/ndbapi/testBitfield.cpp
index 8ba8f3d92ef..40a7a9d4557 100644
--- a/ndb/test/ndbapi/testBitfield.cpp
+++ b/ndb/test/ndbapi/testBitfield.cpp
@@ -4,6 +4,8 @@
#include <NDBT.hpp>
#include <NdbApi.hpp>
#include <HugoTransactions.hpp>
+#include <Bitmask.hpp>
+#include <Vector.hpp>
static const char* _dbname = "TEST_DB";
static int g_loops = 7;
@@ -37,6 +39,7 @@ static int unique_indexes(Ndb*, const NdbDictionary::Table* tab);
static int ordered_indexes(Ndb*, const NdbDictionary::Table* tab);
static int node_restart(Ndb*, const NdbDictionary::Table* tab);
static int system_restart(Ndb*, const NdbDictionary::Table* tab);
+static int testBitmask();
int
main(int argc, char** argv){
@@ -49,6 +52,15 @@ main(int argc, char** argv){
ndb_std_get_one_option)))
return NDBT_ProgramExit(NDBT_WRONGARGS);
+ int res = NDBT_FAILED;
+
+ /* Run cluster-independent tests */
+ for (int i=0; i<(10*g_loops); i++)
+ {
+ if (NDBT_OK != (res= testBitmask()))
+ return NDBT_ProgramExit(res);
+ }
+
Ndb_cluster_connection con(opt_connect_str);
if(con.connect(12, 5, 1))
{
@@ -60,7 +72,6 @@ main(int argc, char** argv){
pNdb = new Ndb(&con, _dbname);
pNdb->init();
while (pNdb->waitUntilReady() != 0);
- int res = NDBT_FAILED;
NdbDictionary::Dictionary * dict = pNdb->getDictionary();
@@ -121,14 +132,12 @@ create_random_table(Ndb* pNdb)
do {
NdbDictionary::Table tab;
Uint32 cols = 1 + (rand() % (NDB_MAX_ATTRIBUTES_IN_TABLE - 1));
- Uint32 keys = NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY;
Uint32 length = 4090;
- Uint32 key_size = NDB_MAX_KEYSIZE_IN_WORDS;
BaseString name;
name.assfmt("TAB_%d", rand() & 65535);
tab.setName(name.c_str());
- for(int i = 0; i<cols && length > 2; i++)
+ for(Uint32 i = 0; i<cols && length > 2; i++)
{
NdbDictionary::Column col;
name.assfmt("COL_%d", i);
@@ -206,3 +215,393 @@ system_restart(Ndb* pNdb, const NdbDictionary::Table* tab)
{
return 0;
}
+
+/* Note : folowing classes test functionality of storage/ndb/src/common/util/Bitmask.cpp
+ * and were originally defined there.
+ * Set BITMASK_DEBUG to 1 to get more test debugging info.
+ */
+#define BITMASK_DEBUG 0
+
+static
+bool cmp(const Uint32 b1[], const Uint32 b2[], Uint32 len)
+{
+ Uint32 sz32 = (len + 31) >> 5;
+ for(Uint32 i = 0; i<len; i++)
+ {
+ if(BitmaskImpl::get(sz32, b1, i) ^ BitmaskImpl::get(sz32, b2, i))
+ return false;
+ }
+ return true;
+}
+
+static
+void print(const Uint32 src[], Uint32 len, Uint32 pos = 0)
+{
+ printf("b'");
+ for(unsigned i = 0; i<len; i++)
+ {
+ if(BitmaskImpl::get((pos + len + 31) >> 5, src, i+pos))
+ printf("1");
+ else
+ printf("0");
+ if((i & 31) == 31)
+ printf(" ");
+ }
+}
+
+static int lrand()
+{
+ return rand();
+}
+
+static
+void rand(Uint32 dst[], Uint32 len)
+{
+ for(Uint32 i = 0; i<len; i++)
+ BitmaskImpl::set((len + 31) >> 5, dst, i, (lrand() % 1000) > 500);
+}
+
+static
+int checkNoTramplingGetSetField(const Uint32 totalTests)
+{
+ const Uint32 numWords= 67;
+ const Uint32 maxBitsToCopy= (numWords * 32);
+ Uint32 sourceBuf[numWords];
+ Uint32 targetBuf[numWords];
+
+ ndbout << "Testing : Bitmask NoTrampling\n";
+
+ memset(sourceBuf, 0x00, (numWords*4));
+
+ for (Uint32 test=0; test<totalTests; test++)
+ {
+ /* Always copy at least 1 bit */
+ Uint32 srcStart= rand() % (maxBitsToCopy -1);
+ Uint32 length= (rand() % ((maxBitsToCopy -1) - srcStart)) + 1;
+
+ if (BITMASK_DEBUG)
+ ndbout << "Testing start %u, length %u \n"
+ << srcStart
+ << length;
+ // Set target to all ones.
+ memset(targetBuf, 0xff, (numWords*4));
+
+ BitmaskImpl::getField(numWords, sourceBuf, srcStart, length, targetBuf);
+
+ // Check that there is no trampling
+ Uint32 firstUntrampledWord= (length + 31)/32;
+
+ for (Uint32 word=0; word< numWords; word++)
+ {
+ Uint32 targetWord= targetBuf[word];
+ if (BITMASK_DEBUG)
+ ndbout << "word=%d, targetWord=%u, firstUntrampledWord..=%u"
+ << word << targetWord << firstUntrampledWord;
+
+ if (! (word < firstUntrampledWord) ?
+ (targetWord == 0) :
+ (targetWord == 0xffffffff))
+ {
+ ndbout << "Notrampling getField failed for srcStart "
+ << srcStart
+ << " length " << length
+ << " at word " << word << "\n";
+ ndbout << "word=%d, targetWord=%u, firstUntrampledWord..=%u"
+ << word << targetWord << firstUntrampledWord;
+ return -1;
+ }
+
+ }
+
+ /* Set target back to all ones. */
+ memset(targetBuf, 0xff, (numWords*4));
+
+ BitmaskImpl::setField(numWords, targetBuf, srcStart, length, sourceBuf);
+
+ /* Check we've got all ones, with zeros only where expected */
+ for (Uint32 word=0; word< numWords; word++)
+ {
+ Uint32 targetWord= targetBuf[word];
+
+ for (Uint32 bit=0; bit< 32; bit++)
+ {
+ Uint32 bitNum= (word << 5) + bit;
+ bool expectedValue= !((bitNum >= srcStart) &&
+ (bitNum < (srcStart + length)));
+ bool actualValue= (((targetWord >> bit) & 1) == 1);
+ if (BITMASK_DEBUG)
+ ndbout << "bitNum=%u expectedValue=%u, actual value=%u"
+ << bitNum << expectedValue << actualValue;
+
+ if (actualValue != expectedValue)
+ {
+ ndbout << "Notrampling setField failed for srcStart "
+ << srcStart
+ << " length " << length
+ << " at word " << word << " bit " << bit << "\n";
+ ndbout << "bitNum=%u expectedValue=%u, actual value=%u"
+ << bitNum << expectedValue << actualValue;
+ return -1;
+ }
+ }
+ }
+
+ }
+
+ return 0;
+}
+
+static
+int simple(int pos, int size)
+{
+ ndbout << "Testing : Bitmask simple pos: " << pos << " size: " << size << "\n";
+ Vector<Uint32> _mask;
+ Vector<Uint32> _src;
+ Vector<Uint32> _dst;
+ Uint32 sz32 = (size + pos + 32) >> 5;
+ const Uint32 sz = 4 * sz32;
+
+ Uint32 zero = 0;
+ _mask.fill(sz32+1, zero);
+ _src.fill(sz32+1, zero);
+ _dst.fill(sz32+1, zero);
+
+ Uint32 * src = _src.getBase();
+ Uint32 * dst = _dst.getBase();
+ Uint32 * mask = _mask.getBase();
+
+ memset(src, 0x0, sz);
+ memset(dst, 0x0, sz);
+ memset(mask, 0xFF, sz);
+ rand(src, size);
+ BitmaskImpl::setField(sz32, mask, pos, size, src);
+ BitmaskImpl::getField(sz32, mask, pos, size, dst);
+ if (BITMASK_DEBUG)
+ {
+ printf("src: "); print(src, size+31); printf("\n");
+ printf("msk: "); print(mask, (sz32 << 5) + 31); printf("\n");
+ printf("dst: "); print(dst, size+31); printf("\n");
+ }
+ return (cmp(src, dst, size+31)?0 : -1);
+};
+
+struct Alloc
+{
+ Uint32 pos;
+ Uint32 size;
+ Vector<Uint32> data;
+};
+
+static
+int
+testRanges(Uint32 bitmask_size)
+{
+ Vector<Alloc> alloc_list;
+ bitmask_size = (bitmask_size + 31) & ~31;
+ Uint32 sz32 = (bitmask_size >> 5);
+ Vector<Uint32> alloc_mask;
+ Vector<Uint32> test_mask;
+
+ ndbout_c("Testing : Bitmask ranges for bitmask of size %d", bitmask_size);
+ Uint32 zero = 0;
+ alloc_mask.fill(sz32, zero);
+ test_mask.fill(sz32, zero);
+
+ /* Loop a number of times, setting and clearing bits in the mask
+ * and tracking the modifications in a separate structure.
+ * Check that both structures remain in sync
+ */
+ for(int i = 0; i<5000; i++)
+ {
+ Vector<Uint32> tmp;
+ tmp.fill(sz32, zero);
+
+ Uint32 pos = lrand() % (bitmask_size - 1);
+ Uint32 free = 0;
+ if(BitmaskImpl::get(sz32, alloc_mask.getBase(), pos))
+ {
+ // Bit was allocated
+ // 1) Look up allocation
+ // 2) Check data
+ // 3) free it
+ size_t j;
+ Uint32 min, max;
+ for(j = 0; j<alloc_list.size(); j++)
+ {
+ min = alloc_list[j].pos;
+ max = min + alloc_list[j].size;
+ if(pos >= min && pos < max)
+ {
+ break;
+ }
+ }
+ if (! ((pos >= min) && (pos < max)))
+ {
+ printf("Failed with pos %u, min %u, max %u\n",
+ pos, min, max);
+ return -1;
+ }
+ BitmaskImpl::getField(sz32, test_mask.getBase(), min, max-min,
+ tmp.getBase());
+ if(BITMASK_DEBUG)
+ {
+ printf("freeing [ %d %d ]", min, max);
+ printf("- mask: ");
+ print(tmp.getBase(), max - min);
+
+ printf(" save: ");
+ size_t k;
+ Alloc& a = alloc_list[j];
+ for(k = 0; k<a.data.size(); k++)
+ printf("%.8x ", a.data[k]);
+ printf("\n");
+ }
+ if(!cmp(tmp.getBase(), alloc_list[j].data.getBase(), max - min))
+ {
+ return -1;
+ }
+ while(min < max)
+ BitmaskImpl::clear(sz32, alloc_mask.getBase(), min++);
+ alloc_list.erase(j);
+ }
+ else
+ {
+ Vector<Uint32> tmp;
+ tmp.fill(sz32, zero);
+
+ // Bit was free
+ // 1) Check how much space is avaiable
+ // 2) Create new allocation of lrandom size
+ // 3) Fill data with lrandom data
+ // 4) Update alloc mask
+ while(pos+free < bitmask_size &&
+ !BitmaskImpl::get(sz32, alloc_mask.getBase(), pos+free))
+ free++;
+
+ Uint32 sz =
+ (free <= 64 && ((lrand() % 100) > 80)) ? free : (lrand() % free);
+ sz = sz ? sz : 1;
+ sz = pos + sz == bitmask_size ? sz - 1 : sz;
+ Alloc a;
+ a.pos = pos;
+ a.size = sz;
+ a.data.fill(((sz+31)>> 5)-1, zero);
+ if(BITMASK_DEBUG)
+ printf("pos %d -> alloc [ %d %d ]", pos, pos, pos+sz);
+ for(size_t j = 0; j<sz; j++)
+ {
+ BitmaskImpl::set(sz32, alloc_mask.getBase(), pos+j);
+ if((lrand() % 1000) > 500)
+ BitmaskImpl::set((sz + 31) >> 5, a.data.getBase(), j);
+ }
+ if(BITMASK_DEBUG)
+ {
+ printf("- mask: ");
+ print(a.data.getBase(), sz);
+ printf("\n");
+ }
+ BitmaskImpl::setField(sz32, test_mask.getBase(), pos, sz,
+ a.data.getBase());
+ alloc_list.push_back(a);
+ }
+ }
+
+#ifdef NDB_BM_SUPPORT_RANGE
+ for(Uint32 i = 0; i<1000; i++)
+ {
+ Uint32 sz32 = 10+rand() % 100;
+ Uint32 zero = 0;
+ Vector<Uint32> map;
+ map.fill(sz32, zero);
+
+ Uint32 sz = 32 * sz32;
+ Uint32 start = (rand() % sz);
+ Uint32 stop = start + ((rand() % (sz - start)) & 0xFFFFFFFF);
+
+ Vector<Uint32> check;
+ check.fill(sz32, zero);
+
+ /* Verify range setting method works correctly */
+ for(Uint32 j = 0; j<sz; j++)
+ {
+ bool expect = (j >= start && j<stop);
+ if(expect)
+ BitmaskImpl::set(sz32, check.getBase(), j);
+ }
+
+ BitmaskImpl::set_range(sz32, map.getBase(), start, stop);
+ if (!BitmaskImpl::equal(sz32, map.getBase(), check.getBase()))
+ {
+ ndbout_c(" FAIL 1 sz: %d [ %d %d ]", sz, start, stop);
+ printf("check: ");
+ for(Uint32 j = 0; j<sz32; j++)
+ printf("%.8x ", check[j]);
+ printf("\n");
+
+ printf("map : ");
+ for(Uint32 j = 0; j<sz32; j++)
+ printf("%.8x ", map[j]);
+ printf("\n");
+ return -1;
+ }
+
+ map.clear();
+ check.clear();
+
+ /* Verify range clearing method works correctly */
+ Uint32 one = ~(Uint32)0;
+ map.fill(sz32, one);
+ check.fill(sz32, one);
+
+ for(Uint32 j = 0; j<sz; j++)
+ {
+ bool expect = (j >= start && j<stop);
+ if(expect)
+ BitmaskImpl::clear(sz32, check.getBase(), j);
+ }
+
+ BitmaskImpl::clear_range(sz32, map.getBase(), start, stop);
+ if (!BitmaskImpl::equal(sz32, map.getBase(), check.getBase()))
+ {
+ ndbout_c(" FAIL 2 sz: %d [ %d %d ]", sz, start, stop);
+ printf("check: ");
+ for(Uint32 j = 0; j<sz32; j++)
+ printf("%.8x ", check[j]);
+ printf("\n");
+
+ printf("map : ");
+ for(Uint32 j = 0; j<sz32; j++)
+ printf("%.8x ", map[j]);
+ printf("\n");
+ return -1;
+ }
+ }
+#endif
+
+ return 0;
+}
+
+static
+int
+testBitmask()
+{
+ /* Some testcases from storage/ndb/src/common/util/Bitmask.cpp */
+ int res= 0;
+
+ if ((res= checkNoTramplingGetSetField(100 /* totalTests */)) != 0)
+ return res;
+
+ if ((res= simple(rand() % 33, // position
+ (rand() % 63)+1) // size
+ ) != 0)
+ return res;
+
+ if ((res= testRanges(1+(rand() % 1000) // bitmask size
+ )) != 0)
+ return res;
+
+ return 0;
+}
+
+template class Vector<Alloc>;
+template class Vector<Uint32>;
diff --git a/ndb/test/ndbapi/testInterpreter.cpp b/ndb/test/ndbapi/testInterpreter.cpp
index 0dc032ba7aa..22b810107b4 100644
--- a/ndb/test/ndbapi/testInterpreter.cpp
+++ b/ndb/test/ndbapi/testInterpreter.cpp
@@ -77,6 +77,11 @@ int runTestIncValue32(NDBT_Context* ctx, NDBT_Step* step){
const NdbDictionary::Table * pTab = ctx->getTab();
Ndb* pNdb = GETNDB(step);
+ if (strcmp(pTab->getName(), "T1") != 0) {
+ g_err << "runTestBug19537: skip, table != T1" << endl;
+ return NDBT_OK;
+ }
+
NdbConnection* pTrans = pNdb->startTransaction();
if (pTrans == NULL){
@@ -258,6 +263,84 @@ int runTestBug19537(NDBT_Context* ctx, NDBT_Step* step){
}
+int runTestBug34107(NDBT_Context* ctx, NDBT_Step* step){
+ int result = NDBT_OK;
+ const NdbDictionary::Table * pTab = ctx->getTab();
+ Ndb* pNdb = GETNDB(step);
+
+ int i;
+ for (i = 0; i <= 1; i++) {
+ g_info << "bug34107:" << (i == 0 ? " small" : " too big") << endl;
+
+ NdbConnection* pTrans = pNdb->startTransaction();
+ if (pTrans == NULL){
+ ERR(pNdb->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ NdbScanOperation* pOp = pTrans->getNdbScanOperation(pTab->getName());
+ if (pOp == NULL) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ if (pOp->readTuples() == -1) {
+ ERR(pOp->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ int n = i == 0 ? 10000 : 30000;
+ int k;
+
+ for (k = 0; k < n; k++) {
+
+ // inserts 1 word ATTRINFO
+
+ if (pOp->interpret_exit_ok() == -1) {
+ ERR(pOp->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+ }
+
+ if (pTrans->execute(NoCommit) == -1) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ int ret;
+ while ((ret = pOp->nextResult()) == 0)
+ ;
+ g_info << "ret=" << ret << " err=" << pOp->getNdbError().code << endl;
+
+ if (i == 0 && ret != 1) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ if (i == 1 && ret != -1) {
+ g_err << "unexpected big filter success" << endl;
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+ if (i == 1 && pOp->getNdbError().code != 874) {
+ g_err << "unexpected big filter error code, wanted 874" << endl;
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ pNdb->closeTransaction(pTrans);
+ }
+
+ return NDBT_OK;
+}
+
+
NDBT_TESTSUITE(testInterpreter);
TESTCASE("IncValue32",
"Test incValue for 32 bit integer\n"){
@@ -277,6 +360,12 @@ TESTCASE("Bug19537",
INITIALIZER(runTestBug19537);
FINALIZER(runClearTable);
}
+TESTCASE("Bug34107",
+ "Test too big scan filter (error 874)\n"){
+ INITIALIZER(runLoadTable);
+ INITIALIZER(runTestBug34107);
+ FINALIZER(runClearTable);
+}
#if 0
TESTCASE("MaxTransactions",
"Start transactions until no more can be created\n"){
diff --git a/ndb/test/ndbapi/testOIBasic.cpp b/ndb/test/ndbapi/testOIBasic.cpp
index 8f77f0bb062..4e1c8400768 100644
--- a/ndb/test/ndbapi/testOIBasic.cpp
+++ b/ndb/test/ndbapi/testOIBasic.cpp
@@ -36,10 +36,11 @@
struct Opt {
// common options
- unsigned m_batch;
+ uint m_batch;
const char* m_bound;
const char* m_case;
bool m_collsp;
+ bool m_cont;
bool m_core;
const char* m_csname;
CHARSET_INFO* m_cs;
@@ -47,26 +48,29 @@ struct Opt {
bool m_dups;
NdbDictionary::Object::FragmentType m_fragtype;
const char* m_index;
- unsigned m_loop;
+ uint m_loop;
bool m_msglock;
bool m_nologging;
bool m_noverify;
- unsigned m_pctnull;
- unsigned m_rows;
- unsigned m_samples;
- unsigned m_scanbatch;
- unsigned m_scanpar;
- unsigned m_scanstop;
+ uint m_pctnull;
+ uint m_rows;
+ uint m_samples;
+ uint m_scanbatch;
+ uint m_scanpar;
+ uint m_scanstop;
int m_seed;
- unsigned m_subloop;
+ const char* m_skip;
+ uint m_sloop;
+ uint m_ssloop;
const char* m_table;
- unsigned m_threads;
+ uint m_threads;
int m_v; // int for lint
Opt() :
m_batch(32),
m_bound("01234"),
m_case(0),
m_collsp(false),
+ m_cont(false),
m_core(false),
m_csname("random"),
m_cs(0),
@@ -85,7 +89,9 @@ struct Opt {
m_scanpar(0),
m_scanstop(0),
m_seed(-1),
- m_subloop(4),
+ m_skip(0),
+ m_sloop(4),
+ m_ssloop(4),
m_table(0),
m_threads(4),
m_v(1) {
@@ -107,6 +113,7 @@ printhelp()
<< " -bound xyz use only these bound types 0-4 [" << d.m_bound << "]" << endl
<< " -case abc only given test cases (letters a-z)" << endl
<< " -collsp use strnncollsp instead of strnxfrm" << endl
+ << " -cont on error continue to next test case [" << d.m_cont << "]" << endl
<< " -core core dump on error [" << d.m_core << "]" << endl
<< " -csname S charset or collation [" << d.m_csname << "]" << endl
<< " -die nnn exit immediately on NDB error code nnn" << endl
@@ -122,7 +129,9 @@ printhelp()
<< " -scanbatch N scan batch 0=default [" << d.m_scanbatch << "]" << endl
<< " -scanpar N scan parallel 0=default [" << d.m_scanpar << "]" << endl
<< " -seed N srandom seed 0=loop number -1=random [" << d.m_seed << "]" << endl
- << " -subloop N subtest (and subsubtest) loop count [" << d.m_subloop << "]" << endl
+ << " -skip abc skip given test cases (letters a-z)" << endl
+ << " -sloop N level 2 (sub)loop count [" << d.m_sloop << "]" << endl
+ << " -ssloop N level 3 (sub)loop count [" << d.m_ssloop << "]" << endl
<< " -table xyz only given table numbers (digits 0-9)" << endl
<< " -threads N number of threads [" << d.m_threads << "]" << endl
<< " -vN verbosity [" << d.m_v << "]" << endl
@@ -142,17 +151,17 @@ static const char* hexstr = "0123456789abcdef";
// random ints
-static unsigned
-urandom(unsigned n)
+static uint
+urandom(uint n)
{
if (n == 0)
return 0;
- unsigned i = random() % n;
+ uint i = random() % n;
return i;
}
static int
-irandom(unsigned n)
+irandom(uint n)
{
if (n == 0)
return 0;
@@ -163,7 +172,7 @@ irandom(unsigned n)
}
static bool
-randompct(unsigned pct)
+randompct(uint pct)
{
if (pct == 0)
return false;
@@ -172,15 +181,15 @@ randompct(unsigned pct)
return urandom(100) < pct;
}
-static unsigned
-random_coprime(unsigned n)
+static uint
+random_coprime(uint n)
{
- unsigned prime[] = { 101, 211, 307, 401, 503, 601, 701, 809, 907 };
- unsigned count = sizeof(prime) / sizeof(prime[0]);
+ uint prime[] = { 101, 211, 307, 401, 503, 601, 701, 809, 907 };
+ uint count = sizeof(prime) / sizeof(prime[0]);
if (n == 0)
return 0;
while (1) {
- unsigned i = urandom(count);
+ uint i = urandom(count);
if (n % prime[i] != 0)
return prime[i];
}
@@ -189,16 +198,16 @@ random_coprime(unsigned n)
// random re-sequence of 0...(n-1)
struct Rsq {
- Rsq(unsigned n);
- unsigned next();
+ Rsq(uint n);
+ uint next();
private:
- unsigned m_n;
- unsigned m_i;
- unsigned m_start;
- unsigned m_prime;
+ uint m_n;
+ uint m_i;
+ uint m_start;
+ uint m_prime;
};
-Rsq::Rsq(unsigned n)
+Rsq::Rsq(uint n)
{
m_n = n;
m_i = 0;
@@ -206,7 +215,7 @@ Rsq::Rsq(unsigned n)
m_prime = random_coprime(n);
}
-unsigned
+uint
Rsq::next()
{
assert(m_n != 0);
@@ -216,30 +225,16 @@ Rsq::next()
// log and error macros
static NdbMutex *ndbout_mutex = NULL;
-
-static unsigned getthrno();
-
-static const char*
-getthrstr()
-{
- static char buf[20];
- unsigned n = getthrno();
- if (n == (unsigned)-1)
- strcpy(buf, "");
- else {
- unsigned m =
- g_opt.m_threads < 10 ? 1 :
- g_opt.m_threads < 100 ? 2 : 3;
- sprintf(buf, "[%0*u] ", m, n);
- }
- return buf;
-}
+static const char* getthrprefix();
#define LLN(n, s) \
do { \
if ((n) > g_opt.m_v) break; \
if (g_opt.m_msglock) NdbMutex_Lock(ndbout_mutex); \
- ndbout << getthrstr() << s << endl; \
+ ndbout << getthrprefix(); \
+ if ((n) > 2) \
+ ndbout << "line " << __LINE__ << ": "; \
+ ndbout << s << endl; \
if (g_opt.m_msglock) NdbMutex_Unlock(ndbout_mutex); \
} while(0)
@@ -250,6 +245,8 @@ getthrstr()
#define LL4(s) LLN(4, s)
#define LL5(s) LLN(5, s)
+#define HEX(x) hex << (x) << dec
+
// following check a condition and return -1 on failure
#undef CHK // simple check
@@ -281,53 +278,58 @@ getthrstr()
class Thr;
class Con;
class Tab;
+class ITab;
class Set;
class Tmr;
struct Par : public Opt {
- unsigned m_no;
+ uint m_no;
Con* m_con;
Con& con() const { assert(m_con != 0); return *m_con; }
const Tab* m_tab;
const Tab& tab() const { assert(m_tab != 0); return *m_tab; }
+ const ITab* m_itab;
+ const ITab& itab() const { assert(m_itab != 0); return *m_itab; }
Set* m_set;
Set& set() const { assert(m_set != 0); return *m_set; }
Tmr* m_tmr;
Tmr& tmr() const { assert(m_tmr != 0); return *m_tmr; }
char m_currcase[2];
- unsigned m_lno;
- unsigned m_slno;
- unsigned m_totrows;
+ uint m_lno;
+ uint m_slno;
+ uint m_totrows;
// value calculation
- unsigned m_range;
- unsigned m_pctrange;
- unsigned m_pctbrange;
+ uint m_range;
+ uint m_pctrange;
+ uint m_pctbrange;
int m_bdir;
bool m_noindexkeyupdate;
// choice of key
bool m_randomkey;
// do verify after read
bool m_verify;
- // deadlock possible
- bool m_deadlock;
- // abort percentabge
- unsigned m_abortpct;
+ // errors to catch (see Con)
+ bool m_catcherr;
+ // abort percentage
+ uint m_abortpct;
NdbOperation::LockMode m_lockmode;
// scan options
bool m_tupscan;
bool m_ordered;
bool m_descending;
- // timer location
+ // threads used by current test case
+ uint m_usedthreads;
Par(const Opt& opt) :
Opt(opt),
m_no(0),
m_con(0),
m_tab(0),
+ m_itab(0),
m_set(0),
m_tmr(0),
m_lno(0),
m_slno(0),
- m_totrows(m_threads * m_rows),
+ m_totrows(0),
m_range(m_rows),
m_pctrange(40),
m_pctbrange(80),
@@ -335,39 +337,40 @@ struct Par : public Opt {
m_noindexkeyupdate(false),
m_randomkey(false),
m_verify(false),
- m_deadlock(false),
+ m_catcherr(0),
m_abortpct(0),
m_lockmode(NdbOperation::LM_Read),
m_tupscan(false),
m_ordered(false),
- m_descending(false)
+ m_descending(false),
+ m_usedthreads(0)
{
m_currcase[0] = 0;
}
};
static bool
-usetable(Par par, unsigned i)
+usetable(Par par, uint i)
{
return par.m_table == 0 || strchr(par.m_table, '0' + i) != 0;
}
static bool
-useindex(Par par, unsigned i)
+useindex(Par par, uint i)
{
return par.m_index == 0 || strchr(par.m_index, '0' + i) != 0;
}
-static unsigned
-thrrow(Par par, unsigned j)
+static uint
+thrrow(Par par, uint j)
{
- return par.m_threads * j + par.m_no;
+ return par.m_usedthreads * j + par.m_no;
}
static bool
-isthrrow(Par par, unsigned i)
+isthrrow(Par par, uint i)
{
- return i % par.m_threads == par.m_no;
+ return i % par.m_usedthreads == par.m_no;
}
// timer
@@ -375,13 +378,13 @@ isthrrow(Par par, unsigned i)
struct Tmr {
void clr();
void on();
- void off(unsigned cnt = 0);
+ void off(uint cnt = 0);
const char* time();
const char* pct(const Tmr& t1);
const char* over(const Tmr& t1);
NDB_TICKS m_on;
- unsigned m_ms;
- unsigned m_cnt;
+ uint m_ms;
+ uint m_cnt;
char m_time[100];
char m_text[100];
Tmr() { clr(); }
@@ -401,7 +404,7 @@ Tmr::on()
}
void
-Tmr::off(unsigned cnt)
+Tmr::off(uint cnt)
{
NDB_TICKS off = NdbTick_CurrentMillisecond();
assert(m_on != 0 && off >= m_on);
@@ -446,53 +449,18 @@ Tmr::over(const Tmr& t1)
return m_text;
}
-// list of ints
-
-struct Lst {
- Lst();
- unsigned m_arr[1000];
- unsigned m_cnt;
- void push(unsigned i);
- unsigned cnt() const;
- void reset();
-};
-
-Lst::Lst() :
- m_cnt(0)
-{
-}
-
-void
-Lst::push(unsigned i)
-{
- assert(m_cnt < sizeof(m_arr)/sizeof(m_arr[0]));
- m_arr[m_cnt++] = i;
-}
-
-unsigned
-Lst::cnt() const
-{
- return m_cnt;
-}
-
-void
-Lst::reset()
-{
- m_cnt = 0;
-}
-
// character sets
-static const unsigned maxcsnumber = 512;
-static const unsigned maxcharcount = 32;
-static const unsigned maxcharsize = 4;
-static const unsigned maxxmulsize = 8;
+static const uint maxcsnumber = 512;
+static const uint maxcharcount = 32;
+static const uint maxcharsize = 4;
+static const uint maxxmulsize = 8;
// single mb char
struct Chr {
- unsigned char m_bytes[maxcharsize];
- unsigned char m_xbytes[maxxmulsize * maxcharsize];
- unsigned m_size;
+ uchar m_bytes[maxcharsize];
+ uchar m_xbytes[maxxmulsize * maxcharsize];
+ uint m_size;
Chr();
};
@@ -506,7 +474,7 @@ Chr::Chr()
// charset and random valid chars to use
struct Chs {
CHARSET_INFO* m_cs;
- unsigned m_xmul;
+ uint m_xmul;
Chr* m_chr;
Chs(CHARSET_INFO* cs);
~Chs();
@@ -523,22 +491,22 @@ Chs::Chs(CHARSET_INFO* cs) :
m_xmul = 1;
assert(m_xmul <= maxxmulsize);
m_chr = new Chr [maxcharcount];
- unsigned i = 0;
- unsigned miss1 = 0;
- unsigned miss2 = 0;
- unsigned miss3 = 0;
- unsigned miss4 = 0;
+ uint i = 0;
+ uint miss1 = 0;
+ uint miss2 = 0;
+ uint miss3 = 0;
+ uint miss4 = 0;
while (i < maxcharcount) {
- unsigned char* bytes = m_chr[i].m_bytes;
- unsigned char* xbytes = m_chr[i].m_xbytes;
- unsigned& size = m_chr[i].m_size;
+ uchar* bytes = m_chr[i].m_bytes;
+ uchar* xbytes = m_chr[i].m_xbytes;
+ uint& size = m_chr[i].m_size;
bool ok;
size = m_cs->mbminlen + urandom(m_cs->mbmaxlen - m_cs->mbminlen + 1);
assert(m_cs->mbminlen <= size && size <= m_cs->mbmaxlen);
// prefer longer chars
if (size == m_cs->mbminlen && m_cs->mbminlen < m_cs->mbmaxlen && urandom(5) != 0)
continue;
- for (unsigned j = 0; j < size; j++) {
+ for (uint j = 0; j < size; j++) {
bytes[j] = urandom(256);
}
int not_used;
@@ -550,13 +518,13 @@ Chs::Chs(CHARSET_INFO* cs) :
}
// check no proper prefix wellformed
ok = true;
- for (unsigned j = 1; j < size; j++) {
+ for (uint j = 1; j < size; j++) {
if ((*cs->cset->well_formed_len)(cs, sbytes, sbytes + j, 1, &not_used) == j) {
ok = false;
break;
}
}
- if (! ok) {
+ if (!ok) {
miss2++;
continue;
}
@@ -566,37 +534,37 @@ Chs::Chs(CHARSET_INFO* cs) :
int xlen = (*cs->coll->strnxfrm)(cs, xbytes, m_xmul * size, bytes, size);
// check we got something
ok = false;
- for (unsigned j = 0; j < xlen; j++) {
+ for (uint j = 0; j < xlen; j++) {
if (xbytes[j] != 0) {
ok = true;
break;
}
}
- if (! ok) {
+ if (!ok) {
miss3++;
continue;
}
// check for duplicate (before normalize)
ok = true;
- for (unsigned j = 0; j < i; j++) {
+ for (uint j = 0; j < i; j++) {
const Chr& chr = m_chr[j];
if (chr.m_size == size && memcmp(chr.m_bytes, bytes, size) == 0) {
ok = false;
break;
}
}
- if (! ok) {
+ if (!ok) {
miss4++;
continue;
}
i++;
}
bool disorder = true;
- unsigned bubbles = 0;
+ uint bubbles = 0;
while (disorder) {
disorder = false;
- for (unsigned i = 1; i < maxcharcount; i++) {
- unsigned len = sizeof(m_chr[i].m_xbytes);
+ for (uint i = 1; i < maxcharcount; i++) {
+ uint len = sizeof(m_chr[i].m_xbytes);
if (memcmp(m_chr[i-1].m_xbytes, m_chr[i].m_xbytes, len) > 0) {
Chr chr = m_chr[i];
m_chr[i] = m_chr[i-1];
@@ -627,7 +595,7 @@ static Chs* cslist[maxcsnumber];
static void
resetcslist()
{
- for (unsigned i = 0; i < maxcsnumber; i++) {
+ for (uint i = 0; i < maxcsnumber; i++) {
delete cslist[i];
cslist[i] = 0;
}
@@ -641,7 +609,7 @@ getcs(Par par)
cs = par.m_cs;
} else {
while (1) {
- unsigned n = urandom(maxcsnumber);
+ uint n = urandom(maxcsnumber);
cs = get_charset(n, MYF(0));
if (cs != 0) {
// prefer complex charsets
@@ -667,24 +635,24 @@ struct Col {
Longvarchar = NdbDictionary::Column::Longvarchar
};
const class Tab& m_tab;
- unsigned m_num;
+ uint m_num;
const char* m_name;
bool m_pk;
Type m_type;
- unsigned m_length;
- unsigned m_bytelength; // multiplied by char width
- unsigned m_attrsize; // base type size
- unsigned m_headsize; // length bytes
- unsigned m_bytesize; // full value size
+ uint m_length;
+ uint m_bytelength; // multiplied by char width
+ uint m_attrsize; // base type size
+ uint m_headsize; // length bytes
+ uint m_bytesize; // full value size
bool m_nullable;
const Chs* m_chs;
- Col(const class Tab& tab, unsigned num, const char* name, bool pk, Type type, unsigned length, bool nullable, const Chs* chs);
+ Col(const class Tab& tab, uint num, const char* name, bool pk, Type type, uint length, bool nullable, const Chs* chs);
~Col();
bool equal(const Col& col2) const;
void wellformed(const void* addr) const;
};
-Col::Col(const class Tab& tab, unsigned num, const char* name, bool pk, Type type, unsigned length, bool nullable, const Chs* chs) :
+Col::Col(const class Tab& tab, uint num, const char* name, bool pk, Type type, uint length, bool nullable, const Chs* chs) :
m_tab(tab),
m_num(num),
m_name(strcpy(new char [strlen(name) + 1], name)),
@@ -735,7 +703,7 @@ Col::wellformed(const void* addr) const
{
CHARSET_INFO* cs = m_chs->m_cs;
const char* src = (const char*)addr;
- unsigned len = m_bytelength;
+ uint len = m_bytelength;
int not_used;
assert((*cs->cset->well_formed_len)(cs, src, src + len, 0xffff, &not_used) == len);
}
@@ -743,9 +711,9 @@ Col::wellformed(const void* addr) const
case Col::Varchar:
{
CHARSET_INFO* cs = m_chs->m_cs;
- const unsigned char* src = (const unsigned char*)addr;
+ const uchar* src = (const uchar*)addr;
const char* ssrc = (const char*)src;
- unsigned len = src[0];
+ uint len = src[0];
int not_used;
assert(len <= m_bytelength);
assert((*cs->cset->well_formed_len)(cs, ssrc + 1, ssrc + 1 + len, 0xffff, &not_used) == len);
@@ -754,9 +722,9 @@ Col::wellformed(const void* addr) const
case Col::Longvarchar:
{
CHARSET_INFO* cs = m_chs->m_cs;
- const unsigned char* src = (const unsigned char*)addr;
+ const uchar* src = (const uchar*)addr;
const char* ssrc = (const char*)src;
- unsigned len = src[0] + (src[1] << 8);
+ uint len = src[0] + (src[1] << 8);
int not_used;
assert(len <= m_bytelength);
assert((*cs->cset->well_formed_len)(cs, ssrc + 2, ssrc + 2 + len, 0xffff, &not_used) == len);
@@ -774,7 +742,7 @@ operator<<(NdbOut& out, const Col& col)
out << "col[" << col.m_num << "] " << col.m_name;
switch (col.m_type) {
case Col::Unsigned:
- out << " unsigned";
+ out << " uint";
break;
case Col::Char:
{
@@ -808,13 +776,13 @@ operator<<(NdbOut& out, const Col& col)
struct ICol {
const class ITab& m_itab;
- unsigned m_num;
+ uint m_num;
const Col& m_col;
- ICol(const class ITab& itab, unsigned num, const Col& col);
+ ICol(const class ITab& itab, uint num, const Col& col);
~ICol();
};
-ICol::ICol(const class ITab& itab, unsigned num, const Col& col) :
+ICol::ICol(const class ITab& itab, uint num, const Col& col) :
m_itab(itab),
m_num(num),
m_col(col)
@@ -842,47 +810,47 @@ struct ITab {
const class Tab& m_tab;
const char* m_name;
Type m_type;
- unsigned m_icols;
+ uint m_icols;
const ICol** m_icol;
- unsigned m_colmask;
- ITab(const class Tab& tab, const char* name, Type type, unsigned icols);
+ uint m_keymask;
+ ITab(const class Tab& tab, const char* name, Type type, uint icols);
~ITab();
- void icoladd(unsigned k, const ICol* icolptr);
+ void icoladd(uint k, const ICol* icolptr);
};
-ITab::ITab(const class Tab& tab, const char* name, Type type, unsigned icols) :
+ITab::ITab(const class Tab& tab, const char* name, Type type, uint icols) :
m_tab(tab),
m_name(strcpy(new char [strlen(name) + 1], name)),
m_type(type),
m_icols(icols),
m_icol(new const ICol* [icols + 1]),
- m_colmask(0)
+ m_keymask(0)
{
- for (unsigned k = 0; k <= m_icols; k++)
+ for (uint k = 0; k <= m_icols; k++)
m_icol[k] = 0;
}
ITab::~ITab()
{
delete [] m_name;
- for (unsigned i = 0; i < m_icols; i++)
+ for (uint i = 0; i < m_icols; i++)
delete m_icol[i];
delete [] m_icol;
}
void
-ITab::icoladd(unsigned k, const ICol* icolptr)
+ITab::icoladd(uint k, const ICol* icolptr)
{
assert(k == icolptr->m_num && k < m_icols && m_icol[k] == 0);
m_icol[k] = icolptr;
- m_colmask |= (1 << icolptr->m_col.m_num);
+ m_keymask |= (1 << icolptr->m_col.m_num);
}
static NdbOut&
operator<<(NdbOut& out, const ITab& itab)
{
out << "itab " << itab.m_name << " icols=" << itab.m_icols;
- for (unsigned k = 0; k < itab.m_icols; k++) {
+ for (uint k = 0; k < itab.m_icols; k++) {
const ICol& icol = *itab.m_icol[k];
out << endl << icol;
}
@@ -893,56 +861,60 @@ operator<<(NdbOut& out, const ITab& itab)
struct Tab {
const char* m_name;
- unsigned m_cols;
+ uint m_cols;
const Col** m_col;
- unsigned m_itabs;
+ uint m_pkmask;
+ uint m_itabs;
const ITab** m_itab;
- unsigned m_orderedindexes;
- unsigned m_hashindexes;
+ uint m_orderedindexes;
+ uint m_hashindexes;
// pk must contain an Unsigned column
- unsigned m_keycol;
- void coladd(unsigned k, Col* colptr);
- void itabadd(unsigned j, ITab* itab);
- Tab(const char* name, unsigned cols, unsigned itabs, unsigned keycol);
+ uint m_keycol;
+ void coladd(uint k, Col* colptr);
+ void itabadd(uint j, ITab* itab);
+ Tab(const char* name, uint cols, uint itabs, uint keycol);
~Tab();
};
-Tab::Tab(const char* name, unsigned cols, unsigned itabs, unsigned keycol) :
+Tab::Tab(const char* name, uint cols, uint itabs, uint keycol) :
m_name(strcpy(new char [strlen(name) + 1], name)),
m_cols(cols),
m_col(new const Col* [cols + 1]),
+ m_pkmask(0),
m_itabs(itabs),
m_itab(new const ITab* [itabs + 1]),
m_orderedindexes(0),
m_hashindexes(0),
m_keycol(keycol)
{
- for (unsigned k = 0; k <= cols; k++)
+ for (uint k = 0; k <= cols; k++)
m_col[k] = 0;
- for (unsigned j = 0; j <= itabs; j++)
+ for (uint j = 0; j <= itabs; j++)
m_itab[j] = 0;
}
Tab::~Tab()
{
delete [] m_name;
- for (unsigned i = 0; i < m_cols; i++)
+ for (uint i = 0; i < m_cols; i++)
delete m_col[i];
delete [] m_col;
- for (unsigned i = 0; i < m_itabs; i++)
+ for (uint i = 0; i < m_itabs; i++)
delete m_itab[i];
delete [] m_itab;
}
void
-Tab::coladd(unsigned k, Col* colptr)
+Tab::coladd(uint k, Col* colptr)
{
assert(k == colptr->m_num && k < m_cols && m_col[k] == 0);
m_col[k] = colptr;
+ if (colptr->m_pk)
+ m_pkmask |= (1 << k);
}
void
-Tab::itabadd(unsigned j, ITab* itabptr)
+Tab::itabadd(uint j, ITab* itabptr)
{
assert(j < m_itabs && m_itab[j] == 0 && itabptr != 0);
m_itab[j] = itabptr;
@@ -956,11 +928,11 @@ static NdbOut&
operator<<(NdbOut& out, const Tab& tab)
{
out << "tab " << tab.m_name << " cols=" << tab.m_cols;
- for (unsigned k = 0; k < tab.m_cols; k++) {
+ for (uint k = 0; k < tab.m_cols; k++) {
const Col& col = *tab.m_col[k];
out << endl << col;
}
- for (unsigned i = 0; i < tab.m_itabs; i++) {
+ for (uint i = 0; i < tab.m_itabs; i++) {
if (tab.m_itab[i] == 0)
continue;
const ITab& itab = *tab.m_itab[i];
@@ -972,20 +944,20 @@ operator<<(NdbOut& out, const Tab& tab)
// make table structs
static const Tab** tablist = 0;
-static unsigned tabcount = 0;
+static uint tabcount = 0;
static void
verifytables()
{
- for (unsigned j = 0; j < tabcount; j++) {
+ for (uint j = 0; j < tabcount; j++) {
const Tab* t = tablist[j];
if (t == 0)
continue;
assert(t->m_cols != 0 && t->m_col != 0);
- for (unsigned k = 0; k < t->m_cols; k++) {
+ for (uint k = 0; k < t->m_cols; k++) {
const Col* c = t->m_col[k];
assert(c != 0 && c->m_num == k);
- assert(! (c->m_pk && c->m_nullable));
+ assert(!(c->m_pk && c->m_nullable));
}
assert(t->m_col[t->m_cols] == 0);
{
@@ -994,16 +966,16 @@ verifytables()
assert(c->m_pk && c->m_type == Col::Unsigned);
}
assert(t->m_itabs != 0 && t->m_itab != 0);
- for (unsigned i = 0; i < t->m_itabs; i++) {
+ for (uint i = 0; i < t->m_itabs; i++) {
const ITab* x = t->m_itab[i];
if (x == 0)
continue;
assert(x != 0 && x->m_icols != 0 && x->m_icol != 0);
- for (unsigned k = 0; k < x->m_icols; k++) {
+ for (uint k = 0; k < x->m_icols; k++) {
const ICol* c = x->m_icol[k];
assert(c != 0 && c->m_num == k && c->m_col.m_num < t->m_cols);
if (x->m_type == ITab::UniqueHashIndex) {
- assert(! c->m_col.m_nullable);
+ assert(!c->m_col.m_nullable);
}
}
}
@@ -1019,11 +991,11 @@ makebuiltintables(Par par)
tabcount = 3;
if (tablist == 0) {
tablist = new const Tab* [tabcount];
- for (unsigned j = 0; j < tabcount; j++) {
+ for (uint j = 0; j < tabcount; j++) {
tablist[j] = 0;
}
} else {
- for (unsigned j = 0; j < tabcount; j++) {
+ for (uint j = 0; j < tabcount; j++) {
delete tablist[j];
tablist[j] = 0;
}
@@ -1202,7 +1174,8 @@ static Ndb_cluster_connection* g_ncc = 0;
struct Con {
Ndb* m_ndb;
NdbDictionary::Dictionary* m_dic;
- NdbConnection* m_tx;
+ NdbTransaction* m_tx;
+ Uint64 m_txid;
NdbOperation* m_op;
NdbIndexOperation* m_indexop;
NdbScanOperation* m_scanop;
@@ -1210,10 +1183,16 @@ struct Con {
NdbScanFilter* m_scanfilter;
enum ScanMode { ScanNo = 0, Committed, Latest, Exclusive };
ScanMode m_scanmode;
- enum ErrType { ErrNone = 0, ErrDeadlock, ErrNospace, ErrOther };
+ enum ErrType {
+ ErrNone = 0,
+ ErrDeadlock = 1,
+ ErrNospace = 2,
+ ErrOther = 4
+ };
ErrType m_errtype;
+ char m_errname[100];
Con() :
- m_ndb(0), m_dic(0), m_tx(0), m_op(0), m_indexop(0),
+ m_ndb(0), m_dic(0), m_tx(0), m_txid(0), m_op(0), m_indexop(0),
m_scanop(0), m_indexscanop(0), m_scanfilter(0),
m_scanmode(ScanNo), m_errtype(ErrNone) {}
~Con() {
@@ -1237,18 +1216,20 @@ struct Con {
int setBound(int num, int type, const void* value);
int beginFilter(int group);
int endFilter();
- int setFilter(int num, int cond, const void* value, unsigned len);
- int execute(ExecType t);
- int execute(ExecType t, bool& deadlock, bool& nospace);
+ int setFilter(int num, int cond, const void* value, uint len);
+ int execute(ExecType et);
+ int execute(ExecType et, uint& err);
+ int readTuple(Par par);
int readTuples(Par par);
int readIndexTuples(Par par);
int executeScan();
int nextScanResult(bool fetchAllowed);
- int nextScanResult(bool fetchAllowed, bool& deadlock);
+ int nextScanResult(bool fetchAllowed, uint& err);
int updateScanTuple(Con& con2);
int deleteScanTuple(Con& con2);
void closeScan();
void closeTransaction();
+ const char* errname(uint err);
void printerror(NdbOut& out);
};
@@ -1259,7 +1240,7 @@ Con::connect()
m_ndb = new Ndb(g_ncc, "TEST_DB");
CHKCON(m_ndb->init() == 0, *this);
CHKCON(m_ndb->waitUntilReady(30) == 0, *this);
- m_tx = 0, m_op = 0;
+ m_tx = 0, m_txid = 0, m_op = 0;
return 0;
}
@@ -1274,7 +1255,7 @@ void
Con::disconnect()
{
delete m_ndb;
- m_ndb = 0, m_dic = 0, m_tx = 0, m_op = 0;
+ m_ndb = 0, m_dic = 0, m_tx = 0, m_txid = 0, m_op = 0;
}
int
@@ -1284,6 +1265,7 @@ Con::startTransaction()
if (m_tx != 0)
closeTransaction();
CHKCON((m_tx = m_ndb->startTransaction()) != 0, *this);
+ m_txid = m_tx->getTransactionId();
return 0;
}
@@ -1307,7 +1289,7 @@ int
Con::getNdbIndexOperation(const ITab& itab, const Tab& tab)
{
assert(m_tx != 0);
- unsigned tries = 0;
+ uint tries = 0;
while (1) {
if (getNdbIndexOperation1(itab, tab) == 0)
break;
@@ -1337,7 +1319,7 @@ int
Con::getNdbIndexScanOperation(const ITab& itab, const Tab& tab)
{
assert(m_tx != 0);
- unsigned tries = 0;
+ uint tries = 0;
while (1) {
if (getNdbIndexScanOperation1(itab, tab) == 0)
break;
@@ -1405,7 +1387,7 @@ Con::endFilter()
}
int
-Con::setFilter(int num, int cond, const void* value, unsigned len)
+Con::setFilter(int num, int cond, const void* value, uint len)
{
assert(m_tx != 0 && m_scanfilter != 0);
CHKCON(m_scanfilter->cmp((NdbScanFilter::BinaryCondition)cond, num, value, len) == 0, *this);
@@ -1413,34 +1395,46 @@ Con::setFilter(int num, int cond, const void* value, unsigned len)
}
int
-Con::execute(ExecType t)
+Con::execute(ExecType et)
{
assert(m_tx != 0);
- CHKCON(m_tx->execute(t) == 0, *this);
+ CHKCON(m_tx->execute(et) == 0, *this);
return 0;
}
int
-Con::execute(ExecType t, bool& deadlock, bool& nospace)
+Con::execute(ExecType et, uint& err)
{
- int ret = execute(t);
- if (ret != 0 && deadlock && m_errtype == ErrDeadlock) {
- LL3("caught deadlock");
- ret = 0;
- } else {
- deadlock = false;
- }
- if (ret != 0 && nospace && m_errtype == ErrNospace) {
- LL3("caught nospace");
- ret = 0;
- } else {
- nospace = false;
+ int ret = execute(et);
+ // err in: errors to catch, out: error caught
+ const uint errin = err;
+ err = 0;
+ if (ret == -1) {
+ if (m_errtype == ErrDeadlock && (errin & ErrDeadlock)) {
+ LL3("caught deadlock");
+ err = ErrDeadlock;
+ ret = 0;
+ }
+ if (m_errtype == ErrNospace && (errin & ErrNospace)) {
+ LL3("caught nospace");
+ err = ErrNospace;
+ ret = 0;
+ }
}
CHK(ret == 0);
return 0;
}
int
+Con::readTuple(Par par)
+{
+ assert(m_tx != 0 && m_op != 0);
+ NdbOperation::LockMode lm = par.m_lockmode;
+ CHKCON(m_op->readTuple(lm) == 0, *this);
+ return 0;
+}
+
+int
Con::readTuples(Par par)
{
assert(m_tx != 0 && m_scanop != 0);
@@ -1477,23 +1471,25 @@ Con::nextScanResult(bool fetchAllowed)
int ret;
assert(m_scanop != 0);
CHKCON((ret = m_scanop->nextResult(fetchAllowed)) != -1, *this);
- assert(ret == 0 || ret == 1 || (! fetchAllowed && ret == 2));
+ assert(ret == 0 || ret == 1 || (!fetchAllowed && ret == 2));
return ret;
}
int
-Con::nextScanResult(bool fetchAllowed, bool& deadlock)
+Con::nextScanResult(bool fetchAllowed, uint& err)
{
int ret = nextScanResult(fetchAllowed);
+ // err in: errors to catch, out: error caught
+ const uint errin = err;
+ err = 0;
if (ret == -1) {
- if (deadlock && m_errtype == ErrDeadlock) {
+ if (m_errtype == ErrDeadlock && (errin & ErrDeadlock)) {
LL3("caught deadlock");
+ err = ErrDeadlock;
ret = 0;
}
- } else {
- deadlock = false;
}
- CHK(ret == 0 || ret == 1 || (! fetchAllowed && ret == 2));
+ CHK(ret == 0 || ret == 1 || (!fetchAllowed && ret == 2));
return ret;
}
@@ -1502,6 +1498,7 @@ Con::updateScanTuple(Con& con2)
{
assert(con2.m_tx != 0);
CHKCON((con2.m_op = m_scanop->updateCurrentTuple(con2.m_tx)) != 0, *this);
+ con2.m_txid = m_txid; // in the kernel
return 0;
}
@@ -1510,6 +1507,7 @@ Con::deleteScanTuple(Con& con2)
{
assert(con2.m_tx != 0);
CHKCON(m_scanop->deleteCurrentTuple(con2.m_tx) == 0, *this);
+ con2.m_txid = m_txid; // in the kernel
return 0;
}
@@ -1527,15 +1525,26 @@ Con::closeTransaction()
{
assert(m_ndb != 0 && m_tx != 0);
m_ndb->closeTransaction(m_tx);
- m_tx = 0, m_op = 0;
+ m_tx = 0, m_txid = 0, m_op = 0;
m_scanop = 0, m_indexscanop = 0;
}
+const char*
+Con::errname(uint err)
+{
+ sprintf(m_errname, "0x%x", err);
+ if (err & ErrDeadlock)
+ strcat(m_errname, ",deadlock");
+ if (err & ErrNospace)
+ strcat(m_errname, ",nospace");
+ return m_errname;
+}
+
void
Con::printerror(NdbOut& out)
{
m_errtype = ErrOther;
- unsigned any = 0;
+ uint any = 0;
int code;
int die = 0;
if (m_ndb) {
@@ -1563,7 +1572,7 @@ Con::printerror(NdbOut& out)
}
}
}
- if (! any) {
+ if (!any) {
LL0("failed but no NDB error code");
}
if (die) {
@@ -1589,7 +1598,7 @@ invalidateindex(Par par)
{
Con& con = par.con();
const Tab& tab = par.tab();
- for (unsigned i = 0; i < tab.m_itabs; i++) {
+ for (uint i = 0; i < tab.m_itabs; i++) {
if (tab.m_itab[i] == 0)
continue;
const ITab& itab = *tab.m_itab[i];
@@ -1639,7 +1648,7 @@ createtable(Par par)
if (par.m_nologging) {
t.setLogging(false);
}
- for (unsigned k = 0; k < tab.m_cols; k++) {
+ for (uint k = 0; k < tab.m_cols; k++) {
const Col& col = *tab.m_col[k];
NdbDictionary::Column c(col.m_name);
c.setType((NdbDictionary::Column::Type)col.m_type);
@@ -1677,7 +1686,7 @@ static int
dropindex(Par par)
{
const Tab& tab = par.tab();
- for (unsigned i = 0; i < tab.m_itabs; i++) {
+ for (uint i = 0; i < tab.m_itabs; i++) {
if (tab.m_itab[i] == 0)
continue;
const ITab& itab = *tab.m_itab[i];
@@ -1699,7 +1708,7 @@ createindex(Par par, const ITab& itab)
if (par.m_nologging || itab.m_type == ITab::OrderedIndex) {
x.setLogging(false);
}
- for (unsigned k = 0; k < itab.m_icols; k++) {
+ for (uint k = 0; k < itab.m_icols; k++) {
const ICol& icol = *itab.m_icol[k];
const Col& col = icol.m_col;
x.addColumnName(col.m_name);
@@ -1714,7 +1723,7 @@ static int
createindex(Par par)
{
const Tab& tab = par.tab();
- for (unsigned i = 0; i < tab.m_itabs; i++) {
+ for (uint i = 0; i < tab.m_itabs; i++) {
if (tab.m_itab[i] == 0)
continue;
const ITab& itab = *tab.m_itab[i];
@@ -1731,27 +1740,29 @@ struct Val {
const Col& m_col;
union {
Uint32 m_uint32;
- unsigned char* m_char;
- unsigned char* m_varchar;
- unsigned char* m_longvarchar;
+ uchar* m_char;
+ uchar* m_varchar;
+ uchar* m_longvarchar;
};
+ bool m_null;
+ // construct
Val(const Col& col);
~Val();
void copy(const Val& val2);
void copy(const void* addr);
const void* dataaddr() const;
- bool m_null;
- int equal(Par par) const;
- int equal(Par par, const ICol& icol) const;
- int setval(Par par) const;
- void calc(Par par, unsigned i);
- void calckey(Par par, unsigned i);
- void calckeychars(Par par, unsigned i, unsigned& n, unsigned char* buf);
+ void calc(Par par, uint i);
+ void calckey(Par par, uint i);
+ void calckeychars(Par par, uint i, uint& n, uchar* buf);
void calcnokey(Par par);
- void calcnokeychars(Par par, unsigned& n, unsigned char* buf);
- int verify(Par par, const Val& val2) const;
+ void calcnokeychars(Par par, uint& n, uchar* buf);
+ // operations
+ int setval(Par par) const;
+ int setval(Par par, const ICol& icol) const;
+ // compare
int cmp(Par par, const Val& val2) const;
- int cmpchars(Par par, const unsigned char* buf1, unsigned len1, const unsigned char* buf2, unsigned len2) const;
+ int cmpchars(Par par, const uchar* buf1, uint len1, const uchar* buf2, uint len2) const;
+ int verify(Par par, const Val& val2) const;
private:
Val& operator=(const Val& val2);
};
@@ -1759,20 +1770,26 @@ private:
static NdbOut&
operator<<(NdbOut& out, const Val& val);
+// construct
+
Val::Val(const Col& col) :
m_col(col)
{
switch (col.m_type) {
case Col::Unsigned:
+ m_uint32 = 0x7e7e7e7e;
break;
case Col::Char:
- m_char = new unsigned char [col.m_bytelength];
+ m_char = new uchar [col.m_bytelength];
+ memset(m_char, 0x7e, col.m_bytelength);
break;
case Col::Varchar:
- m_varchar = new unsigned char [1 + col.m_bytelength];
+ m_varchar = new uchar [1 + col.m_bytelength];
+ memset(m_char, 0x7e, 1 + col.m_bytelength);
break;
case Col::Longvarchar:
- m_longvarchar = new unsigned char [2 + col.m_bytelength];
+ m_longvarchar = new uchar [2 + col.m_bytelength];
+ memset(m_char, 0x7e, 2 + col.m_bytelength);
break;
default:
assert(false);
@@ -1858,52 +1875,17 @@ Val::dataaddr() const
return 0;
}
-int
-Val::equal(Par par) const
-{
- Con& con = par.con();
- const Col& col = m_col;
- assert(col.m_pk && ! m_null);
- const char* addr = (const char*)dataaddr();
- LL5("equal [" << col << "] " << *this);
- CHK(con.equal(col.m_num, addr) == 0);
- return 0;
-}
-
-int
-Val::equal(Par par, const ICol& icol) const
-{
- Con& con = par.con();
- assert(! m_null);
- const char* addr = (const char*)dataaddr();
- LL5("equal [" << icol << "] " << *this);
- CHK(con.equal(icol.m_num, addr) == 0);
- return 0;
-}
-
-int
-Val::setval(Par par) const
-{
- Con& con = par.con();
- const Col& col = m_col;
- assert(! col.m_pk);
- const char* addr = ! m_null ? (const char*)dataaddr() : 0;
- LL5("setval [" << col << "] " << *this);
- CHK(con.setValue(col.m_num, addr) == 0);
- return 0;
-}
-
void
-Val::calc(Par par, unsigned i)
+Val::calc(Par par, uint i)
{
const Col& col = m_col;
col.m_pk ? calckey(par, i) : calcnokey(par);
- if (! m_null)
+ if (!m_null)
col.wellformed(dataaddr());
}
void
-Val::calckey(Par par, unsigned i)
+Val::calckey(Par par, uint i)
{
const Col& col = m_col;
m_null = false;
@@ -1915,7 +1897,7 @@ Val::calckey(Par par, unsigned i)
{
const Chs* chs = col.m_chs;
CHARSET_INFO* cs = chs->m_cs;
- unsigned n = 0;
+ uint n = 0;
calckeychars(par, i, n, m_char);
// extend by appropriate space
(*cs->cset->fill)(cs, (char*)&m_char[n], col.m_bytelength - n, 0x20);
@@ -1923,7 +1905,7 @@ Val::calckey(Par par, unsigned i)
break;
case Col::Varchar:
{
- unsigned n = 0;
+ uint n = 0;
calckeychars(par, i, n, m_varchar + 1);
// set length and pad with nulls
m_varchar[0] = n;
@@ -1932,7 +1914,7 @@ Val::calckey(Par par, unsigned i)
break;
case Col::Longvarchar:
{
- unsigned n = 0;
+ uint n = 0;
calckeychars(par, i, n, m_longvarchar + 2);
// set length and pad with nulls
m_longvarchar[0] = (n & 0xff);
@@ -1947,13 +1929,13 @@ Val::calckey(Par par, unsigned i)
}
void
-Val::calckeychars(Par par, unsigned i, unsigned& n, unsigned char* buf)
+Val::calckeychars(Par par, uint i, uint& n, uchar* buf)
{
const Col& col = m_col;
const Chs* chs = col.m_chs;
CHARSET_INFO* cs = chs->m_cs;
n = 0;
- unsigned len = 0;
+ uint len = 0;
while (len < col.m_length) {
if (i % (1 + n) == 0) {
break;
@@ -1980,7 +1962,7 @@ Val::calcnokey(Par par)
if (r < 0 && par.m_bdir > 0 || r > 0 && par.m_bdir < 0)
r = -r;
}
- unsigned v = par.m_range + r;
+ uint v = par.m_range + r;
switch (col.m_type) {
case Col::Unsigned:
m_uint32 = v;
@@ -1989,7 +1971,7 @@ Val::calcnokey(Par par)
{
const Chs* chs = col.m_chs;
CHARSET_INFO* cs = chs->m_cs;
- unsigned n = 0;
+ uint n = 0;
calcnokeychars(par, n, m_char);
// extend by appropriate space
(*cs->cset->fill)(cs, (char*)&m_char[n], col.m_bytelength - n, 0x20);
@@ -1997,7 +1979,7 @@ Val::calcnokey(Par par)
break;
case Col::Varchar:
{
- unsigned n = 0;
+ uint n = 0;
calcnokeychars(par, n, m_varchar + 1);
// set length and pad with nulls
m_varchar[0] = n;
@@ -2006,7 +1988,7 @@ Val::calcnokey(Par par)
break;
case Col::Longvarchar:
{
- unsigned n = 0;
+ uint n = 0;
calcnokeychars(par, n, m_longvarchar + 2);
// set length and pad with nulls
m_longvarchar[0] = (n & 0xff);
@@ -2021,24 +2003,24 @@ Val::calcnokey(Par par)
}
void
-Val::calcnokeychars(Par par, unsigned& n, unsigned char* buf)
+Val::calcnokeychars(Par par, uint& n, uchar* buf)
{
const Col& col = m_col;
const Chs* chs = col.m_chs;
CHARSET_INFO* cs = chs->m_cs;
n = 0;
- unsigned len = 0;
+ uint len = 0;
while (len < col.m_length) {
if (urandom(1 + col.m_bytelength) == 0) {
break;
}
- unsigned half = maxcharcount / 2;
+ uint half = maxcharcount / 2;
int r = irandom((par.m_pctrange * half) / 100);
if (par.m_bdir != 0 && urandom(10) != 0) {
if (r < 0 && par.m_bdir > 0 || r > 0 && par.m_bdir < 0)
r = -r;
}
- unsigned i = half + r;
+ uint i = half + r;
assert(i < maxcharcount);
const Chr& chr = chs->m_chr[i];
assert(n + chr.m_size <= col.m_bytelength);
@@ -2048,13 +2030,39 @@ Val::calcnokeychars(Par par, unsigned& n, unsigned char* buf)
}
}
+// operations
+
int
-Val::verify(Par par, const Val& val2) const
+Val::setval(Par par) const
{
- CHK(cmp(par, val2) == 0);
+ Con& con = par.con();
+ const Col& col = m_col;
+ if (col.m_pk) {
+ assert(!m_null);
+ const char* addr = (const char*)dataaddr();
+ LL5("setval pk [" << col << "] " << *this);
+ CHK(con.equal(col.m_num, addr) == 0);
+ } else {
+ const char* addr = !m_null ? (const char*)dataaddr() : 0;
+ LL5("setval non-pk [" << col << "] " << *this);
+ CHK(con.setValue(col.m_num, addr) == 0);
+ }
+ return 0;
+}
+
+int
+Val::setval(Par par, const ICol& icol) const
+{
+ Con& con = par.con();
+ assert(!m_null);
+ const char* addr = (const char*)dataaddr();
+ LL5("setval key [" << icol << "] " << *this);
+ CHK(con.equal(icol.m_num, addr) == 0);
return 0;
}
+// compare
+
int
Val::cmp(Par par, const Val& val2) const
{
@@ -2062,9 +2070,9 @@ Val::cmp(Par par, const Val& val2) const
const Col& col2 = val2.m_col;
assert(col.equal(col2));
if (m_null || val2.m_null) {
- if (! m_null)
+ if (!m_null)
return +1;
- if (! val2.m_null)
+ if (!val2.m_null)
return -1;
return 0;
}
@@ -2084,21 +2092,21 @@ Val::cmp(Par par, const Val& val2) const
break;
case Col::Char:
{
- unsigned len = col.m_bytelength;
+ uint len = col.m_bytelength;
return cmpchars(par, m_char, len, val2.m_char, len);
}
break;
case Col::Varchar:
{
- unsigned len1 = m_varchar[0];
- unsigned len2 = val2.m_varchar[0];
+ uint len1 = m_varchar[0];
+ uint len2 = val2.m_varchar[0];
return cmpchars(par, m_varchar + 1, len1, val2.m_varchar + 1, len2);
}
break;
case Col::Longvarchar:
{
- unsigned len1 = m_longvarchar[0] + (m_longvarchar[1] << 8);
- unsigned len2 = val2.m_longvarchar[0] + (val2.m_longvarchar[1] << 8);
+ uint len1 = m_longvarchar[0] + (m_longvarchar[1] << 8);
+ uint len2 = val2.m_longvarchar[0] + (val2.m_longvarchar[1] << 8);
return cmpchars(par, m_longvarchar + 2, len1, val2.m_longvarchar + 2, len2);
}
break;
@@ -2110,17 +2118,17 @@ Val::cmp(Par par, const Val& val2) const
}
int
-Val::cmpchars(Par par, const unsigned char* buf1, unsigned len1, const unsigned char* buf2, unsigned len2) const
+Val::cmpchars(Par par, const uchar* buf1, uint len1, const uchar* buf2, uint len2) const
{
const Col& col = m_col;
const Chs* chs = col.m_chs;
CHARSET_INFO* cs = chs->m_cs;
int k;
- if (! par.m_collsp) {
- unsigned char x1[maxxmulsize * 8000];
- unsigned char x2[maxxmulsize * 8000];
+ if (!par.m_collsp) {
+ uchar x1[maxxmulsize * 8000];
+ uchar x2[maxxmulsize * 8000];
// make strxfrm pad both to same length
- unsigned len = maxxmulsize * col.m_bytelength;
+ uint len = maxxmulsize * col.m_bytelength;
int n1 = NdbSqlUtil::strnxfrm_bug7284(cs, x1, chs->m_xmul * len, buf1, len1);
int n2 = NdbSqlUtil::strnxfrm_bug7284(cs, x2, chs->m_xmul * len, buf2, len2);
assert(n1 != -1 && n1 == n2);
@@ -2131,8 +2139,17 @@ Val::cmpchars(Par par, const unsigned char* buf1, unsigned len1, const unsigned
return k < 0 ? -1 : k > 0 ? +1 : 0;
}
+int
+Val::verify(Par par, const Val& val2) const
+{
+ CHK(cmp(par, val2) == 0);
+ return 0;
+}
+
+// print
+
static void
-printstring(NdbOut& out, const unsigned char* str, unsigned len, bool showlen)
+printstring(NdbOut& out, const uchar* str, uint len, bool showlen)
{
char buf[4 * 8000];
char *p = buf;
@@ -2141,12 +2158,12 @@ printstring(NdbOut& out, const unsigned char* str, unsigned len, bool showlen)
sprintf(p, "%u:", len);
p += strlen(p);
}
- for (unsigned i = 0; i < len; i++) {
- unsigned char c = str[i];
+ for (uint i = 0; i < len; i++) {
+ uchar c = str[i];
if (c == '\\') {
*p++ = '\\';
*p++ = c;
- } else if (0x20 <= c && c < 0x7e) {
+ } else if (0x20 <= c && c <= 0x7e) {
*p++ = c;
} else {
*p++ = '\\';
@@ -2173,19 +2190,19 @@ operator<<(NdbOut& out, const Val& val)
break;
case Col::Char:
{
- unsigned len = col.m_bytelength;
+ uint len = col.m_bytelength;
printstring(out, val.m_char, len, false);
}
break;
case Col::Varchar:
{
- unsigned len = val.m_varchar[0];
+ uint len = val.m_varchar[0];
printstring(out, val.m_varchar + 1, len, true);
}
break;
case Col::Longvarchar:
{
- unsigned len = val.m_longvarchar[0] + (val.m_longvarchar[1] << 8);
+ uint len = val.m_longvarchar[0] + (val.m_longvarchar[1] << 8);
printstring(out, val.m_longvarchar + 2, len, true);
}
break;
@@ -2202,16 +2219,36 @@ operator<<(NdbOut& out, const Val& val)
struct Row {
const Tab& m_tab;
Val** m_val;
- bool m_exist;
- enum Op { NoOp = 0, ReadOp = 1, InsOp = 2, UpdOp = 4, DelOp = 8, AnyOp = 15 };
- Op m_pending;
- Row* m_dbrow; // copy of db row before update
+ enum St {
+ StUndef = 0,
+ StDefine = 1,
+ StPrepare = 2,
+ StCommit = 3
+ };
+ enum Op {
+ OpNone = 0,
+ OpIns = 2,
+ OpUpd = 4,
+ OpDel = 8,
+ OpRead = 16,
+ OpReadEx = 32,
+ OpReadCom = 64,
+ OpDML = 2 | 4 | 8,
+ OpREAD = 16 | 32 | 64
+ };
+ St m_st;
+ Op m_op;
+ Uint64 m_txid;
+ Row* m_bi;
+ // construct
Row(const Tab& tab);
~Row();
- void copy(const Row& row2);
- void calc(Par par, unsigned i, unsigned mask = 0);
- const Row& dbrow() const;
- int verify(Par par, const Row& row2, bool pkonly) const;
+ void copy(const Row& row2, bool copy_bi);
+ void copyval(const Row& row2, uint colmask = ~0);
+ void calc(Par par, uint i, uint colmask = ~0);
+ // operations
+ int setval(Par par, uint colmask = ~0);
+ int setval(Par par, const ITab& itab);
int insrow(Par par);
int updrow(Par par);
int updrow(Par par, const ITab& itab);
@@ -2220,120 +2257,132 @@ struct Row {
int selrow(Par par);
int selrow(Par par, const ITab& itab);
int setrow(Par par);
+ // compare
int cmp(Par par, const Row& row2) const;
int cmp(Par par, const Row& row2, const ITab& itab) const;
+ int verify(Par par, const Row& row2, bool pkonly) const;
private:
Row& operator=(const Row& row2);
};
+static NdbOut&
+operator<<(NdbOut& out, const Row* rowp);
+
+static NdbOut&
+operator<<(NdbOut& out, const Row& row);
+
+// construct
+
Row::Row(const Tab& tab) :
m_tab(tab)
{
m_val = new Val* [tab.m_cols];
- for (unsigned k = 0; k < tab.m_cols; k++) {
+ for (uint k = 0; k < tab.m_cols; k++) {
const Col& col = *tab.m_col[k];
m_val[k] = new Val(col);
}
- m_exist = false;
- m_pending = NoOp;
- m_dbrow = 0;
+ m_st = StUndef;
+ m_op = OpNone;
+ m_txid = 0;
+ m_bi = 0;
}
Row::~Row()
{
const Tab& tab = m_tab;
- for (unsigned k = 0; k < tab.m_cols; k++) {
+ for (uint k = 0; k < tab.m_cols; k++) {
delete m_val[k];
}
delete [] m_val;
- delete m_dbrow;
+ delete m_bi;
}
void
-Row::copy(const Row& row2)
+Row::copy(const Row& row2, bool copy_bi)
+{
+ const Tab& tab = m_tab;
+ copyval(row2);
+ m_st = row2.m_st;
+ m_op = row2.m_op;
+ m_txid = row2.m_txid;
+ assert(m_bi == 0);
+ if (copy_bi && row2.m_bi != 0) {
+ m_bi = new Row(tab);
+ m_bi->copy(*row2.m_bi, copy_bi);
+ }
+}
+
+void
+Row::copyval(const Row& row2, uint colmask)
{
const Tab& tab = m_tab;
assert(&tab == &row2.m_tab);
- for (unsigned k = 0; k < tab.m_cols; k++) {
+ for (uint k = 0; k < tab.m_cols; k++) {
Val& val = *m_val[k];
const Val& val2 = *row2.m_val[k];
- val.copy(val2);
- }
- m_exist = row2.m_exist;
- m_pending = row2.m_pending;
- if (row2.m_dbrow == 0) {
- m_dbrow = 0;
- } else {
- assert(row2.m_dbrow->m_dbrow == 0);
- if (m_dbrow == 0)
- m_dbrow = new Row(tab);
- m_dbrow->copy(*row2.m_dbrow);
+ if ((1 << k) & colmask)
+ val.copy(val2);
}
}
void
-Row::calc(Par par, unsigned i, unsigned mask)
+Row::calc(Par par, uint i, uint colmask)
{
const Tab& tab = m_tab;
- for (unsigned k = 0; k < tab.m_cols; k++) {
- if (! (mask & (1 << k))) {
+ for (uint k = 0; k < tab.m_cols; k++) {
+ if ((1 << k) & colmask) {
Val& val = *m_val[k];
val.calc(par, i);
}
}
}
-const Row&
-Row::dbrow() const
-{
- if (m_dbrow == 0)
- return *this;
- assert(m_pending == Row::UpdOp || m_pending == Row::DelOp);
- return *m_dbrow;
-}
+// operations
int
-Row::verify(Par par, const Row& row2, bool pkonly) const
+Row::setval(Par par, uint colmask)
{
const Tab& tab = m_tab;
- const Row& row1 = *this;
- assert(&row1.m_tab == &row2.m_tab && row1.m_exist && row2.m_exist);
- for (unsigned k = 0; k < tab.m_cols; k++) {
- const Col& col = row1.m_val[k]->m_col;
- if (! pkonly || col.m_pk) {
- const Val& val1 = *row1.m_val[k];
- const Val& val2 = *row2.m_val[k];
- CHK(val1.verify(par, val2) == 0);
+ Rsq rsq(tab.m_cols);
+ for (uint k = 0; k < tab.m_cols; k++) {
+ uint k2 = rsq.next();
+ if ((1 << k2) & colmask) {
+ const Val& val = *m_val[k2];
+ CHK(val.setval(par) == 0);
}
}
return 0;
}
int
+Row::setval(Par par, const ITab& itab)
+{
+ Con& con = par.con();
+ Rsq rsq(itab.m_icols);
+ for (uint k = 0; k < itab.m_icols; k++) {
+ uint k2 = rsq.next();
+ const ICol& icol = *itab.m_icol[k2];
+ const Col& col = icol.m_col;
+ uint m = col.m_num;
+ const Val& val = *m_val[m];
+ CHK(val.setval(par, icol) == 0);
+ }
+ return 0;
+}
+
+int
Row::insrow(Par par)
{
Con& con = par.con();
const Tab& tab = m_tab;
- assert(! m_exist);
CHK(con.getNdbOperation(tab) == 0);
CHKCON(con.m_op->insertTuple() == 0, con);
- Rsq rsq1(tab.m_cols);
- for (unsigned k = 0; k < tab.m_cols; k++) {
- unsigned k2 = rsq1.next();
- const Val& val = *m_val[k2];
- const Col& col = val.m_col;
- if (col.m_pk)
- CHK(val.equal(par) == 0);
- }
- Rsq rsq2(tab.m_cols);
- for (unsigned k = 0; k < tab.m_cols; k++) {
- unsigned k2 = rsq2.next();
- const Val& val = *m_val[k2];
- const Col& col = val.m_col;
- if (! col.m_pk)
- CHK(val.setval(par) == 0);
- }
- m_pending = InsOp;
+ CHK(setval(par, tab.m_pkmask) == 0);
+ CHK(setval(par, ~tab.m_pkmask) == 0);
+ assert(m_st == StUndef);
+ m_st = StDefine;
+ m_op = OpIns;
+ m_txid = con.m_txid;
return 0;
}
@@ -2342,26 +2391,14 @@ Row::updrow(Par par)
{
Con& con = par.con();
const Tab& tab = m_tab;
- assert(m_exist);
CHK(con.getNdbOperation(tab) == 0);
CHKCON(con.m_op->updateTuple() == 0, con);
- Rsq rsq1(tab.m_cols);
- for (unsigned k = 0; k < tab.m_cols; k++) {
- unsigned k2 = rsq1.next();
- const Val& val = *m_val[k2];
- const Col& col = val.m_col;
- if (col.m_pk)
- CHK(val.equal(par) == 0);
- }
- Rsq rsq2(tab.m_cols);
- for (unsigned k = 0; k < tab.m_cols; k++) {
- unsigned k2 = rsq2.next();
- const Val& val = *m_val[k2];
- const Col& col = val.m_col;
- if (! col.m_pk)
- CHK(val.setval(par) == 0);
- }
- m_pending = UpdOp;
+ CHK(setval(par, tab.m_pkmask) == 0);
+ CHK(setval(par, ~tab.m_pkmask) == 0);
+ assert(m_st == StUndef);
+ m_st = StDefine;
+ m_op = OpUpd;
+ m_txid = con.m_txid;
return 0;
}
@@ -2371,27 +2408,14 @@ Row::updrow(Par par, const ITab& itab)
Con& con = par.con();
const Tab& tab = m_tab;
assert(itab.m_type == ITab::UniqueHashIndex && &itab.m_tab == &tab);
- assert(m_exist);
CHK(con.getNdbIndexOperation(itab, tab) == 0);
CHKCON(con.m_op->updateTuple() == 0, con);
- Rsq rsq1(itab.m_icols);
- for (unsigned k = 0; k < itab.m_icols; k++) {
- unsigned k2 = rsq1.next();
- const ICol& icol = *itab.m_icol[k2];
- const Col& col = icol.m_col;
- unsigned m = col.m_num;
- const Val& val = *m_val[m];
- CHK(val.equal(par, icol) == 0);
- }
- Rsq rsq2(tab.m_cols);
- for (unsigned k = 0; k < tab.m_cols; k++) {
- unsigned k2 = rsq2.next();
- const Val& val = *m_val[k2];
- const Col& col = val.m_col;
- if (! col.m_pk)
- CHK(val.setval(par) == 0);
- }
- m_pending = UpdOp;
+ CHK(setval(par, itab) == 0);
+ CHK(setval(par, ~tab.m_pkmask) == 0);
+ assert(m_st == StUndef);
+ m_st = StDefine;
+ m_op = OpUpd;
+ m_txid = con.m_txid;
return 0;
}
@@ -2400,18 +2424,13 @@ Row::delrow(Par par)
{
Con& con = par.con();
const Tab& tab = m_tab;
- assert(m_exist);
CHK(con.getNdbOperation(m_tab) == 0);
CHKCON(con.m_op->deleteTuple() == 0, con);
- Rsq rsq1(tab.m_cols);
- for (unsigned k = 0; k < tab.m_cols; k++) {
- unsigned k2 = rsq1.next();
- const Val& val = *m_val[k2];
- const Col& col = val.m_col;
- if (col.m_pk)
- CHK(val.equal(par) == 0);
- }
- m_pending = DelOp;
+ CHK(setval(par, tab.m_pkmask) == 0);
+ assert(m_st == StUndef);
+ m_st = StDefine;
+ m_op = OpDel;
+ m_txid = con.m_txid;
return 0;
}
@@ -2421,19 +2440,13 @@ Row::delrow(Par par, const ITab& itab)
Con& con = par.con();
const Tab& tab = m_tab;
assert(itab.m_type == ITab::UniqueHashIndex && &itab.m_tab == &tab);
- assert(m_exist);
CHK(con.getNdbIndexOperation(itab, tab) == 0);
CHKCON(con.m_op->deleteTuple() == 0, con);
- Rsq rsq1(itab.m_icols);
- for (unsigned k = 0; k < itab.m_icols; k++) {
- unsigned k2 = rsq1.next();
- const ICol& icol = *itab.m_icol[k2];
- const Col& col = icol.m_col;
- unsigned m = col.m_num;
- const Val& val = *m_val[m];
- CHK(val.equal(par, icol) == 0);
- }
- m_pending = DelOp;
+ CHK(setval(par, itab) == 0);
+ assert(m_st == StUndef);
+ m_st = StDefine;
+ m_op = OpDel;
+ m_txid = con.m_txid;
return 0;
}
@@ -2443,15 +2456,9 @@ Row::selrow(Par par)
Con& con = par.con();
const Tab& tab = m_tab;
CHK(con.getNdbOperation(m_tab) == 0);
- CHKCON(con.m_op->readTuple() == 0, con);
- Rsq rsq1(tab.m_cols);
- for (unsigned k = 0; k < tab.m_cols; k++) {
- unsigned k2 = rsq1.next();
- const Val& val = *m_val[k2];
- const Col& col = val.m_col;
- if (col.m_pk)
- CHK(val.equal(par) == 0);
- }
+ CHKCON(con.readTuple(par) == 0, con);
+ CHK(setval(par, tab.m_pkmask) == 0);
+ // TODO state
return 0;
}
@@ -2462,16 +2469,9 @@ Row::selrow(Par par, const ITab& itab)
const Tab& tab = m_tab;
assert(itab.m_type == ITab::UniqueHashIndex && &itab.m_tab == &tab);
CHK(con.getNdbIndexOperation(itab, tab) == 0);
- CHKCON(con.m_op->readTuple() == 0, con);
- Rsq rsq1(itab.m_icols);
- for (unsigned k = 0; k < itab.m_icols; k++) {
- unsigned k2 = rsq1.next();
- const ICol& icol = *itab.m_icol[k2];
- const Col& col = icol.m_col;
- unsigned m = col.m_num;
- const Val& val = *m_val[m];
- CHK(val.equal(par, icol) == 0);
- }
+ CHKCON(con.readTuple(par) == 0, con);
+ CHK(setval(par, itab) == 0);
+ // TODO state
return 0;
}
@@ -2480,25 +2480,23 @@ Row::setrow(Par par)
{
Con& con = par.con();
const Tab& tab = m_tab;
- Rsq rsq1(tab.m_cols);
- for (unsigned k = 0; k < tab.m_cols; k++) {
- unsigned k2 = rsq1.next();
- const Val& val = *m_val[k2];
- const Col& col = val.m_col;
- if (! col.m_pk)
- CHK(val.setval(par) == 0);
- }
- m_pending = UpdOp;
+ CHK(setval(par, ~tab.m_pkmask) == 0);
+ assert(m_st == StUndef);
+ m_st = StDefine;
+ m_op = OpUpd;
+ m_txid = con.m_txid;
return 0;
}
+// compare
+
int
Row::cmp(Par par, const Row& row2) const
{
const Tab& tab = m_tab;
assert(&tab == &row2.m_tab);
int c = 0;
- for (unsigned k = 0; k < tab.m_cols; k++) {
+ for (uint k = 0; k < tab.m_cols; k++) {
const Val& val = *m_val[k];
const Val& val2 = *row2.m_val[k];
if ((c = val.cmp(par, val2)) != 0)
@@ -2512,10 +2510,10 @@ Row::cmp(Par par, const Row& row2, const ITab& itab) const
{
const Tab& tab = m_tab;
int c = 0;
- for (unsigned i = 0; i < itab.m_icols; i++) {
+ for (uint i = 0; i < itab.m_icols; i++) {
const ICol& icol = *itab.m_icol[i];
const Col& col = icol.m_col;
- unsigned k = col.m_num;
+ uint k = col.m_num;
assert(k < tab.m_cols);
const Val& val = *m_val[k];
const Val& val2 = *row2.m_val[k];
@@ -2525,19 +2523,70 @@ Row::cmp(Par par, const Row& row2, const ITab& itab) const
return c;
}
+int
+Row::verify(Par par, const Row& row2, bool pkonly) const
+{
+ const Tab& tab = m_tab;
+ const Row& row1 = *this;
+ assert(&row1.m_tab == &row2.m_tab);
+ for (uint k = 0; k < tab.m_cols; k++) {
+ const Col& col = row1.m_val[k]->m_col;
+ if (!pkonly || col.m_pk) {
+ const Val& val1 = *row1.m_val[k];
+ const Val& val2 = *row2.m_val[k];
+ CHK(val1.verify(par, val2) == 0);
+ }
+ }
+ return 0;
+}
+
+// print
+
+static NdbOut&
+operator<<(NdbOut& out, const Row::St st)
+{
+ if (st == Row::StUndef)
+ out << "StUndef";
+ else if (st == Row::StDefine)
+ out << "StDefine";
+ else if (st == Row::StPrepare)
+ out << "StPrepare";
+ else if (st == Row::StCommit)
+ out << "StCommit";
+ else
+ out << "st=" << st;
+ return out;
+}
+
static NdbOut&
operator<<(NdbOut& out, const Row::Op op)
{
- if (op == Row::NoOp)
- out << "NoOp";
- else if (op == Row::InsOp)
- out << "InsOp";
- else if (op == Row::UpdOp)
- out << "UpdOp";
- else if (op == Row::DelOp)
- out << "DelOp";
+ if (op == Row::OpNone)
+ out << "OpNone";
+ else if (op == Row::OpIns)
+ out << "OpIns";
+ else if (op == Row::OpUpd)
+ out << "OpUpd";
+ else if (op == Row::OpDel)
+ out << "OpDel";
+ else if (op == Row::OpRead)
+ out << "OpRead";
+ else if (op == Row::OpReadEx)
+ out << "OpReadEx";
+ else if (op == Row::OpReadCom)
+ out << "OpReadCom";
else
- out << op;
+ out << "op=" << op;
+ return out;
+}
+
+static NdbOut&
+operator<<(NdbOut& out, const Row* rowp)
+{
+ if (rowp == 0)
+ out << "[null]";
+ else
+ out << *rowp;
return out;
}
@@ -2545,26 +2594,18 @@ static NdbOut&
operator<<(NdbOut& out, const Row& row)
{
const Tab& tab = row.m_tab;
- for (unsigned i = 0; i < tab.m_cols; i++) {
+ out << "[";
+ for (uint i = 0; i < tab.m_cols; i++) {
if (i > 0)
out << " ";
out << *row.m_val[i];
}
- out << " exist=" << row.m_exist;
- if (row.m_pending)
- out << " pending=" << row.m_pending;
- if (row.m_dbrow != 0)
- out << " [dbrow=" << *row.m_dbrow << "]";
- return out;
-}
-
-static NdbOut&
-operator<<(NdbOut& out, const Row* rowptr)
-{
- if (rowptr == 0)
- out << "null";
- else
- out << *rowptr;
+ out << " " << row.m_st;
+ out << " " << row.m_op;
+ out << " " << HEX(row.m_txid);
+ if (row.m_bi != 0)
+ out << " " << row.m_bi;
+ out << "]";
return out;
}
@@ -2572,45 +2613,38 @@ operator<<(NdbOut& out, const Row* rowptr)
struct Set {
const Tab& m_tab;
- unsigned m_rows;
+ uint m_rows;
Row** m_row;
- unsigned* m_rowkey; // maps row number (from 0) in scan to tuple key
+ uint* m_rowkey; // maps row number (from 0) in scan to tuple key
Row* m_keyrow;
NdbRecAttr** m_rec;
- Set(const Tab& tab, unsigned rows);
+ // construct
+ Set(const Tab& tab, uint rows);
~Set();
void reset();
- unsigned count() const;
- // old and new values
- bool exist(unsigned i) const;
- void dbsave(unsigned i);
- void calc(Par par, unsigned i, unsigned mask = 0);
- bool pending(unsigned i, unsigned mask) const;
- void notpending(unsigned i, ExecType et = Commit);
- void notpending(const Lst& lst, ExecType et = Commit);
- void dbdiscard(unsigned i);
- void dbdiscard(const Lst& lst);
- const Row& dbrow(unsigned i) const;
+ bool compat(Par par, uint i, const Row::Op op) const;
+ void push(uint i);
+ void copyval(uint i, uint colmask = ~0); // from bi
+ void calc(Par par, uint i, uint colmask = ~0);
+ uint count() const;
+ const Row* getrow(uint i, bool dirty = false) const;
+ // transaction
+ void post(Par par, ExecType et);
// operations
- int insrow(Par par, unsigned i);
- int updrow(Par par, unsigned i);
- int updrow(Par par, const ITab& itab, unsigned i);
- int delrow(Par par, unsigned i);
- int delrow(Par par, const ITab& itab, unsigned i);
+ int insrow(Par par, uint i);
+ int updrow(Par par, uint i);
+ int updrow(Par par, const ITab& itab, uint i);
+ int delrow(Par par, uint i);
+ int delrow(Par par, const ITab& itab, uint i);
int selrow(Par par, const Row& keyrow);
int selrow(Par par, const ITab& itab, const Row& keyrow);
- // set and get
- void setkey(Par par, const Row& keyrow);
- void setkey(Par par, const ITab& itab, const Row& keyrow);
- int setrow(Par par, unsigned i);
+ int setrow(Par par, uint i);
int getval(Par par);
- int getkey(Par par, unsigned* i);
- int putval(unsigned i, bool force, unsigned n = ~0);
- // sort rows in-place according to ordered index
+ int getkey(Par par, uint* i);
+ int putval(uint i, bool force, uint n = ~0);
+ // compare
void sort(Par par, const ITab& itab);
- void sort(Par par, const ITab& itab, unsigned lo, unsigned hi);
- // verify
- int verify(Par par, const Set& set2, bool pkonly) const;
+ int verify(Par par, const Set& set2, bool pkonly, bool dirty = false) const;
int verifyorder(Par par, const ITab& itab, bool descending) const;
// protect structure
NdbMutex* m_mutex;
@@ -2621,26 +2655,27 @@ struct Set {
NdbMutex_Unlock(m_mutex);
}
private:
+ void sort(Par par, const ITab& itab, uint lo, uint hi);
Set& operator=(const Set& set2);
};
-Set::Set(const Tab& tab, unsigned rows) :
+// construct
+
+Set::Set(const Tab& tab, uint rows) :
m_tab(tab)
{
m_rows = rows;
m_row = new Row* [m_rows];
- for (unsigned i = 0; i < m_rows; i++) {
- // allocate on need to save space
+ for (uint i = 0; i < m_rows; i++) {
m_row[i] = 0;
}
- m_rowkey = new unsigned [m_rows];
- for (unsigned n = 0; n < m_rows; n++) {
- // initialize to null
+ m_rowkey = new uint [m_rows];
+ for (uint n = 0; n < m_rows; n++) {
m_rowkey[n] = ~0;
}
m_keyrow = new Row(tab);
m_rec = new NdbRecAttr* [tab.m_cols];
- for (unsigned k = 0; k < tab.m_cols; k++) {
+ for (uint k = 0; k < tab.m_cols; k++) {
m_rec[k] = 0;
}
m_mutex = NdbMutex_Create();
@@ -2649,7 +2684,7 @@ Set::Set(const Tab& tab, unsigned rows) :
Set::~Set()
{
- for (unsigned i = 0; i < m_rows; i++) {
+ for (uint i = 0; i < m_rows; i++) {
delete m_row[i];
}
delete [] m_row;
@@ -2662,132 +2697,203 @@ Set::~Set()
void
Set::reset()
{
- for (unsigned i = 0; i < m_rows; i++) {
- if (m_row[i] != 0) {
- Row& row = *m_row[i];
- row.m_exist = false;
- }
- }
-}
-
-unsigned
-Set::count() const
-{
- unsigned count = 0;
- for (unsigned i = 0; i < m_rows; i++) {
- if (m_row[i] != 0) {
- Row& row = *m_row[i];
- if (row.m_exist)
- count++;
- }
+ for (uint i = 0; i < m_rows; i++) {
+ m_row[i] = 0;
}
- return count;
}
-// old and new values
-
+// this sucks
bool
-Set::exist(unsigned i) const
+Set::compat(Par par, uint i, const Row::Op op) const
{
- assert(i < m_rows);
- if (m_row[i] == 0) // not allocated => not exist
- return false;
- return m_row[i]->m_exist;
+ Con& con = par.con();
+ int ret = -1;
+ int place = 0;
+ do {
+ const Row* rowp = getrow(i);
+ if (rowp == 0) {
+ ret = op == Row::OpIns;
+ place = 1;
+ break;
+ }
+ const Row& row = *rowp;
+ if (!(op & Row::OpREAD)) {
+ if (row.m_st == Row::StDefine || row.m_st == Row::StPrepare) {
+ assert(row.m_op & Row::OpDML);
+ assert(row.m_txid != 0);
+ if (con.m_txid != row.m_txid) {
+ ret = false;
+ place = 2;
+ break;
+ }
+ if (row.m_op != Row::OpDel) {
+ ret = op == Row::OpUpd || op == Row::OpDel;
+ place = 3;
+ break;
+ }
+ ret = op == Row::OpIns;
+ place = 4;
+ break;
+ }
+ if (row.m_st == Row::StCommit) {
+ assert(row.m_op == Row::OpNone);
+ assert(row.m_txid == 0);
+ ret = op == Row::OpUpd || op == Row::OpDel;
+ place = 5;
+ break;
+ }
+ }
+ if (op & Row::OpREAD) {
+ bool dirty =
+ con.m_txid != row.m_txid &&
+ par.m_lockmode == NdbOperation::LM_CommittedRead;
+ const Row* rowp2 = getrow(i, dirty);
+ if (rowp2 == 0 || rowp2->m_op == Row::OpDel) {
+ ret = false;
+ place = 6;
+ break;
+ }
+ ret = true;
+ place = 7;
+ break;
+ }
+ } while (0);
+ LL4("compat ret=" << ret << " place=" << place);
+ assert(ret == false || ret == true);
+ return ret;
}
void
-Set::dbsave(unsigned i)
+Set::push(uint i)
{
const Tab& tab = m_tab;
- assert(i < m_rows && m_row[i] != 0);
+ assert(i < m_rows);
+ Row* bi = m_row[i];
+ m_row[i] = new Row(tab);
Row& row = *m_row[i];
- LL5("dbsave " << i << ": " << row);
- assert(row.m_exist && ! row.m_pending && row.m_dbrow == 0);
- // could swap pointers but making copy is safer
- Row* rowptr = new Row(tab);
- rowptr->copy(row);
- row.m_dbrow = rowptr;
+ row.m_bi = bi;
+ if (bi != 0)
+ row.copyval(*bi);
}
void
-Set::calc(Par par, unsigned i, unsigned mask)
+Set::copyval(uint i, uint colmask)
{
- const Tab& tab = m_tab;
- if (m_row[i] == 0)
- m_row[i] = new Row(tab);
+ assert(m_row[i] != 0);
Row& row = *m_row[i];
- row.calc(par, i, mask);
-}
-
-bool
-Set::pending(unsigned i, unsigned mask) const
-{
- assert(i < m_rows);
- if (m_row[i] == 0) // not allocated => not pending
- return Row::NoOp;
- return m_row[i]->m_pending & mask;
+ assert(row.m_bi != 0);
+ row.copyval(*row.m_bi, colmask);
}
void
-Set::notpending(unsigned i, ExecType et)
+Set::calc(Par par, uint i, uint colmask)
{
assert(m_row[i] != 0);
Row& row = *m_row[i];
- if (et == Commit) {
- if (row.m_pending == Row::InsOp)
- row.m_exist = true;
- if (row.m_pending == Row::DelOp)
- row.m_exist = false;
- } else {
- if (row.m_pending == Row::InsOp)
- row.m_exist = false;
- if (row.m_pending == Row::DelOp)
- row.m_exist = true;
- }
- row.m_pending = Row::NoOp;
+ row.calc(par, i, colmask);
}
-void
-Set::notpending(const Lst& lst, ExecType et)
+uint
+Set::count() const
{
- for (unsigned j = 0; j < lst.m_cnt; j++) {
- unsigned i = lst.m_arr[j];
- notpending(i, et);
+ uint count = 0;
+ for (uint i = 0; i < m_rows; i++) {
+ if (m_row[i] != 0)
+ count++;
}
+ return count;
}
-void
-Set::dbdiscard(unsigned i)
+const Row*
+Set::getrow(uint i, bool dirty) const
{
- assert(m_row[i] != 0);
- Row& row = *m_row[i];
- LL5("dbdiscard " << i << ": " << row);
- assert(row.m_dbrow != 0);
- delete row.m_dbrow;
- row.m_dbrow = 0;
+ assert(i < m_rows);
+ const Row* rowp = m_row[i];
+ if (dirty) {
+ while (rowp != 0) {
+ bool b1 = rowp->m_op == Row::OpNone;
+ bool b2 = rowp->m_st == Row::StCommit;
+ assert(b1 == b2);
+ if (b1) {
+ assert(rowp->m_bi == 0);
+ break;
+ }
+ rowp = rowp->m_bi;
+ }
+ }
+ return rowp;
}
-const Row&
-Set::dbrow(unsigned i) const
-{
- assert(m_row[i] != 0);
- Row& row = *m_row[i];
- return row.dbrow();
-}
+// transaction
void
-Set::dbdiscard(const Lst& lst)
+Set::post(Par par, ExecType et)
{
- for (unsigned j = 0; j < lst.m_cnt; j++) {
- unsigned i = lst.m_arr[j];
- dbdiscard(i);
+ LL4("post");
+ Con& con = par.con();
+ assert(con.m_txid != 0);
+ uint i;
+ for (i = 0; i < m_rows; i++) {
+ Row* rowp = m_row[i];
+ if (rowp == 0) {
+ LL5("skip " << i << " " << rowp);
+ continue;
+ }
+ if (rowp->m_st == Row::StCommit) {
+ assert(rowp->m_op == Row::OpNone);
+ assert(rowp->m_txid == 0);
+ assert(rowp->m_bi == 0);
+ LL5("skip committed " << i << " " << rowp);
+ continue;
+ }
+ assert(rowp->m_st == Row::StDefine || rowp->m_st == Row::StPrepare);
+ assert(rowp->m_txid != 0);
+ if (con.m_txid != rowp->m_txid) {
+ LL5("skip txid " << i << " " << HEX(con.m_txid) << " " << rowp);
+ continue;
+ }
+ // TODO read ops
+ assert(rowp->m_op & Row::OpDML);
+ LL4("post BEFORE " << rowp);
+ if (et == NoCommit) {
+ if (rowp->m_st == Row::StDefine) {
+ rowp->m_st = Row::StPrepare;
+ Row* bi = rowp->m_bi;
+ while (bi != 0 && bi->m_st == Row::StDefine) {
+ bi->m_st = Row::StPrepare;
+ bi = bi->m_bi;
+ }
+ }
+ } else if (et == Commit) {
+ if (rowp->m_op != Row::OpDel) {
+ rowp->m_st = Row::StCommit;
+ rowp->m_op = Row::OpNone;
+ rowp->m_txid = 0;
+ delete rowp->m_bi;
+ rowp->m_bi = 0;
+ } else {
+ delete rowp;
+ rowp = 0;
+ }
+ } else if (et == Rollback) {
+ while (rowp != 0 && rowp->m_st != Row::StCommit) {
+ Row* tmp = rowp;
+ rowp = rowp->m_bi;
+ tmp->m_bi = 0;
+ delete tmp;
+ }
+ } else {
+ assert(false);
+ }
+ m_row[i] = rowp;
+ LL4("post AFTER " << rowp);
}
}
// operations
int
-Set::insrow(Par par, unsigned i)
+Set::insrow(Par par, uint i)
{
assert(m_row[i] != 0);
Row& row = *m_row[i];
@@ -2796,7 +2902,7 @@ Set::insrow(Par par, unsigned i)
}
int
-Set::updrow(Par par, unsigned i)
+Set::updrow(Par par, uint i)
{
assert(m_row[i] != 0);
Row& row = *m_row[i];
@@ -2805,7 +2911,7 @@ Set::updrow(Par par, unsigned i)
}
int
-Set::updrow(Par par, const ITab& itab, unsigned i)
+Set::updrow(Par par, const ITab& itab, uint i)
{
assert(m_row[i] != 0);
Row& row = *m_row[i];
@@ -2814,7 +2920,7 @@ Set::updrow(Par par, const ITab& itab, unsigned i)
}
int
-Set::delrow(Par par, unsigned i)
+Set::delrow(Par par, uint i)
{
assert(m_row[i] != 0);
Row& row = *m_row[i];
@@ -2823,7 +2929,7 @@ Set::delrow(Par par, unsigned i)
}
int
-Set::delrow(Par par, const ITab& itab, unsigned i)
+Set::delrow(Par par, const ITab& itab, uint i)
{
assert(m_row[i] != 0);
Row& row = *m_row[i];
@@ -2836,8 +2942,8 @@ Set::selrow(Par par, const Row& keyrow)
{
Con& con = par.con();
const Tab& tab = par.tab();
- setkey(par, keyrow);
- LL5("selrow " << tab.m_name << ": keyrow: " << keyrow);
+ LL5("selrow " << tab.m_name << " keyrow " << keyrow);
+ m_keyrow->copyval(keyrow, tab.m_pkmask);
CHK(m_keyrow->selrow(par) == 0);
CHK(getval(par) == 0);
return 0;
@@ -2847,45 +2953,15 @@ int
Set::selrow(Par par, const ITab& itab, const Row& keyrow)
{
Con& con = par.con();
- setkey(par, itab, keyrow);
- LL5("selrow " << itab.m_name << ": keyrow: " << keyrow);
+ LL5("selrow " << itab.m_name << " keyrow " << keyrow);
+ m_keyrow->copyval(keyrow, itab.m_keymask);
CHK(m_keyrow->selrow(par, itab) == 0);
CHK(getval(par) == 0);
return 0;
}
-// set and get
-
-void
-Set::setkey(Par par, const Row& keyrow)
-{
- const Tab& tab = m_tab;
- for (unsigned k = 0; k < tab.m_cols; k++) {
- const Col& col = *tab.m_col[k];
- if (col.m_pk) {
- Val& val1 = *m_keyrow->m_val[k];
- const Val& val2 = *keyrow.dbrow().m_val[k];
- val1.copy(val2);
- }
- }
-}
-
-void
-Set::setkey(Par par, const ITab& itab, const Row& keyrow)
-{
- const Tab& tab = m_tab;
- for (unsigned k = 0; k < itab.m_icols; k++) {
- const ICol& icol = *itab.m_icol[k];
- const Col& col = icol.m_col;
- unsigned m = col.m_num;
- Val& val1 = *m_keyrow->m_val[m];
- const Val& val2 = *keyrow.dbrow().m_val[m];
- val1.copy(val2);
- }
-}
-
int
-Set::setrow(Par par, unsigned i)
+Set::setrow(Par par, uint i)
{
Con& con = par.con();
assert(m_row[i] != 0);
@@ -2899,18 +2975,18 @@ Set::getval(Par par)
Con& con = par.con();
const Tab& tab = m_tab;
Rsq rsq1(tab.m_cols);
- for (unsigned k = 0; k < tab.m_cols; k++) {
- unsigned k2 = rsq1.next();
+ for (uint k = 0; k < tab.m_cols; k++) {
+ uint k2 = rsq1.next();
CHK(con.getValue(k2, m_rec[k2]) == 0);
}
return 0;
}
int
-Set::getkey(Par par, unsigned* i)
+Set::getkey(Par par, uint* i)
{
const Tab& tab = m_tab;
- unsigned k = tab.m_keycol;
+ uint k = tab.m_keycol;
assert(m_rec[k] != 0);
const char* aRef = m_rec[k]->aRef();
Uint32 key = *(const Uint32*)aRef;
@@ -2921,14 +2997,18 @@ Set::getkey(Par par, unsigned* i)
}
int
-Set::putval(unsigned i, bool force, unsigned n)
+Set::putval(uint i, bool force, uint n)
{
const Tab& tab = m_tab;
- if (m_row[i] == 0)
- m_row[i] = new Row(tab);
+ LL4("putval key=" << i << " row=" << n << " old=" << m_row[i]);
+ if (m_row[i] != 0) {
+ assert(force);
+ delete m_row[i];
+ m_row[i] = 0;
+ }
+ m_row[i] = new Row(tab);
Row& row = *m_row[i];
- CHK(! row.m_exist || force);
- for (unsigned k = 0; k < tab.m_cols; k++) {
+ for (uint k = 0; k < tab.m_cols; k++) {
Val& val = *row.m_val[k];
NdbRecAttr* rec = m_rec[k];
assert(rec != 0);
@@ -2940,13 +3020,13 @@ Set::putval(unsigned i, bool force, unsigned n)
val.copy(aRef);
val.m_null = false;
}
- if (! row.m_exist)
- row.m_exist = true;
if (n != ~0)
m_rowkey[n] = i;
return 0;
}
+// compare
+
void
Set::sort(Par par, const ITab& itab)
{
@@ -2955,12 +3035,12 @@ Set::sort(Par par, const ITab& itab)
}
void
-Set::sort(Par par, const ITab& itab, unsigned lo, unsigned hi)
+Set::sort(Par par, const ITab& itab, uint lo, uint hi)
{
assert(lo < m_rows && hi < m_rows && lo <= hi);
Row* const p = m_row[lo];
- unsigned i = lo;
- unsigned j = hi;
+ uint i = lo;
+ uint j = hi;
while (i < j) {
while (i < j && m_row[j]->cmp(par, *p, itab) >= 0)
j--;
@@ -2982,22 +3062,48 @@ Set::sort(Par par, const ITab& itab, unsigned lo, unsigned hi)
sort(par, itab, i + 1, hi);
}
+/*
+ * set1 (self) is from dml and can contain un-committed operations.
+ * set2 is from read and contains no operations. "dirty" applies
+ * to set1: false = use latest row, true = use committed row.
+ */
int
-Set::verify(Par par, const Set& set2, bool pkonly) const
-{
- assert(&m_tab == &set2.m_tab && m_rows == set2.m_rows);
- LL4("verify set1 count=" << count() << " vs set2 count=" << set2.count());
- for (unsigned i = 0; i < m_rows; i++) {
+Set::verify(Par par, const Set& set2, bool pkonly, bool dirty) const
+{
+ const Set& set1 = *this;
+ assert(&set1.m_tab == &set2.m_tab && set1.m_rows == set2.m_rows);
+ LL3("verify dirty:" << dirty);
+ for (uint i = 0; i < set1.m_rows; i++) {
+ // the row versions we actually compare
+ const Row* row1p = set1.getrow(i, dirty);
+ const Row* row2p = set2.getrow(i);
bool ok = true;
- if (exist(i) != set2.exist(i)) {
- ok = false;
- } else if (exist(i)) {
- if (dbrow(i).verify(par, set2.dbrow(i), pkonly) != 0)
+ int place = 0;
+ if (row1p == 0) {
+ if (row2p != 0) {
+ ok = false;
+ place = 1;
+ }
+ } else {
+ Row::Op op1 = row1p->m_op;
+ if (op1 != Row::OpDel) {
+ if (row2p == 0) {
+ ok = false;
+ place = 2;
+ } else if (row1p->verify(par, *row2p, pkonly) == -1) {
+ ok = false;
+ place = 3;
+ }
+ } else if (row2p != 0) {
ok = false;
+ place = 4;
+ }
}
- if (! ok) {
- LL1("verify failed: key=" << i << " row1=" << m_row[i] << " row2=" << set2.m_row[i]);
- CHK(0 == 1);
+ if (!ok) {
+ LL1("verify " << i << " failed at " << place);
+ LL1("row1 " << row1p);
+ LL1("row2 " << row2p);
+ CHK(false);
}
}
return 0;
@@ -3007,18 +3113,17 @@ int
Set::verifyorder(Par par, const ITab& itab, bool descending) const
{
const Tab& tab = m_tab;
- for (unsigned n = 0; n < m_rows; n++) {
- unsigned i2 = m_rowkey[n];
+ for (uint n = 0; n < m_rows; n++) {
+ uint i2 = m_rowkey[n];
if (i2 == ~0)
break;
if (n == 0)
continue;
- unsigned i1 = m_rowkey[n - 1];
- assert(i1 < m_rows && i2 < m_rows);
+ uint i1 = m_rowkey[n - 1];
+ assert(m_row[i1] != 0 && m_row[i2] != 0);
const Row& row1 = *m_row[i1];
const Row& row2 = *m_row[i2];
- assert(row1.m_exist && row2.m_exist);
- if (! descending)
+ if (!descending)
CHK(row1.cmp(par, row2, itab) <= 0);
else
CHK(row1.cmp(par, row2, itab) >= 0);
@@ -3026,10 +3131,12 @@ Set::verifyorder(Par par, const ITab& itab, bool descending) const
return 0;
}
+// print
+
static NdbOut&
operator<<(NdbOut& out, const Set& set)
{
- for (unsigned i = 0; i < set.m_rows; i++) {
+ for (uint i = 0; i < set.m_rows; i++) {
const Row& row = *set.m_row[i];
if (i > 0)
out << endl;
@@ -3058,8 +3165,8 @@ int
BVal::setbnd(Par par) const
{
Con& con = par.con();
- assert(g_compare_null || ! m_null);
- const char* addr = ! m_null ? (const char*)dataaddr() : 0;
+ assert(g_compare_null || !m_null);
+ const char* addr = !m_null ? (const char*)dataaddr() : 0;
const ICol& icol = m_icol;
CHK(con.setBound(icol.m_num, m_type, addr) == 0);
return 0;
@@ -3068,7 +3175,7 @@ BVal::setbnd(Par par) const
int
BVal::setflt(Par par) const
{
- static unsigned index_bound_to_filter_bound[5] = {
+ static uint index_bound_to_filter_bound[5] = {
NdbScanFilter::COND_GE,
NdbScanFilter::COND_GT,
NdbScanFilter::COND_LE,
@@ -3076,12 +3183,12 @@ BVal::setflt(Par par) const
NdbScanFilter::COND_EQ
};
Con& con = par.con();
- assert(g_compare_null || ! m_null);
- const char* addr = ! m_null ? (const char*)dataaddr() : 0;
+ assert(g_compare_null || !m_null);
+ const char* addr = !m_null ? (const char*)dataaddr() : 0;
const ICol& icol = m_icol;
const Col& col = icol.m_col;
- unsigned length = col.m_bytesize;
- unsigned cond = index_bound_to_filter_bound[m_type];
+ uint length = col.m_bytesize;
+ uint cond = index_bound_to_filter_bound[m_type];
CHK(con.setFilter(col.m_num, cond, addr, length) == 0);
return 0;
}
@@ -3104,27 +3211,27 @@ operator<<(NdbOut& out, const BVal& bval)
struct BSet {
const Tab& m_tab;
const ITab& m_itab;
- unsigned m_alloc;
- unsigned m_bvals;
+ uint m_alloc;
+ uint m_bvals;
BVal** m_bval;
- BSet(const Tab& tab, const ITab& itab, unsigned rows);
+ BSet(const Tab& tab, const ITab& itab);
~BSet();
void reset();
void calc(Par par);
- void calcpk(Par par, unsigned i);
+ void calcpk(Par par, uint i);
int setbnd(Par par) const;
int setflt(Par par) const;
void filter(Par par, const Set& set, Set& set2) const;
};
-BSet::BSet(const Tab& tab, const ITab& itab, unsigned rows) :
+BSet::BSet(const Tab& tab, const ITab& itab) :
m_tab(tab),
m_itab(itab),
m_alloc(2 * itab.m_icols),
m_bvals(0)
{
m_bval = new BVal* [m_alloc];
- for (unsigned i = 0; i < m_alloc; i++) {
+ for (uint i = 0; i < m_alloc; i++) {
m_bval[i] = 0;
}
}
@@ -3138,7 +3245,7 @@ void
BSet::reset()
{
while (m_bvals > 0) {
- unsigned i = --m_bvals;
+ uint i = --m_bvals;
delete m_bval[i];
m_bval[i] = 0;
}
@@ -3150,10 +3257,10 @@ BSet::calc(Par par)
const ITab& itab = m_itab;
par.m_pctrange = par.m_pctbrange;
reset();
- for (unsigned k = 0; k < itab.m_icols; k++) {
+ for (uint k = 0; k < itab.m_icols; k++) {
const ICol& icol = *itab.m_icol[k];
const Col& col = icol.m_col;
- for (unsigned i = 0; i <= 1; i++) {
+ for (uint i = 0; i <= 1; i++) {
if (m_bvals == 0 && urandom(100) == 0)
return;
if (m_bvals != 0 && urandom(3) == 0)
@@ -3162,7 +3269,7 @@ BSet::calc(Par par)
BVal& bval = *new BVal(icol);
m_bval[m_bvals++] = &bval;
bval.m_null = false;
- unsigned sel;
+ uint sel;
do {
// equality bound only on i==0
sel = urandom(5 - i);
@@ -3175,7 +3282,7 @@ BSet::calc(Par par)
bval.m_type = 4;
if (k + 1 < itab.m_icols)
bval.m_type = 4;
- if (! g_compare_null)
+ if (!g_compare_null)
par.m_pctnull = 0;
if (bval.m_type == 0 || bval.m_type == 1)
par.m_bdir = -1;
@@ -3199,11 +3306,11 @@ BSet::calc(Par par)
}
void
-BSet::calcpk(Par par, unsigned i)
+BSet::calcpk(Par par, uint i)
{
const ITab& itab = m_itab;
reset();
- for (unsigned k = 0; k < itab.m_icols; k++) {
+ for (uint k = 0; k < itab.m_icols; k++) {
const ICol& icol = *itab.m_icol[k];
const Col& col = icol.m_col;
assert(col.m_pk);
@@ -3220,14 +3327,14 @@ BSet::setbnd(Par par) const
{
if (m_bvals != 0) {
Rsq rsq1(m_bvals);
- for (unsigned j = 0; j < m_bvals; j++) {
- unsigned j2 = rsq1.next();
+ for (uint j = 0; j < m_bvals; j++) {
+ uint j2 = rsq1.next();
const BVal& bval = *m_bval[j2];
CHK(bval.setbnd(par) == 0);
}
// duplicate
if (urandom(5) == 0) {
- unsigned j3 = urandom(m_bvals);
+ uint j3 = urandom(m_bvals);
const BVal& bval = *m_bval[j3];
CHK(bval.setbnd(par) == 0);
}
@@ -3243,14 +3350,14 @@ BSet::setflt(Par par) const
CHK(con.beginFilter(NdbScanFilter::AND) == 0);
if (m_bvals != 0) {
Rsq rsq1(m_bvals);
- for (unsigned j = 0; j < m_bvals; j++) {
- unsigned j2 = rsq1.next();
+ for (uint j = 0; j < m_bvals; j++) {
+ uint j2 = rsq1.next();
const BVal& bval = *m_bval[j2];
CHK(bval.setflt(par) == 0);
}
// duplicate
if (urandom(5) == 0) {
- unsigned j3 = urandom(m_bvals);
+ uint j3 = urandom(m_bvals);
const BVal& bval = *m_bval[j3];
CHK(bval.setflt(par) == 0);
}
@@ -3266,57 +3373,59 @@ BSet::filter(Par par, const Set& set, Set& set2) const
const ITab& itab = m_itab;
assert(&tab == &set2.m_tab && set.m_rows == set2.m_rows);
assert(set2.count() == 0);
- for (unsigned i = 0; i < set.m_rows; i++) {
- if (! set.exist(i))
- continue;
+ for (uint i = 0; i < set.m_rows; i++) {
set.lock();
- const Row& row = set.dbrow(i);
- set.unlock();
- if (! g_store_null_key) {
- bool ok1 = false;
- for (unsigned k = 0; k < itab.m_icols; k++) {
- const ICol& icol = *itab.m_icol[k];
+ do {
+ if (set.m_row[i] == 0) {
+ break;
+ }
+ const Row& row = *set.m_row[i];
+ if (!g_store_null_key) {
+ bool ok1 = false;
+ for (uint k = 0; k < itab.m_icols; k++) {
+ const ICol& icol = *itab.m_icol[k];
+ const Col& col = icol.m_col;
+ const Val& val = *row.m_val[col.m_num];
+ if (!val.m_null) {
+ ok1 = true;
+ break;
+ }
+ }
+ if (!ok1)
+ break;
+ }
+ bool ok2 = true;
+ for (uint j = 0; j < m_bvals; j++) {
+ const BVal& bval = *m_bval[j];
+ const ICol& icol = bval.m_icol;
const Col& col = icol.m_col;
const Val& val = *row.m_val[col.m_num];
- if (! val.m_null) {
- ok1 = true;
- break;
+ int ret = bval.cmp(par, val);
+ LL5("cmp: ret=" << ret << " " << bval << " vs " << val);
+ if (bval.m_type == 0)
+ ok2 = (ret <= 0);
+ else if (bval.m_type == 1)
+ ok2 = (ret < 0);
+ else if (bval.m_type == 2)
+ ok2 = (ret >= 0);
+ else if (bval.m_type == 3)
+ ok2 = (ret > 0);
+ else if (bval.m_type == 4)
+ ok2 = (ret == 0);
+ else {
+ assert(false);
}
+ if (!ok2)
+ break;
}
- if (! ok1)
- continue;
- }
- bool ok2 = true;
- for (unsigned j = 0; j < m_bvals; j++) {
- const BVal& bval = *m_bval[j];
- const ICol& icol = bval.m_icol;
- const Col& col = icol.m_col;
- const Val& val = *row.m_val[col.m_num];
- int ret = bval.cmp(par, val);
- LL5("cmp: ret=" << ret << " " << bval << " vs " << val);
- if (bval.m_type == 0)
- ok2 = (ret <= 0);
- else if (bval.m_type == 1)
- ok2 = (ret < 0);
- else if (bval.m_type == 2)
- ok2 = (ret >= 0);
- else if (bval.m_type == 3)
- ok2 = (ret > 0);
- else if (bval.m_type == 4)
- ok2 = (ret == 0);
- else {
- assert(false);
- }
- if (! ok2)
+ if (!ok2)
break;
- }
- if (! ok2)
- continue;
- if (set2.m_row[i] == 0)
+ assert(set2.m_row[i] == 0);
set2.m_row[i] = new Row(tab);
- Row& row2 = *set2.m_row[i];
- assert(! row2.m_exist);
- row2.copy(row);
+ Row& row2 = *set2.m_row[i];
+ row2.copy(row, true);
+ } while (0);
+ set.unlock();
}
}
@@ -3324,7 +3433,7 @@ static NdbOut&
operator<<(NdbOut& out, const BSet& bset)
{
out << "bounds=" << bset.m_bvals;
- for (unsigned j = 0; j < bset.m_bvals; j++) {
+ for (uint j = 0; j < bset.m_bvals; j++) {
const BVal& bval = *bset.m_bval[j];
out << " [bound " << j << ": " << bval << "]";
}
@@ -3341,59 +3450,40 @@ pkinsert(Par par)
Set& set = par.set();
LL3("pkinsert " << tab.m_name);
CHK(con.startTransaction() == 0);
- Lst lst;
- for (unsigned j = 0; j < par.m_rows; j++) {
- unsigned j2 = ! par.m_randomkey ? j : urandom(par.m_rows);
- unsigned i = thrrow(par, j2);
+ uint batch = 0;
+ for (uint j = 0; j < par.m_rows; j++) {
+ uint j2 = !par.m_randomkey ? j : urandom(par.m_rows);
+ uint i = thrrow(par, j2);
set.lock();
- if (set.exist(i) || set.pending(i, Row::AnyOp)) {
+ if (!set.compat(par, i, Row::OpIns)) {
+ LL3("pkinsert SKIP " << i << " " << set.getrow(i));
set.unlock();
- continue;
- }
- set.calc(par, i);
- CHK(set.insrow(par, i) == 0);
- set.unlock();
- LL4("pkinsert " << i << ": " << *set.m_row[i]);
- lst.push(i);
- if (lst.cnt() == par.m_batch) {
- bool deadlock = par.m_deadlock;
- bool nospace = true;
- ExecType et = randompct(par.m_abortpct) ? Rollback : Commit;
- CHK(con.execute(et, deadlock, nospace) == 0);
- con.closeTransaction();
- if (deadlock) {
- LL1("pkinsert: stop on deadlock [at 1]");
- return 0;
- }
- if (nospace) {
- LL1("pkinsert: cnt=" << j << " stop on nospace");
- return 0;
- }
+ } else {
+ set.push(i);
+ set.calc(par, i);
+ CHK(set.insrow(par, i) == 0);
+ set.unlock();
+ LL4("pkinsert key=" << i << " " << set.getrow(i));
+ batch++;
+ }
+ bool lastbatch = (batch != 0 && j + 1 == par.m_rows);
+ if (batch == par.m_batch || lastbatch) {
+ uint err = par.m_catcherr;
+ ExecType et = !randompct(par.m_abortpct) ? Commit : Rollback;
+ CHK(con.execute(et, err) == 0);
set.lock();
- set.notpending(lst, et);
+ set.post(par, !err ? et : Rollback);
set.unlock();
- lst.reset();
- CHK(con.startTransaction() == 0);
- }
- }
- if (lst.cnt() != 0) {
- bool deadlock = par.m_deadlock;
- bool nospace = true;
- ExecType et = randompct(par.m_abortpct) ? Rollback : Commit;
- CHK(con.execute(et, deadlock, nospace) == 0);
- con.closeTransaction();
- if (deadlock) {
- LL1("pkinsert: stop on deadlock [at 2]");
- return 0;
- }
- if (nospace) {
- LL1("pkinsert: end: stop on nospace");
- return 0;
+ if (err) {
+ LL1("pkinsert key=" << i << " stop on " << con.errname(err));
+ break;
+ }
+ batch = 0;
+ if (!lastbatch) {
+ con.closeTransaction();
+ CHK(con.startTransaction() == 0);
+ }
}
- set.lock();
- set.notpending(lst, et);
- set.unlock();
- return 0;
}
con.closeTransaction();
return 0;
@@ -3407,59 +3497,40 @@ pkupdate(Par par)
Set& set = par.set();
LL3("pkupdate " << tab.m_name);
CHK(con.startTransaction() == 0);
- Lst lst;
- bool deadlock = false;
- bool nospace = false;
- for (unsigned j = 0; j < par.m_rows; j++) {
- unsigned j2 = ! par.m_randomkey ? j : urandom(par.m_rows);
- unsigned i = thrrow(par, j2);
+ uint batch = 0;
+ for (uint j = 0; j < par.m_rows; j++) {
+ uint j2 = !par.m_randomkey ? j : urandom(par.m_rows);
+ uint i = thrrow(par, j2);
set.lock();
- if (! set.exist(i) || set.pending(i, Row::AnyOp)) {
- set.unlock();
- continue;
- }
- set.dbsave(i);
- set.calc(par, i);
- CHK(set.updrow(par, i) == 0);
- set.unlock();
- LL4("pkupdate " << i << ": " << *set.m_row[i]);
- lst.push(i);
- if (lst.cnt() == par.m_batch) {
- deadlock = par.m_deadlock;
- nospace = true;
- ExecType et = randompct(par.m_abortpct) ? Rollback : Commit;
- CHK(con.execute(et, deadlock, nospace) == 0);
- if (deadlock) {
- LL1("pkupdate: stop on deadlock [at 1]");
- break;
- }
- if (nospace) {
- LL1("pkupdate: cnt=" << j << " stop on nospace [at 1]");
- break;
- }
- con.closeTransaction();
- set.lock();
- set.notpending(lst, et);
- set.dbdiscard(lst);
+ if (!set.compat(par, i, Row::OpUpd)) {
+ LL3("pkupdate SKIP " << i << " " << set.getrow(i));
set.unlock();
- lst.reset();
- CHK(con.startTransaction() == 0);
- }
- }
- if (! deadlock && ! nospace && lst.cnt() != 0) {
- deadlock = par.m_deadlock;
- nospace = true;
- ExecType et = randompct(par.m_abortpct) ? Rollback : Commit;
- CHK(con.execute(et, deadlock, nospace) == 0);
- if (deadlock) {
- LL1("pkupdate: stop on deadlock [at 2]");
- } else if (nospace) {
- LL1("pkupdate: end: stop on nospace [at 2]");
} else {
+ set.push(i);
+ set.copyval(i, tab.m_pkmask);
+ set.calc(par, i, ~tab.m_pkmask);
+ CHK(set.updrow(par, i) == 0);
+ set.unlock();
+ LL4("pkupdate key=" << i << " " << set.getrow(i));
+ batch++;
+ }
+ bool lastbatch = (batch != 0 && j + 1 == par.m_rows);
+ if (batch == par.m_batch || lastbatch) {
+ uint err = par.m_catcherr;
+ ExecType et = !randompct(par.m_abortpct) ? Commit : Rollback;
+ CHK(con.execute(et, err) == 0);
set.lock();
- set.notpending(lst, et);
- set.dbdiscard(lst);
+ set.post(par, !err ? et : Rollback);
set.unlock();
+ if (err) {
+ LL1("pkupdate key=" << i << ": stop on " << con.errname(err));
+ break;
+ }
+ batch = 0;
+ if (!lastbatch) {
+ con.closeTransaction();
+ CHK(con.startTransaction() == 0);
+ }
}
}
con.closeTransaction();
@@ -3474,49 +3545,39 @@ pkdelete(Par par)
Set& set = par.set();
LL3("pkdelete " << tab.m_name);
CHK(con.startTransaction() == 0);
- Lst lst;
- bool deadlock = false;
- bool nospace = false;
- for (unsigned j = 0; j < par.m_rows; j++) {
- unsigned j2 = ! par.m_randomkey ? j : urandom(par.m_rows);
- unsigned i = thrrow(par, j2);
+ uint batch = 0;
+ for (uint j = 0; j < par.m_rows; j++) {
+ uint j2 = !par.m_randomkey ? j : urandom(par.m_rows);
+ uint i = thrrow(par, j2);
set.lock();
- if (! set.exist(i) || set.pending(i, Row::AnyOp)) {
+ if (!set.compat(par, i, Row::OpDel)) {
+ LL3("pkdelete SKIP " << i << " " << set.getrow(i));
set.unlock();
- continue;
- }
- CHK(set.delrow(par, i) == 0);
- set.unlock();
- LL4("pkdelete " << i << ": " << *set.m_row[i]);
- lst.push(i);
- if (lst.cnt() == par.m_batch) {
- deadlock = par.m_deadlock;
- nospace = true;
- ExecType et = randompct(par.m_abortpct) ? Rollback : Commit;
- CHK(con.execute(et, deadlock, nospace) == 0);
- if (deadlock) {
- LL1("pkdelete: stop on deadlock [at 1]");
- break;
- }
- con.closeTransaction();
- set.lock();
- set.notpending(lst, et);
- set.unlock();
- lst.reset();
- CHK(con.startTransaction() == 0);
- }
- }
- if (! deadlock && ! nospace && lst.cnt() != 0) {
- deadlock = par.m_deadlock;
- nospace = true;
- ExecType et = randompct(par.m_abortpct) ? Rollback : Commit;
- CHK(con.execute(et, deadlock, nospace) == 0);
- if (deadlock) {
- LL1("pkdelete: stop on deadlock [at 2]");
} else {
+ set.push(i);
+ set.copyval(i, tab.m_pkmask);
+ CHK(set.delrow(par, i) == 0);
+ set.unlock();
+ LL4("pkdelete key=" << i << " " << set.getrow(i));
+ batch++;
+ }
+ bool lastbatch = (batch != 0 && j + 1 == par.m_rows);
+ if (batch == par.m_batch || lastbatch) {
+ uint err = par.m_catcherr;
+ ExecType et = !randompct(par.m_abortpct) ? Commit : Rollback;
+ CHK(con.execute(et, err) == 0);
set.lock();
- set.notpending(lst, et);
+ set.post(par, !err ? et : Rollback);
set.unlock();
+ if (err) {
+ LL1("pkdelete key=" << i << " stop on " << con.errname(err));
+ break;
+ }
+ batch = 0;
+ if (!lastbatch) {
+ con.closeTransaction();
+ CHK(con.startTransaction() == 0);
+ }
}
}
con.closeTransaction();
@@ -3533,9 +3594,11 @@ pkread(Par par)
// expected
const Set& set1 = set;
Set set2(tab, set.m_rows);
- for (unsigned i = 0; i < set.m_rows; i++) {
+ for (uint i = 0; i < set.m_rows; i++) {
set.lock();
- if (! set.exist(i)) {
+ // TODO lock mode
+ if (!set.compat(par, i, Row::OpREAD)) {
+ LL3("pkread SKIP " << i << " " << set.getrow(i));
set.unlock();
continue;
}
@@ -3543,10 +3606,10 @@ pkread(Par par)
CHK(con.startTransaction() == 0);
CHK(set2.selrow(par, *set1.m_row[i]) == 0);
CHK(con.execute(Commit) == 0);
- unsigned i2 = (unsigned)-1;
+ uint i2 = (uint)-1;
CHK(set2.getkey(par, &i2) == 0 && i == i2);
CHK(set2.putval(i, false) == 0);
- LL4("row " << set2.count() << ": " << *set2.m_row[i]);
+ LL4("row " << set2.count() << " " << set2.getrow(i));
con.closeTransaction();
}
if (par.m_verify)
@@ -3555,7 +3618,7 @@ pkread(Par par)
}
static int
-pkreadfast(Par par, unsigned count)
+pkreadfast(Par par, uint count)
{
Con& con = par.con();
const Tab& tab = par.tab();
@@ -3563,9 +3626,9 @@ pkreadfast(Par par, unsigned count)
LL3("pkfast " << tab.m_name);
Row keyrow(tab);
// not batched on purpose
- for (unsigned j = 0; j < count; j++) {
- unsigned i = urandom(set.m_rows);
- assert(set.exist(i));
+ for (uint j = 0; j < count; j++) {
+ uint i = urandom(set.m_rows);
+ assert(set.compat(par, i, Row::OpREAD));
CHK(con.startTransaction() == 0);
// define key
keyrow.calc(par, i);
@@ -3585,53 +3648,46 @@ static int
hashindexupdate(Par par, const ITab& itab)
{
Con& con = par.con();
+ const Tab& tab = par.tab();
Set& set = par.set();
LL3("hashindexupdate " << itab.m_name);
CHK(con.startTransaction() == 0);
- Lst lst;
- bool deadlock = false;
- bool nospace = false;
- for (unsigned j = 0; j < par.m_rows; j++) {
- unsigned j2 = ! par.m_randomkey ? j : urandom(par.m_rows);
- unsigned i = thrrow(par, j2);
+ uint batch = 0;
+ for (uint j = 0; j < par.m_rows; j++) {
+ uint j2 = !par.m_randomkey ? j : urandom(par.m_rows);
+ uint i = thrrow(par, j2);
set.lock();
- if (! set.exist(i) || set.pending(i, Row::AnyOp)) {
+ if (!set.compat(par, i, Row::OpUpd)) {
+ LL3("hashindexupdate SKIP " << i << " " << set.getrow(i));
set.unlock();
- continue;
- }
- set.dbsave(i);
- // index key columns are not re-calculated
- set.calc(par, i, itab.m_colmask);
- CHK(set.updrow(par, itab, i) == 0);
- set.unlock();
- LL4("hashindexupdate " << i << ": " << *set.m_row[i]);
- lst.push(i);
- if (lst.cnt() == par.m_batch) {
- deadlock = par.m_deadlock;
- CHK(con.execute(Commit, deadlock, nospace) == 0);
- if (deadlock) {
- LL1("hashindexupdate: stop on deadlock [at 1]");
- break;
- }
- con.closeTransaction();
- set.lock();
- set.notpending(lst);
- set.dbdiscard(lst);
- set.unlock();
- lst.reset();
- CHK(con.startTransaction() == 0);
- }
- }
- if (! deadlock && lst.cnt() != 0) {
- deadlock = par.m_deadlock;
- CHK(con.execute(Commit, deadlock, nospace) == 0);
- if (deadlock) {
- LL1("hashindexupdate: stop on deadlock [at 2]");
} else {
+ // table pk and index key are not updated
+ set.push(i);
+ uint keymask = tab.m_pkmask | itab.m_keymask;
+ set.copyval(i, keymask);
+ set.calc(par, i, ~keymask);
+ CHK(set.updrow(par, itab, i) == 0);
+ set.unlock();
+ LL4("hashindexupdate " << i << " " << set.getrow(i));
+ batch++;
+ }
+ bool lastbatch = (batch != 0 && j + 1 == par.m_rows);
+ if (batch == par.m_batch || lastbatch) {
+ uint err = par.m_catcherr;
+ ExecType et = !randompct(par.m_abortpct) ? Commit : Rollback;
+ CHK(con.execute(et, err) == 0);
set.lock();
- set.notpending(lst);
- set.dbdiscard(lst);
+ set.post(par, !err ? et : Rollback);
set.unlock();
+ if (err) {
+ LL1("hashindexupdate " << i << " stop on " << con.errname(err));
+ break;
+ }
+ batch = 0;
+ if (!lastbatch) {
+ con.closeTransaction();
+ CHK(con.startTransaction() == 0);
+ }
}
}
con.closeTransaction();
@@ -3645,45 +3701,39 @@ hashindexdelete(Par par, const ITab& itab)
Set& set = par.set();
LL3("hashindexdelete " << itab.m_name);
CHK(con.startTransaction() == 0);
- Lst lst;
- bool deadlock = false;
- bool nospace = false;
- for (unsigned j = 0; j < par.m_rows; j++) {
- unsigned j2 = ! par.m_randomkey ? j : urandom(par.m_rows);
- unsigned i = thrrow(par, j2);
+ uint batch = 0;
+ for (uint j = 0; j < par.m_rows; j++) {
+ uint j2 = !par.m_randomkey ? j : urandom(par.m_rows);
+ uint i = thrrow(par, j2);
set.lock();
- if (! set.exist(i) || set.pending(i, Row::AnyOp)) {
- set.unlock();
- continue;
- }
- CHK(set.delrow(par, itab, i) == 0);
- set.unlock();
- LL4("hashindexdelete " << i << ": " << *set.m_row[i]);
- lst.push(i);
- if (lst.cnt() == par.m_batch) {
- deadlock = par.m_deadlock;
- CHK(con.execute(Commit, deadlock, nospace) == 0);
- if (deadlock) {
- LL1("hashindexdelete: stop on deadlock [at 1]");
- break;
- }
- con.closeTransaction();
- set.lock();
- set.notpending(lst);
+ if (!set.compat(par, i, Row::OpDel)) {
+ LL3("hashindexdelete SKIP " << i << " " << set.getrow(i));
set.unlock();
- lst.reset();
- CHK(con.startTransaction() == 0);
- }
- }
- if (! deadlock && lst.cnt() != 0) {
- deadlock = par.m_deadlock;
- CHK(con.execute(Commit, deadlock, nospace) == 0);
- if (deadlock) {
- LL1("hashindexdelete: stop on deadlock [at 2]");
} else {
+ set.push(i);
+ set.copyval(i, itab.m_keymask);
+ CHK(set.delrow(par, itab, i) == 0);
+ set.unlock();
+ LL4("hashindexdelete " << i << " " << set.getrow(i));
+ batch++;
+ }
+ bool lastbatch = (batch != 0 && j + 1 == par.m_rows);
+ if (batch == par.m_batch || lastbatch) {
+ uint err = par.m_catcherr;
+ ExecType et = !randompct(par.m_abortpct) ? Commit : Rollback;
+ CHK(con.execute(et, err) == 0);
set.lock();
- set.notpending(lst);
+ set.post(par, !err ? et : Rollback);
set.unlock();
+ if (err) {
+ LL1("hashindexdelete " << i << " stop on " << con.errname(err));
+ break;
+ }
+ batch = 0;
+ if (!lastbatch) {
+ con.closeTransaction();
+ CHK(con.startTransaction() == 0);
+ }
}
}
con.closeTransaction();
@@ -3700,9 +3750,11 @@ hashindexread(Par par, const ITab& itab)
// expected
const Set& set1 = set;
Set set2(tab, set.m_rows);
- for (unsigned i = 0; i < set.m_rows; i++) {
+ for (uint i = 0; i < set.m_rows; i++) {
set.lock();
- if (! set.exist(i)) {
+ // TODO lock mode
+ if (!set.compat(par, i, Row::OpREAD)) {
+ LL3("hashindexread SKIP " << i << " " << set.getrow(i));
set.unlock();
continue;
}
@@ -3710,10 +3762,10 @@ hashindexread(Par par, const ITab& itab)
CHK(con.startTransaction() == 0);
CHK(set2.selrow(par, itab, *set1.m_row[i]) == 0);
CHK(con.execute(Commit) == 0);
- unsigned i2 = (unsigned)-1;
+ uint i2 = (uint)-1;
CHK(set2.getkey(par, &i2) == 0 && i == i2);
CHK(set2.putval(i, false) == 0);
- LL4("row " << set2.count() << ": " << *set2.m_row[i]);
+ LL4("row " << set2.count() << " " << *set2.m_row[i]);
con.closeTransaction();
}
if (par.m_verify)
@@ -3731,40 +3783,39 @@ scanreadtable(Par par)
const Set& set = par.set();
// expected
const Set& set1 = set;
- LL3("scanread " << tab.m_name << " lockmode=" << par.m_lockmode << " tupscan=" << par.m_tupscan << " expect=" << set1.count() << " verify=" << par.m_verify);
+ LL3("scanreadtable " << tab.m_name << " lockmode=" << par.m_lockmode << " tupscan=" << par.m_tupscan << " expect=" << set1.count() << " verify=" << par.m_verify);
Set set2(tab, set.m_rows);
CHK(con.startTransaction() == 0);
CHK(con.getNdbScanOperation(tab) == 0);
CHK(con.readTuples(par) == 0);
set2.getval(par);
CHK(con.executeScan() == 0);
- unsigned n = 0;
- bool deadlock = false;
+ uint n = 0;
while (1) {
int ret;
- deadlock = par.m_deadlock;
- CHK((ret = con.nextScanResult(true, deadlock)) == 0 || ret == 1);
+ uint err = par.m_catcherr;
+ CHK((ret = con.nextScanResult(true, err)) == 0 || ret == 1);
if (ret == 1)
break;
- if (deadlock) {
- LL1("scanreadtable: stop on deadlock");
+ if (err) {
+ LL1("scanreadtable stop on " << con.errname(err));
break;
}
- unsigned i = (unsigned)-1;
+ uint i = (uint)-1;
CHK(set2.getkey(par, &i) == 0);
CHK(set2.putval(i, false, n) == 0);
- LL4("row " << n << ": " << *set2.m_row[i]);
+ LL4("row " << n << " " << *set2.m_row[i]);
n++;
}
con.closeTransaction();
if (par.m_verify)
CHK(set1.verify(par, set2, false) == 0);
- LL3("scanread " << tab.m_name << " done rows=" << n);
+ LL3("scanreadtable " << tab.m_name << " done rows=" << n);
return 0;
}
static int
-scanreadtablefast(Par par, unsigned countcheck)
+scanreadtablefast(Par par, uint countcheck)
{
Con& con = par.con();
const Tab& tab = par.tab();
@@ -3777,7 +3828,7 @@ scanreadtablefast(Par par, unsigned countcheck)
NdbRecAttr* rec;
CHK(con.getValue((Uint32)0, rec) == 0);
CHK(con.executeScan() == 0);
- unsigned count = 0;
+ uint count = 0;
while (1) {
int ret;
CHK((ret = con.nextScanResult(true)) == 0 || ret == 1);
@@ -3797,7 +3848,7 @@ calcscanbounds(Par par, const ITab& itab, BSet& bset, const Set& set, Set& set1)
while (true) {
bset.calc(par);
bset.filter(par, set, set1);
- unsigned n = set1.count();
+ uint n = set1.count();
// prefer proper subset
if (0 < n && n < set.m_rows)
break;
@@ -3819,7 +3870,7 @@ scanreadindex(Par par, const ITab& itab, BSet& bset, bool calc)
} else {
bset.filter(par, set, set1);
}
- LL3("scanread " << itab.m_name << " " << bset << " lockmode=" << par.m_lockmode << " expect=" << set1.count() << " ordered=" << par.m_ordered << " descending=" << par.m_descending << " verify=" << par.m_verify);
+ LL3("scanreadindex " << itab.m_name << " " << bset << " lockmode=" << par.m_lockmode << " expect=" << set1.count() << " ordered=" << par.m_ordered << " descending=" << par.m_descending << " verify=" << par.m_verify);
Set set2(tab, set.m_rows);
CHK(con.startTransaction() == 0);
CHK(con.getNdbIndexScanOperation(itab, tab) == 0);
@@ -3827,22 +3878,21 @@ scanreadindex(Par par, const ITab& itab, BSet& bset, bool calc)
CHK(bset.setbnd(par) == 0);
set2.getval(par);
CHK(con.executeScan() == 0);
- unsigned n = 0;
- bool deadlock = false;
+ uint n = 0;
while (1) {
int ret;
- deadlock = par.m_deadlock;
- CHK((ret = con.nextScanResult(true, deadlock)) == 0 || ret == 1);
+ uint err = par.m_catcherr;
+ CHK((ret = con.nextScanResult(true, err)) == 0 || ret == 1);
if (ret == 1)
break;
- if (deadlock) {
- LL1("scanreadindex: stop on deadlock");
+ if (err) {
+ LL1("scanreadindex stop on " << con.errname(err));
break;
}
- unsigned i = (unsigned)-1;
+ uint i = (uint)-1;
CHK(set2.getkey(par, &i) == 0);
CHK(set2.putval(i, par.m_dups, n) == 0);
- LL4("key " << i << " row " << n << ": " << *set2.m_row[i]);
+ LL4("key " << i << " row " << n << " " << *set2.m_row[i]);
n++;
}
con.closeTransaction();
@@ -3851,12 +3901,12 @@ scanreadindex(Par par, const ITab& itab, BSet& bset, bool calc)
if (par.m_ordered)
CHK(set2.verifyorder(par, itab, par.m_descending) == 0);
}
- LL3("scanread " << itab.m_name << " done rows=" << n);
+ LL3("scanreadindex " << itab.m_name << " done rows=" << n);
return 0;
}
static int
-scanreadindexfast(Par par, const ITab& itab, const BSet& bset, unsigned countcheck)
+scanreadindexfast(Par par, const ITab& itab, const BSet& bset, uint countcheck)
{
Con& con = par.con();
const Tab& tab = par.tab();
@@ -3871,7 +3921,7 @@ scanreadindexfast(Par par, const ITab& itab, const BSet& bset, unsigned countche
NdbRecAttr* rec;
CHK(con.getValue((Uint32)0, rec) == 0);
CHK(con.executeScan() == 0);
- unsigned count = 0;
+ uint count = 0;
while (1) {
int ret;
CHK((ret = con.nextScanResult(true)) == 0 || ret == 1);
@@ -3904,22 +3954,21 @@ scanreadfilter(Par par, const ITab& itab, BSet& bset, bool calc)
CHK(bset.setflt(par) == 0);
set2.getval(par);
CHK(con.executeScan() == 0);
- unsigned n = 0;
- bool deadlock = false;
+ uint n = 0;
while (1) {
int ret;
- deadlock = par.m_deadlock;
- CHK((ret = con.nextScanResult(true, deadlock)) == 0 || ret == 1);
+ uint err = par.m_catcherr;
+ CHK((ret = con.nextScanResult(true, err)) == 0 || ret == 1);
if (ret == 1)
break;
- if (deadlock) {
- LL1("scanfilter: stop on deadlock");
+ if (err) {
+ LL1("scanfilter stop on " << con.errname(err));
break;
}
- unsigned i = (unsigned)-1;
+ uint i = (uint)-1;
CHK(set2.getkey(par, &i) == 0);
CHK(set2.putval(i, par.m_dups, n) == 0);
- LL4("key " << i << " row " << n << ": " << *set2.m_row[i]);
+ LL4("key " << i << " row " << n << " " << *set2.m_row[i]);
n++;
}
con.closeTransaction();
@@ -3934,9 +3983,9 @@ static int
scanreadindex(Par par, const ITab& itab)
{
const Tab& tab = par.tab();
- for (unsigned i = 0; i < par.m_subloop; i++) {
+ for (uint i = 0; i < par.m_ssloop; i++) {
if (itab.m_type == ITab::OrderedIndex) {
- BSet bset(tab, itab, par.m_rows);
+ BSet bset(tab, itab);
CHK(scanreadfilter(par, itab, bset, true) == 0);
CHK(scanreadindex(par, itab, bset, true) == 0);
}
@@ -3948,7 +3997,7 @@ static int
scanreadindex(Par par)
{
const Tab& tab = par.tab();
- for (unsigned i = 0; i < tab.m_itabs; i++) {
+ for (uint i = 0; i < tab.m_itabs; i++) {
if (tab.m_itab[i] == 0)
continue;
const ITab& itab = *tab.m_itab[i];
@@ -3985,7 +4034,7 @@ timescanpkindex(Par par)
{
const Tab& tab = par.tab();
const ITab& itab = *tab.m_itab[0]; // 1st index is on PK
- BSet bset(tab, itab, par.m_rows);
+ BSet bset(tab, itab);
par.tmr().on();
CHK(scanreadindexfast(par, itab, bset, par.m_totrows) == 0);
par.tmr().off(par.set().m_rows);
@@ -3996,7 +4045,7 @@ static int
timepkreadtable(Par par)
{
par.tmr().on();
- unsigned count = par.m_samples;
+ uint count = par.m_samples;
if (count == 0)
count = par.m_totrows;
CHK(pkreadfast(par, count) == 0);
@@ -4009,13 +4058,13 @@ timepkreadindex(Par par)
{
const Tab& tab = par.tab();
const ITab& itab = *tab.m_itab[0]; // 1st index is on PK
- BSet bset(tab, itab, par.m_rows);
- unsigned count = par.m_samples;
+ BSet bset(tab, itab);
+ uint count = par.m_samples;
if (count == 0)
count = par.m_totrows;
par.tmr().on();
- for (unsigned j = 0; j < count; j++) {
- unsigned i = urandom(par.m_totrows);
+ for (uint j = 0; j < count; j++) {
+ uint i = urandom(par.m_totrows);
bset.calcpk(par, i);
CHK(scanreadindexfast(par, itab, bset, 1) == 0);
}
@@ -4031,7 +4080,7 @@ scanupdatetable(Par par)
Con& con = par.con();
const Tab& tab = par.tab();
Set& set = par.set();
- LL3("scan update " << tab.m_name);
+ LL3("scanupdatetable " << tab.m_name);
Set set2(tab, set.m_rows);
par.m_lockmode = NdbOperation::LM_Exclusive;
CHK(con.startTransaction() == 0);
@@ -4039,87 +4088,70 @@ scanupdatetable(Par par)
CHK(con.readTuples(par) == 0);
set2.getval(par);
CHK(con.executeScan() == 0);
- unsigned count = 0;
+ uint count = 0;
// updating trans
Con con2;
con2.connect(con);
CHK(con2.startTransaction() == 0);
- Lst lst;
- bool deadlock = false;
- bool nospace = false;
+ uint batch = 0;
while (1) {
int ret;
- deadlock = par.m_deadlock;
- CHK((ret = con.nextScanResult(true, deadlock)) == 0 || ret == 1);
- if (ret == 1)
+ uint32 err = par.m_catcherr;
+ CHK((ret = con.nextScanResult(true, err)) != -1);
+ if (ret != 0)
break;
- if (deadlock) {
- LL1("scanupdatetable: stop on deadlock [at 1]");
+ if (err) {
+ LL1("scanupdatetable [scan] stop on " << con.errname(err));
break;
}
if (par.m_scanstop != 0 && urandom(par.m_scanstop) == 0) {
con.closeScan();
break;
}
- do {
- unsigned i = (unsigned)-1;
+ while (1) {
+ uint i = (uint)-1;
CHK(set2.getkey(par, &i) == 0);
- const Row& row = *set.m_row[i];
set.lock();
- if (! set.exist(i) || set.pending(i, Row::AnyOp)) {
- LL4("scan update " << tab.m_name << ": skip: " << row);
+ if (!set.compat(par, i, Row::OpUpd)) {
+ LL3("scanupdatetable SKIP " << i << " " << set.getrow(i));
} else {
CHKTRY(set2.putval(i, false) == 0, set.unlock());
CHKTRY(con.updateScanTuple(con2) == 0, set.unlock());
Par par2 = par;
par2.m_con = &con2;
- set.dbsave(i);
- set.calc(par, i);
+ set.push(i);
+ set.calc(par, i, ~tab.m_pkmask);
CHKTRY(set.setrow(par2, i) == 0, set.unlock());
- LL4("scan update " << tab.m_name << ": " << row);
- lst.push(i);
+ LL4("scanupdatetable " << i << " " << set.getrow(i));
+ batch++;
}
set.unlock();
- if (lst.cnt() == par.m_batch) {
- deadlock = par.m_deadlock;
- CHK(con2.execute(Commit, deadlock, nospace) == 0);
- if (deadlock) {
- LL1("scanupdatetable: stop on deadlock [at 2]");
- goto out;
- }
- con2.closeTransaction();
+ CHK((ret = con.nextScanResult(false)) != -1);
+ bool lastbatch = (batch != 0 && ret != 0);
+ if (batch == par.m_batch || lastbatch) {
+ uint err = par.m_catcherr;
+ ExecType et = Commit;
+ CHK(con2.execute(et, err) == 0);
set.lock();
- set.notpending(lst);
- set.dbdiscard(lst);
+ set.post(par, !err ? et : Rollback);
set.unlock();
- count += lst.cnt();
- lst.reset();
- CHK(con2.startTransaction() == 0);
- }
- CHK((ret = con.nextScanResult(false)) == 0 || ret == 1 || ret == 2);
- if (ret == 2 && lst.cnt() != 0) {
- deadlock = par.m_deadlock;
- CHK(con2.execute(Commit, deadlock, nospace) == 0);
- if (deadlock) {
- LL1("scanupdatetable: stop on deadlock [at 3]");
+ if (err) {
+ LL1("scanupdatetable [update] stop on " << con2.errname(err));
goto out;
}
+ LL4("scanupdatetable committed batch");
+ count += batch;
+ batch = 0;
con2.closeTransaction();
- set.lock();
- set.notpending(lst);
- set.dbdiscard(lst);
- set.unlock();
- count += lst.cnt();
- lst.reset();
CHK(con2.startTransaction() == 0);
}
- } while (ret == 0);
- if (ret == 1)
- break;
+ if (ret != 0)
+ break;
+ }
}
out:
con2.closeTransaction();
- LL3("scan update " << tab.m_name << " rows updated=" << count);
+ LL3("scanupdatetable " << tab.m_name << " rows updated=" << count);
con.closeTransaction();
return 0;
}
@@ -4137,7 +4169,7 @@ scanupdateindex(Par par, const ITab& itab, BSet& bset, bool calc)
} else {
bset.filter(par, set, set1);
}
- LL3("scan update " << itab.m_name << " " << bset << " expect=" << set1.count() << " ordered=" << par.m_ordered << " descending=" << par.m_descending << " verify=" << par.m_verify);
+ LL3("scanupdateindex " << itab.m_name << " " << bset << " expect=" << set1.count() << " ordered=" << par.m_ordered << " descending=" << par.m_descending << " verify=" << par.m_verify);
Set set2(tab, set.m_rows);
par.m_lockmode = NdbOperation::LM_Exclusive;
CHK(con.startTransaction() == 0);
@@ -4146,83 +4178,67 @@ scanupdateindex(Par par, const ITab& itab, BSet& bset, bool calc)
CHK(bset.setbnd(par) == 0);
set2.getval(par);
CHK(con.executeScan() == 0);
- unsigned count = 0;
+ uint count = 0;
// updating trans
Con con2;
con2.connect(con);
CHK(con2.startTransaction() == 0);
- Lst lst;
- bool deadlock = false;
- bool nospace = false;
+ uint batch = 0;
while (1) {
int ret;
- deadlock = par.m_deadlock;
- CHK((ret = con.nextScanResult(true, deadlock)) == 0 || ret == 1);
- if (ret == 1)
+ uint err = par.m_catcherr;
+ CHK((ret = con.nextScanResult(true, err)) != -1);
+ if (ret != 0)
break;
- if (deadlock) {
- LL1("scanupdateindex: stop on deadlock [at 1]");
+ if (err) {
+ LL1("scanupdateindex [scan] stop on " << con.errname(err));
break;
}
if (par.m_scanstop != 0 && urandom(par.m_scanstop) == 0) {
con.closeScan();
break;
}
- do {
- unsigned i = (unsigned)-1;
+ while (1) {
+ uint i = (uint)-1;
CHK(set2.getkey(par, &i) == 0);
- const Row& row = *set.m_row[i];
set.lock();
- if (! set.exist(i) || set.pending(i, Row::AnyOp)) {
- LL4("scan update " << itab.m_name << ": skip: " << row);
+ if (!set.compat(par, i, Row::OpUpd)) {
+ LL4("scanupdateindex SKIP " << set.getrow(i));
} else {
CHKTRY(set2.putval(i, par.m_dups) == 0, set.unlock());
CHKTRY(con.updateScanTuple(con2) == 0, set.unlock());
Par par2 = par;
par2.m_con = &con2;
- set.dbsave(i);
- set.calc(par, i, ! par.m_noindexkeyupdate ? 0 : itab.m_colmask);
+ set.push(i);
+ uint colmask = !par.m_noindexkeyupdate ? ~0 : ~itab.m_keymask;
+ set.calc(par, i, colmask);
CHKTRY(set.setrow(par2, i) == 0, set.unlock());
- LL4("scan update " << itab.m_name << ": " << row);
- lst.push(i);
+ LL4("scanupdateindex " << i << " " << set.getrow(i));
+ batch++;
}
set.unlock();
- if (lst.cnt() == par.m_batch) {
- deadlock = par.m_deadlock;
- CHK(con2.execute(Commit, deadlock, nospace) == 0);
- if (deadlock) {
- LL1("scanupdateindex: stop on deadlock [at 2]");
- goto out;
- }
- con2.closeTransaction();
- LL4("scanupdateindex: committed batch [at 1]");
+ CHK((ret = con.nextScanResult(false)) != -1);
+ bool lastbatch = (batch != 0 && ret != 0);
+ if (batch == par.m_batch || lastbatch) {
+ uint err = par.m_catcherr;
+ ExecType et = Commit;
+ CHK(con2.execute(et, err) == 0);
set.lock();
- set.notpending(lst);
- set.dbdiscard(lst);
+ set.post(par, !err ? et : Rollback);
set.unlock();
- count += lst.cnt();
- lst.reset();
- CHK(con2.startTransaction() == 0);
- }
- CHK((ret = con.nextScanResult(false)) == 0 || ret == 1 || ret == 2);
- if (ret == 2 && lst.cnt() != 0) {
- deadlock = par.m_deadlock;
- CHK(con2.execute(Commit, deadlock, nospace) == 0);
- if (deadlock) {
- LL1("scanupdateindex: stop on deadlock [at 3]");
+ if (err) {
+ LL1("scanupdateindex [update] stop on " << con2.errname(err));
goto out;
}
+ LL4("scanupdateindex committed batch");
+ count += batch;
+ batch = 0;
con2.closeTransaction();
- LL4("scanupdateindex: committed batch [at 2]");
- set.lock();
- set.notpending(lst);
- set.dbdiscard(lst);
- set.unlock();
- count += lst.cnt();
- lst.reset();
CHK(con2.startTransaction() == 0);
}
- } while (ret == 0);
+ if (ret != 0)
+ break;
+ }
}
out:
con2.closeTransaction();
@@ -4231,7 +4247,7 @@ out:
if (par.m_ordered)
CHK(set2.verifyorder(par, itab, par.m_descending) == 0);
}
- LL3("scan update " << itab.m_name << " rows updated=" << count);
+ LL3("scanupdateindex " << itab.m_name << " rows updated=" << count);
con.closeTransaction();
return 0;
}
@@ -4240,9 +4256,9 @@ static int
scanupdateindex(Par par, const ITab& itab)
{
const Tab& tab = par.tab();
- for (unsigned i = 0; i < par.m_subloop; i++) {
+ for (uint i = 0; i < par.m_ssloop; i++) {
if (itab.m_type == ITab::OrderedIndex) {
- BSet bset(tab, itab, par.m_rows);
+ BSet bset(tab, itab);
CHK(scanupdateindex(par, itab, bset, true) == 0);
} else {
CHK(hashindexupdate(par, itab) == 0);
@@ -4255,7 +4271,7 @@ static int
scanupdateindex(Par par)
{
const Tab& tab = par.tab();
- for (unsigned i = 0; i < tab.m_itabs; i++) {
+ for (uint i = 0; i < tab.m_itabs; i++) {
if (tab.m_itab[i] == 0)
continue;
const ITab& itab = *tab.m_itab[i];
@@ -4294,14 +4310,14 @@ readverifyfull(Par par)
CHK(scanreadtable(par) == 0);
}
// each thread scans different indexes
- for (unsigned i = 0; i < tab.m_itabs; i++) {
- if (i % par.m_threads != par.m_no)
+ for (uint i = 0; i < tab.m_itabs; i++) {
+ if (i % par.m_usedthreads != par.m_no)
continue;
if (tab.m_itab[i] == 0)
continue;
const ITab& itab = *tab.m_itab[i];
if (itab.m_type == ITab::OrderedIndex) {
- BSet bset(tab, itab, par.m_rows);
+ BSet bset(tab, itab);
CHK(scanreadindex(par, itab, bset, false) == 0);
} else {
CHK(hashindexread(par, itab) == 0);
@@ -4317,7 +4333,7 @@ readverifyindex(Par par)
return 0;
par.m_verify = true;
par.m_lockmode = NdbOperation::LM_CommittedRead;
- unsigned sel = urandom(10);
+ uint sel = urandom(10);
if (sel < 9) {
par.m_ordered = true;
par.m_descending = (sel < 5);
@@ -4331,8 +4347,8 @@ pkops(Par par)
{
const Tab& tab = par.tab();
par.m_randomkey = true;
- for (unsigned i = 0; i < par.m_subloop; i++) {
- unsigned j = 0;
+ for (uint i = 0; i < par.m_ssloop; i++) {
+ uint j = 0;
while (j < tab.m_itabs) {
if (tab.m_itab[j] != 0) {
const ITab& itab = *tab.m_itab[j];
@@ -4341,7 +4357,7 @@ pkops(Par par)
}
j++;
}
- unsigned sel = urandom(10);
+ uint sel = urandom(10);
if (par.m_slno % 2 == 0) {
// favor insert
if (sel < 8) {
@@ -4389,8 +4405,8 @@ static int
pkupdatescanread(Par par)
{
par.m_dups = true;
- par.m_deadlock = true;
- unsigned sel = urandom(10);
+ par.m_catcherr |= Con::ErrDeadlock;
+ uint sel = urandom(10);
if (sel < 5) {
CHK(pkupdate(par) == 0);
} else if (sel < 6) {
@@ -4411,9 +4427,9 @@ static int
mixedoperations(Par par)
{
par.m_dups = true;
- par.m_deadlock = true;
+ par.m_catcherr |= Con::ErrDeadlock;
par.m_scanstop = par.m_totrows; // randomly close scans
- unsigned sel = urandom(10);
+ uint sel = urandom(10);
if (sel < 2) {
CHK(pkdelete(par) == 0);
} else if (sel < 4) {
@@ -4434,8 +4450,8 @@ static int
parallelorderedupdate(Par par)
{
const Tab& tab = par.tab();
- unsigned k = 0;
- for (unsigned i = 0; i < tab.m_itabs; i++) {
+ uint k = 0;
+ for (uint i = 0; i < tab.m_itabs; i++) {
if (tab.m_itab[i] == 0)
continue;
const ITab& itab = *tab.m_itab[i];
@@ -4447,10 +4463,11 @@ parallelorderedupdate(Par par)
par.m_noindexkeyupdate = true;
par.m_ordered = true;
par.m_descending = (par.m_slno != 0);
+ par.m_dups = false;
par.m_verify = true;
- BSet bset(tab, itab, par.m_rows); // empty bounds
+ BSet bset(tab, itab); // empty bounds
// prefer empty bounds
- unsigned sel = urandom(10);
+ uint sel = urandom(10);
CHK(scanupdateindex(par, itab, bset, sel < 2) == 0);
}
}
@@ -4469,6 +4486,418 @@ pkupdateindexbuild(Par par)
return 0;
}
+// savepoint tests (single thread for now)
+
+struct Spt {
+ enum Res { Committed, Latest, Deadlock };
+ bool m_same; // same transaction
+ NdbOperation::LockMode m_lm;
+ Res m_res;
+};
+
+static Spt sptlist[] = {
+ { 1, NdbOperation::LM_Read, Spt::Latest },
+ { 1, NdbOperation::LM_Exclusive, Spt::Latest },
+ { 1, NdbOperation::LM_CommittedRead, Spt::Latest },
+ { 0, NdbOperation::LM_Read, Spt::Deadlock },
+ { 0, NdbOperation::LM_Exclusive, Spt::Deadlock },
+ { 0, NdbOperation::LM_CommittedRead, Spt::Committed }
+};
+static uint sptcount = sizeof(sptlist)/sizeof(sptlist[0]);
+
+static int
+savepointreadpk(Par par, Spt spt)
+{
+ LL3("savepointreadpk");
+ Con& con = par.con();
+ const Tab& tab = par.tab();
+ Set& set = par.set();
+ const Set& set1 = set;
+ Set set2(tab, set.m_rows);
+ uint n = 0;
+ for (uint i = 0; i < set.m_rows; i++) {
+ set.lock();
+ if (!set.compat(par, i, Row::OpREAD)) {
+ LL4("savepointreadpk SKIP " << i << " " << set.getrow(i));
+ set.unlock();
+ continue;
+ }
+ set.unlock();
+ CHK(set2.selrow(par, *set1.m_row[i]) == 0);
+ uint err = par.m_catcherr | Con::ErrDeadlock;
+ ExecType et = NoCommit;
+ CHK(con.execute(et, err) == 0);
+ if (err) {
+ if (err & Con::ErrDeadlock) {
+ CHK(spt.m_res == Spt::Deadlock);
+ // all rows have same behaviour
+ CHK(n == 0);
+ }
+ LL1("savepointreadpk stop on " << con.errname(err));
+ break;
+ }
+ uint i2 = (uint)-1;
+ CHK(set2.getkey(par, &i2) == 0 && i == i2);
+ CHK(set2.putval(i, false) == 0);
+ LL4("row " << set2.count() << " " << set2.getrow(i));
+ n++;
+ }
+ bool dirty = (!spt.m_same && spt.m_lm == NdbOperation::LM_CommittedRead);
+ if (spt.m_res != Spt::Deadlock)
+ CHK(set1.verify(par, set2, false, dirty) == 0);
+ return 0;
+}
+
+static int
+savepointreadhashindex(Par par, Spt spt)
+{
+ if (spt.m_lm == NdbOperation::LM_CommittedRead && !spt.m_same) {
+ LL1("skip hash index dirty read");
+ return 0;
+ }
+ LL3("savepointreadhashindex");
+ Con& con = par.con();
+ const Tab& tab = par.tab();
+ const ITab& itab = par.itab();
+ Set& set = par.set();
+ const Set& set1 = set;
+ Set set2(tab, set.m_rows);
+ uint n = 0;
+ for (uint i = 0; i < set.m_rows; i++) {
+ set.lock();
+ if (!set.compat(par, i, Row::OpREAD)) {
+ LL3("savepointreadhashindex SKIP " << i << " " << set.getrow(i));
+ set.unlock();
+ continue;
+ }
+ set.unlock();
+ CHK(set2.selrow(par, itab, *set1.m_row[i]) == 0);
+ uint err = par.m_catcherr | Con::ErrDeadlock;
+ ExecType et = NoCommit;
+ CHK(con.execute(et, err) == 0);
+ if (err) {
+ if (err & Con::ErrDeadlock) {
+ CHK(spt.m_res == Spt::Deadlock);
+ // all rows have same behaviour
+ CHK(n == 0);
+ }
+ LL1("savepointreadhashindex stop on " << con.errname(err));
+ break;
+ }
+ uint i2 = (uint)-1;
+ CHK(set2.getkey(par, &i2) == 0 && i == i2);
+ CHK(set2.putval(i, false) == 0);
+ LL4("row " << set2.count() << " " << *set2.m_row[i]);
+ n++;
+ }
+ bool dirty = (!spt.m_same && spt.m_lm == NdbOperation::LM_CommittedRead);
+ if (spt.m_res != Spt::Deadlock)
+ CHK(set1.verify(par, set2, false, dirty) == 0);
+ return 0;
+}
+
+static int
+savepointscantable(Par par, Spt spt)
+{
+ LL3("savepointscantable");
+ Con& con = par.con();
+ const Tab& tab = par.tab();
+ const Set& set = par.set();
+ const Set& set1 = set; // not modifying current set
+ Set set2(tab, set.m_rows); // scan result
+ CHK(con.getNdbScanOperation(tab) == 0);
+ CHK(con.readTuples(par) == 0);
+ set2.getval(par); // getValue all columns
+ CHK(con.executeScan() == 0);
+ bool deadlock = false;
+ uint n = 0;
+ while (1) {
+ int ret;
+ uint err = par.m_catcherr | Con::ErrDeadlock;
+ CHK((ret = con.nextScanResult(true, err)) == 0 || ret == 1);
+ if (ret == 1)
+ break;
+ if (err) {
+ if (err & Con::ErrDeadlock) {
+ CHK(spt.m_res == Spt::Deadlock);
+ // all rows have same behaviour
+ CHK(n == 0);
+ deadlock = true;
+ }
+ LL1("savepointscantable stop on " << con.errname(err));
+ break;
+ }
+ CHK(spt.m_res != Spt::Deadlock);
+ uint i = (uint)-1;
+ CHK(set2.getkey(par, &i) == 0);
+ CHK(set2.putval(i, false, n) == 0);
+ LL4("row " << n << " key " << i << " " << set2.getrow(i));
+ n++;
+ }
+ if (set1.m_rows > 0) {
+ if (!deadlock)
+ CHK(spt.m_res != Spt::Deadlock);
+ else
+ CHK(spt.m_res == Spt::Deadlock);
+ }
+ LL2("savepointscantable " << n << " rows");
+ bool dirty = (!spt.m_same && spt.m_lm == NdbOperation::LM_CommittedRead);
+ if (spt.m_res != Spt::Deadlock)
+ CHK(set1.verify(par, set2, false, dirty) == 0);
+ return 0;
+}
+
+static int
+savepointscanindex(Par par, Spt spt)
+{
+ LL3("savepointscanindex");
+ Con& con = par.con();
+ const Tab& tab = par.tab();
+ const ITab& itab = par.itab();
+ const Set& set = par.set();
+ const Set& set1 = set;
+ Set set2(tab, set.m_rows);
+ CHK(con.getNdbIndexScanOperation(itab, tab) == 0);
+ CHK(con.readIndexTuples(par) == 0);
+ set2.getval(par);
+ CHK(con.executeScan() == 0);
+ bool deadlock = false;
+ uint n = 0;
+ while (1) {
+ int ret;
+ uint err = par.m_catcherr | Con::ErrDeadlock;
+ CHK((ret = con.nextScanResult(true, err)) == 0 || ret == 1);
+ if (ret == 1)
+ break;
+ if (err) {
+ if (err & Con::ErrDeadlock) {
+ CHK(spt.m_res == Spt::Deadlock);
+ // all rows have same behaviour
+ CHK(n == 0);
+ deadlock = true;
+ }
+ LL1("savepointscanindex stop on " << con.errname(err));
+ break;
+ }
+ CHK(spt.m_res != Spt::Deadlock);
+ uint i = (uint)-1;
+ CHK(set2.getkey(par, &i) == 0);
+ CHK(set2.putval(i, par.m_dups, n) == 0);
+ LL4("row " << n << " key " << i << " " << set2.getrow(i));
+ n++;
+ }
+ if (set1.m_rows > 0) {
+ if (!deadlock)
+ CHK(spt.m_res != Spt::Deadlock);
+ else
+ CHK(spt.m_res == Spt::Deadlock);
+ }
+ LL2("savepointscanindex " << n << " rows");
+ bool dirty = (!spt.m_same && spt.m_lm == NdbOperation::LM_CommittedRead);
+ if (spt.m_res != Spt::Deadlock)
+ CHK(set1.verify(par, set2, false, dirty) == 0);
+ return 0;
+}
+
+typedef int (*SptFun)(Par, Spt);
+
+static int
+savepointtest(Par par, Spt spt, SptFun fun)
+{
+ Con& con = par.con();
+ Par par2 = par;
+ Con con2;
+ if (!spt.m_same) {
+ con2.connect(con); // copy ndb reference
+ par2.m_con = &con2;
+ CHK(con2.startTransaction() == 0);
+ }
+ par2.m_lockmode = spt.m_lm;
+ CHK((*fun)(par2, spt) == 0);
+ if (!spt.m_same) {
+ con2.closeTransaction();
+ }
+ return 0;
+}
+
+static int
+savepointtest(Par par, const char* op)
+{
+ Con& con = par.con();
+ const Tab& tab = par.tab();
+ Set& set = par.set();
+ LL2("savepointtest op=\"" << op << "\"");
+ CHK(con.startTransaction() == 0);
+ const char* p = op;
+ char c;
+ while ((c = *p++) != 0) {
+ uint j;
+ for (j = 0; j < par.m_rows; j++) {
+ uint i = thrrow(par, j);
+ if (c == 'c') {
+ ExecType et = Commit;
+ CHK(con.execute(et) == 0);
+ set.lock();
+ set.post(par, et);
+ set.unlock();
+ CHK(con.startTransaction() == 0);
+ } else {
+ set.lock();
+ set.push(i);
+ if (c == 'i') {
+ set.calc(par, i);
+ CHK(set.insrow(par, i) == 0);
+ } else if (c == 'u') {
+ set.copyval(i, tab.m_pkmask);
+ set.calc(par, i, ~tab.m_pkmask);
+ CHK(set.updrow(par, i) == 0);
+ } else if (c == 'd') {
+ set.copyval(i, tab.m_pkmask);
+ CHK(set.delrow(par, i) == 0);
+ } else {
+ assert(false);
+ }
+ set.unlock();
+ }
+ }
+ }
+ {
+ ExecType et = NoCommit;
+ CHK(con.execute(et) == 0);
+ set.lock();
+ set.post(par, et);
+ set.unlock();
+ }
+ for (uint k = 0; k < sptcount; k++) {
+ Spt spt = sptlist[k];
+ LL2("spt lm=" << spt.m_lm << " same=" << spt.m_same);
+ CHK(savepointtest(par, spt, &savepointreadpk) == 0);
+ CHK(savepointtest(par, spt, &savepointscantable) == 0);
+ for (uint i = 0; i < tab.m_itabs; i++) {
+ if (tab.m_itab[i] == 0)
+ continue;
+ const ITab& itab = *tab.m_itab[i];
+ par.m_itab = &itab;
+ if (itab.m_type == ITab::OrderedIndex)
+ CHK(savepointtest(par, spt, &savepointscanindex) == 0);
+ else
+ CHK(savepointtest(par, spt, &savepointreadhashindex) == 0);
+ par.m_itab = 0;
+ }
+ }
+ {
+ ExecType et = Rollback;
+ CHK(con.execute(et) == 0);
+ set.lock();
+ set.post(par, et);
+ set.unlock();
+ }
+ con.closeTransaction();
+ return 0;
+}
+
+static int
+savepointtest(Par par)
+{
+ assert(par.m_usedthreads == 1);
+ const char* oplist[] = {
+ // each based on previous and "c" not last
+ "i",
+ "icu",
+ "uuuuu",
+ "d",
+ "dciuuuuud",
+ 0
+ };
+ int i;
+ for (i = 0; oplist[i] != 0; i++) {
+ CHK(savepointtest(par, oplist[i]) == 0);
+ }
+ return 0;
+}
+
+static int
+halloweentest(Par par, const ITab& itab)
+{
+ LL2("halloweentest " << itab.m_name);
+ Con& con = par.con();
+ const Tab& tab = par.tab();
+ Set& set = par.set();
+ CHK(con.startTransaction() == 0);
+ // insert 1 row
+ uint i = 0;
+ set.push(i);
+ set.calc(par, i);
+ CHK(set.insrow(par, i) == 0);
+ CHK(con.execute(NoCommit) == 0);
+ // scan via index until Set m_rows reached
+ uint scancount = 0;
+ bool stop = false;
+ while (!stop) {
+ par.m_lockmode = // makes no difference
+ scancount % 2 == 0 ? NdbOperation::LM_CommittedRead :
+ NdbOperation::LM_Read;
+ Set set1(tab, set.m_rows); // expected scan result
+ Set set2(tab, set.m_rows); // actual scan result
+ BSet bset(tab, itab);
+ calcscanbounds(par, itab, bset, set, set1);
+ CHK(con.getNdbIndexScanOperation(itab, tab) == 0);
+ CHK(con.readIndexTuples(par) == 0);
+ CHK(bset.setbnd(par) == 0);
+ set2.getval(par);
+ CHK(con.executeScan() == 0);
+ const uint savepoint = i;
+ LL3("scancount=" << scancount << " savepoint=" << savepoint);
+ uint n = 0;
+ while (1) {
+ int ret;
+ CHK((ret = con.nextScanResult(true)) == 0 || ret == 1);
+ if (ret == 1)
+ break;
+ uint k = (uint)-1;
+ CHK(set2.getkey(par, &k) == 0);
+ CHK(set2.putval(k, false, n) == 0);
+ LL3("row=" << n << " key=" << k);
+ CHK(k <= savepoint);
+ if (++i == set.m_rows) {
+ stop = true;
+ break;
+ }
+ set.push(i);
+ set.calc(par, i);
+ CHK(set.insrow(par, i) == 0);
+ CHK(con.execute(NoCommit) == 0);
+ n++;
+ }
+ con.closeScan();
+ LL3("scanrows=" << n);
+ if (!stop) {
+ CHK(set1.verify(par, set2, false) == 0);
+ }
+ scancount++;
+ }
+ CHK(con.execute(Commit) == 0);
+ set.post(par, Commit);
+ assert(set.count() == set.m_rows);
+ CHK(pkdelete(par) == 0);
+ return 0;
+}
+
+static int
+halloweentest(Par par)
+{
+ assert(par.m_usedthreads == 1);
+ const Tab& tab = par.tab();
+ for (uint i = 0; i < tab.m_itabs; i++) {
+ if (tab.m_itab[i] == 0)
+ continue;
+ const ITab& itab = *tab.m_itab[i];
+ if (itab.m_type == ITab::OrderedIndex)
+ CHK(halloweentest(par, itab) == 0);
+ }
+ return 0;
+}
+
// threads
typedef int (*TFunc)(Par par);
@@ -4477,22 +4906,22 @@ enum TMode { ST = 1, MT = 2 };
extern "C" { static void* runthread(void* arg); }
struct Thr {
- enum State { Wait, Start, Stop, Stopped, Exit };
+ enum State { Wait, Start, Stop, Exit };
State m_state;
Par m_par;
- Uint64 m_id;
+ pthread_t m_id;
NdbThread* m_thread;
NdbMutex* m_mutex;
NdbCondition* m_cond;
TFunc m_func;
int m_ret;
void* m_status;
- Thr(Par par, unsigned n);
+ char m_tmp[20]; // used for debug msg prefix
+ Thr(Par par, uint n);
~Thr();
int run();
void start();
void stop();
- void stopped();
void exit();
//
void lock() {
@@ -4513,10 +4942,9 @@ struct Thr {
}
};
-Thr::Thr(Par par, unsigned n) :
+Thr::Thr(Par par, uint n) :
m_state(Wait),
m_par(par),
- m_id(0),
m_thread(0),
m_mutex(0),
m_cond(0),
@@ -4533,7 +4961,7 @@ Thr::Thr(Par par, unsigned n) :
m_cond = NdbCondition_Create();
assert(m_mutex != 0 && m_cond != 0);
// run
- const unsigned stacksize = 256 * 1024;
+ const uint stacksize = 256 * 1024;
const NDB_THREAD_PRIO prio = NDB_THREAD_PRIO_LOW;
m_thread = NdbThread_Create(runthread, (void**)this, stacksize, name, prio);
}
@@ -4558,7 +4986,7 @@ static void*
runthread(void* arg)
{
Thr& thr = *(Thr*)arg;
- thr.m_id = (Uint64)pthread_self();
+ thr.m_id = pthread_self();
if (thr.run() < 0) {
LL1("exit on error");
} else {
@@ -4589,11 +5017,16 @@ Thr::run()
LL4("start");
assert(m_state == Start);
m_ret = (*m_func)(m_par);
- m_state = Stopped;
+ m_state = Stop;
LL4("stop");
signal();
unlock();
- CHK(m_ret == 0);
+ if (m_ret == -1) {
+ if (m_par.m_cont)
+ LL1("continue running due to -cont");
+ else
+ return -1;
+ }
}
con.disconnect();
return 0;
@@ -4612,16 +5045,7 @@ void
Thr::stop()
{
lock();
- m_state = Stop;
- signal();
- unlock();
-}
-
-void
-Thr::stopped()
-{
- lock();
- while (m_state != Stopped)
+ while (m_state != Stop)
wait();
m_state = Wait;
unlock();
@@ -4640,27 +5064,44 @@ Thr::exit()
static Thr** g_thrlist = 0;
-static unsigned
-getthrno()
+static Thr*
+getthr()
{
if (g_thrlist != 0) {
- Uint64 id = (Uint64)pthread_self();
- for (unsigned n = 0; n < g_opt.m_threads; n++) {
+ pthread_t id = pthread_self();
+ for (uint n = 0; n < g_opt.m_threads; n++) {
if (g_thrlist[n] != 0) {
- const Thr& thr = *g_thrlist[n];
- if (thr.m_id == id)
- return thr.m_par.m_no;
+ Thr& thr = *g_thrlist[n];
+ if (pthread_equal(thr.m_id, id))
+ return &thr;
}
}
}
- return (unsigned)-1;
+ return 0;
+}
+
+// for debug messages (par.m_no not available)
+static const char*
+getthrprefix()
+{
+ Thr* thrp = getthr();
+ if (thrp != 0) {
+ Thr& thr = *thrp;
+ uint n = thr.m_par.m_no;
+ uint m =
+ g_opt.m_threads < 10 ? 1 :
+ g_opt.m_threads < 100 ? 2 : 3;
+ sprintf(thr.m_tmp, "[%0*u] ", m, n);
+ return thr.m_tmp;
+ }
+ return "";
}
static int
-runstep(Par par, const char* fname, TFunc func, unsigned mode)
+runstep(Par par, const char* fname, TFunc func, uint mode)
{
LL2("step: " << fname);
- const int threads = (mode & ST ? 1 : par.m_threads);
+ const int threads = (mode & ST ? 1 : par.m_usedthreads);
int n;
for (n = 0; n < threads; n++) {
LL4("start " << n);
@@ -4673,11 +5114,11 @@ runstep(Par par, const char* fname, TFunc func, unsigned mode)
thr.m_func = func;
thr.start();
}
- unsigned errs = 0;
+ uint errs = 0;
for (n = threads - 1; n >= 0; n--) {
LL4("stop " << n);
Thr& thr = *g_thrlist[n];
- thr.stopped();
+ thr.stop();
if (thr.m_ret != 0)
errs++;
}
@@ -4689,7 +5130,7 @@ runstep(Par par, const char* fname, TFunc func, unsigned mode)
CHK(runstep(par, #func, func, mode) == 0)
#define SUBLOOP(par) \
- "subloop: " << par.m_lno << "/" << par.m_currcase << "/" << \
+ "sloop: " << par.m_lno << "/" << par.m_currcase << "/" << \
par.m_tab->m_name << "/" << par.m_slno
static int
@@ -4698,7 +5139,7 @@ tbuild(Par par)
RUNSTEP(par, droptable, ST);
RUNSTEP(par, createtable, ST);
RUNSTEP(par, invalidatetable, MT);
- for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) {
+ for (par.m_slno = 0; par.m_slno < par.m_sloop; par.m_slno++) {
LL1(SUBLOOP(par));
if (par.m_slno % 3 == 0) {
RUNSTEP(par, createindex, ST);
@@ -4718,7 +5159,7 @@ tbuild(Par par)
}
RUNSTEP(par, readverifyfull, MT);
// leave last one
- if (par.m_slno + 1 < par.m_subloop) {
+ if (par.m_slno + 1 < par.m_sloop) {
RUNSTEP(par, pkdelete, MT);
RUNSTEP(par, readverifyfull, MT);
RUNSTEP(par, dropindex, ST);
@@ -4737,7 +5178,7 @@ tindexscan(Par par)
RUNSTEP(par, invalidateindex, MT);
RUNSTEP(par, pkinsert, MT);
RUNSTEP(par, readverifyfull, MT);
- for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) {
+ for (par.m_slno = 0; par.m_slno < par.m_sloop; par.m_slno++) {
LL1(SUBLOOP(par));
RUNSTEP(par, readverifyindex, MT);
}
@@ -4753,7 +5194,7 @@ tpkops(Par par)
RUNSTEP(par, invalidatetable, MT);
RUNSTEP(par, createindex, ST);
RUNSTEP(par, invalidateindex, MT);
- for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) {
+ for (par.m_slno = 0; par.m_slno < par.m_sloop; par.m_slno++) {
LL1(SUBLOOP(par));
RUNSTEP(par, pkops, MT);
LL2("rows=" << par.set().count());
@@ -4772,7 +5213,7 @@ tpkopsread(Par par)
RUNSTEP(par, createindex, ST);
RUNSTEP(par, invalidateindex, MT);
RUNSTEP(par, readverifyfull, MT);
- for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) {
+ for (par.m_slno = 0; par.m_slno < par.m_sloop; par.m_slno++) {
LL1(SUBLOOP(par));
RUNSTEP(par, pkupdatescanread, MT);
RUNSTEP(par, readverifyfull, MT);
@@ -4792,7 +5233,7 @@ tmixedops(Par par)
RUNSTEP(par, createindex, ST);
RUNSTEP(par, invalidateindex, MT);
RUNSTEP(par, readverifyfull, MT);
- for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) {
+ for (par.m_slno = 0; par.m_slno < par.m_sloop; par.m_slno++) {
LL1(SUBLOOP(par));
RUNSTEP(par, mixedoperations, MT);
RUNSTEP(par, readverifyfull, MT);
@@ -4807,7 +5248,7 @@ tbusybuild(Par par)
RUNSTEP(par, createtable, ST);
RUNSTEP(par, invalidatetable, MT);
RUNSTEP(par, pkinsert, MT);
- for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) {
+ for (par.m_slno = 0; par.m_slno < par.m_sloop; par.m_slno++) {
LL1(SUBLOOP(par));
RUNSTEP(par, pkupdateindexbuild, MT);
RUNSTEP(par, invalidateindex, MT);
@@ -4828,7 +5269,7 @@ trollback(Par par)
RUNSTEP(par, createindex, ST);
RUNSTEP(par, invalidateindex, MT);
RUNSTEP(par, readverifyfull, MT);
- for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) {
+ for (par.m_slno = 0; par.m_slno < par.m_sloop; par.m_slno++) {
LL1(SUBLOOP(par));
RUNSTEP(par, mixedoperations, MT);
RUNSTEP(par, readverifyfull, MT);
@@ -4846,7 +5287,7 @@ tparupdate(Par par)
RUNSTEP(par, createindex, ST);
RUNSTEP(par, invalidateindex, MT);
RUNSTEP(par, readverifyfull, MT);
- for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) {
+ for (par.m_slno = 0; par.m_slno < par.m_sloop; par.m_slno++) {
LL1(SUBLOOP(par));
RUNSTEP(par, parallelorderedupdate, MT);
RUNSTEP(par, readverifyfull, MT);
@@ -4855,13 +5296,44 @@ tparupdate(Par par)
}
static int
+tsavepoint(Par par)
+{
+ RUNSTEP(par, droptable, ST);
+ RUNSTEP(par, createtable, ST);
+ RUNSTEP(par, invalidatetable, MT);
+ RUNSTEP(par, createindex, ST);
+ RUNSTEP(par, invalidateindex, MT);
+ for (par.m_slno = 0; par.m_slno < par.m_sloop; par.m_slno++) {
+ LL1(SUBLOOP(par));
+ RUNSTEP(par, savepointtest, MT);
+ RUNSTEP(par, readverifyfull, MT);
+ }
+ return 0;
+}
+
+static int
+thalloween(Par par)
+{
+ RUNSTEP(par, droptable, ST);
+ RUNSTEP(par, createtable, ST);
+ RUNSTEP(par, invalidatetable, MT);
+ RUNSTEP(par, createindex, ST);
+ RUNSTEP(par, invalidateindex, MT);
+ for (par.m_slno = 0; par.m_slno < par.m_sloop; par.m_slno++) {
+ LL1(SUBLOOP(par));
+ RUNSTEP(par, halloweentest, MT);
+ }
+ return 0;
+}
+
+static int
ttimebuild(Par par)
{
Tmr t1;
RUNSTEP(par, droptable, ST);
RUNSTEP(par, createtable, ST);
RUNSTEP(par, invalidatetable, MT);
- for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) {
+ for (par.m_slno = 0; par.m_slno < par.m_sloop; par.m_slno++) {
LL1(SUBLOOP(par));
RUNSTEP(par, pkinsert, MT);
t1.on();
@@ -4881,7 +5353,7 @@ ttimemaint(Par par)
RUNSTEP(par, droptable, ST);
RUNSTEP(par, createtable, ST);
RUNSTEP(par, invalidatetable, MT);
- for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) {
+ for (par.m_slno = 0; par.m_slno < par.m_sloop; par.m_slno++) {
LL1(SUBLOOP(par));
RUNSTEP(par, pkinsert, MT);
t1.on();
@@ -4911,7 +5383,7 @@ ttimescan(Par par)
RUNSTEP(par, droptable, ST);
RUNSTEP(par, createtable, ST);
RUNSTEP(par, invalidatetable, MT);
- for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) {
+ for (par.m_slno = 0; par.m_slno < par.m_sloop; par.m_slno++) {
LL1(SUBLOOP(par));
RUNSTEP(par, pkinsert, MT);
RUNSTEP(par, createindex, ST);
@@ -4938,7 +5410,7 @@ ttimepkread(Par par)
RUNSTEP(par, droptable, ST);
RUNSTEP(par, createtable, ST);
RUNSTEP(par, invalidatetable, MT);
- for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) {
+ for (par.m_slno = 0; par.m_slno < par.m_sloop; par.m_slno++) {
LL1(SUBLOOP(par));
RUNSTEP(par, pkinsert, MT);
RUNSTEP(par, createindex, ST);
@@ -4981,7 +5453,9 @@ tcaselist[] = {
TCase("e", tmixedops, "pk operations and scan operations"),
TCase("f", tbusybuild, "pk operations and index build"),
TCase("g", trollback, "operations with random rollbacks"),
- TCase("h", tparupdate, "parallel ordered update (bug20446)"),
+ TCase("h", tparupdate, "parallel ordered update bug#20446"),
+ TCase("i", tsavepoint, "savepoint test locking bug#31477"),
+ TCase("j", thalloween, "savepoint test halloween problem"),
TCase("t", ttimebuild, "time index build"),
TCase("u", ttimemaint, "time index maintenance"),
TCase("v", ttimescan, "time full scan table vs index on pk"),
@@ -4989,14 +5463,14 @@ tcaselist[] = {
TCase("z", tdrop, "drop test tables")
};
-static const unsigned
+static const uint
tcasecount = sizeof(tcaselist) / sizeof(tcaselist[0]);
static void
printcases()
{
ndbout << "test cases:" << endl;
- for (unsigned i = 0; i < tcasecount; i++) {
+ for (uint i = 0; i < tcasecount; i++) {
const TCase& tcase = tcaselist[i];
ndbout << " " << tcase.m_name << " - " << tcase.m_desc << endl;
}
@@ -5008,13 +5482,13 @@ printtables()
Par par(g_opt);
makebuiltintables(par);
ndbout << "tables and indexes (x=ordered z=hash x0=on pk):" << endl;
- for (unsigned j = 0; j < tabcount; j++) {
+ for (uint j = 0; j < tabcount; j++) {
if (tablist[j] == 0)
continue;
const Tab& tab = *tablist[j];
const char* tname = tab.m_name;
ndbout << " " << tname;
- for (unsigned i = 0; i < tab.m_itabs; i++) {
+ for (uint i = 0; i < tab.m_itabs; i++) {
if (tab.m_itab[i] == 0)
continue;
const ITab& itab = *tab.m_itab[i];
@@ -5023,7 +5497,7 @@ printtables()
iname += strlen(tname);
ndbout << " " << iname;
ndbout << "(";
- for (unsigned k = 0; k < itab.m_icols; k++) {
+ for (uint k = 0; k < itab.m_icols; k++) {
if (k != 0)
ndbout << ",";
const ICol& icol = *itab.m_icol[k];
@@ -5036,14 +5510,48 @@ printtables()
}
}
+static bool
+setcasepar(Par& par)
+{
+ Opt d;
+ const char* c = par.m_currcase;
+ switch (c[0]) {
+ case 'i':
+ {
+ if (par.m_usedthreads > 1) {
+ par.m_usedthreads = 1;
+ LL1("case " << c << " reduce threads to " << par.m_usedthreads);
+ }
+ const uint rows = 100;
+ if (par.m_rows > rows) {
+ par.m_rows = rows;
+ LL1("case " << c << " reduce rows to " << rows);
+ }
+ }
+ break;
+ case 'j':
+ {
+ if (par.m_usedthreads > 1) {
+ par.m_usedthreads = 1;
+ LL1("case " << c << " reduce threads to " << par.m_usedthreads);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
static int
runtest(Par par)
{
+ int totret = 0;
if (par.m_seed == -1) {
// good enough for daily run
- unsigned short seed = (unsigned short)getpid();
+ ushort seed = (ushort)getpid();
LL0("random seed: " << seed);
- srandom((unsigned)seed);
+ srandom((uint)seed);
} else if (par.m_seed != 0) {
LL0("random seed: " << par.m_seed);
srandom(par.m_seed);
@@ -5061,9 +5569,10 @@ runtest(Par par)
Con con;
CHK(con.connect() == 0);
par.m_con = &con;
+ par.m_catcherr |= Con::ErrNospace;
// threads
g_thrlist = new Thr* [par.m_threads];
- unsigned n;
+ uint n;
for (n = 0; n < par.m_threads; n++) {
g_thrlist[n] = 0;
}
@@ -5078,23 +5587,38 @@ runtest(Par par)
LL1("random seed: " << par.m_lno);
srandom(par.m_lno);
}
- for (unsigned i = 0; i < tcasecount; i++) {
+ for (uint i = 0; i < tcasecount; i++) {
const TCase& tcase = tcaselist[i];
- if (par.m_case != 0 && strchr(par.m_case, tcase.m_name[0]) == 0)
+ if (par.m_case != 0 && strchr(par.m_case, tcase.m_name[0]) == 0 ||
+ par.m_skip != 0 && strchr(par.m_skip, tcase.m_name[0]) != 0) {
continue;
+ }
sprintf(par.m_currcase, "%c", tcase.m_name[0]);
+ par.m_usedthreads = par.m_threads;
+ if (!setcasepar(par)) {
+ LL1("case " << tcase.m_name << " cannot run with given options");
+ continue;
+ }
+ par.m_totrows = par.m_usedthreads * par.m_rows;
makebuiltintables(par);
LL1("case: " << par.m_lno << "/" << tcase.m_name << " - " << tcase.m_desc);
- for (unsigned j = 0; j < tabcount; j++) {
+ for (uint j = 0; j < tabcount; j++) {
if (tablist[j] == 0)
continue;
const Tab& tab = *tablist[j];
par.m_tab = &tab;
par.m_set = new Set(tab, par.m_totrows);
LL1("table: " << par.m_lno << "/" << tcase.m_name << "/" << tab.m_name);
- CHK(tcase.m_func(par) == 0);
+ int ret = tcase.m_func(par);
delete par.m_set;
par.m_set = 0;
+ if (ret == -1) {
+ if (!par.m_cont)
+ return -1;
+ totret = -1;
+ LL1("continue to next case due to -cont");
+ break;
+ }
}
}
}
@@ -5110,7 +5634,7 @@ runtest(Par par)
delete [] g_thrlist;
g_thrlist = 0;
con.disconnect();
- return 0;
+ return totret;
}
static const char* g_progname = "testOIBasic";
@@ -5119,7 +5643,7 @@ int
main(int argc, char** argv)
{
ndb_init();
- unsigned i;
+ uint i;
ndbout << g_progname;
for (i = 1; i < argc; i++)
ndbout << " " << argv[i];
@@ -5156,6 +5680,10 @@ main(int argc, char** argv)
g_opt.m_collsp = true;
continue;
}
+ if (strcmp(arg, "-cont") == 0) {
+ g_opt.m_cont = true;
+ continue;
+ }
if (strcmp(arg, "-core") == 0) {
g_opt.m_core = true;
continue;
@@ -5252,9 +5780,21 @@ main(int argc, char** argv)
continue;
}
}
- if (strcmp(arg, "-subloop") == 0) {
+ if (strcmp(arg, "-skip") == 0) {
+ if (++argv, --argc > 0) {
+ g_opt.m_skip = strdup(argv[0]);
+ continue;
+ }
+ }
+ if (strcmp(arg, "-sloop") == 0) {
+ if (++argv, --argc > 0) {
+ g_opt.m_sloop = atoi(argv[0]);
+ continue;
+ }
+ }
+ if (strcmp(arg, "-ssloop") == 0) {
if (++argv, --argc > 0) {
- g_opt.m_subloop = atoi(argv[0]);
+ g_opt.m_ssloop = atoi(argv[0]);
continue;
}
}
diff --git a/ndb/test/run-test/daily-basic-tests.txt b/ndb/test/run-test/daily-basic-tests.txt
index 7b4a4ca0e2d..a27b94193e5 100644
--- a/ndb/test/run-test/daily-basic-tests.txt
+++ b/ndb/test/run-test/daily-basic-tests.txt
@@ -649,10 +649,10 @@ max-time: 1000
cmd: testNdbApi
args: -n Bug28443
-#max-time: 500
-#cmd: testInterpreter
-#args: T1
-#
+max-time: 500
+cmd: testInterpreter
+args: T1
+
max-time: 150000
cmd: testOperations
args:
diff --git a/ndb/tools/waiter.cpp b/ndb/tools/waiter.cpp
index e221a26182e..8226de87b49 100644
--- a/ndb/tools/waiter.cpp
+++ b/ndb/tools/waiter.cpp
@@ -21,13 +21,11 @@
#include <NdbMain.h>
#include <NdbOut.hpp>
#include <NdbSleep.h>
-#include <kernel/ndb_limits.h>
#include <NDBT.hpp>
-int
-waitClusterStatus(const char* _addr, ndb_mgm_node_status _status,
- unsigned int _timeout);
+static int
+waitClusterStatus(const char* _addr, ndb_mgm_node_status _status);
enum ndb_waiter_options {
OPT_WAIT_STATUS_NOT_STARTED = NDB_STD_OPTIONS_LAST,
@@ -55,12 +53,13 @@ static struct my_option my_long_options[] =
"Wait for cluster to enter single user mode",
(gptr*) &_single_user, (gptr*) &_single_user, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
- { "timeout", 't', "Timeout to wait",
+ { "timeout", 't', "Timeout to wait in seconds",
(gptr*) &_timeout, (gptr*) &_timeout, 0,
GET_INT, REQUIRED_ARG, 120, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+
static void usage()
{
ndb_std_print_version();
@@ -70,16 +69,18 @@ static void usage()
my_print_variables(my_long_options);
}
+
int main(int argc, char** argv){
NDB_INIT(argv[0]);
load_defaults("my",load_default_groups,&argc,&argv);
const char* _hostName = NULL;
- int ho_error;
+
#ifndef DBUG_OFF
opt_debug= "d:t:O,/tmp/ndb_waiter.trace";
#endif
- if ((ho_error=handle_options(&argc, &argv, my_long_options,
- ndb_std_get_one_option)))
+
+ if (handle_options(&argc, &argv, my_long_options,
+ ndb_std_get_one_option))
return NDBT_ProgramExit(NDBT_WRONGARGS);
_hostName = argv[0];
@@ -105,7 +106,7 @@ int main(int argc, char** argv){
wait_status= NDB_MGM_NODE_STATUS_STARTED;
}
- if (waitClusterStatus(_hostName, wait_status, _timeout) != 0)
+ if (waitClusterStatus(_hostName, wait_status) != 0)
return NDBT_ProgramExit(NDBT_FAILED);
return NDBT_ProgramExit(NDBT_OK);
}
@@ -118,8 +119,6 @@ int main(int argc, char** argv){
NdbMgmHandle handle= NULL;
Vector<ndb_mgm_node_state> ndbNodes;
-Vector<ndb_mgm_node_state> mgmNodes;
-Vector<ndb_mgm_node_state> apiNodes;
int
getStatus(){
@@ -128,8 +127,6 @@ getStatus(){
struct ndb_mgm_node_state * node;
ndbNodes.clear();
- mgmNodes.clear();
- apiNodes.clear();
while(retries < 10){
status = ndb_mgm_get_status(handle);
@@ -153,18 +150,16 @@ getStatus(){
ndbNodes.push_back(*node);
break;
case NDB_MGM_NODE_TYPE_MGM:
- mgmNodes.push_back(*node);
+ /* Don't care about MGM nodes */
break;
case NDB_MGM_NODE_TYPE_API:
- apiNodes.push_back(*node);
+ /* Don't care about API nodes */
break;
default:
if(node->node_status == NDB_MGM_NODE_STATUS_UNKNOWN ||
node->node_status == NDB_MGM_NODE_STATUS_NO_CONTACT){
retries++;
ndbNodes.clear();
- mgmNodes.clear();
- apiNodes.clear();
free(status);
status = NULL;
count = 0;
@@ -183,24 +178,22 @@ getStatus(){
free(status);
return 0;
}
-
- g_err << "getStatus failed" << endl;
+
return -1;
}
-int
+static int
waitClusterStatus(const char* _addr,
- ndb_mgm_node_status _status,
- unsigned int _timeout)
+ ndb_mgm_node_status _status)
{
int _startphase = -1;
- int _nodes[MAX_NDB_NODES];
- int _num_nodes = 0;
+ /* Ignore SIGPIPE */
+ signal(SIGPIPE, SIG_IGN);
handle = ndb_mgm_create_handle();
if (handle == NULL){
- g_err << "handle == NULL" << endl;
+ g_err << "Could not create ndb_mgm handle" << endl;
return -1;
}
g_info << "Connecting to mgmsrv at " << _addr << endl;
@@ -216,19 +209,11 @@ waitClusterStatus(const char* _addr,
return -1;
}
- if (getStatus() != 0)
- return -1;
-
- // Collect all nodes into nodes
- for (size_t i = 0; i < ndbNodes.size(); i++){
- _nodes[i] = ndbNodes[i].node_id;
- _num_nodes++;
- }
-
- unsigned int attempts = 0;
- unsigned int resetAttempts = 0;
- const unsigned int MAX_RESET_ATTEMPTS = 10;
- bool allInState = false;
+ int attempts = 0;
+ int resetAttempts = 0;
+ const int MAX_RESET_ATTEMPTS = 10;
+ bool allInState = false;
+ int timeout_ms= _timeout * 10; /* In number of 100 milliseconds */
while (allInState == false){
if (_timeout > 0 && attempts > _timeout){
/**
@@ -236,8 +221,8 @@ waitClusterStatus(const char* _addr,
* the state we want
*/
bool waitMore = false;
- /**
- * Make special check if we are waiting for
+ /**
+ * Make special check if we are waiting for
* cluster to become started
*/
if(_status == NDB_MGM_NODE_STATUS_STARTED){
@@ -252,7 +237,7 @@ waitClusterStatus(const char* _addr,
waitMore = false;
}
- }
+ }
if (!waitMore || resetAttempts > MAX_RESET_ATTEMPTS){
g_err << "waitNodeState("
@@ -260,7 +245,7 @@ waitClusterStatus(const char* _addr,
<<", "<<_startphase<<")"
<< " timeout after " << attempts <<" attemps" << endl;
return -1;
- }
+ }
g_err << "waitNodeState("
<< ndb_mgm_get_node_status_string(_status)
@@ -269,62 +254,34 @@ waitClusterStatus(const char* _addr,
<< resetAttempts << endl;
attempts = 0;
resetAttempts++;
-
}
- allInState = true;
if (getStatus() != 0){
- g_err << "getStatus != 0" << endl;
return -1;
}
- // ndbout << "waitNodeState; _num_nodes = " << _num_nodes << endl;
- // for (int i = 0; i < _num_nodes; i++)
- // ndbout << " node["<<i<<"] =" <<_nodes[i] << endl;
+ /* Assume all nodes are in state(if there is any) */
+ allInState = (ndbNodes.size() > 0);
- for (int i = 0; i < _num_nodes; i++){
- ndb_mgm_node_state* ndbNode = NULL;
- for (size_t n = 0; n < ndbNodes.size(); n++){
- if (ndbNodes[n].node_id == _nodes[i])
- ndbNode = &ndbNodes[n];
- }
+ /* Loop through all nodes and check their state */
+ for (size_t n = 0; n < ndbNodes.size(); n++) {
+ ndb_mgm_node_state* ndbNode = &ndbNodes[n];
- if(ndbNode == NULL){
- allInState = false;
- continue;
- }
+ assert(ndbNode != NULL);
- g_info << "State node " << ndbNode->node_id << " "
+ g_info << "Node " << ndbNode->node_id << ": "
<< ndb_mgm_get_node_status_string(ndbNode->node_status)<< endl;
- assert(ndbNode != NULL);
-
- if(_status == NDB_MGM_NODE_STATUS_STARTING &&
- ((ndbNode->node_status == NDB_MGM_NODE_STATUS_STARTING &&
- ndbNode->start_phase >= _startphase) ||
- (ndbNode->node_status == NDB_MGM_NODE_STATUS_STARTED)))
- continue;
-
- if (_status == NDB_MGM_NODE_STATUS_STARTING){
- g_info << "status = "
- << ndb_mgm_get_node_status_string(ndbNode->node_status)
- <<", start_phase="<<ndbNode->start_phase<<endl;
- if (ndbNode->node_status != _status) {
- if (ndbNode->node_status < _status)
- allInState = false;
- else
- g_info << "node_status(" << (unsigned)ndbNode->node_status
- << ") != _status("<< (unsigned)_status << ")" <<endl;
- } else if (ndbNode->start_phase < _startphase)
- allInState = false;
- } else {
- if (ndbNode->node_status != _status)
+ if (ndbNode->node_status != _status)
allInState = false;
- }
}
- g_info << "Waiting for cluster enter state "
- << ndb_mgm_get_node_status_string(_status)<< endl;
- NdbSleep_SecSleep(1);
+
+ if (!allInState) {
+ g_info << "Waiting for cluster enter state "
+ << ndb_mgm_get_node_status_string(_status)<< endl;
+ NdbSleep_MilliSleep(100);
+ }
+
attempts++;
}
return 0;
diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
index 6fbfcab72d4..d7bcb8fd4e7 100755
--- a/scripts/CMakeLists.txt
+++ b/scripts/CMakeLists.txt
@@ -40,3 +40,44 @@ ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/scripts/mysql_fix_privilege_tabl
ADD_CUSTOM_TARGET(GenFixPrivs
ALL
DEPENDS ${PROJECT_SOURCE_DIR}/scripts/mysql_fix_privilege_tables_sql.c)
+
+# ----------------------------------------------------------------------
+# Replace some variables @foo@ in the .in/.sh file, and write the new script
+# ----------------------------------------------------------------------
+
+SET(CFLAGS "-D_WINDOWS ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
+SET(prefix "${CMAKE_INSTALL_PREFIX}/MySQL Server ${MYSQL_BASE_VERSION}")
+SET(sysconfdir ${prefix})
+SET(bindir ${prefix}/bin)
+SET(libexecdir ${prefix}/bin)
+SET(scriptdir ${prefix}/bin)
+SET(datadir ${prefix}/share)
+SET(pkgdatadir ${prefix}/share)
+SET(localstatedir ${prefix}/data)
+
+CONFIGURE_FILE(mysql_config.pl.in
+ scripts/mysql_config.pl ESCAPE_QUOTES @ONLY)
+
+CONFIGURE_FILE(mysql_convert_table_format.sh
+ scripts/mysql_convert_table_format.pl ESCAPE_QUOTES @ONLY)
+
+CONFIGURE_FILE(mysql_explain_log.sh
+ scripts/mysql_explain_log.pl ESCAPE_QUOTES @ONLY)
+
+CONFIGURE_FILE(mysql_install_db.pl.in
+ scripts/mysql_install_db.pl ESCAPE_QUOTES @ONLY)
+
+CONFIGURE_FILE(mysql_secure_installation.pl.in
+ scripts/mysql_secure_installation.pl ESCAPE_QUOTES @ONLY)
+
+CONFIGURE_FILE(mysql_tableinfo.sh
+ scripts/mysql_tableinfo.pl ESCAPE_QUOTES @ONLY)
+
+CONFIGURE_FILE(mysqld_multi.sh
+ scripts/mysqld_multi.pl ESCAPE_QUOTES @ONLY)
+
+CONFIGURE_FILE(mysqldumpslow.sh
+ scripts/mysqldumpslow.pl ESCAPE_QUOTES @ONLY)
+
+CONFIGURE_FILE(mysqlhotcopy.sh
+ scripts/mysqlhotcopy.pl ESCAPE_QUOTES @ONLY)
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 5db5fdd550f..87170b46675 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -48,11 +48,14 @@ EXTRA_SCRIPTS = make_binary_distribution.sh \
make_win_src_distribution_old.sh \
msql2mysql.sh \
mysql_config.sh \
+ mysql_config.pl.in \
mysql_fix_privilege_tables.sh \
mysql_fix_extensions.sh \
mysql_install_db.sh \
+ mysql_install_db.pl.in \
mysql_setpermission.sh \
mysql_secure_installation.sh \
+ mysql_secure_installation.pl.in \
mysql_zap.sh \
mysqlaccess.sh \
mysqlbug.sh \
diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh
index a87bb03526d..8598a022669 100644
--- a/scripts/make_binary_distribution.sh
+++ b/scripts/make_binary_distribution.sh
@@ -400,11 +400,13 @@ BASE=$BASE2
#
if [ x"@GXX@" = x"yes" ] ; then
- gcclib=`@CC@ @CFLAGS@ --print-libgcc-file`
- if [ $? -ne 0 ] ; then
- echo "Warning: Couldn't find libgcc.a!"
- else
+ gcclib=`@CC@ @CFLAGS@ --print-libgcc-file 2>/dev/null` || true
+ if [ -z "$gcclib" ] ; then
+ echo "Warning: Compiler doesn't tell libgcc.a!"
+ elif [ -f "$gcclib" ] ; then
$CP $gcclib $BASE/lib/libmygcc.a
+ else
+ echo "Warning: Compiler result '$gcclib' not found / no file!"
fi
fi
diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist
index d065e171bb0..56510dc857b 100755
--- a/scripts/make_win_bin_dist
+++ b/scripts/make_win_bin_dist
@@ -327,35 +327,34 @@ if [ -d mysql-test/extra ] ; then
fi
# ----------------------------------------------------------------------
-# Copy what could be usable in the "scripts" directory. Currently
-# only SQL files, others are Bourne shell scripts or Perl scripts
-# not really usable on Windows.
-#
-# But to be nice to the few Cygwin users we might have in 5.0 we
-# continue to copy the stuff, but don't include it in the WiX install.
+# Copy what could be usable in the "scripts" directory
# ----------------------------------------------------------------------
+mysql_scripts="\
+mysql_config.pl \
+mysql_convert_table_format.pl \
+mysql_explain_log.pl \
+mysql_install_db.pl \
+mysql_secure_installation.pl \
+mysql_tableinfo.pl \
+mysqld_multi.pl \
+mysqldumpslow.pl \
+mysqlhotcopy.pl \
+"
+
mkdir -p $DESTDIR/scripts
-# Uncomment and remove the for loop in 5.1
-#cp scripts/*.sql $DESTDIR/scripts/
-
-for i in `cd scripts && ls`; do \
- if echo $i | grep -q '\.sh'; then \
- cp scripts/$i $DESTDIR/scripts/`echo $i | sed -e 's/\.sh$//'`; \
- elif [ -d scripts/$i -o $i = Makefile.am -o $i = Makefile.in -o -e scripts/$i.sh ] ; then \
- : ; \
- else \
- cp scripts/$i $DESTDIR/scripts/$i; \
- fi; \
+for i in $mysql_scripts
+do
+ cp scripts/$i $DESTDIR/scripts/$i
done
cp -pR sql/share $DESTDIR/
cp -pR sql-bench $DESTDIR/
rm -f $DESTDIR/sql-bench/*.sh $DESTDIR/sql-bench/Makefile*
-# The SQL initialisation code is really expected to be in "share"
-mv $DESTDIR/scripts/*.sql $DESTDIR/share/ || true
+# The SQL initialisation code is to be in "share"
+cp scripts/*.sql $DESTDIR/share/
# ----------------------------------------------------------------------
# Clean up from possibly copied SCCS directories
diff --git a/scripts/mysql_config.pl.in b/scripts/mysql_config.pl.in
new file mode 100644
index 00000000000..3ae8baf7db0
--- /dev/null
+++ b/scripts/mysql_config.pl.in
@@ -0,0 +1,285 @@
+#!/usr/bin/perl
+# -*- cperl -*-
+#
+# Copyright (C) 2007 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
+
+##############################################################################
+#
+# This script reports various configuration settings that may be needed
+# when using the MySQL client library.
+#
+# This script try to match the shell script version as close as possible,
+# but in addition being compatible with ActiveState Perl on Windows.
+#
+# All unrecognized arguments to this script are passed to mysqld.
+#
+# NOTE: This script will only be used on Windows until solved how to
+# handle @LIBS@ and other strings inserted that might contain
+# several arguments, possibly with spaces in them.
+#
+# NOTE: This script was deliberately written to be as close to the shell
+# script as possible, to make the maintenance of both in parallel
+# easier.
+#
+##############################################################################
+
+use File::Basename;
+use Getopt::Long;
+use Cwd;
+use strict;
+
+my @exclude_cflags =
+ qw/DDBUG_OFF DSAFEMALLOC USAFEMALLOC DSAFE_MUTEX
+ DPEDANTIC_SAFEMALLOC DUNIV_MUST_NOT_INLINE DFORCE_INIT_OF_VARS
+ DEXTRA_DEBUG DHAVE_purify O O[0-9] xO[0-9] W[-A-Za-z]*
+ Xa xstrconst xc99=none
+ unroll2 ip mp restrict/;
+
+my @exclude_libs = qw/lmtmalloc static-libcxa i-static static-intel/;
+
+my $cwd = cwd();
+my $basedir;
+
+my $socket = '@MYSQL_UNIX_ADDR@';
+my $version = '@VERSION@';
+
+sub which
+{
+ my $file = shift;
+
+ my $IFS = $^O eq "MSWin32" ? ";" : ":";
+
+ foreach my $dir ( split($IFS, $ENV{PATH}) )
+ {
+ if ( -f "$dir/$file" or -f "$dir/$file.exe" )
+ {
+ return "$dir/$file";
+ }
+ }
+ print STDERR "which: no $file in ($ENV{PATH})\n";
+ exit 1;
+}
+
+# ----------------------------------------------------------------------
+# If we can find the given directory relatively to where mysql_config is
+# we should use this instead of the incompiled one.
+# This is to ensure that this script also works with the binary MySQL
+# version
+# ----------------------------------------------------------------------
+
+sub fix_path
+{
+ my $default = shift;
+ my @dirs = @_;
+
+ foreach my $dirname ( @dirs )
+ {
+ my $path = "$basedir/$dirname";
+ if ( -d $path )
+ {
+ return $path;
+ }
+ }
+ return $default;
+}
+
+sub get_full_path
+{
+ my $file = shift;
+
+ # if the file is a symlink, try to resolve it
+ if ( $^O ne "MSWin32" and -l $file )
+ {
+ $file = readlink($file);
+ }
+
+ if ( $file =~ m,^/, )
+ {
+ # Do nothing, absolute path
+ }
+ elsif ( $file =~ m,/, )
+ {
+ # Make absolute, and remove "/./" in path
+ $file = "$cwd/$file";
+ $file =~ s,/\./,/,g;
+ }
+ else
+ {
+ # Find in PATH
+ $file = which($file);
+ }
+
+ return $file;
+}
+
+##############################################################################
+#
+# Form a command line that can handle spaces in paths and arguments
+#
+##############################################################################
+
+sub quote_options {
+ my @cmd;
+ foreach my $opt ( @_ )
+ {
+ next unless $opt; # If undefined or empty, just skip
+ push(@cmd, "\"$opt\""); # Quote argument
+ }
+ return join(" ", @cmd);
+}
+
+##############################################################################
+#
+# Main program
+#
+##############################################################################
+
+my $me = get_full_path($0);
+$basedir = dirname(dirname($me)); # Remove "/bin/mysql_config" part
+
+my $ldata = '@localstatedir@';
+my $execdir = '@libexecdir@';
+my $bindir = '@bindir@';
+
+# ----------------------------------------------------------------------
+# If installed, search for the compiled in directory first (might be "lib64")
+# ----------------------------------------------------------------------
+
+my $pkglibdir = fix_path('@pkglibdir@',"libmysql/relwithdebinfo",
+ "libmysql/release","libmysql/debug","lib/mysql","lib");
+
+my $pkgincludedir = fix_path('@pkgincludedir@', "include/mysql", "include");
+
+# Assume no argument with space in it
+my @ldflags = split(" ",'@LDFLAGS@');
+
+my $port;
+if ( '@MYSQL_TCP_PORT_DEFAULT@' == 0 ) {
+ $port = 0;
+} else {
+ $port = '@MYSQL_TCP_PORT@';
+}
+
+# ----------------------------------------------------------------------
+# Create options
+# We intentionally add a space to the beginning and end of lib strings, simplifies replace later
+# ----------------------------------------------------------------------
+
+my (@lib_opts,@lib_r_opts,@lib_e_opts);
+if ( $^O eq "MSWin32" )
+{
+ my $linkpath = "$pkglibdir";
+ # user32 is only needed for debug or embedded
+ my @winlibs = ("wsock32.lib","advapi32.lib","user32.lib");
+ @lib_opts = ("$linkpath/mysqlclient.lib",@winlibs);
+ @lib_r_opts = @lib_opts;
+ @lib_e_opts = ("$linkpath/mysqlserver.lib",@winlibs);
+}
+else
+{
+ my $linkpath = "-L$pkglibdir";
+ @lib_opts = ($linkpath,"-lmysqlclient");
+ @lib_r_opts = ($linkpath,"-lmysqlclient_r");
+ @lib_e_opts = ($linkpath,"-lmysqld");
+}
+
+my $flags;
+$flags->{libs} =
+ [@ldflags,@lib_opts,'@ZLIB_DEPS@','@NON_THREADED_LIBS@','@openssl_libs@','@STATIC_NSS_FLAGS@'];
+$flags->{libs_r} =
+ [@ldflags,@lib_r_opts,'@ZLIB_DEPS@','@LIBS@','@openssl_libs@'];
+$flags->{embedded_libs} =
+ [@ldflags,@lib_e_opts,'@ZLIB_DEPS@','@LIBS@','@WRAPLIBS@','@innodb_system_libs@','@openssl_libs@'];
+
+$flags->{include} = ["-I$pkgincludedir"];
+$flags->{cflags} = [@{$flags->{include}},split(" ",'@CFLAGS@')];
+
+# ----------------------------------------------------------------------
+# Remove some options that a client doesn't have to care about
+# FIXME until we have a --cxxflags, we need to remove -Xa
+# and -xstrconst to make --cflags usable for Sun Forte C++
+# ----------------------------------------------------------------------
+
+my $filter = join("|", @exclude_cflags);
+my @tmp = @{$flags->{cflags}}; # Copy the flag list
+$flags->{cflags} = []; # Clear it
+foreach my $cflag ( @tmp )
+{
+ push(@{$flags->{cflags}}, $cflag) unless $cflag =~ m/^($filter)$/o;
+}
+
+# Same for --libs(_r)
+$filter = join("|", @exclude_libs);
+foreach my $lib_type ( "libs","libs_r","embedded_libs" )
+{
+ my @tmp = @{$flags->{$lib_type}}; # Copy the flag list
+ $flags->{$lib_type} = []; # Clear it
+ foreach my $lib ( @tmp )
+ {
+ push(@{$flags->{$lib_type}}, $lib) unless $lib =~ m/^($filter)$/o;
+ }
+}
+
+my $include = quote_options(@{$flags->{include}});
+my $cflags = quote_options(@{$flags->{cflags}});
+my $libs = quote_options(@{$flags->{libs}});
+my $libs_r = quote_options(@{$flags->{libs_r}});
+my $embedded_libs = quote_options(@{$flags->{embedded_libs}});
+
+##############################################################################
+#
+# Usage information, output if no option is given
+#
+##############################################################################
+
+sub usage
+{
+ print <<EOF;
+Usage: $0 [OPTIONS]
+Options:
+ --cflags [$cflags]
+ --include [$include]
+ --libs [$libs]
+ --libs_r [$libs_r]
+ --socket [$socket]
+ --port [$port]
+ --version [$version]
+ --libmysqld-libs [$embedded_libs]
+EOF
+ exit 1;
+}
+
+@ARGV or usage();
+
+##############################################################################
+#
+# Get options and output the values
+#
+##############################################################################
+
+GetOptions(
+ "cflags" => sub { print "$cflags\n" },
+ "include" => sub { print "$include\n" },
+ "libs" => sub { print "$libs\n" },
+ "libs_r" => sub { print "$libs_r\n" },
+ "socket" => sub { print "$socket\n" },
+ "port" => sub { print "$port\n" },
+ "version" => sub { print "$version\n" },
+ "embedded-libs|embedded|libmysqld-libs" =>
+ sub { print "$embedded_libs\n" },
+ ) or usage();
+
+exit 0
diff --git a/scripts/mysql_config.sh b/scripts/mysql_config.sh
index ae58655ed0f..915f623578d 100644
--- a/scripts/mysql_config.sh
+++ b/scripts/mysql_config.sh
@@ -107,16 +107,29 @@ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
libs_r=" $ldflags -L$pkglibdir -lmysqlclient_r @ZLIB_DEPS@ @LIBS@ @openssl_libs@ "
embedded_libs=" $ldflags -L$pkglibdir -lmysqld @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @innodb_system_libs@ @openssl_libs@ "
+if [ -r "$pkglibdir/libmygcc.a" ]; then
+ # When linking against the static library with a different version of GCC
+ # from what was used to compile the library, some symbols may not be defined
+ # automatically. We package the libmygcc.a from the build host, to provide
+ # definitions for those. Bugs 4921, 19561, 19817, 21158, etc.
+ libs="$libs -lmygcc "
+ libs_r="$libs_r -lmygcc "
+ embedded_libs="$embedded_libs -lmygcc "
+fi
+
cflags="-I$pkgincludedir @CFLAGS@ " #note: end space!
include="-I$pkgincludedir"
# Remove some options that a client doesn't have to care about
# FIXME until we have a --cxxflags, we need to remove -Xa
# and -xstrconst to make --cflags usable for Sun Forte C++
+# FIXME until we have a --cxxflags, we need to remove -AC99
+# to make --cflags usable for HP C++ (aCC)
for remove in DDBUG_OFF DSAFEMALLOC USAFEMALLOC DSAFE_MUTEX \
DPEDANTIC_SAFEMALLOC DUNIV_MUST_NOT_INLINE DFORCE_INIT_OF_VARS \
DEXTRA_DEBUG DHAVE_purify O 'O[0-9]' 'xO[0-9]' 'W[-A-Za-z]*' \
- Xa xstrconst "xc99=none" \
+ 'mtune=[-A-Za-z0-9]*' 'mcpu=[-A-Za-z0-9]*' 'march=[-A-Za-z0-9]*' \
+ Xa xstrconst "xc99=none" AC99 \
unroll2 ip mp restrict
do
# The first option we might strip will always have a space before it because
diff --git a/scripts/mysql_convert_table_format.sh b/scripts/mysql_convert_table_format.sh
index 0c9ce3a67e0..833b5bf5f11 100644
--- a/scripts/mysql_convert_table_format.sh
+++ b/scripts/mysql_convert_table_format.sh
@@ -1,4 +1,4 @@
-#!@PERL@
+#!/usr/bin/perl
# Copyright (C) 2000-2002 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
diff --git a/scripts/mysql_explain_log.sh b/scripts/mysql_explain_log.sh
index a549817db5a..30bee722873 100644
--- a/scripts/mysql_explain_log.sh
+++ b/scripts/mysql_explain_log.sh
@@ -1,4 +1,4 @@
-#!@PERL@
+#!/usr/bin/perl
# Copyright (C) 2001-2003, 2006 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
@@ -196,9 +196,10 @@ if (defined ($help)) {
elsif (m/^\s+(.+)$/ ) { # command could be some lines ...
#print "multi-lined ($1)\n";
my ($A)=$1;
- chomp $A;
- $Param->{Query} .= " $1";
- #print "multi-lined ($1)<<$Param->{Query}>>\n";
+ $A =~ s/\-\-.*//;
+
+ $Param->{Query} .= " $A";
+ #print "multi-lined ($A)<<$Param->{Query}>>\n";
}
diff --git a/scripts/mysql_install_db.pl.in b/scripts/mysql_install_db.pl.in
new file mode 100644
index 00000000000..18bd713c041
--- /dev/null
+++ b/scripts/mysql_install_db.pl.in
@@ -0,0 +1,612 @@
+#!/usr/bin/perl
+# -*- cperl -*-
+#
+# Copyright (C) 2007 MySQL AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+##############################################################################
+#
+# This scripts creates the MySQL Server system tables.
+#
+# This script try to match the shell script version as close as possible,
+# but in addition being compatible with ActiveState Perl on Windows.
+#
+# All unrecognized arguments to this script are passed to mysqld.
+#
+# NOTE: This script in 5.0 doesn't really match the shell script
+# version 100%, it is more close to the 5.1 version.
+#
+# NOTE: This script was deliberately written to be as close to the shell
+# script as possible, to make the maintenance of both in parallel
+# easier.
+#
+##############################################################################
+
+use File::Basename;
+use Getopt::Long;
+use Sys::Hostname;
+use Data::Dumper;
+use strict;
+
+Getopt::Long::Configure("pass_through");
+
+my @args; # Argument list filled in
+
+##############################################################################
+#
+# Usage information
+#
+##############################################################################
+
+sub usage
+{
+ print <<EOF;
+Usage: $0 [OPTIONS]
+ --basedir=path The path to the MySQL installation directory.
+ --builddir=path If using --srcdir with out-of-directory builds, you
+ will need to set this to the location of the build
+ directory where built files reside.
+ --cross-bootstrap For internal use. Used when building the MySQL system
+ tables on a different host than the target.
+ --datadir=path The path to the MySQL data directory.
+ --force Causes mysql_install_db to run even if DNS does not
+ work. In that case, grant table entries that normally
+ use hostnames will use IP addresses.
+ --ldata=path The path to the MySQL data directory. Same as --datadir.
+ --rpm For internal use. This option is used by RPM files
+ during the MySQL installation process.
+ --skip-name-resolve Use IP addresses rather than hostnames when creating
+ grant table entries. This option can be useful if
+ your DNS does not work.
+ --srcdir=path The path to the MySQL source directory. This option
+ uses the compiled binaries and support files within the
+ source tree, useful for if you don't want to install
+ MySQL yet and just want to create the system tables.
+ --user=user_name The login username to use for running mysqld. Files
+ and directories created by mysqld will be owned by this
+ user. You must be root to use this option. By default
+ mysqld runs using your current login name and files and
+ directories that it creates will be owned by you.
+
+All other options are passed to the mysqld program
+
+EOF
+ exit 1;
+}
+
+##############################################################################
+#
+# Parse an argument list
+#
+# We only need to pass arguments through to the server if we don't
+# handle them here. So, we collect unrecognized options (passed on
+# the command line) into the args variable.
+#
+##############################################################################
+
+sub parse_arguments
+{
+ my $opt = shift;
+
+ my @saved_ARGV = @ARGV;
+ @ARGV = @_; # Set ARGV so GetOptions works
+
+ my $pick_args;
+ if (@ARGV and $ARGV[0] eq 'PICK-ARGS-FROM-ARGV')
+ {
+ $pick_args = 1;
+ shift @ARGV;
+ }
+
+ GetOptions(
+ $opt,
+ "force",
+ "basedir=s",
+ "builddir=s", # FIXME not documented
+ "srcdir=s",
+ "ldata|datadir=s",
+
+ # Note that the user will be passed to mysqld so that it runs
+ # as 'user' (crucial e.g. if log-bin=/some_other_path/
+ # where a chown of datadir won't help)
+ "user=s",
+
+ "skip-name-resolve",
+ "verbose",
+ "rpm",
+ "help",
+ "defaults-file|defaults-extra-file|no-defaults:s",
+
+ # Used when building the MySQL system tables on a different host than
+ # the target. The platform-independent files that are created in
+ # --datadir on the host can be copied to the target system.
+ #
+ # The most common use for this feature is in the Windows installer
+ # which will take the files from datadir and include them as part of
+ # the install package. See top-level 'dist-hook' make target.
+ #
+ # --windows is a deprecated alias
+ "cross-bootstrap|windows", # FIXME undocumented, even needed?
+ ) or usage();
+
+ usage() if $opt->{help};
+
+ @args = @ARGV if $pick_args;
+
+ @ARGV = @saved_ARGV; # Set back ARGV
+}
+
+##############################################################################
+#
+# Try to find a specific file within --basedir which can either be a binary
+# release or installed source directory and return the path.
+#
+##############################################################################
+
+sub find_in_basedir
+{
+ my $opt = shift;
+ my $mode = shift; # "dir" or "file"
+ my $files = shift;
+
+ foreach my $file ( @{ref($files) ? $files : [$files]} )
+ {
+ foreach my $dir ( @_ )
+ {
+ foreach my $part ( "$file","$file.exe","release/$file.exe",
+ "debug/$file.exe","relwithdebinfo/$file.exe" )
+ {
+ my $path = "$opt->{basedir}/$dir/$part";
+ if ( -f $path )
+ {
+ return $mode eq "dir" ? dirname($path) : $path;
+ }
+ }
+ }
+ }
+}
+
+##############################################################################
+#
+# Just a function to write out an error report
+#
+##############################################################################
+
+sub cannot_find_file
+{
+ my $file = shift;
+
+ print "FATAL ERROR: Could not find $file\n";
+ print "\n";
+ print "If you compiled from source, you need to run 'make install' to\n";
+ print "copy the software into the correct location ready for operation.\n";
+ print "\n";
+ print "If you are using a binary release, you must either be at the top\n";
+ print "level of the extracted archive, or pass the --basedir option\n";
+ print "pointing to that location.\n";
+ print "\n";
+
+ exit 1;
+}
+
+##############################################################################
+#
+# Form a command line that can handle spaces in paths and arguments
+#
+##############################################################################
+
+# FIXME this backslash escaping needed if using '"..."' ?
+# This regexp makes sure that any special chars are quoted,
+# so the arg gets passed exactly to the server.
+# XXX: This is broken; true fix requires using eval and proper
+# quoting of every single arg ($opt->{basedir}, $opt->{ldata}, etc.)
+# join(" ", map {s/([^\w\_\.\-])/\\$1/g}
+
+sub quote_options {
+ my @cmd;
+ foreach my $opt ( @_ )
+ {
+ next unless $opt; # If undefined or empty, just skip
+ push(@cmd, "\"$opt\""); # Quote argument
+ }
+ return join(" ", @cmd);
+}
+
+##############################################################################
+#
+# Ok, let's go. We first need to parse arguments which are required by
+# my_print_defaults so that we can execute it first, then later re-parse
+# the command line to add any extra bits that we need.
+#
+##############################################################################
+
+my $opt = {};
+parse_arguments($opt, 'PICK-ARGS-FROM-ARGV', @ARGV);
+
+# ----------------------------------------------------------------------
+# We can now find my_print_defaults. This script supports:
+#
+# --srcdir=path pointing to compiled source tree
+# --basedir=path pointing to installed binary location
+#
+# or default to compiled-in locations.
+# ----------------------------------------------------------------------
+
+my $print_defaults;
+
+if ( $opt->{srcdir} and $opt->{basedir} )
+{
+ error("Specify either --basedir or --srcdir, not both");
+}
+if ( $opt->{srcdir} )
+{
+ $opt->{builddir} = $opt->{srcdir} unless $opt->{builddir};
+ $print_defaults = "$opt->{builddir}/extra/my_print_defaults";
+}
+elsif ( $opt->{basedir} )
+{
+ $print_defaults = find_in_basedir($opt,"file","my_print_defaults","bin","extra");
+}
+else
+{
+ $print_defaults='@bindir@/my_print_defaults';
+}
+
+-x $print_defaults or -f "$print_defaults.exe"
+ or cannot_find_file($print_defaults);
+
+# ----------------------------------------------------------------------
+# Now we can get arguments from the groups [mysqld] and [mysql_install_db]
+# in the my.cfg file, then re-run to merge with command line arguments.
+# ----------------------------------------------------------------------
+
+my @default_options;
+my $cmd = quote_options($print_defaults,$opt->{'defaults-file'},
+ "mysqld","mysql_install_db");
+open(PIPE, "$cmd |") or error($opt,"can't run $cmd: $!");
+while ( <PIPE> )
+{
+ chomp;
+ next unless /\S/;
+ push(@default_options, $_);
+}
+close PIPE;
+$opt = {}; # Reset the arguments FIXME ?
+parse_arguments($opt, @default_options);
+parse_arguments($opt, 'PICK-ARGS-FROM-ARGV', @ARGV);
+
+# ----------------------------------------------------------------------
+# Configure paths to support files
+# ----------------------------------------------------------------------
+
+# FIXME $extra_bindir is not used
+my ($bindir,$extra_bindir,$mysqld,$pkgdatadir,$mysqld_opt,$scriptdir);
+
+if ( $opt->{srcdir} )
+{
+ $opt->{basedir} = $opt->{builddir};
+ $bindir = "$opt->{basedir}/client";
+ $extra_bindir = "$opt->{basedir}/extra";
+ $mysqld = "$opt->{basedir}/sql/mysqld";
+ $mysqld_opt = "--language=$opt->{srcdir}/sql/share/english";
+ $pkgdatadir = "$opt->{srcdir}/scripts";
+ $scriptdir = "$opt->{srcdir}/scripts";
+}
+elsif ( $opt->{basedir} )
+{
+ $bindir = "$opt->{basedir}/bin";
+ $extra_bindir = $bindir;
+ $mysqld = find_in_basedir($opt,"file",["mysqld-nt","mysqld"],
+ "libexec","sbin","bin") || # ,"sql"
+ find_in_basedir($opt,"file","mysqld-nt",
+ "bin"); # ,"sql"
+ $pkgdatadir = find_in_basedir($opt,"dir","fill_help_tables.sql",
+ "share","share/mysql"); # ,"scripts"
+ $scriptdir = "$opt->{basedir}/scripts";
+}
+else
+{
+ $opt->{basedir} = '@prefix@';
+ $bindir = '@bindir@';
+ $extra_bindir = $bindir;
+ $mysqld = '@libexecdir@/mysqld';
+ $pkgdatadir = '@pkgdatadir@';
+ $scriptdir = '@scriptdir@';
+}
+
+unless ( $opt->{ldata} )
+{
+ $opt->{ldata} = '@localstatedir@';
+}
+
+if ( $opt->{srcdir} )
+{
+ $pkgdatadir = "$opt->{srcdir}/scripts";
+}
+
+# ----------------------------------------------------------------------
+# Set up paths to SQL scripts required for bootstrap
+# ----------------------------------------------------------------------
+
+my $fill_help_tables = "$pkgdatadir/fill_help_tables.sql";
+my $create_system_tables = "$pkgdatadir/mysql_system_tables.sql";
+my $fill_system_tables = "$pkgdatadir/mysql_system_tables_data.sql";
+
+foreach my $f ( $fill_help_tables,$create_system_tables,$fill_system_tables )
+{
+ -f $f or cannot_find_file($f);
+}
+
+-x $mysqld or -f "$mysqld.exe" or cannot_find_file($mysqld);
+# Try to determine the hostname
+my $hostname = hostname();
+
+# ----------------------------------------------------------------------
+# Check if hostname is valid
+# ----------------------------------------------------------------------
+
+my $resolved;
+if ( !$opt->{'cross-bootstrap'} and !$opt->{rpm} and !$opt->{force} )
+{
+ my $resolveip;
+
+ $resolved = `$resolveip $hostname 2>&1`;
+ if ( $? != 0 )
+ {
+ $resolved=`$resolveip localhost 2>&1`;
+ if ( $? != 0 )
+ {
+ error($opt,
+ "Neither host '$hostname' nor 'localhost' could be looked up with",
+ "$bindir/resolveip",
+ "Please configure the 'hostname' command to return a correct",
+ "hostname.",
+ "If you want to solve this at a later stage, restart this script",
+ "with the --force option");
+ }
+ warning($opt,
+ "The host '$hostname' could not be looked up with resolveip.",
+ "This probably means that your libc libraries are not 100 % compatible",
+ "with this binary MySQL version. The MySQL daemon, mysqld, should work",
+ "normally with the exception that host name resolving will not work.",
+ "This means that you should use IP addresses instead of hostnames",
+ "when specifying MySQL privileges !");
+ }
+}
+
+# FIXME what does this really mean....
+if ( $opt->{'skip-name-resolve'} and $resolved and $resolved =~ /\s/ )
+{
+ $hostname = (split(' ', $resolved))[5];
+}
+
+# ----------------------------------------------------------------------
+# Create database directories mysql & test
+# ----------------------------------------------------------------------
+
+foreach my $dir ( $opt->{ldata}, "$opt->{ldata}/mysql", "$opt->{ldata}/test" )
+{
+ # FIXME not really the same as original "mkdir -p", but ok?
+ mkdir($dir, 0700) unless -d $dir;
+ chown($opt->{user}, $dir) if -w "/" and !$opt->{user};
+}
+
+push(@args, "--user=$opt->{user}") if $opt->{user};
+
+# ----------------------------------------------------------------------
+# Configure mysqld command line
+# ----------------------------------------------------------------------
+
+# FIXME use --init-file instead of --bootstrap ?!
+
+my $mysqld_bootstrap = $ENV{MYSQLD_BOOTSTRAP} || $mysqld;
+my $mysqld_install_cmd_line = quote_options($mysqld_bootstrap,
+ $opt->{'defaults-file'},
+ $mysqld_opt,
+ "--bootstrap",
+ "--basedir=$opt->{basedir}",
+ "--datadir=$opt->{ldata}",
+ "--skip-innodb",
+ "--skip-bdb",
+ "--skip-ndbcluster",
+ "--max_allowed_packet=8M",
+ "--net_buffer_length=16K",
+ @args,
+ );
+
+# ----------------------------------------------------------------------
+# Create the system and help tables by passing them to "mysqld --bootstrap"
+# ----------------------------------------------------------------------
+
+report_verbose_wait($opt,"Installing MySQL system tables...");
+
+open(SQL, $create_system_tables)
+ or error($opt,"can't open $create_system_tables for reading: $!");
+# FIXME > /dev/null ?
+if ( open(PIPE, "| $mysqld_install_cmd_line") )
+{
+ print PIPE "use mysql;\n";
+ while ( <SQL> )
+ {
+ # When doing a "cross bootstrap" install, no reference to the current
+ # host should be added to the system tables. So we filter out any
+ # lines which contain the current host name.
+ next if $opt->{'cross-bootstrap'} and /\@current_hostname/;
+
+ print PIPE $_;
+ }
+ close PIPE;
+ close SQL;
+
+ report_verbose($opt,"OK");
+
+ # ----------------------------------------------------------------------
+ # Pipe fill_help_tables.sql to "mysqld --bootstrap"
+ # ----------------------------------------------------------------------
+
+ report_verbose_wait($opt,"Filling help tables...");
+ open(SQL, $fill_help_tables)
+ or error($opt,"can't open $fill_help_tables for reading: $!");
+ # FIXME > /dev/null ?
+ if ( open(PIPE, "| $mysqld_install_cmd_line") )
+ {
+ print PIPE "use mysql;\n";
+ while ( <SQL> )
+ {
+ print PIPE $_;
+ }
+ close PIPE;
+ close SQL;
+
+ report_verbose($opt,"OK");
+ }
+ else
+ {
+ warning($opt,"HELP FILES ARE NOT COMPLETELY INSTALLED!",
+ "The \"HELP\" command might not work properly");
+ }
+
+ report_verbose($opt,"To start mysqld at boot time you have to copy",
+ "support-files/mysql.server to the right place " .
+ "for your system");
+
+ if ( !$opt->{'cross-bootstrap'} )
+ {
+ # This is not a true installation on a running system. The end user must
+ # set a password after installing the data files on the real host system.
+ # At this point, there is no end user, so it does not make sense to print
+ # this reminder.
+ report($opt,
+ "PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !",
+ "To do so, start the server, then issue the following commands:",
+ "",
+ " $bindir/mysqladmin -u root password 'new-password'",
+ " $bindir/mysqladmin -u root -h $hostname password 'new-password'",
+ "",
+ "Alternatively you can run:",
+ "",
+ " $bindir/mysql_secure_installation",
+ "",
+ "which will also give you the option of removing the test",
+ "databases and anonymous user created by default. This is",
+ "strongly recommended for production servers.",
+ "",
+ "See the manual for more instructions.");
+
+ if ( !$opt->{rpm} )
+ {
+ report($opt,
+ "You can start the MySQL daemon with:",
+ "",
+ " cd " . '@prefix@' . " ; $bindir/mysqld_safe &",
+ "",
+ "You can test the MySQL daemon with mysql-test-run.pl",
+ "",
+ " cd mysql-test ; perl mysql-test-run.pl");
+ }
+ report($opt,
+ "Please report any problems with the " . '@scriptdir@' . "/mysqlbug script!",
+ "",
+ "The latest information about MySQL is available on the web at",
+ "",
+ " http://www.mysql.com",
+ "",
+ "Support MySQL by buying support/licenses at http://shop.mysql.com");
+ }
+ exit 0
+}
+else
+{
+ error($opt,
+ "Installation of system tables failed!",
+ "",
+ "Examine the logs in $opt->{ldata} for more information.",
+ "You can try to start the mysqld daemon with:",
+ "$mysqld --skip-grant &",
+ "and use the command line tool",
+ "$bindir/mysql to connect to the mysql",
+ "database and look at the grant tables:",
+ "",
+ "shell> $bindir/mysql -u root mysql",
+ "mysql> show tables",
+ "",
+ "Try 'mysqld --help' if you have problems with paths. Using --log",
+ "gives you a log in $opt->{ldata} that may be helpful.",
+ "",
+ "The latest information about MySQL is available on the web at",
+ "http://www.mysql.com",
+ "Please consult the MySQL manual section: 'Problems running mysql_install_db',",
+ "and the manual section that describes problems on your OS.",
+ "Another information source is the MySQL email archive.",
+ "Please check all of the above before mailing us!",
+ "And if you do mail us, you MUST use the " . '@scriptdir@' . "/mysqlbug script!")
+}
+
+##############################################################################
+#
+# Misc
+#
+##############################################################################
+
+sub report_verbose
+{
+ my $opt = shift;
+ my $text = shift;
+
+ report_verbose_wait($opt, $text, @_);
+ print "\n\n";
+}
+
+sub report_verbose_wait
+{
+ my $opt = shift;
+ my $text = shift;
+
+ if ( $opt->{verbose} or (!$opt->{rpm} and !$opt->{'cross-bootstrap'}) )
+ {
+ print "$text";
+ map {print "\n$_"} @_;
+ }
+}
+
+sub report
+{
+ my $opt = shift;
+ my $text = shift;
+
+ print "$text\n";
+ map {print "$_\n"} @_;
+ print "\n";
+}
+
+sub error
+{
+ my $opt = shift;
+ my $text = shift;
+
+ print "FATAL ERROR: $text\n";
+ map {print "$_\n"} @_;
+ exit 1;
+}
+
+sub warning
+{
+ my $opt = shift;
+ my $text = shift;
+
+ print "WARNING: $text\n";
+ map {print "$_\n"} @_;
+ print "\n";
+}
diff --git a/scripts/mysql_secure_installation.pl.in b/scripts/mysql_secure_installation.pl.in
new file mode 100755
index 00000000000..4eeb50e6d2f
--- /dev/null
+++ b/scripts/mysql_secure_installation.pl.in
@@ -0,0 +1,352 @@
+#!/usr/bin/perl
+# -*- cperl -*-
+#
+# Copyright (C) 2002 MySQL AB and Jeremy Cole
+#
+# 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
+
+use Fcntl;
+use strict;
+
+my $config = ".my.cnf.$$";
+my $command = ".mysql.$$";
+my $hadpass = 0;
+
+# FIXME
+# trap "interrupt" 2
+
+my $rootpass = "";
+
+sub echo_on {
+ if ($^O eq 'MSWin32') {
+ ReadMode('normal');
+ } else {
+ system("stty echo");
+ }
+}
+
+sub echo_off {
+ if ($^O eq 'MSWin32') {
+ ReadMode('noecho');
+ } else {
+ system("stty -echo");
+ }
+}
+
+sub write_file {
+ my $file = shift;
+ -f $file or die "ERROR: file is missing \"$file\": $!";
+ open(FILE, ">$file") or die "ERROR: can't write to file \"$file\": $!";
+ foreach my $line ( @_ ) {
+ print FILE $line, "\n"; # Add EOL char
+ }
+ close FILE;
+}
+
+sub prepare {
+ foreach my $file ( $config, $command ) {
+ next if -f $file; # Already exists
+ local *FILE;
+ sysopen(FILE, $file, O_CREAT, 0600)
+ or die "ERROR: can't create $file: $!";
+ close FILE;
+ }
+}
+
+sub do_query {
+ my $query = shift;
+ write_file($command, $query);
+ system("mysql --defaults-file=$config < $command");
+ return $?;
+}
+
+sub make_config {
+ my $password = shift;
+
+ write_file($config,
+ "# mysql_secure_installation config file",
+ "[mysql]",
+ "user=root",
+ "password=$rootpass");
+}
+
+sub get_root_password {
+ my $status = 1;
+ while ( $status == 1 ) {
+ echo_off();
+ print "Enter current password for root (enter for none): ";
+ my $password = <STDIN>;
+ echo_on();
+ if ( $password ) {
+ $hadpass = 1;
+ } else {
+ $hadpass = 0;
+ }
+ $rootpass = $password;
+ make_config($rootpass);
+ do_query("");
+ $status = $?;
+ }
+ print "OK, successfully used password, moving on...\n\n";
+}
+
+sub set_root_password {
+ echo_off();
+ print "New password: ";
+ my $password1 = <STDIN>;
+ print "\nRe-enter new password: ";
+ my $password2 = <STDIN>;
+ print "\n";
+ echo_on();
+
+ if ( $password1 eq $password2 ) {
+ print "Sorry, passwords do not match.\n\n";
+ return 1;
+ }
+
+ if ( !$password1 ) {
+ print "Sorry, you can't use an empty password here.\n\n";
+ return 1;
+ }
+
+ do_query("UPDATE mysql.user SET Password=PASSWORD('$password1') WHERE User='root';");
+ if ( $? == 0 ) {
+ print "Password updated successfully!\n";
+ print "Reloading privilege tables..\n";
+ if ( !reload_privilege_tables() ) {
+ exit 1;
+ }
+ print "\n";
+ $rootpass = $password1;
+ make_config($rootpass);
+ } else {
+ print "Password update failed!\n";
+ exit 1;
+ }
+
+ return 0;
+}
+
+sub remove_anonymous_users {
+ do_query("DELETE FROM mysql.user WHERE User='';");
+ if ( $? == 0 ) {
+ print " ... Success!\n";
+ } else {
+ print " ... Failed!\n";
+ exit 1;
+ }
+
+ return 0;
+}
+
+sub remove_remote_root {
+ do_query("DELETE FROM mysql.user WHERE User='root' AND Host!='localhost';");
+ if ( $? == 0 ) {
+ print " ... Success!\n";
+ } else {
+ print " ... Failed!\n";
+ }
+}
+
+sub remove_test_database {
+ print " - Dropping test database...\n";
+ do_query("DROP DATABASE test;");
+ if ( $? == 0 ) {
+ print " ... Success!\n";
+ } else {
+ print " ... Failed! Not critical, keep moving...\n";
+ }
+
+ print " - Removing privileges on test database...\n";
+ do_query("DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'");
+ if ( $? == 0 ) {
+ print " ... Success!\n";
+ } else {
+ print " ... Failed! Not critical, keep moving...\n";
+ }
+
+ return 0;
+}
+
+sub reload_privilege_tables {
+ do_query("FLUSH PRIVILEGES;");
+ if ( $? == 0 ) {
+ print " ... Success!\n";
+ return 0;
+ } else {
+ print " ... Failed!\n";
+ return 1;
+ }
+}
+
+sub interrupt {
+ print "\nAborting!\n\n";
+ cleanup();
+ echo_on();
+ exit 1;
+}
+
+sub cleanup {
+ print "Cleaning up...\n";
+ unlink($config,$command);
+}
+
+
+# The actual script starts here
+
+prepare();
+
+print <<HERE;
+
+
+
+NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
+ SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!
+
+In order to log into MySQL to secure it, we'll need the current
+password for the root user. If you've just installed MySQL, and
+you haven't set the root password yet, the password will be blank,
+so you should just press enter here.
+
+HERE
+
+get_root_password();
+
+
+#
+# Set the root password
+#
+
+print "Setting the root password ensures that nobody can log into the MySQL\n";
+print "root user without the proper authorisation.\n\n";
+
+if ( $hadpass == 0 ) {
+ print "Set root password? [Y/n] ";
+} else {
+ print "You already have a root password set, so you can safely answer 'n'.\n\n";
+ print "Change the root password? [Y/n] ";
+}
+
+my $reply = <STDIN>;
+if ( $reply =~ /n/i ) {
+ print " ... skipping.\n";
+} else {
+ my $status = 1;
+ while ( $status == 1 ) {
+ set_root_password();
+ $status = $?;
+ }
+}
+print "\n";
+
+
+#
+# Remove anonymous users
+#
+
+print <<HERE;
+By default, a MySQL installation has an anonymous user, allowing anyone
+to log into MySQL without having to have a user account created for
+them. This is intended only for testing, and to make the installation
+go a bit smoother. You should remove them before moving into a
+production environment.
+
+HERE
+
+print "Remove anonymous users? [Y/n] ";
+$reply = <STDIN>;
+if ( $reply =~ /n/i ) {
+ print " ... skipping.\n";
+} else {
+ remove_anonymous_users();
+}
+print "\n";
+
+
+#
+# Disallow remote root login
+#
+
+print <<HERE;
+Normally, root should only be allowed to connect from 'localhost'. This
+ensures that someone cannot guess at the root password from the network.
+
+HERE
+
+print "Disallow root login remotely? [Y/n] ";
+$reply = <STDIN>;
+if ( $reply =~ /n/i ) {
+ print " ... skipping.\n";
+} else {
+ remove_remote_root();
+}
+print "\n";
+
+
+#
+# Remove test database
+#
+
+print <<HERE;
+By default, MySQL comes with a database named 'test' that anyone can
+access. This is also intended only for testing, and should be removed
+before moving into a production environment.
+
+HERE
+
+print "Remove test database and access to it? [Y/n] ";
+$reply = <STDIN>;
+if ( $reply =~ /n/i ) {
+ print " ... skipping.\n";
+} else {
+ remove_test_database();
+}
+print "\n";
+
+
+#
+# Reload privilege tables
+#
+
+print <<HERE;
+Reloading the privilege tables will ensure that all changes made so far
+will take effect immediately.
+
+HERE
+
+print "Reload privilege tables now? [Y/n] ";
+$reply = <STDIN>;
+if ( $reply =~ /n/i ) {
+ print " ... skipping.\n";
+} else {
+ reload_privilege_tables();
+}
+print "\n";
+
+cleanup();
+
+print <<HERE;
+
+
+
+All done! If you've completed all of the above steps, your MySQL
+installation should now be secure.
+
+Thanks for using MySQL!
+
+
+HERE
+
+
+
diff --git a/scripts/mysql_tableinfo.sh b/scripts/mysql_tableinfo.sh
index 2ed7e381fa3..c90c410ca78 100644
--- a/scripts/mysql_tableinfo.sh
+++ b/scripts/mysql_tableinfo.sh
@@ -1,4 +1,4 @@
-#!@PERL@ -w
+#!/usr/bin/perl
use strict;
use Getopt::Long;
diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh
index 92cfbe3ef22..3cb4665eb1c 100644
--- a/scripts/mysqld_multi.sh
+++ b/scripts/mysqld_multi.sh
@@ -1,4 +1,4 @@
-#!@PERL@
+#!/usr/bin/perl
use Getopt::Long;
use POSIX qw(strftime);
diff --git a/scripts/mysqldumpslow.sh b/scripts/mysqldumpslow.sh
index ff82a35ec3f..f05761bb837 100644
--- a/scripts/mysqldumpslow.sh
+++ b/scripts/mysqldumpslow.sh
@@ -1,4 +1,4 @@
-#!@PERL@
+#!/usr/bin/perl
# mysqldumpslow - parse and summarize the MySQL slow query log
# Original version by Tim Bunce, sometime in 2000.
diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh
index 6ad5c77b954..8814e36b2fa 100644
--- a/scripts/mysqlhotcopy.sh
+++ b/scripts/mysqlhotcopy.sh
@@ -1,4 +1,4 @@
-#!@PERL@ -w
+#!/usr/bin/perl
use strict;
use Getopt::Long;
@@ -39,7 +39,7 @@ WARNING: THIS PROGRAM IS STILL IN BETA. Comments/patches welcome.
# Documentation continued at end of file
-my $VERSION = "1.22";
+my $VERSION = "1.23";
my $opt_tmpdir = $ENV{TMPDIR} || "/tmp";
@@ -132,7 +132,6 @@ GetOptions( \%opt,
# 'target' - destination directory of the copy
# 'tables' - array-ref to list of tables in the db
# 'files' - array-ref to list of files to be copied
-# (RAID files look like 'nn/name.MYD')
# 'index' - array-ref to list of indexes to be copied
#
@@ -263,7 +262,6 @@ my $hc_locks = "";
my $hc_tables = "";
my $num_tables = 0;
my $num_files = 0;
-my $raid_dir_regex = '[A-Za-z0-9]{2}';
foreach my $rdb ( @db_desc ) {
my $db = $rdb->{src};
@@ -292,20 +290,12 @@ foreach my $rdb ( @db_desc ) {
or die "Cannot open dir '$db_dir': $!";
my %db_files;
- my @raid_dir = ();
while ( defined( my $name = readdir DBDIR ) ) {
- if ( $name =~ /^$raid_dir_regex$/ && -d "$db_dir/$name" ) {
- push @raid_dir, $name;
- }
- else {
- $db_files{$name} = $1 if ( $name =~ /(.+)\.\w+$/ );
- }
+ $db_files{$name} = $1 if ( $name =~ /(.+)\.\w+$/ );
}
closedir( DBDIR );
- scan_raid_dir( \%db_files, $db_dir, @raid_dir );
-
unless( keys %db_files ) {
warn "'$db' is an empty database\n";
}
@@ -336,8 +326,6 @@ foreach my $rdb ( @db_desc ) {
my @hc_tables = map { quote_names("$db.$_") } @dbh_tables;
$rdb->{tables} = [ @hc_tables ];
- $rdb->{raid_dirs} = [ get_raid_dirs( $rdb->{files} ) ];
-
$hc_locks .= ", " if ( length $hc_locks && @hc_tables );
$hc_locks .= join ", ", map { "$_ READ" } @hc_tables;
$hc_tables .= ", " if ( length $hc_tables && @hc_tables );
@@ -411,27 +399,24 @@ if ($opt{method} =~ /^cp\b/)
retire_directory( @existing ) if @existing && !$opt{addtodest};
foreach my $rdb ( @db_desc ) {
- foreach my $td ( '', @{$rdb->{raid_dirs}} ) {
-
- my $tgt_dirpath = "$rdb->{target}/$td";
- # Remove trailing slashes (needed for Mac OS X)
- substr($tgt_dirpath, 1) =~ s|/+$||;
- if ( $opt{dryrun} ) {
- print "mkdir $tgt_dirpath, 0750\n";
- }
- elsif ($opt{method} =~ /^scp\b/) {
- ## assume it's there?
- ## ...
- }
- else {
- mkdir($tgt_dirpath, 0750) or die "Can't create '$tgt_dirpath': $!\n"
- unless -d $tgt_dirpath;
- if ($^O !~ m/^(NetWare)$/)
- {
- my @f_info= stat "$datadir/$rdb->{src}";
- chown $f_info[4], $f_info[5], $tgt_dirpath;
- }
- }
+ my $tgt_dirpath = "$rdb->{target}";
+ # Remove trailing slashes (needed for Mac OS X)
+ substr($tgt_dirpath, 1) =~ s|/+$||;
+ if ( $opt{dryrun} ) {
+ print "mkdir $tgt_dirpath, 0750\n";
+ }
+ elsif ($opt{method} =~ /^scp\b/) {
+ ## assume it's there?
+ ## ...
+ }
+ else {
+ mkdir($tgt_dirpath, 0750) or die "Can't create '$tgt_dirpath': $!\n"
+ unless -d $tgt_dirpath;
+ if ($^O !~ m/^(NetWare)$/)
+ {
+ my @f_info= stat "$datadir/$rdb->{src}";
+ chown $f_info[4], $f_info[5], $tgt_dirpath;
+ }
}
}
@@ -489,7 +474,7 @@ foreach my $rdb ( @db_desc )
my @files = map { "$datadir/$rdb->{src}/$_" } @{$rdb->{files}};
next unless @files;
- eval { copy_files($opt{method}, \@files, $rdb->{target}, $rdb->{raid_dirs} ); };
+ eval { copy_files($opt{method}, \@files, $rdb->{target}); };
push @failed, "$rdb->{src} -> $rdb->{target} failed: $@"
if ( $@ );
@@ -582,7 +567,7 @@ exit 0;
# ---
sub copy_files {
- my ($method, $files, $target, $raid_dirs) = @_;
+ my ($method, $files, $target) = @_;
my @cmd;
print "Copying ".@$files." files...\n" unless $opt{quiet};
@@ -603,15 +588,8 @@ sub copy_files {
# add recursive option for scp
$cp.= " -r" if $^O =~ /m^(solaris|linux|freebsd|darwin)$/ && $method =~ /^scp\b/;
- my @non_raid = map { "'$_'" } grep { ! m:/$raid_dir_regex/[^/]+$: } @$files;
-
- # add files to copy and the destination directory
- safe_system( $cp, @non_raid, "'$target'" ) if (@non_raid);
-
- foreach my $rd ( @$raid_dirs ) {
- my @raid = map { "'$_'" } grep { m:$rd/: } @$files;
- safe_system( $cp, @raid, "'$target'/$rd" ) if ( @raid );
- }
+ # perform the actual copy
+ safe_system( $cp, (map { "'$_'" } @$files), "'$target'" );
}
else
{
@@ -789,35 +767,6 @@ sub get_row_hash {
return $sth->fetchrow_hashref();
}
-sub scan_raid_dir {
- my ( $r_db_files, $data_dir, @raid_dir ) = @_;
-
- local(*RAID_DIR);
-
- foreach my $rd ( @raid_dir ) {
-
- opendir(RAID_DIR, "$data_dir/$rd" )
- or die "Cannot open dir '$data_dir/$rd': $!";
-
- while ( defined( my $name = readdir RAID_DIR ) ) {
- $r_db_files->{"$rd/$name"} = $1 if ( $name =~ /(.+)\.\w+$/ );
- }
- closedir( RAID_DIR );
- }
-}
-
-sub get_raid_dirs {
- my ( $r_files ) = @_;
-
- my %dirs = ();
- foreach my $f ( @$r_files ) {
- if ( $f =~ m:^($raid_dir_regex)/: ) {
- $dirs{$1} = 1;
- }
- }
- return sort keys %dirs;
-}
-
sub get_list_of_tables {
my ( $db ) = @_;
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 84b042a91b1..9ea9874c1b1 100755
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -48,7 +48,7 @@ ENDIF(DISABLE_GRANT_OPTIONS)
ADD_EXECUTABLE(mysqld${MYSQLD_EXE_SUFFIX}
../sql-common/client.c derror.cc des_key_file.cc
- discover.cc ../libmysql/errmsg.c field.cc field_conv.cc
+ discover.cc ../libmysql/errmsg.c field.cc stacktrace.c stacktrace.h field_conv.cc
filesort.cc gstream.cc ha_blackhole.cc
ha_archive.cc ha_heap.cc ha_myisam.cc ha_myisammrg.cc
ha_innodb.cc ha_federated.cc ha_berkeley.cc
diff --git a/sql/field.cc b/sql/field.cc
index f1e2b6a4f27..53eafcaf2cc 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5861,26 +5861,41 @@ check_string_copy_error(Field_str *field,
}
-
/*
- Send a truncation warning or a truncation error
- after storing a too long character string info a field.
+ Check if we lost any important data and send a truncation error/warning
SYNOPSIS
- report_data_too_long()
- field - Field
+ Field_longstr::report_if_important_data()
+ ptr - Truncated rest of string
+ end - End of truncated string
- RETURN
- N/A
+ RETURN VALUES
+ 0 - None was truncated (or we don't count cut fields)
+ 2 - Some bytes was truncated
+
+ NOTE
+ Check if we lost any important data (anything in a binary string,
+ or any non-space in others). If only trailing spaces was lost,
+ send a truncation note, otherwise send a truncation error.
*/
-inline void
-report_data_too_long(Field_str *field)
+int
+Field_longstr::report_if_important_data(const char *ptr, const char *end)
{
- if (field->table->in_use->abort_on_warning)
- field->set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
- else
- field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
+ if ((ptr < end) && table->in_use->count_cuted_fields)
+ {
+ if (test_if_important_data(field_charset, ptr, end))
+ {
+ if (table->in_use->abort_on_warning)
+ set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
+ else
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
+ }
+ else /* If we lost only spaces then produce a NOTE, not a WARNING */
+ set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
+ return 2;
+ }
+ return 0;
}
@@ -5914,19 +5929,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
cannot_convert_error_pos, from + length))
return 2;
- /*
- Check if we lost any important data (anything in a binary string,
- or any non-space in others).
- */
- if ((from_end_pos < from + length) && table->in_use->count_cuted_fields)
- {
- if (test_if_important_data(field_charset, from_end_pos, from + length))
- {
- report_data_too_long(this);
- return 2;
- }
- }
- return 0;
+ return report_if_important_data(from_end_pos, from + length);
}
@@ -6385,16 +6388,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
cannot_convert_error_pos, from + length))
return 2;
- // Check if we lost something other than just trailing spaces
- if ((from_end_pos < from + length) && table->in_use->count_cuted_fields)
- {
- if (test_if_important_data(field_charset, from_end_pos, from + length))
- report_data_too_long(this);
- else /* If we lost only spaces then produce a NOTE, not a WARNING */
- set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
- return 2;
- }
- return 0;
+ return report_if_important_data(from_end_pos, from + length);
}
@@ -7030,13 +7024,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
cannot_convert_error_pos, from + length))
return 2;
- if (from_end_pos < from + length)
- {
- report_data_too_long(this);
- return 2;
- }
-
- return 0;
+ return report_if_important_data(from_end_pos, from + length);
oom_error:
/* Fatal OOM error */
@@ -7883,10 +7871,10 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
int Field_set::store(longlong nr, bool unsigned_val)
{
int error= 0;
- if ((ulonglong) nr > (ulonglong) (((longlong) 1 << typelib->count) -
- (longlong) 1))
+ ulonglong max_nr= set_bits(ulonglong, typelib->count);
+ if ((ulonglong) nr > max_nr)
{
- nr&= (longlong) (((longlong) 1 << typelib->count) - (longlong) 1);
+ nr&= max_nr;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
error=1;
}
diff --git a/sql/field.h b/sql/field.h
index d681229a9fd..c82d65147ac 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -454,6 +454,8 @@ public:
class Field_longstr :public Field_str
{
+protected:
+ int report_if_important_data(const char *ptr, const char *end);
public:
Field_longstr(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg,
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 43b079e83d5..70fc6937b59 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -112,6 +112,13 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
FILESORT_INFO table_sort;
TABLE_LIST *tab= table->pos_in_table_list;
Item_subselect *subselect= tab ? tab->containing_subselect() : 0;
+
+ /*
+ Release InnoDB's adaptive hash index latch (if holding) before
+ running a sort.
+ */
+ ha_release_temporary_latches(thd);
+
/*
Don't use table->sort in filesort as it is also used by
QUICK_INDEX_MERGE_SELECT. Work with a copy and put it back at the end
@@ -215,8 +222,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
sort_keys= table_sort.sort_keys;
if (memavl < min_sort_memory)
{
- my_error(ER_OUTOFMEMORY,MYF(ME_ERROR+ME_WAITTANG),
- thd->variables.sortbuff_size);
+ my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERROR+ME_WAITTANG));
goto err;
}
if (open_cached_file(&buffpek_pointers,mysql_tmpdir,TEMP_PREFIX,
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index fa68da87661..2d2007c8fdd 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -6339,7 +6339,9 @@ void
innodb_export_status(void)
/*======================*/
{
- srv_export_innodb_status();
+ if (innodb_inited) {
+ srv_export_innodb_status();
+ }
}
/****************************************************************************
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index c93091e36d2..e3ab2b67e26 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -439,7 +439,8 @@ void ha_ndbcluster::no_uncommitted_rows_reset(THD *thd)
void ha_ndbcluster::invalidate_dictionary_cache(bool global)
{
- NDBDICT *dict= get_ndb()->getDictionary();
+ Ndb * ndb= get_ndb();
+ NDBDICT *dict= ndb->getDictionary();
DBUG_ENTER("invalidate_dictionary_cache");
DBUG_PRINT("info", ("invalidating %s", m_tabname));
@@ -459,6 +460,7 @@ void ha_ndbcluster::invalidate_dictionary_cache(bool global)
}
else
dict->removeCachedTable(m_tabname);
+ build_index_list(ndb, table, ILBP_OPEN);
table->s->version=0L; /* Free when thread is ready */
/* Invalidate indexes */
for (uint i= 0; i < table->s->keys; i++)
@@ -470,17 +472,23 @@ void ha_ndbcluster::invalidate_dictionary_cache(bool global)
switch (idx_type) {
case PRIMARY_KEY_ORDERED_INDEX:
case ORDERED_INDEX:
+ if (!index)
+ break;
if (global)
dict->invalidateIndex(index->getName(), m_tabname);
else
dict->removeCachedIndex(index->getName(), m_tabname);
break;
case UNIQUE_ORDERED_INDEX:
+ if (!index)
+ break;
if (global)
dict->invalidateIndex(index->getName(), m_tabname);
else
dict->removeCachedIndex(index->getName(), m_tabname);
case UNIQUE_INDEX:
+ if (!unique_index)
+ break;
if (global)
dict->invalidateIndex(unique_index->getName(), m_tabname);
else
diff --git a/sql/ha_ndbcluster_cond.cc b/sql/ha_ndbcluster_cond.cc
index c7b185a92f0..f5b41959b40 100644
--- a/sql/ha_ndbcluster_cond.cc
+++ b/sql/ha_ndbcluster_cond.cc
@@ -117,7 +117,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
if (item->type() == Item::FUNC_ITEM)
{
Item_func *func_item= (Item_func *) item;
- if (func_item->functype() == Item_func::UNKNOWN_FUNC &&
+ if ((func_item->functype() == Item_func::UNKNOWN_FUNC ||
+ func_item->functype() == Item_func::NEG_FUNC) &&
func_item->const_item())
{
// Skip any arguments since we will evaluate function instead
@@ -369,8 +370,9 @@ void ndb_serialize_cond(const Item *item, void *arg)
{
Item_func *func_item= (Item_func *) item;
// Check that we expect a function or functional expression here
- if (context->expecting(Item::FUNC_ITEM) ||
- func_item->functype() == Item_func::UNKNOWN_FUNC)
+ if (context->expecting(Item::FUNC_ITEM) ||
+ func_item->functype() == Item_func::UNKNOWN_FUNC ||
+ func_item->functype() == Item_func::NEG_FUNC)
context->expect_nothing();
else
{
@@ -584,6 +586,7 @@ void ndb_serialize_cond(const Item *item, void *arg)
context->expect(Item::FUNC_ITEM);
break;
}
+ case Item_func::NEG_FUNC:
case Item_func::UNKNOWN_FUNC:
{
DBUG_PRINT("info", ("UNKNOWN_FUNC %s",
diff --git a/sql/ha_ndbcluster_cond.h b/sql/ha_ndbcluster_cond.h
index 6baf6945b58..6504df8d9d4 100644
--- a/sql/ha_ndbcluster_cond.h
+++ b/sql/ha_ndbcluster_cond.h
@@ -228,6 +228,7 @@ public:
case (Item_func::ISNOTNULL_FUNC): { return NDB_ISNOTNULL_FUNC; }
case (Item_func::LIKE_FUNC): { return NDB_LIKE_FUNC; }
case (Item_func::NOT_FUNC): { return NDB_NOT_FUNC; }
+ case (Item_func::NEG_FUNC): { return NDB_UNKNOWN_FUNC; }
case (Item_func::UNKNOWN_FUNC): { return NDB_UNKNOWN_FUNC; }
case (Item_func::COND_AND_FUNC): { return NDB_COND_AND_FUNC; }
case (Item_func::COND_OR_FUNC): { return NDB_COND_OR_FUNC; }
diff --git a/sql/handler.cc b/sql/handler.cc
index 27204ae725b..bfad10f986f 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1381,6 +1381,13 @@ int ha_delete_table(THD *thd, enum db_type table_type, const char *path,
handler *handler::clone(MEM_ROOT *mem_root)
{
handler *new_handler= get_new_handler(table, mem_root, table->s->db_type);
+ /*
+ Allocate handler->ref here because otherwise ha_open will allocate it
+ on this->table->mem_root and we will not be able to reclaim that memory
+ when the clone handler object is destroyed.
+ */
+ if (!(new_handler->ref= (byte*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
+ return NULL;
if (new_handler && !new_handler->ha_open(table->s->path, table->db_stat,
HA_OPEN_IGNORE_IF_LOCKED))
return new_handler;
@@ -1420,8 +1427,9 @@ int handler::ha_open(const char *name, int mode, int test_if_locked)
(void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
DBUG_ASSERT(alloc_root_inited(&table->mem_root));
-
- if (!(ref= (byte*) alloc_root(&table->mem_root, ALIGN_SIZE(ref_length)*2)))
+ /* ref is already allocated for us if we're called from handler::clone() */
+ if (!ref && !(ref= (byte*) alloc_root(&table->mem_root,
+ ALIGN_SIZE(ref_length)*2)))
{
close();
error=HA_ERR_OUT_OF_MEM;
diff --git a/sql/item.cc b/sql/item.cc
index 713e7709bcb..11e9acb1e55 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1207,6 +1207,22 @@ bool Item_name_const::is_null()
return value_item->is_null();
}
+
+Item_name_const::Item_name_const(Item *name_arg, Item *val):
+ value_item(val), name_item(name_arg)
+{
+ if (!(valid_args= name_item->basic_const_item() &&
+ (value_item->basic_const_item() ||
+ ((value_item->type() == FUNC_ITEM) &&
+ (((Item_func *) value_item)->functype() ==
+ Item_func::NEG_FUNC) &&
+ (((Item_func *) value_item)->key_item()->type() !=
+ FUNC_ITEM)))))
+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "NAME_CONST");
+ Item::maybe_null= TRUE;
+}
+
+
Item::Type Item_name_const::type() const
{
/*
@@ -1218,8 +1234,17 @@ Item::Type Item_name_const::type() const
if (item->type() == FIELD_ITEM)
((Item_field *) item)->...
we return NULL_ITEM in the case to avoid wrong casting.
+
+ valid_args guarantees value_item->basic_const_item(); if type is
+ FUNC_ITEM, then we have a fudged item_func_neg() on our hands
+ and return the underlying type.
*/
- return valid_args ? value_item->type() : NULL_ITEM;
+ return valid_args ?
+ (((value_item->type() == FUNC_ITEM) &&
+ (((Item_func *) value_item)->functype() == Item_func::NEG_FUNC)) ?
+ ((Item_func *) value_item)->key_item()->type() :
+ value_item->type()) :
+ NULL_ITEM;
}
@@ -2385,14 +2410,14 @@ default_set_param_func(Item_param *param,
Item_param::Item_param(unsigned pos_in_query_arg) :
- strict_type(FALSE),
state(NO_VALUE),
item_result_type(STRING_RESULT),
/* Don't pretend to be a literal unless value for this item is set. */
item_type(PARAM_ITEM),
param_type(MYSQL_TYPE_VARCHAR),
pos_in_query(pos_in_query_arg),
- set_param_func(default_set_param_func)
+ set_param_func(default_set_param_func),
+ limit_clause_param(FALSE)
{
name= (char*) "?";
/*
@@ -2580,8 +2605,14 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
if (entry && entry->value)
{
item_result_type= entry->type;
- if (strict_type && required_result_type != item_result_type)
- DBUG_RETURN(1);
+ unsigned_flag= entry->unsigned_flag;
+ if (limit_clause_param)
+ {
+ my_bool unused;
+ set_int(entry->val_int(&unused), MY_INT64_NUM_DECIMAL_DIGITS);
+ item_type= Item::INT_ITEM;
+ DBUG_RETURN(!unsigned_flag && value.integer < 0 ? 1 : 0);
+ }
switch (item_result_type) {
case REAL_RESULT:
set_double(*(double*)entry->value);
@@ -2875,7 +2906,10 @@ const String *Item_param::query_val_str(String* str) const
{
switch (state) {
case INT_VALUE:
- str->set(value.integer, &my_charset_bin);
+ if (unsigned_flag)
+ str->set((ulonglong) value.integer, &my_charset_bin);
+ else
+ str->set(value.integer, &my_charset_bin);
break;
case REAL_VALUE:
str->set(value.real, NOT_FIXED_DEC, &my_charset_bin);
@@ -3903,6 +3937,18 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
else if (!from_field)
goto error;
+ if (!outer_fixed && cached_table && cached_table->select_lex &&
+ context->select_lex &&
+ cached_table->select_lex != context->select_lex)
+ {
+ int ret;
+ if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
+ goto error;
+ else if (!ret)
+ return FALSE;
+ outer_fixed= 1;
+ }
+
/*
if it is not expression from merged VIEW we will set this field.
@@ -3918,18 +3964,6 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
if (from_field == view_ref_found)
return FALSE;
- if (!outer_fixed && cached_table && cached_table->select_lex &&
- context->select_lex &&
- cached_table->select_lex != context->select_lex)
- {
- int ret;
- if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
- goto error;
- else if (!ret)
- return FALSE;
- outer_fixed= 1;
- }
-
set_field(from_field);
if (thd->lex->in_sum_func &&
thd->lex->in_sum_func->nest_level ==
@@ -4083,6 +4117,30 @@ bool Item_field::subst_argument_checker(byte **arg)
}
+/**
+ Convert a numeric value to a zero-filled string
+
+ @param[in,out] item the item to operate on
+ @param field The field that this value is equated to
+
+ This function converts a numeric value to a string. In this conversion
+ the zero-fill flag of the field is taken into account.
+ This is required so the resulting string value can be used instead of
+ the field reference when propagating equalities.
+*/
+
+static void convert_zerofill_number_to_string(Item **item, Field_num *field)
+{
+ char buff[MAX_FIELD_WIDTH],*pos;
+ String tmp(buff,sizeof(buff), field->charset()), *res;
+
+ res= (*item)->val_str(&tmp);
+ field->prepend_zeros(res);
+ pos= (char *) sql_strmake (res->ptr(), res->length());
+ *item= new Item_string(pos, res->length(), field->charset());
+}
+
+
/*
Set a pointer to the multiple equality the field reference belongs to
(if any)
@@ -4131,6 +4189,13 @@ Item *Item_field::equal_fields_propagator(byte *arg)
if (!item ||
(cmp_context != (Item_result)-1 && item->cmp_context != cmp_context))
item= this;
+ else if (field && (field->flags & ZEROFILL_FLAG) && IS_NUM(field->type()))
+ {
+ if (item && cmp_context != INT_RESULT)
+ convert_zerofill_number_to_string(&item, (Field_num *)field);
+ else
+ item= this;
+ }
return item;
}
@@ -4302,6 +4367,49 @@ String *Item::check_well_formed_result(String *str, bool send_error)
return str;
}
+/*
+ Compare two items using a given collation
+
+ SYNOPSIS
+ eq_by_collation()
+ item item to compare with
+ binary_cmp TRUE <-> compare as binaries
+ cs collation to use when comparing strings
+
+ DESCRIPTION
+ This method works exactly as Item::eq if the collation cs coincides with
+ the collation of the compared objects. Otherwise, first the collations that
+ differ from cs are replaced for cs and then the items are compared by
+ Item::eq. After the comparison the original collations of items are
+ restored.
+
+ RETURN
+ 1 compared items has been detected as equal
+ 0 otherwise
+*/
+
+bool Item::eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs)
+{
+ CHARSET_INFO *save_cs= 0;
+ CHARSET_INFO *save_item_cs= 0;
+ if (collation.collation != cs)
+ {
+ save_cs= collation.collation;
+ collation.collation= cs;
+ }
+ if (item->collation.collation != cs)
+ {
+ save_item_cs= item->collation.collation;
+ item->collation.collation= cs;
+ }
+ bool res= eq(item, binary_cmp);
+ if (save_cs)
+ collation.collation= save_cs;
+ if (save_item_cs)
+ item->collation.collation= save_item_cs;
+ return res;
+}
+
/*
Create a field to hold a string value from an item
diff --git a/sql/item.h b/sql/item.h
index 5f511557f47..a948c5a45f7 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -873,12 +873,30 @@ public:
virtual Field::geometry_type get_geometry_type() const
{ return Field::GEOM_GEOMETRY; };
String *check_well_formed_result(String *str, bool send_error= 0);
+ bool eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs);
};
class sp_head;
+class Item_basic_constant :public Item
+{
+public:
+ /* to prevent drop fixed flag (no need parent cleanup call) */
+ void cleanup()
+ {
+ /*
+ Restore the original field name as it might not have been allocated
+ in the statement memory. If the name is auto generated, it must be
+ done again between subsequent executions of a prepared statement.
+ */
+ if (orig_name)
+ name= orig_name;
+ }
+};
+
+
/*****************************************************************************
The class is a base class for representation of stored routine variables in
the Item-hierarchy. There are the following kinds of SP-vars:
@@ -1113,14 +1131,7 @@ class Item_name_const : public Item
Item *name_item;
bool valid_args;
public:
- Item_name_const(Item *name_arg, Item *val):
- value_item(val), name_item(name_arg)
- {
- if (!(valid_args= name_item->basic_const_item() &
- value_item->basic_const_item()))
- my_error(ER_WRONG_ARGUMENTS, MYF(0), "NAME_CONST");
- Item::maybe_null= TRUE;
- }
+ Item_name_const(Item *name_arg, Item *val);
bool fix_fields(THD *, Item **);
@@ -1161,7 +1172,7 @@ bool agg_item_charsets(DTCollation &c, const char *name,
Item **items, uint nitems, uint flags, int item_sep);
-class Item_num: public Item
+class Item_num: public Item_basic_constant
{
public:
Item_num() {} /* Remove gcc warning */
@@ -1352,7 +1363,7 @@ public:
friend class st_select_lex_unit;
};
-class Item_null :public Item
+class Item_null :public Item_basic_constant
{
public:
Item_null(char *name_par=0)
@@ -1374,8 +1385,6 @@ public:
bool send(Protocol *protocol, String *str);
enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_NULL; }
- /* to prevent drop fixed flag (no need parent cleanup call) */
- void cleanup() {}
bool basic_const_item() const { return 1; }
Item *clone_item() { return new Item_null(name); }
bool is_null() { return 1; }
@@ -1402,8 +1411,6 @@ class Item_param :public Item
char cnvbuf[MAX_FIELD_WIDTH];
String cnvstr;
Item *cnvitem;
- bool strict_type;
- enum Item_result required_result_type;
public:
enum enum_item_param_state
@@ -1533,11 +1540,8 @@ public:
Otherwise return FALSE.
*/
bool eq(const Item *item, bool binary_cmp) const;
- void set_strict_type(enum Item_result result_type_arg)
- {
- strict_type= TRUE;
- required_result_type= result_type_arg;
- }
+ /** Item is a argument to a limit clause. */
+ bool limit_clause_param;
};
@@ -1567,8 +1571,6 @@ public:
int save_in_field(Field *field, bool no_conversions);
bool basic_const_item() const { return 1; }
Item *clone_item() { return new Item_int(name,value,max_length); }
- // to prevent drop fixed flag (no need parent cleanup call)
- void cleanup() {}
void print(String *str);
Item_num *neg() { value= -value; return this; }
uint decimal_precision() const
@@ -1621,8 +1623,6 @@ public:
{
return new Item_decimal(name, &decimal_value, decimals, max_length);
}
- // to prevent drop fixed flag (no need parent cleanup call)
- void cleanup() {}
void print(String *str);
Item_num *neg()
{
@@ -1673,8 +1673,6 @@ public:
String *val_str(String*);
my_decimal *val_decimal(my_decimal *);
bool basic_const_item() const { return 1; }
- // to prevent drop fixed flag (no need parent cleanup call)
- void cleanup() {}
Item *clone_item()
{ return new Item_float(name, value, decimals, max_length); }
Item_num *neg() { value= -value; return this; }
@@ -1696,7 +1694,7 @@ public:
};
-class Item_string :public Item
+class Item_string :public Item_basic_constant
{
public:
Item_string(const char *str,uint length,
@@ -1780,8 +1778,6 @@ public:
max_length= str_value.numchars() * collation.collation->mbmaxlen;
}
void print(String *str);
- // to prevent drop fixed flag (no need parent cleanup call)
- void cleanup() {}
};
@@ -1839,10 +1835,10 @@ public:
};
-class Item_hex_string: public Item
+class Item_hex_string: public Item_basic_constant
{
public:
- Item_hex_string(): Item() {}
+ Item_hex_string() {}
Item_hex_string(const char *str,uint str_length);
enum Type type() const { return VARBIN_ITEM; }
double val_real()
@@ -1858,8 +1854,6 @@ public:
enum Item_result result_type () const { return STRING_RESULT; }
enum Item_result cast_to_int_type() const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
- // to prevent drop fixed flag (no need parent cleanup call)
- void cleanup() {}
void print(String *str);
bool eq(const Item *item, bool binary_cmp) const;
virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
@@ -1989,6 +1983,35 @@ public:
Item_field *filed_for_view_update()
{ return (*ref)->filed_for_view_update(); }
virtual Ref_Type ref_type() { return REF; }
+
+ // Row emulation: forwarding of ROW-related calls to ref
+ uint cols()
+ {
+ return ref && result_type() == ROW_RESULT ? (*ref)->cols() : 1;
+ }
+ Item* element_index(uint i)
+ {
+ return ref && result_type() == ROW_RESULT ? (*ref)->element_index(i) : this;
+ }
+ Item** addr(uint i)
+ {
+ return ref && result_type() == ROW_RESULT ? (*ref)->addr(i) : 0;
+ }
+ bool check_cols(uint c)
+ {
+ return ref && result_type() == ROW_RESULT ? (*ref)->check_cols(c)
+ : Item::check_cols(c);
+ }
+ bool null_inside()
+ {
+ return ref && result_type() == ROW_RESULT ? (*ref)->null_inside() : 0;
+ }
+ void bring_value()
+ {
+ if (ref && result_type() == ROW_RESULT)
+ (*ref)->bring_value();
+ }
+
};
@@ -2449,7 +2472,7 @@ private:
};
-class Item_cache: public Item
+class Item_cache: public Item_basic_constant
{
protected:
Item *example;
@@ -2486,8 +2509,6 @@ public:
static Item_cache* get_cache(const Item *item);
table_map used_tables() const { return used_table_map; }
virtual void keep_array() {}
- // to prevent drop fixed flag (no need parent cleanup call)
- void cleanup() {}
void print(String *str);
bool eq_def(Field *field)
{
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 98bcb256138..17345e76bba 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -2995,7 +2995,10 @@ void in_string::set(uint pos,Item *item)
{
if (res->uses_buffer_owned_by(str))
res->copy();
- *str= *res;
+ if (item->type() == Item::FUNC_ITEM)
+ str->copy(*res);
+ else
+ *str= *res;
}
if (!str->charset())
{
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 639e069d24e..44b8ed998fe 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -3985,7 +3985,7 @@ double user_var_entry::val_real(my_bool *null_value)
/* Get the value of a variable as an integer */
-longlong user_var_entry::val_int(my_bool *null_value)
+longlong user_var_entry::val_int(my_bool *null_value) const
{
if ((*null_value= (value == 0)))
return LL(0);
@@ -5515,6 +5515,8 @@ Item_func_sp::make_field(Send_field *tmp_field)
DBUG_ENTER("Item_func_sp::make_field");
DBUG_ASSERT(sp_result_field);
sp_result_field->make_field(tmp_field);
+ if (name)
+ tmp_field->col_name= name;
DBUG_VOID_RETURN;
}
diff --git a/sql/item_func.h b/sql/item_func.h
index 940586fce01..6dcf32cba07 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -54,7 +54,8 @@ public:
NOT_FUNC, NOT_ALL_FUNC,
NOW_FUNC, TRIG_COND_FUNC,
SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
- EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC };
+ EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC,
+ NEG_FUNC };
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
OPTIMIZE_EQUAL };
enum Type type() const { return FUNC_ITEM; }
@@ -466,7 +467,7 @@ public:
longlong int_op();
my_decimal *decimal_op(my_decimal *);
const char *func_name() const { return "-"; }
- virtual bool basic_const_item() const { return args[0]->basic_const_item(); }
+ enum Functype functype() const { return NEG_FUNC; }
void fix_length_and_dec();
void fix_num_length_and_dec();
uint decimal_precision() const { return args[0]->decimal_precision(); }
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 3d261dc2c36..3d6d46ab3f4 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -597,6 +597,7 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
result_field=0;
null_value=1;
fix_length_and_dec();
+ item= item->real_item();
if (item->type() == Item::FIELD_ITEM)
hybrid_field_type= ((Item_field*) item)->field->type();
else
@@ -3459,6 +3460,6 @@ void Item_func_group_concat::print(String *str)
Item_func_group_concat::~Item_func_group_concat()
{
- if (unique_filter)
+ if (!original && unique_filter)
delete unique_filter;
}
diff --git a/sql/log.cc b/sql/log.cc
index d1da900e1b5..15e8679171c 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -122,6 +122,20 @@ static int binlog_prepare(THD *thd, bool all)
return 0;
}
+/**
+ This function is called once after each statement.
+
+ It has the responsibility to flush the transaction cache to the
+ binlog file on commits.
+
+ @param thd The client thread that executes the transaction.
+ @param all true if this is the last statement before a COMMIT
+ statement; false if either this is a statement in a
+ transaction but not the last, or if this is a statement
+ not inside a BEGIN block and autocommit is on.
+
+ @see handlerton::commit
+*/
static int binlog_commit(THD *thd, bool all)
{
IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
@@ -134,7 +148,15 @@ static int binlog_commit(THD *thd, bool all)
// we're here because trans_log was flushed in MYSQL_LOG::log_xid()
DBUG_RETURN(0);
}
- if (all)
+ /*
+ Write commit event if at least one of the following holds:
+ - the user sends an explicit COMMIT; or
+ - the autocommit flag is on, and we are not inside a BEGIN.
+ However, if the user has not sent an explicit COMMIT, and we are
+ either inside a BEGIN or run with autocommit off, then this is not
+ the end of a transaction and we should not write a commit event.
+ */
+ if (all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{
Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE);
qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
@@ -144,6 +166,22 @@ static int binlog_commit(THD *thd, bool all)
DBUG_RETURN(binlog_end_trans(thd, trans_log, &invisible_commit));
}
+/**
+ This function is called when a transaction involving a transactional
+ table is rolled back.
+
+ It has the responsibility to flush the transaction cache to the
+ binlog file. However, if the transaction does not involve
+ non-transactional tables, nothing needs to be logged.
+
+ @param thd The client thread that executes the transaction.
+ @param all true if this is the last statement before a COMMIT
+ statement; false if either this is a statement in a
+ transaction but not the last, or if this is a statement
+ not inside a BEGIN block and autocommit is on.
+
+ @see handlerton::rollback
+*/
static int binlog_rollback(THD *thd, bool all)
{
int error=0;
@@ -1817,9 +1855,11 @@ uint MYSQL_LOG::next_file_id()
IMPLEMENTATION
- To support transaction over replication, we wrap the transaction
with BEGIN/COMMIT or BEGIN/ROLLBACK in the binary log.
- We want to write a BEGIN/ROLLBACK block when a non-transactional table
- was updated in a transaction which was rolled back. This is to ensure
- that the same updates are run on the slave.
+ If a transaction that only involves transactional tables is
+ rolled back, we do not binlog it. However, we write a
+ BEGIN/ROLLBACK block when a non-transactional table was updated
+ in a transaction which was rolled back. This is to ensure that
+ the same updates are run on the slave.
*/
bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
@@ -1837,32 +1877,34 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
byte header[LOG_EVENT_HEADER_LEN];
/*
- Log "BEGIN" at the beginning of the transaction.
- which may contain more than 1 SQL statement.
+ Log "BEGIN" at the beginning of every transaction. Here, a
+ transaction is either a BEGIN..COMMIT block or a single
+ statement in autocommit mode.
*/
- if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
- {
- Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE);
- /*
- Imagine this is rollback due to net timeout, after all statements of
- the transaction succeeded. Then we want a zero-error code in BEGIN.
- In other words, if there was a really serious error code it's already
- in the statement's events, there is no need to put it also in this
- internally generated event, and as this event is generated late it
- would lead to false alarms.
- This is safer than thd->clear_error() against kills at shutdown.
- */
- qinfo.error_code= 0;
- /*
- Now this Query_log_event has artificial log_pos 0. It must be adjusted
- to reflect the real position in the log. Not doing it would confuse the
- slave: it would prevent this one from knowing where he is in the
- master's binlog, which would result in wrong positions being shown to
- the user, MASTER_POS_WAIT undue waiting etc.
- */
- if (qinfo.write(&log_file))
- goto err;
- }
+ Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE);
+ /*
+ Imagine this is rollback due to net timeout, after all
+ statements of the transaction succeeded. Then we want a
+ zero-error code in BEGIN. In other words, if there was a
+ really serious error code it's already in the statement's
+ events, there is no need to put it also in this internally
+ generated event, and as this event is generated late it would
+ lead to false alarms.
+
+ This is safer than thd->clear_error() against kills at shutdown.
+ */
+ qinfo.error_code= 0;
+ /*
+ Now this Query_log_event has artificial log_pos 0. It must be
+ adjusted to reflect the real position in the log. Not doing it
+ would confuse the slave: it would prevent this one from
+ knowing where he is in the master's binlog, which would result
+ in wrong positions being shown to the user, MASTER_POS_WAIT
+ undue waiting etc.
+ */
+ if (qinfo.write(&log_file))
+ goto err;
+
/* Read from the file used to cache the queries .*/
if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
goto err;
diff --git a/sql/log_event.cc b/sql/log_event.cc
index d22973d12a3..a950094a018 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1862,7 +1862,7 @@ void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
print_query_header(file, print_event_info);
my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME));
- fprintf(file, "%s\n", print_event_info->delimiter);
+ fprintf(file, "\n%s\n", print_event_info->delimiter);
}
#endif /* MYSQL_CLIENT */
@@ -3793,6 +3793,7 @@ Xid_log_event(const char* buf,
#ifndef MYSQL_CLIENT
bool Xid_log_event::write(IO_CACHE* file)
{
+ DBUG_EXECUTE_IF("do_not_write_xid", return 0;);
return write_header(file, sizeof(xid)) ||
my_b_safe_write(file, (byte*) &xid, sizeof(xid));
}
@@ -5180,12 +5181,12 @@ void Execute_load_query_log_event::print(FILE* file,
fprintf(file, " INTO");
my_fwrite(file, (byte*) query + fn_pos_end, q_len-fn_pos_end,
MYF(MY_NABP | MY_WME));
- fprintf(file, "%s\n", print_event_info->delimiter);
+ fprintf(file, "\n%s\n", print_event_info->delimiter);
}
else
{
my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME));
- fprintf(file, "%s\n", print_event_info->delimiter);
+ fprintf(file, "\n%s\n", print_event_info->delimiter);
}
if (!print_event_info->short_form)
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 4334dedfe4e..59ec18e1a3d 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -73,6 +73,7 @@ extern const char *primary_key_name;
#include "mysql_com.h"
#include <violite.h>
#include "unireg.h"
+#define IS_NUM(t) ((t) <= FIELD_TYPE_INT24 || (t) == FIELD_TYPE_YEAR || (t) == FIELD_TYPE_NEWDECIMAL)
void init_sql_alloc(MEM_ROOT *root, uint block_size, uint pre_alloc_size);
gptr sql_alloc(unsigned size);
@@ -1254,6 +1255,7 @@ void my_dbopt_free(void);
extern time_t server_start_time;
extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
mysql_real_data_home[], *opt_mysql_tmpdir, mysql_charsets_dir[],
+ mysql_unpacked_real_data_home[],
def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
#define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list))
extern MY_TMPDIR mysql_tmpdir_list;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 693b72f5c98..b8df51e9e58 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -138,6 +138,13 @@ extern "C" { // Because of SCO 3.2V4.2
#include <sys/mman.h>
#endif
+#ifdef __WIN__
+#include <crtdbg.h>
+#define SIGNAL_FMT "exception 0x%x"
+#else
+#define SIGNAL_FMT "signal %d"
+#endif
+
#ifdef __NETWARE__
#define zVOLSTATE_ACTIVE 6
#define zVOLSTATE_DEACTIVE 2
@@ -227,6 +234,7 @@ inline void set_proper_floating_point_mode()
extern "C" int gethostname(char *name, int namelen);
#endif
+extern "C" sig_handler handle_segfault(int sig);
/* Constants */
@@ -467,14 +475,13 @@ char log_error_file[FN_REFLEN], glob_hostname[FN_REFLEN];
char mysql_real_data_home[FN_REFLEN],
language[FN_REFLEN], reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN],
*opt_init_file, *opt_tc_log_file,
+ mysql_unpacked_real_data_home[FN_REFLEN],
def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
-
+char *mysql_data_home= mysql_real_data_home;
const key_map key_map_empty(0);
key_map key_map_full(0); // Will be initialized later
const char *opt_date_time_formats[3];
-
-char *mysql_data_home= mysql_real_data_home;
char server_version[SERVER_VERSION_LENGTH];
char *mysqld_unix_port, *opt_mysql_tmpdir;
const char **errmesg; /* Error messages */
@@ -1031,9 +1038,6 @@ static void __cdecl kill_server(int sig_ptr)
#endif
close_connections();
if (sig != MYSQL_KILL_SIGNAL &&
-#ifdef __WIN__
- sig != SIGINT && /* Bug#18235 */
-#endif
sig != 0)
unireg_abort(1); /* purecov: inspected */
else
@@ -1592,8 +1596,7 @@ static void network_init(void)
FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0, NULL );
- MessageBox(NULL, (LPTSTR) lpMsgBuf, "Error from CreateNamedPipe",
- MB_OK|MB_ICONINFORMATION);
+ sql_perror((char *)lpMsgBuf);
LocalFree(lpMsgBuf);
unireg_abort(1);
}
@@ -1796,17 +1799,163 @@ extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
******************************************************************************/
-#if defined(__WIN__) || defined(OS2)
+#if defined(__WIN__)
+
+
+/*
+ On Windows, we use native SetConsoleCtrlHandler for handle events like Ctrl-C
+ with graceful shutdown.
+ Also, we do not use signal(), but SetUnhandledExceptionFilter instead - as it
+ provides possibility to pass the exception to just-in-time debugger, collect
+ dumps and potentially also the exception and thread context used to output
+ callstack.
+*/
+
+static BOOL WINAPI console_event_handler( DWORD type )
+{
+ DBUG_ENTER("console_event_handler");
+ if(type == CTRL_C_EVENT)
+ {
+ /*
+ Do not shutdown before startup is finished and shutdown
+ thread is initialized. Otherwise there is a race condition
+ between main thread doing initialization and CTRL-C thread doing
+ cleanup, which can result into crash.
+ */
+ if(hEventShutdown)
+ kill_mysql();
+ else
+ sql_print_warning("CTRL-C ignored during startup");
+ DBUG_RETURN(TRUE);
+ }
+ DBUG_RETURN(FALSE);
+}
+
+
+/*
+ In Visual Studio 2005 and later, default SIGABRT handler will overwrite
+ any unhandled exception filter set by the application and will try to
+ call JIT debugger. This is not what we want, this we calling __debugbreak
+ to stop in debugger, if process is being debugged or to generate
+ EXCEPTION_BREAKPOINT and then handle_segfault will do its magic.
+*/
+
+#if (_MSC_VER >= 1400)
+static void my_sigabrt_handler(int sig)
+{
+ __debugbreak();
+}
+#endif /*_MSC_VER >=1400 */
+
+void win_install_sigabrt_handler(void)
+{
+#if (_MSC_VER >=1400)
+ /*abort() should not override our exception filter*/
+ _set_abort_behavior(0,_CALL_REPORTFAULT);
+ signal(SIGABRT,my_sigabrt_handler);
+#endif /* _MSC_VER >=1400 */
+}
+
+#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
+#define DEBUGGER_ATTACH_TIMEOUT 120
+/*
+ Wait for debugger to attach and break into debugger. If debugger is not attached,
+ resume after timeout.
+*/
+static void wait_for_debugger(int timeout_sec)
+{
+ if(!IsDebuggerPresent())
+ {
+ int i;
+ printf("Waiting for debugger to attach, pid=%u\n",GetCurrentProcessId());
+ fflush(stdout);
+ for(i= 0; i < timeout_sec; i++)
+ {
+ Sleep(1000);
+ if(IsDebuggerPresent())
+ {
+ /* Break into debugger */
+ __debugbreak();
+ return;
+ }
+ }
+ printf("pid=%u, debugger not attached after %d seconds, resuming\n",GetCurrentProcessId(),
+ timeout_sec);
+ fflush(stdout);
+ }
+}
+#endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */
+
+LONG WINAPI my_unhandler_exception_filter(EXCEPTION_POINTERS *ex_pointers)
+{
+ static BOOL first_time= TRUE;
+ if(!first_time)
+ {
+ /*
+ This routine can be called twice, typically
+ when detaching in JIT debugger.
+ Return EXCEPTION_EXECUTE_HANDLER to terminate process.
+ */
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
+ first_time= FALSE;
+#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
+ /*
+ Unfortunately there is no clean way to debug unhandled exception filters,
+ as debugger does not stop there(also documented in MSDN)
+ To overcome, one could put a MessageBox, but this will not work in service.
+ Better solution is to print error message and sleep some minutes
+ until debugger is attached
+ */
+ wait_for_debugger(DEBUGGER_ATTACH_TIMEOUT);
+#endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */
+ __try
+ {
+ set_exception_pointers(ex_pointers);
+ handle_segfault(ex_pointers->ExceptionRecord->ExceptionCode);
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DWORD written;
+ const char msg[] = "Got exception in exception handler!\n";
+ WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),msg, sizeof(msg)-1,
+ &written,NULL);
+ }
+ /*
+ Return EXCEPTION_CONTINUE_SEARCH to give JIT debugger
+ (drwtsn32 or vsjitdebugger) possibility to attach,
+ if JIT debugger is configured.
+ Windows Error reporting might generate a dump here.
+ */
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+
static void init_signals(void)
{
- int signals[] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGABRT } ;
- for (uint i=0 ; i < sizeof(signals)/sizeof(int) ; i++)
- signal(signals[i], kill_server) ;
-#if defined(__WIN__)
- signal(SIGBREAK,SIG_IGN); //ignore SIGBREAK for NT
-#else
- signal(SIGBREAK, kill_server);
-#endif
+ win_install_sigabrt_handler();
+ if(opt_console)
+ SetConsoleCtrlHandler(console_event_handler,TRUE);
+ else
+ {
+ /* Avoid MessageBox()es*/
+ _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
+ _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
+ _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
+ _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
+ _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
+ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
+
+ /*
+ Do not use SEM_NOGPFAULTERRORBOX in the following SetErrorMode (),
+ because it would prevent JIT debugger and Windows error reporting
+ from working. We need WER or JIT-debugging, since our own unhandled
+ exception filter is not guaranteed to work in all situation
+ (like heap corruption or stack overflow)
+ */
+ SetErrorMode(SetErrorMode(0)|SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
+ }
+ SetUnhandledExceptionFilter(my_unhandler_exception_filter);
}
static void start_signal_handler(void)
@@ -2094,8 +2243,8 @@ static void start_signal_handler(void)
static void check_data_home(const char *path)
{}
+#endif /*__WIN__ || __NETWARE || __EMX__*/
-#else /* if ! __WIN__ && ! __EMX__ */
#ifdef HAVE_LINUXTHREADS
#define UNSAFE_DEFAULT_LINUX_THREADS 200
@@ -2115,7 +2264,7 @@ extern "C" sig_handler handle_segfault(int sig)
*/
if (segfaulted)
{
- fprintf(stderr, "Fatal signal %d while backtracing\n", sig);
+ fprintf(stderr, "Fatal " SIGNAL_FMT " while backtracing\n", sig);
exit(1);
}
@@ -2125,7 +2274,7 @@ extern "C" sig_handler handle_segfault(int sig)
localtime_r(&curr_time, &tm);
fprintf(stderr,"\
-%02d%02d%02d %2d:%02d:%02d - mysqld got signal %d;\n\
+%02d%02d%02d %2d:%02d:%02d - mysqld got " SIGNAL_FMT " ;\n\
This could be because you hit a bug. It is also possible that this binary\n\
or one of the libraries it was linked against is corrupt, improperly built,\n\
or misconfigured. This error can also be caused by malfunctioning hardware.\n",
@@ -2166,6 +2315,10 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
if (!(test_flags & TEST_NO_STACKTRACE))
{
fprintf(stderr,"thd=%p\n",thd);
+ fprintf(stderr,"\
+Attempting backtrace. You can use the following information to find out\n\
+where mysqld died. If you see no messages after this, something went\n\
+terribly wrong...\n");
print_stacktrace(thd ? (gptr) thd->thread_stack : (gptr) 0,
thread_stack);
}
@@ -2214,15 +2367,22 @@ of those buggy OS calls. You should consider whether you really need the\n\
bugs.\n");
}
+#ifdef HAVE_WRITE_CORE
if (test_flags & TEST_CORE_ON_SIGNAL)
{
fprintf(stderr, "Writing a core file\n");
fflush(stderr);
write_core(sig);
}
+#endif
+
+#ifndef __WIN__
+ /* On Windows, do not terminate, but pass control to exception filter */
exit(1);
+#endif
}
+#if !defined(__WIN__) && !defined(__NETWARE__) && !defined(__EMX__)
#ifndef SA_RESETHAND
#define SA_RESETHAND 0
#endif
@@ -2238,10 +2398,6 @@ static void init_signals(void)
struct sigaction sa;
DBUG_ENTER("init_signals");
- if (test_flags & TEST_SIGINT)
- {
- my_sigset(thr_kill_signal, end_thread_signal);
- }
my_sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
@@ -2278,7 +2434,6 @@ static void init_signals(void)
(void) sigemptyset(&set);
my_sigset(SIGPIPE,SIG_IGN);
sigaddset(&set,SIGPIPE);
- sigaddset(&set,SIGINT);
#ifndef IGNORE_SIGHUP_SIGQUIT
sigaddset(&set,SIGQUIT);
sigaddset(&set,SIGHUP);
@@ -2300,9 +2455,12 @@ static void init_signals(void)
sigaddset(&set,THR_SERVER_ALARM);
if (test_flags & TEST_SIGINT)
{
+ my_sigset(thr_kill_signal, end_thread_signal);
// May be SIGINT
sigdelset(&set, thr_kill_signal);
}
+ else
+ sigaddset(&set,SIGINT);
sigprocmask(SIG_SETMASK,&set,NULL);
pthread_sigmask(SIG_SETMASK,&set,NULL);
DBUG_VOID_RETURN;
@@ -2567,19 +2725,6 @@ static void my_str_free_mysqld(void *ptr)
#ifdef __WIN__
-
-struct utsname
-{
- char nodename[FN_REFLEN];
-};
-
-
-int uname(struct utsname *a)
-{
- return -1;
-}
-
-
pthread_handler_t handle_shutdown(void *arg)
{
MSG msg;
@@ -2593,18 +2738,6 @@ pthread_handler_t handle_shutdown(void *arg)
kill_server(MYSQL_KILL_SIGNAL);
return 0;
}
-
-
-int STDCALL handle_kill(ulong ctrl_type)
-{
- if (ctrl_type == CTRL_CLOSE_EVENT ||
- ctrl_type == CTRL_SHUTDOWN_EVENT)
- {
- kill_server(MYSQL_KILL_SIGNAL);
- return TRUE;
- }
- return FALSE;
-}
#endif
@@ -3633,11 +3766,6 @@ we force server id to 2, but this MySQL server will not act as a slave.");
freopen(log_error_file,"a+",stderr);
FreeConsole(); // Remove window
}
- else
- {
- /* Don't show error dialog box when on foreground: it stops the server */
- SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
- }
#endif
/*
@@ -5798,7 +5926,7 @@ log and this option does nothing anymore.",
"Data file autoextend increment in megabytes",
(gptr*) &srv_auto_extend_increment,
(gptr*) &srv_auto_extend_increment,
- 0, GET_LONG, REQUIRED_ARG, 8L, 1L, 1000L, 0, 1L, 0},
+ 0, GET_ULONG, REQUIRED_ARG, 8L, 1L, 1000L, 0, 1L, 0},
{"innodb_buffer_pool_awe_mem_mb", OPT_INNODB_BUFFER_POOL_AWE_MEM_MB,
"If Windows AWE is used, the size of InnoDB buffer pool allocated from the AWE memory.",
(gptr*) &innobase_buffer_pool_awe_mem_mb, (gptr*) &innobase_buffer_pool_awe_mem_mb, 0,
@@ -5811,7 +5939,7 @@ log and this option does nothing anymore.",
{"innodb_commit_concurrency", OPT_INNODB_COMMIT_CONCURRENCY,
"Helps in performance tuning in heavily concurrent environments.",
(gptr*) &srv_commit_concurrency, (gptr*) &srv_commit_concurrency,
- 0, GET_LONG, REQUIRED_ARG, 0, 0, 1000, 0, 1, 0},
+ 0, GET_ULONG, REQUIRED_ARG, 0, 0, 1000, 0, 1, 0},
{"innodb_concurrency_tickets", OPT_INNODB_CONCURRENCY_TICKETS,
"Number of times a thread is allowed to enter InnoDB within the same \
SQL query after it has once got the ticket",
@@ -7611,6 +7739,9 @@ static void fix_paths(void)
pos[1]= 0;
}
convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
+ (void) fn_format(buff, mysql_real_data_home, "", "",
+ (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
+ (void) unpack_dirname(mysql_unpacked_real_data_home, buff);
convert_dirname(language,language,NullS);
(void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
(void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
diff --git a/sql/set_var.cc b/sql/set_var.cc
index d0362edaa29..a99b063a97e 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -113,8 +113,7 @@ static int check_max_delayed_threads(THD *thd, set_var *var);
static void fix_thd_mem_root(THD *thd, enum_var_type type);
static void fix_trans_mem_root(THD *thd, enum_var_type type);
static void fix_server_id(THD *thd, enum_var_type type);
-static ulonglong fix_unsigned(THD *thd, ulonglong num,
- const struct my_option *option_limits);
+static ulonglong fix_unsigned(THD *, ulonglong, const struct my_option *);
static bool get_unsigned(THD *thd, set_var *var);
static void throw_bounds_warning(THD *thd, const char *name, ulonglong num);
static KEY_CACHE *create_key_cache(const char *name, uint length);
@@ -1449,6 +1448,7 @@ static void fix_trans_mem_root(THD *thd, enum_var_type type)
static void fix_server_id(THD *thd, enum_var_type type)
{
server_id_supplied = 1;
+ thd->server_id= server_id;
}
@@ -1524,8 +1524,10 @@ bool sys_var_long_ptr_global::update(THD *thd, set_var *var)
void sys_var_long_ptr_global::set_default(THD *thd, enum_var_type type)
{
+ bool not_used;
pthread_mutex_lock(guard);
- *value= (ulong) option_limits->def_value;
+ *value= (ulong) getopt_ull_limit_value((ulong) option_limits->def_value,
+ option_limits, &not_used);
pthread_mutex_unlock(guard);
}
@@ -1545,8 +1547,10 @@ bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var)
void sys_var_ulonglong_ptr::set_default(THD *thd, enum_var_type type)
{
+ bool not_used;
pthread_mutex_lock(&LOCK_global_system_variables);
- *value= (ulonglong) option_limits->def_value;
+ *value= getopt_ull_limit_value((ulonglong) option_limits->def_value,
+ option_limits, &not_used);
pthread_mutex_unlock(&LOCK_global_system_variables);
}
@@ -1616,8 +1620,11 @@ void sys_var_thd_ulong::set_default(THD *thd, enum_var_type type)
{
if (type == OPT_GLOBAL)
{
+ bool not_used;
/* We will not come here if option_limits is not set */
- global_system_variables.*offset= (ulong) option_limits->def_value;
+ global_system_variables.*offset=
+ (ulong) getopt_ull_limit_value((ulong) option_limits->def_value,
+ option_limits, &not_used);
}
else
thd->variables.*offset= global_system_variables.*offset;
@@ -1660,9 +1667,12 @@ void sys_var_thd_ha_rows::set_default(THD *thd, enum_var_type type)
{
if (type == OPT_GLOBAL)
{
+ bool not_used;
/* We will not come here if option_limits is not set */
pthread_mutex_lock(&LOCK_global_system_variables);
- global_system_variables.*offset= (ha_rows) option_limits->def_value;
+ global_system_variables.*offset=
+ (ha_rows) getopt_ull_limit_value((ha_rows) option_limits->def_value,
+ option_limits, &not_used);
pthread_mutex_unlock(&LOCK_global_system_variables);
}
else
@@ -1709,8 +1719,11 @@ void sys_var_thd_ulonglong::set_default(THD *thd, enum_var_type type)
{
if (type == OPT_GLOBAL)
{
+ bool not_used;
pthread_mutex_lock(&LOCK_global_system_variables);
- global_system_variables.*offset= (ulonglong) option_limits->def_value;
+ global_system_variables.*offset=
+ getopt_ull_limit_value((ulonglong) option_limits->def_value,
+ option_limits, &not_used);
pthread_mutex_unlock(&LOCK_global_system_variables);
}
else
diff --git a/sql/slave.cc b/sql/slave.cc
index 1509916fe91..8a3620080f2 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -2447,14 +2447,15 @@ bool show_master_info(THD* thd, MASTER_INFO* mi)
protocol->prepare_for_resend();
/*
- TODO: we read slave_running without run_lock, whereas these variables
- are updated under run_lock and not data_lock. In 5.0 we should lock
- run_lock on top of data_lock (with good order).
+ slave_running can be accessed without run_lock but not other
+ non-volotile members like mi->io_thd, which is guarded by the mutex.
*/
+ pthread_mutex_lock(&mi->run_lock);
+ protocol->store(mi->io_thd ? mi->io_thd->proc_info : "", &my_charset_bin);
+ pthread_mutex_unlock(&mi->run_lock);
+
pthread_mutex_lock(&mi->data_lock);
pthread_mutex_lock(&mi->rli.data_lock);
-
- protocol->store(mi->io_thd ? mi->io_thd->proc_info : "", &my_charset_bin);
protocol->store(mi->host, &my_charset_bin);
protocol->store(mi->user, &my_charset_bin);
protocol->store((uint32) mi->port);
@@ -3348,7 +3349,10 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
if (rli->slave_skip_counter &&
!((type_code == INTVAR_EVENT ||
type_code == RAND_EVENT ||
- type_code == USER_VAR_EVENT) &&
+ type_code == USER_VAR_EVENT ||
+ type_code == BEGIN_LOAD_QUERY_EVENT ||
+ type_code == APPEND_BLOCK_EVENT ||
+ type_code == CREATE_FILE_EVENT) &&
rli->slave_skip_counter == 1) &&
#if MYSQL_VERSION_ID < 50100
/*
diff --git a/sql/slave.h b/sql/slave.h
index e7d4456ccd9..c61787cdf3b 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -65,8 +65,8 @@
mi->rli does not either.
In MASTER_INFO: run_lock, data_lock
- run_lock protects all information about the run state: slave_running, and the
- existence of the I/O thread (to stop/start it, you need this mutex).
+ run_lock protects all information about the run state: slave_running, thd
+ and the existence of the I/O thread to stop/start it, you need this mutex).
data_lock protects some moving members of the struct: counters (log name,
position) and relay log (MYSQL_LOG object).
diff --git a/sql/sp.cc b/sql/sp.cc
index f8b039626f9..7224d3c4f0e 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -261,6 +261,7 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
char buff[65];
String str(buff, sizeof(buff), &my_charset_bin);
ulong sql_mode;
+ bool saved_time_zone_used= thd->time_zone_used;
Open_tables_state open_tables_state_backup;
DBUG_ENTER("db_find_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s",
@@ -370,6 +371,11 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
definer, created, modified);
done:
+ /*
+ Restore the time zone flag as the timezone usage in proc table
+ does not affect replication.
+ */
+ thd->time_zone_used= saved_time_zone_used;
if (table)
close_proc_table(thd, &open_tables_state_backup);
DBUG_RETURN(ret);
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index e8ddacb820e..46f3d25c441 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1933,11 +1933,17 @@ sp_head::backpatch(sp_label_t *lab)
uint dest= instructions();
List_iterator_fast<bp_t> li(m_backpatch);
+ DBUG_ENTER("sp_head::backpatch");
while ((bp= li++))
{
if (bp->lab == lab)
+ {
+ DBUG_PRINT("info", ("backpatch: (m_ip %d, label 0x%lx <%s>) to dest %d",
+ bp->instr->m_ip, (ulong) lab, lab->name, dest));
bp->instr->backpatch(dest, lab->ctx);
+ }
}
+ DBUG_VOID_RETURN;
}
/*
diff --git a/sql/sp_head.h b/sql/sp_head.h
index a46ec9433d7..0e710196603 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -779,8 +779,9 @@ public:
virtual void backpatch(uint dest, sp_pcontext *dst_ctx)
{
- if (m_dest == 0) // Don't reset
- m_dest= dest;
+ /* Calling backpatch twice is a logic flaw in jump resolution. */
+ DBUG_ASSERT(m_dest == 0);
+ m_dest= dest;
}
/*
diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc
index 54e016f6099..129aaa46de6 100644
--- a/sql/sp_rcontext.cc
+++ b/sql/sp_rcontext.cc
@@ -334,17 +334,91 @@ sp_rcontext::handle_error(uint sql_errno,
void
sp_rcontext::push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i)
{
+ DBUG_ENTER("sp_rcontext::push_cursor");
+ DBUG_ASSERT(m_ccount < m_root_parsing_ctx->max_cursor_index());
m_cstack[m_ccount++]= new sp_cursor(lex_keeper, i);
+ DBUG_PRINT("info", ("m_ccount: %d", m_ccount));
+ DBUG_VOID_RETURN;
}
-
void
sp_rcontext::pop_cursors(uint count)
{
+ DBUG_ENTER("sp_rcontext::pop_cursors");
+ DBUG_ASSERT(m_ccount >= count);
while (count--)
{
delete m_cstack[--m_ccount];
}
+ DBUG_PRINT("info", ("m_ccount: %d", m_ccount));
+ DBUG_VOID_RETURN;
+}
+
+void
+sp_rcontext::push_handler(struct sp_cond_type *cond, uint h, int type, uint f)
+{
+ DBUG_ENTER("sp_rcontext::push_handler");
+ DBUG_ASSERT(m_hcount < m_root_parsing_ctx->max_handler_index());
+
+ m_handler[m_hcount].cond= cond;
+ m_handler[m_hcount].handler= h;
+ m_handler[m_hcount].type= type;
+ m_handler[m_hcount].foffset= f;
+ m_hcount+= 1;
+
+ DBUG_PRINT("info", ("m_hcount: %d", m_hcount));
+ DBUG_VOID_RETURN;
+}
+
+void
+sp_rcontext::pop_handlers(uint count)
+{
+ DBUG_ENTER("sp_rcontext::pop_handlers");
+ DBUG_ASSERT(m_hcount >= count);
+ m_hcount-= count;
+ DBUG_PRINT("info", ("m_hcount: %d", m_hcount));
+ DBUG_VOID_RETURN;
+}
+
+void
+sp_rcontext::push_hstack(uint h)
+{
+ DBUG_ENTER("sp_rcontext::push_hstack");
+ DBUG_ASSERT(m_hsp < m_root_parsing_ctx->max_handler_index());
+ m_hstack[m_hsp++]= h;
+ DBUG_PRINT("info", ("m_hsp: %d", m_hsp));
+ DBUG_VOID_RETURN;
+}
+
+uint
+sp_rcontext::pop_hstack()
+{
+ uint handler;
+ DBUG_ENTER("sp_rcontext::pop_hstack");
+ DBUG_ASSERT(m_hsp);
+ handler= m_hstack[--m_hsp];
+ DBUG_PRINT("info", ("m_hsp: %d", m_hsp));
+ DBUG_RETURN(handler);
+}
+
+void
+sp_rcontext::enter_handler(int hid)
+{
+ DBUG_ENTER("sp_rcontext::enter_handler");
+ DBUG_ASSERT(m_ihsp < m_root_parsing_ctx->max_handler_index());
+ m_in_handler[m_ihsp++]= hid;
+ DBUG_PRINT("info", ("m_ihsp: %d", m_ihsp));
+ DBUG_VOID_RETURN;
+}
+
+void
+sp_rcontext::exit_handler()
+{
+ DBUG_ENTER("sp_rcontext::exit_handler");
+ DBUG_ASSERT(m_ihsp);
+ m_ihsp-= 1;
+ DBUG_PRINT("info", ("m_ihsp: %d", m_ihsp));
+ DBUG_VOID_RETURN;
}
diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h
index 43102cfeeb2..368a017da21 100644
--- a/sql/sp_rcontext.h
+++ b/sql/sp_rcontext.h
@@ -107,21 +107,9 @@ class sp_rcontext : public Sql_alloc
return m_return_value_set;
}
- inline void
- push_handler(struct sp_cond_type *cond, uint h, int type, uint f)
- {
- m_handler[m_hcount].cond= cond;
- m_handler[m_hcount].handler= h;
- m_handler[m_hcount].type= type;
- m_handler[m_hcount].foffset= f;
- m_hcount+= 1;
- }
+ void push_handler(struct sp_cond_type *cond, uint h, int type, uint f);
- inline void
- pop_handlers(uint count)
- {
- m_hcount-= count;
- }
+ void pop_handlers(uint count);
// Returns 1 if a handler was found, 0 otherwise.
bool
@@ -158,29 +146,13 @@ class sp_rcontext : public Sql_alloc
m_hfound= -1;
}
- inline void
- push_hstack(uint h)
- {
- m_hstack[m_hsp++]= h;
- }
+ void push_hstack(uint h);
- inline uint
- pop_hstack()
- {
- return m_hstack[--m_hsp];
- }
+ uint pop_hstack();
- inline void
- enter_handler(int hid)
- {
- m_in_handler[m_ihsp++]= hid;
- }
+ void enter_handler(int hid);
- inline void
- exit_handler()
- {
- m_ihsp-= 1;
- }
+ void exit_handler();
void
push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i);
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 134541368e9..e9504f423ad 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -668,7 +668,9 @@ static ulong get_sort(uint count,...)
{
for (; *str ; str++)
{
- if (*str == wild_many || *str == wild_one || *str == wild_prefix)
+ if (*str == wild_prefix && str[1])
+ str++;
+ else if (*str == wild_many || *str == wild_one)
{
wild_pos= (uint) (str - start) + 1;
break;
@@ -5333,6 +5335,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
LEX_USER *user_name, *tmp_user_name;
List_iterator <LEX_USER> user_list(list);
TABLE_LIST tables[GRANT_TABLES];
+ bool some_users_created= FALSE;
DBUG_ENTER("mysql_create_user");
/* CREATE USER may be skipped on replication client. */
@@ -5361,6 +5364,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
continue;
}
+ some_users_created= TRUE;
sql_mode= thd->variables.sql_mode;
if (replace_user_table(thd, tables[0].table, *user_name, 0, 0, 1, 0))
{
@@ -5371,7 +5375,10 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
VOID(pthread_mutex_unlock(&acl_cache->lock));
- if (mysql_bin_log.is_open())
+ if (result)
+ my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr_safe());
+
+ if (some_users_created && mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
mysql_bin_log.write(&qinfo);
@@ -5379,8 +5386,6 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
- if (result)
- my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr_safe());
DBUG_RETURN(result);
}
@@ -5405,6 +5410,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
LEX_USER *user_name, *tmp_user_name;
List_iterator <LEX_USER> user_list(list);
TABLE_LIST tables[GRANT_TABLES];
+ bool some_users_deleted= FALSE;
DBUG_ENTER("mysql_drop_user");
/* DROP USER may be skipped on replication client. */
@@ -5426,7 +5432,9 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
{
append_user(&wrong_users, user_name);
result= TRUE;
+ continue;
}
+ some_users_deleted= TRUE;
}
/* Rebuild 'acl_check_hosts' since 'acl_users' has been modified */
@@ -5440,7 +5448,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
DBUG_PRINT("info", ("thd->net.last_errno: %d", thd->net.last_errno));
DBUG_PRINT("info", ("thd->net.last_error: %s", thd->net.last_error));
- if (mysql_bin_log.is_open())
+ if (some_users_deleted && mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
mysql_bin_log.write(&qinfo);
@@ -5473,6 +5481,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
LEX_USER *user_to, *tmp_user_to;
List_iterator <LEX_USER> user_list(list);
TABLE_LIST tables[GRANT_TABLES];
+ bool some_users_renamed= FALSE;
DBUG_ENTER("mysql_rename_user");
/* RENAME USER may be skipped on replication client. */
@@ -5506,7 +5515,9 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
{
append_user(&wrong_users, user_from);
result= TRUE;
+ continue;
}
+ some_users_renamed= TRUE;
}
/* Rebuild 'acl_check_hosts' since 'acl_users' has been modified */
@@ -5514,7 +5525,10 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
VOID(pthread_mutex_unlock(&acl_cache->lock));
- if (mysql_bin_log.is_open())
+ if (result)
+ my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe());
+
+ if (some_users_renamed && mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
mysql_bin_log.write(&qinfo);
@@ -5522,8 +5536,6 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
- if (result)
- my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe());
DBUG_RETURN(result);
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 8190b3eeacd..c9f20b3d71b 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -2852,8 +2852,12 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
}
if (tables->lock_type != TL_UNLOCK && ! thd->locked_tables)
- tables->table->reginfo.lock_type= tables->lock_type == TL_WRITE_DEFAULT ?
- thd->update_lock_default : tables->lock_type;
+ {
+ if (tables->lock_type == TL_WRITE_DEFAULT)
+ tables->table->reginfo.lock_type= thd->update_lock_default;
+ else if (tables->table->s->tmp_table == NO_TMP_TABLE)
+ tables->table->reginfo.lock_type= tables->lock_type;
+ }
tables->table->grant= tables->grant;
process_view_routines:
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 97f2d07b1d3..4ca8947de30 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -2329,7 +2329,7 @@ class user_var_entry
bool unsigned_flag;
double val_real(my_bool *null_value);
- longlong val_int(my_bool *null_value);
+ longlong val_int(my_bool *null_value) const;
String *val_str(my_bool *null_value, String *str, uint decimals);
my_decimal *val_decimal(my_bool *null_value, my_decimal *result);
DTCollation collation;
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index 2e98da42be1..c2345f1f2cd 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -88,6 +88,7 @@ class Materialized_cursor: public Server_side_cursor
public:
Materialized_cursor(select_result *result, TABLE *table);
+ int fill_item_list(THD *thd, List<Item> &send_fields);
virtual bool is_open() const { return table != 0; }
virtual int open(JOIN *join __attribute__((unused)));
virtual void fetch(ulong num_rows);
@@ -109,6 +110,7 @@ class Select_materialize: public select_union
{
select_result *result; /* the result object of the caller (PS or SP) */
public:
+ Materialized_cursor *materialized_cursor;
Select_materialize(select_result *result_arg) :result(result_arg) {}
virtual bool send_fields(List<Item> &list, uint flags);
};
@@ -152,7 +154,7 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
if (! (sensitive_cursor= new (thd->mem_root) Sensitive_cursor(thd, result)))
{
- delete result;
+ delete result_materialize;
return 1;
}
@@ -174,13 +176,13 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
/*
Possible options here:
- a sensitive cursor is open. In this case rc is 0 and
- result_materialize->table is NULL, or
+ result_materialize->materialized_cursor is NULL, or
- a materialized cursor is open. In this case rc is 0 and
- result_materialize->table is not NULL
- - an error occured during materializaton.
- result_materialize->table is not NULL, but rc != 0
+ result_materialize->materialized is not NULL
+ - an error occurred during materialization.
+ result_materialize->materialized_cursor is not NULL, but rc != 0
- successful completion of mysql_execute_command without
- a cursor: rc is 0, result_materialize->table is NULL,
+ a cursor: rc is 0, result_materialize->materialized_cursor is NULL,
sensitive_cursor is not open.
This is possible if some command writes directly to the
network, bypassing select_result mechanism. An example of
@@ -191,7 +193,7 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
if (sensitive_cursor->is_open())
{
- DBUG_ASSERT(!result_materialize->table);
+ DBUG_ASSERT(!result_materialize->materialized_cursor);
/*
It's safer if we grab THD state after mysql_execute_command
is finished and not in Sensitive_cursor::open(), because
@@ -202,18 +204,10 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
*pcursor= sensitive_cursor;
goto end;
}
- else if (result_materialize->table)
+ else if (result_materialize->materialized_cursor)
{
- Materialized_cursor *materialized_cursor;
- TABLE *table= result_materialize->table;
- MEM_ROOT *mem_root= &table->mem_root;
-
- if (!(materialized_cursor= new (mem_root)
- Materialized_cursor(result, table)))
- {
- rc= 1;
- goto err_open;
- }
+ Materialized_cursor *materialized_cursor=
+ result_materialize->materialized_cursor;
if ((rc= materialized_cursor->open(0)))
{
@@ -229,8 +223,6 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
err_open:
DBUG_ASSERT(! (sensitive_cursor && sensitive_cursor->is_open()));
delete sensitive_cursor;
- if (result_materialize->table)
- free_tmp_table(thd, result_materialize->table);
end:
delete result_materialize;
return rc;
@@ -544,6 +536,51 @@ Materialized_cursor::Materialized_cursor(select_result *result_arg,
}
+/**
+ Preserve the original metadata that would be sent to the client.
+
+ @param thd Thread identifier.
+ @param send_fields List of fields that would be sent.
+*/
+
+int Materialized_cursor::fill_item_list(THD *thd, List<Item> &send_fields)
+{
+ Query_arena backup_arena;
+ int rc;
+ List_iterator_fast<Item> it_org(send_fields);
+ List_iterator_fast<Item> it_dst(item_list);
+ Item *item_org;
+ Item *item_dst;
+
+ thd->set_n_backup_active_arena(this, &backup_arena);
+
+ if ((rc= table->fill_item_list(&item_list)))
+ goto end;
+
+ DBUG_ASSERT(send_fields.elements == item_list.elements);
+
+ /*
+ Unless we preserve the original metadata, it will be lost,
+ since new fields describe columns of the temporary table.
+ Allocate a copy of the name for safety only. Currently
+ items with original names are always kept in memory,
+ but in case this changes a memory leak may be hard to notice.
+ */
+ while ((item_dst= it_dst++, item_org= it_org++))
+ {
+ Send_field send_field;
+ Item_ident *ident= static_cast<Item_ident *>(item_dst);
+ item_org->make_field(&send_field);
+
+ ident->db_name= thd->strdup(send_field.db_name);
+ ident->table_name= thd->strdup(send_field.table_name);
+ }
+end:
+ thd->restore_active_arena(this, &backup_arena);
+ /* Check for thd->is_error() in case of OOM */
+ return rc || thd->net.report_error;
+}
+
int Materialized_cursor::open(JOIN *join __attribute__((unused)))
{
THD *thd= fake_unit.thd;
@@ -552,8 +589,7 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused)))
thd->set_n_backup_active_arena(this, &backup_arena);
/* Create a list of fields and start sequential scan */
- rc= (table->fill_item_list(&item_list) ||
- result->prepare(item_list, &fake_unit) ||
+ rc= (result->prepare(item_list, &fake_unit) ||
table->file->ha_rnd_init(TRUE));
thd->restore_active_arena(this, &backup_arena);
if (rc == 0)
@@ -664,6 +700,24 @@ bool Select_materialize::send_fields(List<Item> &list, uint flags)
if (create_result_table(unit->thd, unit->get_unit_column_types(),
FALSE, thd->options | TMP_TABLE_ALL_COLUMNS, ""))
return TRUE;
+
+ materialized_cursor= new (&table->mem_root)
+ Materialized_cursor(result, table);
+
+ if (! materialized_cursor)
+ {
+ free_tmp_table(table->in_use, table);
+ table= 0;
+ return TRUE;
+ }
+ if (materialized_cursor->fill_item_list(unit->thd, list))
+ {
+ delete materialized_cursor;
+ table= 0;
+ materialized_cursor= 0;
+ return TRUE;
+ }
+
return FALSE;
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 14292f1cd9d..1d324872409 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -3006,7 +3006,8 @@ bool select_insert::send_eof()
((thd->client_capabilities & CLIENT_FOUND_ROWS) ?
info.touched : info.updated);
id= autoinc_value_of_first_inserted_row > 0 ?
- autoinc_value_of_first_inserted_row : thd->last_insert_id;
+ autoinc_value_of_first_inserted_row : thd->insert_id_used ?
+ thd->last_insert_id : 0;
::send_ok(thd, (ulong) thd->row_count_func, id, buff);
DBUG_RETURN(0);
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 8af79d77fa1..8bdbd812529 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -76,6 +76,7 @@ static void remove_escape(char *name);
static bool append_file_to_dir(THD *thd, const char **filename_ptr,
const char *table_name);
static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
+static bool test_if_data_home_dir(const char *dir);
const char *any_db="*any*"; // Special symbol for check_access
@@ -98,22 +99,7 @@ static bool do_command(THD *thd);
#endif // EMBEDDED_LIBRARY
#ifdef __WIN__
-static void test_signal(int sig_ptr)
-{
-#if !defined( DBUG_OFF)
- MessageBox(NULL,"Test signal","DBUG",MB_OK);
-#endif
-#if defined(OS2)
- fprintf(stderr, "Test signal %d\n", sig_ptr);
- fflush(stderr);
-#endif
-}
-static void init_signals(void)
-{
- int signals[7] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGBREAK,SIGABRT } ;
- for (int i=0 ; i < 7 ; i++)
- signal( signals[i], test_signal) ;
-}
+extern void win_install_sigabrt_handler(void);
#endif
static void unlock_locked_tables(THD *thd)
@@ -1124,7 +1110,7 @@ pthread_handler_t handle_one_connection(void *arg)
/* now that we've called my_thread_init(), it is safe to call DBUG_* */
#if defined(__WIN__)
- init_signals();
+ win_install_sigabrt_handler();
#elif !defined(OS2) && !defined(__NETWARE__)
sigset_t set;
VOID(sigemptyset(&set)); // Get mask in use
@@ -2067,7 +2053,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
unregister_slave(thd,1,1);
/* fake COM_QUIT -- if we get here, the thread needs to terminate */
error = TRUE;
- net->error = 0;
break;
}
#endif
@@ -3056,6 +3041,20 @@ mysql_execute_command(THD *thd)
"INDEX DIRECTORY option ignored");
create_info.data_file_name= create_info.index_file_name= NULL;
#else
+
+ if (test_if_data_home_dir(lex->create_info.data_file_name))
+ {
+ my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECORY");
+ res= -1;
+ break;
+ }
+ if (test_if_data_home_dir(lex->create_info.index_file_name))
+ {
+ my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECORY");
+ res= -1;
+ break;
+ }
+
/* Fix names if symlinked tables */
if (append_file_to_dir(thd, &create_info.data_file_name,
create_table->table_name) ||
@@ -7899,3 +7898,48 @@ bool check_string_length(LEX_STRING *str, const char *err_msg,
return TRUE;
}
+
+
+/*
+ Check if path does not contain mysql data home directory
+
+ SYNOPSIS
+ test_if_data_home_dir()
+ dir directory
+ conv_home_dir converted data home directory
+ home_dir_len converted data home directory length
+
+ RETURN VALUES
+ 0 ok
+ 1 error
+*/
+
+static bool test_if_data_home_dir(const char *dir)
+{
+ char path[FN_REFLEN], conv_path[FN_REFLEN];
+ uint dir_len, home_dir_len= strlen(mysql_unpacked_real_data_home);
+ DBUG_ENTER("test_if_data_home_dir");
+
+ if (!dir)
+ DBUG_RETURN(0);
+
+ (void) fn_format(path, dir, "", "",
+ (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
+ dir_len= unpack_dirname(conv_path, dir);
+
+ if (home_dir_len <= dir_len)
+ {
+ if (lower_case_file_system)
+ {
+ if (!my_strnncoll(default_charset_info, (const uchar*) conv_path,
+ home_dir_len,
+ (const uchar*) mysql_unpacked_real_data_home,
+ home_dir_len))
+ DBUG_RETURN(1);
+ }
+ else if (!memcmp(conv_path, mysql_unpacked_real_data_home, home_dir_len))
+ DBUG_RETURN(1);
+ }
+ DBUG_RETURN(0);
+}
+
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 74cbd2c5505..18cfd8d7dfc 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1512,6 +1512,44 @@ static bool mysql_test_create_table(Prepared_statement *stmt)
}
+/**
+ @brief Validate and prepare for execution CREATE VIEW statement
+
+ @param stmt prepared statement
+
+ @note This function handles create view commands.
+
+ @retval FALSE Operation was a success.
+ @retval TRUE An error occured.
+*/
+
+static bool mysql_test_create_view(Prepared_statement *stmt)
+{
+ DBUG_ENTER("mysql_test_create_view");
+ THD *thd= stmt->thd;
+ LEX *lex= stmt->lex;
+ bool res= TRUE;
+ /* Skip first table, which is the view we are creating */
+ bool link_to_local;
+ TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
+ TABLE_LIST *tables= lex->query_tables;
+
+ if (create_view_precheck(thd, tables, view, lex->create_view_mode))
+ goto err;
+
+ if (open_normal_and_derived_tables(thd, tables, 0))
+ goto err;
+
+ lex->view_prepare_mode= 1;
+ res= select_like_stmt_test(stmt, 0, 0);
+
+err:
+ /* put view back for PS rexecuting */
+ lex->link_first_table_back(view, link_to_local);
+ DBUG_RETURN(res);
+}
+
+
/*
Validate and prepare for execution a multi update statement.
@@ -1730,6 +1768,7 @@ static bool check_prepared_statement(Prepared_statement *stmt,
my_message(ER_UNSUPPORTED_PS, ER(ER_UNSUPPORTED_PS), MYF(0));
goto error;
}
+ res= mysql_test_create_view(stmt);
break;
case SQLCOM_DO:
res= mysql_test_do_fields(stmt, tables, lex->insert_list);
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 903d254db8f..5bbff69f197 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1229,9 +1229,6 @@ bool change_master(THD* thd, MASTER_INFO* mi)
DBUG_RETURN(TRUE);
}
}
- mi->rli.group_master_log_pos = mi->master_log_pos;
- DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
-
/*
Coordinates in rli were spoilt by the 'if (need_relay_log_purge)' block,
so restore them to good values. If we left them to ''/0, that would work;
@@ -1243,6 +1240,7 @@ bool change_master(THD* thd, MASTER_INFO* mi)
That's why we always save good coords in rli.
*/
mi->rli.group_master_log_pos= mi->master_log_pos;
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
strmake(mi->rli.group_master_log_name,mi->master_log_name,
sizeof(mi->rli.group_master_log_name)-1);
@@ -1355,6 +1353,11 @@ bool mysql_show_binlog_events(THD* thd)
if ((file=open_binlog(&log, linfo.log_file_name, &errmsg)) < 0)
goto err;
+ /*
+ to account binlog event header size
+ */
+ thd->variables.max_allowed_packet += MAX_LOG_EVENT_HEADER;
+
pthread_mutex_lock(log_lock);
/*
@@ -1365,7 +1368,6 @@ bool mysql_show_binlog_events(THD* thd)
This code will fail on a mixed relay log (one which has Format_desc then
Rotate then Format_desc).
*/
-
ev = Log_event::read_log_event(&log,(pthread_mutex_t*)0,description_event);
if (ev)
{
@@ -1556,37 +1558,52 @@ err:
DBUG_RETURN(TRUE);
}
-
+/**
+ Load data's io cache specific hook to be executed
+ before a chunk of data is being read into the cache's buffer
+ The fuction instantianates and writes into the binlog
+ replication events along LOAD DATA processing.
+
+ @param file pointer to io-cache
+ @return 0
+*/
int log_loaded_block(IO_CACHE* file)
{
+ DBUG_ENTER("log_loaded_block");
LOAD_FILE_INFO *lf_info;
- uint block_len ;
-
- /* file->request_pos contains position where we started last read */
- char* buffer = (char*) file->request_pos;
- if (!(block_len = (char*) file->read_end - (char*) buffer))
- return 0;
- lf_info = (LOAD_FILE_INFO*) file->arg;
+ uint block_len;
+ /* buffer contains position where we started last read */
+ char* buffer= (char*) my_b_get_buffer_start(file);
+ uint max_event_size= current_thd->variables.max_allowed_packet;
+ lf_info= (LOAD_FILE_INFO*) file->arg;
if (lf_info->last_pos_in_file != HA_POS_ERROR &&
- lf_info->last_pos_in_file >= file->pos_in_file)
- return 0;
- lf_info->last_pos_in_file = file->pos_in_file;
- if (lf_info->wrote_create_file)
- {
- Append_block_log_event a(lf_info->thd, lf_info->thd->db, buffer,
- block_len, lf_info->log_delayed);
- mysql_bin_log.write(&a);
- }
- else
+ lf_info->last_pos_in_file >= my_b_get_pos_in_file(file))
+ DBUG_RETURN(0);
+
+ for (block_len= my_b_get_bytes_in_buffer(file); block_len > 0;
+ buffer += min(block_len, max_event_size),
+ block_len -= min(block_len, max_event_size))
{
- Begin_load_query_log_event b(lf_info->thd, lf_info->thd->db,
- buffer, block_len,
- lf_info->log_delayed);
- mysql_bin_log.write(&b);
- lf_info->wrote_create_file = 1;
- DBUG_SYNC_POINT("debug_lock.created_file_event",10);
+ lf_info->last_pos_in_file= my_b_get_pos_in_file(file);
+ if (lf_info->wrote_create_file)
+ {
+ Append_block_log_event a(lf_info->thd, lf_info->thd->db, buffer,
+ min(block_len, max_event_size),
+ lf_info->log_delayed);
+ mysql_bin_log.write(&a);
+ }
+ else
+ {
+ Begin_load_query_log_event b(lf_info->thd, lf_info->thd->db,
+ buffer,
+ min(block_len, max_event_size),
+ lf_info->log_delayed);
+ mysql_bin_log.write(&b);
+ lf_info->wrote_create_file= 1;
+ DBUG_SYNC_POINT("debug_lock.created_file_event",10);
+ }
}
- return 0;
+ DBUG_RETURN(0);
}
#endif /* HAVE_REPLICATION */
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 87935b5548f..6392f7c4299 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -360,10 +360,10 @@ fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
}
}
new_ref= direct_ref ?
- new Item_direct_ref(ref->context, item_ref, ref->field_name,
- ref->table_name, ref->alias_name_used) :
- new Item_ref(ref->context, item_ref, ref->field_name,
- ref->table_name, ref->alias_name_used);
+ new Item_direct_ref(ref->context, item_ref, ref->table_name,
+ ref->field_name, ref->alias_name_used) :
+ new Item_ref(ref->context, item_ref, ref->table_name,
+ ref->field_name, ref->alias_name_used);
if (!new_ref)
return TRUE;
ref->outer_ref= new_ref;
@@ -2887,7 +2887,9 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
}
}
else if (old->eq_func && new_fields->eq_func &&
- old->val->eq(new_fields->val, old->field->binary()))
+ old->val->eq_by_collation(new_fields->val,
+ old->field->binary(),
+ old->field->charset()))
{
old->level= and_level;
@@ -10794,7 +10796,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
we found a row, as no new rows can be added to the result.
*/
if (not_used_in_distinct && found_records != join->found_records)
- return NESTED_LOOP_OK;
+ return NESTED_LOOP_NO_MORE_ROWS;
}
else
join_tab->read_record.file->unlock_row();
@@ -11171,19 +11173,42 @@ join_read_key(JOIN_TAB *tab)
}
+/*
+ ref access method implementation: "read_first" function
+
+ SYNOPSIS
+ join_read_always_key()
+ tab JOIN_TAB of the accessed table
+
+ DESCRIPTION
+ This is "read_fist" function for the "ref" access method.
+
+ The functon must leave the index initialized when it returns.
+ ref_or_null access implementation depends on that.
+
+ RETURN
+ 0 - Ok
+ -1 - Row not found
+ 1 - Error
+*/
+
static int
join_read_always_key(JOIN_TAB *tab)
{
int error;
TABLE *table= tab->table;
+ /* Initialize the index first */
+ if (!table->file->inited)
+ table->file->ha_index_init(tab->ref.key);
+
+ /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
for (uint i= 0 ; i < tab->ref.key_parts ; i++)
{
if ((tab->ref.null_rejecting & 1 << i) && tab->ref.items[i]->is_null())
return -1;
- }
- if (!table->file->inited)
- table->file->ha_index_init(tab->ref.key);
+ }
+
if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
return -1;
if ((error=table->file->index_read(table->record[0],
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 606a9ddb26d..75e47dd0c8e 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -307,8 +307,8 @@ bool String::copy_aligned(const char *str,uint32 arg_length, uint32 offset,
return TRUE;
/*
- Note, this is only safe for little-endian UCS-2.
- If we add big-endian UCS-2 sometimes, this code
+ Note, this is only safe for big-endian UCS-2.
+ If we add little-endian UCS-2 sometimes, this code
will be more complicated. But it's OK for now.
*/
bzero((char*) Ptr, offset);
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 297edd0d90d..4c8e6e80c41 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -182,10 +182,33 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
TABLE_LIST decoy;
memcpy (&decoy, view, sizeof (TABLE_LIST));
- if (!open_table(thd, &decoy, thd->mem_root, &not_used, OPEN_VIEW_NO_PARSE) &&
- !decoy.view)
+
+ /*
+ Let's reset decoy.view before calling open_table(): when we start
+ supporting ALTER VIEW in PS/SP that may save us from a crash.
+ */
+
+ decoy.view= NULL;
+
+ /*
+ open_table() will return NULL if 'decoy' is idenitifying a view *and*
+ there is no TABLE object for that view in the table cache. However,
+ decoy.view will be set to 1.
+
+ If there is a TABLE-instance for the oject identified by 'decoy',
+ open_table() will return that instance no matter if it is a table or
+ a view.
+
+ Thus, there is no need to check for the return value of open_table(),
+ since the return value itself does not mean anything.
+ */
+
+ open_table(thd, &decoy, thd->mem_root, &not_used, OPEN_VIEW_NO_PARSE);
+
+ if (!decoy.view)
{
- /* It's a table */
+ /* It's a table. */
+ my_error(ER_WRONG_OBJECT, MYF(0), view->db, view->table_name, "VIEW");
return TRUE;
}
@@ -204,104 +227,31 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
return FALSE;
}
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
/**
- @brief Creating/altering VIEW procedure
+ @brief CREATE VIEW privileges pre-check.
@param thd thread handler
+ @param tables tables used in the view
@param views views to create
@param mode VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE
- @note This function handles both create and alter view commands.
-
@retval FALSE Operation was a success.
@retval TRUE An error occured.
*/
-bool mysql_create_view(THD *thd, TABLE_LIST *views,
- enum_view_create_mode mode)
+bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
+ enum_view_create_mode mode)
{
LEX *lex= thd->lex;
- bool link_to_local;
/* first table in list is target VIEW name => cut off it */
- TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
- TABLE_LIST *tables= lex->query_tables;
TABLE_LIST *tbl;
SELECT_LEX *select_lex= &lex->select_lex;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
SELECT_LEX *sl;
-#endif
- SELECT_LEX_UNIT *unit= &lex->unit;
- bool res= FALSE;
- DBUG_ENTER("mysql_create_view");
+ bool res= TRUE;
+ DBUG_ENTER("create_view_precheck");
- /* This is ensured in the parser. */
- DBUG_ASSERT(!lex->proc_list.first && !lex->result &&
- !lex->param_list.elements && !lex->derived_tables);
-
- if (mode != VIEW_CREATE_NEW)
- {
- if (mode == VIEW_ALTER &&
- fill_defined_view_parts(thd, view))
- {
- res= TRUE;
- goto err;
- }
- sp_cache_invalidate();
- }
-
- if (!lex->definer)
- {
- /*
- DEFINER-clause is missing; we have to create default definer in
- persistent arena to be PS/SP friendly.
- If this is an ALTER VIEW then the current user should be set as
- the definer.
- */
- Query_arena original_arena;
- Query_arena *ps_arena = thd->activate_stmt_arena_if_needed(&original_arena);
-
- if (!(lex->definer= create_default_definer(thd)))
- res= TRUE;
-
- if (ps_arena)
- thd->restore_active_arena(ps_arena, &original_arena);
-
- if (res)
- goto err;
- }
-
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- /*
- check definer of view:
- - same as current user
- - current user has SUPER_ACL
- */
- if (lex->definer &&
- (strcmp(lex->definer->user.str, thd->security_ctx->priv_user) != 0 ||
- my_strcasecmp(system_charset_info,
- lex->definer->host.str,
- thd->security_ctx->priv_host) != 0))
- {
- if (!(thd->security_ctx->master_access & SUPER_ACL))
- {
- my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
- res= TRUE;
- goto err;
- }
- else
- {
- if (!is_acl_user(lex->definer->host.str,
- lex->definer->user.str))
- {
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
- ER_NO_SUCH_USER,
- ER(ER_NO_SUCH_USER),
- lex->definer->user.str,
- lex->definer->host.str);
- }
- }
- }
/*
Privilege check for view creation:
- user has CREATE VIEW privilege on view table
@@ -323,10 +273,8 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
(check_access(thd, DROP_ACL, view->db, &view->grant.privilege,
0, 0, is_schema_db(view->db)) ||
grant_option && check_grant(thd, DROP_ACL, view, 0, 1, 0))))
- {
- res= TRUE;
goto err;
- }
+
for (sl= select_lex; sl; sl= sl->next_select())
{
for (tbl= sl->get_table_list(); tbl; tbl= tbl->next_local)
@@ -340,7 +288,6 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
"ANY", thd->security_ctx->priv_user,
thd->security_ctx->priv_host, tbl->table_name);
- res= TRUE;
goto err;
}
/*
@@ -376,10 +323,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
if (check_access(thd, SELECT_ACL, tbl->db,
&tbl->grant.privilege, 0, 0, test(tbl->schema_table)) ||
grant_option && check_grant(thd, SELECT_ACL, tbl, 0, 1, 0))
- {
- res= TRUE;
goto err;
- }
}
}
}
@@ -403,8 +347,126 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
}
}
}
+
+ res= FALSE;
+
+err:
+ DBUG_RETURN(res || thd->net.report_error);
+}
+
+#else
+
+bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
+ enum_view_create_mode mode)
+{
+ return FALSE;
+}
+
+#endif
+
+
+/**
+ @brief Creating/altering VIEW procedure
+
+ @param thd thread handler
+ @param views views to create
+ @param mode VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE
+
+ @note This function handles both create and alter view commands.
+
+ @retval FALSE Operation was a success.
+ @retval TRUE An error occured.
+*/
+
+bool mysql_create_view(THD *thd, TABLE_LIST *views,
+ enum_view_create_mode mode)
+{
+ LEX *lex= thd->lex;
+ bool link_to_local;
+ /* first table in list is target VIEW name => cut off it */
+ TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
+ TABLE_LIST *tables= lex->query_tables;
+ TABLE_LIST *tbl;
+ SELECT_LEX *select_lex= &lex->select_lex;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ SELECT_LEX *sl;
+#endif
+ SELECT_LEX_UNIT *unit= &lex->unit;
+ bool res= FALSE;
+ DBUG_ENTER("mysql_create_view");
+
+ /* This is ensured in the parser. */
+ DBUG_ASSERT(!lex->proc_list.first && !lex->result &&
+ !lex->param_list.elements && !lex->derived_tables);
+
+ if (mode != VIEW_CREATE_NEW)
+ {
+ if (mode == VIEW_ALTER &&
+ fill_defined_view_parts(thd, view))
+ {
+ res= TRUE;
+ goto err;
+ }
+ sp_cache_invalidate();
+ }
+
+ if (!lex->definer)
+ {
+ /*
+ DEFINER-clause is missing; we have to create default definer in
+ persistent arena to be PS/SP friendly.
+ If this is an ALTER VIEW then the current user should be set as
+ the definer.
+ */
+ Query_arena original_arena;
+ Query_arena *ps_arena = thd->activate_stmt_arena_if_needed(&original_arena);
+
+ if (!(lex->definer= create_default_definer(thd)))
+ res= TRUE;
+
+ if (ps_arena)
+ thd->restore_active_arena(ps_arena, &original_arena);
+
+ if (res)
+ goto err;
+ }
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ /*
+ check definer of view:
+ - same as current user
+ - current user has SUPER_ACL
+ */
+ if (lex->definer &&
+ (strcmp(lex->definer->user.str, thd->security_ctx->priv_user) != 0 ||
+ my_strcasecmp(system_charset_info,
+ lex->definer->host.str,
+ thd->security_ctx->priv_host) != 0))
+ {
+ if (!(thd->security_ctx->master_access & SUPER_ACL))
+ {
+ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
+ res= TRUE;
+ goto err;
+ }
+ else
+ {
+ if (!is_acl_user(lex->definer->host.str,
+ lex->definer->user.str))
+ {
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+ ER_NO_SUCH_USER,
+ ER(ER_NO_SUCH_USER),
+ lex->definer->user.str,
+ lex->definer->host.str);
+ }
+ }
+ }
#endif
+ if ((res= create_view_precheck(thd, tables, view, mode)))
+ goto err;
+
if (open_and_lock_tables(thd, tables))
{
res= TRUE;
@@ -1424,6 +1486,8 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
String non_existant_views;
char *wrong_object_db= NULL, *wrong_object_name= NULL;
bool error= FALSE;
+ bool some_views_deleted= FALSE;
+ bool something_wrong= FALSE;
VOID(pthread_mutex_lock(&LOCK_open));
for (view= views; view; view= view->next_local)
@@ -1462,33 +1526,37 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
}
if (my_delete(path, MYF(MY_WME)))
error= TRUE;
+ some_views_deleted= TRUE;
query_cache_invalidate3(thd, view, 0);
sp_cache_invalidate();
}
- if (mysql_bin_log.is_open())
- {
- thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
- }
- VOID(pthread_mutex_unlock(&LOCK_open));
-
- if (error)
- {
- DBUG_RETURN(TRUE);
- }
if (wrong_object_name)
{
my_error(ER_WRONG_OBJECT, MYF(0), wrong_object_db, wrong_object_name,
"VIEW");
- DBUG_RETURN(TRUE);
}
if (non_existant_views.length())
{
my_error(ER_BAD_TABLE_ERROR, MYF(0), non_existant_views.c_ptr());
+ }
+
+ something_wrong= error || wrong_object_name || non_existant_views.length();
+ if (some_views_deleted || !something_wrong)
+ {
+ if (!something_wrong)
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ mysql_bin_log.write(&qinfo);
+ }
+
+ VOID(pthread_mutex_unlock(&LOCK_open));
+
+ if (something_wrong)
+ {
DBUG_RETURN(TRUE);
}
+
send_ok(thd);
DBUG_RETURN(FALSE);
}
diff --git a/sql/sql_view.h b/sql/sql_view.h
index ab0920e0bf2..1d45283352b 100644
--- a/sql/sql_view.h
+++ b/sql/sql_view.h
@@ -15,6 +15,9 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
+ enum_view_create_mode mode);
+
bool mysql_create_view(THD *thd, TABLE_LIST *view,
enum_view_create_mode mode);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index af57fbdb108..80fa037b964 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -458,10 +458,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%pure_parser /* We have threads */
/*
- Currently there are 245 shift/reduce conflicts.
+ Currently there are 240 shift/reduce conflicts.
We should not introduce new conflicts any more.
*/
-%expect 245
+%expect 240
%token END_OF_INPUT
@@ -1111,6 +1111,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <interval_time_st> interval_time_st
+%type <interval_time_st> interval_time_stamp
+
%type <db_type> storage_engines
%type <row_type> row_types
@@ -2214,6 +2216,10 @@ sp_proc_stmt:
lex->sphead->backpatch(lex->spcont->pop_label());
}
+ | sp_labeled_block
+ {}
+ | sp_unlabeled_block
+ {}
| LEAVE_SYM label_ident
{
LEX *lex= Lex;
@@ -2231,9 +2237,17 @@ sp_proc_stmt:
sp_instr_jump *i;
uint ip= sp->instructions();
uint n;
+ /*
+ When jumping to a BEGIN-END block end, the target jump
+ points to the block hpop/cpop cleanup instructions,
+ so we should exclude the block context here.
+ When jumping to something else (i.e., SP_LAB_ITER),
+ there are no hpop/cpop at the jump destination,
+ so we should include the block context here for cleanup.
+ */
+ bool exclusive= (lab->type == SP_LAB_BEGIN);
- n= ctx->diff_handlers(lab->ctx, TRUE); /* Exclusive the dest. */
-
+ n= ctx->diff_handlers(lab->ctx, exclusive);
if (n)
{
sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n);
@@ -2241,10 +2255,12 @@ sp_proc_stmt:
MYSQL_YYABORT;
sp->add_instr(hpop);
}
- n= ctx->diff_cursors(lab->ctx, TRUE); /* Exclusive the dest. */
+ n= ctx->diff_cursors(lab->ctx, exclusive);
if (n)
{
sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n);
+ if (cpop == NULL)
+ MYSQL_YYABORT;
sp->add_instr(cpop);
}
i= new sp_instr_jump(ip, ctx);
@@ -2276,12 +2292,16 @@ sp_proc_stmt:
if (n)
{
sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n);
+ if (hpop == NULL)
+ MYSQL_YYABORT;
sp->add_instr(hpop);
}
n= ctx->diff_cursors(lab->ctx, FALSE); /* Inclusive the dest. */
if (n)
{
sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n);
+ if (cpop == NULL)
+ MYSQL_YYABORT;
sp->add_instr(cpop);
}
i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
@@ -2577,19 +2597,17 @@ sp_labeled_control:
sp_unlabeled_control sp_opt_label
{
LEX *lex= Lex;
+ sp_label_t *lab= lex->spcont->pop_label();
if ($5.str)
{
- sp_label_t *lab= lex->spcont->find_label($5.str);
-
- if (!lab ||
- my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
+ if (my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
{
my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
MYSQL_YYABORT;
}
}
- lex->sphead->backpatch(lex->spcont->pop_label());
+ lex->sphead->backpatch(lab);
}
;
@@ -2598,15 +2616,59 @@ sp_opt_label:
| label_ident { $$= $1; }
;
-sp_unlabeled_control:
+sp_labeled_block:
+ label_ident ':'
+ {
+ LEX *lex= Lex;
+ sp_pcontext *ctx= lex->spcont;
+ sp_label_t *lab= ctx->find_label($1.str);
+
+ if (lab)
+ {
+ my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str);
+ MYSQL_YYABORT;
+ }
+
+ lab= lex->spcont->push_label($1.str,
+ lex->sphead->instructions());
+ lab->type= SP_LAB_BEGIN;
+ }
+ sp_block_content sp_opt_label
+ {
+ LEX *lex= Lex;
+ sp_label_t *lab= lex->spcont->pop_label();
+
+ if ($5.str)
+ {
+ if (my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
+ {
+ my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
+ MYSQL_YYABORT;
+ }
+ }
+ }
+ ;
+
+sp_unlabeled_block:
+ { /* Unlabeled blocks get a secret label. */
+ LEX *lex= Lex;
+ uint ip= lex->sphead->instructions();
+ sp_label_t *lab= lex->spcont->push_label((char *)"", ip);
+ lab->type= SP_LAB_BEGIN;
+ }
+ sp_block_content
+ {
+ LEX *lex= Lex;
+ lex->spcont->pop_label();
+ }
+ ;
+
+sp_block_content:
BEGIN_SYM
{ /* QQ This is just a dummy for grouping declarations and statements
together. No [[NOT] ATOMIC] yet, and we need to figure out how
make it coexist with the existing BEGIN COMMIT/ROLLBACK. */
LEX *lex= Lex;
- sp_label_t *lab= lex->spcont->last_label();
-
- lab->type= SP_LAB_BEGIN;
lex->spcont= lex->spcont->push_context(LABEL_DEFAULT_SCOPE);
}
sp_decls
@@ -2636,7 +2698,10 @@ sp_unlabeled_control:
}
lex->spcont= ctx->pop_context();
}
- | LOOP_SYM
+ ;
+
+sp_unlabeled_control:
+ LOOP_SYM
sp_proc_stmts1 END LOOP_SYM
{
LEX *lex= Lex;
@@ -5027,9 +5092,9 @@ simple_expr:
{ $$= new Item_datetime_typecast($3); }
| TIMESTAMP '(' expr ',' expr ')'
{ $$= new Item_func_add_time($3, $5, 1, 0); }
- | TIMESTAMP_ADD '(' interval_time_st ',' expr ',' expr ')'
+ | TIMESTAMP_ADD '(' interval_time_stamp ',' expr ',' expr ')'
{ $$= new Item_date_add_interval($7,$5,$3,0); }
- | TIMESTAMP_DIFF '(' interval_time_st ',' expr ',' expr ')'
+ | TIMESTAMP_DIFF '(' interval_time_stamp ',' expr ',' expr ')'
{ $$= new Item_func_timestamp_diff($5,$7,$3); }
| TRIM '(' expr ')'
{ $$= new Item_func_trim($3); }
@@ -6005,21 +6070,40 @@ interval:
| HOUR_MICROSECOND_SYM { $$=INTERVAL_HOUR_MICROSECOND; }
| HOUR_MINUTE_SYM { $$=INTERVAL_HOUR_MINUTE; }
| HOUR_SECOND_SYM { $$=INTERVAL_HOUR_SECOND; }
- | MICROSECOND_SYM { $$=INTERVAL_MICROSECOND; }
| MINUTE_MICROSECOND_SYM { $$=INTERVAL_MINUTE_MICROSECOND; }
| MINUTE_SECOND_SYM { $$=INTERVAL_MINUTE_SECOND; }
| SECOND_MICROSECOND_SYM { $$=INTERVAL_SECOND_MICROSECOND; }
| YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; };
+interval_time_stamp:
+ interval_time_st {}
+ | FRAC_SECOND_SYM {
+ $$=INTERVAL_MICROSECOND;
+ /*
+ FRAC_SECOND was mistakenly implemented with
+ a wrong resolution. According to the ODBC
+ standard it should be nanoseconds, not
+ microseconds. Changing it to nanoseconds
+ in MySQL would mean making TIMESTAMPDIFF
+ and TIMESTAMPADD to return DECIMAL, since
+ the return value would be too big for BIGINT
+ Hence we just deprecate the incorrect
+ implementation without changing its
+ resolution.
+ */
+ WARN_DEPRECATED("FRAC_SECOND", "MICROSECOND"); // Will be removed in 6.2
+ }
+ ;
+
interval_time_st:
DAY_SYM { $$=INTERVAL_DAY; }
| WEEK_SYM { $$=INTERVAL_WEEK; }
| HOUR_SYM { $$=INTERVAL_HOUR; }
- | FRAC_SECOND_SYM { $$=INTERVAL_MICROSECOND; }
| MINUTE_SYM { $$=INTERVAL_MINUTE; }
| MONTH_SYM { $$=INTERVAL_MONTH; }
| QUARTER_SYM { $$=INTERVAL_QUARTER; }
| SECOND_SYM { $$=INTERVAL_SECOND; }
+ | MICROSECOND_SYM { $$=INTERVAL_MICROSECOND; }
| YEAR_SYM { $$=INTERVAL_YEAR; }
;
@@ -6257,7 +6341,7 @@ limit_options:
limit_option:
param_marker
{
- ((Item_param *) $1)->set_strict_type(INT_RESULT);
+ ((Item_param *) $1)->limit_clause_param= TRUE;
}
| ULONGLONG_NUM { $$= new Item_uint($1.str, $1.length); }
| LONG_NUM { $$= new Item_uint($1.str, $1.length); }
diff --git a/sql/stacktrace.c b/sql/stacktrace.c
index c947beafac3..ce91d63d3f7 100644
--- a/sql/stacktrace.c
+++ b/sql/stacktrace.c
@@ -13,11 +13,15 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+/* Workaround for Bug#32082: VOID redefinition on Win results in compile errors*/
+#define DONT_DEFINE_VOID 1
+
#include <my_global.h>
#include "stacktrace.h"
+
+#ifndef __WIN__
#include <signal.h>
#include <my_pthread.h>
-
#ifdef HAVE_STACKTRACE
#include <unistd.h>
#include <strings.h>
@@ -118,10 +122,7 @@ void print_stacktrace(gptr stack_bottom, ulong thread_stack)
#endif
LINT_INIT(fp);
- fprintf(stderr,"\
-Attempting backtrace. You can use the following information to find out\n\
-where mysqld died. If you see no messages after this, something went\n\
-terribly wrong...\n");
+
#ifdef __i386__
__asm __volatile__ ("movl %%ebp,%0"
:"=r"(fp)
@@ -257,3 +258,267 @@ void write_core(int sig)
#endif
}
#endif
+#else /* __WIN__*/
+
+#include <dbghelp.h>
+
+/*
+ Stack tracing on Windows is implemented using Debug Helper library(dbghelp.dll)
+ We do not redistribute dbghelp and the one comes with older OS (up to Windows 2000)
+ is missing some important functions like functions StackWalk64 or MinidumpWriteDump.
+ Hence, we have to load functions at runtime using LoadLibrary/GetProcAddress.
+*/
+
+typedef DWORD (WINAPI *SymSetOptions_FctType)(DWORD dwOptions);
+typedef BOOL (WINAPI *SymGetModuleInfo64_FctType)
+ (HANDLE,DWORD64,PIMAGEHLP_MODULE64) ;
+typedef BOOL (WINAPI *SymGetSymFromAddr64_FctType)
+ (HANDLE,DWORD64,PDWORD64,PIMAGEHLP_SYMBOL64) ;
+typedef BOOL (WINAPI *SymGetLineFromAddr64_FctType)
+ (HANDLE,DWORD64,PDWORD,PIMAGEHLP_LINE64);
+typedef BOOL (WINAPI *SymInitialize_FctType)
+ (HANDLE,PSTR,BOOL);
+typedef BOOL (WINAPI *StackWalk64_FctType)
+ (DWORD,HANDLE,HANDLE,LPSTACKFRAME64,PVOID,PREAD_PROCESS_MEMORY_ROUTINE64,
+ PFUNCTION_TABLE_ACCESS_ROUTINE64,PGET_MODULE_BASE_ROUTINE64 ,
+ PTRANSLATE_ADDRESS_ROUTINE64);
+typedef BOOL (WINAPI *MiniDumpWriteDump_FctType)(
+ IN HANDLE hProcess,
+ IN DWORD ProcessId,
+ IN HANDLE hFile,
+ IN MINIDUMP_TYPE DumpType,
+ IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
+ IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
+ IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
+ );
+
+static SymSetOptions_FctType pSymSetOptions;
+static SymGetModuleInfo64_FctType pSymGetModuleInfo64;
+static SymGetSymFromAddr64_FctType pSymGetSymFromAddr64;
+static SymInitialize_FctType pSymInitialize;
+static StackWalk64_FctType pStackWalk64;
+static SymGetLineFromAddr64_FctType pSymGetLineFromAddr64;
+static MiniDumpWriteDump_FctType pMiniDumpWriteDump;
+
+static EXCEPTION_POINTERS *exception_ptrs;
+
+#define MODULE64_SIZE_WINXP 576
+#define STACKWALK_MAX_FRAMES 64
+
+/*
+ Dynamically load dbghelp functions
+*/
+BOOL init_dbghelp_functions()
+{
+ static BOOL first_time= TRUE;
+ static BOOL rc;
+ HMODULE hDbghlp;
+
+ if(first_time)
+ {
+ first_time= FALSE;
+ hDbghlp= LoadLibrary("dbghelp");
+ if(!hDbghlp)
+ {
+ rc= FALSE;
+ return rc;
+ }
+ pSymSetOptions= (SymSetOptions_FctType)
+ GetProcAddress(hDbghlp,"SymSetOptions");
+ pSymInitialize= (SymInitialize_FctType)
+ GetProcAddress(hDbghlp,"SymInitialize");
+ pSymGetModuleInfo64= (SymGetModuleInfo64_FctType)
+ GetProcAddress(hDbghlp,"SymGetModuleInfo64");
+ pSymGetLineFromAddr64= (SymGetLineFromAddr64_FctType)
+ GetProcAddress(hDbghlp,"SymGetLineFromAddr64");
+ pSymGetSymFromAddr64=(SymGetSymFromAddr64_FctType)
+ GetProcAddress(hDbghlp,"SymGetSymFromAddr64");
+ pStackWalk64= (StackWalk64_FctType)
+ GetProcAddress(hDbghlp,"StackWalk64");
+ pMiniDumpWriteDump = (MiniDumpWriteDump_FctType)
+ GetProcAddress(hDbghlp,"MiniDumpWriteDump");
+
+ rc = (BOOL)(pSymSetOptions && pSymInitialize && pSymGetModuleInfo64
+ && pSymGetLineFromAddr64 && pSymGetSymFromAddr64 && pStackWalk64);
+ }
+ return rc;
+}
+
+void set_exception_pointers(EXCEPTION_POINTERS *ep)
+{
+ exception_ptrs = ep;
+}
+
+/* Platform SDK in VS2003 does not have definition for SYMOPT_NO_PROMPTS*/
+#ifndef SYMOPT_NO_PROMPTS
+#define SYMOPT_NO_PROMPTS 0
+#endif
+
+void print_stacktrace(gptr unused1, ulong unused2)
+{
+ HANDLE hProcess= GetCurrentProcess();
+ HANDLE hThread= GetCurrentThread();
+ static IMAGEHLP_MODULE64 module= {sizeof(module)};
+ static IMAGEHLP_SYMBOL64_PACKAGE package;
+ DWORD64 addr;
+ DWORD machine;
+ int i;
+ CONTEXT context;
+ STACKFRAME64 frame={0};
+
+ if(!exception_ptrs || !init_dbghelp_functions())
+ return;
+
+ /* Copy context, as stackwalking on original will unwind the stack */
+ context = *(exception_ptrs->ContextRecord);
+ /*Initialize symbols.*/
+ pSymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_NO_PROMPTS|SYMOPT_DEFERRED_LOADS|SYMOPT_DEBUG);
+ pSymInitialize(hProcess,NULL,TRUE);
+
+ /*Prepare stackframe for the first StackWalk64 call*/
+ frame.AddrFrame.Mode= frame.AddrPC.Mode= frame.AddrStack.Mode= AddrModeFlat;
+#if (defined _M_IX86)
+ machine= IMAGE_FILE_MACHINE_I386;
+ frame.AddrFrame.Offset= context.Ebp;
+ frame.AddrPC.Offset= context.Eip;
+ frame.AddrStack.Offset= context.Esp;
+#elif (defined _M_X64)
+ machine = IMAGE_FILE_MACHINE_AMD64;
+ frame.AddrFrame.Offset= context.Rbp;
+ frame.AddrPC.Offset= context.Rip;
+ frame.AddrStack.Offset= context.Rsp;
+#else
+ /*There is currently no need to support IA64*/
+#pragma error ("unsupported architecture")
+#endif
+
+ package.sym.SizeOfStruct= sizeof(package.sym);
+ package.sym.MaxNameLength= sizeof(package.name);
+
+ /*Walk the stack, output useful information*/
+ for(i= 0; i< STACKWALK_MAX_FRAMES;i++)
+ {
+ DWORD64 function_offset= 0;
+ DWORD line_offset= 0;
+ IMAGEHLP_LINE64 line= {sizeof(line)};
+ BOOL have_module= FALSE;
+ BOOL have_symbol= FALSE;
+ BOOL have_source= FALSE;
+
+ if(!pStackWalk64(machine, hProcess, hThread, &frame, &context, 0, 0, 0 ,0))
+ break;
+ addr= frame.AddrPC.Offset;
+
+ have_module= pSymGetModuleInfo64(hProcess,addr,&module);
+#ifdef _M_IX86
+ if(!have_module)
+ {
+ /*
+ ModuleInfo structure has been "compatibly" extended in releases after XP,
+ and its size was increased. To make XP dbghelp.dll function
+ happy, pretend passing the old structure.
+ */
+ module.SizeOfStruct= MODULE64_SIZE_WINXP;
+ have_module= pSymGetModuleInfo64(hProcess, addr, &module);
+ }
+#endif
+
+ have_symbol= pSymGetSymFromAddr64(hProcess, addr, &function_offset,
+ &(package.sym));
+ have_source= pSymGetLineFromAddr64(hProcess, addr, &line_offset, &line);
+
+ fprintf(stderr, "%p ", addr);
+ if(have_module)
+ {
+ char *base_image_name= strrchr(module.ImageName, '\\');
+ if(base_image_name)
+ base_image_name++;
+ else
+ base_image_name= module.ImageName;
+ fprintf(stderr, "%s!", base_image_name);
+ }
+ if(have_symbol)
+ fprintf(stderr, "%s()", package.sym.Name);
+ else if(have_module)
+ fprintf(stderr, "???");
+
+ if(have_source)
+ {
+ char *base_file_name= strrchr(line.FileName, '\\');
+ if(base_file_name)
+ base_file_name++;
+ else
+ base_file_name= line.FileName;
+ fprintf(stderr,"[%s:%u]", base_file_name, line.LineNumber);
+ }
+ fprintf(stderr, "\n");
+ }
+ fflush(stderr);
+}
+
+
+/*
+ Write dump. The dump is created in current directory,
+ file name is constructed from executable name plus
+ ".dmp" extension
+*/
+void write_core(int unused)
+{
+ char path[MAX_PATH];
+ char dump_fname[MAX_PATH]= "core.dmp";
+ MINIDUMP_EXCEPTION_INFORMATION info;
+ HANDLE hFile;
+
+ if(!exception_ptrs || !init_dbghelp_functions() || !pMiniDumpWriteDump)
+ return;
+
+ info.ExceptionPointers= exception_ptrs;
+ info.ClientPointers= FALSE;
+ info.ThreadId= GetCurrentThreadId();
+
+ if(GetModuleFileName(NULL, path, sizeof(path)))
+ {
+ _splitpath(path, NULL, NULL,dump_fname,NULL);
+ strncat(dump_fname, ".dmp", sizeof(dump_fname));
+ }
+
+ hFile= CreateFile(dump_fname, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ if(hFile)
+ {
+ /* Create minidump */
+ if(pMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
+ hFile, MiniDumpNormal, &info, 0, 0))
+ {
+ fprintf(stderr, "Minidump written to %s\n",
+ _fullpath(path, dump_fname, sizeof(path)) ? path : dump_fname);
+ }
+ else
+ {
+ fprintf(stderr,"MiniDumpWriteDump() failed, last error %u\n",
+ GetLastError());
+ }
+ CloseHandle(hFile);
+ }
+ else
+ {
+ fprintf(stderr, "CreateFile(%s) failed, last error %u\n", dump_fname,
+ GetLastError());
+ }
+ fflush(stderr);
+}
+
+
+void safe_print_str(const char *name, const char *val, int len)
+{
+ fprintf(stderr,"%s at %p", name, val);
+ __try
+ {
+ fprintf(stderr,"=%.*s\n", len, val);
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ fprintf(stderr,"is an invalid string pointer\n");
+ }
+}
+#endif /*__WIN__*/
diff --git a/sql/stacktrace.h b/sql/stacktrace.h
index f5c92e54e1c..e5e17cc5b9b 100644
--- a/sql/stacktrace.h
+++ b/sql/stacktrace.h
@@ -29,20 +29,33 @@ extern char* heap_start;
heap_start = (char*) &__bss_start; \
check_thread_lib(); \
} while(0);
+void check_thread_lib(void);
+#endif /* defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) */
+#elif defined (__WIN__)
+#define HAVE_STACKTRACE
+extern void set_exception_pointers(EXCEPTION_POINTERS *ep);
+#define init_stacktrace() {}
+#endif
+
+#ifdef HAVE_STACKTRACE
void print_stacktrace(gptr stack_bottom, ulong thread_stack);
void safe_print_str(const char* name, const char* val, int max_len);
-void check_thread_lib(void);
-#endif /* (defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) */
-#endif /* TARGET_OS_LINUX */
-
+#else
/* Define empty prototypes for functions that are not implemented */
-#ifndef HAVE_STACKTRACE
#define init_stacktrace() {}
#define print_stacktrace(A,B) {}
#define safe_print_str(A,B,C) {}
#endif /* HAVE_STACKTRACE */
+
+#if !defined(__NETWARE__)
+#define HAVE_WRITE_CORE
+#endif
+
+#ifdef HAVE_WRITE_CORE
void write_core(int sig);
+#endif
+
#ifdef __cplusplus
}
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index 8c4909fc8d5..acf7d571710 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -15,6 +15,7 @@
# MA 02110-1301 USA.
%define mysql_version @VERSION@
+%define mysql_vendor MySQL AB
# use "rpmbuild --with static" or "rpm --define '_with_static 1'" (for RPM 3.x)
# to enable static linking (off by default)
@@ -69,7 +70,7 @@ License: %{license}
Source: http://www.mysql.com/Downloads/MySQL-@MYSQL_BASE_VERSION@/mysql-%{mysql_version}.tar.gz
URL: http://www.mysql.com/
Packager: MySQL Production Engineering Team <build@mysql.com>
-Vendor: MySQL AB
+Vendor: %{mysql_vendor}
Provides: msqlormysql MySQL-server mysql
BuildRequires: ncurses-devel
Obsoletes: mysql
@@ -420,6 +421,72 @@ touch $RBR%{_sysconfdir}/my.cnf
touch $RBR%{_sysconfdir}/mysqlmanager.passwd
%pre server
+# Check if we can safely upgrade. An upgrade is only safe if it's from one
+# of our RPMs in the same version family.
+
+installed=`rpm -q --whatprovides mysql-server 2> /dev/null`
+if [ $? -eq 0 -a -n "$installed" ]; then
+ vendor=`rpm -q --queryformat='%{VENDOR}' "$installed" 2>&1`
+ version=`rpm -q --queryformat='%{VERSION}' "$installed" 2>&1`
+ myvendor='%{mysql_vendor}'
+ myversion='%{mysql_version}'
+
+ old_family=`echo $version | sed -n -e 's,^\([1-9][0-9]*\.[0-9][0-9]*\)\..*$,\1,p'`
+ new_family=`echo $myversion | sed -n -e 's,^\([1-9][0-9]*\.[0-9][0-9]*\)\..*$,\1,p'`
+
+ [ -z "$vendor" ] && vendor='<unknown>'
+ [ -z "$old_family" ] && old_family="<unrecognized version $version>"
+ [ -z "$new_family" ] && new_family="<bad package specification: version $myversion>"
+
+ error_text=
+ if [ "$vendor" != "$myvendor" ]; then
+ error_text="$error_text
+The current MySQL server package is provided by a different
+vendor ($vendor) than $myvendor. Some files may be installed
+to different locations, including log files and the service
+startup script in %{_sysconfdir}/init.d/.
+"
+ fi
+
+ if [ "$old_family" != "$new_family" ]; then
+ error_text="$error_text
+Upgrading directly from MySQL $old_family to MySQL $new_family may not
+be safe in all cases. A manual dump and restore using mysqldump is
+recommended. It is important to review the MySQL manual's Upgrading
+section for version-specific incompatibilities.
+"
+ fi
+
+ if [ -n "$error_text" ]; then
+ cat <<HERE >&2
+
+******************************************************************
+A MySQL server package ($installed) is installed.
+$error_text
+A manual upgrade is required.
+
+- Ensure that you have a complete, working backup of your data and my.cnf
+ files
+- Shut down the MySQL server cleanly
+- Remove the existing MySQL packages. Usually this command will
+ list the packages you should remove:
+ rpm -qa | grep -i '^mysql-'
+
+ You may choose to use 'rpm --nodeps -ev <package-name>' to remove
+ the package which contains the mysqlclient shared library. The
+ library will be reinstalled by the MySQL-shared-compat package.
+- Install the new MySQL packages supplied by $myvendor
+- Ensure that the MySQL server is started
+- Run the 'mysql_upgrade' program
+
+This is a brief description of the upgrade process. Important details
+can be found in the MySQL manual, in the Upgrading section.
+******************************************************************
+HERE
+ exit 1
+ fi
+fi
+
# Shut down a previously installed server first
if test -x %{_sysconfdir}/init.d/mysql
then
@@ -715,6 +782,11 @@ fi
# itself - note that they must be ordered by date (important when
# merging BK trees)
%changelog
+* Mon Feb 18 2008 Timothy Smith <tim@mysql.com>
+
+- Require a manual upgrade if the alread-installed mysql-server is
+ from another vendor, or is of a different major version.
+
* Fri Nov 16 2007 Joerg Bruehe <joerg@mysql.com>
- When testing the debug server, use "make test-bt-debug".
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 9cc2af25529..dbe22f2a9e4 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -8702,8 +8702,8 @@ static void test_sqlmode()
strmov(c1, "My"); strmov(c2, "SQL");
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
-
mysql_stmt_close(stmt);
+
verify_col_data("test_piping", "name", "MySQL");
rc= mysql_query(mysql, "DELETE FROM test_piping");
@@ -12993,7 +12993,7 @@ from t2);");
static void test_bug8378()
{
#if defined(HAVE_CHARSET_gbk) && !defined(EMBEDDED_LIBRARY)
- MYSQL *old_mysql=mysql;
+ MYSQL *lmysql;
char out[9]; /* strlen(TEST_BUG8378)*2+1 */
char buf[256];
int len, rc;
@@ -13002,17 +13002,17 @@ static void test_bug8378()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(mysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_init(NULL)))
{
myerror("mysql_init() failed");
exit(1);
}
- if (mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "gbk"))
+ if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk"))
{
myerror("mysql_options() failed");
exit(1);
}
- if (!(mysql_real_connect(mysql, opt_host, opt_user,
+ if (!(mysql_real_connect(lmysql, opt_host, opt_user,
opt_password, current_db, opt_port,
opt_unix_socket, 0)))
{
@@ -13022,19 +13022,17 @@ static void test_bug8378()
if (!opt_silent)
fprintf(stdout, " OK");
- len= mysql_real_escape_string(mysql, out, TEST_BUG8378_IN, 4);
+ len= mysql_real_escape_string(lmysql, out, TEST_BUG8378_IN, 4);
/* No escaping should have actually happened. */
DIE_UNLESS(memcmp(out, TEST_BUG8378_OUT, len) == 0);
sprintf(buf, "SELECT '%s'", out);
- rc=mysql_real_query(mysql, buf, strlen(buf));
+ rc=mysql_real_query(lmysql, buf, strlen(buf));
myquery(rc);
- mysql_close(mysql);
-
- mysql=old_mysql;
+ mysql_close(lmysql);
#endif
}
@@ -14869,7 +14867,7 @@ static void test_opt_reconnect()
if (mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true))
{
myerror("mysql_options failed: unknown option MYSQL_OPT_RECONNECT\n");
- exit(1);
+ DIE_UNLESS(0);
}
/* reconnect should be 1 */
@@ -14882,7 +14880,7 @@ static void test_opt_reconnect()
opt_unix_socket, 0)))
{
myerror("connection failed");
- exit(1);
+ DIE_UNLESS(0);
}
/* reconnect should still be 1 */
@@ -14896,7 +14894,7 @@ static void test_opt_reconnect()
if (!(lmysql= mysql_init(NULL)))
{
myerror("mysql_init() failed");
- exit(1);
+ DIE_UNLESS(0);
}
if (!opt_silent)
@@ -14908,7 +14906,7 @@ static void test_opt_reconnect()
opt_unix_socket, 0)))
{
myerror("connection failed");
- exit(1);
+ DIE_UNLESS(0);
}
/* reconnect should still be 0 */
@@ -14926,32 +14924,32 @@ static void test_opt_reconnect()
static void test_bug12744()
{
MYSQL_STMT *prep_stmt = NULL;
+ MYSQL *lmysql;
int rc;
myheader("test_bug12744");
- prep_stmt= mysql_stmt_init(mysql);
- rc= mysql_stmt_prepare(prep_stmt, "SELECT 1", 8);
- DIE_UNLESS(rc==0);
-
- mysql_close(mysql);
+ lmysql= mysql_init(NULL);
+ DIE_UNLESS(lmysql);
- if ((rc= mysql_stmt_execute(prep_stmt)))
+ if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
+ current_db, opt_port, opt_unix_socket, 0))
{
- if ((rc= mysql_stmt_reset(prep_stmt)))
- printf("OK!\n");
- else
- {
- printf("Error!");
- DIE_UNLESS(1==0);
- }
- }
- else
- {
- fprintf(stderr, "expected error but no error occured\n");
- DIE_UNLESS(1==0);
+ fprintf(stderr, "Failed to connect to the database\n");
+ DIE_UNLESS(0);
}
+
+ prep_stmt= mysql_stmt_init(lmysql);
+ rc= mysql_stmt_prepare(prep_stmt, "SELECT 1", 8);
+ DIE_UNLESS(rc == 0);
+
+ mysql_close(lmysql);
+
+ rc= mysql_stmt_execute(prep_stmt);
+ DIE_UNLESS(rc);
+ rc= mysql_stmt_reset(prep_stmt);
+ DIE_UNLESS(rc);
rc= mysql_stmt_close(prep_stmt);
- client_connect(0);
+ DIE_UNLESS(rc == 0);
}
#endif /* EMBEDDED_LIBRARY */
@@ -15216,7 +15214,6 @@ static void test_bug14169()
/*
Test that mysql_insert_id() behaves as documented in our manual
*/
-
static void test_mysql_insert_id()
{
my_ulonglong res;
@@ -15241,6 +15238,22 @@ static void test_mysql_insert_id()
myquery(rc);
res= mysql_insert_id(mysql);
DIE_UNLESS(res == 0);
+
+ /*
+ Test for bug #34889: mysql_client_test::test_mysql_insert_id test fails
+ sporadically
+ */
+ rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
+ myquery(rc);
+ rc= mysql_query(mysql, "insert into t2 values (null,'b')");
+ myquery(rc);
+ rc= mysql_query(mysql, "insert into t1 select 5,'c'");
+ myquery(rc);
+ res= mysql_insert_id(mysql);
+ DIE_UNLESS(res == 0);
+ rc= mysql_query(mysql, "drop table t2");
+ myquery(rc);
+
rc= mysql_query(mysql, "insert into t1 select null,'d'");
myquery(rc);
res= mysql_insert_id(mysql);
@@ -15759,6 +15772,7 @@ static void test_bug24179()
mysql_stmt_error(stmt));
}
DIE_UNLESS(mysql_stmt_errno(stmt) == 1323);
+ mysql_stmt_close(stmt);
DBUG_VOID_RETURN;
}
@@ -15801,6 +15815,7 @@ static void test_bug27876()
myquery(rc);
result= mysql_store_result(mysql);
mytest(result);
+ mysql_free_result(result);
sprintf(query, "DROP FUNCTION IF EXISTS %s", utf8_func);
rc= mysql_query(mysql, query);
@@ -15817,6 +15832,7 @@ static void test_bug27876()
myquery(rc);
result= mysql_store_result(mysql);
mytest(result);
+ mysql_free_result(result);
sprintf(query, "DROP FUNCTION %s", utf8_func);
rc= mysql_query(mysql, query);
@@ -15936,6 +15952,7 @@ static void test_bug27592()
DBUG_VOID_RETURN;
}
+#if 0
static void test_bug29948()
{
@@ -15965,6 +15982,7 @@ static void test_bug29948()
exit(1);
}
+ bzero(&bind, sizeof(bind));
bind.buffer_type= MYSQL_TYPE_LONG;
bind.buffer= (char *)&buf;
bind.is_null= &is_null;
@@ -16010,6 +16028,8 @@ static void test_bug29948()
mysql_close(dbc);
}
+#endif
+
/**
Bug#29306 Truncated data in MS Access with decimal (3,1) columns in a VIEW
*/
@@ -16152,6 +16172,99 @@ static void test_bug31669()
DBUG_VOID_RETURN;
}
+
+/**
+ Bug#32265 Server returns different metadata if prepared statement is used
+*/
+
+static void test_bug32265()
+{
+ int rc;
+ MYSQL_STMT *stmt;
+ MYSQL_FIELD *field;
+ MYSQL_RES *metadata;
+
+ DBUG_ENTER("test_bug32265");
+ myheader("test_bug32265");
+
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
+ myquery(rc);
+ rc= mysql_query(mysql, "CREATE TABLE t1 (a INTEGER)");
+ myquery(rc);
+ rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
+ myquery(rc);
+ rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT * FROM t1");
+ myquery(rc);
+
+ stmt= open_cursor("SELECT * FROM t1");
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ metadata= mysql_stmt_result_metadata(stmt);
+ field= mysql_fetch_field(metadata);
+ DIE_UNLESS(field);
+ DIE_UNLESS(strcmp(field->table, "t1") == 0);
+ DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
+ DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
+ mysql_free_result(metadata);
+ mysql_stmt_close(stmt);
+
+ stmt= open_cursor("SELECT a '' FROM t1 ``");
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ metadata= mysql_stmt_result_metadata(stmt);
+ field= mysql_fetch_field(metadata);
+ DIE_UNLESS(strcmp(field->table, "") == 0);
+ DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
+ DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
+ mysql_free_result(metadata);
+ mysql_stmt_close(stmt);
+
+ stmt= open_cursor("SELECT a '' FROM t1 ``");
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ metadata= mysql_stmt_result_metadata(stmt);
+ field= mysql_fetch_field(metadata);
+ DIE_UNLESS(strcmp(field->table, "") == 0);
+ DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
+ DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
+ mysql_free_result(metadata);
+ mysql_stmt_close(stmt);
+
+ stmt= open_cursor("SELECT * FROM v1");
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ metadata= mysql_stmt_result_metadata(stmt);
+ field= mysql_fetch_field(metadata);
+ DIE_UNLESS(strcmp(field->table, "v1") == 0);
+ DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
+ DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
+ mysql_free_result(metadata);
+ mysql_stmt_close(stmt);
+
+ stmt= open_cursor("SELECT * FROM v1 /* SIC */ GROUP BY 1");
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ metadata= mysql_stmt_result_metadata(stmt);
+ field= mysql_fetch_field(metadata);
+ DIE_UNLESS(strcmp(field->table, "v1") == 0);
+ DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
+ DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
+ mysql_free_result(metadata);
+ mysql_stmt_close(stmt);
+
+ rc= mysql_query(mysql, "DROP VIEW v1");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP TABLE t1");
+ myquery(rc);
+
+ DBUG_VOID_RETURN;
+}
+
/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -16443,9 +16556,10 @@ static struct my_tests_st my_tests[]= {
{ "test_bug28505", test_bug28505 },
{ "test_bug28934", test_bug28934 },
{ "test_bug27592", test_bug27592 },
- { "test_bug29948", test_bug29948 },
+ /* { "test_bug29948", test_bug29948 }, Bug#35103 */
{ "test_bug29306", test_bug29306 },
{ "test_bug31669", test_bug31669 },
+ { "test_bug32265", test_bug32265 },
{ 0, 0 }
};
diff --git a/vio/viossl.c b/vio/viossl.c
index c178d9e9d1b..eea274cf92d 100644
--- a/vio/viossl.c
+++ b/vio/viossl.c
@@ -172,20 +172,15 @@ void vio_ssl_delete(Vio *vio)
vio_delete(vio);
}
-int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
-{
- DBUG_ENTER("sslaccept");
- DBUG_RETURN(sslconnect(ptr, vio, timeout));
-}
-
-int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
+static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
+ int (*connect_accept_func)(SSL*))
{
SSL *ssl;
my_bool unused;
my_bool was_blocking;
- DBUG_ENTER("sslconnect");
+ DBUG_ENTER("ssl_do");
DBUG_PRINT("enter", ("ptr: 0x%lx, sd: %d ctx: 0x%lx",
(long) ptr, vio->sd, (long) ptr->ssl_context));
@@ -204,13 +199,9 @@ int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
SSL_set_fd(ssl, vio->sd);
- /*
- SSL_do_handshake will select between SSL_connect
- or SSL_accept depending on server or client side
- */
- if (SSL_do_handshake(ssl) < 1)
+ if (connect_accept_func(ssl) < 1)
{
- DBUG_PRINT("error", ("SSL_do_handshake failure"));
+ DBUG_PRINT("error", ("SSL_connect/accept failure"));
report_errors(ssl);
SSL_free(ssl);
vio_blocking(vio, was_blocking, &unused);
@@ -259,6 +250,20 @@ int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
}
+int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
+{
+ DBUG_ENTER("sslaccept");
+ DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_accept));
+}
+
+
+int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
+{
+ DBUG_ENTER("sslconnect");
+ DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_connect));
+}
+
+
int vio_ssl_blocking(Vio *vio __attribute__((unused)),
my_bool set_blocking_mode,
my_bool *old_mode)
@@ -269,4 +274,6 @@ int vio_ssl_blocking(Vio *vio __attribute__((unused)),
return (set_blocking_mode ? 0 : 1);
}
+
+
#endif /* HAVE_OPENSSL */